lightapi 0.1.6__tar.gz → 0.1.7__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 (130) hide show
  1. {lightapi-0.1.6 → lightapi-0.1.7}/PKG-INFO +1 -1
  2. {lightapi-0.1.6 → lightapi-0.1.7}/docs/advanced/authentication.md +4 -0
  3. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/rest.md +16 -1
  4. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/auth.md +20 -31
  5. {lightapi-0.1.6 → lightapi-0.1.7}/docs/index.md +27 -0
  6. {lightapi-0.1.6 → lightapi-0.1.7}/docs/tutorial/endpoints.md +15 -0
  7. {lightapi-0.1.6 → lightapi-0.1.7}/examples/README.md +36 -50
  8. lightapi-0.1.6/examples/auth_example.py → lightapi-0.1.7/examples/authentication_jwt.py +5 -11
  9. lightapi-0.1.7/examples/blog_post.py +57 -0
  10. lightapi-0.1.6/examples/caching_example.py → lightapi-0.1.7/examples/caching_redis_custom.py +2 -3
  11. lightapi-0.1.6/examples/user_goal_example.py → lightapi-0.1.7/examples/comprehensive_ideal_usage.py +4 -3
  12. lightapi-0.1.6/examples/filtering_pagination_example.py → lightapi-0.1.7/examples/filtering_pagination.py +3 -11
  13. lightapi-0.1.6/examples/example.py → lightapi-0.1.7/examples/general_usage.py +7 -10
  14. lightapi-0.1.7/examples/mega_example.py +660 -0
  15. lightapi-0.1.6/examples/custom_snippet.py → lightapi-0.1.7/examples/middleware_cors_auth.py +14 -27
  16. lightapi-0.1.6/examples/middleware_example.py → lightapi-0.1.7/examples/middleware_custom.py +4 -14
  17. lightapi-0.1.6/examples/relationships_example.py → lightapi-0.1.7/examples/relationships_sqlalchemy.py +31 -73
  18. lightapi-0.1.6/examples/basic_rest_api.py → lightapi-0.1.7/examples/rest_crud_basic.py +1 -1
  19. lightapi-0.1.6/examples/swagger_example.py → lightapi-0.1.7/examples/swagger_openapi_docs.py +5 -10
  20. lightapi-0.1.6/examples/validation_example.py → lightapi-0.1.7/examples/validation_custom_fields.py +1 -1
  21. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/auth.py +1 -3
  22. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/base_endpoint.py +1 -3
  23. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/config.py +6 -18
  24. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/core.py +56 -109
  25. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/database.py +12 -2
  26. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/exceptions.py +1 -2
  27. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/handlers.py +125 -64
  28. lightapi-0.1.7/lightapi/lightapi.py +719 -0
  29. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/models.py +57 -11
  30. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/rest.py +140 -27
  31. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/swagger.py +9 -35
  32. {lightapi-0.1.6 → lightapi-0.1.7}/pyproject.toml +1 -1
  33. lightapi-0.1.7/run_server.py +6 -0
  34. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_additional_features.py +2 -62
  35. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_auth.py +5 -2
  36. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_cache.py +7 -32
  37. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_caching_example.py +19 -160
  38. lightapi-0.1.7/tests/test_core.py +41 -0
  39. lightapi-0.1.7/tests/test_custom_snippet.py +40 -0
  40. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_filtering_pagination_example.py +7 -7
  41. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_filters.py +4 -24
  42. lightapi-0.1.7/tests/test_from_config.py +1149 -0
  43. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_helpers.py +3 -19
  44. lightapi-0.1.7/tests/test_integration.py +54 -0
  45. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_middleware.py +4 -0
  46. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_rest.py +1 -17
  47. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_swagger.py +2 -6
  48. lightapi-0.1.7/tests/test_validators.py +45 -0
  49. lightapi-0.1.7/uv.lock +3107 -0
  50. lightapi-0.1.6/lightapi/lightapi.py +0 -341
  51. lightapi-0.1.6/run_server.py +0 -6
  52. lightapi-0.1.6/tests/test_auth_example.py +0 -301
  53. lightapi-0.1.6/tests/test_basic_rest_api.py +0 -209
  54. lightapi-0.1.6/tests/test_core.py +0 -81
  55. lightapi-0.1.6/tests/test_custom_snippet.py +0 -328
  56. lightapi-0.1.6/tests/test_example.py +0 -56
  57. lightapi-0.1.6/tests/test_from_config.py +0 -932
  58. lightapi-0.1.6/tests/test_integration.py +0 -112
  59. lightapi-0.1.6/tests/test_middleware_example.py +0 -337
  60. lightapi-0.1.6/tests/test_validation_example.py +0 -210
  61. lightapi-0.1.6/uv.lock +0 -734
  62. {lightapi-0.1.6 → lightapi-0.1.7}/.github/workflows/pages-publish.yml +0 -0
  63. {lightapi-0.1.6 → lightapi-0.1.7}/.github/workflows/python-publish.yml +0 -0
  64. {lightapi-0.1.6 → lightapi-0.1.7}/.github/workflows/test-dev.yml +0 -0
  65. {lightapi-0.1.6 → lightapi-0.1.7}/.gitignore +0 -0
  66. {lightapi-0.1.6 → lightapi-0.1.7}/LICENSE +0 -0
  67. {lightapi-0.1.6 → lightapi-0.1.7}/README.md +0 -0
  68. {lightapi-0.1.6 → lightapi-0.1.7}/docs/.pages +0 -0
  69. {lightapi-0.1.6 → lightapi-0.1.7}/docs/advanced/.pages +0 -0
  70. {lightapi-0.1.6 → lightapi-0.1.7}/docs/advanced/caching.md +0 -0
  71. {lightapi-0.1.6 → lightapi-0.1.7}/docs/advanced/filtering.md +0 -0
  72. {lightapi-0.1.6 → lightapi-0.1.7}/docs/advanced/middleware.md +0 -0
  73. {lightapi-0.1.6 → lightapi-0.1.7}/docs/advanced/pagination.md +0 -0
  74. {lightapi-0.1.6 → lightapi-0.1.7}/docs/advanced/validation.md +0 -0
  75. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/.pages +0 -0
  76. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/auth.md +0 -0
  77. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/cache.md +0 -0
  78. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/core.md +0 -0
  79. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/database.md +0 -0
  80. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/exceptions.md +0 -0
  81. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/filters.md +0 -0
  82. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/index.md +0 -0
  83. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/models.md +0 -0
  84. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/pagination.md +0 -0
  85. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/swagger.md +0 -0
  86. {lightapi-0.1.6 → lightapi-0.1.7}/docs/api-reference/validation.md +0 -0
  87. {lightapi-0.1.6 → lightapi-0.1.7}/docs/deployment/.pages +0 -0
  88. {lightapi-0.1.6 → lightapi-0.1.7}/docs/deployment/docker.md +0 -0
  89. {lightapi-0.1.6 → lightapi-0.1.7}/docs/deployment/production.md +0 -0
  90. {lightapi-0.1.6 → lightapi-0.1.7}/docs/deployment/security.md +0 -0
  91. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/.pages +0 -0
  92. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/basic-crud.md +0 -0
  93. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/basic-rest.md +0 -0
  94. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/caching.md +0 -0
  95. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/custom-application.md +0 -0
  96. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/filtering-pagination.md +0 -0
  97. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/middleware.md +0 -0
  98. {lightapi-0.1.6 → lightapi-0.1.7}/docs/examples/validation.md +0 -0
  99. {lightapi-0.1.6 → lightapi-0.1.7}/docs/getting-started/.pages +0 -0
  100. {lightapi-0.1.6 → lightapi-0.1.7}/docs/getting-started/configuration.md +0 -0
  101. {lightapi-0.1.6 → lightapi-0.1.7}/docs/getting-started/first-steps.md +0 -0
  102. {lightapi-0.1.6 → lightapi-0.1.7}/docs/getting-started/installation.md +0 -0
  103. {lightapi-0.1.6 → lightapi-0.1.7}/docs/getting-started/introduction.md +0 -0
  104. {lightapi-0.1.6 → lightapi-0.1.7}/docs/getting-started/quickstart.md +0 -0
  105. {lightapi-0.1.6 → lightapi-0.1.7}/docs/technical-reference/.pages +0 -0
  106. {lightapi-0.1.6 → lightapi-0.1.7}/docs/technical-reference/cache.md +0 -0
  107. {lightapi-0.1.6 → lightapi-0.1.7}/docs/technical-reference/core-api.md +0 -0
  108. {lightapi-0.1.6 → lightapi-0.1.7}/docs/technical-reference/endpoints.md +0 -0
  109. {lightapi-0.1.6 → lightapi-0.1.7}/docs/technical-reference/handlers.md +0 -0
  110. {lightapi-0.1.6 → lightapi-0.1.7}/docs/technical-reference/middleware.md +0 -0
  111. {lightapi-0.1.6 → lightapi-0.1.7}/docs/technical-reference/models.md +0 -0
  112. {lightapi-0.1.6 → lightapi-0.1.7}/docs/troubleshooting.md +0 -0
  113. {lightapi-0.1.6 → lightapi-0.1.7}/docs/tutorial/.pages +0 -0
  114. {lightapi-0.1.6 → lightapi-0.1.7}/docs/tutorial/basic-api.md +0 -0
  115. {lightapi-0.1.6 → lightapi-0.1.7}/docs/tutorial/database.md +0 -0
  116. {lightapi-0.1.6 → lightapi-0.1.7}/docs/tutorial/requests.md +0 -0
  117. {lightapi-0.1.6 → lightapi-0.1.7}/docs/tutorial/responses.md +0 -0
  118. {lightapi-0.1.6 → lightapi-0.1.7}/examples/__init__.py +0 -0
  119. lightapi-0.1.6/tests/__init__.py → lightapi-0.1.7/examples/example.py +0 -0
  120. lightapi-0.1.6/tests/test_clients.py → lightapi-0.1.7/examples/user_goal_example.py +0 -0
  121. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/__init__.py +1 -1
  122. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/cache.py +0 -0
  123. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/filters.py +0 -0
  124. {lightapi-0.1.6 → lightapi-0.1.7}/lightapi/pagination.py +0 -0
  125. {lightapi-0.1.6 → lightapi-0.1.7}/mkdocs.yml +0 -0
  126. {lightapi-0.1.6 → lightapi-0.1.7}/pytest.ini +0 -0
  127. {lightapi-0.1.6 → lightapi-0.1.7}/requirements.txt +0 -0
  128. {lightapi-0.1.6 → lightapi-0.1.7}/tests/conftest.py +0 -0
  129. {lightapi-0.1.6 → lightapi-0.1.7}/tests/test_pagination.py +0 -0
  130. {lightapi-0.1.6 → lightapi-0.1.7}/update_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lightapi
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: A lightweight framework for building API endpoints using Python's native libraries.
5
5
  Project-URL: Repository, https://github.com/henriqueblobato/LightApi
