nextpy-framework 2.4.4__tar.gz → 2.4.5__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 (77) hide show
  1. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/cli.py +136 -108
  2. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/component_router.py +23 -15
  3. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/router.py +23 -15
  4. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/app.py +52 -13
  5. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5/.nextpy_framework/nextpy_framework.egg-info}/PKG-INFO +1 -1
  6. {nextpy_framework-2.4.4/.nextpy_framework/nextpy_framework.egg-info → nextpy_framework-2.4.5}/PKG-INFO +1 -1
  7. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/pyproject.toml +1 -1
  8. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/__init__.py +0 -0
  9. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/auth.py +0 -0
  10. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/builder.py +0 -0
  11. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/__init__.py +0 -0
  12. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/debug/AutoDebug.py +0 -0
  13. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/debug/DebugIcon.py +0 -0
  14. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/debug/DebugIconFixed.py +0 -0
  15. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/feedback.py +0 -0
  16. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/form.py +0 -0
  17. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/head.py +0 -0
  18. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/hooks_provider.py +0 -0
  19. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/image.py +0 -0
  20. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/layout.py +0 -0
  21. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/link.py +0 -0
  22. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/loader.py +0 -0
  23. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/navigation.py +0 -0
  24. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/toast.py +0 -0
  25. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/ui.py +0 -0
  26. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/visual.py +0 -0
  27. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components.py +0 -0
  28. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/config.py +0 -0
  29. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/__init__.py +0 -0
  30. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/builder.py +0 -0
  31. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/component_renderer.py +0 -0
  32. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/data_fetching.py +0 -0
  33. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/demo_pages_simple.py +0 -0
  34. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/demo_router.py +0 -0
  35. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/renderer.py +0 -0
  36. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/sync.py +0 -0
  37. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/db.py +0 -0
  38. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/dev_server.py +0 -0
  39. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/dev_tools.py +0 -0
  40. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/errors.py +0 -0
  41. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks.py +0 -0
  42. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks_provider.py +0 -0
  43. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks_provider_new.py +0 -0
  44. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx.py +0 -0
  45. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx_preprocessor.py +0 -0
  46. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx_transformer.py +0 -0
  47. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/main.py +0 -0
  48. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/performance.py +0 -0
  49. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/__init__.py +0 -0
  50. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/base.py +0 -0
  51. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/builtin.py +0 -0
  52. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/config.py +0 -0
  53. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins.py +0 -0
  54. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/py.typed +0 -0
  55. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/security.py +0 -0
  56. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/__init__.py +0 -0
  57. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/debug.py +0 -0
  58. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/middleware.py +0 -0
  59. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/true_jsx.py +0 -0
  60. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/__init__.py +0 -0
  61. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/cache.py +0 -0
  62. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/email.py +0 -0
  63. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/file_upload.py +0 -0
  64. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/logging.py +0 -0
  65. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/search.py +0 -0
  66. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/seo.py +0 -0
  67. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/validators.py +0 -0
  68. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/websocket.py +0 -0
  69. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/SOURCES.txt +0 -0
  70. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/dependency_links.txt +0 -0
  71. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/entry_points.txt +0 -0
  72. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/requires.txt +0 -0
  73. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/top_level.txt +0 -0
  74. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/LICENSE +0 -0
  75. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/README.md +0 -0
  76. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/setup.cfg +0 -0
  77. {nextpy_framework-2.4.4 → nextpy_framework-2.4.5}/tests/test_routing.py +0 -0
@@ -196,7 +196,7 @@ def _format_size(size_bytes: int) -> str:
196
196
  return f"{size:.1f} {size_names[i]}"
197
197
 
198
198
  @click.group()
199
- @click.version_option(version="1.0.0", prog_name="NextPy")
199
+ @click.version_option(version="2.4.4", prog_name="NextPy")
200
200
  def cli():
201
201
  """NextPy - A Python web framework inspired by Next.js"""
202
202
  pass
@@ -533,7 +533,7 @@ def version():
533
533
  click.echo(click.style("\n 📋 NextPy Framework Info", fg="cyan", bold=True))
534
534
  click.echo(click.style(" ===================\n", fg="cyan"))
535
535
 
536
- click.echo(f" 🏷️ Version: 2.4.3")
536
+ click.echo(f" 🏷️ Version: 2.4.5")
537
537
  click.echo(f" 🐍 Python: {sys.version.split()[0]}")
538
538
  click.echo(f" ⚡ Framework: NextPy")
539
539
  click.echo(f" 🎨 Architecture: True JSX")
@@ -561,7 +561,7 @@ def info():
561
561
 
562
562
  # Framework info
563
563
  click.echo(click.style(" 📦 Framework Details:", fg="blue", bold=True))
564
- click.echo(f" Version: 2.0.0")
564
+ click.echo(f" Version: 2.4.4")
565
565
  click.echo(f" Architecture: True JSX")
566
566
  click.echo(f" Python: {sys.version.split()[0]}")
567
567
 
@@ -878,6 +878,43 @@ def _create_project_structure(project_dir: Path):
878
878
  (project_dir / dir_path).mkdir(parents=True, exist_ok=True)
879
879
  click.echo(f" Created: {dir_path}/")
880
880
 
