lightapi 0.1.1__tar.gz → 0.1.3__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 (124) hide show
  1. {lightapi-0.1.1 → lightapi-0.1.3}/.github/workflows/python-publish.yml +53 -0
  2. {lightapi-0.1.1 → lightapi-0.1.3}/.github/workflows/test-dev.yml +11 -5
  3. lightapi-0.1.3/PKG-INFO +207 -0
  4. lightapi-0.1.3/README.md +156 -0
  5. {lightapi-0.1.1 → lightapi-0.1.3}/examples/auth_example.py +59 -43
  6. {lightapi-0.1.1 → lightapi-0.1.3}/examples/basic_rest_api.py +12 -9
  7. {lightapi-0.1.1 → lightapi-0.1.3}/examples/caching_example.py +73 -77
  8. {lightapi-0.1.1 → lightapi-0.1.3}/examples/custom_snippet.py +45 -25
  9. {lightapi-0.1.1 → lightapi-0.1.3}/examples/example.py +22 -22
  10. {lightapi-0.1.1 → lightapi-0.1.3}/examples/filtering_pagination_example.py +202 -93
  11. {lightapi-0.1.1 → lightapi-0.1.3}/examples/middleware_example.py +80 -72
  12. {lightapi-0.1.1 → lightapi-0.1.3}/examples/relationships_example.py +239 -165
  13. {lightapi-0.1.1 → lightapi-0.1.3}/examples/swagger_example.py +87 -80
  14. {lightapi-0.1.1 → lightapi-0.1.3}/examples/user_goal_example.py +46 -33
  15. {lightapi-0.1.1 → lightapi-0.1.3}/examples/validation_example.py +29 -23
  16. lightapi-0.1.3/lightapi/__init__.py +30 -0
  17. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/auth.py +26 -34
  18. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/base_endpoint.py +6 -6
  19. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/cache.py +15 -15
  20. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/config.py +29 -15
  21. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/core.py +172 -169
  22. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/database.py +9 -7
  23. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/exceptions.py +3 -3
  24. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/filters.py +11 -13
  25. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/handlers.py +29 -29
  26. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/lightapi.py +1 -1
  27. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/models.py +28 -24
  28. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/pagination.py +13 -13
  29. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/rest.py +79 -72
  30. {lightapi-0.1.1 → lightapi-0.1.3}/lightapi/swagger.py +41 -31
  31. {lightapi-0.1.1 → lightapi-0.1.3}/pyproject.toml +1 -1
  32. lightapi-0.1.3/test_simple_response.py +16 -0
  33. {lightapi-0.1.1 → lightapi-0.1.3}/tests/conftest.py +23 -24
  34. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_additional_features.py +29 -26
  35. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_auth.py +6 -3
  36. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_auth_example.py +124 -128
  37. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_basic_rest_api.py +50 -52
  38. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_cache.py +9 -7
  39. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_caching_example.py +180 -171
  40. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_core.py +25 -15
  41. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_custom_snippet.py +61 -43
  42. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_example.py +11 -9
  43. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_filtering_pagination_example.py +186 -152
  44. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_filters.py +3 -1
  45. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_helpers.py +13 -9
  46. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_integration.py +27 -21
  47. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_middleware.py +5 -3
  48. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_middleware_example.py +121 -116
  49. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_pagination.py +5 -3
  50. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_rest.py +39 -31
  51. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_swagger.py +11 -13
  52. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_validation_example.py +13 -13
  53. lightapi-0.1.1/PKG-INFO +0 -1231
  54. lightapi-0.1.1/README.md +0 -1180
  55. lightapi-0.1.1/lightapi/__init__.py +0 -24
  56. lightapi-0.1.1/test_simple_response.py +0 -14
  57. {lightapi-0.1.1 → lightapi-0.1.3}/.github/workflows/pages-publish.yml +0 -0
  58. {lightapi-0.1.1 → lightapi-0.1.3}/.gitignore +0 -0
  59. {lightapi-0.1.1 → lightapi-0.1.3}/.idx/dev.nix +0 -0
  60. {lightapi-0.1.1 → lightapi-0.1.3}/LICENSE +0 -0
  61. {lightapi-0.1.1 → lightapi-0.1.3}/docs/.pages +0 -0
  62. {lightapi-0.1.1 → lightapi-0.1.3}/docs/advanced/.pages +0 -0
  63. {lightapi-0.1.1 → lightapi-0.1.3}/docs/advanced/authentication.md +0 -0
  64. {lightapi-0.1.1 → lightapi-0.1.3}/docs/advanced/caching.md +0 -0
  65. {lightapi-0.1.1 → lightapi-0.1.3}/docs/advanced/filtering.md +0 -0
  66. {lightapi-0.1.1 → lightapi-0.1.3}/docs/advanced/middleware.md +0 -0
  67. {lightapi-0.1.1 → lightapi-0.1.3}/docs/advanced/pagination.md +0 -0
  68. {lightapi-0.1.1 → lightapi-0.1.3}/docs/advanced/validation.md +0 -0
  69. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/.pages +0 -0
  70. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/auth.md +0 -0
  71. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/cache.md +0 -0
  72. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/core.md +0 -0
  73. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/database.md +0 -0
  74. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/exceptions.md +0 -0
  75. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/filters.md +0 -0
  76. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/index.md +0 -0
  77. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/models.md +0 -0
  78. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/pagination.md +0 -0
  79. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/rest.md +0 -0
  80. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/swagger.md +0 -0
  81. {lightapi-0.1.1 → lightapi-0.1.3}/docs/api-reference/validation.md +0 -0
  82. {lightapi-0.1.1 → lightapi-0.1.3}/docs/deployment/.pages +0 -0
  83. {lightapi-0.1.1 → lightapi-0.1.3}/docs/deployment/docker.md +0 -0
  84. {lightapi-0.1.1 → lightapi-0.1.3}/docs/deployment/production.md +0 -0
  85. {lightapi-0.1.1 → lightapi-0.1.3}/docs/deployment/security.md +0 -0
  86. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/.pages +0 -0
  87. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/auth.md +0 -0
  88. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/basic-crud.md +0 -0
  89. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/basic-rest.md +0 -0
  90. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/caching.md +0 -0
  91. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/custom-application.md +0 -0
  92. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/filtering-pagination.md +0 -0
  93. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/middleware.md +0 -0
  94. {lightapi-0.1.1 → lightapi-0.1.3}/docs/examples/validation.md +0 -0
  95. {lightapi-0.1.1 → lightapi-0.1.3}/docs/getting-started/.pages +0 -0
  96. {lightapi-0.1.1 → lightapi-0.1.3}/docs/getting-started/configuration.md +0 -0
  97. {lightapi-0.1.1 → lightapi-0.1.3}/docs/getting-started/first-steps.md +0 -0
  98. {lightapi-0.1.1 → lightapi-0.1.3}/docs/getting-started/installation.md +0 -0
  99. {lightapi-0.1.1 → lightapi-0.1.3}/docs/getting-started/introduction.md +0 -0
  100. {lightapi-0.1.1 → lightapi-0.1.3}/docs/getting-started/quickstart.md +0 -0
  101. {lightapi-0.1.1 → lightapi-0.1.3}/docs/index.md +0 -0
  102. {lightapi-0.1.1 → lightapi-0.1.3}/docs/technical-reference/.pages +0 -0
  103. {lightapi-0.1.1 → lightapi-0.1.3}/docs/technical-reference/cache.md +0 -0
  104. {lightapi-0.1.1 → lightapi-0.1.3}/docs/technical-reference/core-api.md +0 -0
  105. {lightapi-0.1.1 → lightapi-0.1.3}/docs/technical-reference/endpoints.md +0 -0
  106. {lightapi-0.1.1 → lightapi-0.1.3}/docs/technical-reference/handlers.md +0 -0
  107. {lightapi-0.1.1 → lightapi-0.1.3}/docs/technical-reference/middleware.md +0 -0
  108. {lightapi-0.1.1 → lightapi-0.1.3}/docs/technical-reference/models.md +0 -0
  109. {lightapi-0.1.1 → lightapi-0.1.3}/docs/troubleshooting.md +0 -0
  110. {lightapi-0.1.1 → lightapi-0.1.3}/docs/tutorial/.pages +0 -0
  111. {lightapi-0.1.1 → lightapi-0.1.3}/docs/tutorial/basic-api.md +0 -0
  112. {lightapi-0.1.1 → lightapi-0.1.3}/docs/tutorial/database.md +0 -0
  113. {lightapi-0.1.1 → lightapi-0.1.3}/docs/tutorial/endpoints.md +0 -0
  114. {lightapi-0.1.1 → lightapi-0.1.3}/docs/tutorial/requests.md +0 -0
  115. {lightapi-0.1.1 → lightapi-0.1.3}/docs/tutorial/responses.md +0 -0
  116. {lightapi-0.1.1 → lightapi-0.1.3}/examples/README.md +0 -0
  117. {lightapi-0.1.1 → lightapi-0.1.3}/examples/__init__.py +0 -0
  118. {lightapi-0.1.1 → lightapi-0.1.3}/mkdocs.yml +0 -0
  119. {lightapi-0.1.1 → lightapi-0.1.3}/pytest.ini +0 -0
  120. {lightapi-0.1.1 → lightapi-0.1.3}/requirements.txt +0 -0
  121. {lightapi-0.1.1 → lightapi-0.1.3}/tests/__init__.py +0 -0
  122. {lightapi-0.1.1 → lightapi-0.1.3}/tests/test_clients.py +0 -0
  123. {lightapi-0.1.1 → lightapi-0.1.3}/update_version.py +0 -0
  124. {lightapi-0.1.1 → lightapi-0.1.3}/uv.lock +0 -0