6
6
  Project-URL: Issues, https://github.com/henriqueblobato/LightApi/issues
@@ -732,3 +732,7 @@ app.add_middleware([SecurityHeadersMiddleware])
732
732
  ```
733
733
 
734
734
  This comprehensive authentication system provides enterprise-grade security while maintaining the simplicity and performance that LightAPI is known for. The modular design allows you to implement exactly the authentication strategy your application needs, from simple API keys to complex multi-factor authentication systems.
735
+
736
+ > **Note:** All JWT-protected endpoints require the `LIGHTAPI_JWT_SECRET` environment variable to be set before running the server.
737
+
738
+ > **Custom endpoints must specify their intended paths using `route_patterns`. See the mega example for a full-stack authentication and registration demo.**
@@ -753,4 +753,19 @@ class User(RestEndpoint):
753
753
  - All required fields must be defined as NOT NULL in your database schema for correct enforcement.
754
754
  - The API will return 409 Conflict if you attempt to create or update a record missing a NOT NULL field, or violating a UNIQUE or FOREIGN KEY constraint.
755
755
 
756
- To start your API, always use `api.run(host, port)`. Do not use external libraries or 'app = api.app' to start the server directly.
756
+ To start your API, always use `api.run(host, port)`. Do not use external libraries or 'app = api.app' to start the server directly.
757
+
758
+ ## Custom Endpoint Registration with route_patterns
759
+
760
+ When registering custom (non-model) endpoints, you must specify the intended REST path(s) using the `route_patterns` attribute. Fallback to class names is not supported for custom endpoints.
761
+
762
+ ```python
763
+ class HelloWorldEndpoint(RestEndpoint):
764
+ route_patterns = ["/hello"]
765
+ def get(self, request):
766
+ return {"message": "Hello, World!"}
767
+
768
+ app.register(HelloWorldEndpoint)
769
+ ```
770
+
771
+ > See the mega example for a comprehensive demonstration of registering multiple endpoints with custom paths.
@@ -158,52 +158,41 @@ curl -X POST http://localhost:8000/auth/login \
158
158
  }
159
159
  ```
