Plotly Dash Multi Page App Yapmak

Baysan
5 min readOct 3, 2020

Merhabalar, iş gereği bu aralar Plotly Dash’i kurcalamaya başladım. Bu yazımda da Dash kullanarak birden fazla sayfaya sahip uygulamayı nasıl yapabiliriz kısaca onu göstermeye çalışacağım.

Dash ile çok sayfalı bir uygulama yapmak için temel mantığı anlamamız yeterli olacaktır. Bu sayede aşağıdakilerden veya benim yapmaya çalıştığım yapıdan daha farklı/kullanışlı/hızlı bir yapı kurabilirsiniz. Peki nedir bu temel mantık?

Temel Mantık

Dash’in mantığından ziyade çok sayfalı uygulamanın mantığını anlatmaya çalışacağım. Temel Dash mantığı için buraya ve buraya bakabilirsiniz.

Hepimizin bildiği gibi bir Dash projesine başlarken ilk önce Dash sınıfından bir instance üretiyoruz ve bu instance’in üzerine projemizi inşa ediyoruz. Dash ile 3 adet dashboard hazırladığımızı varsayarsak muhtemelen ayrı ayrı 3 adet app.py’a sahip olacağız.

Çok sayfalı bir uygulama yapmak istersek bir adet app.py oluşturacağız ve direkt app.layout’u set etmeyeceğiz. Bu app bizim serverimiz olacak. Her dashboard için ayrı ayrı layout tanımlayacağız fakat bunlar birer Dash instance’i olmayacak. dash_core_components, dash_html_components veya dash_bootstrap_components altından gelen instance’lar olacaklar. Daha sonra url path’ine göre app’imizin layout’unu eşleşen layout ile güncelleyeceğiz. Tek bir app.py fakat her sayfa için ayrı birer layout olarak düşünebiliriz.

Aşağıda elimden geldiğince detaylı olarak anlatmaya çalıştım, kafamızda önceden fikir oluşması için kodu burada paylaşıyorum. “Tek app.py birden fazla layout”

Klasör Yapısı

Öncelikle klasör yapısını belirlememizde fayda var. Bunun için biraz araştırma yapabildim ve 2 farklı yöntem buldum.

  • İlk yöntem Dash’in official dökümantasyonunda belirtilen bu yöntem
  • İkincisi ise Stackoverflow’da paylaşılan bu yöntem

İkisini harmanlamaya çalıştım ve biraz minimal bir farkla başka bir yapı kurabildim. Benim için daha rahat oldu sizin için zor veya gereksiz olduğunu düşünüyorsanız temel mantığı baz alarak kendi yapınızı oluşturabilirsiniz.

Dosyaları İnceleyelim

app.py

Bu dosya içerisinde server’i oluştururuz ve projeyi bunun üzerine inşa ederiz. Standart bir Dash uygulamasında dbc’nin import edilmesi gerekmez fakat ben bu örnekte dash bootstrap’i denemek istemiştim.

Gördüğümüz gibi henüz app’in layout’unu set etmedik. Bunu route’a göre index.py içerisinde set edeceğiz.

index.py

Bu dosya içerisinde (kök dizinde) route işlemlerimizi gerçekleştiriyoruz.

dcc.Location için daha detaylı bilgiye buradan ulaşabiliriz. Kısaca özet geçmek gerekirse bu component sayesinde url bilgilerini alabiliyoruz diyebiliriz.

app’imize bir callback yazıyoruz. Buradaki önemli nokta şu ki yazdığımız tüm dashboard’lar, callback’ler aynı app üzerinde olmalıdır. Ve tabii ki bu app project_name/app.py içerisinde app = dash.Dash()’in ta kendisi.

Input’u Location componentinin pathname’inden alıyoruz. Bize 127.0.0.1:8050'den sonrasını verir.

  • 127.0.0.1:8050/ -> /
  • 127.0.0.1:8050/apps/covid19 -> /apps/covid19

Aldığımız Input’u app’in layout’u içerisindeki Div’e output olarak veriyoruz. callback fonksiyonumuz sayesinde route’a göre bir layout alıp return ediyorduk. Bu sayede dinamik olarak layout’u güncelleyebileceğiz.

urls.py

