nexios 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. nexios-0.1.0/PKG-INFO +249 -0
  2. nexios-0.1.0/nexios/__init__.py +33 -0
  3. nexios-0.1.0/nexios/application.py +161 -0
  4. nexios-0.1.0/nexios/background.py +44 -0
  5. nexios-0.1.0/nexios/cli/__init__.py +0 -0
  6. nexios-0.1.0/nexios/cli/create_project.py +161 -0
  7. nexios-0.1.0/nexios/cli/main.py +20 -0
  8. nexios-0.1.0/nexios/config/__init__.py +1 -0
  9. nexios-0.1.0/nexios/config/settings.py +21 -0
  10. nexios-0.1.0/nexios/decorators.py +62 -0
  11. nexios-0.1.0/nexios/filestorage.py +65 -0
  12. nexios-0.1.0/nexios/http/__init__.py +0 -0
  13. nexios-0.1.0/nexios/http/cookies_parser.py +30 -0
  14. nexios-0.1.0/nexios/http/mixins.py +32 -0
  15. nexios-0.1.0/nexios/http/parsers.py +161 -0
  16. nexios-0.1.0/nexios/http/request.py +208 -0
  17. nexios-0.1.0/nexios/http/response.py +550 -0
  18. nexios-0.1.0/nexios/middlewares/__init__.py +0 -0
  19. nexios-0.1.0/nexios/middlewares/base.py +16 -0
  20. nexios-0.1.0/nexios/middlewares/common.py +22 -0
  21. nexios-0.1.0/nexios/middlewares/cors.py +135 -0
  22. nexios-0.1.0/nexios/middlewares/logging.py +62 -0
  23. nexios-0.1.0/nexios/nexios.egg-info/PKG-INFO +238 -0
  24. nexios-0.1.0/nexios/nexios.egg-info/SOURCES.txt +0 -0
  25. nexios-0.1.0/nexios/nexios.egg-info/dependency_links.txt +1 -0
  26. nexios-0.1.0/nexios/nexios.egg-info/entry_points.txt +2 -0
  27. nexios-0.1.0/nexios/nexios.egg-info/requires.txt +6 -0
  28. nexios-0.1.0/nexios/nexios.egg-info/top_level.txt +1 -0
  29. nexios-0.1.0/nexios/routers.py +155 -0
  30. nexios-0.1.0/nexios/sessions/__init__.py +9 -0
  31. nexios-0.1.0/nexios/sessions/backends/__init__.py +0 -0
  32. nexios-0.1.0/nexios/sessions/backends/base.py +346 -0
  33. nexios-0.1.0/nexios/sessions/backends/db.py +117 -0
  34. nexios-0.1.0/nexios/sessions/backends/exceptions.py +40 -0
  35. nexios-0.1.0/nexios/sessions/middlewares.py +28 -0
  36. nexios-0.1.0/nexios/sessions/models.py +22 -0
  37. nexios-0.1.0/nexios/sessions/session_base.py +52 -0
  38. nexios-0.1.0/nexios/sessions/utils.py +26 -0
  39. nexios-0.1.0/nexios/static.py +54 -0
  40. nexios-0.1.0/nexios/structs.py +649 -0
  41. nexios-0.1.0/nexios/types.py +10 -0
  42. nexios-0.1.0/nexios/urlParsers.py +204 -0
  43. nexios-0.1.0/nexios/utils/__init__.py +0 -0
  44. nexios-0.1.0/nexios/utils/async_utils.py +18 -0
  45. nexios-0.1.0/nexios/utils/crypto.py +9 -0
  46. nexios-0.1.0/nexios/utils/cuncurrency.py +65 -0
  47. nexios-0.1.0/nexios/utils/db/__init__.py +0 -0
  48. nexios-0.1.0/nexios/utils/db/fields.py +79 -0
  49. nexios-0.1.0/nexios/utils/files.py +193 -0
  50. nexios-0.1.0/nexios/utils/signing.py +84 -0
  51. nexios-0.1.0/nexios/utils/timezone.py +336 -0
  52. nexios-0.1.0/nexios/validator/__init__.py +3 -0
  53. nexios-0.1.0/nexios/validator/base.py +84 -0
  54. nexios-0.1.0/nexios/validator/descriptor.py +49 -0
  55. nexios-0.1.0/nexios/validator/exceptions.py +4 -0
  56. nexios-0.1.0/nexios/validator/fields.py +419 -0
  57. nexios-0.1.0/nexios/validator/l.py +299 -0
  58. nexios-0.1.0/nexios/websockets/__init__.py +0 -0
  59. nexios-0.1.0/nexios/websockets/base.py +180 -0
  60. nexios-0.1.0/pyproject.toml +21 -0
  61. nexios-0.1.0/readme.md +224 -0