160
160
 
161
- ### 2. Access Public Endpoint
161
+ ### 2. Access User Profile (JWT-protected)
162
162
 
163
- ```bash
164
- curl http://localhost:8000/public
165
- ```
166
-
167
- **Response:**
168
- ```json
169
- {
170
- "message": "This is public information"
171
- }
172
- ```
173
-
174
- ### 3. Access Protected Endpoint
163
+ > **Note:** The `user_id` field in the profile must match the JWT `sub` claim (e.g., `user_1`).
175
164
 
176
165
  ```bash
177
- # Without token (will fail)
178
- curl http://localhost:8000/secret
179
- ```
180
-
181
- **Response:**
182
- ```json
183
- {
184
- "error": "Authentication failed"
185
- }
186
- ```
166
+ curl -X POST http://localhost:8000/user_profiles \
167
+ -H "Content-Type: application/json" \
168
+ -H "Authorization: Bearer YOUR_TOKEN" \
169
+ -d '{
170
+ "user_id": "user_1",
171
+ "full_name": "Admin User",
172
+ "email": "admin@example.com"
173
+ }'
187
174
 
188
- ```bash
189
- # With valid token
190
175
  curl -H "Authorization: Bearer YOUR_TOKEN" \
191
- http://localhost:8000/secret
176
+ http://localhost:8000/user_profiles
192
177
  ```
