nextpy-framework 2.4.3__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.
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/cli.py +136 -108
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/component_router.py +23 -15
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/router.py +23 -15
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/app.py +53 -11
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5/.nextpy_framework/nextpy_framework.egg-info}/PKG-INFO +1 -1
- {nextpy_framework-2.4.3/.nextpy_framework/nextpy_framework.egg-info → nextpy_framework-2.4.5}/PKG-INFO +1 -1
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/pyproject.toml +1 -1
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/__init__.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/auth.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/builder.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/__init__.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/debug/AutoDebug.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/debug/DebugIcon.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/debug/DebugIconFixed.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/feedback.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/form.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/head.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/hooks_provider.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/image.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/layout.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/link.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/loader.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/navigation.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/toast.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/ui.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/visual.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/config.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/__init__.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/builder.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/component_renderer.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/data_fetching.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/demo_pages_simple.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/demo_router.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/renderer.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/sync.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/db.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/dev_server.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/dev_tools.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/errors.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks_provider.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks_provider_new.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx_preprocessor.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx_transformer.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/main.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/performance.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/__init__.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/base.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/builtin.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/config.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/py.typed +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/security.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/__init__.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/debug.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/middleware.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/true_jsx.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/__init__.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/cache.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/email.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/file_upload.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/logging.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/search.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/seo.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/validators.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/websocket.py +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/SOURCES.txt +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/dependency_links.txt +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/entry_points.txt +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/requires.txt +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy_framework.egg-info/top_level.txt +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/LICENSE +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/README.md +0 -0
- {nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/setup.cfg +0 -0
- {nextpy_framework-2.4.3 → 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="
|
|
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.
|
|
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.
|
|
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
|
|
918
|
-
'./components
|
|
919
|
-
'./templates
|
|
920
|
-
'./app
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
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 →
|
|
1115
1149
|
</a>
|
|
1116
1150
|
</div>
|
|
1117
1151
|
|
|
1118
|
-
|
|
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=
|
|
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 →
|
|
1133
1167
|
</a>
|
|
1134
1168
|
</div>
|
|
1135
1169
|
|
|
1136
|
-
|
|
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=
|
|
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 →
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1249
|
+
Built with ♥ 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1494
|
+
Built with ♥ 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1563
|
+
|
|
1531
1564
|
</ul>
|
|
1532
1565
|
</div>
|
|
1533
1566
|
</div>
|
|
1534
1567
|
|
|
1535
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
-
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
1931
|
-
"
|
|
1932
|
-
"
|
|
1933
|
-
"
|
|
1934
|
-
"
|
|
1935
|
-
"
|
|
1936
|
-
"
|
|
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
|
-
"
|
|
1940
|
-
"
|
|
1941
|
-
"
|
|
1942
|
-
"
|
|
1943
|
-
"
|
|
1944
|
-
"
|
|
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
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
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:
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/component_router.py
RENAMED
|
@@ -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
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
|
|
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
|
-
|
|
360
|
-
|
|
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
|
-
|
|
363
|
-
|
|
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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
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,31 +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
|
-
|
|
142
|
+
create_api_handler(route),
|
|
138
143
|
methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
|
139
144
|
)
|
|
140
145
|
else:
|
|
141
|
-
# Page routes
|
|
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
|
|
151
|
+
|
|
142
152
|
self.app.add_route(
|
|
143
153
|
route.path,
|
|
144
|
-
|
|
154
|
+
create_page_handler(route.path),
|
|
145
155
|
methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
|
146
156
|
)
|
|
147
157
|
|
|
148
158
|
def _load_module_from_file(self, file_path: Path) -> Optional[Any]:
|
|
149
|
-
"""Load a Python module from a file path"""
|
|
159
|
+
"""Load a Python module from a file path with caching"""
|
|
150
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
|
+
|
|
151
172
|
module_name = f"nextpy_page_{file_path.stem}_{hash(str(file_path))}"
|
|
152
173
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
+
|
|
159
185
|
except Exception as e:
|
|
160
186
|
if self.debug:
|
|
161
187
|
print(f"Error loading module from {file_path}: {e}")
|
|
@@ -207,13 +233,29 @@ class NextPyApp:
|
|
|
207
233
|
|
|
208
234
|
if module:
|
|
209
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)
|
|
210
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
|
+
|
|
211
252
|
template_name = self._get_template_name(route, module)
|
|
212
253
|
|
|
213
254
|
html = await self.renderer.render_async(
|
|
214
255
|
template_name,
|
|
215
256
|
context={
|
|
216
257
|
**props,
|
|
258
|
+
"content": content,
|
|
217
259
|
"params": params,
|
|
218
260
|
"query": dict(request.query_params),
|
|
219
261
|
"request": request,
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nextpy-framework"
|
|
7
|
-
version = "2.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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/feedback.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/form.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/head.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/image.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/layout.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/link.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/loader.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/navigation.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/toast.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/components/visual.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/data_fetching.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/demo_pages_simple.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/core/demo_router.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks_provider.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/hooks_provider_new.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx_preprocessor.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/jsx_transformer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/builtin.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/plugins/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/server/middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/file_upload.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.3 → nextpy_framework-2.4.5}/.nextpy_framework/nextpy/utils/validators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|