3 पॉइंट द्वारा GN⁺ 2024-03-04 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Observable Framework एक open source टूल है, जो अस्थायी data exploration में मजबूत notebook model से आगे जाकर तेज़ी से load होने वाले data apps, dashboards और reports को static sites के रूप में deploy करने के लिए है
  • Markdown के अंदर js code blocks और inline expressions browser में execute होते हैं, और now जैसे reactive values बदलने पर संबंधित display भी अपने-आप update हो जाता है
  • Framework, Observable Notebooks की reactivity बनाए रखते हुए भी single Markdown file, standard JavaScript और Git-friendly workflow देता है
  • Inputs, d3, Plot जैसी libraries development के दौरान lazy-loaded होती हैं, और build/deploy के समय केवल referenced code ही jsdelivr CDN से अपने-आप load होता है
  • Data loader का उपयोग करने पर build time पर किसी भी भाषा में data तैयार कर उसे JSON·CSV जैसे static files के रूप में bundle किया जा सकता है, जिससे backend dependency कम करते हुए dashboards deploy करना संभव होता है

Data apps के लिए static site generator

  • Observable Framework एक static site generator है, जो Markdown, JavaScript और ज़रूरत पड़ने पर अन्य भाषाओं को मिलाकर interactive pages में compile करता है
  • इसमें पूरी क्षमता वाला hot reloading server शामिल है, इसलिए editor में file बदलकर save करते ही browser में बदलाव तुरंत दिखते हैं
  • काम पूरा होने पर build command से static files का set बनाया जा सकता है
    • इस file को server पर deploy किया जा सकता है
    • npm run deploy से Observable के authenticated sharing platform पर सीधे deploy भी किया जा सकता है

Markdown के अंदर चलने वाला JavaScript

  • Framework का core design Markdown document के अंदर JavaScript डालकर interactive document बनाने का तरीका है
  • js से tagged Markdown code blocks user के browser में JavaScript के रूप में execute होते हैं
  • Inline expressions भी इस्तेमाल किए जा सकते हैं, और ${new Date(now)} की तरह current time को string के रूप में दिखाया जा सकता है
  • now एक special variable है, जो epoch के बाद से milliseconds में current time देता है और लगातार update होता रहता है
    • now बदलने पर उसे reference करने वाले cells और inline expressions भी साथ में update होते हैं
  • Observable Notebooks में code और Markdown अलग-अलग cells में लिखे जाते हैं, लेकिन Framework में दोनों एक ही text document के अंदर होते हैं
  • Inline expressions और js blocks का display तरीका अलग हो सकता है
    • Inline expressions JavaScript object की default string representation का उपयोग करते हैं
    • js blocks Observable के display() function का उपयोग करते हैं, और display rules inspect/src/inspect.js में हैं

Reactive execution model बरकरार

  • Observable Notebooks की core capability यानी reactivity Framework के JavaScript Markdown documents में भी बनी रहती है
  • कोई cell बदलने पर उस cell पर निर्भर अन्य cells अपने-आप फिर से evaluate होते हैं
  • यह तरीका Jupyter notebooks से बड़ा फर्क है, और Python notebook tool marimo की भी प्रमुख capability है
  • Form inputs के साथ इस्तेमाल करने पर इसका असर बड़ा होता है
    • Page में input जोड़कर उसके value को document के दूसरे हिस्सों में reference करने से real-time interaction आसानी से बनाया जा सकता है

PyPI downloads dashboard का उदाहरण

  • Example dashboard Python package के अनुसार PyPI download statistics दिखाता है, और Observable Framework version 57-line Markdown document से बना है
  • User Inputs.select() से packages array में से package चुनता है
    • Inputs.select() Framework में शामिल method है और Observable Inputs documentation में देखा जा सकता है
    • view() function Framework में नया जोड़ा गया feature है, जिससे input selection में बदलाव document के दूसरे code blocks में reflect होता है
  • packageName को const के रूप में define किया गया है और page के अन्य js blocks में इस्तेमाल किया जा सकता है
  • Data d3.json() से लाया जाता है
    • Framework में पूरा D3 इस्तेमाल किया जा सकता है
    • URL में selected package name शामिल होता है
    • Data source Datasette का JSON API है
  • SQLite table datasette.io/content/stats पर है, और latest PyPI package statistics के साथ दिन में एक बार update होती है
    • संबंधित GitHub Actions workflow पहले के baked data लेख में cover किया गया था
  • URL में .json जोड़ने पर JSON return होता है
    • केवल specific package rows मांगी जाती हैं
    • Date descending order में sort किया जाता है
    • अधिकतम 1,000 rows object array के रूप में मिलती हैं
  • SQLite string dates को d3.timeParse("%Y-%m-%d") से JavaScript Date objects में convert किया जाता है
  • Chart को Framework के साथ packaged Observable Plot से render किया जाता है
  • Package list Datasette के /content database पर सीधे SQL query चलाकर लाई जाती है
    • Query है select package from stats group by package order by max(downloads) desc
    • _shape=arrayfirst result rows के पहले column को JSON array के रूप में पाने का shortcut है

