nextpy-framework 3.7.3__tar.gz → 3.9.0__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.
Files changed (143) hide show
  1. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/__init__.py +1 -1
  2. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/cli.py +151 -360
  3. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/component_renderer.py +19 -11
  4. nextpy_framework-3.9.0/.nextpy_framework/nextpy/main.py +72 -0
  5. nextpy_framework-3.9.0/.nextpy_framework/nextpy/psx/compiler/actions.py +878 -0
  6. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/compiler/handler_compiler.py +52 -11
  7. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/components/component.py +18 -6
  8. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/parser.py +117 -30
  9. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/runtime.py +15 -4
  10. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/decorators.py +460 -136
  11. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/engine.py +60 -1
  12. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/integration.py +18 -4
  13. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/runtime/actions_runtime.py +157 -11
  14. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/runtime/js_actions_runtime.py +232 -52
  15. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0/.nextpy_framework/nextpy_framework.egg-info}/PKG-INFO +3 -3
  16. {nextpy_framework-3.7.3/.nextpy_framework/nextpy_framework.egg-info → nextpy_framework-3.9.0}/PKG-INFO +3 -3
  17. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/README.md +2 -2
  18. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/pyproject.toml +1 -1
  19. nextpy_framework-3.7.3/.nextpy_framework/nextpy/main.py +0 -81
  20. nextpy_framework-3.7.3/.nextpy_framework/nextpy/psx/compiler/actions.py +0 -431
  21. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/ast_parser.py +0 -0
  22. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/auth.py +0 -0
  23. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/builder.py +0 -0
  24. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/__init__.py +0 -0
  25. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/AutoDebug.py +0 -0
  26. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/AutoDebug_v3.py +0 -0
  27. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/DebugIcon.py +0 -0
  28. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/DebugIconFixed.py +0 -0
  29. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/feedback.py +0 -0
  30. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/form.py +0 -0
  31. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/head.py +0 -0
  32. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/hooks_provider.py +0 -0
  33. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/image.py +0 -0
  34. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/layout.py +0 -0
  35. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/link.py +0 -0
  36. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/loader.py +0 -0
  37. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/navigation.py +0 -0
  38. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/toast.py +0 -0
  39. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/ui.py +0 -0
  40. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/visual.py +0 -0
  41. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components.py +0 -0
  42. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/conf.py +0 -0
  43. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/config.py +0 -0
  44. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/__init__.py +0 -0
  45. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/builder.py +0 -0
  46. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/component_router.py +0 -0
  47. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/data_fetching.py +0 -0
  48. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/demo_pages_simple.py +0 -0
  49. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/demo_router.py +0 -0
  50. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/renderer.py +0 -0
  51. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/router.py +0 -0
  52. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/sync.py +0 -0
  53. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/db.py +0 -0
  54. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/core.py +0 -0
  55. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/performance.py +0 -0
  56. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/ui.py +0 -0
  57. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/websocket.py +0 -0
  58. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/dev_server.py +0 -0
  59. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/dev_tools.py +0 -0
  60. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/errors.py +0 -0
  61. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/hooks.py +0 -0
  62. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/hooks_provider.py +0 -0
  63. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/hooks_provider_new.py +0 -0
  64. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/jsx.py +0 -0
  65. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/jsx_preprocessor.py +0 -0
  66. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/jsx_transformer.py +0 -0
  67. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/performance.py +0 -0
  68. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/__init__.py +0 -0
  69. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/base.py +0 -0
  70. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/builtin.py +0 -0
  71. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/config.py +0 -0
  72. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins.py +0 -0
  73. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/__init__.py +0 -0
  74. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/__init__.py +0 -0
  75. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/ast_nodes.py +0 -0
  76. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/evaluator.py +0 -0
  77. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/language_server.py +0 -0
  78. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/language_server_lsp.py +0 -0
  79. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/psx_formatter.py +0 -0
  80. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/server_client_components.py +0 -0
  81. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/setup.py +0 -0
  82. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/__init__.py +0 -0
  83. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/renderer/renderer.py +0 -0
  84. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/tests/test_full_integration.py +0 -0
  85. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/tests/test_html_attribute_support.py +0 -0
  86. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/utils/helpers.py +0 -0
  87. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/vdom/vnode.py +0 -0
  88. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/py.typed +0 -0
  89. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/runtime/events.py +0 -0
  90. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/security.py +0 -0
  91. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/__init__.py +0 -0
  92. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/app.py +0 -0
  93. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/debug.py +0 -0
  94. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/middleware.py +0 -0
  95. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/source/conf.py +0 -0
  96. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/HANDLER_REGISTRATION_SYSTEM.py +0 -0
  97. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/setup_complete.py +0 -0
  98. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_autodebug_enhanced.py +0 -0
  99. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_cli_scaffolding.py +0 -0
  100. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_colors.py +0 -0
  101. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_component_rendering.py +0 -0
  102. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_conversion.py +0 -0
  103. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_critical_fixes.py +0 -0
  104. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_demo_mode.py +0 -0
  105. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_demo_server.py +0 -0
  106. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_enhanced_handlers.py +0 -0
  107. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_extraction.py +0 -0
  108. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_final.py +0 -0
  109. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_fixes.py +0 -0
  110. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_handler_system.py +0 -0
  111. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_hydration_engine.py +0 -0
  112. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_integration.py +0 -0
  113. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_interactive_bug.py +0 -0
  114. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_jsx_edgecases.py +0 -0
  115. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_jsx_preprocessor.py +0 -0
  116. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_migration.py +0 -0
  117. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_modular_debug.py +0 -0
  118. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_routing.py +0 -0
  119. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_server.py +0 -0
  120. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_server_features.py +0 -0
  121. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_server_working.py +0 -0
  122. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind.py +0 -0
  123. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind_full.py +0 -0
  124. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind_integration.py +0 -0
  125. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind_up_to_date.py +0 -0
  126. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_websocket_complete.py +0 -0
  127. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/true_jsx.py +0 -0
  128. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/__init__.py +0 -0
  129. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/cache.py +0 -0
  130. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/email.py +0 -0
  131. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/file_upload.py +0 -0
  132. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/logging.py +0 -0
  133. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/search.py +0 -0
  134. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/seo.py +0 -0
  135. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/validators.py +0 -0
  136. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/websocket.py +0 -0
  137. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/SOURCES.txt +0 -0
  138. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/dependency_links.txt +0 -0
  139. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/entry_points.txt +0 -0
  140. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/requires.txt +0 -0
  141. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/top_level.txt +0 -0
  142. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/LICENSE +0 -0
  143. {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/setup.cfg +0 -0
@@ -3,7 +3,7 @@ NextPy - The Python Web Framdwork
3
3
  File-based routing, SSR, SSG, and more with FastAPI + PSX (True JSX)
4
4
  """
5
5
 
6
- __version__ = "3.7.2"
6
+ __version__ = "3.9.0"
7
7
 
8
8
  from nextpy.core.router import Router, Route, DynamicRoute
9
9
  from nextpy.core.renderer import Renderer
@@ -243,7 +243,7 @@ def cli():
243
243
 
244
244
 
245
245
  @cli.command()
246
- @click.option("--port", "-p", default=5000, help="Port to run the server on")
246
+ @click.option("--port", "-p", default=8000, help="Port to run the server on")
247
247
  @click.option("--host", "-h", default="0.0.0.0", help="Host to bind to")
248
248
  @click.option("--reload/--no-reload", default=True, help="Enable hot reload")
249
249
  @click.option("--debug/--no-debug", default=True, help="Enable debug mode")
@@ -322,6 +322,7 @@ def dev(port: int, host: str, reload: bool, debug: bool):
322
322
  # Enhanced reload patterns for JSX files
323
323
  reload_includes = [
324
324
  "*.py",
325
+ "*.psx",
325
326
  "*.py.jsx",
326
327
  "*.jsx",
327
328
  "*.html",
@@ -993,7 +994,10 @@ def _generate_page(name: str):
993
994
  page_path.parent.mkdir(parents=True, exist_ok=True)
994
995
 
995
996
  content = f'''"""Generated {name} page"""
997
+
998
+ from nextpy.psx import interactive_component as component
996
999
 
1000
+ @component
997
1001
  def {name.title()}(props = None):
998
1002
  """{name.title()} page component"""
999
1003
  props = props or {{}}
@@ -1160,6 +1164,37 @@ def _create_project_structure(
1160
1164
  </body>
1161
1165
  </html>""")
