lenapi 0.1.2__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.
- {lenapi-0.1.2 → lenapi-0.1.3}/PKG-INFO +174 -6
- {lenapi-0.1.2 → lenapi-0.1.3}/README.md +170 -4
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/__init__.py +3 -2
- lenapi-0.1.3/lenapi/admin.py +1017 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/application.py +237 -40
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/cli.py +338 -89
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/database.py +22 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/docs_guard.py +52 -13
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/models.py +193 -21
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/mongodb.py +16 -2
- lenapi-0.1.3/lenapi/project.py +62 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/request.py +8 -3
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/security_store.py +12 -3
- lenapi-0.1.3/lenapi/transaction.py +76 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi.egg-info/PKG-INFO +174 -6
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi.egg-info/SOURCES.txt +6 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi.egg-info/requires.txt +3 -0
- lenapi-0.1.3/lenapi.egg-info/top_level.txt +2 -0
- lenapi-0.1.3/lenapi_bootstrap.py +97 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/pyproject.toml +6 -2
- lenapi-0.1.3/tests/test_admin_console.py +219 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_framework_features.py +61 -1
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_media_upload.py +20 -0
- lenapi-0.1.3/tests/test_project_isolation.py +233 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_user_model_extension.py +7 -0
- lenapi-0.1.2/lenapi.egg-info/top_level.txt +0 -1
- {lenapi-0.1.2 → lenapi-0.1.3}/LICENSE +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/auth.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/authentication.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/authorization.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/background.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/concurrency.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/dependencies.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/logging.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/middleware.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/model.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/openapi.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/parameters.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/response.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/security.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/sentinels.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/service.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi/throttling.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi.egg-info/dependency_links.txt +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/lenapi.egg-info/entry_points.txt +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/setup.cfg +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_cli_settings_recovery.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_docs_guard.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_mongodb.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_platform_services.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_security_patch.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_sentinels.py +0 -0
- {lenapi-0.1.2 → lenapi-0.1.3}/tests/test_throttle.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lenapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: A modern ASGI framework with Pydantic validation, sync and async database access, WebSockets, authentication, and integrated API documentation.
|
|
5
5
|
Author: Maekandex Communication Limitation
|
|
6
6
|
Author-email: "Ifeanyi M. Onovo" <ifeanyi@maekandex.com.ng>
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
Project-URL: Homepage, https://github.com/Mikandex/lenapi
|
|
9
9
|
Project-URL: Repository, https://github.com/Mikandex/lenapi
|
|
10
|
-
Project-URL: Documentation, https://
|
|
10
|
+
Project-URL: Documentation, https://lenapi.site/
|
|
11
11
|
Project-URL: Issues, https://github.com/Mikandex/lenapi/issues
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -46,6 +46,8 @@ Provides-Extra: async-mysql
|
|
|
46
46
|
Requires-Dist: asyncmy>=0.2; extra == "async-mysql"
|
|
47
47
|
Provides-Extra: mongodb
|
|
48
48
|
Requires-Dist: pymongo<5,>=4.13; extra == "mongodb"
|
|
49
|
+
Provides-Extra: monitoring
|
|
50
|
+
Requires-Dist: psutil<8,>=5.9; extra == "monitoring"
|
|
49
51
|
Dynamic: license-file
|
|
50
52
|
|
|
51
53
|
# lenApi
|
|
@@ -58,6 +60,18 @@ LenAPI aims to reduce repetitive code and simplify common integrations, helping
|
|
|
58
60
|
|
|
59
61
|
**LenAPI — Compact by Design, Powerful by Capability.**
|
|
60
62
|
|
|
63
|
+
## Feature overview
|
|
64
|
+
|
|
65
|
+
- Typed HTTP routes with Pydantic request and response validation, Swagger UI, and ReDoc.
|
|
66
|
+
- Synchronous and asynchronous ORM operations, migrations, transactions, search, aggregates, and pagination for SQLite, MySQL, and PostgreSQL. MongoDB document support is currently in beta.
|
|
67
|
+
- Authentication building blocks for JWT, API keys, HTTP Basic, sessions, opaque bearer tokens, HMAC, OIDC, and social sign-in.
|
|
68
|
+
- WebSockets for chat, video signaling, JSON, text, and binary messages; webhook handlers with optional HMAC verification; cache and durable background jobs with retries and delayed execution.
|
|
69
|
+
- Validated public and private file uploads, middleware, throttling, and optional gzip compression.
|
|
70
|
+
- An optional model admin console with explicit model/field allow-lists, per-model permissions, and CPU/RAM/process monitoring.
|
|
71
|
+
- Independent generated projects that can run separately or be mounted under a path in a primary project.
|
|
72
|
+
|
|
73
|
+
See the [LenAPI documentation](https://lenapi.site/) for setup guides and runnable examples.
|
|
74
|
+
|
|
61
75
|
## Python versions
|
|
62
76
|
|
|
63
77
|
LenAPI is tested and supported on Python 3.11 through 3.14. Python 3.10 reached
|
|
@@ -523,6 +537,8 @@ Run `python lenora.py apikey` inside a project to set `AUTHENTICATION = "api_key
|
|
|
523
537
|
|
|
524
538
|
`settings.py` centralizes the API title/version, docs and OpenAPI URLs, host, port, database selection, token settings, and shared security storage. `HOST = ""` uses `127.0.0.1`; set `HOST` directly to bind another address. `app = LENAPI()` loads project settings automatically. Each generated project gets a unique high-entropy `SECRET_KEY`; `TOKEN` uses it to sign tokens and configures token lifetime and issuer. Keep the key private. Changing it invalidates tokens signed with the old key. `DATABASE_TYPE` chooses one backend (`sqlite`, `mysql`, `postgresql`, or `mongodb`), and `DATABASE_URL` configures it. `ACTIVATE_ASYNC` enables asynchronous access using the same database URL. The default database is SQLite.
|
|
525
539
|
|
|
540
|
+
Generated projects set `DEBUG = True` for local development. Unexpected route or dependency errors then print a traceback to the terminal. LenAPI returns a generic `500 Internal Server Error` response to the client in both debug modes; request validation errors and explicit `HTTPException` responses keep their normal status codes. Set `DEBUG = False` in production to stop LenAPI from printing exception tracebacks. If `DEBUG` is absent, LenAPI defaults to `False`.
|
|
541
|
+
|
|
526
542
|
## Automated tests
|
|
527
543
|
|
|
528
544
|
Pytest is installed with lenApi, so you can run the framework test suite from the repository root:
|
|
@@ -849,6 +865,117 @@ The docs gate only handles `/`, `/logout`, the configured Swagger and ReDoc path
|
|
|
849
865
|
|
|
850
866
|
To remove the gate, set `SAFE_GUARD_DOCS_URL = False` and restart the app. The admin tables may remain in the database; they are not queried while the feature is disabled.
|
|
851
867
|
|
|
868
|
+
### Built-in model admin and resource monitor
|
|
869
|
+
|
|
870
|
+
The optional admin console is separate from the Swagger/ReDoc login and is served at `/admin/`. It uses stateless HTTP Basic authentication for its API requests. Enable it in `settings.py`, then run a migration and create an administrator. The first CLI-created superadmin has full access and can create other admin accounts and grant per-model permissions. If the project already had docs-admin accounts before this feature, create an additional account with the CLI; it becomes superadmin if no superadmin exists yet.
|
|
871
|
+
|
|
872
|
+
```python
|
|
873
|
+
# settings.py
|
|
874
|
+
ADMIN_ENABLED = True
|
|
875
|
+
ADMIN_URL = "/admin/"
|
|
876
|
+
ADMIN_SESSION_LIFETIME_SECONDS = 3600
|
|
877
|
+
ADMIN_COOKIE_SECURE = None # follows the ASGI HTTPS scheme
|
|
878
|
+
|
|
879
|
+
# Monitoring is optional and requires the admin console to be enabled.
|
|
880
|
+
ADMIN_MONITORING_ENABLED = True
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
```bash
|
|
884
|
+
python lenora.py migration
|
|
885
|
+
python lenora.py admin
|
|
886
|
+
python lenora.py run
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
The first SQL migration includes the framework `AdminUser` fields and session storage along with the imported app models. MongoDB initializes the admin collections through `migration`. Mongo collections need a corresponding `MongoDocument` class so the admin can safely render typed edit forms.
|
|
890
|
+
|
|
891
|
+
Create `app/admin.py` to explicitly allow-list models and choose which fields are visible. Once this file exists, only models registered there appear in the console. `fields` selects displayed/editable fields, `readonly` displays selected fields without allowing changes, and `exclude` hides fields. Credential-like fields such as `password`, `api_key`, and `key_digest` remain hidden even if listed; use application routes that hash or rotate credentials.
|
|
892
|
+
|
|
893
|
+
```python
|
|
894
|
+
# app/admin.py
|
|
895
|
+
from lenapi.admin import admin
|
|
896
|
+
from .models import Student, Course, Invoice, Staff
|
|
897
|
+
|
|
898
|
+
admin.register(
|
|
899
|
+
Student,
|
|
900
|
+
fields=("person_name", "course", "email", "profile_image"),
|
|
901
|
+
readonly=("email",),
|
|
902
|
+
exclude=("password", "private_notes"),
|
|
903
|
+
)
|
|
904
|
+
|
|
905
|
+
admin.register(
|
|
906
|
+
Course,
|
|
907
|
+
fields=("title", "description", "duration_weeks", "is_active"),
|
|
908
|
+
)
|
|
909
|
+
|
|
910
|
+
admin.register(
|
|
911
|
+
Invoice,
|
|
912
|
+
fields=("invoice_number", "student_id", "amount", "status", "issued_at"),
|
|
913
|
+
readonly=("invoice_number", "issued_at"),
|
|
914
|
+
exclude=("payment_token", "provider_response"),
|
|
915
|
+
)
|
|
916
|
+
|
|
917
|
+
admin.register(
|
|
918
|
+
Staff,
|
|
919
|
+
fields=("name", "work_email", "department"),
|
|
920
|
+
readonly=("work_email",),
|
|
921
|
+
exclude=("password", "salary", "hr_notes"),
|
|
922
|
+
)
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
When `app/admin.py` is absent, the console keeps its backward-compatible model discovery. Registered models show only the selected columns; readonly fields appear in record forms without editable controls, and excluded fields are omitted from both the UI and the API response. Update requests are checked against the same field allow-list. The console supports list/read, update, and delete; record creation is handled by application endpoints. Superadmins grant `view`, `read`, `write`, and `delete` independently. `view` controls whether a model appears in the sidebar, `read` allows listing records, `write` permits updates, and `delete` controls deletion.
|
|
926
|
+
|
|
927
|
+
Admin accounts and model records use the selected SQL database or MongoDB. Disable the console with `ADMIN_ENABLED = False`; set `ADMIN_MONITORING_ENABLED = False` to hide its monitor. Resource metrics are available only to a superadmin when both settings are enabled:
|
|
928
|
+
|
|
929
|
+
```bash
|
|
930
|
+
python -m pip install 'lenapi[monitoring]'
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
The Resource Monitor page shows CPU and RAM metric cards with rolling graphs, plus the LenAPI process PID and thread count. RAM shows process resident memory and total system-memory use. Metrics refresh every two seconds while the page is open; history remains in that browser page only. The endpoint is restricted to superadmins. This is an operational status view, not a host monitoring or alerting system. Monitoring requires psutil and does not start background sampling.
|
|
934
|
+
|
|
935
|
+
When a main LenAPI project mounts sibling projects, the main project's `/admin/` is the single admin entry point. It groups each mounted project's explicitly registered models under that project's name and reads or updates records through that project's own database. Enable `ADMIN_ENABLED` and create the admin account only in the main project. Keep `ADMIN_ENABLED = False` in mounted projects; they contribute their `app/admin.py` registrations but do not need their own admin login. The mount must be configured with `app.mount(...)` for the main admin to discover that project.
|
|
936
|
+
|
|
937
|
+
In generated projects, prefer a relative model import in `app/admin.py` so project names and mounts remain unambiguous:
|
|
938
|
+
|
|
939
|
+
```python
|
|
940
|
+
from lenapi.admin import admin
|
|
941
|
+
from .models import Student, Course
|
|
942
|
+
|
|
943
|
+
admin.register(Student, fields=("person_name", "course"))
|
|
944
|
+
admin.register(Course, fields=("title", "is_active"))
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
Per-model permissions for the main project keep their existing model-name keys. Mounted-project permissions use `<project_name>:<model_name>`, for example `games:student`, so same-named models in different projects stay separate.
|
|
948
|
+
|
|
949
|
+
### Mount independent projects
|
|
950
|
+
|
|
951
|
+
Every generated project keeps its own settings, models, migrations, and database configuration. Run projects independently on different ports, or mount a sibling project into a primary app at any URL prefix you choose. A mount prefix does not need to match the sibling project's name.
|
|
952
|
+
|
|
953
|
+
```python
|
|
954
|
+
# win/main.py — primary application
|
|
955
|
+
from lenapi import LENAPI
|
|
956
|
+
|
|
957
|
+
app = LENAPI()
|
|
958
|
+
app.mount("/gamer", "games")
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
The sibling project must be in the same parent directory and have its own generated `settings.py` with a `PROJECT_NAME`:
|
|
962
|
+
|
|
963
|
+
```text
|
|
964
|
+
workspace/
|
|
965
|
+
├── win/
|
|
966
|
+
│ ├── main.py
|
|
967
|
+
│ ├── settings.py
|
|
968
|
+
│ └── app/
|
|
969
|
+
└── games/
|
|
970
|
+
├── main.py
|
|
971
|
+
├── settings.py
|
|
972
|
+
└── app/
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
The mounted app keeps its own database URL and project namespace. Its routes are reachable under `/gamer/`, while its own docs paths are under `/gamer/docs/` and `/gamer/redoc/`. Project table names include the project's namespace so separate apps sharing one database do not collide. Mounting is optional; independent projects can instead run on separate ports or deployments.
|
|
976
|
+
|
|
977
|
+
For the shared admin console, enable `ADMIN_ENABLED` and create the admin account only in the primary project. Register models explicitly in each project's `app/admin.py`; after mounting, the primary `/admin/` groups those models by project and performs their data operations against each project's configured database. Keep `ADMIN_ENABLED = False` in mounted projects. Each mounted app instance can belong to only one parent admin.
|
|
978
|
+
|
|
852
979
|
The sample app exposes the model queries as HTTP routes: `POST /classrooms` creates a classroom, `GET /classrooms` lists them, and `POST /students` accepts an optional `classroom_id`. `POST /students/batch` creates multiple students, `PUT /students/batch` updates multiple students by ID, and `DELETE /students/batch` deletes multiple students by ID. Batch requests are all-or-nothing: unknown IDs, duplicate names, or a protected deletion reject the whole operation. `PUT /students/{student_id}` updates one student; it returns HTTP 404 if the ID does not exist. `GET /students/{student_id}/classroom` returns the related classroom. Other student routes list, search, and check existence. These routes appear in Swagger at `/docs/`.
|
|
853
980
|
|
|
854
981
|
Batch request examples:
|
|
@@ -1625,7 +1752,7 @@ async def billing_webhook(
|
|
|
1625
1752
|
|
|
1626
1753
|
## Databases
|
|
1627
1754
|
|
|
1628
|
-
`DATABASE_TYPE` chooses one backend and `DATABASE_URL` connects to it. The generated project defaults to SQLite. SQLite, MySQL, and PostgreSQL use SQLAlchemy models and Alembic revisions; MongoDB uses the separate `MongoDocument` API and does not have SQL schema revisions. `ACTIVATE_ASYNC = True` enables async access to the same database URL. Keep production credentials out of committed settings and URL-encode reserved characters in credentials.
|
|
1755
|
+
`DATABASE_TYPE` chooses one backend and `DATABASE_URL` connects to it. The generated project defaults to SQLite. SQLite, MySQL, and PostgreSQL use SQLAlchemy models and Alembic revisions; MongoDB uses the separate `MongoDocument` API and does not have SQL schema revisions. `app.database_type` reports the selected backend at runtime. `ACTIVATE_ASYNC = True` enables async access to the same database URL. Keep production credentials out of committed settings and URL-encode reserved characters in credentials.
|
|
1629
1756
|
|
|
1630
1757
|
```python
|
|
1631
1758
|
# settings.py — choose one backend and its URL
|
|
@@ -1643,6 +1770,8 @@ DATABASE_URL = f"sqlite:///{BASE_DIR / 'lenapi.db'}"
|
|
|
1643
1770
|
# MongoDB: install `python -m pip install 'lenapi[mongodb]'`
|
|
1644
1771
|
# DATABASE_TYPE = "mongodb"
|
|
1645
1772
|
# DATABASE_URL = "mongodb://user:password@localhost:27017/app_db"
|
|
1773
|
+
# If the URI has no database path, set this explicitly instead:
|
|
1774
|
+
# MONGODB_DATABASE = "app_db"
|
|
1646
1775
|
|
|
1647
1776
|
ACTIVATE_ASYNC = False
|
|
1648
1777
|
```
|
|
@@ -1686,7 +1815,44 @@ await student.asave()
|
|
|
1686
1815
|
await student.adelete()
|
|
1687
1816
|
```
|
|
1688
1817
|
|
|
1689
|
-
`MongoDatabase.ping()` and `await MongoDatabase.aping()` check connectivity. To select MongoDB, set `DATABASE_TYPE = "mongodb"
|
|
1818
|
+
`MongoDatabase.ping()` and `await MongoDatabase.aping()` check connectivity. To select MongoDB, set `DATABASE_TYPE = "mongodb"`. Put the database name in the URI path, such as `mongodb://localhost:27017/my_database`, or set `MONGODB_DATABASE = "my_database"` when the URI has no path. `ACTIVATE_ASYNC` controls whether LenApi also creates PyMongo's async client. `migration` and `migrate` ensure collections exist for imported `MongoDocument` models and framework security/admin state; document fields are schema-flexible and do not use Alembic revisions. `SECURITY_STORAGE = "database"` uses MongoDB for shared security state, while Redis and process memory remain optional choices. MongoDB uses the official synchronous and `AsyncMongoClient` APIs; see the [PyMongo driver guide](https://www.mongodb.com/docs/languages/python/pymongo-driver/current/).
|
|
1819
|
+
|
|
1820
|
+
#### Switching an existing project from SQL to MongoDB
|
|
1821
|
+
|
|
1822
|
+
Changing `DATABASE_TYPE` and `DATABASE_URL` selects MongoDB for the app; it does not convert existing SQLAlchemy models, tables, or rows. Define the Mongo-backed version as a `MongoDocument`, bind it after creating the app, and update routes to use that document class. If a SQL `model.Model` query runs while MongoDB is selected, LenAPI raises a clear backend-mismatch error explaining that a Mongo document is required. Check the active backend with `app.database_type`.
|
|
1823
|
+
|
|
1824
|
+
```python
|
|
1825
|
+
# settings.py
|
|
1826
|
+
DATABASE_TYPE = "mongodb"
|
|
1827
|
+
DATABASE_URL = "mongodb://127.0.0.1:27017/my_app"
|
|
1828
|
+
|
|
1829
|
+
# app/models.py
|
|
1830
|
+
from lenapi import MongoDocument
|
|
1831
|
+
|
|
1832
|
+
class MongoStudent(MongoDocument):
|
|
1833
|
+
collection_name = "students"
|
|
1834
|
+
username: str
|
|
1835
|
+
course: str
|
|
1836
|
+
|
|
1837
|
+
# main.py
|
|
1838
|
+
from lenapi import LENAPI
|
|
1839
|
+
from pydantic import BaseModel
|
|
1840
|
+
from app.models import MongoStudent
|
|
1841
|
+
|
|
1842
|
+
class StudentCreate(BaseModel):
|
|
1843
|
+
username: str
|
|
1844
|
+
course: str
|
|
1845
|
+
|
|
1846
|
+
app = LENAPI()
|
|
1847
|
+
MongoStudent.bind(app.mongodb)
|
|
1848
|
+
print(app.database_type) # mongodb
|
|
1849
|
+
|
|
1850
|
+
@app.post("/students")
|
|
1851
|
+
def create_student(data: StudentCreate):
|
|
1852
|
+
return MongoStudent.create(**data.model_dump())
|
|
1853
|
+
```
|
|
1854
|
+
|
|
1855
|
+
If you need to carry existing records over, treat that as an explicit data migration: back up both stores, copy in controlled batches, verify counts and important fields, and only then switch production traffic. LenAPI's `migration`/`migrate` commands initialize MongoDB collections and framework state; they do not copy SQL data. MongoDB document IDs are strings, so update route and response-schema ID types that previously expected integer SQL IDs.
|
|
1690
1856
|
|
|
1691
1857
|
Put application models in `app/models.py` and import that module from `main.py`. The migration command loads `main:app`, so it discovers those model classes before creating a migration. The library's `Model` base supplies an integer `id`:
|
|
1692
1858
|
|
|
@@ -1801,6 +1967,8 @@ python lenora.py migration --message "add student phone"
|
|
|
1801
1967
|
|
|
1802
1968
|
An existing unversioned SQLite database is adopted only when its schema matches the migration history; adoption preserves its data.
|
|
1803
1969
|
|
|
1970
|
+
`PositiveIntegerField` and `PositiveBigIntegerField` include a named database `CHECK` constraint. LenAPI prevents Alembic's metadata-copy step from adding that constraint twice, which MySQL rejects as a duplicate constraint name. If a local revision generated by an older LenAPI contains duplicate identical `sa.CheckConstraint(...)` entries, correct or regenerate that unapplied revision before using it. MySQL uses non-transactional DDL, so a failed migration may leave some project tables created even though no revision was recorded. Check `showmigrations` and inspect the project-namespaced tables before retrying. For a disposable database, `delete_migrations` can reset this project's tables and revisions after its confirmation prompt; if the data must be preserved, reconcile the partial schema instead of deleting it.
|
|
1971
|
+
|
|
1804
1972
|
`migrate` applies pending migration files already in `migrations/versions/`; it does not generate a revision. A common release workflow is to generate and inspect a revision during development, commit the revision with the code, then run `migrate` during deployment:
|
|
1805
1973
|
|
|
1806
1974
|
```bash
|
|
@@ -1823,9 +1991,9 @@ python lenora.py showmigrations
|
|
|
1823
1991
|
python lenora.py repair-migrations
|
|
1824
1992
|
```
|
|
1825
1993
|
|
|
1826
|
-
`clear_migrations` removes local revision files and
|
|
1994
|
+
`clear_migrations` removes local revision files and this project's Alembic version table only when there are no application tables in this project's namespace. It is for resetting an empty SQL project, not for reconciling an existing schema.
|
|
1827
1995
|
|
|
1828
|
-
`delete_migrations` is a destructive
|
|
1996
|
+
`delete_migrations` is a destructive reset of the current project. After an interactive y/n confirmation, it drops tables and views in this project's SQL namespace (or collections in this project's MongoDB namespace) and deletes local revision files. Objects belonging to other project namespaces are left alone. This also deletes this project's application data. Back up first and use it only when a clean project database is intended:
|
|
1829
1997
|
|
|
1830
1998
|
```bash
|
|
1831
1999
|
python lenora.py delete_migrations
|
|
@@ -8,6 +8,18 @@ LenAPI aims to reduce repetitive code and simplify common integrations, helping
|
|
|
8
8
|
|
|
9
9
|
**LenAPI — Compact by Design, Powerful by Capability.**
|
|
10
10
|
|
|
11
|
+
## Feature overview
|
|
12
|
+
|
|
13
|
+
- Typed HTTP routes with Pydantic request and response validation, Swagger UI, and ReDoc.
|
|
14
|
+
- Synchronous and asynchronous ORM operations, migrations, transactions, search, aggregates, and pagination for SQLite, MySQL, and PostgreSQL. MongoDB document support is currently in beta.
|
|
15
|
+
- Authentication building blocks for JWT, API keys, HTTP Basic, sessions, opaque bearer tokens, HMAC, OIDC, and social sign-in.
|
|
16
|
+
- WebSockets for chat, video signaling, JSON, text, and binary messages; webhook handlers with optional HMAC verification; cache and durable background jobs with retries and delayed execution.
|
|
17
|
+
- Validated public and private file uploads, middleware, throttling, and optional gzip compression.
|
|
18
|
+
- An optional model admin console with explicit model/field allow-lists, per-model permissions, and CPU/RAM/process monitoring.
|
|
19
|
+
- Independent generated projects that can run separately or be mounted under a path in a primary project.
|
|
20
|
+
|
|
21
|
+
See the [LenAPI documentation](https://lenapi.site/) for setup guides and runnable examples.
|
|
22
|
+
|
|
11
23
|
## Python versions
|
|
12
24
|
|
|
13
25
|
LenAPI is tested and supported on Python 3.11 through 3.14. Python 3.10 reached
|
|
@@ -473,6 +485,8 @@ Run `python lenora.py apikey` inside a project to set `AUTHENTICATION = "api_key
|
|
|
473
485
|
|
|
474
486
|
`settings.py` centralizes the API title/version, docs and OpenAPI URLs, host, port, database selection, token settings, and shared security storage. `HOST = ""` uses `127.0.0.1`; set `HOST` directly to bind another address. `app = LENAPI()` loads project settings automatically. Each generated project gets a unique high-entropy `SECRET_KEY`; `TOKEN` uses it to sign tokens and configures token lifetime and issuer. Keep the key private. Changing it invalidates tokens signed with the old key. `DATABASE_TYPE` chooses one backend (`sqlite`, `mysql`, `postgresql`, or `mongodb`), and `DATABASE_URL` configures it. `ACTIVATE_ASYNC` enables asynchronous access using the same database URL. The default database is SQLite.
|
|
475
487
|
|
|
488
|
+
Generated projects set `DEBUG = True` for local development. Unexpected route or dependency errors then print a traceback to the terminal. LenAPI returns a generic `500 Internal Server Error` response to the client in both debug modes; request validation errors and explicit `HTTPException` responses keep their normal status codes. Set `DEBUG = False` in production to stop LenAPI from printing exception tracebacks. If `DEBUG` is absent, LenAPI defaults to `False`.
|
|
489
|
+
|
|
476
490
|
## Automated tests
|
|
477
491
|
|
|
478
492
|
Pytest is installed with lenApi, so you can run the framework test suite from the repository root:
|
|
@@ -799,6 +813,117 @@ The docs gate only handles `/`, `/logout`, the configured Swagger and ReDoc path
|
|
|
799
813
|
|
|
800
814
|
To remove the gate, set `SAFE_GUARD_DOCS_URL = False` and restart the app. The admin tables may remain in the database; they are not queried while the feature is disabled.
|
|
801
815
|
|
|
816
|
+
### Built-in model admin and resource monitor
|
|
817
|
+
|
|
818
|
+
The optional admin console is separate from the Swagger/ReDoc login and is served at `/admin/`. It uses stateless HTTP Basic authentication for its API requests. Enable it in `settings.py`, then run a migration and create an administrator. The first CLI-created superadmin has full access and can create other admin accounts and grant per-model permissions. If the project already had docs-admin accounts before this feature, create an additional account with the CLI; it becomes superadmin if no superadmin exists yet.
|
|
819
|
+
|
|
820
|
+
```python
|
|
821
|
+
# settings.py
|
|
822
|
+
ADMIN_ENABLED = True
|
|
823
|
+
ADMIN_URL = "/admin/"
|
|
824
|
+
ADMIN_SESSION_LIFETIME_SECONDS = 3600
|
|
825
|
+
ADMIN_COOKIE_SECURE = None # follows the ASGI HTTPS scheme
|
|
826
|
+
|
|
827
|
+
# Monitoring is optional and requires the admin console to be enabled.
|
|
828
|
+
ADMIN_MONITORING_ENABLED = True
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
```bash
|
|
832
|
+
python lenora.py migration
|
|
833
|
+
python lenora.py admin
|
|
834
|
+
python lenora.py run
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
The first SQL migration includes the framework `AdminUser` fields and session storage along with the imported app models. MongoDB initializes the admin collections through `migration`. Mongo collections need a corresponding `MongoDocument` class so the admin can safely render typed edit forms.
|
|
838
|
+
|
|
839
|
+
Create `app/admin.py` to explicitly allow-list models and choose which fields are visible. Once this file exists, only models registered there appear in the console. `fields` selects displayed/editable fields, `readonly` displays selected fields without allowing changes, and `exclude` hides fields. Credential-like fields such as `password`, `api_key`, and `key_digest` remain hidden even if listed; use application routes that hash or rotate credentials.
|
|
840
|
+
|
|
841
|
+
```python
|
|
842
|
+
# app/admin.py
|
|
843
|
+
from lenapi.admin import admin
|
|
844
|
+
from .models import Student, Course, Invoice, Staff
|
|
845
|
+
|
|
846
|
+
admin.register(
|
|
847
|
+
Student,
|
|
848
|
+
fields=("person_name", "course", "email", "profile_image"),
|
|
849
|
+
readonly=("email",),
|
|
850
|
+
exclude=("password", "private_notes"),
|
|
851
|
+
)
|
|
852
|
+
|
|
853
|
+
admin.register(
|
|
854
|
+
Course,
|
|
855
|
+
fields=("title", "description", "duration_weeks", "is_active"),
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
admin.register(
|
|
859
|
+
Invoice,
|
|
860
|
+
fields=("invoice_number", "student_id", "amount", "status", "issued_at"),
|
|
861
|
+
readonly=("invoice_number", "issued_at"),
|
|
862
|
+
exclude=("payment_token", "provider_response"),
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
admin.register(
|
|
866
|
+
Staff,
|
|
867
|
+
fields=("name", "work_email", "department"),
|
|
868
|
+
readonly=("work_email",),
|
|
869
|
+
exclude=("password", "salary", "hr_notes"),
|
|
870
|
+
)
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
When `app/admin.py` is absent, the console keeps its backward-compatible model discovery. Registered models show only the selected columns; readonly fields appear in record forms without editable controls, and excluded fields are omitted from both the UI and the API response. Update requests are checked against the same field allow-list. The console supports list/read, update, and delete; record creation is handled by application endpoints. Superadmins grant `view`, `read`, `write`, and `delete` independently. `view` controls whether a model appears in the sidebar, `read` allows listing records, `write` permits updates, and `delete` controls deletion.
|
|
874
|
+
|
|
875
|
+
Admin accounts and model records use the selected SQL database or MongoDB. Disable the console with `ADMIN_ENABLED = False`; set `ADMIN_MONITORING_ENABLED = False` to hide its monitor. Resource metrics are available only to a superadmin when both settings are enabled:
|
|
876
|
+
|
|
877
|
+
```bash
|
|
878
|
+
python -m pip install 'lenapi[monitoring]'
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
The Resource Monitor page shows CPU and RAM metric cards with rolling graphs, plus the LenAPI process PID and thread count. RAM shows process resident memory and total system-memory use. Metrics refresh every two seconds while the page is open; history remains in that browser page only. The endpoint is restricted to superadmins. This is an operational status view, not a host monitoring or alerting system. Monitoring requires psutil and does not start background sampling.
|
|
882
|
+
|
|
883
|
+
When a main LenAPI project mounts sibling projects, the main project's `/admin/` is the single admin entry point. It groups each mounted project's explicitly registered models under that project's name and reads or updates records through that project's own database. Enable `ADMIN_ENABLED` and create the admin account only in the main project. Keep `ADMIN_ENABLED = False` in mounted projects; they contribute their `app/admin.py` registrations but do not need their own admin login. The mount must be configured with `app.mount(...)` for the main admin to discover that project.
|
|
884
|
+
|
|
885
|
+
In generated projects, prefer a relative model import in `app/admin.py` so project names and mounts remain unambiguous:
|
|
886
|
+
|
|
887
|
+
```python
|
|
888
|
+
from lenapi.admin import admin
|
|
889
|
+
from .models import Student, Course
|
|
890
|
+
|
|
891
|
+
admin.register(Student, fields=("person_name", "course"))
|
|
892
|
+
admin.register(Course, fields=("title", "is_active"))
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
Per-model permissions for the main project keep their existing model-name keys. Mounted-project permissions use `<project_name>:<model_name>`, for example `games:student`, so same-named models in different projects stay separate.
|
|
896
|
+
|
|
897
|
+
### Mount independent projects
|
|
898
|
+
|
|
899
|
+
Every generated project keeps its own settings, models, migrations, and database configuration. Run projects independently on different ports, or mount a sibling project into a primary app at any URL prefix you choose. A mount prefix does not need to match the sibling project's name.
|
|
900
|
+
|
|
901
|
+
```python
|
|
902
|
+
# win/main.py — primary application
|
|
903
|
+
from lenapi import LENAPI
|
|
904
|
+
|
|
905
|
+
app = LENAPI()
|
|
906
|
+
app.mount("/gamer", "games")
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
The sibling project must be in the same parent directory and have its own generated `settings.py` with a `PROJECT_NAME`:
|
|
910
|
+
|
|
911
|
+
```text
|
|
912
|
+
workspace/
|
|
913
|
+
├── win/
|
|
914
|
+
│ ├── main.py
|
|
915
|
+
│ ├── settings.py
|
|
916
|
+
│ └── app/
|
|
917
|
+
└── games/
|
|
918
|
+
├── main.py
|
|
919
|
+
├── settings.py
|
|
920
|
+
└── app/
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
The mounted app keeps its own database URL and project namespace. Its routes are reachable under `/gamer/`, while its own docs paths are under `/gamer/docs/` and `/gamer/redoc/`. Project table names include the project's namespace so separate apps sharing one database do not collide. Mounting is optional; independent projects can instead run on separate ports or deployments.
|
|
924
|
+
|
|
925
|
+
For the shared admin console, enable `ADMIN_ENABLED` and create the admin account only in the primary project. Register models explicitly in each project's `app/admin.py`; after mounting, the primary `/admin/` groups those models by project and performs their data operations against each project's configured database. Keep `ADMIN_ENABLED = False` in mounted projects. Each mounted app instance can belong to only one parent admin.
|
|
926
|
+
|
|
802
927
|
The sample app exposes the model queries as HTTP routes: `POST /classrooms` creates a classroom, `GET /classrooms` lists them, and `POST /students` accepts an optional `classroom_id`. `POST /students/batch` creates multiple students, `PUT /students/batch` updates multiple students by ID, and `DELETE /students/batch` deletes multiple students by ID. Batch requests are all-or-nothing: unknown IDs, duplicate names, or a protected deletion reject the whole operation. `PUT /students/{student_id}` updates one student; it returns HTTP 404 if the ID does not exist. `GET /students/{student_id}/classroom` returns the related classroom. Other student routes list, search, and check existence. These routes appear in Swagger at `/docs/`.
|
|
803
928
|
|
|
804
929
|
Batch request examples:
|
|
@@ -1575,7 +1700,7 @@ async def billing_webhook(
|
|
|
1575
1700
|
|
|
1576
1701
|
## Databases
|
|
1577
1702
|
|
|
1578
|
-
`DATABASE_TYPE` chooses one backend and `DATABASE_URL` connects to it. The generated project defaults to SQLite. SQLite, MySQL, and PostgreSQL use SQLAlchemy models and Alembic revisions; MongoDB uses the separate `MongoDocument` API and does not have SQL schema revisions. `ACTIVATE_ASYNC = True` enables async access to the same database URL. Keep production credentials out of committed settings and URL-encode reserved characters in credentials.
|
|
1703
|
+
`DATABASE_TYPE` chooses one backend and `DATABASE_URL` connects to it. The generated project defaults to SQLite. SQLite, MySQL, and PostgreSQL use SQLAlchemy models and Alembic revisions; MongoDB uses the separate `MongoDocument` API and does not have SQL schema revisions. `app.database_type` reports the selected backend at runtime. `ACTIVATE_ASYNC = True` enables async access to the same database URL. Keep production credentials out of committed settings and URL-encode reserved characters in credentials.
|
|
1579
1704
|
|
|
1580
1705
|
```python
|
|
1581
1706
|
# settings.py — choose one backend and its URL
|
|
@@ -1593,6 +1718,8 @@ DATABASE_URL = f"sqlite:///{BASE_DIR / 'lenapi.db'}"
|
|
|
1593
1718
|
# MongoDB: install `python -m pip install 'lenapi[mongodb]'`
|
|
1594
1719
|
# DATABASE_TYPE = "mongodb"
|
|
1595
1720
|
# DATABASE_URL = "mongodb://user:password@localhost:27017/app_db"
|
|
1721
|
+
# If the URI has no database path, set this explicitly instead:
|
|
1722
|
+
# MONGODB_DATABASE = "app_db"
|
|
1596
1723
|
|
|
1597
1724
|
ACTIVATE_ASYNC = False
|
|
1598
1725
|
```
|
|
@@ -1636,7 +1763,44 @@ await student.asave()
|
|
|
1636
1763
|
await student.adelete()
|
|
1637
1764
|
```
|
|
1638
1765
|
|
|
1639
|
-
`MongoDatabase.ping()` and `await MongoDatabase.aping()` check connectivity. To select MongoDB, set `DATABASE_TYPE = "mongodb"
|
|
1766
|
+
`MongoDatabase.ping()` and `await MongoDatabase.aping()` check connectivity. To select MongoDB, set `DATABASE_TYPE = "mongodb"`. Put the database name in the URI path, such as `mongodb://localhost:27017/my_database`, or set `MONGODB_DATABASE = "my_database"` when the URI has no path. `ACTIVATE_ASYNC` controls whether LenApi also creates PyMongo's async client. `migration` and `migrate` ensure collections exist for imported `MongoDocument` models and framework security/admin state; document fields are schema-flexible and do not use Alembic revisions. `SECURITY_STORAGE = "database"` uses MongoDB for shared security state, while Redis and process memory remain optional choices. MongoDB uses the official synchronous and `AsyncMongoClient` APIs; see the [PyMongo driver guide](https://www.mongodb.com/docs/languages/python/pymongo-driver/current/).
|
|
1767
|
+
|
|
1768
|
+
#### Switching an existing project from SQL to MongoDB
|
|
1769
|
+
|
|
1770
|
+
Changing `DATABASE_TYPE` and `DATABASE_URL` selects MongoDB for the app; it does not convert existing SQLAlchemy models, tables, or rows. Define the Mongo-backed version as a `MongoDocument`, bind it after creating the app, and update routes to use that document class. If a SQL `model.Model` query runs while MongoDB is selected, LenAPI raises a clear backend-mismatch error explaining that a Mongo document is required. Check the active backend with `app.database_type`.
|
|
1771
|
+
|
|
1772
|
+
```python
|
|
1773
|
+
# settings.py
|
|
1774
|
+
DATABASE_TYPE = "mongodb"
|
|
1775
|
+
DATABASE_URL = "mongodb://127.0.0.1:27017/my_app"
|
|
1776
|
+
|
|
1777
|
+
# app/models.py
|
|
1778
|
+
from lenapi import MongoDocument
|
|
1779
|
+
|
|
1780
|
+
class MongoStudent(MongoDocument):
|
|
1781
|
+
collection_name = "students"
|
|
1782
|
+
username: str
|
|
1783
|
+
course: str
|
|
1784
|
+
|
|
1785
|
+
# main.py
|
|
1786
|
+
from lenapi import LENAPI
|
|
1787
|
+
from pydantic import BaseModel
|
|
1788
|
+
from app.models import MongoStudent
|
|
1789
|
+
|
|
1790
|
+
class StudentCreate(BaseModel):
|
|
1791
|
+
username: str
|
|
1792
|
+
course: str
|
|
1793
|
+
|
|
1794
|
+
app = LENAPI()
|
|
1795
|
+
MongoStudent.bind(app.mongodb)
|
|
1796
|
+
print(app.database_type) # mongodb
|
|
1797
|
+
|
|
1798
|
+
@app.post("/students")
|
|
1799
|
+
def create_student(data: StudentCreate):
|
|
1800
|
+
return MongoStudent.create(**data.model_dump())
|
|
1801
|
+
```
|
|
1802
|
+
|
|
1803
|
+
If you need to carry existing records over, treat that as an explicit data migration: back up both stores, copy in controlled batches, verify counts and important fields, and only then switch production traffic. LenAPI's `migration`/`migrate` commands initialize MongoDB collections and framework state; they do not copy SQL data. MongoDB document IDs are strings, so update route and response-schema ID types that previously expected integer SQL IDs.
|
|
1640
1804
|
|
|
1641
1805
|
Put application models in `app/models.py` and import that module from `main.py`. The migration command loads `main:app`, so it discovers those model classes before creating a migration. The library's `Model` base supplies an integer `id`:
|
|
1642
1806
|
|
|
@@ -1751,6 +1915,8 @@ python lenora.py migration --message "add student phone"
|
|
|
1751
1915
|
|
|
1752
1916
|
An existing unversioned SQLite database is adopted only when its schema matches the migration history; adoption preserves its data.
|
|
1753
1917
|
|
|
1918
|
+
`PositiveIntegerField` and `PositiveBigIntegerField` include a named database `CHECK` constraint. LenAPI prevents Alembic's metadata-copy step from adding that constraint twice, which MySQL rejects as a duplicate constraint name. If a local revision generated by an older LenAPI contains duplicate identical `sa.CheckConstraint(...)` entries, correct or regenerate that unapplied revision before using it. MySQL uses non-transactional DDL, so a failed migration may leave some project tables created even though no revision was recorded. Check `showmigrations` and inspect the project-namespaced tables before retrying. For a disposable database, `delete_migrations` can reset this project's tables and revisions after its confirmation prompt; if the data must be preserved, reconcile the partial schema instead of deleting it.
|
|
1919
|
+
|
|
1754
1920
|
`migrate` applies pending migration files already in `migrations/versions/`; it does not generate a revision. A common release workflow is to generate and inspect a revision during development, commit the revision with the code, then run `migrate` during deployment:
|
|
1755
1921
|
|
|
1756
1922
|
```bash
|
|
@@ -1773,9 +1939,9 @@ python lenora.py showmigrations
|
|
|
1773
1939
|
python lenora.py repair-migrations
|
|
1774
1940
|
```
|
|
1775
1941
|
|
|
1776
|
-
`clear_migrations` removes local revision files and
|
|
1942
|
+
`clear_migrations` removes local revision files and this project's Alembic version table only when there are no application tables in this project's namespace. It is for resetting an empty SQL project, not for reconciling an existing schema.
|
|
1777
1943
|
|
|
1778
|
-
`delete_migrations` is a destructive
|
|
1944
|
+
`delete_migrations` is a destructive reset of the current project. After an interactive y/n confirmation, it drops tables and views in this project's SQL namespace (or collections in this project's MongoDB namespace) and deletes local revision files. Objects belonging to other project namespaces are left alone. This also deletes this project's application data. Back up first and use it only when a clean project database is intended:
|
|
1779
1945
|
|
|
1780
1946
|
```bash
|
|
1781
1947
|
python lenora.py delete_migrations
|
|
@@ -8,7 +8,7 @@ if sys.version_info < (3, 11):
|
|
|
8
8
|
"on 2026-10-01 and is no longer supported."
|
|
9
9
|
)
|
|
10
10
|
|
|
11
|
-
__version__ = "0.1.
|
|
11
|
+
__version__ = "0.1.3"
|
|
12
12
|
|
|
13
13
|
from .application import Application, LENAPI, Router
|
|
14
14
|
from .background import BackgroundQueue, BackgroundTasks
|
|
@@ -17,6 +17,7 @@ from .authentication import authentication
|
|
|
17
17
|
from .auth import SocialAuth
|
|
18
18
|
from .authorization import require_owner, require_permission, require_role
|
|
19
19
|
from .database import AsyncDatabase, Database
|
|
20
|
+
from .transaction import transaction
|
|
20
21
|
from .mongodb import MongoDatabase, MongoDocument, MultipleDocumentsFound
|
|
21
22
|
from .parameters import Body, File
|
|
22
23
|
from .logging import get_logger, logger
|
|
@@ -95,7 +96,7 @@ from .security import (
|
|
|
95
96
|
from . import model
|
|
96
97
|
|
|
97
98
|
__all__ = [
|
|
98
|
-
"Application", "LENAPI", "Router", "Depends", "BackgroundTasks", "BackgroundQueue", "Cache", "Faker", "OpenAI", "Ollama", "CORSMiddleware", "DocsAuthMiddleware", "GZipMiddleware", "RequestIDMiddleware", "TimingMiddleware", "require_role", "require_permission", "require_owner", "Database", "AsyncDatabase", "MongoDatabase", "MongoDocument", "MultipleDocumentsFound", "Body", "File", "Model", "AdminUser", "AutoField", "logger", "get_logger", "WebSocket", "WebSocketConnection", "WebSocketDisconnect", "WebSocketService",
|
|
99
|
+
"Application", "LENAPI", "Router", "Depends", "BackgroundTasks", "BackgroundQueue", "Cache", "Faker", "OpenAI", "Ollama", "CORSMiddleware", "DocsAuthMiddleware", "GZipMiddleware", "RequestIDMiddleware", "TimingMiddleware", "require_role", "require_permission", "require_owner", "Database", "AsyncDatabase", "transaction", "MongoDatabase", "MongoDocument", "MultipleDocumentsFound", "Body", "File", "Model", "AdminUser", "AutoField", "logger", "get_logger", "WebSocket", "WebSocketConnection", "WebSocketDisconnect", "WebSocketService",
|
|
99
100
|
"IntegerField", "PositiveIntegerField", "BigIntField", "BigIntegerField", "PositiveBigIntegerField", "DecimalField", "StringField", "EmailField", "IPField", "PhoneField", "TextField", "UUIDField", "ImageField", "FileField", "FileImageField", "URLField", "BooleanField", "FloatField", "User",
|
|
100
101
|
"DateTimeField", "DateField", "TimeField", "DurationField", "JSONField", "ForeignKeyField", "OneToOneField", "ManyToManyField", "Count", "Sum", "Min", "Max", "Avg", "Request", "UploadFile", "Response", "JSONResponse",
|
|
101
102
|
"HTTPException", "JWTAuth", "APIKeyAuth", "BasicAuth", "CSRFProtect", "SessionAuth", "OpaqueBearerAuth", "HMACAuth", "OIDCAuth", "WebhookAuth", "hmac_request_signature", "session_auth", "opaque_bearer_auth", "hmac_auth", "oidc_auth", "webhook_auth", "create_authenticator", "authentication", "SocialAuth", "hash_password", "verify_password", "make_password", "check_password", "make_api_key", "hash_api_key", "UNSET", "model", "CASCADE", "SET_NULL", "PROTECT", "cascade", "null", "protected",
|