Bu dosya içerisinde de route şemalarımızı belirleyeceğiz. Aslında bu işlemi index.py içerisinde if blokları ile hallediyorlardı. 2–3 route için hızlı bir şekilde bizi çözüme götürür fakat ben önümdeki proje için 20–25 route yazacağımı düşünerek bu dosyayı oluşturmaya karar verdim. Bu sayede sadece URL_PATHS içerisinde sözlük olarak şemalarımı belirtmem yetecek (umarım).

get_layout fonksiyonu parametre olarak gelen pathname’i URL_PATHS’in elemanlarının path’i içerisinde arıyor ve eşleşen elemanın layout’unu return ediyor. Bu fonksiyon index.py içerisindeki callback’de kullanılıyor. Location’dan gelen path’i buraya parametre olarak yolluyoruz. Eğer ilgili path bulunamazsa components/error_404.py return ediliyor.

Layoutları ise en üstte gördüğümüz gibi; Django’da view import edermiş gibi apps/app_name/ altındaki app_name.layout’u çağırarak sözlüğe ekliyoruz. Bu sayede direkt objeyi eklediğimizden return ederken layout nesnesini return etmiş oluyoruz.

get_app_names ve get_paths fonksiyonlarını navbar, sidebar vb. componentlerim olursa diye yazmıştım. Otomatik olarak liste halinde mevcut route’larımı listelerim diye düşünmüştüm. Henüz kullanmadım.

components/

Bu klasörü altında kendime ait componentleri tutmak için oluşturdum. Navbar, sidebar, footer vb.

Bu örnekte 404 sayfasını ve anasayfa’yı göstereceğim.

components/error_404.py

urls.py altında get_layout fonksiyonu ilgili path’i bulamazsa bu layout’u dönüyor demiştik.

components/index.py

Bu dosya ise proje ilk açıldığında dönecek olan layout’u tutuyor. Yani projemizin anasayfasını.

Proje ilk ayağa kalktığında kök içerisindeki index.py’da callback’e ilk önce ‘/’ pathname’i geliyor ve callback get_layout fonksiyonunu çağırıp bu path’i aratıyor. URL_PATHS içerisinde ‘/’ path’ini set etmiştik ve layout’u burayı gösteriyor.

Bu arada Dash Bootstrap Component’ine göz gezdirmenizi öneririm.

assets/

Bu klasör static dosyalar için Dash tarafından otomatik olarak aranan klasördür. Altına favicon.ico adında bir dosya koyarsak favicon’u set edecektir.

apps/

Bu klasör app’lerimi (dashboard) barındıracağım klasördür. Altında her app’e özel bir klasör oluşturup app layoutlarını yazıyorum.

  • covid19/
  • covid19/app.py # bu app’in layout’u
  • covid19/mydata.py # bu dashboard veriyi requests paketi ile alıyordu, eğer csv dosyası varsa onu koyabilirsiniz. Size kalmış.

apps/covid19

Bu klasör ise bu örnekte kullandığım covid19 dashboard’ının layout’unu tutuyor. İçerisindeki mydata.py ise verisetini requests ile aldığım dosya.

apps/covid19/mydata.py

Bu dosya içerisinde de kök dizindeki app.py içerisindeki app’i import ediyoruz. Bu sayede yazdığımız callback’ler aynı app üzerinde olmuş oluyor.

apps/covid19/app.py

urls.py içerisinde de bu dosya içerisinde (apps/covid19/app.py) yazdığımız layout’u çağırıyoruz ve route şemamızı belirtiyoruz.

urls.py içerisinde ilgili dashboard’a ait route’u yazıyoruz

Her şey yolundaysa çok sayfalı uygulamamızı inşa etmiş bulunuyoruz. Artık diğer sayfaları da apps/ altında klasör oluşturduktan ve layout yazdıktan sonra (isterseniz oluşturmadan size kalmış) urls.py içerisinde URL_PATHS’e kaydedip kullanabiliriz.

Umarım faydalı olmuştur, elimden geldiğince anlatmaya çalıştım. Daha güzel bir yapı bulana kadar bunu kullanacağım. Sizin de önerileriniz varsa memnun olurum. İyi çalışmalar ^^

Flask ve Çok Sayfalı Dash projesi yapımına dair çektiğim videoya buradan ulaşabilirsiniz.

--

--

Baysan
Baysan

Written by Baysan

Lifelong learner & Developer. I use technology that helps me. mebaysan.com

No responses yet