lightapi 0.1.3__tar.gz → 0.1.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.
- {lightapi-0.1.3 → lightapi-0.1.5}/PKG-INFO +67 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/README.md +65 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/auth.md +4 -2
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/cache.md +3 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/core.md +5 -13
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/models.md +3 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/rest.md +9 -3
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/auth.md +3 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/getting-started/configuration.md +26 -0
- lightapi-0.1.5/docs/getting-started/quickstart.md +91 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/index.md +11 -3
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/technical-reference/core-api.md +1 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/README.md +4 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/__init__.py +1 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/handlers.py +133 -83
- lightapi-0.1.5/lightapi/lightapi.py +341 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/models.py +26 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/pyproject.toml +2 -1
- {lightapi-0.1.3 → lightapi-0.1.5}/requirements.txt +2 -1
- lightapi-0.1.5/run_server.py +6 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_basic_rest_api.py +0 -25
- lightapi-0.1.5/tests/test_from_config.py +932 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_middleware_example.py +0 -19
- lightapi-0.1.3/.idx/dev.nix +0 -38
- lightapi-0.1.3/docs/getting-started/quickstart.md +0 -47
- lightapi-0.1.3/lightapi/lightapi.py +0 -110
- lightapi-0.1.3/test_simple_response.py +0 -16
- {lightapi-0.1.3 → lightapi-0.1.5}/.github/workflows/pages-publish.yml +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/.github/workflows/python-publish.yml +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/.github/workflows/test-dev.yml +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/.gitignore +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/LICENSE +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/advanced/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/advanced/authentication.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/advanced/caching.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/advanced/filtering.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/advanced/middleware.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/advanced/pagination.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/advanced/validation.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/database.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/exceptions.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/filters.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/index.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/pagination.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/swagger.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/api-reference/validation.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/deployment/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/deployment/docker.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/deployment/production.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/deployment/security.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/basic-crud.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/basic-rest.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/caching.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/custom-application.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/filtering-pagination.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/middleware.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/examples/validation.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/getting-started/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/getting-started/first-steps.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/getting-started/installation.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/getting-started/introduction.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/technical-reference/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/technical-reference/cache.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/technical-reference/endpoints.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/technical-reference/handlers.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/technical-reference/middleware.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/technical-reference/models.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/troubleshooting.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/tutorial/.pages +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/tutorial/basic-api.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/tutorial/database.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/tutorial/endpoints.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/tutorial/requests.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/docs/tutorial/responses.md +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/__init__.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/auth_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/basic_rest_api.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/caching_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/custom_snippet.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/filtering_pagination_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/middleware_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/relationships_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/swagger_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/user_goal_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/examples/validation_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/auth.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/base_endpoint.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/cache.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/config.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/core.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/database.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/exceptions.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/filters.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/pagination.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/rest.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/lightapi/swagger.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/mkdocs.yml +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/pytest.ini +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/__init__.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/conftest.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_additional_features.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_auth.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_auth_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_cache.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_caching_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_clients.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_core.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_custom_snippet.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_filtering_pagination_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_filters.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_helpers.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_integration.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_middleware.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_pagination.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_rest.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_swagger.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/tests/test_validation_example.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/update_version.py +0 -0
- {lightapi-0.1.3 → lightapi-0.1.5}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lightapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
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
|
|
@@ -22,6 +22,7 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
|
22
22
|
Requires-Python: >=3.8.1
|
|
23
23
|
Requires-Dist: aiohttp<4.0.0,>=3.9.5
|
|
24
24
|
Requires-Dist: pyjwt<3.0.0,>=2.8.0
|
|
25
|
+
Requires-Dist: pyyaml>=5.1
|
|
25
26
|
Requires-Dist: redis<6.0.0,>=5.0.0
|
|
26
27
|
Requires-Dist: sqlalchemy<3.0.0,>=2.0.30
|
|
27
28
|
Requires-Dist: starlette<1.0.0,>=0.37.0
|
|
@@ -112,6 +113,66 @@ That's it! You now have a fully functional REST API with:
|
|
|
112
113
|
- `DELETE /users/{id}` - Delete user
|
|
113
114
|
- `OPTIONS /users` - CORS preflight support
|
|
114
115
|
|
|
116
|
+
## Dynamic API from YAML Config (SQLAlchemy Reflection)
|
|
117
|
+
|
|
118
|
+
LightAPI can instantly generate a REST API from a YAML configuration file, reflecting your database schema at runtime using SQLAlchemy. This is ideal for exposing existing databases with zero model code.
|
|
119
|
+
|
|
120
|
+
### How It Works
|
|
121
|
+
- **Reflects** the schema of specified tables from your database (PostgreSQL, MySQL, SQLite, etc.)
|
|
122
|
+
- **Dynamically generates** SQLAlchemy models and CRUD endpoints for each table
|
|
123
|
+
- **Configurable**: You control which tables and which CRUD operations (GET, POST, PUT, PATCH, DELETE) are exposed
|
|
124
|
+
- **Composite primary keys, unique constraints, foreign keys, BLOBs, JSON, and more** are supported
|
|
125
|
+
- **Advanced edge cases** (triggers, generated columns, partial unique constraints, etc.) are handled
|
|
126
|
+
|
|
127
|
+
### End-to-End Example
|
|
128
|
+
|
|
129
|
+
#### 1. Create a YAML Config
|
|
130
|
+
```yaml
|
|
131
|
+
database_url: sqlite:///mydata.db
|
|
132
|
+
|
|
133
|
+
tables:
|
|
134
|
+
- name: users
|
|
135
|
+
crud: [get, post, put, patch, delete]
|
|
136
|
+
- name: orders
|
|
137
|
+
crud: [get, post]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### 2. Create Your Database (SQLite example)
|
|
141
|
+
```bash
|
|
142
|
+
sqlite3 mydata.db "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL UNIQUE); CREATE TABLE orders (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, amount REAL NOT NULL, FOREIGN KEY(user_id) REFERENCES users(id));"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### 3. Start the API
|
|
146
|
+
```python
|
|
147
|
+
from lightapi import LightApi
|
|
148
|
+
api = LightApi.from_config('config.yaml')
|
|
149
|
+
api.run(host="0.0.0.0", port=8081)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### 4. Use the API (with curl)
|
|
153
|
+
```bash
|
|
154
|
+
# Create a user
|
|
155
|
+
curl -X POST http://localhost:8080/users/ -H 'Content-Type: application/json' -d '{"name": "Alice", "email": "alice@example.com"}'
|
|
156
|
+
|
|
157
|
+
# List users
|
|
158
|
+
curl http://localhost:8080/users/
|
|
159
|
+
|
|
160
|
+
# Create an order for Alice (id=1)
|
|
161
|
+
curl -X POST http://localhost:8080/orders/ -H 'Content-Type: application/json' -d '{"user_id": 1, "amount": 42.5}'
|
|
162
|
+
|
|
163
|
+
# List orders
|
|
164
|
+
curl http://localhost:8080/orders/
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### FAQ & Tips
|
|
168
|
+
- **Server-side defaults**: Only `server_default` (e.g., `server_default=text('...')`) are available after reflection. Python-side defaults are not reflected.
|
|
169
|
+
- **Composite PKs**: Supported transparently in routes and handlers.
|
|
170
|
+
- **Error handling**: Unique, check, not null, and foreign key constraints are enforced. Violations return 409 Conflict with details.
|
|
171
|
+
- **Partial CRUD**: You can expose only the operations you want per table.
|
|
172
|
+
- **Supported DBs**: Any DB supported by SQLAlchemy reflection (PostgreSQL, MySQL, SQLite, etc.)
|
|
173
|
+
|
|
174
|
+
See the [docs](./docs/getting-started/quickstart.md#dynamic-api-from-yaml-config-sqlalchemy-reflection) for more advanced examples and details.
|
|
175
|
+
|
|
115
176
|
## Documentation
|
|
116
177
|
|
|
117
178
|
Visit our comprehensive documentation at: https://iklobato.github.io/lightapi/
|
|
@@ -158,6 +219,9 @@ class UserValidator(Validator):
|
|
|
158
219
|
app.register(User, validator=UserValidator())
|
|
159
220
|
```
|
|
160
221
|
|
|
222
|
+
- All required fields must be defined as NOT NULL in your database schema for correct enforcement.
|
|
223
|
+
- 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.
|
|
224
|
+
|
|
161
225
|
### Middleware
|
|
162
226
|
|
|
163
227
|
```python
|
|
@@ -205,3 +269,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
205
269
|
**LightAPI** - *Making web APIs light and fast* ⚡
|
|
206
270
|
|
|
207
271
|
<!-- Testing development pipeline -->
|
|
272
|
+
|
|
273
|
+
> **Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
@@ -61,6 +61,66 @@ That's it! You now have a fully functional REST API with:
|
|
|
61
61
|
- `DELETE /users/{id}` - Delete user
|
|
62
62
|
- `OPTIONS /users` - CORS preflight support
|
|
63
63
|
|
|
64
|
+
## Dynamic API from YAML Config (SQLAlchemy Reflection)
|
|
65
|
+
|
|
66
|
+
LightAPI can instantly generate a REST API from a YAML configuration file, reflecting your database schema at runtime using SQLAlchemy. This is ideal for exposing existing databases with zero model code.
|
|
67
|
+
|
|
68
|
+
### How It Works
|
|
69
|
+
- **Reflects** the schema of specified tables from your database (PostgreSQL, MySQL, SQLite, etc.)
|
|
70
|
+
- **Dynamically generates** SQLAlchemy models and CRUD endpoints for each table
|
|
71
|
+
- **Configurable**: You control which tables and which CRUD operations (GET, POST, PUT, PATCH, DELETE) are exposed
|
|
72
|
+
- **Composite primary keys, unique constraints, foreign keys, BLOBs, JSON, and more** are supported
|
|
73
|
+
- **Advanced edge cases** (triggers, generated columns, partial unique constraints, etc.) are handled
|
|
74
|
+
|
|
75
|
+
### End-to-End Example
|
|
76
|
+
|
|
77
|
+
#### 1. Create a YAML Config
|
|
78
|
+
```yaml
|
|
79
|
+
database_url: sqlite:///mydata.db
|
|
80
|
+
|
|
81
|
+
tables:
|
|
82
|
+
- name: users
|
|
83
|
+
crud: [get, post, put, patch, delete]
|
|
84
|
+
- name: orders
|
|
85
|
+
crud: [get, post]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### 2. Create Your Database (SQLite example)
|
|
89
|
+
```bash
|
|
90
|
+
sqlite3 mydata.db "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL UNIQUE); CREATE TABLE orders (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, amount REAL NOT NULL, FOREIGN KEY(user_id) REFERENCES users(id));"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### 3. Start the API
|
|
94
|
+
```python
|
|
95
|
+
from lightapi import LightApi
|
|
96
|
+
api = LightApi.from_config('config.yaml')
|
|
97
|
+
api.run(host="0.0.0.0", port=8081)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### 4. Use the API (with curl)
|
|
101
|
+
```bash
|
|
102
|
+
# Create a user
|
|
103
|
+
curl -X POST http://localhost:8080/users/ -H 'Content-Type: application/json' -d '{"name": "Alice", "email": "alice@example.com"}'
|
|
104
|
+
|
|
105
|
+
# List users
|
|
106
|
+
curl http://localhost:8080/users/
|
|
107
|
+
|
|
108
|
+
# Create an order for Alice (id=1)
|
|
109
|
+
curl -X POST http://localhost:8080/orders/ -H 'Content-Type: application/json' -d '{"user_id": 1, "amount": 42.5}'
|
|
110
|
+
|
|
111
|
+
# List orders
|
|
112
|
+
curl http://localhost:8080/orders/
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### FAQ & Tips
|
|
116
|
+
- **Server-side defaults**: Only `server_default` (e.g., `server_default=text('...')`) are available after reflection. Python-side defaults are not reflected.
|
|
117
|
+
- **Composite PKs**: Supported transparently in routes and handlers.
|
|
118
|
+
- **Error handling**: Unique, check, not null, and foreign key constraints are enforced. Violations return 409 Conflict with details.
|
|
119
|
+
- **Partial CRUD**: You can expose only the operations you want per table.
|
|
120
|
+
- **Supported DBs**: Any DB supported by SQLAlchemy reflection (PostgreSQL, MySQL, SQLite, etc.)
|
|
121
|
+
|
|
122
|
+
See the [docs](./docs/getting-started/quickstart.md#dynamic-api-from-yaml-config-sqlalchemy-reflection) for more advanced examples and details.
|
|
123
|
+
|
|
64
124
|
## Documentation
|
|
65
125
|
|
|
66
126
|
Visit our comprehensive documentation at: https://iklobato.github.io/lightapi/
|
|
@@ -107,6 +167,9 @@ class UserValidator(Validator):
|
|
|
107
167
|
app.register(User, validator=UserValidator())
|
|
108
168
|
```
|
|
109
169
|
|
|
170
|
+
- All required fields must be defined as NOT NULL in your database schema for correct enforcement.
|
|
171
|
+
- 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.
|
|
172
|
+
|
|
110
173
|
### Middleware
|
|
111
174
|
|
|
112
175
|
```python
|
|
@@ -154,3 +217,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
154
217
|
**LightAPI** - *Making web APIs light and fast* ⚡
|
|
155
218
|
|
|
156
219
|
<!-- Testing development pipeline -->
|
|
220
|
+
|
|
221
|
+
> **Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
@@ -555,7 +555,7 @@ class DebugAuth(JWTAuthentication):
|
|
|
555
555
|
|
|
556
556
|
result = super().authenticate(request)
|
|
557
557
|
print(f"Auth result: {result}")
|
|
558
|
-
|
|
558
|
+
|
|
559
559
|
if hasattr(request.state, 'user'):
|
|
560
560
|
print(f"User: {request.state.user}")
|
|
561
561
|
|
|
@@ -566,4 +566,6 @@ class DebugAuth(JWTAuthentication):
|
|
|
566
566
|
|
|
567
567
|
- **[Core API](core.md)** - Application and middleware setup
|
|
568
568
|
- **[REST Endpoints](rest.md)** - Endpoint authentication configuration
|
|
569
|
-
- **[Authentication Example](../examples/auth.md)** - Complete implementation example
|
|
569
|
+
- **[Authentication Example](../examples/auth.md)** - Complete implementation example
|
|
570
|
+
|
|
571
|
+
> **Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
@@ -164,4 +164,6 @@ def update_user(id):
|
|
|
164
164
|
|
|
165
165
|
- [Core API](core.md) - Core framework functionality
|
|
166
166
|
- [REST API](rest.md) - REST endpoint implementation
|
|
167
|
-
- [Database](database.md) - Database integration
|
|
167
|
+
- [Database](database.md) - Database integration
|
|
168
|
+
|
|
169
|
+
> **Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
@@ -83,24 +83,14 @@ app.add_middleware([
|
|
|
83
83
|
**Parameters:**
|
|
84
84
|
- `middleware_classes` (List[Type[Middleware]]): List of middleware classes to add
|
|
85
85
|
|
|
86
|
-
#### run()
|
|
86
|
+
#### run(host: str = "0.0.0.0", port: int = 8000, debug: bool = False) -> None
|
|
87
87
|
|
|
88
|
-
Starts the
|
|
89
|
-
|
|
90
|
-
```python
|
|
91
|
-
app.run(
|
|
92
|
-
host="0.0.0.0",
|
|
93
|
-
port=8000,
|
|
94
|
-
debug=True,
|
|
95
|
-
reload=True
|
|
96
|
-
)
|
|
97
|
-
```
|
|
88
|
+
Starts the server. This is the only supported way to start the application. Do not use external libraries to start the server directly.
|
|
98
89
|
|
|
99
90
|
**Parameters:**
|
|
100
91
|
- `host` (str): Server host address
|
|
101
92
|
- `port` (int): Server port number
|
|
102
93
|
- `debug` (bool): Enable debug mode
|
|
103
|
-
- `reload` (bool): Enable auto-reload on code changes
|
|
104
94
|
|
|
105
95
|
### Advanced Configuration
|
|
106
96
|
|
|
@@ -456,4 +446,6 @@ class CustomEndpoint(RestEndpoint):
|
|
|
456
446
|
{"error": "Something went wrong"},
|
|
457
447
|
status_code=500
|
|
458
448
|
)
|
|
459
|
-
```
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
@@ -193,4 +193,6 @@ except ValueError as e:
|
|
|
193
193
|
|
|
194
194
|
- [Database](database.md) - Database integration
|
|
195
195
|
- [REST API](rest.md) - REST endpoint implementation
|
|
196
|
-
- [Validation](validation.md) - Request validation
|
|
196
|
+
- [Validation](validation.md) - Request validation
|
|
197
|
+
|
|
198
|
+
> **Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
@@ -490,7 +490,7 @@ class StatisticsEndpoint(RestEndpoint):
|
|
|
490
490
|
class Configuration:
|
|
491
491
|
authentication_class = JWTAuthentication
|
|
492
492
|
http_method_names = ['GET']
|
|
493
|
-
|
|
493
|
+
|
|
494
494
|
def get(self, request):
|
|
495
495
|
# Complex analytics logic
|
|
496
496
|
return {
|
|
@@ -640,7 +640,7 @@ class RobustEndpoint(RestEndpoint):
|
|
|
640
640
|
|
|
641
641
|
id = Column(Integer, primary_key=True)
|
|
642
642
|
name = Column(String(100))
|
|
643
|
-
|
|
643
|
+
|
|
644
644
|
def get(self, request):
|
|
645
645
|
try:
|
|
646
646
|
return super().get(request)
|
|
@@ -747,4 +747,10 @@ class User(RestEndpoint):
|
|
|
747
747
|
- [Core API](core.md) - Core framework functionality
|
|
748
748
|
- [Models](models.md) - Data models and schemas
|
|
749
749
|
- [Filtering](filters.md) - Advanced filtering options
|
|
750
|
-
- [Pagination](pagination.md) - Pagination configuration
|
|
750
|
+
- [Pagination](pagination.md) - Pagination configuration
|
|
751
|
+
|
|
752
|
+
- Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available.
|
|
753
|
+
- All required fields must be defined as NOT NULL in your database schema for correct enforcement.
|
|
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
|
+
|
|
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.
|
|
@@ -483,4 +483,6 @@ class DebugJWTAuth(JWTAuthentication):
|
|
|
483
483
|
- **[Middleware Example](middleware.md)** - Custom middleware patterns
|
|
484
484
|
- **[Validation Example](validation.md)** - Request validation
|
|
485
485
|
- **[Caching Example](caching.md)** - Performance optimization
|
|
486
|
-
- **[API Reference](../api-reference/auth.md)** - Authentication API details
|
|
486
|
+
- **[API Reference](../api-reference/auth.md)** - Authentication API details
|
|
487
|
+
|
|
488
|
+
> **Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
@@ -41,3 +41,29 @@ LIGHTAPI_JWT_SECRET=supersecretkey
|
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Use `python-dotenv` or your own environment loader to populate these variables before starting your app.
|
|
44
|
+
|
|
45
|
+
## YAML Config for Dynamic API Generation
|
|
46
|
+
|
|
47
|
+
You can define your API using a YAML config file for dynamic, reflection-based API generation. This is useful for exposing existing databases without writing models.
|
|
48
|
+
|
|
49
|
+
**Example:**
|
|
50
|
+
```yaml
|
|
51
|
+
database_url: sqlite:///mydata.db
|
|
52
|
+
tables:
|
|
53
|
+
- name: users
|
|
54
|
+
crud: [get, post, put, patch, delete]
|
|
55
|
+
- name: logs
|
|
56
|
+
crud: [get]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- `database_url`: Connection string (can use environment variables or a file path)
|
|
60
|
+
- `tables`: List of tables to expose, with allowed CRUD operations per table
|
|
61
|
+
- `name`: Table name in your database
|
|
62
|
+
- `crud`: List of allowed HTTP verbs (get, post, put, patch, delete)
|
|
63
|
+
|
|
64
|
+
**Notes:**
|
|
65
|
+
- Only server-side defaults (e.g., `server_default`) are available after reflection.
|
|
66
|
+
- All SQLAlchemy-reflectable constraints (unique, foreign key, etc.) are enforced.
|
|
67
|
+
- Errors (e.g., constraint violations) return 409 Conflict with details.
|
|
68
|
+
|
|
69
|
+
See the [Quickstart](quickstart.md#dynamic-api-from-yaml-config-sqlalchemy-reflection) or [README](../../README.md) for more details and advanced usage.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Quickstart
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
This quickstart guide shows you how to create your first LightAPI application in just a few simple steps.
|
|
6
|
+
|
|
7
|
+
## 1. Create a Virtual Environment
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
python3 -m venv .venv
|
|
11
|
+
source .venv/bin/activate
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 2. Install LightAPI
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install lightapi
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 3. Define a SQLAlchemy Model
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
# models.py
|
|
24
|
+
from sqlalchemy import Column, Integer, String
|
|
25
|
+
from lightapi.database import Base
|
|
26
|
+
|
|
27
|
+
class Item(Base):
|
|
28
|
+
id = Column(Integer, primary_key=True, index=True)
|
|
29
|
+
name = Column(String, unique=True, index=True)
|
|
30
|
+
description = Column(String, nullable=True)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 4. Create and Run Your App
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
# main.py
|
|
37
|
+
from lightapi import LightApi
|
|
38
|
+
from models import Item
|
|
39
|
+
|
|
40
|
+
app = LightApi()
|
|
41
|
+
app.register({'/items': Item})
|
|
42
|
+
|
|
43
|
+
if __name__ == '__main__':
|
|
44
|
+
app.run(host='0.0.0.0', port=8000, debug=True)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Now navigate to `http://localhost:8000/items` in your browser or use CURL to interact with the automatically generated CRUD endpoints.
|
|
48
|
+
|
|
49
|
+
## Dynamic API from YAML Config (SQLAlchemy Reflection)
|
|
50
|
+
|
|
51
|
+
LightAPI can generate a REST API from a YAML configuration file, reflecting your database schema at runtime. This is ideal for exposing existing databases without writing models.
|
|
52
|
+
|
|
53
|
+
### End-to-End Example
|
|
54
|
+
|
|
55
|
+
**1. Create a YAML config:**
|
|
56
|
+
```yaml
|
|
57
|
+
database_url: sqlite:///mydata.db
|
|
58
|
+
tables:
|
|
59
|
+
- name: users
|
|
60
|
+
crud: [get, post, put, patch, delete]
|
|
61
|
+
- name: orders
|
|
62
|
+
crud: [get, post]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**2. Create your database (SQLite example):**
|
|
66
|
+
```bash
|
|
67
|
+
sqlite3 mydata.db "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT UNIQUE); CREATE TABLE orders (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, amount REAL, FOREIGN KEY(user_id) REFERENCES users(id));"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**3. Start the API:**
|
|
71
|
+
```python
|
|
72
|
+
from lightapi import LightApi
|
|
73
|
+
api = LightApi.from_config('my_api_config.yaml')
|
|
74
|
+
api.run(host="0.0.0.0", port=8080)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**4. Use the API (with curl):**
|
|
78
|
+
```bash
|
|
79
|
+
curl -X POST http://localhost:8080/users/ -H 'Content-Type: application/json' -d '{"name": "Alice", "email": "alice@example.com"}'
|
|
80
|
+
curl http://localhost:8080/users/
|
|
81
|
+
curl -X POST http://localhost:8080/orders/ -H 'Content-Type: application/json' -d '{"user_id": 1, "amount": 42.5}'
|
|
82
|
+
curl http://localhost:8080/orders/
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### FAQ
|
|
86
|
+
- Only server-side defaults (e.g., `server_default`) are available after reflection.
|
|
87
|
+
- Composite PKs, foreign keys, and constraints are supported.
|
|
88
|
+
- Violations (e.g., unique, FK) return 409 Conflict with details.
|
|
89
|
+
- You can expose only the operations you want per table.
|
|
90
|
+
|
|
91
|
+
See the [README](../../README.md) for more details and advanced usage.
|
|
@@ -14,6 +14,7 @@ description: Enterprise-grade REST API framework for Python
|
|
|
14
14
|
- **Automatic OpenAPI/Swagger documentation** - Interactive API docs generated automatically
|
|
15
15
|
- **Built-in validation** - Request/response validation with customizable validators
|
|
16
16
|
- **Database integration** - Seamless SQLAlchemy integration with automatic table creation
|
|
17
|
+
- **Dynamic API from YAML** - Instantly generate REST APIs from a YAML config file using SQLAlchemy reflection
|
|
17
18
|
|
|
18
19
|
### 🔒 **Security & Authentication**
|
|
19
20
|
- **JWT Authentication** - Built-in JSON Web Token support
|
|
@@ -134,9 +135,12 @@ Environment-based configuration with sensible defaults:
|
|
|
134
135
|
Ready to build your first API? Check out our guides:
|
|
135
136
|
|
|
136
137
|
1. **[Getting Started](getting-started/)** - Basic setup and your first API
|
|
137
|
-
2. **[
|
|
138
|
-
3. **[
|
|
139
|
-
4. **[
|
|
138
|
+
2. **[Dynamic API from YAML Config](getting-started/quickstart.md#dynamic-api-from-yaml-config-sqlalchemy-reflection)** - Instantly expose your database as an API from a config file
|
|
139
|
+
3. **[Tutorial](tutorial/)** - Step-by-step walkthrough
|
|
140
|
+
4. **[Examples](examples/)** - Real-world examples and patterns
|
|
141
|
+
5. **[API Reference](api-reference/)** - Complete API documentation
|
|
142
|
+
|
|
143
|
+
See the [README](../README.md) for a full feature overview and advanced usage.
|
|
140
144
|
|
|
141
145
|
## Community & Support
|
|
142
146
|
|
|
@@ -152,3 +156,7 @@ LightAPI is released under the [MIT License](https://github.com/henriqueblobato/
|
|
|
152
156
|
|
|
153
157
|
*Built with ❤️ for Python developers who value simplicity and productivity.*
|
|
154
158
|
|
|
159
|
+
> **Note:** Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available. Required fields must be NOT NULL in the schema. Constraint violations (NOT NULL, UNIQUE, FK) return 409.
|
|
160
|
+
|
|
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
|
+
|
|
@@ -50,7 +50,7 @@ Adds application-wide middleware.
|
|
|
50
50
|
|
|
51
51
|
#### run(host: str = "0.0.0.0", port: int = 8000, debug: bool = False) -> None
|
|
52
52
|
|
|
53
|
-
Starts the
|
|
53
|
+
Starts the server. This is the only supported way to start the application. Do not use external libraries to start the server directly.
|
|
54
54
|
|
|
55
55
|
- **Parameters:**
|
|
56
56
|
- `host`: Host address to bind (default: `"0.0.0.0"`).
|
|
@@ -203,4 +203,7 @@ def get(self, request):
|
|
|
203
203
|
return {'data': 'ok'}
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
-
## Notes
|
|
206
|
+
## Notes
|
|
207
|
+
- All required fields must be defined as NOT NULL in your database schema for correct enforcement.
|
|
208
|
+
- 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.
|
|
209
|
+
- Only GET, POST, PUT, PATCH, DELETE HTTP verbs are supported. OPTIONS and HEAD are not available.
|