3 puan yazan GN⁺ 2024-03-04 | 1 yorum | WhatsApp'ta paylaş
  • Observable Framework, geçici veri keşfinde güçlü olan notebook modelinin ötesine geçerek hızlı yüklenen veri uygulamaları, panolar ve raporları statik site olarak dağıtmayı amaçlayan açık kaynaklı bir araçtır
  • Markdown içindeki js kod blokları ve satır içi ifadeler tarayıcıda çalışır; now gibi reaktif değerler değiştiğinde ilgili gösterimler de otomatik olarak güncellenir
  • Framework, Observable Notebooks’un reaktifliğini korurken tek bir Markdown dosyası, standart JavaScript ve Git dostu bir iş akışı sunar
  • Inputs, d3, Plot gibi kütüphaneler geliştirme sırasında tembel yüklenir; derleme ve dağıtım sırasında ise yalnızca başvurulan kod jsdelivr CDN’inden otomatik yüklenir
  • Data loader kullanıldığında veriler derleme zamanında herhangi bir dille hazırlanıp JSON, CSV gibi statik dosyalar halinde paketlenebilir; böylece backend bağımlılığı azaltılmış panolar dağıtılabilir

Veri uygulamaları için statik site üreticisi

  • Observable Framework, Markdown, JavaScript ve gerekirse başka dilleri de karıştırarak etkileşimli sayfalara derleyen bir statik site üreticisidir
  • Tam özellikli bir hot reload sunucusu içerir; editörde dosyayı değiştirip kaydettiğinizde değişiklikler tarayıcıya anında yansır
  • İş bittiğinde derleme komutuyla bir statik dosya seti oluşturabilirsiniz
    • Bu dosyalar bir sunucuya dağıtılabilir
    • npm run deploy ile Observable’ın kimlik doğrulamalı paylaşım platformuna doğrudan da dağıtılabilir

Markdown içinde çalışan JavaScript

  • Framework’ün temel tasarımı, Markdown belgesinin içine JavaScript koyarak etkileşimli belgeler oluşturma yaklaşımıdır
  • js ile etiketlenmiş Markdown kod blokları, kullanıcının tarayıcısında JavaScript olarak çalıştırılır
  • Satır içi ifadeler de kullanılabilir; ${new Date(now)} gibi mevcut zamanı metin olarak gösterebilirsiniz
  • now, epoch’tan bu yana milisaniye cinsinden mevcut zamanı sağlayan ve sürekli güncellenen özel bir değişkendir
    • now değiştiğinde ona başvuran hücreler ve satır içi ifadeler de birlikte güncellenir
  • Observable Notebooks’ta kod ve Markdown ayrı hücrelerde yazılır; Framework’te ise ikisi tek bir metin belgesinin içinde yer alır
  • Satır içi ifadeler ile js bloklarının gösterim biçimi farklı olabilir
    • Satır içi ifadeler JavaScript nesnelerinin varsayılan metin temsilini kullanır
    • js blokları Observable’ın display() fonksiyonunu kullanır; gösterim kuralları inspect/src/inspect.js içindedir

Reaktif yürütme modelini koruma

  • Observable Notebooks’un temel özelliği olan reaktiflik, Framework’ün JavaScript Markdown belgelerinde de korunur
  • Bir hücre değiştiğinde, o hücreye bağımlı diğer hücreler otomatik olarak yeniden değerlendirilir
  • Bu yaklaşım Jupyter notebooks ile arasındaki büyük farklardan biridir ve Python notebook aracı marimo’nun da öne çıkan özelliklerindendir
  • Form girdileriyle birlikte kullanıldığında etkisi büyüktür
    • Sayfaya bir girdi ekleyip değerini belgenin başka bölümlerinde referans gösterirseniz gerçek zamanlı etkileşimleri kolayca oluşturabilirsiniz