1162
1166
  click.echo(" Created: templates/_404.html")
1167
+
1168
+ try:
1169
+ from importlib.resources import files, as_file
1170
+ import shutil
1171
+
1172
+ images_dir = project_dir / "public" / "images"
1173
+ images_dir.mkdir(parents=True, exist_ok=True)
1174
+
1175
+ logo_source = files("nextpy.public").joinpath("logo.png")
1176
+
1177
+ with as_file(logo_source) as logo_path:
1178
+ shutil.copy2(
1179
+ logo_path,
1180
+ images_dir / "logo.png"
1181
+ )
1182
+ click.echo(" Copied: logo.png to public/images/")
1183
+ except Exception as e:
1184
+ click.echo(click.style(f" ⚠️ Failed to copy logo.png: {str(e)}", fg="yellow"))
1185
+
1186
+ #create minimal stylesheet
1187
+ (project_dir / "public" / "css"/ "styles.css").write_text("""/* NextPy Styles */
1188
+ body{
1189
+ margin: 0;
1190
+ padding: 0;
1191
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
1192
+ }
1193
+ """)
1194
+
1195
+ click.echo(" Created: public/css/styles.css")
1196
+
1197
+
1163
1198
 
1164
1199
  # Create styles.css with Tailwind directives
1165
1200
  (project_dir / "styles" / "styles.css").write_text("""/* NextPy Styles */
@@ -1329,7 +1364,7 @@ module.exports = {
1329
1364
 
1330
1365
  (project_dir / "pages" / "index.py").write_text('''"""Interactive Homepage """
1331
1366
 
1332
- from nextpy.psx import component
1367
+ from nextpy.psx import interactive_component as component
1333
1368
 
1334
1369
 
1335
1370
  @component
@@ -1337,204 +1372,143 @@ def Home(props=None):
1337
1372
  props = props or {}
1338
1373
  title = props.get("title", "Welcome to NextPy!")
1339
1374
  message = props.get("message", "Build amazing web apps with Python and True JSX")
1340
-
1341
- return (
1342
- <div class="min-h-screen bg-gradient-to-br from-blue-600 via-purple-600 to-pink-600">
1343
- <div class="bg-white border-b border-white bg-opacity-10 backdrop-blur-md border-opacity-20">
1344
- <div class="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
1345
- <div class="flex items-center justify-between h-16">
1346
- <div class="flex items-center">
1347
- <h1 class="text-xl font-bold text-white">NextPy</h1>
1348
- </div>
1349
- <div class="flex space-x-4">
1350
- <a href="/about" class="px-3 py-2 text-sm font-medium text-white transition-colors rounded-md hover:text-blue-200">
1351
- About
1352
- </a>
1353
- <a href="/features" class="px-3 py-2 text-sm font-medium text-white transition-colors rounded-md hover:text-blue-200">
1354
- Features
1355
- </a>
1356
- <a href="/docs" class="px-3 py-2 text-sm font-medium text-white transition-colors rounded-md hover:text-blue-200">
1357
- Docs
1358
- </a>
1359
- </div>
1360
- </div>
1361
- </div>
1362
- </div>
1363
- </div>
1364
-
1365
-
1366
-
1367
- </div>
1368
- )
1369
-
1370
- def getServerSideProps(context):
1371
- return {
1372
- "props": {
1373
- "title": "Welcome to NextPy!",
1374
- "message": "Build amazing web apps with Python and True JSX"
1375
- }
1376
- }
1377
1375
 
1378
- default = Home
1379
- ''')
1380
- click.echo(" Created: pages/index.py ")
1376
+ return (
1377
+ <div class="flex flex-col items-center justify-between min-h-screen p-8 font-sans antialiased text-black bg-white selection:bg-gray-200">
1378
+ <head>
1379
+ {/* optionally load a stylesheet from public/css <link rel="stylesheet" href="static/css/styles.css" /> */}
1380
+ </head>
1381
+ {/* Top spacer to perfectly center the main content vertically */}
1382
+ <div class=""></div>
1383
+
1384
+ {/* Main Centered Content */}
1385
+ <div class="flex flex-col items-center max-w-xl gap-8 text-center">
1386
+ {/* Logo Section */}
1387
+ <h1 class="text-[56px] font-extrabold tracking-tighter leading-none select-none font-mono flex items-baseline">
1388
+ <img src="static/images/logo.png" alt="NextPy Logo" class="w-auto h-16" />
1381
1389
 
1382
- # Create enhanced about page with interactive features
1383
- (project_dir / "pages" / "about.py").write_text(
1384
- '''"""Enhanced About page with True JSX"""
1390
+ </h1>
1385
1391
 
1386
- from nextpy.psx import component
1392
+ {/* Step-by-Step Instructions */}
1393
+ <ol class="list-decimal list-inside text-left text-[16px] font-mono text-gray-800 space-y-2.5">
1394
+ <li>
1395
+ Get started by editing
1396
+ <code class="bg-black/[0.05] px-1.5 py-0.5 rounded font-bold text-black text-[13px]">
1397
+ pages/index.py
1398
+ </code>
1399
+ .
1400
+ </li>
1401
+ <li>Save and see your changes instantly.</li>
1402
+ </ol>
1403
+
1404
+ {/* Call To Action Buttons */}
1405
+ <div class="flex flex-col items-center gap-4 mt-2 sm:flex-row">
1406
+
1407
+ <a
1408
+ href="https://nextpy-framework.onrender.com/deploy"
1409
+ class="flex items-center gap-2 bg-black text-white px-6 py-3 rounded-full text-[14px] font-medium transition-colors hover:bg-[#2c2c2c] shadow-sm"
1410
+
1411
+ >
1412
+ <svg
1413
+ class="w-6 h-6"
1414
+ fill="none"
1415
+ stroke="currentColor"
1416
+ stroke-width="2"
1417
+ viewBox="0 0 24 24"
1418
+ >
1419
+ <path
1420
+ stroke-linecap="round"
1421
+ stroke-linejoin="round"
1422
+ d="M7 18a4 4 0 010-8 5 5 0 019.7-1.2A3.5 3.5 0 0117.5 18H7z"
1423
+ />
1424
+ <path
1425
+ stroke-linecap="round"
1426
+ stroke-linejoin="round"
1427
+ d="M12 14V8m0 0l-3 3m3-3l3 3"
1428
+ />
1429
+ </svg>
1430
+
1431
+ Deploy now
1432
+ </a>
1433
+
1434
+ <a
1435
+ href="https://nextpy-framework.onrender.com/"
1436
+ class="flex items-center justify-center border border-black/[0.08] bg-white text-black px-6 py-3 rounded-full text-[14px] font-medium transition-colors hover:bg-gray-50 hover:border-black/[0.15] min-w-[140px]"
1437
+
1438
+ >
1439
+ Read our docs
1440
+ </a>
1441
+ </div>
1442
+
1443
+ <div class="flex flex-wrap items-center justify-center gap-x-8 text-[14px] font-medium text-gray-600 w-full max-w-2xl py-4 border-t border-gray-100 sm:border-none">
1444
+ <a
1445
+ href="https://nextpy-framework.onrender.com/learn"
1446
+ class="flex items-center gap-2 transition-colors hover:underline hover:text-black"
1447
+
1448
+ >
1449
+ {/* Document Icon */}
1450
+ <svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
1451
+ <path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
1452
+ </svg>
1453
+ Learn
1454
+ </a>
1387
1455
 
1456
+ <a
1457
+ href="https://nextpy-framework.onrender.com/templates"
1458
+ class="flex items-center gap-2 transition-colors hover:underline hover:text-black"
1459
+
1460
+ >
1461
+ {/* Window Layout Icon */}
1462
+ <svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
1463
+ <path stroke-linecap="round" stroke-linejoin="round" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zm0 7a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zm10 0a1 1 0 011-1h4a1 1 0 011 1v6a1 1 0 01-1 1h-4a1 1 0 01-1-1v-6z"/>
1464
+ </svg>
1465
+ Examples
1466
+ </a>
1388
1467
 
1389
- @component
1390
- def About(props=None):
1391
- """About page component with interactive features"""
1392
- props = props or {}
1393
-
1394
- title = props.get("title", "About NextPy")
1395
- description = props.get("description", "The Python web framework that brings React-like development to Python")
1396
-
1397
- return (
1398
- <div class="min-h-screen bg-gray-50">
1399
- <div class="text-white bg-gradient-to-r from-blue-600 to-purple-600">
1400
- <div class="px-4 py-16 mx-auto max-w-7xl sm:py-24 sm:px-6 lg:px-8">
1401
- <div class="text-center">
1402
- <h1 class="text-4xl font-extrabold tracking-tight sm:text-5xl lg:text-6xl">
1403
- {title}
1404
- </h1>
1405
- <p class="max-w-2xl mx-auto mt-6 text-xl text-blue-100">
1406
- {description}
1407
- </p>
1408
- <div class="flex justify-center mt-10 space-x-4">
1409
- <a href="/features" class="inline-flex items-center justify-center px-8 py-3 text-base font-medium text-blue-600 bg-white border border-transparent rounded-md hover:bg-blue-50 md:py-4 md:text-lg md:px-10">
1410
- Explore Features
1411
- </a>
1412
- <a href="/getting-started" class="inline-flex items-center justify-center px-8 py-3 text-base font-medium text-white bg-blue-500 border border-transparent rounded-md hover:bg-blue-600 md:py-4 md:text-lg md:px-10">
1413
- Get Started
1414
- </a>
1415
- </div>
1416
- </div>
1468
+ <a
1469
+ href="https://nextpy-framework.onrender.com/"
1470
+ class="flex items-center gap-1.5 hover:underline hover:text-black transition-colors"
1471
+
1472
+ >
1473
+ {/* Globe Icon */}
1474
+ <svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
1475
+ <path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/>
1476
+ </svg>
1477
+ Go to nextpy.org →
1478
+ </a>
1417
1479
  </div>
1480
+
1418
1481
  </div>
1419
1482
 
1420
-
1483
+ <footer class="flex flex-wrap items-center justify-center text-[14px] font-medium text-gray-600 w-full max-w-2xl py-4 border-t border-gray-100 sm:border-none">
1484
+ The Python Web Framework for Everyone
1485
+ </footer>
1421
1486
  </div>
1422
1487
  )
1423
1488
 
1489
+
1424
1490
  def getServerSideProps(context):
1425
1491
  return {
1426
1492
  "props": {
1427
- "title": "About NextPy",
1428
- "description": "The Python web framework that brings React-like development to Python"
1493
+ "title": "Welcome to NextPy!",
1494
+ "message": "Build amazing web apps with Python and True JSX"
1429
1495
  }
1430
1496
  }
1431
1497
 
1432
- default = About
1433
- '''
1434
- )
1435
- click.echo(" Created: pages/about.py (enhanced interactive page)")
1436
-
1437
- # Create interactive demo pages
1438
- (project_dir / "pages" / "interactive.py").write_text('''"""Interactive Demo Page"""
1439
-
1440
- from nextpy.psx import component
1441
-
1442
1498
 
1443
- @component
1444
- def InteractiveDemo(props=None):
1445
- """Interactive demo showcasing NextPy capabilities"""
1446
- return (
1447
- <div class="min-h-screen py-12 bg-gradient-to-br from-indigo-50 to-purple-100">
1448
- <div class="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
1449
- <h1 class="mb-12 text-4xl font-extrabold text-center text-gray-900">
1450
- Interactive NextPy Demos
1451
- </h1>
1452
-
1453
- <div class="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3">
1454
-
1455
- <div class="p-6 bg-white shadow-lg rounded-xl">
1456
- <h2 class="mb-4 text-2xl font-bold text-gray-900">Live Counter</h2>
1457
- <div class="text-center">
1458
- <div class="mb-4 text-6xl font-bold text-blue-600" id="counter">0</div>
1459
- <div class="space-x-4">
1460
- <button onclick="updateCounter(-1)" class="px-6 py-3 text-white transition-colors bg-red-500 rounded-lg hover:bg-red-600">
1461
- -
1462
- </button>
1463
- <button onclick="updateCounter(1)" class="px-6 py-3 text-white transition-colors bg-green-500 rounded-lg hover:bg-green-600">
1464
- +
1465
- </button>
1466
- <button onclick="resetCounter()" class="px-6 py-3 text-white transition-colors bg-gray-500 rounded-lg hover:bg-gray-600">
1467
- Reset
1468
- </button>
1469
- </div>
1470
- </div>
1471
- </div>
1472
-
1473
-
1474
- <div class="p-6 bg-white shadow-lg rounded-xl">
1475
- <h2 class="mb-4 text-2xl font-bold text-gray-900">Todo List</h2>
1476
- <div class="space-y-4">
1477
- <div class="flex space-x-2">
1478
- <input type="text" id="todoInput" placeholder="Add a new todo..." class="flex-1 px-4 py-2 border border-gray-300 rounded-lg" />
1479
- <button onclick="addTodo()" class="px-6 py-2 text-white transition-colors bg-blue-500 rounded-lg hover:bg-blue-600">
1480
- Add
1481
- </button>
1482
- </div>
1483
- <ul id="todoList" class="space-y-2">
1484
-
1485
- </ul>
1486
- </div>
1487
- </div>
1488
-
1489
-
1490
- <div class="p-6 bg-white shadow-lg rounded-xl">
1491
- <h2 class="mb-4 text-2xl font-bold text-gray-900">Color Picker</h2>
1492
- <div class="space-y-4">
1493
- <input type="color" id="colorPicker" class="w-full h-20 rounded-lg cursor-pointer" />
1494
- <div id="colorDisplay" class="p-4 font-mono text-lg text-center bg-gray-100 rounded-lg">
1495
- Selected: #3B82F6
1496
- </div>
1497
- </div>
1498
- </div>
1499
-
1500
-
1501
- <div class="p-6 bg-white shadow-lg rounded-xl">
1502
- <h2 class="mb-4 text-2xl font-bold text-gray-900">Form Validation</h2>
1503
- <form onsubmit="validateForm(event)" class="space-y-4">
1504
- <div>
1505
- <label class="block mb-2 text-sm font-medium text-gray-700">Email</label>
1506
- <input type="email" id="email" required class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="you@example.com" />
1507
- </div>
1508
- <div>
1509
- <label class="block mb-2 text-sm font-medium text-gray-700">Password</label>
1510
- <input type="password" id="password" required minlength="6" class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="•••••••••" />
1511
- </div>
1512
- <button type="submit" class="w-full px-6 py-3 text-white transition-colors bg-blue-500 rounded-lg hover:bg-blue-600">
1513
- Validate & Submit
1514
- </button>
1515
- </form>
1516
- <div id="validationResult" class="hidden p-4 mt-4 rounded-lg">
1517
-
1518
- </div>
1519
- </div>
1520
- </div>
1521
- </div>
1522
- </div>
1523
- )
1499
+ default = Home
1524
1500
 
1525
- def getServerSideProps(context):
1526
- return {"props": {}}
1527
1501
 
1528
- default = InteractiveDemo
1529
1502
  ''')
1530
- click.echo(" Created: pages/interactive.py (interactive demos)")
1503
+ click.echo(" Created: pages/index.py ")
1504
+
1531
1505
 
1532
1506
  (project_dir / "components" / "ui" / "Button.py").write_text(
1533
1507
  '''"""Button component"""
1534
- from nextpy.psx import component
1508
+ from nextpy.psx import psx
1509
+
1535
1510
 
1536
1511
 
1537
- @component
1538
1512
  def Button(props = None):
1539
1513
  """Reusable Button component"""
1540
1514
  props = props or {}
@@ -1556,14 +1530,14 @@ def Button(props = None):
1556
1530
 
1557
1531
  class_attr = f"px-6 py-3 rounded-lg font-medium transition-all duration-200 transform hover:scale-105 {variant_class} {className}"
1558
1532
 
1559
- return (
1533
+ return psx(f"
1560
1534
  <button class={class_attr}
1561
1535
  id={props.get("id")}
1562
1536
  disabled={props.get("disabled", False)}
1563
1537
  onclick={props.get("onClick", "")}>
1564
1538
  {children}
1565
1539
  </button>
1566
- )
1540
+ ")
1567
1541
 
1568
1542
  default = Button
1569
1543
  '''
@@ -1613,119 +1587,7 @@ default = Layout
1613
1587
  )
1614
1588
  click.echo(" Created: components/layout/Layout.py")
1615
1589
 
1616
- # Create VS Code configuration for PSX support
1617
- (project_dir / ".vscode").mkdir(exist_ok=True)
1618
- (project_dir / ".vscode" / "settings.json").write_text("""{
1619
- "files.associations": {
1620
- "*.py": "python",
1621
- "*.py.jsx": "python",
1622
- "*.jsx": "javascriptreact"
1623
- },
1624
- "emmet.includeLanguages": {
1625
- "python": "html",
1626
- "javascriptreact": "html",
1627
- "typescriptreact": "html"
1628
- },
1629
- "emmet.triggerExpansionOnTab": true,
1630
- "typescript.preferences.includePackageJsonAutoImports": "on",
1631
- "editor.quickSuggestions": {
1632
- "strings": true
1633
- },
1634
- "editor.suggestSelection": "first",
1635
- "editor.wordBasedSuggestions": true,
1636
- "editor.snippetSuggestions": "top",
1637
- "editor.parameterHints": {
1638
- "enabled": true
1639
- },
1640
- "editor.snippetSuggestions": "top",
1641
- "html.autoClosingTags": true,
1642
- "css.autoClosingTags": true,
1643
- "javascript.autoClosingTags": true,
1644
- "typescript.autoClosingTags": true,
1645
- "editor.autoClosingBrackets": "always",
1646
- "editor.autoClosingQuotes": "always",
1647
- "editor.formatOnSave": true,
1648
- "editor.codeActionsOnSave": {
1649
- "source.fixAll.eslint": true,
1650
- "source.organizeImports": true
1651
- },
1652
- "emmet.preferences": {
1653
- "css.property.endWithSemicolon": true,
1654
- "css.value.unit": "rem"
1655
- },
1656
- "files.exclude": {
1657
- "*}__pycache__": true,
1658
- "*}*.pyc": true,
1659
- "*}node_modules": true,
1660
- "*}out": true,
1661
- "*}.next": true,
1662
- "*}.pytest_cache": true,
1663
- "*}.mypy_cache": true
1664
- },
1665
- "search.exclude": {
1666
- "*}node_modules": true,
1667
- "*}out": true,
1668
- "*}.next": true,
1669
- "*}__pycache__": true,
1670
- "*}.pytest_cache": true,
1671
- "*}.mypy_cache": true
1672
- },
1673
- "python.linting.enabled": true,
1674
- "python.linting.pylintEnabled": false,
1675
- "python.linting.flake8Enabled": false,
1676
- "python.linting.pylintArgs": [
1677
- "--disable=C0114,C0115,C0116,E1132,E1131,E1130"
1678
- ],
1679
- "python.formatting.provider": "black",
1680
- "[python]": {
1681
- "editor.defaultFormatter": "ms-python.black-formatter",
1682
- "editor.formatOnSave": true,
1683
- "editor.rulers": [88],
1684
- "editor.tabSize": 4,
1685
- "editor.insertSpaces": true
1686
- }
1687
- }""")
1688
- click.echo(" Created: .vscode/settings.json")
1689
-
1690
- (project_dir / ".vscode" / "extensions.json").write_text("""{
1691
- "recommendations": [
1692
- "ms-python.python",
1693
- "ms-python.vscode-pylance",
1694
- "bradlc.vscode-tailwindcss",
1695
- "esbenp.prettier-vscode",
1696
- "ms-vscode.vscode-json",
1697
- "formulahendry.auto-rename-tag",
1698
- "christian-kohler.path-intellisense",
1699
- "ms-vscode.vscode-html-css-class-completion",
1700
- "ms-vscode.vscode-emmet",
1701
- "ms-vscode.vscode-eslint",
1702
- "dbaeumer.vscode-eslint",
1703
- "ms-vscode.vscode-typescript-next",
1704
- "ritwickdey.liveserver",
1705
- "ms-vscode.vscode-jest",
1706
- "esbenp.prettier-vscode",
1707
- "streetsidesoftware.code-spell-checker",
1708
- "gruntfuggly.todo-tree",
1709
- "ms-vscode.vscode-git-graph",
1710
- "eamodio.gitlens",
1711
- "ms-vscode.vscode-docker",
1712
- "ms-vscode.remote-explorer",
1713
- "ms-vscode-remote.remote-containers",
1714
- "ms-vscode.vscode-remote-wsl",
1715
- "redhat.vscode-yaml",
1716
- "ms-vscode.vscode-markdown",
1717
- "yzhang.markdown-all-in-one",
1718
- "shd101wyy.markdown-preview-enhanced",
1719
- "ms-vscode.vscode-python",
1720
- "kevinrose.vsc-python-indent",
1721
- "ms-python.black-formatter",
1722
- "ms-python.isort",
1723
- "ms-python.flake8",
1724
- "ms-python.mypy-type-checker"
1725
- ]
1726
- }""")
1727
- click.echo(" Created: .vscode/extensions.json")
1728
-
1590
+
1729
1591
  # Create comprehensive API examples
1730
1592
  (project_dir / "pages" / "api" / "hello.py").write_text(
1731
1593
  '''"""API example - Hello endpoint"""
@@ -2208,77 +2070,6 @@ Thumbs.db
2208
2070
  ''')
2209
2071
  click.echo(" Created: .gitignore")
2210
2072
 
2211
- # Create main.py with Tailwind compilation (for pip-installed NextPy)
2212
- (project_dir / "main.py").write_text('''"""NextPy ASGI Application Entry Point"""
2213
-
2214
- import os
2215
- import sys
2216
- import subprocess
2217
- from pathlib import Path
2218
-
2219
- try:
2220
- print("Compiling Tailwind CSS...")
2221
- proj_root = Path.cwd()
2222
- framework_dir = Path(__file__).parent
2223
- # If the project root doesn't have a styles.css yet, warn the user and create a minimal one.
2224
- styles_file = proj_root / "styles.css"
2225
- if not styles_file.exists():
2226
- print("Warning: styles.css not found, creating a minimal file.")
2227
- styles_file.write_text("@tailwind base;\n@tailwind components;\n@tailwind utilities;\n")
2228
-
2229
- import shutil
2230
- npm_bin = shutil.which("npm")
2231
- if not npm_bin:
2232
- raise FileNotFoundError("npm not found on PATH")
2233
-
2234
- lockfile = framework_dir / "package-lock.json"
2235
- node_modules = framework_dir / "node_modules"
2236
- if not node_modules.exists():
2237
- if lockfile.exists():
2238
- subprocess.run([npm_bin, "ci"], cwd=str(framework_dir), check=True)
2239
- else:
2240
- subprocess.run([npm_bin, "install"], cwd=str(framework_dir), check=True)
2241
-
2242
- subprocess.run([npm_bin, "run", "build:tailwind"], cwd=str(framework_dir), check=True)
2243
- print("Tailwind CSS compiled successfully.")
2244
- except subprocess.CalledProcessError as e:
2245
- print(f"Error compiling Tailwind CSS: {e}")
2246
- print("You can also run `cd .nextpy_framework/nextpy && npm ci && npm run build:tailwind` manually.")
2247
- except FileNotFoundError:
2248
- print("Error: npm not found. Make sure Node.js is installed and available on PATH.")
2249
- print("See https://nodejs.org/ for installation instructions.")
2250
-
2251
- # Import NextPy modules (works when installed via pip)
2252
- from nextpy.server.app import create_app
2253
- from nextpy.db import init_db
2254
- from nextpy.config import settings
2255
-
2256
- # Initialize database
2257
- try:
2258
- init_db(settings["database_url"])
2259
- print("Database initialized successfully.")
2260
- except Exception as e:
2261
- print(f"Warning: Database initialization failed: {e}")
2262
-
2263
- # Create NextPy app with file-based routing
2264
- app = create_app(
2265
- pages_dir="pages",
2266
- templates_dir="templates",
2267
- public_dir="public",
2268
- out_dir="out",
2269
- debug=settings["debug"],
2270
- )
2271
-
2272
- # Note: Routes are automatically loaded from pages/ directory
2273
- # - / -> pages/index.py
2274
- # - /about -> pages/about.py
2275
- # - /api/* -> pages/api/*.py
2276
-
2277
- if __name__ == "__main__":
2278
- import uvicorn
2279
- uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
2280
- ''')
2281
- click.echo(" Created: main.py (pip-compatible)")
2282
2073
 
2283
2074
  # Create .env file for development
2284
2075
  (project_dir / ".env").write_text("""# NextPy Development Environment