193
178
 
194
179
  **Response:**
195
180
  ```json
196
181
  {
197
- "message": "Hello, admin! You have admin access.",
198
- "secret_data": "This is protected information"
182
+ "id": 2,
183
+ "user_id": "user_1",
184
+ "full_name": "Admin User",
185
+ "email": "admin@example.com"
199
186
  }
200
187
  ```
201
188
 
202
- ### 4. Access User Profile
189
+ ### 3. Troubleshooting
190
+
191
+ - If you get `{ "error": "Profile not found" }`, ensure you created the profile with `user_id` matching the JWT `sub` claim.
192
+ - Always set the environment variable before running the server:
203
193
 
204
194
  ```bash
205
- curl -H "Authorization: Bearer YOUR_TOKEN" \
206
- http://localhost:8000/profile
195
+ export LIGHTAPI_JWT_SECRET="your-super-secret-key"
207
196
  ```
208
197
 
209
198
  ## JWT Token Structure
@@ -160,3 +160,30 @@ LightAPI is released under the [MIT License](https://github.com/henriqueblobato/
160
160
 
161
161
  > To start your API, always use `api.run(host, port)`. Do not use external libraries or 'app = api.app' to start the server directly.
162
162
 
163
+ ## Mega Example: All Features in One App
164
+
165
+ The `examples/mega_example.py` script demonstrates the full capabilities of LightAPI:
166
+ - RESTful models (products, categories, orders, users, etc.)
167
+ - Custom endpoints (auth, weather, hello, secret, public, etc.)
168
+ - JWT authentication and protected resources
169
+ - Middleware (logging, CORS, rate limiting, authentication)
170
+ - Caching, filtering, pagination, and more
171
+
172
+ **Available Endpoints:**
173
+
174
+ | Path | Methods | Description |
175
+ |-----------------------|--------------------------------------------|------------------------------|
176
+ | /products | GET, POST, PUT, PATCH, DELETE, OPTIONS | Product CRUD |
177
+ | /categories | GET, POST, PUT, PATCH, DELETE, OPTIONS | Category CRUD |
178
+ | /orders | GET, POST, PUT, PATCH, DELETE, OPTIONS | Order CRUD |
179
+ | /order_items | GET, POST, PUT, PATCH, DELETE, OPTIONS | Order item CRUD |
180
+ | /users | GET, POST, PUT, PATCH, DELETE, OPTIONS | User CRUD |
181
+ | /user_profiles | GET, POST, PUT, PATCH, DELETE, OPTIONS | User profile (JWT protected) |
182
+ | /auth/login | POST, OPTIONS | JWT login |
183
+ | /secret | GET, OPTIONS (JWT required) | Protected resource |
184
+ | /public | GET, OPTIONS | Public resource |
185
+ | /weather/{city} | GET, OPTIONS | Weather info (custom path) |
186
+ | /hello | GET, OPTIONS | Hello world (custom path) |
187
+
188
+ > All endpoints are registered with explicit RESTful or custom paths using `route_patterns` or `__tablename__`.
189
+
@@ -33,6 +33,21 @@ app = LightApi()
33
33
  app.register({'/custom-users': CustomUserEndpoint})
34
34
  ```
35
35
 
36
+ ## Registering Custom Endpoints with route_patterns
37
+
38
+ When defining a custom endpoint (not a SQLAlchemy model), always specify the intended path(s) using the `route_patterns` attribute:
39
+
40
+ ```python
41
+ class HelloWorldEndpoint(RestEndpoint):
42
+ route_patterns = ["/hello"]
43
+ def get(self, request):
44
+ return {"message": "Hello, World!"}
45
+
46
+ app.register(HelloWorldEndpoint)
47
+ ```
48
+
49
+ > See the mega example for a comprehensive demonstration of this pattern.
50
+
36
51
  ## HTTP Method Configuration
37
52
 
38
53
  - `http_method_names`: List of allowed HTTP methods.
@@ -2,9 +2,9 @@
2
2
 
3
3
  This directory contains example applications demonstrating various features of the LightAPI framework.
4
4
 
5
- ## Basic Examples
5
+ ## Example Features
6
6
 
7
- - **user_goal_example.py**: Comprehensive demonstration of intended LightAPI usage patterns
7
+ - **comprehensive_ideal_usage.py**: Comprehensive demonstration of intended LightAPI usage patterns
8
8
  - Shows the exact API design philosophy and usage as envisioned
9
9
  - Demonstrates custom validators with field-specific validation methods
10
10
  - Implements JWT authentication with proper configuration
@@ -13,17 +13,17 @@ This directory contains example applications demonstrating various features of t
13
13
  - Includes CORS support and proper environment variable usage
14
14
  - **Note**: Some advanced features (caching + pagination) are commented out due to current limitations
15
15
 
16
- - **basic_rest_api.py**: A simple REST API with default CRUD operations
16
+ - **rest_crud_basic.py**: A simple REST API with default CRUD operations
17
17
  - Demonstrates minimal setup for a REST endpoint
18
18
  - Shows automatic handling of GET, POST, PUT, DELETE operations
19
19
  - Illustrates SQLAlchemy model integration with LightAPI
20
20
 
21
- - **validation_example.py**: Data validation with custom validators
21
+ - **validation_custom_fields.py**: Data validation with custom validators
22
22
  - Shows field-specific validation rules using Validator class
23
23
  - Demonstrates error handling for validation failures
24
24
  - Illustrates data transformation (price conversion between dollars and cents)
25
25
 
26
- - **auth_example.py**: JWT authentication with protected resources
26
+ - **authentication_jwt.py**: JWT authentication with protected resources
27
27
  - Implements JWT token generation and verification
28
28
  - Shows protected endpoints requiring authentication
29
29
  - Demonstrates user information extraction from token
@@ -31,45 +31,31 @@ This directory contains example applications demonstrating various features of t
31
31
 
32
32
  ## Advanced Features
33
33
 
34
- - **custom_snippet.py**: Built-in middleware demonstration
34
+ - **middleware_cors_auth.py**: Built-in middleware demonstration
35
35
  - Shows new `CORSMiddleware` and `AuthenticationMiddleware` classes
36
36
  - Demonstrates automatic CORS preflight handling with JWT authentication
37
37
  - Illustrates seamless integration of authentication with CORS support
38
38
  - Uses built-in middleware for cleaner, more maintainable code
39
39
 
40
- - **middleware_example.py**: Custom middleware implementation for request/response processing
41
- - Demonstrates request/response lifecycle hooks
42
- - Includes logging middleware with request timing
43
- - Shows custom CORS headers management for cross-origin requests
44
- - Implements rate limiting with custom window controls
45
-
46
- - **filtering_pagination_example.py**: Query filtering and result pagination
47
- - Shows parameter-based filtering for REST endpoints
48
- - Implements custom filter logic for search and range queries
49
- - Demonstrates paginated results with metadata
50
- - Illustrates dynamic sorting by different fields
51
-
52
- - **caching_example.py**: Response caching for improved performance
53
- - Shows Redis cache implementation with automatic JSON serialization
54
- - Demonstrates cache key generation strategies
55
- - Includes time-to-live (TTL) management
56
- - Shows manual cache invalidation (DELETE operations)
57
- - Implements cache hit/miss HTTP headers
58
- - Fixed JSON serialization issues for proper caching
59
-
60
- - **swagger_example.py**: Enhanced OpenAPI/Swagger documentation
61
- - Demonstrates docstring-based API documentation
62
- - Shows custom SwaggerGenerator implementation
63
- - Illustrates request/response schema documentation
64
- - Implements API grouping with tags
65
- - Demonstrates security scheme definitions
66
-
67
- - **relationships_example.py**: Complex SQLAlchemy relationships (one-to-many, many-to-many)
68
- - Shows many-to-many relationships with association tables
69
- - Demonstrates one-to-many relationships with back references
70
- - Illustrates cascade behaviors on related objects
71
- - Shows nested data serialization across relationships
72
- - Implements relationship handling in POST/PUT operations
40
+ - **filtering_pagination.py**: Filtering and pagination
41
+ - Demonstrates filtering, pagination, and sorting of results
42
+ - Shows how to use query parameters for advanced queries
43
+
44
+ - **middleware_custom.py**: Custom middleware and order
45
+ - Demonstrates how to add custom middleware
46
+ - Shows the order of middleware execution
47
+ - Includes logging, CORS, and rate limiting examples
48
+
49
+ - **relationships_sqlalchemy.py**: SQLAlchemy relationships
50
+ - Demonstrates one-to-many and many-to-many relationships
51
+ - Shows how to query related resources
52
+
53
+ - **swagger_openapi_docs.py**: Swagger/OpenAPI documentation
54
+ - Shows how to generate and customize API documentation
55
+ - Demonstrates validator docstrings for better docs
56
+
57
+ - **general_usage.py**: General usage
58
+ - Shows custom validator, custom headers, and CRUD
73
59
 
74
60
  ## New Built-in Features (Latest Updates)
75
61
 
@@ -95,17 +81,17 @@ All examples now demonstrate improved CORS handling:
95
81
  Each example is self-contained and can be run directly:
96
82
 
97
83
  ```bash
98
- # Basic example
99
- python examples/basic_rest_api.py
84
+ # Basic REST/CRUD example
85
+ python examples/rest_crud_basic.py
100
86
 
101
- # Built-in middleware example (demonstrates new features)
102
- LIGHTAPI_JWT_SECRET="your-secret-key" python examples/custom_snippet.py
87
+ # Built-in middleware, CORS, Auth example
88
+ LIGHTAPI_JWT_SECRET="your-secret-key" python examples/middleware_cors_auth.py
103
89
 
104
- # Authentication with CORS
105
- LIGHTAPI_JWT_SECRET="your-secret-key" python examples/auth_example.py
90
+ # JWT Authentication example
91
+ LIGHTAPI_JWT_SECRET="your-secret-key" python examples/authentication_jwt.py
106
92
 
107
93
  # Caching with Redis (requires Redis running)
108
- python examples/caching_example.py
94
+ python examples/caching_redis_custom.py
109
95
  ```
110
96
 
111
97
  Most examples will:
@@ -119,11 +105,11 @@ Most examples will:
119
105
  The examples now include improved CORS and authentication. Test with:
120
106
 
121
107
  ```bash
122
- # Start the custom_snippet example
123
- LIGHTAPI_JWT_SECRET="test-secret-key-123" python examples/custom_snippet.py
108
+ # Start the middleware_cors_auth example
109
+ LIGHTAPI_JWT_SECRET="test-secret-key-123" python examples/middleware_cors_auth.py
124
110
 
125
- # Start the user goal example (comprehensive demonstration)
126
- LIGHTAPI_JWT_SECRET="test-secret-key-123" python examples/user_goal_example.py
111
+ # Start the comprehensive_ideal_usage example (comprehensive demonstration)
112
+ LIGHTAPI_JWT_SECRET="test-secret-key-123" python examples/comprehensive_ideal_usage.py
127
113
 
128
114
  # Test CORS preflight (should work without authentication)
129
115
  curl -X OPTIONS http://localhost:8000/custom -v
@@ -124,14 +124,10 @@ if __name__ == "__main__":
124
124
  swagger_description="Example showing JWT authentication with LightAPI",
125
125
  )