@@ -127,3 +127,56 @@ jobs:
127
127
  git add pyproject.toml
128
128
  git commit -m "Bump version to ${{ steps.update_version.outputs.new_version }}" || exit 0
129
129
  git push
130
+
131
+ - name: Create Git Tag
132
+ run: |
133
+ git tag v${{ steps.update_version.outputs.new_version }}
134
+ git push origin v${{ steps.update_version.outputs.new_version }}
135
+
136
+ - name: Generate Release Notes
137
+ id: release_notes
138
+ run: |
139
+ # Get commits since last tag
140
+ LAST_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
141
+ if [ -z "$LAST_TAG" ]; then
142
+ # First release - get all commits
143
+ COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges HEAD~10..HEAD)
144
+ else
145
+ # Get commits since last tag
146
+ COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges $LAST_TAG..HEAD~1)
147
+ fi
148
+
149
+ # Create release notes file
150
+ cat > release_notes.md << EOF
151
+ ## 🚀 Release v${{ steps.update_version.outputs.new_version }}
152
+
153
+ ### What's Changed
154
+ $COMMITS
155
+
156
+ ### 📦 Installation
157
+ \`\`\`bash
158
+ pip install lightapi==${{ steps.update_version.outputs.new_version }}
159
+ \`\`\`
160
+
161
+ ### 📖 Documentation
162
+ - [Getting Started](https://iklobato.github.io/lightapi/getting-started/installation/)
163
+ - [API Reference](https://iklobato.github.io/lightapi/api-reference/core/)
164
+ - [Examples](https://iklobato.github.io/lightapi/examples/basic-rest/)
165
+
166
+ **Full Changelog**: https://github.com/iklobato/lightapi/compare/${LAST_TAG}...v${{ steps.update_version.outputs.new_version }}
167
+ EOF
168
+
169
+ echo "Generated release notes for v${{ steps.update_version.outputs.new_version }}"
170
+
171
+ - name: Create GitHub Release
172
+ uses: softprops/action-gh-release@v1
173
+ with:
174
+ tag_name: v${{ steps.update_version.outputs.new_version }}
175
+ name: "LightAPI v${{ steps.update_version.outputs.new_version }}"
176
+ body_path: release_notes.md
177
+ draft: false
178
+ prerelease: false
179
+ files: |
180
+ dist/lightapi-${{ steps.update_version.outputs.new_version }}-py3-none-any.whl
181
+ dist/lightapi-${{ steps.update_version.outputs.new_version }}.tar.gz
182
+ token: ${{ secrets.GITHUB_TOKEN }}
@@ -38,14 +38,20 @@ jobs:
38
38
  # Install linting tools
39
39
  pip install black isort flake8 mypy
40
40
 
41
- # Run code formatting checks
42
- black --check --diff .
41
+ # Run code formatting checks (warn only in development)
42
+ echo "🔍 Checking code formatting..."
43
+ black --check --diff . || echo "⚠️ Code formatting issues found, but not failing in development"
43
44
 
44
- # Run import sorting checks
45
- isort --check-only --diff .
45
+ # Run import sorting checks (warn only in development)
46
+ echo "🔍 Checking import sorting..."
47
+ isort --check-only --diff . || echo "⚠️ Import sorting issues found, but not failing in development"
46
48
 
47
- # Run style checks
49
+ # Run style checks (errors only)
50
+ echo "🔍 Checking critical style issues..."
48
51
  flake8 lightapi/ --count --select=E9,F63,F7,F82 --show-source --statistics
52
+
53
+ # Run additional style checks (warnings only)
54
+ echo "🔍 Checking style guidelines..."
49
55
  flake8 lightapi/ --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
50
56
 
51
57
  - name: Run tests
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: lightapi
3
+ Version: 0.1.3
4
+ Summary: A lightweight framework for building API endpoints using Python's native libraries.
5
+ Project-URL: Repository, https://github.com/henriqueblobato/LightApi
6
+ Project-URL: Issues, https://github.com/henriqueblobato/LightApi/issues
7
+ Project-URL: Homepage, https://github.com/henriqueblobato/LightApi
8
+ Author-email: iklobato <iklobato1@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,endpoint,framework,lightweight,rest,restful
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Topic :: Internet :: WWW/HTTP
20
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
21
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
22
+ Requires-Python: >=3.8.1
23
+ Requires-Dist: aiohttp<4.0.0,>=3.9.5
24
+ Requires-Dist: pyjwt<3.0.0,>=2.8.0
25
+ Requires-Dist: redis<6.0.0,>=5.0.0
26
+ Requires-Dist: sqlalchemy<3.0.0,>=2.0.30
27
+ Requires-Dist: starlette<1.0.0,>=0.37.0
28
+ Requires-Dist: uvicorn<1.0.0,>=0.30.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: black<24.0.0,>=23.3.0; extra == 'dev'
31
+ Requires-Dist: flake8<7.0.0,>=6.0.0; extra == 'dev'
32
+ Requires-Dist: isort<6.0.0,>=5.12.0; extra == 'dev'
33
+ Requires-Dist: mypy<2.0.0,>=1.3.0; extra == 'dev'
34
+ Requires-Dist: pytest<8.0.0,>=7.3.1; extra == 'dev'
35
+ Provides-Extra: docs
36
+ Requires-Dist: mkdocs-awesome-pages-plugin; extra == 'docs'
37
+ Requires-Dist: mkdocs-git-authors-plugin; extra == 'docs'
38
+ Requires-Dist: mkdocs-git-committers-plugin-2; extra == 'docs'
39
+ Requires-Dist: mkdocs-git-revision-date-localized-plugin; extra == 'docs'
40
+ Requires-Dist: mkdocs-glightbox; extra == 'docs'
41
+ Requires-Dist: mkdocs-material; extra == 'docs'
42
+ Requires-Dist: mkdocstrings[python]; extra == 'docs'
43
+ Provides-Extra: test
44
+ Requires-Dist: httpx<1.0.0,>=0.27.0; extra == 'test'
45
+ Requires-Dist: pyjwt<3.0.0,>=2.8.0; extra == 'test'
46
+ Requires-Dist: pytest<8.0.0,>=7.3.1; extra == 'test'
47
+ Requires-Dist: redis<6.0.0,>=5.0.0; extra == 'test'
48
+ Requires-Dist: starlette<1.0.0,>=0.37.0; extra == 'test'
49
+ Requires-Dist: uvicorn<1.0.0,>=0.30.0; extra == 'test'
50
+ Description-Content-Type: text/markdown
51
+
52
+ # LightAPI
53
+
54
+ [![PyPI version](https://badge.fury.io/py/lightapi.svg)](https://badge.fury.io/py/lightapi)
55
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
56
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
57
+
58
+ A lightweight, fast, and easy-to-use web API framework for Python with automatic REST endpoint generation, built-in authentication, caching, and more.
59
+
60
+ ## Features
61
+
62
+ - 🚀 **Zero-boilerplate REST APIs** - Automatically generate CRUD operations from SQLAlchemy models
63
+ - 🔐 **Built-in Authentication** - JWT authentication with automatic CORS handling
64
+ - ⚡ **High Performance** - Built on Starlette for async support and speed
65
+ - 💾 **Smart Caching** - Redis-based caching with automatic invalidation
66
+ - 📊 **Request Validation** - Automatic request validation and error handling
67
+ - 🔍 **Advanced Filtering** - Query filtering, pagination, and sorting out of the box
68
+ - 📖 **Auto Documentation** - Automatic OpenAPI/Swagger documentation generation
69
+ - 🔧 **Flexible Middleware** - Easy middleware system for custom logic
70
+ - 🗄️ **Database Integration** - Seamless SQLAlchemy integration with automatic table creation
71
+ - ⚙️ **Environment Configuration** - Easy configuration management
72
+
73
+ ## Quick Start
74
+
75
+ ### Installation
76
+
77
+ ```bash
78
+ pip install lightapi
79
+ ```
80
+
81
+ ### Basic Usage
82
+
83
+ ```python
84
+ from lightapi import LightApi
85
+ from lightapi.database import Base
86
+ from sqlalchemy import Column, Integer, String
87
+
88
+ # Define your model
89
+ class User(Base):
90
+ __tablename__ = "users"
91
+
92
+ id = Column(Integer, primary_key=True)
93
+ name = Column(String(50))
94
+ email = Column(String(100))
95
+
96
+ # Create API instance
97
+ app = LightApi()
98
+
99
+ # Register your model - automatically creates CRUD endpoints
100
+ app.register(User)
101
+
102
+ # Run the server
103
+ if __name__ == "__main__":
104
+ app.run()
105
+ ```
106
+
107
+ That's it! You now have a fully functional REST API with:
108
+ - `GET /users` - List all users with filtering and pagination
109
+ - `GET /users/{id}` - Get user by ID
110
+ - `POST /users` - Create new user
111
+ - `PUT /users/{id}` - Update user
112
+ - `DELETE /users/{id}` - Delete user
113
+ - `OPTIONS /users` - CORS preflight support
114
+
115
+ ## Documentation
116
+
117
+ Visit our comprehensive documentation at: https://iklobato.github.io/lightapi/
118
+
119
+ - [Getting Started Guide](https://iklobato.github.io/lightapi/getting-started/installation/)
120
+ - [API Reference](https://iklobato.github.io/lightapi/api-reference/core/)
121
+ - [Examples](https://iklobato.github.io/lightapi/examples/basic-rest/)
122
+
123
+ ## Advanced Features
124
+
125
+ ### Authentication
126
+
127
+ ```python
128
+ from lightapi.auth import JWTAuthentication
129
+
130
+ # Add JWT authentication
131
+ auth = JWTAuthentication(secret_key="your-secret-key")
132
+ app.add_middleware(auth)
133
+
134
+ # Protected endpoints automatically require valid JWT tokens
135
+ ```
136
+
137
+ ### Caching
138
+
139
+ ```python
140
+ from lightapi.cache import RedisCache
141
+
142
+ # Add Redis caching
143
+ cache = RedisCache(host="localhost", port=6379)
144
+ app.register(User, cache=cache, cache_ttl=300) # 5 minutes TTL
145
+ ```
146
+
147
+ ### Validation
148
+
149
+ ```python
150
+ from lightapi.rest import Validator
151
+
152
+ class UserValidator(Validator):
153
+ def validate_post(self, data):
154
+ if not data.get("email"):
155
+ raise ValueError("Email is required")
156
+ return data
157
+
158
+ app.register(User, validator=UserValidator())
159
+ ```
160
+
161
+ ### Middleware
162
+
163
+ ```python
164
+ from lightapi.core import Middleware
165
+
166
+ class LoggingMiddleware(Middleware):
167
+ async def process(self, request, call_next):
168
+ print(f"Request: {request.method} {request.url}")
169
+ response = await call_next(request)
170
+ print(f"Response: {response.status_code}")
171
+ return response
172
+
173
+ app.add_middleware(LoggingMiddleware())
174
+ ```
175
+
176
+ ## Why LightAPI?
177
+
178
+ - **Rapid Development**: Get REST APIs running in minutes, not hours
179
+ - **Production Ready**: Built-in security, caching, and error handling
180
+ - **Flexible**: Customize every aspect while keeping defaults simple
181
+ - **Modern**: Async support, type hints, and contemporary Python practices
182
+ - **Well Documented**: Comprehensive docs with real-world examples
183
+
184
+ ## Examples
185
+
186
+ Check out the [examples directory](./examples/) for complete applications:
187
+
188
+ - [Basic REST API](./examples/basic_rest_api.py) - Simple CRUD operations
189
+ - [Authentication](./examples/auth_example.py) - JWT authentication
190
+ - [Caching](./examples/caching_example.py) - Redis caching implementation
191
+ - [Validation](./examples/validation_example.py) - Request validation
192
+ - [Middleware](./examples/middleware_example.py) - Custom middleware
193
+ - [Filtering & Pagination](./examples/filtering_pagination_example.py) - Advanced queries
194
+
195
+ ## Contributing
196
+
197
+ Contributions are welcome! Please feel free to submit a Pull Request.
198
+
199
+ ## License
200
+
201
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
202
+
203
+ ---
204
+
205
+ **LightAPI** - *Making web APIs light and fast* ⚡
206
+
207
+ <!-- Testing development pipeline -->
@@ -0,0 +1,156 @@
1
+ # LightAPI
2
+
3
+ [![PyPI version](https://badge.fury.io/py/lightapi.svg)](https://badge.fury.io/py/lightapi)
4
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ A lightweight, fast, and easy-to-use web API framework for Python with automatic REST endpoint generation, built-in authentication, caching, and more.
8
+
9
+ ## Features
10
+
11
+ - 🚀 **Zero-boilerplate REST APIs** - Automatically generate CRUD operations from SQLAlchemy models
12
+ - 🔐 **Built-in Authentication** - JWT authentication with automatic CORS handling
13
+ - ⚡ **High Performance** - Built on Starlette for async support and speed
14
+ - 💾 **Smart Caching** - Redis-based caching with automatic invalidation
15
+ - 📊 **Request Validation** - Automatic request validation and error handling
16
+ - 🔍 **Advanced Filtering** - Query filtering, pagination, and sorting out of the box
17
+ - 📖 **Auto Documentation** - Automatic OpenAPI/Swagger documentation generation
18
+ - 🔧 **Flexible Middleware** - Easy middleware system for custom logic
19
+ - 🗄️ **Database Integration** - Seamless SQLAlchemy integration with automatic table creation
20
+ - ⚙️ **Environment Configuration** - Easy configuration management
21
+
22
+ ## Quick Start
23
+
24
+ ### Installation
25
+
26
+ ```bash
27
+ pip install lightapi
28
+ ```
29
+
30
+ ### Basic Usage
31
+
32
+ ```python
33
+ from lightapi import LightApi
34
+ from lightapi.database import Base
35
+ from sqlalchemy import Column, Integer, String
36
+
37
+ # Define your model
38
+ class User(Base):
39
+ __tablename__ = "users"
40
+
41
+ id = Column(Integer, primary_key=True)
42
+ name = Column(String(50))
43
+ email = Column(String(100))
44
+
45
+ # Create API instance
46
+ app = LightApi()
47
+
48
+ # Register your model - automatically creates CRUD endpoints
49
+ app.register(User)
50
+
51
+ # Run the server
52
+ if __name__ == "__main__":
53
+ app.run()
54
+ ```
55
+
56
+ That's it! You now have a fully functional REST API with:
57
+ - `GET /users` - List all users with filtering and pagination
58
+ - `GET /users/{id}` - Get user by ID
59
+ - `POST /users` - Create new user
60
+ - `PUT /users/{id}` - Update user
61
+ - `DELETE /users/{id}` - Delete user
62
+ - `OPTIONS /users` - CORS preflight support
63
+
64
+ ## Documentation
65
+
66
+ Visit our comprehensive documentation at: https://iklobato.github.io/lightapi/
67
+
68
+ - [Getting Started Guide](https://iklobato.github.io/lightapi/getting-started/installation/)
69
+ - [API Reference](https://iklobato.github.io/lightapi/api-reference/core/)
70
+ - [Examples](https://iklobato.github.io/lightapi/examples/basic-rest/)
71
+
72
+ ## Advanced Features
73
+
74
+ ### Authentication
75
+
76
+ ```python
77
+ from lightapi.auth import JWTAuthentication
78
+
79
+ # Add JWT authentication
80
+ auth = JWTAuthentication(secret_key="your-secret-key")
81
+ app.add_middleware(auth)
82
+
83
+ # Protected endpoints automatically require valid JWT tokens
84
+ ```
85
+
86
+ ### Caching
87
+
88
+ ```python
89
+ from lightapi.cache import RedisCache
90
+
91
+ # Add Redis caching
92
+ cache = RedisCache(host="localhost", port=6379)
93
+ app.register(User, cache=cache, cache_ttl=300) # 5 minutes TTL
94
+ ```
95
+
96
+ ### Validation
97
+
98
+ ```python
99
+ from lightapi.rest import Validator
100
+
101
+ class UserValidator(Validator):
102
+ def validate_post(self, data):
103
+ if not data.get("email"):
104
+ raise ValueError("Email is required")
105
+ return data
106
+
107
+ app.register(User, validator=UserValidator())
108
+ ```
109
+
110
+ ### Middleware
111
+
112
+ ```python
113
+ from lightapi.core import Middleware
114
+
115
+ class LoggingMiddleware(Middleware):
116
+ async def process(self, request, call_next):
117
+ print(f"Request: {request.method} {request.url}")
118
+ response = await call_next(request)
119
+ print(f"Response: {response.status_code}")
120
+ return response
121
+
122
+ app.add_middleware(LoggingMiddleware())
123
+ ```
124
+
125
+ ## Why LightAPI?
126
+
127
+ - **Rapid Development**: Get REST APIs running in minutes, not hours
128
+ - **Production Ready**: Built-in security, caching, and error handling
129
+ - **Flexible**: Customize every aspect while keeping defaults simple
130
+ - **Modern**: Async support, type hints, and contemporary Python practices
131
+ - **Well Documented**: Comprehensive docs with real-world examples
132
+
133
+ ## Examples
134
+
135
+ Check out the [examples directory](./examples/) for complete applications:
136
+
137
+ - [Basic REST API](./examples/basic_rest_api.py) - Simple CRUD operations
138
+ - [Authentication](./examples/auth_example.py) - JWT authentication
139
+ - [Caching](./examples/caching_example.py) - Redis caching implementation
140
+ - [Validation](./examples/validation_example.py) - Request validation
141
+ - [Middleware](./examples/middleware_example.py) - Custom middleware
142
+ - [Filtering & Pagination](./examples/filtering_pagination_example.py) - Advanced queries
143
+
144
+ ## Contributing
145
+
146
+ Contributions are welcome! Please feel free to submit a Pull Request.
147
+
148
+ ## License
149
+
150
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
151
+
152
+ ---
153
+
154
+ **LightAPI** - *Making web APIs light and fast* ⚡
155
+
156
+ <!-- Testing development pipeline -->
@@ -1,111 +1,121 @@
1
+ import datetime
2
+ import json
3
+
4
+ import jwt
1
5
  from sqlalchemy import Column, Integer, String
2
- from lightapi.core import LightApi, Response, Middleware
3
- from lightapi.rest import RestEndpoint
6
+
4
7
  from lightapi.auth import JWTAuthentication
5
- from lightapi.models import Base, register_model_class
6
8
  from lightapi.config import config
7
- import jwt
8
- import datetime
9
- import json
9
+ from lightapi.core import LightApi, Middleware, Response
10
+ from lightapi.models import Base, register_model_class
11
+ from lightapi.rest import RestEndpoint
12
+
10
13
 
11
14
  # Custom authentication class
12
15
  class CustomJWTAuth(JWTAuthentication):
13
16
  def __init__(self):
14
17
  super().__init__()
15
18
  self.secret_key = config.jwt_secret
16
-
19
+
17
20
  def authenticate(self, request):
18
21
  # Use the parent class implementation
19
22
  return super().authenticate(request)
20
23
 
24
+
21
25
  # Login endpoint to get a token
22
26
  class AuthEndpoint(RestEndpoint):
23
27
  __abstract__ = True # Not a database model
24
-
28
+
25
29
  def post(self, request):
26
- data = getattr(request, 'data', {})
27
- username = data.get('username')
28
- password = data.get('password')
29
-
30
+ data = getattr(request, "data", {})
31
+ username = data.get("username")
32
+ password = data.get("password")
33
+
30
34
  # Simple authentication (replace with database lookup in real apps)
31
35
  if username == "admin" and password == "password":
32
36
  # Create a JWT token
33
37
  payload = {
34
- 'sub': 'user_1',
35
- 'username': username,
36
- 'role': 'admin',
37
- 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
38
+ "sub": "user_1",
39
+ "username": username,
40
+ "role": "admin",
41
+ "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1),
38
42
  }
39
43
  token = jwt.encode(payload, config.jwt_secret, algorithm="HS256")
40
-
44
+
41
45
  return {"token": token}, 200
42
46
  else:
43
47
  return Response({"error": "Invalid credentials"}, status_code=401)
44
48
 
49
+
45
50
  # Protected resource that requires authentication
46
51
  class SecretResource(RestEndpoint):
47
52
  __abstract__ = True # Not a database model
48
-
53
+
49
54
  class Configuration:
50
55
  authentication_class = CustomJWTAuth
51
-
56
+
52
57
  def get(self, request):
53
58
  try:
54
59
  # Access the user info stored during authentication
55
- username = request.state.user.get('username')
56
- role = request.state.user.get('role')
57
-
60
+ username = request.state.user.get("username")
61
+ role = request.state.user.get("role")
62
+
58
63
  return {
59
64
  "message": f"Hello, {username}! You have {role} access.",
60
- "secret_data": "This is protected information"
65
+ "secret_data": "This is protected information",
61
66
  }, 200
62
67
  except Exception as e:
63
68
  import traceback
69
+
64
70
  print(f"Error in SecretResource.get: {e}")
65
71
  print(traceback.format_exc())
66
72
  return {"error": str(e)}, 500
67
73
 
74
+
68
75
  # Public endpoint that doesn't require authentication
69
76
  class PublicResource(RestEndpoint):
70
77
  __abstract__ = True # Not a database model
71
-
78
+
72
79
  def get(self, request):
73
80
  try:
74
81
  return {"message": "This is public information"}, 200
75
82
  except Exception as e:
76
83
  import traceback
84
+
77
85
  print(f"Error in PublicResource.get: {e}")
78
86
  print(traceback.format_exc())
79
87
  return {"error": str(e)}, 500
80
88
 
89
+
81
90
  # User profile endpoint that requires authentication
82
91
  @register_model_class
83
92
  class UserProfile(RestEndpoint):
84
- __tablename__ = 'user_profiles'
85
-
93
+ __tablename__ = "user_profiles"
94
+
86
95
  id = Column(Integer, primary_key=True)
87
96
  user_id = Column(String(50))
88
97
  full_name = Column(String(100))
89
98
  email = Column(String(100))
90
-
99
+
91
100
  class Configuration:
92
101
  authentication_class = CustomJWTAuth
93
-
102
+
94
103
  # Override GET to return only the current user's profile
95
104
  def get(self, request):
96
- user_id = request.state.user.get('sub')
105
+ user_id = request.state.user.get("sub")
97
106
  profile = self.session.query(self.__class__).filter_by(user_id=user_id).first()
98
-
107
+
99
108
  if profile:
100
109
  return {
101
110
  "id": profile.id,
102
111
  "user_id": profile.user_id,
103
112
  "full_name": profile.full_name,
104
- "email": profile.email
113
+ "email": profile.email,
105
114
  }, 200
106
115
  else:
107
116
  return Response({"error": "Profile not found"}, status_code=404)
108
117
 
118
+
109
119
  if __name__ == "__main__":
110
120
  app = LightApi(
111
121
  database_url="sqlite:///auth_example.db",
@@ -113,19 +123,25 @@ if __name__ == "__main__":
113
123
  swagger_version="1.0.0",
114
124
  swagger_description="Example showing JWT authentication with LightAPI",
115
125
  )
116
-
117
- app.register({
118
- '/auth/login': AuthEndpoint,
119
- '/public': PublicResource,
120
- '/secret': SecretResource,
121
- '/profile': UserProfile
122
- })
123
-
126
+
127
+ app.register(
128
+ {
129
+ "/auth/login": AuthEndpoint,
130
+ "/public": PublicResource,
131
+ "/secret": SecretResource,
132
+ "/profile": UserProfile,
133
+ }
134
+ )
135
+
124
136
  print("Server running at http://localhost:8000")
125
137
  print("API documentation available at http://localhost:8000/docs")
126
138
  print("\nTo get a token:")
127
- print("curl -X POST http://localhost:8000/auth/login -H 'Content-Type: application/json' -d '{\"username\": \"admin\", \"password\": \"password\"}'")
139
+ print(
140
+ 'curl -X POST http://localhost:8000/auth/login -H \'Content-Type: application/json\' -d \'{"username": "admin", "password": "password"}\''
141
+ )
128
142
  print("\nTo access protected resource:")
129
- print("curl -X GET http://localhost:8000/secret -H 'Authorization: Bearer YOUR_TOKEN'")
130
-
131
- app.run(host="localhost", port=8000, debug=True)
143
+ print(
144
+ "curl -X GET http://localhost:8000/secret -H 'Authorization: Bearer YOUR_TOKEN'"
145
+ )
146
+
147
+ app.run(host="localhost", port=8000, debug=True)
@@ -1,18 +1,20 @@
1
1
  from sqlalchemy import Column, Integer, String
2
+
2
3
  from lightapi.core import LightApi
3
- from lightapi.rest import RestEndpoint
4
4
  from lightapi.models import Base, register_model_class
5
+ from lightapi.rest import RestEndpoint
6
+
5
7
 
6
8
  # Define a model that inherits from RestEndpoint
7
9
  @register_model_class
8
10
  class User(RestEndpoint):
9
- __tablename__ = 'users'
10
-
11
+ __tablename__ = "users"
12
+
11
13
  id = Column(Integer, primary_key=True)
12
14
  name = Column(String(100))
13
15
  email = Column(String(100))
14
16
  role = Column(String(50))
15
-
17
+
16
18
  # The default implementation already includes:
17
19
  # - GET: List all users or get a specific user by ID
18
20
  # - POST: Create a new user
@@ -20,6 +22,7 @@ class User(RestEndpoint):
20
22
  # - DELETE: Delete a user
21
23
  # - OPTIONS: Return allowed methods
22
24
 
25
+
23
26
  if __name__ == "__main__":
24
27
  # Initialize the API with SQLite database
25
28
  app = LightApi(
@@ -28,12 +31,12 @@ if __name__ == "__main__":
28
31
  swagger_version="1.0.0",
29
32
  swagger_description="Simple REST API demonstrating basic CRUD operations",
30
33
  )
31
-
34
+
32
35
  # Register our endpoint
33
- app.register({'/users': User})
34
-
36
+ app.register({"/users": User})
37
+
35
38
  print("Server running at http://localhost:8000")
36
39
  print("API documentation available at http://localhost:8000/docs")
37
-
40
+
38
41
  # Run the server
39
- app.run(host="localhost", port=8000, debug=True)
42
+ app.run(host="localhost", port=8000, debug=True)