881
+ # Create essential templates
882
+ (project_dir / "templates" / "_page.html").write_text('''<!DOCTYPE html>
883
+ <html lang="en">
884
+ <head>
885
+ <meta charset="utf-8">
886
+ <meta name="viewport" content="width=device-width, initial-scale=1">
887
+ <title>{{ title or "NextPy App" }}</title>
888
+ <script src="https://cdn.tailwindcss.com"></script>
889
+ </head>
890
+ <body>
891
+ <div id="app">
892
+ {{ content }}
893
+ </div>
894
+ </body>
895
+ </html>''')
896
+ click.echo(" Created: templates/_page.html")
897
+
898
+ (project_dir / "templates" / "_404.html").write_text('''<!DOCTYPE html>
899
+ <html lang="en">
900
+ <head>
901
+ <meta charset="utf-8">
902
+ <meta name="viewport" content="width=device-width, initial-scale=1">
903
+ <title>404 - Page Not Found</title>
904
+ <script src="https://cdn.tailwindcss.com"></script>
905
+ </head>
906
+ <body class="min-h-screen bg-gray-100 flex items-center justify-center">
907
+ <div class="text-center">
908
+ <h1 class="text-6xl font-bold text-gray-900 mb-4">404</h1>
909
+ <p class="text-xl text-gray-600 mb-8">Page not found</p>
910
+ <a href="/" class="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
911
+ Go Home
912
+ </a>
913
+ </div>
914
+ </body>
915
+ </html>''')
916
+ click.echo(" Created: templates/_404.html")
917
+
881
918
  # Create styles.css with Tailwind directives