126
126
 
127
- app.register(
128
- {
129
- "/auth/login": AuthEndpoint,
130
- "/public": PublicResource,
131
- "/secret": SecretResource,
132
- "/profile": UserProfile,
133
- }
134
- )
127
+ app.register(AuthEndpoint)
128
+ app.register(PublicResource)
129
+ app.register(SecretResource)
130
+ app.register(UserProfile)
135
131
 
136
132
  print("Server running at http://localhost:8000")
137
133
  print("API documentation available at http://localhost:8000/docs")
@@ -140,8 +136,6 @@ if __name__ == "__main__":
140
136
  'curl -X POST http://localhost:8000/auth/login -H \'Content-Type: application/json\' -d \'{"username": "admin", "password": "password"}\''
141
137
  )
142
138
  print("\nTo access protected resource:")
143
- print(
144
- "curl -X GET http://localhost:8000/secret -H 'Authorization: Bearer YOUR_TOKEN'"
145
- )
139
+ print("curl -X GET http://localhost:8000/secret -H 'Authorization: Bearer YOUR_TOKEN'")
146
140
 
147
141
  app.run(host="localhost", port=8000, debug=True)
@@ -0,0 +1,57 @@
1
+ from datetime import datetime
2
+
3
+ from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Text
4
+ from sqlalchemy.orm import relationship
5
+
6
+ from lightapi import LightApi
7
+ from lightapi.database import Base
8
+ from lightapi.rest import RestEndpoint
9
+
10
+ print(f"DEBUG: LightApi loaded from {LightApi.__module__}")
11
+
12
+
13
+ class BlogPost(Base):
14
+ __tablename__ = "posts"
15
+
16
+ id = Column(Integer, primary_key=True)
17
+ title = Column(String(200), nullable=False)
18
+ content = Column(Text, nullable=False)
19
+ created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
20
+
21
+ comments = relationship("Comment", back_populates="post", cascade="all, delete-orphan")
22
+
23
+
24
+ class Comment(Base):
25
+ __tablename__ = "comments"
26
+
27
+ id = Column(Integer, primary_key=True)
28
+ content = Column(String(1000), nullable=False)
29
+ author = Column(String(100), nullable=False)
30
+ created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
31
+ post_id = Column(Integer, ForeignKey("posts.id"), nullable=False)
32
+
33
+ post = relationship("BlogPost", back_populates="comments")
34
+
35
+
36
+ class Endpoint(RestEndpoint):
37
+ __tablename__ = "asdasd"
38
+
39
+ def get(self, post_id: int):
40
+ return {"status": "ok"}, 200
41
+
42
+ def post(self, data: dict):
43
+ return {"status": "ok"}, 200
44
+
45
+
46
+ if __name__ == "__main__":
47
+ app = LightApi(
48
+ enable_swagger=True,
49
+ swagger_title="Blog Post API",
50
+ swagger_version="1.0.0",
51
+ swagger_description="API documentation for the Blog Post application",
52
+ )
53
+ app.register(BlogPost)
54
+ app.register(Comment)
55
+ app.register(Endpoint)
56
+
57
+ app.run(host="0.0.0.0", port=8000)
@@ -168,9 +168,8 @@ if __name__ == "__main__":
168
168
  swagger_description="Example showing caching capabilities with LightAPI",