nexios-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.1
2
+ Name: nexios
3
+ Version: 0.1.0
4
+ Summary: Nexio is a modern, high-performance ASGI web framework for Python.
5
+ Home-page: https://github.com/techwithdunamix/nexio
6
+ License: MIT
7
+ Author: Chidebele Dunamis
8
+ Author-email: techwithdunamix@example.com
9
+ Requires-Python: >=3.8
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Dist: aerich
19
+ Requires-Dist: anyio
20
+ Requires-Dist: asgiref
21
+ Requires-Dist: tortoise-orm
22
+ Requires-Dist: uvicorn
23
+ Project-URL: Repository, https://github.com/techwithdunamix/nexio
24
+ Description-Content-Type: text/markdown
25
+
26
+ ![Nexio Logo](docs/logo.svg)
27
+
28
+ # Nexio HTTP Framework 🚀💻
29
+
30
+ Welcome to Nexio — a lightning-fast web framework built with Python and written by TechWithDunamix, a Nigerian developer! 🇳🇬💡 Whether you're building APIs, web apps, or anything in between, Nexio is here to make your life easier and faster! ⚡
31
+
32
+ ## Why Nexio? 🤔
33
+
34
+ - **Blazing Fast**: Built with performance in mind. Don't blink or you might miss it! ⚡
35
+ - **Simplicity**: Write less code, get more done. You'll spend less time debugging and more time building cool stuff. 👨‍💻
36
+ - **Easy to Use**: Everything is straightforward, from routing to database setup — no complicated setups, just plug and play! 🔌🎮
37
+
38
+ ## Quick Start 🚀
39
+
40
+ Ready to get started? Here's how you can set up Nexio and make your first web app in minutes:
41
+
42
+
43
+ ### 1. Install Dependencies 📦
44
+
45
+ Install Nexio and the required dependencies with pip:
46
+
47
+ ```bash
48
+ pip install git+https://github.com/TechWithDunamix/Nexio.git
49
+ ```
50
+
51
+ ### 2. Create Your First App 💻
52
+
53
+ ```bash
54
+ nexio create <app_name>
55
+ ```
56
+ ##### Outputs
57
+ ```md
58
+ To get started
59
+ 1. cd <app_name>
60
+
61
+ 2. cd <app_name>
62
+
63
+ 3. Your app will be available at http://localhost:8000
64
+ ```
65
+ # Folder structure
66
+
67
+ ```txt
68
+ project_name/
69
+ ├── config/
70
+ │ ├── __init__.py
71
+ │ ├── database.py
72
+ │ └── settings.py
73
+ ├── handlers/
74
+ │ ├── __init__.py
75
+ │ └── routes.py
76
+ └── main.py
77
+ ```
78
+
79
+
80
+ ### Basic Example
81
+
82
+ ```python
83
+ from nexio import get_application
84
+ import uvicorn
85
+ from nexio.routers import Routes
86
+ app = get_application()
87
+
88
+ async def home(req,res):
89
+ res.json({"text" :"hello welcome to nexio"})
90
+
91
+ app.add_route(Routes("/",home))
92
+ if __name__ == "__main__":
93
+ uvicorn.run(app, host="127.0.0.1", port=8000)
94
+ ```
95
+
96
+
97
+ # Nexio Project Structure Documentation
98
+
99
+
100
+ ```
101
+ project_name/
102
+ ├── config/
103
+ │ ├── __init__.py
104
+ │ ├── database.py
105
+ │ └── settings.py
106
+ ├── handlers/
107
+ │ ├── __init__.py
108
+ │ └── routes.py
109
+ └── main.py
110
+ ```
111
+
112
+ ## File Descriptions
113
+
114
+ ### main.py
115
+ The application entry point and core configuration file.
116
+ ```python
117
+ # Key responsibilities:
118
+ - Initializes the Nexio application
119
+ - Sets up database connections
120
+ - Configures startup/shutdown hooks
121
+ - Mounts routes
122
+ - Starts the ASGI server
123
+ ```
124
+
125
+ Key features:
126
+ - `get_application()`: Creates the main ASGI application instance
127
+ - `connect_db()`: Database connection setup on startup
128
+ - `disconnect_db()`: Clean database shutdown
129
+ - Uvicorn server configuration
130
+
131
+ ### config/database.py
132
+ Database configuration and connection settings.
133
+ ```python
134
+ # Key responsibilities:
135
+ - Defines database connection parameters
136
+ - Configures ORM settings
137
+ - Sets up model locations
138
+ ```
139
+
140
+ Key components:
141
+ - `TORTOISE_ORM`: ORM configuration dictionary
142
+ - Database URL configuration
143
+ - Model locations and namespacing
144
+ - Connection settings
145
+
146
+ ### config/settings.py
147
+ Application-wide configuration and settings.
148
+ ```python
149
+ # Key responsibilities:
150
+ - Defines core application settings
151
+ - Manages security configurations
152
+ - Sets environment-specific variables
153
+ ```
154
+
155
+ Key settings:
156
+ - `AppConfig`: Application configuration class
157
+ - `SECRET_KEY`: Security key for sessions/encryption
158
+ - Can be extended for additional settings:
159
+ - Debug modes
160
+ - API versions
161
+ - Environment configurations
162
+
163
+ ### handlers/routes.py
164
+ HTTP request handlers and route definitions.
165
+ ```python
166
+ # Key responsibilities:
167
+ - Defines endpoint handlers
168
+ - Processes HTTP requests
169
+ - Returns responses
170
+ ```
171
+
172
+ Key components:
173
+ - `home_handler`: Example route handler
174
+ - Request processing logic
175
+ - Response formatting
176
+ - URL parameter handling
177
+
178
+ ## Usage Notes
179
+
180
+ 1. **Configuration Priority**:
181
+ - `settings.py` loads first
182
+ - `database.py` uses settings for configuration
183
+ - `main.py` brings everything together
184
+
185
+ 2. **Database Management**:
186
+ - Uses Tortoise ORM
187
+ - Automatic schema generation
188
+ - Connection lifecycle management
189
+
190
+ 3. **Request Flow**:
191
+ ```
192
+ Request → main.py → routes.py → handler → response
193
+ ```
194
+
195
+ 4. **Development Workflow**:
196
+ 1. Modify settings in `config/`
197
+ 2. Add routes in `handlers/routes.py`
198
+ 3. Run application from `main.py`
199
+
200
+ ## Common Extensions
201
+
202
+ The basic structure can be extended with:
203
+
204
+ 1. **Additional Directories**:
205
+ - `models/`: Database models
206
+ - `middlewares/`: Custom middleware
207
+ - `schemas/`: Data validation
208
+ - `services/`: Business logic
209
+
210
+ 2. **Configuration Files**:
211
+ - `logging.py`: Logging configuration
212
+ - `middleware.py`: Middleware settings
213
+ - `constants.py`: Application constants
214
+
215
+ ## Best Practices
216
+
217
+ 1. **Configuration**:
218
+ - Keep sensitive data in environment variables
219
+ - Use different settings for development/production
220
+ - Document all configuration options
221
+
222
+ 2. **Route Handlers**:
223
+ - Keep handlers focused and simple
224
+ - Use type hints for better code clarity
225
+ - Return consistent response formats
226
+
227
+ 3. **Database**:
228
+ - Use migrations for schema changes
229
+ - Implement proper connection pooling
230
+ - Handle connection errors gracefully
231
+
232
+ ## Quick Start
233
+ ```bash
234
+ # 1. Install dependencies
235
+ pip install git+https://github.com/TechWithDunamix/Nexio.git
236
+
237
+
238
+ # 2. Run the application
239
+ uvicorn main:app --reload
240
+
241
+ # 3. Access the API
242
+ curl http://localhost:8000
243
+ ```
244
+
245
+ The application will be available at `http://localhost:8000` with:
246
+ - Database auto-configuration
247
+ - Basic route setup
248
+ - Error handling
249
+ - Clean shutdown support
@@ -0,0 +1,33 @@
1
+ from .application import NexioApp
2
+ from .sessions.middlewares import SessionMiddleware
3
+ from .middlewares.logging import ErrorHandlerMiddleware
4
+ from .middlewares.common import CommonMiddleware
5
+ from .config.settings import BaseConfig
6
+ from .routers import Router
7
+ from .middlewares.cors import CORSMiddleware
8
+ import os
9
+ def get_application(config = BaseConfig) -> NexioApp:
10
+ config=config()
11
+
12
+
13
+ app = NexioApp(
14
+ middlewares= [
15
+ ErrorHandlerMiddleware(),
16
+ CommonMiddleware(),
17
+ CORSMiddleware(
18
+ allow_origins=config.CORS_ALLOWED_ORIGINS,
19
+ blacklist_origins=config.CORS_BLACKLISTED_ORIGINS,
20
+ allow_methods=config.CORS_ALLOWED_METHODS,
21
+ allow_credentials=config.CORS_ALLOW_CREDENTIALS,
22
+ allow_headers=config.CORS_ALLOW_HEADERS,
23
+ expose_headers = config.EXPOSE_HEADERS,
24
+ allow_origin_regex=config.ALLOW_ORIGIN_REGEX
25
+
26
+
27
+ )
28
+
29
+ ],
30
+ config=config
31
+ )
32
+
33
+ return app
@@ -0,0 +1,161 @@
1
+ from typing import Any, Callable, AsyncIterator, List, Union
2
+ from .http.request import Request
3
+ from .http.response import NexioResponse
4
+ from .http.response import JSONResponse
5
+ from .types import HTTPMethod
6
+ from .decorators import AllowedMethods
7
+ from .routers import Router, Routes
8
+ from enum import Enum
9
+ from .config.settings import BaseConfig
10
+ import logging
11
+ from contextlib import asynccontextmanager
12
+
13
+ class NexioApp:
14
+ def __init__(self,
15
+ config: Enum = BaseConfig,
16
+ middlewares: list = None):
17
+ self.config = config
18
+ self.routes: List[str] = []
19
+ self.middlewares: List = middlewares or []
20
+ self.startup_handlers: List[Callable] = []
21
+ self.shutdown_handlers: List[Callable] = []
22
+ self.logger = logging.getLogger("nexio")
23
+
24
+ def on_startup(self, handler: Callable) -> Callable:
25
+ """Decorator to register startup handlers"""
26
+ self.startup_handlers.append(handler)
27
+ return handler
28
+
29
+ def on_shutdown(self, handler: Callable) -> Callable:
30
+ """Decorator to register shutdown handlers"""
31
+ self.shutdown_handlers.append(handler)
32
+ return handler
33
+
34
+ async def startup(self) -> None:
35
+ """Execute all startup handlers sequentially"""
36
+ for handler in self.startup_handlers:
37
+ await handler()
38
+
39
+ async def shutdown(self) -> None:
40
+ """Execute all shutdown handlers sequentially with error handling"""
41
+ for handler in self.shutdown_handlers:
42
+ try:
43
+ await handler()
44
+ except Exception as e:
45
+ self.logger.error(f"Shutdown handler error: {str(e)}")
46
+
47
+ async def handle_lifespan(self, receive: Callable, send: Callable) -> None:
48
+ """Handle ASGI lifespan protocol events"""
49
+ try:
50
+ while True:
51
+ message = await receive()
52
+
53
+ if message["type"] == "lifespan.startup":
54
+ try:
55
+ await self.startup()
56
+ await send({"type": "lifespan.startup.complete"})
57
+ except Exception as e:
58
+ self.logger.error(f"Startup error: {str(e)}")
59
+ await send({"type": "lifespan.startup.failed", "message": str(e)})
60
+ return
61
+
62
+ elif message["type"] == "lifespan.shutdown":
63
+ try:
64
+ await self.shutdown()
65
+ await send({"type": "lifespan.shutdown.complete"})
66
+ return
67
+ except Exception as e:
68
+ self.logger.error(f"Shutdown error: {str(e)}")
69
+ await send({"type": "lifespan.shutdown.failed", "message": str(e)})
70
+ return
71
+
72
+ except Exception as e:
73
+ self.logger.error(f"Lifespan error: {str(e)}")
74
+ if message["type"].startswith("lifespan.startup"):
75
+ await send({"type": "lifespan.startup.failed", "message": str(e)})
76
+ else:
77
+ await send({"type": "lifespan.shutdown.failed", "message": str(e)})
78
+
79
+ async def execute_middleware_stack(self,
80
+ request: Request,
81
+ response: NexioResponse,
82
+ middleware: Callable,
83
+ handler: Callable,
84
+ **kwargs) -> Any:
85
+ stack = self.middlewares.copy()
86
+ if callable(middleware):
87
+ stack.append(middleware)
88
+ index = -1
89
+
90
+ async def next_middleware():
91
+ nonlocal index
92
+ index += 1
93
+
94
+ if index < len(stack):
95
+ middleware = stack[index]
96
+ return await middleware(request, response, next_middleware, **kwargs)
97
+ else:
98
+ return await handler(request, response, **kwargs)
99
+
100
+ return await next_middleware()
101
+
102
+ async def handle_request(self, scope: dict, receive: Callable, send: Callable) -> None:
103
+ request = Request(scope, receive, send)
104
+ response = NexioResponse()
105
+ request.scope['config'] = self.config
106
+
107
+ for path_pattern, handler, middleware in self.routes:
108
+ match = path_pattern.match(request.url.path)
109
+ if match:
110
+ kwargs = match.groupdict()
111
+ request.url_params = kwargs
112
+
113
+ try:
114
+ await self.execute_middleware_stack(request,
115
+ response,
116
+ middleware,
117
+ handler)
118
+ except Exception as e:
119
+ self.logger.error(f"Request handler error: {str(e)}")
120
+ error_response = JSONResponse(
121
+ {"error": str(e)},
122
+ status_code=500
123
+ )
124
+ await error_response(scope, receive, send)
125
+ return
126
+ await response(scope, receive, send)
127
+ return
128
+
129
+ error_response = JSONResponse({"error": "Not found"}, status_code=404)
130
+ await error_response(scope, receive, send)
131
+
132
+ def route(self, path: str, methods: List[Union[str, HTTPMethod]] = None) -> Callable:
133
+ """Decorator to register routes with optional HTTP methods"""
134
+ def decorator(handler: Callable) -> Callable:
135
+ handler = AllowedMethods(methods)(handler)
136
+ self.add_route(Routes(path, handler))
137
+ return handler
138
+ return decorator
139
+
140
+ def add_route(self, route: Routes) -> None:
141
+ """Add a route to the application"""
142
+
143
+ route, handler, middleware = route()
144
+ self.routes.append((route, handler, middleware))
145
+
146
+ def add_middleware(self, middleware: Callable) -> None:
147
+ """Add middleware to the application"""
148
+ if callable(middleware):
149
+ self.middlewares.append(middleware)
150
+
151
+ def mount_router(self, router: Router) -> None:
152
+ """Mount a router and all its routes to the application"""
153
+ for route in router.get_routes():
154
+ self.add_route(route)
155
+
156
+ async def __call__(self, scope: dict, receive: Callable, send: Callable) -> None:
157
+ """ASGI application callable"""
158
+ if scope["type"] == "lifespan":
159
+ await self.handle_lifespan(receive, send)
160
+ elif scope["type"] == "http":
161
+ await self.handle_request(scope, receive, send)
@@ -0,0 +1,44 @@
1
+
2
+ from nexios.utils.cuncurrency import run_in_threadpool
3
+ from __future__ import annotations
4
+ import sys
5
+ import typing
6
+
7
+ if sys.version_info >= (3, 10):
8
+ from typing import ParamSpec
9
+ else:
10
+ from typing_extensions import ParamSpec
11
+
12
+
13
+
14
+ P = ParamSpec("P")
15
+ T = typing.TypeVar("T")
16
+ AwaitableCallable = typing.Callable[..., typing.Awaitable[T]]
17
+
18
+ @typing.overload
19
+ def is_async_callable(obj: AwaitableCallable[T]): ...
20
+ class BackgroundTask:
21
+ def __init__(self, func: typing.Callable[P, typing.Any], *args: P.args, **kwargs: P.kwargs) -> None:
22
+ self.func = func
23
+ self.args = args
24
+ self.kwargs = kwargs
25
+ self.is_async = is_async_callable(func)
26
+
27
+ async def __call__(self) -> None:
28
+ if self.is_async:
29
+ await self.func(*self.args, **self.kwargs)
30
+ else:
31
+ await run_in_threadpool(self.func, *self.args, **self.kwargs)
32
+
33
+
34
+ class BackgroundTasks(BackgroundTask):
35
+ def __init__(self, tasks: typing.Sequence[BackgroundTask] | None = None):
36
+ self.tasks = list(tasks) if tasks else []
37
+
38
+ def add_task(self, func: typing.Callable[P, typing.Any], *args: P.args, **kwargs: P.kwargs) -> None:
39
+ task = BackgroundTask(func, *args, **kwargs)
40
+ self.tasks.append(task)
41
+
42
+ async def __call__(self) -> None:
43
+ for task in self.tasks:
44
+ await task()
File without changes
@@ -0,0 +1,161 @@
1
+ import os
2
+
3
+ def create_project_structure(project_name: str):
4
+ """Create the basic project structure for a Nexio application."""
5
+
6
+ # Base directories
7
+ directories = [
8
+ f"{project_name}/controllers",
9
+ ]
10
+
11
+ # Create directories
12
+ for directory in directories:
13
+ os.makedirs(directory, exist_ok=True)
14
+ create_file(f"{directory}/__init__.py", "")
15
+
16
+ # Create main application files
17
+ create_file(f"{project_name}/main.py", main_code())
18
+ create_file(f"{project_name}/models.py", models_code())
19
+ create_file(f"{project_name}/settings.py", settings_code())
20
+ create_file(f"{project_name}/controllers/home_handler.py", routes_code())
21
+ create_file(f"{project_name}/README.md", readme_code())
22
+
23
+ print(f"\n✨ Created new Nexio project: {project_name}")
24
+ print("\nProject structure:")
25
+ print(f"""
26
+ {project_name}/
27
+ ├── controllers/
28
+ │ └── home_handler.py
29
+ ├── main.py
30
+ ├── models.py
31
+ ├── settings.py
32
+ └── README.md
33
+ """)
34
+
35
+ print("\nTo get started:")
36
+ print(f"1. cd {project_name}")
37
+ print("2. Install dependencies using `pip install -r requirements.txt`")
38
+ print("3. Run migrations using Aerich:")
39
+ print(" - `aerich init -t settings.TORTOISE_ORM`")
40
+ print(" - `aerich migrate`")
41
+ print(" - `aerich upgrade`")
42
+ print("4. Run the app with uvicorn:")
43
+ print(" - `uvicorn main:app --reload`")
44
+ print("\nYour app will be available at http://localhost:8000")
45
+
46
+ def create_file(file_path: str, content: str):
47
+ """Create a file with the given content."""
48
+ with open(file_path, "w") as f:
49
+ f.write(content)
50
+
51
+ def main_code():
52
+ return '''import uvicorn
53
+ from nexio import get_application
54
+ from nexio.routers import Routes
55
+ from tortoise import Tortoise as db
56
+ from contextlib import asynccontextmanager
57
+ import traceback
58
+ import os
59
+
60
+ from settings import AppConfig
61
+ from controllers.home_handler import home_handler
62
+
63
+ # Initialize app
64
+ app = get_application(config=AppConfig)
65
+
66
+ @app.on_startup
67
+ async def connect_db():
68
+ try:
69
+ db_path = os.path.join(os.path.dirname(__file__), "db.sqlite3")
70
+ await db.init(
71
+ db_url=f"sqlite:///{db_path}",
72
+ modules={"models": ["models"]} # Use models.py directly
73
+ )
74
+ await db.generate_schemas()
75
+ print("Database connected")
76
+ except Exception as e:
77
+ print(f"Database connection error: {e}")
78
+ print(traceback.format_exc())
79
+
80
+ @app.on_shutdown
81
+ async def disconnect_db():
82
+ try:
83
+ await db.close_connections()
84
+ print("Database disconnected")
85
+ except Exception as e:
86
+ print(f"Database disconnect error: {e}")
87
+
88
+ app.add_route(Routes("/", home_handler))
89
+
90
+ if __name__ == "__main__":
91
+ uvicorn.run(app, host="127.0.0.1", port=8000)
92
+ '''
93
+
94
+ def models_code():
95
+ return '''
96
+ '''
97
+
98
+ def settings_code():
99
+ return '''
100
+ import os
101
+ from nexio.config.settings import BaseConfig
102
+
103
+ migration = {
104
+ "connections": {
105
+ "default": f"sqlite://{os.path.join(os.path.dirname(__file__), 'database.db')}"
106
+ },
107
+ "apps": {
108
+ "models": {
109
+ "models": ["nexio.sessions.models","aerich.models"],
110
+ "default_connection": "default",
111
+ },
112
+ },
113
+ }
114
+
115
+ class AppConfig(BaseConfig):
116
+ SECRET_KEY = "your-secret-key" # Change this in production!
117
+ '''
118
+
119
+ def routes_code():
120
+ return '''from nexio.http.request import Request
121
+ from nexio.http.response import NexioResponse
122
+
123
+ async def home_handler(request: Request, response: NexioResponse, **kwargs):
124
+ return response.json({
125
+ "message": "Welcome to your new Nexio application!",
126
+ "docs": "https://nexio.example.com/docs"
127
+ })
128
+ '''
129
+
130
+ def readme_code():
131
+ return '''# Nexio Application Setup
132
+
133
+ ## Requirements
134
+ - Python 3.8 or later
135
+ - [Aerich](https://github.com/tortoise/aerich) for migrations
136
+ - [Uvicorn](https://www.uvicorn.org/) for running the app
137
+
138
+ ## Setup Instructions
139
+
140
+ 1. Install the required dependencies:
141
+ ```bash
142
+
143
+ Migrate the database: Run the following command to create the initial migration files:
144
+
145
+ ```bash
146
+
147
+ aerich init -t settings.migration
148
+ Then, run the following command to apply the migrations to the database:
149
+ ```
150
+ bash
151
+ ```
152
+ aerich migrate
153
+ aerich upgrade
154
+ ```
155
+ To start the application, use Uvicorn:
156
+
157
+ ``bash
158
+
159
+ uvicorn main:app --reload
160
+ ```
161
+ '''
@@ -0,0 +1,20 @@
1
+ import argparse
2
+ from nexios.cli.create_project import create_project_structure
3
+
4
+ def main():
5
+ parser = argparse.ArgumentParser(prog="nexio")
6
+ subparsers = parser.add_subparsers(dest="command")
7
+
8
+ # 'create' subcommand
9
+ create_parser = subparsers.add_parser('create', help="Create a new Nexio project")
10
+ create_parser.add_argument('project_name', type=str, help="The name of the project to create")
11
+
12
+ args = parser.parse_args()
13
+
14
+ if args.command == "create":
15
+ create_project_structure(args.project_name)
16
+ else:
17
+ parser.print_help()
18
+
19
+ if __name__ == "__main__":
20
+ main()
@@ -0,0 +1 @@
1
+ from .settings import BaseConfig
@@ -0,0 +1,21 @@
1
+
2
+ from typing import Any
3
+
4
+
5
+ class BaseConfig:
6
+
7
+ debug :bool = False
8
+
9
+ middleware :list = []
10
+
11
+ COOKIE_AGE = 259200
12
+
13
+
14
+ def __getattribute__(self, name: str) -> Any:
15
+ try:
16
+ return super().__getattribute__(name)
17
+
18
+ except AttributeError:
19
+ return None
20
+
21
+