केवल इस्तेमाल हो रहा code शामिल

  • Example dashboard Inputs, d3, Plot जैसी additional libraries इस्तेमाल करता है
  • Development mode में lazy loading लागू होती है
    • Code केवल तब load होता है जब पहली बार किसी cell में उसे इस्तेमाल करने की कोशिश होती है
  • Application build और deploy करने पर Framework केवल referenced library code को jsdelivr CDN से अपने-आप load करता है

Build time data caching

  • Framework का Data loader dashboard data को build time पर तैयार करने की capability है
  • Framework dashboards runtime पर fetch() या उसके wrapper का उपयोग करके कहीं से भी data ला सकते हैं
    • Observable Notebooks भी इसी तरीके से काम करते हैं
    • इस तरीके में dashboard performance जुड़े हुए backend पर निर्भर होती है
  • Framework deployment time पर dashboard के लिए data बनाने और केवल ज़रूरी data subset को static files के रूप में bundle करने का pattern सुझाता है
    • Static data files dashboard code के समान static hosting से तेज़ी से serve की जा सकती हैं
  • Data loader किसी भी programming language में लिखा गया script होता है
    • Build के समय Framework script execute करता है
    • Script के standard output result को file के रूप में save करता है
  • उदाहरण में quakes.json.sh file में curl https://earthquake.usgs.gov/earthquakes/feed/… डालने का तरीका है
    • Build के समय filename Framework को बताता है कि destination file quakes.json है और execute किया जाने वाला loader .sh है
  • अगर standard output पर JSON, CSV या कोई उपयोगी format output किया जा सकता है, तो data किसी भी technology से लाया जा सकता है

Observable Notebooks से फर्क

  • Observable Framework, Observable Notebooks के कई ideas और code reuse करता है, लेकिन file format और execution environment में बड़ा फर्क है
  • Existing Observable Notebooks की Jupyter Notebooks की तुलना में ये विशेषताएं हैं
    • Python नहीं, JavaScript इस्तेमाल करता है
    • Notebook editor खुद open source नहीं है और observablehq.com पर उपलब्ध hosted product है
    • Notebook को static file के रूप में export करके कहीं भी चलाया जा सकता है, लेकिन editor proprietary product है
    • Cells reactive होते हैं, और कोई cell बदलने पर उस cell पर निर्भर दूसरे cells Excel की तरह अपने-आप re-evaluate होते हैं
    • Reactivity model को support करने के लिए viewof नाम का custom keyword बनाया गया, इसलिए JavaScript syntax पूरी तरह standard नहीं है
    • Editable notebooks complex proprietary file format हैं और Git जैसे tools के साथ अच्छी तरह fit नहीं होते, इसलिए Observable ने अपना version management और collaboration system implement किया है
  • Observable Framework इस model को अधिक simple file format और open source execution environment में लाता है
    • Document JavaScript blocks वाली single Markdown file है
    • यह अब भी reactive है, लेकिन किसी भी text editor से edit किया जा सकता है और Git में रखा जा सकता है
    • पूरा stack ISC license वाला open source है, और पूरा editing stack local machine पर चलाया जा सकता है
    • Custom syntax के बिना केवल standard JavaScript इस्तेमाल करता है