169
169
  )
170
170
 
171
- app.register(
172
- {"/weather/{city}": WeatherEndpoint, "/resource": ConfigurableCacheEndpoint}
173
- )
171
+ app.register(WeatherEndpoint)
172
+ app.register(ConfigurableCacheEndpoint)
174
173
 
175
174
  print("Server running at http://localhost:8000")
176
175
  print("API documentation available at http://localhost:8000/docs")
@@ -47,10 +47,10 @@ class Company(RestEndpoint):
47
47
  validator_class = CustomEndpointValidator
48
48
  filter_class = ParameterFilter
49
49
 
50
- def post(self, request):
50
+ async def post(self, request):
51
51
  """Handle POST requests with custom Response object"""
52
52
  return Response(
53
- {"data": "ok", "request_data": getattr(request, "data", {})},
53
+ {"data": "ok", "request_data": await request.get_data()},
54
54
  status_code=200,
55
55
  content_type="application/json",
56
56
  )
@@ -126,7 +126,8 @@ class CustomCORSMiddleware(Middleware):
126
126
  app = LightApi()
127
127
 
128
128
  # Register endpoints
129
- app.register({"/custom": CustomEndpoint, "/company": Company})
129
+ app.register(CustomEndpoint)
130
+ app.register(Company)
130
131
 
