dars-framework 1.9.7__tar.gz → 1.9.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dars_framework-1.9.8/PKG-INFO +668 -0
- dars_framework-1.9.8/README.md +625 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/all.py +26 -4
- dars_framework-1.9.8/dars/backend/http.py +224 -0
- dars_framework-1.9.8/dars/backend/middleware.py +82 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/backend/ssr.py +146 -26
- dars_framework-1.9.8/dars/backend/store.py +146 -0
- dars_framework-1.9.8/dars/backend/upload.py +148 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/main.py +237 -130
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/preview.py +3 -15
- dars_framework-1.9.8/dars/components/advanced/file_upload.py +80 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/__init__.py +9 -1
- dars_framework-1.9.8/dars/components/basic/each_component.py +166 -0
- dars_framework-1.9.8/dars/components/basic/if_component.py +150 -0
- dars_framework-1.9.8/dars/components/basic/show_component.py +125 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/config.py +7 -0
- dars_framework-1.9.8/dars/env.py +132 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/html_css_js.py +233 -42
- dars_framework-1.9.8/dars/exporters/web/resources/dap.js +885 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/resources/ssr.js +19 -6
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/__init__.py +11 -1
- dars_framework-1.9.8/dars/hooks/form_helpers.py +230 -0
- dars_framework-1.9.8/dars/hooks/form_validator.py +621 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/set_vref.py +3 -1
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/update_vref.py +32 -0
- dars_framework-1.9.8/dars/hooks/use_fetch.py +150 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/scripts/dscript.py +48 -2
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/scripts/utils_ds.py +64 -1
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/version.py +2 -2
- dars_framework-1.9.8/dars_framework.egg-info/PKG-INFO +668 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars_framework.egg-info/SOURCES.txt +8 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars_framework.egg-info/requires.txt +2 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/pyproject.toml +2 -2
- dars_framework-1.9.7/PKG-INFO +0 -618
- dars_framework-1.9.7/README.md +0 -577
- dars_framework-1.9.7/dars/backend/http.py +0 -138
- dars_framework-1.9.7/dars/components/advanced/file_upload.py +0 -59
- dars_framework-1.9.7/dars/env.py +0 -26
- dars_framework-1.9.7/dars/exporters/web/resources/dap.js +0 -417
- dars_framework-1.9.7/dars/hooks/form_helpers.py +0 -302
- dars_framework-1.9.7/dars_framework.egg-info/PKG-INFO +0 -618
- {dars_framework-1.9.7 → dars_framework-1.9.8}/Dars-logo.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/LICENSE +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/MANIFEST.in +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/actionProtocol.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/backend/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/backend/components.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/backend/data.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/backend/json_utils.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/backend/route_loader.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/doctor/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/doctor/detect.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/doctor/doctor.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/doctor/installers.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/doctor/persist.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/doctor/preflight.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/doctor/ui.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/dpm.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/generate.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/hot_reload.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/prompts.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/cli/translations.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/accordion.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/card.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/head.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/modal.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/navbar.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/outlet.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/table.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/advanced/tabs.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/audio.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/button.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/checkbox.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/container.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/datepicker.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/image.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/input.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/link.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/markdown.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/page.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/progressbar.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/radiobutton.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/section.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/select.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/slider.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/spinner.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/text.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/textarea.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/tooltip.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/basic/video.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/layout/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/layout/anchor.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/layout/flex.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/layout/grid.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/visualization/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/visualization/chart.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/components/visualization/table.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/app.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/component.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/events.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/js_bridge.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/properties.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/route_types.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/routing.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/state.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/state_v2.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/core/utilities.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/dars_tests/apps_test/health_check.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/dars_tests/run_tests.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/dars_tests/tests/test_advanced_components.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/dars_tests/tests/test_basic_components.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/dars_tests/tests/test_layout_components.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/dars_tests/tests/test_version_check.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/desktop/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/desktop/api.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/desktop/js_generator.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/docs/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/docs/index.md +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/base.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/desktop/electron.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/resources/anim.js +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/resources/dars.min.js +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/resources/dompurify.js +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/resources/router.js +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/exporters/web/vdom.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/use_dynamic.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/use_value.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/use_vref.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/use_watch.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/hooks/value_helpers.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/scripts/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/scripts/animations.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/scripts/keycode.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/scripts/script.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/security.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/icon.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/backend/icons/icon.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/backend/main.js +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/backend/package.json +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/backend/preload.js +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/dars.config.json +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/icons/icon.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/main.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/public/electron-icon.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/desktop/template/public/icon.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/README.md +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/CustomComp/main.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/StateV2/README.md +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/StateV2/animation_component.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/StateV2/counter_component.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/StateV2/hero_component.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/StateV2/main.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/StateV2/styles.css +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/StateV2/timer_component.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/hooks/useDynamic.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/hooks/useValue.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/advanced/hooks/useWatch.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/basic/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars/templates/examples/markdown/__init__.py +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars_framework.egg-info/dependency_links.txt +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars_framework.egg-info/entry_points.txt +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/dars_framework.egg-info/top_level.txt +0 -0
- {dars_framework-1.9.7 → dars_framework-1.9.8}/setup.cfg +0 -0
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dars-framework
|
|
3
|
+
Version: 1.9.8
|
|
4
|
+
Summary: Dars is a Full-Stack multiplatform Python UI framework for building modern, interactive web and desktop apps with Python code. Seamlessly integrated with FastAPI, it allows you to build complete applications with Server-Side Rendering (SSR) and reactive SPA capabilities also classic multipage html and desktop apps in a single codebase.
|
|
5
|
+
Author-email: ztamdev <ztadevs@gmail.com>
|
|
6
|
+
Maintainer-email: ztamdev <ztadevs@gmail.com>
|
|
7
|
+
License-Expression: MPL-2.0
|
|
8
|
+
Project-URL: Homepage, https://ztamdev.github.io/Dars-Framework/
|
|
9
|
+
Project-URL: Documentation, https://ztamdev.github.io/Dars-Framework/docs.html
|
|
10
|
+
Project-URL: Repository, https://github.com/ZtaMDev/Dars-Framework
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/ZtaMDev/Dars-Framework/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/ZtaMDev/Dars-Framework/releases
|
|
13
|
+
Keywords: ui-framework,web-framework,python-ui,static-site-generator,html-css-js,reactive,components,spa,web-development,desktop-apps,electron
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
18
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
25
|
+
Classifier: Operating System :: OS Independent
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Classifier: Natural Language :: English
|
|
28
|
+
Requires-Python: >=3.11
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: rich==15.0.0
|
|
32
|
+
Requires-Dist: bs4==0.0.2
|
|
33
|
+
Requires-Dist: uvicorn==0.46.0
|
|
34
|
+
Requires-Dist: markdown2==2.5.5
|
|
35
|
+
Requires-Dist: requests==2.33.1
|
|
36
|
+
Requires-Dist: plotly==6.7.0
|
|
37
|
+
Requires-Dist: fastapi==0.136.1
|
|
38
|
+
Requires-Dist: rjsmin==1.2.5
|
|
39
|
+
Requires-Dist: rcssmin==1.2.2
|
|
40
|
+
Requires-Dist: starlette==0.47.3
|
|
41
|
+
Requires-Dist: python-multipart==0.0.28
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
<h1 align="center">Dars Framework</h1>
|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<img src="https://raw.githubusercontent.com/ZtaMDev/Dars-Framework/CrystalMain/Dars-logo.png" alt="Dars Framework Logo" width="200" />
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
<p align="center">
|
|
51
|
+
<img src="https://img.shields.io/pypi/v/dars-framework?color=brightgreen" alt="PyPI Version" />
|
|
52
|
+
<img src="https://img.shields.io/pypi/pyversions/dars-framework?color=blue" alt="Python Versions" />
|
|
53
|
+
<img src="https://img.shields.io/github/license/ZtaMDev/Dars-Framework" alt="License" />
|
|
54
|
+
<a href="https://deepwiki.com/ZtaMDev/Dars-Framework"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
<p align="center">
|
|
58
|
+
<em>Dars is a Full-Stack multiplatform Python UI framework for building modern, interactive web and desktop apps entirely in Python. Seamlessly integrated with FastAPI, it lets you build complete applications with Server-Side Rendering (SSR), reactive SPA routing, static site generation, and a production-ready backend API — all from a single Python codebase, with zero JavaScript required.</em>
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
<div align="center">
|
|
62
|
+
|
|
63
|
+
Official [Website](https://ztamdev.github.io/Dars-Framework/) |
|
|
64
|
+
Documentation [Docs](https://ztamdev.github.io/Dars-Framework/docs.html) |
|
|
65
|
+
Official [Roadmap](https://ztamdev.github.io/Dars-Framework/roadmap.html) |
|
|
66
|
+
Extension for VSCode [here](https://marketplace.visualstudio.com/items?itemName=ZtaMDev.dars-framework) and OpenVSX version [here](https://open-vsx.org/extension/ztamdev/dars-framework)
|
|
67
|
+
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install dars-framework
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Try Dars without installing anything — visit the [Dars Playground](https://dars-playground.vercel.app/)
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## How It Works
|
|
79
|
+
|
|
80
|
+
- Build your UI using Python classes and components (`Text`, `Button`, `Container`, `Page`, `Each`, `Show`, `If`, etc.).
|
|
81
|
+
- Preview instantly with hot-reload using `app.rTimeCompile()`.
|
|
82
|
+
- Export your app to static/dynamic/SSR web files with a single CLI command.
|
|
83
|
+
- Export to native desktop apps (BETA) using project config `format: "desktop"` and `dars build`.
|
|
84
|
+
- Use multipage layouts, scripts, hooks, and more — see docs for advanced features.
|
|
85
|
+
- **One app, four deployment targets simultaneously:** Dars supports Static Site Generation (SSG), Single-Page Application (SPA) routing, Server-Side Rendering (SSR) with FastAPI, and a full Backend API — all from the same Python codebase. Mix and match freely: export some pages as static HTML for SEO, serve others via SSR for dynamic content, and expose REST API endpoints alongside your UI.
|
|
86
|
+
- **Full backend toolkit included:** `useFetch` for declarative data fetching, `FormValidator` for client-side validation, `Each` for runtime list rendering from API responses, `JsonStore` for file-backed persistence, `UploadPipeline` for secure file uploads, `SecurityHeadersMiddleware` for HTTP security, and `DarsEnv` for `.env` file support.
|
|
87
|
+
- For more information visit the [Documentation](https://ztamdev.github.io/Dars-Framework/docs.html)
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Quick Example: Your First App
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from dars.all import *
|
|
95
|
+
|
|
96
|
+
app = App(title="Hello World", theme="dark")
|
|
97
|
+
|
|
98
|
+
# 1. Define State
|
|
99
|
+
state = State("app", title_val="Simple Counter", count=0)
|
|
100
|
+
|
|
101
|
+
# 2. Define Route
|
|
102
|
+
@route("/")
|
|
103
|
+
def index():
|
|
104
|
+
return Page(
|
|
105
|
+
Text(
|
|
106
|
+
text=useValue("app.title_val"),
|
|
107
|
+
style="fs-[33px] text-black font-bold mb-[5px]",
|
|
108
|
+
),
|
|
109
|
+
Text(
|
|
110
|
+
text=useDynamic("app.count"),
|
|
111
|
+
style="fs-[48px] mt-5 mb-[12px]"
|
|
112
|
+
),
|
|
113
|
+
Button(
|
|
114
|
+
text="+1",
|
|
115
|
+
on_click=state.count.increment(1),
|
|
116
|
+
style="bg-[#3498db] text-white p-[15px] px-[30px] rounded-[8px] cursor-pointer fs-[18px]",
|
|
117
|
+
),
|
|
118
|
+
Button(
|
|
119
|
+
text="-1",
|
|
120
|
+
on_click=state.count.decrement(1),
|
|
121
|
+
style="bg-[#3498db] text-white p-[15px] px-[30px] rounded-[8px] cursor-pointer fs-[18px] mt-[5px]",
|
|
122
|
+
),
|
|
123
|
+
Button(
|
|
124
|
+
text="Reset",
|
|
125
|
+
on_click=state.reset(),
|
|
126
|
+
style="bg-[#3498db] text-white p-[15px] px-[30px] rounded-[8px] cursor-pointer fs-[18px] mt-[5px]",
|
|
127
|
+
),
|
|
128
|
+
style="flex flex-col items-center justify-center h-[100vh] ffam-[Arial] bg-[#f0f2f5]",
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
app.add_page("index", index(), title="index")
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
app.rTimeCompile()
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## State Management System
|
|
140
|
+
|
|
141
|
+
Dars features a **powerful state management system** designed for different use cases.
|
|
142
|
+
|
|
143
|
+
### Hook-Based State Management
|
|
144
|
+
|
|
145
|
+
Modern, Pythonic state management for reactive updates. Best for counters, timers, and component interactions.
|
|
146
|
+
|
|
147
|
+
**Hooks System:**
|
|
148
|
+
|
|
149
|
+
- `useDynamic()`: Reactive state binding for automatic UI updates.
|
|
150
|
+
- `useValue()`: Set initial values from state (non-reactive).
|
|
151
|
+
- `useWatch()`: Monitor state changes and trigger side effects.
|
|
152
|
+
|
|
153
|
+
[Learn more about Hooks](https://ztamdev.github.io/Dars-Framework/docs.html#hooks-system)
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from dars.all import *
|
|
157
|
+
|
|
158
|
+
app = App("State Demo")
|
|
159
|
+
state = State("counter", count=0)
|
|
160
|
+
|
|
161
|
+
@route("/")
|
|
162
|
+
def index():
|
|
163
|
+
return Page(
|
|
164
|
+
Text(text=useDynamic("counter.count"), style="fs-[24px]"),
|
|
165
|
+
Button("Increment", on_click=state.count.increment(1)),
|
|
166
|
+
Button("Decrement", on_click=state.count.decrement(1)),
|
|
167
|
+
Button("Reset", on_click=state.count.set(0)),
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
app.add_page("index", index())
|
|
171
|
+
|
|
172
|
+
if __name__ == "__main__":
|
|
173
|
+
app.rTimeCompile()
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
> [!WARNING]
|
|
177
|
+
> **Important:** When using hooks, the State ID is used for binding. **Do not use an ID that belongs to another unrelated component**, as hooks use this ID as the State ID. Using a conflicting ID may cause unexpected behavior or state collisions.
|
|
178
|
+
|
|
179
|
+
For detailed documentation, visit the [State Management Guide](https://ztamdev.github.io/Dars-Framework/docs.html#state-management-in-dars).
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Animation System
|
|
184
|
+
|
|
185
|
+
Dars includes **15+ built-in animations** that work seamlessly with state management:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from dars.all import fadeIn, fadeOut, pulse, shake, sequence
|
|
189
|
+
|
|
190
|
+
# Single animation
|
|
191
|
+
button.on_click = fadeIn(id="modal", duration=500)
|
|
192
|
+
|
|
193
|
+
# Chain multiple animations
|
|
194
|
+
button.on_click = sequence(
|
|
195
|
+
fadeIn(id="box"),
|
|
196
|
+
pulse(id="box", scale=1.2, iterations=2),
|
|
197
|
+
shake(id="box", intensity=5)
|
|
198
|
+
)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Available Animations:** `fadeIn`, `fadeOut`, `slideIn`, `slideOut`, `scaleIn`, `scaleOut`, `pulse`, `shake`, `bounce`, `rotate`, `flip`, `colorChange`, `morphSize`, `popIn`, `popOut`
|
|
202
|
+
|
|
203
|
+
For complete animation documentation, visit the [Animation Guide](https://ztamdev.github.io/Dars-Framework/docs.html#dars-animation-system).
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Routing System (SPA & SSR)
|
|
208
|
+
|
|
209
|
+
Dars offers a flexible routing system supporting Client-Side Routing (SPA), Server-Side Rendering (SSR), and Static Site Generation — all in one app.
|
|
210
|
+
|
|
211
|
+
### Server-Side Rendering (SSR)
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from dars.all import *
|
|
215
|
+
|
|
216
|
+
@route("/dashboard", route_type=RouteType.SSR)
|
|
217
|
+
def dashboard():
|
|
218
|
+
return Page(
|
|
219
|
+
Text("Server-Side Rendered Page"),
|
|
220
|
+
Button("Click Me", on_click=alert("Hello from Client")),
|
|
221
|
+
)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Client-Side Routing (SPA)
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
@route("/")
|
|
228
|
+
def home():
|
|
229
|
+
return Page(Text("Home Page"))
|
|
230
|
+
|
|
231
|
+
@route("/about")
|
|
232
|
+
def about():
|
|
233
|
+
return Page(Text("About Us"))
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Nested Routes with Outlet
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
@route("/dashboard")
|
|
240
|
+
def dashboard():
|
|
241
|
+
return Page(
|
|
242
|
+
Text("Dashboard", style="fs-[24px]"),
|
|
243
|
+
Container(
|
|
244
|
+
Link("Settings", href="/dashboard/settings"),
|
|
245
|
+
Link("Profile", href="/dashboard/profile"),
|
|
246
|
+
),
|
|
247
|
+
Outlet(),
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
app.add_page("dashboard", dashboard(), index=True)
|
|
251
|
+
app.add_page("settings", settings_page, route="/dashboard/settings", parent="dashboard")
|
|
252
|
+
app.add_page("profile", profile_page, route="/dashboard/profile", parent="dashboard")
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### 404 Error Handling
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
app.set_404_page(Page(
|
|
259
|
+
Text("Page not found", style="fs-[32px] text-red-500"),
|
|
260
|
+
Link("Go Home", href="/"),
|
|
261
|
+
))
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Custom Components
|
|
267
|
+
|
|
268
|
+
### Function Components
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from dars.all import *
|
|
272
|
+
|
|
273
|
+
@FunctionComponent
|
|
274
|
+
def UserCard(name, email, **props):
|
|
275
|
+
return f"""
|
|
276
|
+
<div {Props.id} {Props.class_name} {Props.style}>
|
|
277
|
+
<h3>{name}</h3>
|
|
278
|
+
<p>{email}</p>
|
|
279
|
+
<div class="card-body">{Props.children}</div>
|
|
280
|
+
</div>
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
card = UserCard("John Doe", "john@example.com", id="user-1", style="p-[20px]")
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Control Flow Components
|
|
289
|
+
|
|
290
|
+
### `Show` — Runtime Visibility Toggle
|
|
291
|
+
|
|
292
|
+
Always renders children into the DOM. A falsy VRef condition hides the wrapper with `display:none`. Reacts to VRef changes at runtime — perfect for loading spinners, error banners, and any UI that toggles based on live state.
|
|
293
|
+
|
|
294
|
+
```python
|
|
295
|
+
from dars.all import *
|
|
296
|
+
|
|
297
|
+
is_loading = setVRef(True, ".loading")
|
|
298
|
+
has_error = setVRef(False, ".error")
|
|
299
|
+
|
|
300
|
+
Show(
|
|
301
|
+
is_loading,
|
|
302
|
+
Container(Spinner(), Text("Loading…"), style="flex items-center gap-2"),
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
Show(
|
|
306
|
+
has_error,
|
|
307
|
+
Container(
|
|
308
|
+
Text("Something went wrong.", style="text-red-600"),
|
|
309
|
+
style="bg-red-50 border rounded p-3",
|
|
310
|
+
),
|
|
311
|
+
)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### `Each` — List Rendering from Python or API
|
|
315
|
+
|
|
316
|
+
Renders a list using a template function. Works with both compile-time Python lists and runtime VRef arrays (e.g. from `useFetch`).
|
|
317
|
+
|
|
318
|
+
**Compile-time list:**
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
users = [{"name": "Alice"}, {"name": "Bob"}]
|
|
322
|
+
|
|
323
|
+
Each(items=users, render=lambda u: Text(u["name"]))
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Runtime VRef list (from API):**
|
|
327
|
+
|
|
328
|
+
The render function is called at export time with a sentinel dict containing `__item_<field>__` placeholders. At runtime, `dom_each_render` substitutes real values for each item. Use `__item_done_class__` to get `"line-through text-gray-400"` for done items automatically.
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
tasks_vref = setVRef([], ".tasks-data") # filled by useFetch
|
|
332
|
+
|
|
333
|
+
def task_item(t):
|
|
334
|
+
title = t.get("title", "__item_title__") if isinstance(t, dict) else "__item_title__"
|
|
335
|
+
item_id = t.get("id", "__item_id__") if isinstance(t, dict) else "__item_id__"
|
|
336
|
+
return Container(
|
|
337
|
+
Text(title, style="flex: 1 1 0%", class_name="__item_done_class__"),
|
|
338
|
+
Text(f"#{item_id}", style="text-xs text-gray-400 ml-2"),
|
|
339
|
+
style="flex items-center gap-2 p-2 border rounded bg-white shadow-sm",
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
Each(items=tasks_vref, render=task_item, class_name="space-y-1 mb-6")
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Supported API response shapes are automatically unwrapped: `{"tasks":[...]}`, `{"items":[...]}`, `{"data":[...]}`, `{"results":[...]}`, or a plain `[...]` array.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Backend & API Communication
|
|
350
|
+
|
|
351
|
+
Dars ships a complete production-grade backend toolkit. Everything is pure Python — no JavaScript required.
|
|
352
|
+
|
|
353
|
+
### `useFetch` — Declarative Data Fetching
|
|
354
|
+
|
|
355
|
+
Fetch data from any API and bind the response to reactive VRefs automatically:
|
|
356
|
+
|
|
357
|
+
```python
|
|
358
|
+
from dars.all import *
|
|
359
|
+
|
|
360
|
+
tasks_sel = ".tasks-data"
|
|
361
|
+
_tasks = setVRef([], tasks_sel)
|
|
362
|
+
|
|
363
|
+
trigger, loading, data, error = useFetch(
|
|
364
|
+
"/api/tasks",
|
|
365
|
+
on_success=runSequence(
|
|
366
|
+
updateVRef(".loading", False),
|
|
367
|
+
updateVRefFromResponse(tasks_sel), # stores API response → VRef
|
|
368
|
+
),
|
|
369
|
+
on_error=runSequence(
|
|
370
|
+
updateVRef(".loading", False),
|
|
371
|
+
updateVRef(".error", True),
|
|
372
|
+
),
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
page = Page(
|
|
376
|
+
Show(loading, Spinner()),
|
|
377
|
+
Show(error, Text("Could not load tasks.", style="text-red-500")),
|
|
378
|
+
Each(items=_tasks, render=lambda t: Container(
|
|
379
|
+
Text(t.get("title", "__item_title__"), style="flex-1"),
|
|
380
|
+
Text(f"#{t.get('id', '__item_id__')}", style="text-xs text-gray-400"),
|
|
381
|
+
style="flex gap-2 p-2 border rounded bg-white",
|
|
382
|
+
)),
|
|
383
|
+
Button("↻ Refresh", on_click=trigger),
|
|
384
|
+
)
|
|
385
|
+
page.add_script(trigger) # auto-run on page load
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### `FormValidator` — Client-Side Validation
|
|
389
|
+
|
|
390
|
+
Validate forms before submitting — rules declared once in Python, enforced both client-side and server-side:
|
|
391
|
+
|
|
392
|
+
```python
|
|
393
|
+
validator = FormValidator({
|
|
394
|
+
"email": [required(), email()],
|
|
395
|
+
"password": [required(), min_length(8)],
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
submit = validator.validated_submit(
|
|
399
|
+
url="/api/login",
|
|
400
|
+
form_data=collect_form(email=V("#email"), password=V("#password")),
|
|
401
|
+
on_success=goTo("/dashboard"),
|
|
402
|
+
on_error=setText("error-msg", "Login failed."),
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
page = Page(
|
|
406
|
+
Input(id="email", placeholder="Email"),
|
|
407
|
+
Text("", id="email-error", style="text-red-500 text-sm"),
|
|
408
|
+
Input(id="password", placeholder="Password"),
|
|
409
|
+
Text("", id="password-error", style="text-red-500 text-sm"),
|
|
410
|
+
Text("", id="error-msg", style="text-red-500 text-sm"),
|
|
411
|
+
Button("Login", on_click=submit),
|
|
412
|
+
)
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### `JsonStore` — File-Backed Persistence
|
|
416
|
+
|
|
417
|
+
Thread-safe, atomic-write JSON storage for rapid prototyping and small backends:
|
|
418
|
+
|
|
419
|
+
```python
|
|
420
|
+
from dars.backend.store import JsonStore
|
|
421
|
+
|
|
422
|
+
store = JsonStore("tasks.json", default={"tasks": []})
|
|
423
|
+
|
|
424
|
+
tasks = store.get("tasks", [])
|
|
425
|
+
tasks.append({"id": 1, "title": "New task", "done": False})
|
|
426
|
+
store.set("tasks", tasks)
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### `UploadPipeline` — Secure File Uploads
|
|
430
|
+
|
|
431
|
+
```python
|
|
432
|
+
from dars.backend.upload import UploadPipeline
|
|
433
|
+
|
|
434
|
+
pipeline = UploadPipeline(
|
|
435
|
+
upload_dir="uploads",
|
|
436
|
+
allowed_types=["image/png", "image/jpeg", "application/pdf"],
|
|
437
|
+
max_size_bytes=10 * 1024 * 1024,
|
|
438
|
+
)
|
|
439
|
+
pipeline.create_endpoint(app, path="/api/upload")
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Frontend component:
|
|
443
|
+
|
|
444
|
+
```python
|
|
445
|
+
FileUpload(
|
|
446
|
+
upload_url="/api/upload",
|
|
447
|
+
accepted_types=["image/png", "image/jpeg"],
|
|
448
|
+
max_size_bytes=5 * 1024 * 1024,
|
|
449
|
+
on_upload_complete=setText("status", "Uploaded!"),
|
|
450
|
+
on_upload_error=setText("status", "Upload failed."),
|
|
451
|
+
)
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### `SecurityHeadersMiddleware` — HTTP Security
|
|
455
|
+
|
|
456
|
+
```python
|
|
457
|
+
from dars.backend.ssr import SSRApp
|
|
458
|
+
|
|
459
|
+
ssr = SSRApp(dars_app, prefix="/api/ssr")
|
|
460
|
+
ssr.use_cors(origins=["http://localhost:4000"], credentials=True)
|
|
461
|
+
ssr.use_security_headers() # X-Frame-Options, CSP, HSTS, etc.
|
|
462
|
+
ssr.use_upload(upload_dir="uploads", allowed_types=["image/*"])
|
|
463
|
+
|
|
464
|
+
app = ssr.fastapi_app
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### `DarsEnv` — Environment Variables
|
|
468
|
+
|
|
469
|
+
```python
|
|
470
|
+
from dars.env import DarsEnv
|
|
471
|
+
|
|
472
|
+
DarsEnv.load() # loads .env silently if present
|
|
473
|
+
api_key = DarsEnv.get("API_KEY") # None if missing
|
|
474
|
+
secret = DarsEnv.require("SECRET") # raises KeyError if missing
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Full Backend API Example
|
|
478
|
+
|
|
479
|
+
```python
|
|
480
|
+
from dars.backend.ssr import SSRApp
|
|
481
|
+
from dars.backend.store import JsonStore
|
|
482
|
+
from main import app as dars_app
|
|
483
|
+
from fastapi import Request
|
|
484
|
+
from fastapi.responses import JSONResponse
|
|
485
|
+
import os
|
|
486
|
+
|
|
487
|
+
ssr = SSRApp(dars_app, prefix="/api/ssr")
|
|
488
|
+
ssr.use_cors(origins=["http://localhost:4000"], credentials=True)
|
|
489
|
+
ssr.use_security_headers()
|
|
490
|
+
|
|
491
|
+
app = ssr.fastapi_app
|
|
492
|
+
|
|
493
|
+
# ── Production: serve dist/ as static files with SPA fallback ───────────────
|
|
494
|
+
from backend.apiConfig import DarsEnv
|
|
495
|
+
if not DarsEnv.is_dev():
|
|
496
|
+
ssr.use_spa_fallback()
|
|
497
|
+
# ────────────────────────────────────────────────────────────────────────────
|
|
498
|
+
|
|
499
|
+
_store = JsonStore("tasks_db.json", default={"tasks": []})
|
|
500
|
+
|
|
501
|
+
@app.get("/api/tasks")
|
|
502
|
+
async def get_tasks():
|
|
503
|
+
return JSONResponse({"tasks": _store.get("tasks", [])})
|
|
504
|
+
|
|
505
|
+
@app.post("/api/tasks")
|
|
506
|
+
async def create_task(request: Request):
|
|
507
|
+
body = await request.json()
|
|
508
|
+
tasks = _store.get("tasks", [])
|
|
509
|
+
task = {"id": len(tasks) + 1, "title": body.get("title", ""), "done": False}
|
|
510
|
+
tasks.append(task)
|
|
511
|
+
_store.set("tasks", tasks)
|
|
512
|
+
return JSONResponse(task, status_code=201)
|
|
513
|
+
|
|
514
|
+
@app.put("/api/tasks/{task_id}")
|
|
515
|
+
async def update_task(task_id: int, request: Request):
|
|
516
|
+
body = await request.json()
|
|
517
|
+
tasks = _store.get("tasks", [])
|
|
518
|
+
for t in tasks:
|
|
519
|
+
if t["id"] == task_id:
|
|
520
|
+
t.update({k: v for k, v in body.items() if k != "id"})
|
|
521
|
+
_store.set("tasks", tasks)
|
|
522
|
+
return JSONResponse(t)
|
|
523
|
+
return JSONResponse({"error": "Not found"}, status_code=404)
|
|
524
|
+
|
|
525
|
+
@app.delete("/api/tasks/{task_id}")
|
|
526
|
+
async def delete_task(task_id: int):
|
|
527
|
+
tasks = [t for t in _store.get("tasks", []) if t["id"] != task_id]
|
|
528
|
+
_store.set("tasks", tasks)
|
|
529
|
+
return JSONResponse({"deleted": task_id})
|
|
530
|
+
|
|
531
|
+
if __name__ == "__main__":
|
|
532
|
+
import uvicorn
|
|
533
|
+
print("\n" + "=" * 60)
|
|
534
|
+
print("Dars Fullstack Backend")
|
|
535
|
+
print("=" * 60)
|
|
536
|
+
if DarsEnv.is_dev():
|
|
537
|
+
port, host = 3000, "127.0.0.1"
|
|
538
|
+
else:
|
|
539
|
+
port, host = 8000, "0.0.0.0"
|
|
540
|
+
print("=" * 60 + "\n")
|
|
541
|
+
uvicorn.run(app, host=host, port=port)
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
For complete backend documentation, see the [Backend & API Guide](https://ztamdev.github.io/Dars-Framework/docs.html#backend-http-utilities).
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## CLI Usage
|
|
549
|
+
|
|
550
|
+
| Command | What it does |
|
|
551
|
+
|---|---|
|
|
552
|
+
| `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
|
|
553
|
+
| `dars init --type desktop` | Scaffold desktop-capable project (BETA) |
|
|
554
|
+
| `dars init --type fullstack` | Scaffold full-stack project (SPA + SSR + API) |
|
|
555
|
+
| `dars build` (desktop config) | Build desktop app artifacts (BETA) |
|
|
556
|
+
| `dars preview` | Preview exported app (auto-detects output) |
|
|
557
|
+
| `dars preview --port 9000` | Preview on a custom port |
|
|
558
|
+
| `dars init my_project` | Create a new Dars project |
|
|
559
|
+
| `dars init --update` | Create/Update dars.config.json in current dir |
|
|
560
|
+
| `dars build` | Build using dars.config.json |
|
|
561
|
+
| `dars config validate` | Validate dars.config.json and print report |
|
|
562
|
+
| `dars info my_app.py` | Show info about your app |
|
|
563
|
+
| `dars formats` | List supported export formats |
|
|
564
|
+
| `dars dev` | Run the configured entry file with hot preview |
|
|
565
|
+
| `dars dev --port 9000` | Run dev server on a custom port |
|
|
566
|
+
| `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
|
|
567
|
+
| `dars generate component <name>` | Scaffold a new FunctionComponent |
|
|
568
|
+
| `dars generate page <name>` | Scaffold a new page (static, SPA, or SSR) |
|
|
569
|
+
| `dars --help` | Show help and all CLI options |
|
|
570
|
+
|
|
571
|
+
Tip: use `dars doctor` to review optional tooling that can enhance bundling/minification.
|
|
572
|
+
|
|
573
|
+
### Running with Backend
|
|
574
|
+
|
|
575
|
+
```bash
|
|
576
|
+
# Terminal 1 — Frontend dev server
|
|
577
|
+
dars dev
|
|
578
|
+
|
|
579
|
+
# Terminal 2 — Backend SSR + API server
|
|
580
|
+
dars dev --backend
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## Local Execution and Live Preview
|
|
586
|
+
|
|
587
|
+
```python
|
|
588
|
+
if __name__ == "__main__":
|
|
589
|
+
app.rTimeCompile()
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
```bash
|
|
593
|
+
python my_app.py
|
|
594
|
+
# → http://localhost:8000
|
|
595
|
+
|
|
596
|
+
python my_app.py --port 8088
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
# Auto-detects output directory and port from config
|
|
601
|
+
dars preview
|
|
602
|
+
|
|
603
|
+
# Or specify a custom path and port
|
|
604
|
+
dars preview ./my_exported_app -p 8080
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
## Project Configuration (`dars.config.json`)
|
|
610
|
+
|
|
611
|
+
```json
|
|
612
|
+
{
|
|
613
|
+
"entry": "main.py",
|
|
614
|
+
"format": "html",
|
|
615
|
+
"outdir": "dist",
|
|
616
|
+
"publicDir": null,
|
|
617
|
+
"include": [],
|
|
618
|
+
"exclude": ["**/__pycache__", ".git", ".venv", "node_modules"],
|
|
619
|
+
"bundle": true,
|
|
620
|
+
"defaultMinify": true,
|
|
621
|
+
"viteMinify": true,
|
|
622
|
+
"utility_styles": {},
|
|
623
|
+
"markdownHighlight": true,
|
|
624
|
+
"markdownHighlightTheme": "auto",
|
|
625
|
+
"port": 8000,
|
|
626
|
+
"backendEntry": "backend.api:app"
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
| Key | Description |
|
|
631
|
+
|---|---|
|
|
632
|
+
| `entry` | Python entry file for `dars build` and `dars export config` |
|
|
633
|
+
| `format` | Export format: `html` or `desktop` |
|
|
634
|
+
| `outdir` | Output directory |
|
|
635
|
+
| `publicDir` | Folder copied into output (auto-detected if null) |
|
|
636
|
+
| `bundle` | Reserved for future use |
|
|
637
|
+
| `defaultMinify` | Toggle Python HTML/JS/CSS minifier (default `true`) |
|
|
638
|
+
| `viteMinify` | Toggle Vite/esbuild minifier for JS/CSS (default `true`) |
|
|
639
|
+
| `utility_styles` | Custom utility class definitions |
|
|
640
|
+
| `markdownHighlight` | Auto-inject Prism.js for Markdown code blocks (default `true`) |
|
|
641
|
+
| `backendEntry` | Python import path for SSR/backend app (e.g. `"backend.api:app"`) |
|
|
642
|
+
| `port` | Dev preview server port (default `8000`) |
|
|
643
|
+
|
|
644
|
+
```bash
|
|
645
|
+
dars config validate
|
|
646
|
+
dars build
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
---
|
|
650
|
+
|
|
651
|
+
## Documentation
|
|
652
|
+
|
|
653
|
+
- [Getting Started](https://ztamdev.github.io/Dars-Framework/docs.html#getting-started-with-dars)
|
|
654
|
+
- [Components](https://ztamdev.github.io/Dars-Framework/docs.html#dars-components-documentation)
|
|
655
|
+
- [Hooks & Utilities](https://ztamdev.github.io/Dars-Framework/docs.html#hooks-system)
|
|
656
|
+
- [Backend & API](https://ztamdev.github.io/Dars-Framework/docs.html#backend-http-utilities)
|
|
657
|
+
- [State Management](https://ztamdev.github.io/Dars-Framework/docs.html#state-management-in-dars)
|
|
658
|
+
- [Styling](https://ztamdev.github.io/Dars-Framework/docs.html#styling-system-in-dars)
|
|
659
|
+
- [Routing](https://ztamdev.github.io/Dars-Framework/docs.html#spa-routing-in-dars-framework)
|
|
660
|
+
- [SSR & Deployment](https://ztamdev.github.io/Dars-Framework/docs.html#server-side-rendering-in-dars-framework)
|
|
661
|
+
- [Animations](https://ztamdev.github.io/Dars-Framework/docs.html#dars-animation-system)
|
|
662
|
+
- [Release Notes](LandingPage/releases/versions.md)
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
- Visit the Dars [official website](https://ztamdev.github.io/Dars-Framework/)
|
|
667
|
+
- Visit the Dars official [Documentation](https://ztamdev.github.io/Dars-Framework/docs.html)
|
|
668
|
+
- Try Dars without installing anything — visit the [Dars Playground](https://dars-playground.vercel.app/)
|