PyPI indirme panosu örneği

  • Örnek pano, Python paketlerine göre PyPI indirme istatistiklerini gösterir; Observable Framework sürümü 57 satırlık bir Markdown belgesinden oluşur
  • Kullanıcı Inputs.select() ile packages dizisinden bir paket seçer
    • Inputs.select(), Framework’e dahil bir metottur ve Observable Inputs belgelerinde görülebilir
    • view() fonksiyonu Framework’e yeni eklenen bir özelliktir; girdi seçimi değişikliklerinin belgedeki diğer kod bloklarına yansımasını sağlar
  • packageName, sayfadaki diğer js bloklarında kullanılabilmesi için const olarak tanımlanır
  • Veriler d3.json() ile alınır
    • Framework’te D3’ün tamamı kullanılabilir
    • URL, seçilen paket adını içerir
    • Veri kaynağı Datasette’in JSON API’sidir
  • SQLite tablosu datasette.io/content/stats adresindedir ve en güncel PyPI paket istatistikleriyle günde bir kez güncellenir
    • İlgili GitHub Actions iş akışı daha önceki baked data yazısında ele alınmıştı
  • URL’ye .json eklendiğinde JSON döner
    • Yalnızca belirli paket satırları istenir
    • Tarihe göre azalan sırada sıralanır
    • En fazla 1.000 satır nesne dizisi olarak alınır
  • SQLite metin tarihleri d3.timeParse("%Y-%m-%d") ile JavaScript Date nesnelerine dönüştürülür
  • Grafik, Framework ile birlikte paketlenen Observable Plot ile render edilir
  • Paket listesi, Datasette’in /content veritabanına doğrudan SQL sorgusu çalıştırılarak alınır
    • Sorgu select package from stats group by package order by max(downloads) desc
    • _shape=arrayfirst, sonuç satırlarının ilk sütununu JSON dizisi olarak almak için kullanılan kısa bir yoldur

Yalnızca kullanılan kodu dahil etme

  • Örnek pano Inputs, d3, Plot gibi ek kütüphaneler kullanır
  • Geliştirme modunda tembel yükleme uygulanır
    • Kod yalnızca bir hücrede ilk kez kullanılmak istendiğinde yüklenir
  • Uygulamayı derleyip dağıttığınızda Framework, yalnızca referans verilen kütüphane kodunu jsdelivr CDN üzerinden otomatik olarak yükler

Derleme zamanında veri önbelleğe alma

  • Framework’ün Data loader özelliği, pano verilerini derleme zamanında hazırlama işlevi sunar
  • Framework panoları çalışma zamanında fetch() veya onun sarmalayıcılarını kullanarak her yerden veri alabilir
    • Observable Notebooks da aynı şekilde çalışır
    • Bu yaklaşımda pano performansı bağlı olunan backend’e bağlıdır
  • Framework, dağıtım sırasında pano verilerini oluşturup yalnızca gerekli veri alt kümelerini statik dosyalar halinde paketleme desenini önerir
    • Statik veri dosyaları, pano koduyla aynı statik hosting üzerinden hızlıca sunulabilir
  • Data loader, herhangi bir programlama dilinde yazılmış bir betiktir
    • Derleme sırasında Framework betiği çalıştırır
    • Betiğin standart çıktı sonucunu dosya olarak kaydeder
  • Örnek, quakes.json.sh dosyasına curl https://earthquake.usgs.gov/earthquakes/feed/… koyma şeklindedir
    • Derleme sırasında dosya adı, hedef dosyanın quakes.json ve çalıştırılacak loader’ın .sh olduğunu Framework’e bildirir
  • Standart çıktıya JSON, CSV veya kullanışlı bir format basabiliyorsa verileri herhangi bir teknolojiyle alabilirsiniz

Observable Notebooks ile farkları

  • Observable Framework, Observable Notebooks’un birçok fikrini ve kodunu yeniden kullanır; ancak dosya biçimi ve çalışma ortamı açısından büyük farklar vardır
  • Mevcut Observable Notebooks, Jupyter Notebooks ile karşılaştırıldığında şu özelliklere sahiptir
    • Python değil JavaScript kullanır
    • Notebook editörünün kendisi açık kaynak değildir ve observablehq.com üzerinde sunulan barındırılan bir üründür
    • Notebook’lar statik dosya olarak dışa aktarılıp her yerde çalıştırılabilir, ancak editör tescilli bir üründür
    • Hücreler reaktiftir; bir hücre değiştiğinde ona bağımlı diğer hücreler Excel’de olduğu gibi otomatik yeniden değerlendirilir
    • Reaktiflik modelini desteklemek için viewof adlı özel bir anahtar sözcük oluşturulduğundan JavaScript sözdizimi tamamen standart değildir
    • Düzenlenebilir notebook’lar karmaşık, tescilli bir dosya biçimindedir ve Git gibi araçlarla iyi uyum sağlamadığından Observable kendi sürüm yönetimi ve iş birliği sistemini uygular
  • Observable Framework bu modeli daha basit bir dosya biçimine ve açık kaynaklı bir çalışma ortamına taşır
    • Belgeler, JavaScript blokları içeren tek bir Markdown dosyasıdır
    • Hâlâ reaktiftir, ancak herhangi bir metin editörüyle düzenlenebilir ve Git’e eklenebilir
    • Tamamı ISC lisanslı açık kaynaktır ve tüm düzenleme yığınını yerel makinede çalıştırabilirsiniz
    • Özel sözdizimi olmadan yalnızca standart JavaScript kullanır