131
132
  # Add middleware
132
133
  # Note: Custom auth middleware is commented out to avoid blocking all requests
@@ -92,9 +92,7 @@ class ProductPaginator(Paginator):
92
92
 
93
93
  # Validate the sort field
94
94
  if sort_field in self.valid_sort_fields:
95
- column = getattr(
96
- queryset.column_descriptions[0]["type"], sort_field
97
- )
95
+ column = getattr(queryset.column_descriptions[0]["type"], sort_field)
98
96
  if descending:
99
97
  queryset = queryset.order_by(column.desc())
100
98
  else:
@@ -241,9 +239,7 @@ def init_database():
241
239
  category="Clothing",
242
240
  description="Cotton t-shirt",
243
241
  ),
244
- Product(
245
- name="Jeans", price=6000, category="Clothing", description="Denim jeans"
246
- ),
242
+ Product(name="Jeans", price=6000, category="Clothing", description="Denim jeans"),
247
243
  Product(
248
244
  name="Sneakers",
249
245
  price=8000,
@@ -341,11 +337,7 @@ if __name__ == "__main__":
341
337
  swagger_description="Example showing filtering and pagination with LightAPI",
342
338
  )
343
339
 
344
- app.register(
345
- {
346
- "/products": Product,
347
- }
348
- )
340
+ app.register(Product)
349
341
 