882
919
  (project_dir / "styles.css").write_text('''/* NextPy Styles */
883
920
  @tailwind base;
@@ -914,10 +951,10 @@ body {
914
951
  # Create tailwind.config.js with Python support
915
952
  (project_dir / "tailwind.config.js").write_text('''module.exports = {
916
953
  content: [
917
- './pages/**/*.{js,ts,jsx,tsx,mdx,py}',
918
- './components/**/*.{js,ts,jsx,tsx,mdx,py}',
919
- './templates/**/*.{html,htm}',
920
- './app/**/*.{js,ts,jsx,tsx,mdx,py}',
954
+ './pages/*}*.{js,ts,jsx,tsx,mdx,py}',
955
+ './components/*}*.{js,ts,jsx,tsx,mdx,py}',
956
+ './templates/*}*.{html,htm}',
957
+ './app/*}*.{js,ts,jsx,tsx,mdx,py}',
921
958
  ],
922
959
  theme: {
923
960
  extend: {
@@ -1024,7 +1061,6 @@ def Home(props=None):
1024
1061
 
1025
1062
  return (
1026
1063
  <div className="min-h-screen bg-gradient-to-br from-blue-600 via-purple-600 to-pink-600">
1027
- {/* Navigation */}
1028
1064
  <nav className="bg-white border-b border-white bg-opacity-10 backdrop-blur-md border-opacity-20">
1029
1065
  <div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
1030
1066
  <div className="flex items-center justify-between h-16">
@@ -1046,7 +1082,6 @@ def Home(props=None):
1046
1082
  </div>
1047
1083
  </nav>
1048
1084
 
1049
- {/* Hero Section */}
1050
1085
  <div className="relative overflow-hidden">
1051
1086
  <div className="mx-auto max-w-7xl">
1052
1087
  <div className="relative z-10 pb-8 bg-transparent sm:pb-16 md:pb-20 lg:pb-28 xl:pb-32">
@@ -1072,8 +1107,7 @@ def Home(props=None):
1072
1107
  </div>
1073
1108
  </div>
1074
1109
 
1075
- {/* Background decoration */}
1076
- <div className="absolute inset-0 -z-10">
1110
+ <div className="absolute inset-0 -z-10">
1077
1111
  <div className="absolute top-0 transform -translate-x-1/2 left-1/2 blur-3xl opacity-20">
1078
1112
  <div className="rounded-full aspect-square w-96 h-96 bg-gradient-to-r from-blue-400 to-purple-600"></div>
1079
1113
  </div>
@@ -1083,7 +1117,7 @@ def Home(props=None):
1083
1117
  </div>
1084
1118
  </div>
1085
1119
 
1086
- {/* Features Section */}
1120
+
1087
1121
  <div className="py-12 bg-white">
1088
1122
  <div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
1089
1123
  <div className="lg:text-center">
@@ -1097,10 +1131,10 @@ def Home(props=None):
1097
1131
 
1098
1132
  <div className="mt-10">
1099
1133
  <div className="space-y-10 md:space-y-0 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10 lg:grid-cols-3">
1100
- {/* Feature 1 */}
1134
+
1101
1135
  <div className="relative">
1102
1136
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-blue-500 rounded-md">
1103
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1137
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1104
1138
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
1105
1139
  </svg>
1106
1140
  </div>
@@ -1111,14 +1145,14 @@ def Home(props=None):
1111
1145
  Write React-like components directly in Python with full JSX support.
1112
1146
  </p>
1113
1147
  <a href="/jsx-demo" className="mt-4 ml-16 text-base font-medium text-blue-600 hover:text-blue-500">
1114
- Learn more
1148
+ Learn more &rarr;
1115
1149
  </a>
1116
1150
  </div>
1117
1151
 
1118
- {/* Feature 2 */}
1152
+
1119
1153
  <div className="relative">
1120
1154
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-purple-500 rounded-md">
1121
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1155
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1122
1156
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
1123
1157
  </svg>
1124
1158
  </div>
@@ -1129,14 +1163,14 @@ def Home(props=None):
1129
1163
  Built-in Tailwind CSS v4 with PostCSS compilation and utility classes.
1130
1164
  </p>
1131
1165
  <a href="/tailwind-demo" className="mt-4 ml-16 text-base font-medium text-blue-600 hover:text-blue-500">
1132
- Learn more
1166
+ Learn more &rarr;
1133
1167
  </a>
1134
1168
  </div>
1135
1169
 
1136
- {/* Feature 3 */}
1170
+
1137
1171
  <div className="relative">
1138
1172
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-green-500 rounded-md">
1139
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1173
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1140
1174
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
1141
1175
  </svg>
1142
1176
  </div>
@@ -1147,7 +1181,7 @@ def Home(props=None):
1147
1181
  Automatic route discovery with support for dynamic routes and API endpoints.
1148
1182
  </p>
1149
1183
  <a href="/routing-demo" className="mt-4 ml-16 text-base font-medium text-blue-600 hover:text-blue-500">
1150
- Learn more
1184
+ Learn more &rarr;
1151
1185
  </a>
1152
1186
  </div>
1153
1187
  </div>
@@ -1155,7 +1189,7 @@ def Home(props=None):
1155
1189
  </div>
1156
1190
  </div>
1157
1191
 
1158
- {/* Interactive Demo Section */}
1192
+
1159
1193
  <div className="py-12 bg-gray-50">
1160
1194
  <div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
1161
1195
  <div className="text-center">
@@ -1168,7 +1202,7 @@ def Home(props=None):
1168
1202
  </div>
1169
1203
 
1170
1204
  <div className="grid grid-cols-1 gap-8 mt-12 sm:grid-cols-2 lg:grid-cols-3">
1171
- {/* Interactive Counter */}
1205
+
1172
1206
  <div className="p-6 bg-white rounded-lg shadow-lg">
1173
1207
  <h3 className="text-lg font-medium text-gray-900">Live Counter</h3>
1174
1208
  <p className="mt-2 text-sm text-gray-500">Interactive state management demo</p>
@@ -1180,7 +1214,7 @@ def Home(props=None):
1180
1214
  </div>
1181
1215
  </div>
1182
1216
 
1183
- {/* Form Demo */}
1217
+
1184
1218
  <div className="p-6 bg-white rounded-lg shadow-lg">
1185
1219
  <h3 className="text-lg font-medium text-gray-900">Form Handling</h3>
1186
1220
  <p className="mt-2 text-sm text-gray-500">Server-side form processing</p>
@@ -1192,7 +1226,7 @@ def Home(props=None):
1192
1226
  </div>
1193
1227
  </div>
1194
1228
 
1195
- {/* API Demo */}
1229
+
1196
1230
  <div className="p-6 bg-white rounded-lg shadow-lg">
1197
1231
  <h3 className="text-lg font-medium text-gray-900">API Integration</h3>
1198
1232
  <p className="mt-2 text-sm text-gray-500">RESTful API endpoints</p>
@@ -1207,12 +1241,12 @@ def Home(props=None):
1207
1241
  </div>
1208
1242
  </div>
1209
1243
 
1210
- {/* Footer */}
1244
+
1211
1245
  <footer className="bg-gray-900">
1212
1246
  <div className="px-4 py-12 mx-auto max-w-7xl sm:px-6 lg:px-8">
1213
1247
  <div className="flex flex-col items-center space-y-4">
1214
1248
  <p className="text-base text-center text-gray-400">
1215
- Built with ❤️ using NextPy Framework
1249
+ Built with &hearts; using NextPy Framework
1216
1250
  </p>
1217
1251
  <div className="flex space-x-6">
1218
1252
  <a href="/about" className="text-gray-400 hover:text-gray-300">About</a>
@@ -1249,8 +1283,7 @@ def About(props=None):
1249
1283
 
1250
1284
  return (
1251
1285
  <div className="min-h-screen bg-gray-50">
1252
- {/* Hero Section */}
1253
- <div className="text-white bg-gradient-to-r from-blue-600 to-purple-600">
1286
+ <div className="text-white bg-gradient-to-r from-blue-600 to-purple-600">
1254
1287
  <div className="px-4 py-16 mx-auto max-w-7xl sm:py-24 sm:px-6 lg:px-8">
1255
1288
  <div className="text-center">
1256
1289
  <h1 className="text-4xl font-extrabold tracking-tight sm:text-5xl lg:text-6xl">
@@ -1271,7 +1304,7 @@ def About(props=None):
1271
1304
  </div>
1272
1305
  </div>
1273
1306
 
1274
- {/* Features Grid */}
1307
+
1275
1308
  <div className="py-12 bg-white">
1276
1309
  <div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
1277
1310
  <div className="lg:text-center">
@@ -1285,10 +1318,10 @@ def About(props=None):
1285
1318
 
1286
1319
  <div className="mt-10">
1287
1320
  <div className="gap-8 space-y-10 md:space-y-0 md:grid md:grid-cols-2 lg:grid-cols-3">
1288
- {/* Feature 1 */}
1321
+
1289
1322
  <div className="relative">
1290
1323
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-blue-500 rounded-md">
1291
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1324
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1292
1325
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
1293
1326
  </svg>
1294
1327
  </div>
@@ -1298,10 +1331,10 @@ def About(props=None):
1298
1331
  </p>
1299
1332
  </div>
1300
1333
 
1301
- {/* Feature 2 */}
1334
+
1302
1335
  <div className="relative">
1303
1336
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-purple-500 rounded-md">
1304
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1337
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1305
1338
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
1306
1339
  </svg>
1307
1340
  </div>
@@ -1311,10 +1344,10 @@ def About(props=None):
1311
1344
  </p>
1312
1345
  </div>
1313
1346
 
1314
- {/* Feature 3 */}
1347
+
1315
1348
  <div className="relative">
1316
1349
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-green-500 rounded-md">
1317
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1350
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1318
1351
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
1319
1352
  </svg>
1320
1353
  </div>
@@ -1324,10 +1357,10 @@ def About(props=None):
1324
1357
  </p>
1325
1358
  </div>
1326
1359
 
1327
- {/* Feature 4 */}
1360
+
1328
1361
  <div className="relative">
1329
1362
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-red-500 rounded-md">
1330
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1363
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1331
1364
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
1332
1365
  </svg>
1333
1366
  </div>
@@ -1337,10 +1370,10 @@ def About(props=None):
1337
1370
  </p>
1338
1371
  </div>
1339
1372
 
1340
- {/* Feature 5 */}
1373
+
1341
1374
  <div className="relative">
1342
1375
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-yellow-500 rounded-md">
1343
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1376
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1344
1377
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 00-1.065 2.572c1.756.426 1.756 2.924 0 3.35-1.756a1.724 1.724 0 00-1.066-2.573c1.756-.426 1.756-2.924 0-3.35 1.756a1.724 1.724 0 00-2.573-1.066c-1.756.426-1.756-2.924 0-3.35 1.756A1.724 1.724 0 006.573 2.572C3.31 7.76 1.574 8.686 4.317 8.686a1.724 1.724 0 00-1.066-2.572c1.756-.426 1.756-2.924 0-3.35 1.756a1.724 1.724 0 00-2.573-1.066c-1.756.426-1.756-2.924 0-3.35 1.756A1.724 1.724 0 001.066 2.572c1.756.426 1.756 2.924 0 3.35-1.756a1.724 1.724 0 002.573 1.066z" />
1345
1378
  </svg>
1346
1379
  </div>
@@ -1350,10 +1383,10 @@ def About(props=None):
1350
1383
  </p>
1351
1384
  </div>
1352
1385
 
1353
- {/* Feature 6 */}
1386
+
1354
1387
  <div className="relative">
1355
1388
  <div className="absolute flex items-center justify-center w-12 h-12 text-white bg-indigo-500 rounded-md">
1356
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1389
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1357
1390
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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" />
1358
1391
  </svg>
1359
1392
  </div>
@@ -1367,7 +1400,7 @@ def About(props=None):
1367
1400
  </div>
1368
1401
  </div>
1369
1402
 
1370
- {/* Interactive Demo Section */}
1403
+
1371
1404
  <div className="py-12 bg-gray-50">
1372
1405
  <div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
1373
1406
  <div className="text-center">
@@ -1380,11 +1413,11 @@ def About(props=None):
1380
1413
  </div>
1381
1414
 
1382
1415
  <div className="grid grid-cols-1 gap-8 mt-12 sm:grid-cols-2 lg:grid-cols-3">
1383
- {/* JSX Demo */}
1416
+
1384
1417
  <div className="p-6 transition-shadow bg-white rounded-lg shadow-lg hover:shadow-xl">
1385
1418
  <div className="text-center">
1386
1419
  <div className="flex items-center justify-center w-12 h-12 mx-auto mb-4 text-white bg-blue-500 rounded-md">
1387
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1420
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1388
1421
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
1389
1422
  </svg>
1390
1423
  </div>
@@ -1395,11 +1428,11 @@ def About(props=None):
1395
1428
  </button>
1396
1429
  </div>
1397
1430
 
1398
- {/* Tailwind Demo */}
1431
+
1399
1432
  <div className="p-6 transition-shadow bg-white rounded-lg shadow-lg hover:shadow-xl">
1400
1433
  <div className="text-center">
1401
1434
  <div className="flex items-center justify-center w-12 h-12 mx-auto mb-4 text-white bg-purple-500 rounded-md">
1402
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1435
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1403
1436
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
1404
1437
  </svg>
1405
1438
  </div>
@@ -1410,11 +1443,11 @@ def About(props=None):
1410
1443
  </button>
1411
1444
  </div>
1412
1445
 
1413
- {/* API Demo */}
1446
+
1414
1447
  <div className="p-6 transition-shadow bg-white rounded-lg shadow-lg hover:shadow-xl">
1415
1448
  <div className="text-center">
1416
1449
  <div className="flex items-center justify-center w-12 h-12 mx-auto mb-4 text-white bg-green-500 rounded-md">
1417
- <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1450
+ <svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1418
1451
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
1419
1452
  </svg>
1420
1453
  </div>
@@ -1429,7 +1462,7 @@ def About(props=None):
1429
1462
  </div>
1430
1463
  </div>
1431
1464
 
1432
- {/* Stats Section */}
1465
+
1433
1466
  <div className="bg-blue-600">
1434
1467
  <div className="px-4 py-12 mx-auto max-w-7xl sm:px-6 lg:px-8">
1435
1468
  <div className="grid grid-cols-2 gap-8 lg:grid-cols-4">
@@ -1453,12 +1486,12 @@ def About(props=None):
1453
1486
  </div>
1454
1487
  </div>
1455
1488
 
1456
- {/* Footer */}
1489
+
1457
1490
  <footer className="bg-gray-900">
1458
1491
  <div className="px-4 py-8 mx-auto max-w-7xl sm:px-6 lg:px-8">
1459
1492
  <div className="flex flex-col items-center space-y-4">
1460
1493
  <p className="text-base text-center text-gray-400">
1461
- Built with ❤️ using NextPy Framework
1494
+ Built with &hearts; using NextPy Framework
1462
1495
  </p>
1463
1496
  <div className="flex space-x-6">
1464
1497
  <a href="/" className="text-gray-400 hover:text-gray-300">Home</a>
@@ -1497,7 +1530,7 @@ def InteractiveDemo(props=None):
1497
1530
  </h1>
1498
1531
 
1499
1532
  <div className="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3">
1500
- {/* Counter Demo */}
1533
+
1501
1534
  <div className="p-6 bg-white shadow-lg rounded-xl">
1502
1535
  <h2 className="mb-4 text-2xl font-bold text-gray-900">Live Counter</h2>
1503
1536
  <div className="text-center">
@@ -1516,7 +1549,7 @@ def InteractiveDemo(props=None):
1516
1549
  </div>
1517
1550
  </div>
1518
1551
 
1519
- {/* Todo List Demo */}
1552
+
1520
1553
  <div className="p-6 bg-white shadow-lg rounded-xl">
1521
1554
  <h2 className="mb-4 text-2xl font-bold text-gray-900">Todo List</h2>
1522
1555
  <div className="space-y-4">
@@ -1527,12 +1560,12 @@ def InteractiveDemo(props=None):
1527
1560
  </button>
1528
1561
  </div>
1529
1562
  <ul id="todoList" className="space-y-2">
1530
- {/* Todos will be added here dynamically */}
1563
+
1531
1564
  </ul>
1532
1565
  </div>
1533
1566
  </div>
1534
1567
 
1535
- {/* Color Picker Demo */}
1568
+
1536
1569
  <div className="p-6 bg-white shadow-lg rounded-xl">
1537
1570
  <h2 className="mb-4 text-2xl font-bold text-gray-900">Color Picker</h2>
1538
1571
  <div className="space-y-4">
@@ -1543,7 +1576,7 @@ def InteractiveDemo(props=None):
1543
1576
  </div>
1544
1577
  </div>
1545
1578
 
1546
- {/* Form Validation Demo */}
1579
+
1547
1580
  <div className="p-6 bg-white shadow-lg rounded-xl">
1548
1581
  <h2 className="mb-4 text-2xl font-bold text-gray-900">Form Validation</h2>
1549
1582
  <form onsubmit="validateForm(event)" className="space-y-4">
@@ -1560,7 +1593,7 @@ def InteractiveDemo(props=None):
1560
1593
  </button>
1561
1594
  </form>
1562
1595
  <div id="validationResult" className="hidden p-4 mt-4 rounded-lg">
1563
- {/* Validation results will appear here */}
1596
+
1564
1597
  </div>
1565
1598
  </div>
1566
1599
  </div>
@@ -1594,13 +1627,13 @@ def Features(props=None):
1594
1627
 
1595
1628
  <div className="grid grid-cols-1 gap-12 md:grid-cols-2">
1596
1629
  <div className="space-y-12">
1597
- {/* Core Features */}
1630
+
1598
1631
  <div>
1599
1632
  <h2 className="mb-6 text-2xl font-bold text-gray-900">Core Features</h2>
1600
1633
  <div className="space-y-6">
1601
1634
  <div className="flex items-start space-x-4">
1602
1635
  <div className="flex-shrink-0 w-6 h-6 text-green-500">
1603
- <svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
1636
+ <svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1604
1637
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
1605
1638
  </svg>
1606
1639
  </div>
@@ -1612,7 +1645,7 @@ def Features(props=None):
1612
1645
 
1613
1646
  <div className="flex items-start space-x-4">
1614
1647
  <div className="flex-shrink-0 w-6 h-6 text-blue-500">
1615
- <svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
1648
+ <svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1616
1649
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
1617
1650
  </svg>
1618
1651
  </div>
@@ -1624,7 +1657,7 @@ def Features(props=None):
1624
1657
 
1625
1658
  <div className="flex items-start space-x-4">
1626
1659
  <div className="flex-shrink-0 w-6 h-6 text-purple-500">
1627
- <svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
1660
+ <svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1628
1661
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
1629
1662
  </svg>
1630
1663
  </div>
@@ -1636,13 +1669,13 @@ def Features(props=None):
1636
1669
  </div>
1637
1670
  </div>
1638
1671
 
1639
- {/* Development Features */}
1672
+
1640
1673
  <div>
1641
1674
  <h2 className="mb-6 text-2xl font-bold text-gray-900">Development Experience</h2>
1642
1675
  <div className="space-y-6">
1643
1676
  <div className="flex items-start space-x-4">
1644
1677
  <div className="flex-shrink-0 w-6 h-6 text-red-500">
1645
- <svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
1678
+ <svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1646
1679
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v16h16V4H4z" />
1647
1680
  </svg>
1648
1681
  </div>
@@ -1654,7 +1687,7 @@ def Features(props=None):
1654
1687
 
1655
1688
  <div className="flex items-start space-x-4">
1656
1689
  <div className="flex-shrink-0 w-6 h-6 text-yellow-500">
1657
- <svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
1690
+ <svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1658
1691
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.75 5H6.25v13l4.5 4.5z" />
1659
1692
  </svg>
1660
1693
  </div>
@@ -1666,7 +1699,7 @@ def Features(props=None):
1666
1699
 
1667
1700
  <div className="flex items-start space-x-4">
1668
1701
  <div className="flex-shrink-0 w-6 h-6 text-indigo-500">
1669
- <svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
1702
+ <svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
1670
1703
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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" />
1671
1704
  </svg>
1672
1705
  </div>
@@ -1707,7 +1740,7 @@ def GettingStarted(props=None):
1707
1740
  </div>
1708
1741
 
1709
1742
  <div className="space-y-16">
1710
- {/* Step 1 */}
1743
+
1711
1744
  <div className="p-8 rounded-lg bg-blue-50">
1712
1745
  <div className="flex items-center mb-4">
1713
1746
  <div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-blue-500 rounded-full">
@@ -1727,7 +1760,7 @@ def GettingStarted(props=None):
1727
1760
  </div>
1728
1761
  </div>
1729
1762
 
1730
- {/* Step 2 */}
1763
+
1731
1764
  <div className="p-8 rounded-lg bg-green-50">
1732
1765
  <div className="flex items-center mb-4">
1733
1766
  <div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-green-500 rounded-full">
@@ -1744,18 +1777,18 @@ def GettingStarted(props=None):
1744
1777
  <h3 className="mb-2 font-semibold text-gray-900">Project Structure</h3>
1745
1778
  <pre className="p-4 overflow-x-auto text-sm bg-gray-100 rounded">
1746
1779
  {`my-app/
1747
- ├── pages/ # Your pages and API routes
1748
- ├── components/ # Reusable components
1749
- ├── templates/ # HTML templates
1750
- ├── public/ # Static assets
1751
- ├── styles.css # Tailwind CSS
1752
- ├── main.py # Application entry point
1753
- └── requirements.txt # Python dependencies`}</pre>
1780
+ |-- pages/ # Your pages and API routes
1781
+ |-- components/ # Reusable components
1782
+ |-- templates/ # HTML templates
1783
+ |-- public/ # Static assets
1784
+ |-- styles.css # Tailwind CSS
1785
+ |-- main.py # Application entry point
1786
+ `-- requirements.txt # Python dependencies`}</pre>
1754
1787
  </div>
1755
1788
  </div>
1756
1789
  </div>
1757
1790
 
1758
- {/* Step 3 */}
1791
+
1759
1792
  <div className="p-8 rounded-lg bg-purple-50">
1760
1793
  <div className="flex items-center mb-4">
1761
1794
  <div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-purple-500 rounded-full">
@@ -1775,7 +1808,7 @@ def GettingStarted(props=None):
1775
1808
  </div>
1776
1809
  </div>
1777
1810
 
1778
- {/* Step 4 */}
1811
+
1779
1812
  <div className="p-8 rounded-lg bg-yellow-50">
1780
1813
  <div className="flex items-center mb-4">
1781
1814
  <div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-yellow-500 rounded-full">
@@ -1927,21 +1960,21 @@ default = Layout
1927
1960
  "css.value.unit": "rem"
1928
1961
  },
1929
1962
  "files.exclude": {
1930
- "**/__pycache__": true,
1931
- "**/*.pyc": true,
1932
- "**/node_modules": true,
1933
- "**/out": true,
1934
- "**/.next": true,
1935
- "**/.pytest_cache": true,
1936
- "**/.mypy_cache": true
1963
+ "*}__pycache__": true,
1964
+ "*}*.pyc": true,
1965
+ "*}node_modules": true,
1966
+ "*}out": true,
1967
+ "*}.next": true,
1968
+ "*}.pytest_cache": true,
1969
+ "*}.mypy_cache": true
1937
1970
  },
1938
1971
  "search.exclude": {
1939
- "**/node_modules": true,
1940
- "**/out": true,
1941
- "**/.next": true,
1942
- "**/__pycache__": true,
1943
- "**/.pytest_cache": true,
1944
- "**/.mypy_cache": true
1972
+ "*}node_modules": true,
1973
+ "*}out": true,
1974
+ "*}.next": true,
1975
+ "*}__pycache__": true,
1976
+ "*}.pytest_cache": true,
1977
+ "*}.mypy_cache": true
1945
1978
  },
1946
1979
  "python.linting.enabled": true,
1947
1980
  "python.linting.pylintEnabled": false,
@@ -2197,19 +2230,19 @@ This is a NextPy application with True JSX, Tailwind CSS, and comprehensive API
2197
2230
 
2198
2231
  ## Project Structure
2199
2232
  ```
2200
- ├── pages/ # File-based routing
2201
- ├── api/ # API routes
2202
- └── *.py # Page components
2203
- ├── components/ # Reusable components
2204
- ├── templates/ # HTML templates
2205
- ├── models/ # Database models
2206
- ├── utils/ # Utility functions
2207
- ├── hooks/ # Custom hooks
2208
- ├── middleware/ # Custom middleware
2209
- ├── tests/ # Test files
2210
- ├── public/ # Static assets
2211
- ├── styles/ # CSS files
2212
- └── docs/ # Documentation
2233
+ |-- pages/ # File-based routing
2234
+ | |-- api/ # API routes
2235
+ | `-- *.py # Page components
2236
+ |-- components/ # Reusable components
2237
+ |-- templates/ # HTML templates
2238
+ |-- models/ # Database models
2239
+ |-- utils/ # Utility functions
2240
+ |-- hooks/ # Custom hooks
2241
+ |-- middleware/ # Custom middleware
2242
+ |-- tests/ # Test files
2243
+ |-- public/ # Static assets
2244
+ |-- styles/ # CSS files
2245
+ `-- docs/ # Documentation
2213
2246
  ```
2214
2247
 
2215
2248
  ## Getting Started
@@ -2254,9 +2287,6 @@ import sys
2254
2287
  import subprocess
2255
2288
  from pathlib import Path
2256
2289
 
2257
- print(f"DEBUG: Current working directory: {Path.cwd()}")
2258
- print(f"DEBUG: sys.path before modification: {sys.path}")
2259
-
2260
2290
  # Compile Tailwind CSS using PostCSS
2261
2291
  try:
2262
2292
  print("Compiling Tailwind CSS...")
@@ -2268,8 +2298,6 @@ try:
2268
2298
  check=True
2269
2299
  )
2270
2300
  print("Tailwind CSS compiled successfully.")
2271
- if result.stdout:
2272
- print(f"CSS Output: {result.stdout[:200]}...")
2273
2301
  except subprocess.CalledProcessError as e:
2274
2302
  print(f"Error compiling Tailwind CSS: {e}")
2275
2303
  if e.stderr:
@@ -342,26 +342,34 @@ class ComponentRouter:
342
342
  return handler
343
343
 
344
344
  def _create_template_handler(self, file_path: Path) -> Optional[Callable]:
345
- """Load the traditional template-based handler"""
345
+ """Load the traditional template-based handler using JSX transformer"""
346
346
  try:
347
- spec = importlib.util.spec_from_file_location(
348
- file_path.stem,
349
- file_path
350
- )
351
- if spec and spec.loader:
352
- module = importlib.util.module_from_spec(spec)
353
- spec.loader.exec_module(module)
354
-
347
+ # Use JSX transformer for consistent loading
348
+ from ..jsx_transformer import JSXTransformer
349
+ transformer = JSXTransformer()
350
+ module = transformer.load_jsx_module(file_path, file_path.stem)
351
+
352
+ if module:
355
353
  for func_name in ["handler", "page", "get", "post", "default"]:
356
354
  if hasattr(module, func_name):
357
355
  return getattr(module, func_name)
358
-
359
- if hasattr(module, "Page"):
360
- return module.Page
356
+ except Exception:
357
+ # Fallback to regular import if JSX transformer fails
358
+ try:
359
+ spec = importlib.util.spec_from_file_location(
360
+ file_path.stem,
361
+ file_path
362
+ )
363
+ if spec and spec.loader:
364
+ module = importlib.util.module_from_spec(spec)
365
+ spec.loader.exec_module(module)
361
366
 
362
- except Exception as e:
363
- print(f"Error loading handler from {file_path}: {e}")
364
-
367
+ for func_name in ["handler", "page", "get", "post", "default"]:
368
+ if hasattr(module, func_name):
369
+ return getattr(module, func_name)
370
+ except Exception:
371
+ pass # Silently fail if both methods fail
372
+
365
373
  return None
366
374
 
367
375
  def _sort_routes(self) -> None:
@@ -164,26 +164,34 @@ class Router:
164
164
  )
165
165
 
166
166
  def _load_handler(self, file_path: Path) -> Optional[Callable]:
167
- """Dynamically load the handler function from a page file"""
167
+ """Dynamically load the handler function from a page file using JSX transformer"""
168
168
  try:
169
- spec = importlib.util.spec_from_file_location(
170
- file_path.stem,
171
- file_path
172
- )
173
- if spec and spec.loader:
174
- module = importlib.util.module_from_spec(spec)
175
- spec.loader.exec_module(module)
176
-
169
+ # Use JSX transformer for consistent loading
170
+ from ..jsx_transformer import JSXTransformer
171
+ transformer = JSXTransformer()
172
+ module = transformer.load_jsx_module(file_path, file_path.stem)
173
+
174
+ if module:
177
175
  for func_name in ["handler", "page", "get", "post", "default"]:
178
176
  if hasattr(module, func_name):
179
177
  return getattr(module, func_name)
180
-
181
- if hasattr(module, "Page"):
182
- return module.Page
183
-
184
178
  except Exception as e:
185
- print(f"Error loading handler from {file_path}: {e}")
186
-
179
+ # Fallback to regular import if JSX transformer fails
180
+ try:
181
+ spec = importlib.util.spec_from_file_location(
182
+ file_path.stem,
183
+ file_path
184
+ )
185
+ if spec and spec.loader:
186
+ module = importlib.util.module_from_spec(spec)
187
+ spec.loader.exec_module(module)
188
+
189
+ for func_name in ["handler", "page", "get", "post", "default"]:
190
+ if hasattr(module, func_name):
191
+ return getattr(module, func_name)
192
+ except Exception:
193
+ pass # Silently fail if both methods fail
194
+
187
195
  return None
188
196
 
189
197
  def _sort_routes(self) -> None:
@@ -131,34 +131,57 @@ class NextPyApp:
131
131
  # Add all routes from the router
132
132
  for route in self.router.get_all_routes():
133
133
  if route.is_api:
134
- # API routes
134
+ # API routes - FIXED: use default argument to capture route correctly
135
+ def create_api_handler(route_obj):
136
+ def api_handler(request, route=route_obj):
137
+ return self._handle_api_request(request, route, {})
138
+ return api_handler
139
+
135
140
  self.app.add_api_route(
136
141
  route.path,
137
- lambda request, r=route: self._handle_api_request(request, r, {}),
142
+ create_api_handler(route),
138
143
  methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
139
144
  )
140
145
  else:
141
- # Page routes
142
- async def page_handler(request):
143
- return await self._handle_request(request, route.path)
146
+ # Page routes - FIXED: use default argument to capture route correctly
147
+ def create_page_handler(route_path):
148
+ async def page_handler(request, path=route_path):
149
+ return await self._handle_request(request, path)
150
+ return page_handler
144
151
 
145
152
  self.app.add_route(
146
153
  route.path,
147
- page_handler,
154
+ create_page_handler(route.path),
148
155
  methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
149
156
  )
150
157
 
151
158
  def _load_module_from_file(self, file_path: Path) -> Optional[Any]:
152
- """Load a Python module from a file path"""
159
+ """Load a Python module from a file path with caching"""
153
160
  try:
161
+ # Convert relative path to absolute path
162
+ if not file_path.is_absolute():
163
+ file_path = Path.cwd() / file_path
164
+
165
+ # Create cache key
166
+ cache_key = str(file_path.resolve())
167
+
168
+ # Check cache first (unless in debug mode)
169
+ if not self.debug and cache_key in self._modules_cache:
170
+ return self._modules_cache[cache_key]
171
+
154
172
  module_name = f"nextpy_page_{file_path.stem}_{hash(str(file_path))}"
155
173
 
156
- spec = importlib.util.spec_from_file_location(module_name, file_path)
157
- if spec and spec.loader:
158
- module = importlib.util.module_from_spec(spec)
159
- sys.modules[module_name] = module
160
- spec.loader.exec_module(module)
161
- return module
174
+ # Use JSX transformer for JSX files
175
+ from nextpy.jsx_transformer import JSXTransformer
176
+ transformer = JSXTransformer()
177
+ module = transformer.load_jsx_module(file_path, module_name)
178
+
179
+ # Cache the module (unless in debug mode)
180
+ if module and not self.debug:
181
+ self._modules_cache[cache_key] = module
182
+
183
+ return module
184
+
162
185
  except Exception as e:
163
186
  if self.debug:
164
187
  print(f"Error loading module from {file_path}: {e}")
@@ -210,13 +233,29 @@ class NextPyApp:
210
233
 
211
234
  if module:
212
235
  props = await execute_data_fetching(module, context)
236
+
237
+ # Execute the page component to get JSX
238
+ content = ""
239
+ if hasattr(module, 'default'):
240
+ component = module.default
241
+ component_props = {**props, "params": params}
242
+ jsx_element = component(component_props)
213
243
 
244
+ # Convert JSX to HTML
245
+ try:
246
+ from nextpy.jsx import render_jsx
247
+ content = render_jsx(jsx_element)
248
+ except ImportError:
249
+ # Fail fast - JSX renderer is required
250
+ raise RuntimeError("JSX renderer not available. Please install nextpy.jsx module.")
251
+
214
252
  template_name = self._get_template_name(route, module)
215
253
 
216
254
  html = await self.renderer.render_async(
217
255
  template_name,
218
256
  context={
219
257
  **props,
258
+ "content": content,
220
259
  "params": params,
221
260
  "query": dict(request.query_params),
222
261
  "request": request,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextpy-framework
3
- Version: 2.4.4
3
+ Version: 2.4.5
4
4
  Summary: A Python web framework inspired by Next.js with file-based routing, SSR, and SSG and more
5
5
  Author: NextPy Team
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextpy-framework
3
- Version: 2.4.4
3
+ Version: 2.4.5
4
4
  Summary: A Python web framework inspired by Next.js with file-based routing, SSR, and SSG and more
5
5
  Author: NextPy Team
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "nextpy-framework"
7
- version = "2.4.4"
7
+ version = "2.4.5"
8
8
  description = "A Python web framework inspired by Next.js with file-based routing, SSR, and SSG and more"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"