Observable’ın yön değişimi

  • Observable Framework, Observable’ın mevcut tescilli Observable Notebook editörü merkezli iş birliği aracından geliştirici araçlarına doğru daha fazla eğildiği bir değişim gibi görünüyor
  • Observable’ın Twitter tanıtım metni “The end-to-end solution for developers who want to build and host dashboards that don’t suck” şeklindedir
    • 3 Ekim 2023 tarihli Internet Archive kopyasında “Build data visualizations, dashboards, and data apps that impact your business — faster.” yazıyordu
  • Observable Notebooks’un kullanımı, platformun tescilli yapısı ve ücretsiz hesap sınırlamaları, özellikle de ücretsiz gizli notebook bulunmaması nedeniyle kısmen sınırlı olabilir
  • Observable Plot gibi açık kaynaklı kütüphaneler, hâlihazırda etkin biçimde kullanılabilecek teknolojiler olarak değerlendiriliyor
  • Observable Framework, Observable Notebooks’u cazip kılan fikirleri açık kaynak, standart JavaScript, tek metin dosyası ve statik dağıtım modeliyle yeniden hayata geçiriyor

1 yorum

 
GN⁺ 2024-03-04
Hacker News yorumları
  • Bir açıdan Observable Framework, Mike Bostock sinematik evreninin Avengers: Endgame'i gibi
    d3, Observable, Observable Plot ve HTL'yi bir araya getiriyor; üstüne epey yeni fikir de ekliyor

    • Kişisel olarak Polymaps hâlâ onun işleri arasında en sevdiğim
    • “İnsanla güçlendirilmiş” yapay zeka geliştirici ajanları için bir şey yapıyormuş gibi hissettiriyor
      Observable'da zaten yapay zeka entegrasyonu var; bu da yapay zekanın daha kolay birleştirip kullanabilmesini sağlayan bir sarmalayıcı gibi görünüyor. Stratejiyi yapay zeka olmadan değerlendirdikleri kısım biraz tuhaf geldi
    • Daha önce Observable ve Observable Framework'ü yer imlerine eklemiştim ama ayrıntılı bakmamıştım
      Bugün statik Jupyter Notebook barındırmanın ya da WASM ile etkileşimli olarak çalıştırmanın yollarına bakmaya başladım; çoğu kullanım için Observable Framework daha uygun olacak gibi
  • Observable'ın sorunu, d3 örnek galerisi gibi görünmesine rağmen kodun o framework içinde çalışacak şekilde tasarlanmış olması; bu yüzden doğrudan kopyalayıp yapıştıramıyorsunuz
    d3 zaten örneksiz kullanması kolay bir şey değil; özellikle sürümler arası değişikliklerin uyumsuz olduğu durumlar da çok. Yine de sitede çok etkileyici grafikler var
    [0] https://observablehq.com/@d3/gallery

    • %100 katılıyorum. Gerçek JavaScript'ten biraz farklı olması benim için bir türlü aşamadığım noktaydı
      Temel dile yeterince yakın; grafik gösterimi için API'ye biraz ekleme yapıp düz JavaScript kullanmak da mümkün olabilirmiş gibi geliyor
    • Toplulukta Observable tarzı JavaScript'i normal JavaScript'e dönüştürmek için yayımlanmış bir kaynak vardı
      Çoğunlukla üst seviye hücre tanımlarını yeniden yazma işi
      [0]: https://observablehq.com/@bumbeishvili/convert-observable-co...
    • Bu nokta inanılmaz can sıkıcı. Herhangi bir şirketin gurur duyacağı türden bir platform bağımlılığı gibi hissettiriyor
      ObservableHQ notebook'larında bu konuda özellikle çok şikâyetçiydim. Harika örneklerken aynı anda işe yaramaz materyale dönüşüyorlar. Yine de bu Framework tarafı biraz daha açık görünüyor; en azından kendi sunucunda barındırmak mümkün, bu yüzden izliyorum
    • Bu Observable'ın sorunundan çok, d3'nin başka yerlere kopyalanıp yapıştırılabilecek örnekler sunmaması gibi görünüyor
      Üstelik bu yazı, yeni Observable Framework'ün eski Observable notebook'larının bazı sorunlarını ortadan kaldırdığını anlatıyor; dolayısıyla bu yorum yazıyla biraz alakasız kalıyor. Artık “tamamı standart JavaScript, özel sözdizimi yok” tarzında
  • Framework'ü GitHub Pages'a dağıtmak da çok kolay
    Adımları ve örnek bir GitHub Action'ı derledim: https://notes.billmill.org/programming/observable_framework/...

  • Yazar Framework hakkında tam isabet etmiş
    Observable Framework kullanarak küçük bir etkileşimli çizim yaptım (https://github.com/willmeyers/observable-ssta); kurulumu yapmak ve veriyi çizdirmek inanılmaz derecede kolaydı. Tek şikâyetim, Python veri yükleyicisinin virtualenv kullanacak şekilde ayarlanabilmesini isterdim

    • Python veri yükleyicilerini poetry ile, poetry tarafından yönetilen virtualenv içinde çalıştıran bir yapılandırma kullanıyorum
      Python projesini oluşturduktan sonra geliştirme sunucusunu başlatırken yarn run dev yerine poetry run yarn run dev çalıştırırsanız Python virtualenv içinde çalışır. Bu kurulum, veri yükleyicide yeniden kullanılabilir ve birim test edilebilir kodu özel bir Python paketi olarak tanımlayıp sonra *.json.py dosyalarında import ederek çok basit tutmanıza imkân veriyor
    • Python'daki nodeenv ile çözülemez mi? Bir projeye JS eklerken genelde öyle yapıyorum
      node ve npm/yarn gibi araçlar, hatta JavaScript bile venv içinde birlikte tutuluyor
    • .sh veri yükleyicisine shebang koyup sanal ortam dizinindeki bin/python için tam yolu gösteremez misiniz?
  • Kısa süre önce Observable notebook ile ilk “gerçek” projemi tamamladım
    Observable Plot ve Arquero'yu öğrenmeyi, JavaScript'in bir kısmını yeniden hatırlamayı ve veri üretim süreci olan Rust tabanlı simülatörle entegrasyonu içeriyordu. Dürüst olmak gerekirse gerçekten harikaydı. Araçları öğrenmek epey enerji aldı ve veri üreticisini parametreleştirme özelliği hâlâ eksik hissettiriyor ama nihai notebook güzel ve iyi çalışıyor
    Markdown ve reaktiviteyi kullanınca bu tür notebook'ların gerçekten kullanılabilir olduğunu hissettim. Jupyter'in özel formatı sürüm kontrolünü ciddi biçimde zorlaştırıyor; reaktivite olmayınca yinelemeli tasarlanmış bir notebook kolay yazılan ama okunması zor, durum tabanlı bir karmaşaya dönüşüyor. Quarto ve onun Observable entegrasyonuyla da denedim ama geçici çözümlerden oluşan bir yama işi gibiydi
    Samimiyetle söylüyorum, bir notebook yazıp başkalarıyla paylaşmanın keyifli ve heyecan verici olduğu ilk deneyimimdi. İleride daha pürüzlü noktalar olacaktır ama bu projeden sonra notebook araçları arasında ilk tercihim oldu

    • Quarto'ya alternatif arıyorsanız, tek bir kaynaktan reaktif/statik belgeler yazmayı sağlayan ve yakın zamanda yayımlanan Living Papers'a da bakabilirsiniz
      [0]: https://living-papers.vercel.app/)
  • Framework’ü tarayıcıda hızlıca denemek ve kurcalamak isterseniz, Node ve Python ortamlarını otomatik yapılandıran bir Codespace devcontainer hazırladım
    [0]: https://github.com/dleeftink/observable-codespace

  • Jupyter Notebook’tan Observable’a geçmeli miyiz? Yoksa ikisini bu şekilde ayırmak başlı başına yanlış bir çerçeve mi?

    • Sonuçta sorunun özünün, Python ve ekosisteminde mi daha üretken olduğunuz, yoksa JavaScript ve paketlerinde, özellikle de D3 gibi şeylerde mi daha üretken olduğunuz olduğunu düşünüyorum
  • Yazıdaki ifadeyi başka şekilde söylersek, js içerik ipucu bulunan kod bloklarındaki her şey kullanıcının tarayıcısında hemen çalıştırılıyor
    Kodu göstermek için js echo ipucunu kullanmak gerekiyor. Geriye dönük uyumluluğu düşününce bunun tersi daha iyi olmaz mıydı? Örneğin kullanıcının tarayıcısında çalışacak kodlar js exec gibi opt-in bir ipucuyla belirtilir, yaygın kullanılan js ipucu ise olduğu gibi kalırdı. Mevcut yapıda, o renderer’ı mevcut bir uygulamaya entegre ederken nerede çalıştırmaya izin verileceğini ayrıca yönetmek gerekiyor

    • Blokların varsayılan seçeneklerini değiştirmeyi mümkün kılmayı planlıyoruz
      Bunu sayfa bazında front matter içinde yapabilecek ya da proje ayarıyla tüm projeye uygulayabileceksiniz. Böylece js run=false varsayılan yapılabilir ve yalnızca istendiğinde js run ile canlı kod açılabilir. Ancak bizim ana kullanım senaryomuz canlı kod olduğu için bunu varsayılan olarak seçtik
    • Doğru. Bu, GitHub’ın Mermaid diyagramlarını otomatik render etmesiyle aynı sorun
      Artık dil açıklamasını kaldırmadan Mermaid kod bloklarını düz metin olarak gösteremiyorsunuz
  • Observable Framework’e kapılıp bütün gece onunla uğraştım; çok iyiydi
    Neredeyse hiç engel çıkarmadı ve Google Maps geçmişimi ayrıntılı biçimde görselleştirip keşfedebildim. Veri yükleyici ortamıyla ilgili kısım çok net değildi ama Python’ı poetry ortamında çalıştırınca çözüldü
    Kotlin’i sevdiğim için Kotlin script’leri için de bir veri yükleyici yapmayı denedim, ama bazı pürüzler vardı. Kotlin, script dosya adının foo.main.kts olmasını bekliyor; Observable ise çalıştırılabilir shebang loader için foo.exe uzantısını bekliyor. Bu yüzden Kotlin script’ini çağıran bir proxy exe script’i oluşturdum, ama bu durumda verinin otomatik yeniden yüklenmesi tetiklenmiyor
    marimo veya Jupyter ile kıyaslayınca biraz rahatsız edici olan noktalardan biri, veri yükleyici ile notebook arasında değişken kullanımı. Örneğin bir tarih seçme view bileşeniyle loader’ın getirdiği veri aralığını değiştirmek istiyorum, ama bunu nasıl yapacağım net değil. Bu da keşif amaçlı analizi biraz yavaşlatıyor. Bunun paradigmaya ters düştüğünü biliyorum ama belirtmek istedim. Sonuçta keşif yaparken veri işlemenin önemli bir kısmını notebook’a taşıyabilirsiniz; bu da performans açısından ideal değil
    Son olarak veri yükleyicileri inline olarak tanımlayabilmek güzel olurdu. Tek dosyayı seviyorum; bir Python kod bloğu eklediğimde Framework’ün bunu dosya olarak çıkarması küçük bir yaşam kalitesi iyileştirmesi olurdu. Henüz erken ama Framework umut verici görünüyor. Tüm Markdown notlarımı buraya koyup tam anlamıyla Emacs’e gitmeden org-mode benzeri bir ortam oluşturabilsem güzel olurdu

    • Geri bildirim için teşekkürler. .sh veya .exe ile dolanmadan yeni yorumlayıcıları daha kolay kaydetmeyi sağlayan bir PR açık
      Belirli bir dosya uzantısıyla ilişkilendirilmiş yorumlayıcıyı belirtebileceksiniz. Örneğin Kotlin için .kts mümkün olacak. https://github.com/observablehq/framework/pull/935
      Veri yükleyicileri girdilerle çalıştırma yaklaşımı, Framework’ün statik veri snapshot’larını tercih etmesiyle biraz farklı bir çizgide. Amaç, build edilmiş sitenin kendi kendine yeterli ve performanslı olması. Yine de iyi işleyen bir teknik, veri yükleyicide etkileşime girmek istediğiniz verinin üst kümesini Parquet dosyası olarak üretmek ve istemci tarafında DuckDB/SQL ile görselleştirilecek alt kümeyi seçmek. Genelde performansı iyi oluyor ama elbette ele almak istediğiniz üst kümenin boyutuna bağlı
  • Observable, REST API üzerinden ClickHouse ile çok iyi entegre oluyor
    Örnek burada: https://observablehq.com/@stas-sl/github-issues-survival-ana...
    Yeni Observable Framework’ü henüz denemedim ama veritabanını gerçek zamanlı sorgulayan benzer örnekleri görmek ilginç olurdu. Yapının yalnızca tüm verileri önceden yükleyip cache’lemeye izin veren bir şey olmamasını umuyorum. Böyle uygulamalar etkileşimli olmalı; ideal olarak SQL’i canlı düzenlenebilir şekilde sunmalı