Observable की दिशा में बदलाव

  • Observable Framework, Observable के मौजूदा proprietary Observable Notebook editor-केंद्रित collaboration tool से developer tools की ओर अधिक झुके बदलाव जैसा दिखता है
  • Observable का Twitter intro text है “The end-to-end solution for developers who want to build and host dashboards that don’t suck”
    • 3 अक्टूबर 2023 की Internet Archive copy में “Build data visualizations, dashboards, and data apps that impact your business — faster.” लिखा था
  • Observable Notebooks का उपयोग platform की proprietary nature और free account की limitations, खासकर free private notebooks न होने की वजह से कुछ सीमित हो सकता है
  • Observable Plot जैसी open source libraries को पहले से सक्रिय रूप से इस्तेमाल की जा सकने वाली technology माना जाता है
  • Observable Framework उन ideas को, जिन्होंने Observable Notebooks को आकर्षक बनाया था, open source, standard JavaScript, single text file और static deployment model के रूप में फिर से implement करता है

1 टिप्पणियां

 
GN⁺ 2024-03-04
Hacker News की राय
  • कुछ मायनों में Observable Framework, Mike Bostock cinematic universe का Avengers: Endgame जैसा है
    d3, Observable, Observable Plot, HTL को एक साथ लाता है, और ऊपर से काफ़ी नए ideas भी जोड़ता है

    • निजी तौर पर Polymaps अब भी उनकी कृतियों में मुझे सबसे ज़्यादा पसंद है
    • ऐसा लगता है जैसे यह “human-augmented” AI developer agents के लिए कुछ बना रहा है
      Observable में पहले से AI integration है, और यह ऐसा wrapper लगता है जिससे AI चीज़ों को ज़्यादा आसानी से जोड़कर इस्तेमाल कर सके। AI के बिना strategy का मूल्यांकन वाला हिस्सा थोड़ा अटपटा लगा
    • पहले Observable और Observable Framework को bookmark किया था, लेकिन गहराई से नहीं देखा था
      आज static Jupyter Notebook को host करने या WASM के ज़रिए interactive रूप में चलाने के तरीके देखने शुरू किए, लेकिन लगता है कि ज़्यादातर use cases के लिए Observable Framework ज़्यादा ठीक बैठेगा
  • Observable की दिक्कत यह है कि यह d3 examples की gallery जैसा दिखता है, फिर भी उसका code उसी framework के भीतर चलने के लिए design किया गया है, इसलिए बस copy-paste नहीं किया जा सकता
    d3 वैसे भी examples के बिना इस्तेमाल करने में आसान नहीं है, और खासकर versions के बीच breaking changes भी अक्सर होते हैं। फिर भी site पर कई कमाल के graphics हैं
    [0] https://observablehq.com/@d3/gallery

    • 100% सहमत। यह बात कि यह असली JavaScript से थोड़ा अलग है, अंत तक पचा पाना मुश्किल था
      यह मूल भाषा के इतना करीब है कि graphics दिखाने के लिए API थोड़ा जोड़कर बस JavaScript ही इस्तेमाल की जा सकती थी
    • community ने कभी Observable-style JavaScript को सामान्य JavaScript में बदलने का resource publish किया था
      इसमें ज़्यादातर top-level cell definitions को फिर से लिखना होता है
      [0]: https://observablehq.com/@bumbeishvili/convert-observable-co...
    • यही बात बेहद frustrate करती है। यह ऐसी platform lock-in जैसी लगती है जिस पर कोई भी company गर्व करेगी
      ObservableHQ notebooks में यह शिकायत खास तौर पर ज़्यादा थी। वे शानदार examples होते हुए भी practically useless material बन जाते हैं। हालांकि इस बार Framework वाला हिस्सा कुछ ज़्यादा open लगता है, और कम-से-कम self-hosting संभव है, इसलिए देख रहा हूँ
    • यह Observable की समस्या से ज़्यादा d3 की समस्या लगती है कि उसने कहीं और copy-paste किए जा सकने वाले examples नहीं दिए
      ऊपर से यह लेख नए Observable Framework के बारे में है, जिसने पुराने Observable notebooks की कुछ समस्याएँ हटाई हैं, इसलिए यह comment लेख से थोड़ा हटकर है। अब तो बात ऐसी है कि “सब कुछ standard JavaScript है, custom syntax नहीं”
  • Framework को GitHub Pages पर deploy करना भी बहुत आसान है
    steps और sample GitHub Action यहाँ लिख रखे हैं: https://notes.billmill.org/programming/observable_framework/...

  • लेखक ने Framework के बारे में बिल्कुल सही पकड़ा है
    Observable Framework का इस्तेमाल करके एक छोटा interactive plot बनाया था(https://github.com/willmeyers/observable-ssta), और setup करने व data plot करने की प्रक्रिया अविश्वसनीय रूप से आसान थी। मेरी एकमात्र शिकायत यह है कि काश Python data loader को virtualenv इस्तेमाल करने के लिए configure किया जा सकता

    • मैं poetry के साथ Python data loader को poetry-managed virtualenv के अंदर चलाने वाला setup इस्तेमाल कर रहा हूँ
      Python project बनाने के बाद development server शुरू करते समय yarn run dev की जगह poetry run yarn run dev चलाएँ, तो Python virtualenv के अंदर execute होता है। यह setup data loader में reusable और unit-testable code को custom Python package के रूप में define करने देता है, फिर *.json.py files में import करके उन्हें बहुत simple रखा जा सकता है
    • क्या Python के nodeenv से यह हल नहीं हो सकता? आम तौर पर project में JS जोड़ते समय मैं ऐसा ही करता हूँ
      node और npm/yarn जैसे tools, और JavaScript तक, venv के अंदर साथ में रहते हैं
    • क्या .sh data loader में shebang डालकर उसे virtual environment directory के अंदर मौजूद bin/python के full path की ओर point नहीं कराया जा सकता?
  • हाल ही में Observable notebook से अपना पहला “real-world” project पूरा किया
    इसमें Observable Plot, Arquero सीखना, JavaScript के कुछ हिस्से फिर से सीखना, और data generation process यानी Rust-based simulator के साथ integration शामिल था। ईमानदारी से कहूँ तो यह सचमुच शानदार था। tools सीखने में काफ़ी energy लगी और data generator को parameterize करने की capability अभी भी थोड़ी कम लगती है, लेकिन final notebook खूबसूरत है और अच्छी तरह काम करता है
    Markdown और reactivity इस्तेमाल करने पर ऐसे notebooks सच में उपयोगी लगते हैं। Jupyter का custom format version control को बहुत मुश्किल बना देता है, और reactivity न हो तो iteratively design किया गया notebook आसानी से ऐसा state-based mess बन जाता है जिसे लिखना आसान पर पढ़ना मुश्किल होता है। Quarto और उसके Observable integration से भी कोशिश की, लेकिन वह जुगाड़ के टुकड़े जोड़ने जैसा लगा
    सच में, यह पहला अनुभव था जब notebook लिखना और दूसरों के साथ share करना मज़ेदार और उत्साहजनक लगा। आगे भी sharp edges होंगे, लेकिन इस project के बाद notebook tools में मेरी पहली पसंद यही है

    • अगर Quarto का alternative खोज रहे हैं, तो हाल में release हुआ Living Papers भी देख सकते हैं, जिससे single source से reactive/static documents लिखे जा सकते हैं
      [0]: https://living-papers.vercel.app/
  • अगर आप ब्राउज़र में Framework को जल्दी से आज़माना और उससे खेलना चाहते हैं, तो Node और Python environment को अपने-आप configure करने वाला Codespace devcontainer बनाया गया है
    [0]: https://github.com/dleeftink/observable-codespace

  • क्या Jupyter Notebook से Observable पर शिफ्ट होना चाहिए? या दोनों को इस तरह अलग-अलग बांटना ही गलत framing है?

    • आखिरकार, सवाल का मूल यही लगता है कि आप Python और उसके ecosystem में ज़्यादा productive हैं, या JavaScript और उसके packages में—खासकर D3 जैसी चीज़ों में
  • पोस्ट की बात को दूसरे शब्दों में कहें तो, js content hint वाले code block के अंदर की हर चीज़ user के browser में तुरंत execute होती है
    code दिखाने के लिए js echo hint इस्तेमाल करना पड़ता है। backward compatibility को देखते हुए इसका उलटा बेहतर नहीं होता? मसलन, user के browser में चलने वाले code को js exec जैसे opt-in hint के रूप में रखा जाता, और व्यापक रूप से इस्तेमाल होने वाला js hint जैसा है वैसा ही रहता। मौजूदा संरचना में उस renderer को किसी existing app में integrate करते समय अलग से manage करना पड़ता है कि कहाँ execution allow करनी है

    • block के default options बदलने की सुविधा देने की योजना है
      यह page-by-page front matter में किया जा सकेगा, या project settings से पूरे project पर लागू किया जा सकेगा। तब js run=false को default बनाया जा सकता है, और जहाँ चाहें केवल वहाँ js run से live code चालू किया जा सकता है। हालांकि हमारा मुख्य use case live code है, इसलिए हमने इसे default के रूप में चुना
    • सही है। यह GitHub पर Mermaid diagrams को automatically render करने जैसी ही समस्या है
      अब language annotation हटाए बिना Mermaid code block को सिर्फ दिखाना संभव नहीं रह गया है
  • Observable Framework में डूबकर एक रात बिताई, और यह बहुत अच्छा लगा
    लगभग कोई friction नहीं था, और मैं Google Maps history को विस्तार से visualize और explore कर सका। data loader environment से जुड़ा हिस्सा बहुत clear नहीं था, लेकिन Python को poetry environment में चलाने से समाधान हो गया
    मुझे Kotlin पसंद है, इसलिए Kotlin scripts के लिए data loader बनाने की भी कोशिश की, लेकिन कुछ rough edges थे। Kotlin script file का नाम foo.main.kts होने की अपेक्षा करता है, जबकि Observable executable shebang loader के लिए foo.exe extension expect करता है। इसलिए मैंने Kotlin script को call करने वाला proxy exe script बनाया, लेकिन तब data का automatic reload trigger नहीं होता
    marimo या Jupyter की तुलना में एक हल्की असुविधा data loader और notebook के बीच variables इस्तेमाल करने में है। उदाहरण के लिए, मैं date selection view component से loader द्वारा लाई जाने वाली data range बदलना चाहता हूँ, लेकिन यह साफ़ नहीं है कि ऐसा कैसे करना है। इसलिए exploratory analysis थोड़ा धीमा हो जाता है। मुझे पता है कि यह paradigm के खिलाफ है, लेकिन इसे mention करना चाहता था। नतीजतन, explore करते समय data wrangling का काफी हिस्सा notebook में shift हो सकता है, जो performance के लिहाज़ से ideal नहीं है
    आखिर में, अच्छा होगा अगर data loader को inline define किया जा सके। मुझे single file पसंद है, इसलिए अगर Python code block जोड़ने पर Framework उसे file में extract कर दे, तो यह छोटी-सी quality-of-life improvement होगी। अभी शुरुआती दौर है, लेकिन Framework promising लगता है। उम्मीद है कि अपनी सारी Markdown notes यहाँ डालकर, full Emacs तक गए बिना org-mode जैसा environment बनाया जा सकेगा

    • feedback के लिए धन्यवाद। .sh या .exe से workaround किए बिना नए interpreters को ज़्यादा आसानी से register करने के लिए एक PR खुला है
      इससे किसी खास file extension से जुड़े interpreter को specify किया जा सकेगा। उदाहरण के लिए Kotlin के लिए .kts संभव होगा। https://github.com/observablehq/framework/pull/935
      input values से data loader चलाने का तरीका Framework के static data snapshots को prefer करने से थोड़ा अलग दिशा में है। मकसद यह है कि built site self-contained और performant हो। फिर भी एक अच्छी तरह काम करने वाली technique यह है कि data loader में जिस data से interact करना है उसका superset Parquet file के रूप में generate किया जाए, और client-side पर DuckDB/SQL से visualization के लिए subset निकाला जाए। आम तौर पर performance अच्छी रहती है, लेकिन जाहिर है यह उस superset के size पर निर्भर करता है जिसे आप handle करना चाहते हैं
  • Observable, REST API के ज़रिए ClickHouse के साथ बहुत अच्छी तरह integrate होता है
    example यहाँ है: https://observablehq.com/@stas-sl/github-issues-survival-ana...
    नया Observable Framework अभी इस्तेमाल नहीं किया है, लेकिन database को real time में query करने वाले similar examples देखना दिलचस्प होगा। उम्मीद है कि इसकी structure ऐसी नहीं है कि सिर्फ सारे data को पहले से load और cache करना ही possible हो। ऐसे apps interactive होने चाहिए, इसलिए ideally SQL को live edit करने के लिए expose किया जाना चाहिए