350
342
  print("Server running at http://localhost:8000")
351
343
  print("API documentation available at http://localhost:8000/docs")
@@ -36,13 +36,13 @@ class Company(RestEndpoint):
36
36
  validator_class = CustomEndpointValidator
37
37
  filter_class = ParameterFilter
38
38
 
39
- def post(self, request):
39
+ async def post(self, request):
40
40
  """Create a new company.
41
41
 
42
42
  Accepts company data and creates a new record.
43
43
  """
44
44
  return Response(
45
- {"data": "ok", "request_data": request.data},
45
+ {"data": "ok", "request_data": await request.get_data()},
46
46
  status_code=200,
47
47
  content_type="application/json",
48
48
  )
@@ -76,7 +76,7 @@ class CustomEndpoint(RestEndpoint):
76
76
  caching_method_names = ["GET"]
77
77
  pagination_class = CustomPaginator
78
78
 
79
- def post(self, request):
79
+ async def post(self, request):
80
80
  return {"data": "ok"}, 200
81
81
 
82
82
  def get(self, request):
@@ -97,12 +97,8 @@ class CORSMiddleware(Middleware):
97
97
 
98
98
  if hasattr(response, "headers"):
99
99
  response.headers["Access-Control-Allow-Origin"] = "*"
100
- response.headers[
101
- "Access-Control-Allow-Methods"
102
- ] = "GET, POST, PUT, DELETE, OPTIONS"
103
- response.headers[
104
- "Access-Control-Allow-Headers"
105
- ] = "Authorization, Content-Type"
100
+ response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
101
+ response.headers["Access-Control-Allow-Headers"] = "Authorization, Content-Type"
106
102
 
107
103
  if request.method == "OPTIONS":
108
104
  return Response(status_code=200)
@@ -116,7 +112,8 @@ if __name__ == "__main__":
116
112
  swagger_version="1.0.0",
117
113
  swagger_description="Example API for demonstrating LightAPI capabilities",
118
114
  )
119
- app.register({"/companies": Company, "/custom": CustomEndpoint})
115
+ app.register(Company)
116
+ app.register(CustomEndpoint)
120
117
  # app.add_middleware([MyCustomMiddleware, CORSMiddleware])
121
118
 
122
119
  print("Server running at http://0.0.0.0:8000")