fastapi-sqla 3.2.1__tar.gz → 3.3.1__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.
Potentially problematic release.
This version of fastapi-sqla might be problematic. Click here for more details.
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/PKG-INFO +42 -26
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/README.md +31 -6
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/__init__.py +3 -1
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/base.py +28 -0
- fastapi_sqla-3.3.1/pyproject.toml +206 -0
- fastapi_sqla-3.2.1/pyproject.toml +0 -220
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/LICENSE +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/_pytest_plugin.py +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/async_pagination.py +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/async_sqla.py +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/aws_aurora_support.py +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/aws_rds_iam_support.py +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/models.py +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/pagination.py +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/py.typed +0 -0
- {fastapi_sqla-3.2.1 → fastapi_sqla-3.3.1}/fastapi_sqla/sqla.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fastapi-sqla
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: SQLAlchemy extension for FastAPI with support for pagination, asyncio, SQLModel, and pytest, ready for production.
|
|
5
5
|
Home-page: https://github.com/dialoguemd/fastapi-sqla
|
|
6
6
|
License: MIT
|
|
7
7
|
Keywords: FastAPI,SQLAlchemy,asyncio,pytest,alembic
|
|
8
8
|
Author: Hadrien David
|
|
9
9
|
Author-email: hadrien.david@dialogue.co
|
|
10
|
-
Requires-Python: >=3.9,<
|
|
10
|
+
Requires-Python: >=3.9,<3.13
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Environment :: Web Environment
|
|
13
13
|
Classifier: Framework :: AsyncIO
|
|
@@ -35,28 +35,19 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
35
35
|
Classifier: Typing :: Typed
|
|
36
36
|
Provides-Extra: asyncpg
|
|
37
37
|
Provides-Extra: aws-rds-iam
|
|
38
|
+
Provides-Extra: psycopg2
|
|
39
|
+
Provides-Extra: pytest-plugin
|
|
38
40
|
Provides-Extra: sqlmodel
|
|
39
|
-
|
|
40
|
-
Requires-Dist: Faker (>=14.2.0,<15.0.0) ; extra == "tests"
|
|
41
|
-
Requires-Dist: alembic (>=1.4.3,<2.0.0) ; extra == "tests"
|
|
42
|
-
Requires-Dist: asgi_lifespan (>=1.0.1,<2.0.0) ; extra == "tests"
|
|
41
|
+
Requires-Dist: alembic (>=1.4.3,<2.0.0) ; extra == "pytest-plugin"
|
|
43
42
|
Requires-Dist: asyncpg (>=0.28.0,<0.29.0) ; extra == "asyncpg"
|
|
44
43
|
Requires-Dist: boto3 (>=1.24.74,<2.0.0) ; extra == "aws-rds-iam"
|
|
45
|
-
Requires-Dist:
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist:
|
|
48
|
-
Requires-Dist:
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist: psycopg2 (>=2.8.6,<3.0.0) ; extra == "tests"
|
|
51
|
-
Requires-Dist: pydantic (>=1)
|
|
52
|
-
Requires-Dist: pytest (>=7.2.1,<8.0.0) ; extra == "tests"
|
|
53
|
-
Requires-Dist: pytest-asyncio (>=0.19.0,<0.20.0) ; extra == "tests"
|
|
54
|
-
Requires-Dist: pytest-cov (>=2.10.1,<3.0.0) ; extra == "tests"
|
|
55
|
-
Requires-Dist: ruff (>=0.4.5,<0.5.0) ; extra == "tests"
|
|
56
|
-
Requires-Dist: sqlalchemy (>=1.3)
|
|
44
|
+
Requires-Dist: deprecated (>=1.2,<2.0)
|
|
45
|
+
Requires-Dist: fastapi (>=0.95.1,<0.112)
|
|
46
|
+
Requires-Dist: psycopg2 (>=2.8.6,<3.0.0) ; extra == "psycopg2"
|
|
47
|
+
Requires-Dist: pydantic (>=1,<3)
|
|
48
|
+
Requires-Dist: sqlalchemy (>=1.3,<3)
|
|
57
49
|
Requires-Dist: sqlmodel (>=0.0.14,<0.0.15) ; extra == "sqlmodel"
|
|
58
|
-
Requires-Dist: structlog (>=20)
|
|
59
|
-
Requires-Dist: tox (>=3.26.0,<4.0.0) ; extra == "tests"
|
|
50
|
+
Requires-Dist: structlog (>=20,<25)
|
|
60
51
|
Project-URL: Repository, https://github.com/dialoguemd/fastapi-sqla
|
|
61
52
|
Description-Content-Type: text/markdown
|
|
62
53
|
|
|
@@ -82,6 +73,8 @@ Using [pip](https://pip.pypa.io/):
|
|
|
82
73
|
pip install fastapi-sqla
|
|
83
74
|
```
|
|
84
75
|
|
|
76
|
+
Note that you need a [SQLAlchemy compatible engine](https://docs.sqlalchemy.org/en/20/core/engines.html) adapter. We test with `psycopg2` which you can install using the `psycopg2` extra.
|
|
77
|
+
|
|
85
78
|
# Quick Example
|
|
86
79
|
|
|
87
80
|
Assuming it runs against a DB with a table `user` with 3 columns, `id`, `name` and
|
|
@@ -89,15 +82,22 @@ unique `email`:
|
|
|
89
82
|
|
|
90
83
|
```python
|
|
91
84
|
# main.py
|
|
85
|
+
from contextlib import asynccontextmanager
|
|
92
86
|
from fastapi import FastAPI, HTTPException
|
|
93
|
-
from fastapi_sqla import Base, Item, Page, Paginate, Session,
|
|
87
|
+
from fastapi_sqla import Base, Item, Page, Paginate, Session, setup_middlewares, startup
|
|
94
88
|
from pydantic import BaseModel, EmailStr
|
|
95
89
|
from sqlalchemy import select
|
|
96
90
|
from sqlalchemy.exc import IntegrityError
|
|
97
91
|
|
|
98
|
-
app = FastAPI()
|
|
99
92
|
|
|
100
|
-
|
|
93
|
+
@asynccontextmanager
|
|
94
|
+
async def lifespan(app: FastAPI):
|
|
95
|
+
await startup()
|
|
96
|
+
yield
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
app = FastAPI(lifespan=lifespan)
|
|
100
|
+
setup_middlewares(app)
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
class User(Base):
|
|
@@ -202,7 +202,23 @@ And define the environment variable `sqlalchemy_url` with `postgres+asyncpg` sch
|
|
|
202
202
|
export sqlalchemy_url=postgresql+asyncpg://postgres@localhost
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
-
## Setup the app:
|
|
205
|
+
## Setup the app AsyncContextManager (recommended):
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
import fastapi_sqla
|
|
209
|
+
from fastapi import FastAPI
|
|
210
|
+
|
|
211
|
+
@asynccontextmanager
|
|
212
|
+
async def lifespan(app: FastAPI):
|
|
213
|
+
await fastapi_sqla.startup()
|
|
214
|
+
yield
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
app = FastAPI(lifespan=lifespan)
|
|
218
|
+
fastapi_sqla.setup_middlewares(app)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Setup the app using startup/shutdown events (deprecated):
|
|
206
222
|
|
|
207
223
|
```python
|
|
208
224
|
import fastapi_sqla
|
|
@@ -639,7 +655,7 @@ If your project uses [SQLModel], then `Session` dependency is an SQLModel sessio
|
|
|
639
655
|
# Pytest fixtures
|
|
640
656
|
|
|
641
657
|
This library provides a set of utility fixtures, through its PyTest plugin, which is
|
|
642
|
-
automatically installed with the library.
|
|
658
|
+
automatically installed with the library. Using the plugin requires the `pytest_plugin` extra.
|
|
643
659
|
|
|
644
660
|
By default, no records are actually written to the database when running tests.
|
|
645
661
|
There currently is no way to change this behaviour.
|
|
@@ -783,7 +799,7 @@ It returns the path of `alembic.ini` configuration file. By default, it returns
|
|
|
783
799
|
## Setup
|
|
784
800
|
|
|
785
801
|
```bash
|
|
786
|
-
$ poetry install --extras
|
|
802
|
+
$ poetry install --all-extras
|
|
787
803
|
```
|
|
788
804
|
|
|
789
805
|
## Running tests
|
|
@@ -20,6 +20,8 @@ Using [pip](https://pip.pypa.io/):
|
|
|
20
20
|
pip install fastapi-sqla
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
Note that you need a [SQLAlchemy compatible engine](https://docs.sqlalchemy.org/en/20/core/engines.html) adapter. We test with `psycopg2` which you can install using the `psycopg2` extra.
|
|
24
|
+
|
|
23
25
|
# Quick Example
|
|
24
26
|
|
|
25
27
|
Assuming it runs against a DB with a table `user` with 3 columns, `id`, `name` and
|
|
@@ -27,15 +29,22 @@ unique `email`:
|
|
|
27
29
|
|
|
28
30
|
```python
|
|
29
31
|
# main.py
|
|
32
|
+
from contextlib import asynccontextmanager
|
|
30
33
|
from fastapi import FastAPI, HTTPException
|
|
31
|
-
from fastapi_sqla import Base, Item, Page, Paginate, Session,
|
|
34
|
+
from fastapi_sqla import Base, Item, Page, Paginate, Session, setup_middlewares, startup
|
|
32
35
|
from pydantic import BaseModel, EmailStr
|
|
33
36
|
from sqlalchemy import select
|
|
34
37
|
from sqlalchemy.exc import IntegrityError
|
|
35
38
|
|
|
36
|
-
app = FastAPI()
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
@asynccontextmanager
|
|
41
|
+
async def lifespan(app: FastAPI):
|
|
42
|
+
await startup()
|
|
43
|
+
yield
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
app = FastAPI(lifespan=lifespan)
|
|
47
|
+
setup_middlewares(app)
|
|
39
48
|
|
|
40
49
|
|
|
41
50
|
class User(Base):
|
|
@@ -140,7 +149,23 @@ And define the environment variable `sqlalchemy_url` with `postgres+asyncpg` sch
|
|
|
140
149
|
export sqlalchemy_url=postgresql+asyncpg://postgres@localhost
|
|
141
150
|
```
|
|
142
151
|
|
|
143
|
-
## Setup the app:
|
|
152
|
+
## Setup the app AsyncContextManager (recommended):
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
import fastapi_sqla
|
|
156
|
+
from fastapi import FastAPI
|
|
157
|
+
|
|
158
|
+
@asynccontextmanager
|
|
159
|
+
async def lifespan(app: FastAPI):
|
|
160
|
+
await fastapi_sqla.startup()
|
|
161
|
+
yield
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
app = FastAPI(lifespan=lifespan)
|
|
165
|
+
fastapi_sqla.setup_middlewares(app)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Setup the app using startup/shutdown events (deprecated):
|
|
144
169
|
|
|
145
170
|
```python
|
|
146
171
|
import fastapi_sqla
|
|
@@ -577,7 +602,7 @@ If your project uses [SQLModel], then `Session` dependency is an SQLModel sessio
|
|
|
577
602
|
# Pytest fixtures
|
|
578
603
|
|
|
579
604
|
This library provides a set of utility fixtures, through its PyTest plugin, which is
|
|
580
|
-
automatically installed with the library.
|
|
605
|
+
automatically installed with the library. Using the plugin requires the `pytest_plugin` extra.
|
|
581
606
|
|
|
582
607
|
By default, no records are actually written to the database when running tests.
|
|
583
608
|
There currently is no way to change this behaviour.
|
|
@@ -721,7 +746,7 @@ It returns the path of `alembic.ini` configuration file. By default, it returns
|
|
|
721
746
|
## Setup
|
|
722
747
|
|
|
723
748
|
```bash
|
|
724
|
-
$ poetry install --extras
|
|
749
|
+
$ poetry install --all-extras
|
|
725
750
|
```
|
|
726
751
|
|
|
727
752
|
## Running tests
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from fastapi_sqla.base import setup
|
|
1
|
+
from fastapi_sqla.base import setup, setup_middlewares, startup
|
|
2
2
|
from fastapi_sqla.models import Collection, Item, Page
|
|
3
3
|
from fastapi_sqla.pagination import Paginate, PaginateSignature, Pagination
|
|
4
4
|
from fastapi_sqla.sqla import (
|
|
@@ -22,6 +22,8 @@ __all__ = [
|
|
|
22
22
|
"SqlaSession",
|
|
23
23
|
"open_session",
|
|
24
24
|
"setup",
|
|
25
|
+
"setup_middlewares",
|
|
26
|
+
"startup",
|
|
25
27
|
]
|
|
26
28
|
|
|
27
29
|
|
|
@@ -2,6 +2,7 @@ import functools
|
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
|
+
from deprecated import deprecated
|
|
5
6
|
from fastapi import FastAPI
|
|
6
7
|
from sqlalchemy.engine import Engine
|
|
7
8
|
|
|
@@ -20,6 +21,33 @@ except ImportError as err: # pragma: no cover
|
|
|
20
21
|
_ENGINE_KEYS_REGEX = re.compile(r"fastapi_sqla__(?!_)(.+)(?<!_)__(?!_).+")
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
async def startup():
|
|
25
|
+
engine_keys = _get_engine_keys()
|
|
26
|
+
engines = {key: sqla.new_engine(key) for key in engine_keys}
|
|
27
|
+
for key, engine in engines.items():
|
|
28
|
+
if not _is_async_dialect(engine):
|
|
29
|
+
sqla.startup(key=key)
|
|
30
|
+
else:
|
|
31
|
+
await async_sqla.startup(key=key)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def setup_middlewares(app: FastAPI):
|
|
35
|
+
engine_keys = _get_engine_keys()
|
|
36
|
+
engines = {key: sqla.new_engine(key) for key in engine_keys}
|
|
37
|
+
for key, engine in engines.items():
|
|
38
|
+
if not _is_async_dialect(engine):
|
|
39
|
+
app.middleware("http")(
|
|
40
|
+
functools.partial(sqla.add_session_to_request, key=key)
|
|
41
|
+
)
|
|
42
|
+
else:
|
|
43
|
+
app.middleware("http")(
|
|
44
|
+
functools.partial(async_sqla.add_session_to_request, key=key)
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@deprecated(
|
|
49
|
+
reason="FastAPI events are deprecated. This function will be remove in the upcoming major release." # noqa: E501
|
|
50
|
+
)
|
|
23
51
|
def setup(app: FastAPI):
|
|
24
52
|
engine_keys = _get_engine_keys()
|
|
25
53
|
engines = {key: sqla.new_engine(key) for key in engine_keys}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "fastapi-sqla"
|
|
3
|
+
version = "3.3.1"
|
|
4
|
+
description = "SQLAlchemy extension for FastAPI with support for pagination, asyncio, SQLModel, and pytest, ready for production."
|
|
5
|
+
authors = [
|
|
6
|
+
"Hadrien David <hadrien.david@dialogue.co>",
|
|
7
|
+
"Victor Repkow <victor.repkow@dialogue.co>",
|
|
8
|
+
]
|
|
9
|
+
license = "MIT"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
repository = "https://github.com/dialoguemd/fastapi-sqla"
|
|
12
|
+
keywords = ["FastAPI", "SQLAlchemy", "asyncio", "pytest", "alembic"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 5 - Production/Stable",
|
|
15
|
+
"Environment :: Web Environment",
|
|
16
|
+
"Framework :: AsyncIO",
|
|
17
|
+
"Framework :: FastAPI",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: Information Technology",
|
|
20
|
+
"Intended Audience :: System Administrators",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.9",
|
|
28
|
+
"Programming Language :: Python",
|
|
29
|
+
"Programming Language :: SQL",
|
|
30
|
+
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
|
|
31
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
32
|
+
"Topic :: Internet",
|
|
33
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
34
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
35
|
+
"Topic :: Software Development :: Libraries",
|
|
36
|
+
"Topic :: Software Development",
|
|
37
|
+
"Typing :: Typed",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[tool.poetry.dependencies]
|
|
41
|
+
python = ">=3.9,<3.13"
|
|
42
|
+
fastapi = ">=0.95.1,<0.112"
|
|
43
|
+
pydantic = ">=1,<3"
|
|
44
|
+
sqlalchemy = ">=1.3,<3"
|
|
45
|
+
structlog = ">=20,<25"
|
|
46
|
+
deprecated = "^1.2"
|
|
47
|
+
|
|
48
|
+
alembic = { version = "^1.4.3", optional = true }
|
|
49
|
+
asyncpg = { version = "^0.28.0", optional = true }
|
|
50
|
+
boto3 = { version = "^1.24.74", optional = true }
|
|
51
|
+
psycopg2 = { version = "^2.8.6", optional = true }
|
|
52
|
+
sqlmodel = { version = "^0.0.14", optional = true }
|
|
53
|
+
|
|
54
|
+
[tool.poetry.group.dev.dependencies]
|
|
55
|
+
alembic = "1.13.1"
|
|
56
|
+
asgi_lifespan = "2.1.0"
|
|
57
|
+
Faker = "25.8.0"
|
|
58
|
+
greenlet = "3.0.3"
|
|
59
|
+
httpx = "0.27.0"
|
|
60
|
+
mypy = { version = "1.10.0", extras = ["tests"] }
|
|
61
|
+
psycopg2 = { version = "2.9.9", extras = ["binary"] }
|
|
62
|
+
pytest = "8.2.2"
|
|
63
|
+
pytest-asyncio = "0.23.7"
|
|
64
|
+
pytest-cov = "5.0.0"
|
|
65
|
+
ruff = "0.4.9"
|
|
66
|
+
tox = "4.15.1"
|
|
67
|
+
|
|
68
|
+
[tool.poetry.extras]
|
|
69
|
+
asyncpg = ["asyncpg"]
|
|
70
|
+
aws_rds_iam = ["boto3"]
|
|
71
|
+
pytest_plugin = ["alembic"]
|
|
72
|
+
psycopg2 = ["psycopg2"]
|
|
73
|
+
sqlmodel = ["sqlmodel"]
|
|
74
|
+
|
|
75
|
+
[build-system]
|
|
76
|
+
requires = ["poetry>=1.3.0"]
|
|
77
|
+
build-backend = "poetry.masonry.api"
|
|
78
|
+
|
|
79
|
+
[tool.semantic_release]
|
|
80
|
+
version_toml = ["pyproject.toml:tool.poetry.version"]
|
|
81
|
+
upload_to_pypi = false
|
|
82
|
+
commit_message = "{version}\n\nVersion generated by python-semantic-release [ci skip]"
|
|
83
|
+
|
|
84
|
+
[tool.poetry.plugins."pytest11"]
|
|
85
|
+
fastapi-sqla = "fastapi_sqla._pytest_plugin"
|
|
86
|
+
|
|
87
|
+
[tool.ruff]
|
|
88
|
+
target-version = "py39"
|
|
89
|
+
|
|
90
|
+
[tool.ruff.lint]
|
|
91
|
+
select = [
|
|
92
|
+
"E", # pycodestyle
|
|
93
|
+
"W", # pycodestyle warnings
|
|
94
|
+
"F", # pyflakes
|
|
95
|
+
"I", # isort
|
|
96
|
+
"N", # pep8-naming
|
|
97
|
+
"D", # pydocstyle
|
|
98
|
+
"UP", # pyupgrade
|
|
99
|
+
"ASYNC", # flake8-async
|
|
100
|
+
"S", # flake8-bandit
|
|
101
|
+
"B", # flake8-bugbear
|
|
102
|
+
"C4", # flake8-comprehensions
|
|
103
|
+
"SIM", # flake8-simplify
|
|
104
|
+
"TD", # flake8-todos
|
|
105
|
+
"ERA", # eradicate
|
|
106
|
+
"PL", # pylint
|
|
107
|
+
"RUF", # ruff
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
# Ignore some pydocstyle rules that Google convention enables
|
|
111
|
+
ignore = [
|
|
112
|
+
"D100",
|
|
113
|
+
"D101",
|
|
114
|
+
"D102",
|
|
115
|
+
"D103",
|
|
116
|
+
"D104",
|
|
117
|
+
"D105",
|
|
118
|
+
"D106",
|
|
119
|
+
"D107",
|
|
120
|
+
"D212",
|
|
121
|
+
"D415",
|
|
122
|
+
"B008", # Enable using functions in default function args. Easier to work with FastAPI dependencies that way
|
|
123
|
+
"C408", # Enable using dict/list/tuple
|
|
124
|
+
"PLR0911", # Disable max number of return
|
|
125
|
+
"PLR0912", # Disable max number of branches
|
|
126
|
+
"PLR0913", # Disable max number of args
|
|
127
|
+
"PLR0915", # Disable max number of statements
|
|
128
|
+
"PLR2004", # Enable magic values
|
|
129
|
+
"SIM105", # Allow using try - except - pass
|
|
130
|
+
"TD001", # Enable FIXMEs
|
|
131
|
+
"TD002", # Enable TODOs without author
|
|
132
|
+
"TD003", # Enable TODOs without issue link
|
|
133
|
+
"N802", # FastAPI dependency conventions is title cased
|
|
134
|
+
"N803", # Same as N802
|
|
135
|
+
"N806", # Same as N802
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
[tool.ruff.lint.extend-per-file-ignores]
|
|
139
|
+
"tests/*" = [
|
|
140
|
+
"S101", # Enable assert
|
|
141
|
+
"S105", # Disable passwords check
|
|
142
|
+
"S106", # Disable passwords check
|
|
143
|
+
"S608", # Allow SQL string construction
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
[tool.ruff.lint.pydocstyle]
|
|
147
|
+
convention = "google"
|
|
148
|
+
|
|
149
|
+
[tool.pytest.ini_options]
|
|
150
|
+
asyncio_mode = "auto"
|
|
151
|
+
testpaths = "tests"
|
|
152
|
+
norecursedirs = ".git,.venv"
|
|
153
|
+
xfail_strict = "true"
|
|
154
|
+
addopts = """
|
|
155
|
+
-p no:fastapi-sqla
|
|
156
|
+
--cov-config pyproject.toml
|
|
157
|
+
--cov-report term
|
|
158
|
+
--cov-report term-missing
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
# https://nedbatchelder.com/blog/201810/why_warnings_is_mysterious.html
|
|
162
|
+
filterwarnings = ["error:.*removed in version 2.0.*:"]
|
|
163
|
+
|
|
164
|
+
[tool.pytest-watch.run]
|
|
165
|
+
ext = ".py, .yaml, .cfg"
|
|
166
|
+
|
|
167
|
+
[tool.coverage.run]
|
|
168
|
+
branch = true
|
|
169
|
+
omit = ["tests/*", ".venv/*"]
|
|
170
|
+
concurrency = ["thread", "greenlet"]
|
|
171
|
+
|
|
172
|
+
[tool.coverage.report]
|
|
173
|
+
skip_covered = true
|
|
174
|
+
|
|
175
|
+
[tool.tox]
|
|
176
|
+
legacy_tox_ini = """
|
|
177
|
+
[tox]
|
|
178
|
+
envlist = sqlalchemy{ 1.3, 1.4, 2.0, 2.0-sqlmodel }-{ asyncpg, noasyncpg }-{aws_rds_iam, noaws_rds_iam }-pydantic{ 1, 2 }
|
|
179
|
+
|
|
180
|
+
[testenv]
|
|
181
|
+
passenv = CI
|
|
182
|
+
skip_install = true
|
|
183
|
+
allowlist_externals = poetry
|
|
184
|
+
commands_pre =
|
|
185
|
+
poetry install
|
|
186
|
+
sqlmodel: poetry install --extras "sqlmodel"
|
|
187
|
+
aws_rds_iam: poetry install --extras "aws_rds_iam"
|
|
188
|
+
asyncpg: poetry install --extras "asyncpg"
|
|
189
|
+
asyncpg-aws_rds_iam: poetry install --extras "asyncpg aws_rds_iam"
|
|
190
|
+
sqlmodel-aws_rds_iam: poetry install --extras "sqlmodel aws_rds_iam"
|
|
191
|
+
sqlmodel-asyncpg: poetry install --extras "sqlmodel asyncpg"
|
|
192
|
+
sqlmodel-asyncpg-aws_rds_iam: poetry install --extras "sqlmodel asyncpg aws_rds_iam"
|
|
193
|
+
sqlalchemy1.3: pip install sqlalchemy==1.3
|
|
194
|
+
sqlalchemy1.4: pip install sqlalchemy==1.4.52
|
|
195
|
+
pydantic1: pip install pydantic==1.10.16
|
|
196
|
+
commands =
|
|
197
|
+
poetry run pytest -vv --showlocals --cov . --cov-report xml --cov-report html --junitxml=test-reports/pytest/junit.xml
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
[tool.mypy]
|
|
201
|
+
exclude = ["tests"]
|
|
202
|
+
plugins = ["sqlalchemy.ext.mypy.plugin"]
|
|
203
|
+
|
|
204
|
+
[[tool.mypy.overrides]]
|
|
205
|
+
module = ["asyncpg", "boto3", "deprecated"]
|
|
206
|
+
ignore_missing_imports = true
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "fastapi-sqla"
|
|
3
|
-
version = "3.2.1"
|
|
4
|
-
description = "SQLAlchemy extension for FastAPI with support for pagination, asyncio, SQLModel, and pytest, ready for production."
|
|
5
|
-
authors = [
|
|
6
|
-
"Hadrien David <hadrien.david@dialogue.co>",
|
|
7
|
-
"Victor Repkow <victor.repkow@dialogue.co>",
|
|
8
|
-
]
|
|
9
|
-
license = "MIT"
|
|
10
|
-
readme = "README.md"
|
|
11
|
-
repository = "https://github.com/dialoguemd/fastapi-sqla"
|
|
12
|
-
keywords = ["FastAPI", "SQLAlchemy", "asyncio", "pytest", "alembic"]
|
|
13
|
-
classifiers = [
|
|
14
|
-
"Development Status :: 5 - Production/Stable",
|
|
15
|
-
"Environment :: Web Environment",
|
|
16
|
-
"Framework :: AsyncIO",
|
|
17
|
-
"Framework :: FastAPI",
|
|
18
|
-
"Intended Audience :: Developers",
|
|
19
|
-
"Intended Audience :: Information Technology",
|
|
20
|
-
"Intended Audience :: System Administrators",
|
|
21
|
-
"License :: OSI Approved :: MIT License",
|
|
22
|
-
"Operating System :: OS Independent",
|
|
23
|
-
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
-
"Programming Language :: Python :: 3",
|
|
25
|
-
"Programming Language :: Python :: 3.11",
|
|
26
|
-
"Programming Language :: Python :: 3.10",
|
|
27
|
-
"Programming Language :: Python :: 3.9",
|
|
28
|
-
"Programming Language :: Python",
|
|
29
|
-
"Programming Language :: SQL",
|
|
30
|
-
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
|
|
31
|
-
"Topic :: Internet :: WWW/HTTP",
|
|
32
|
-
"Topic :: Internet",
|
|
33
|
-
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
34
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
35
|
-
"Topic :: Software Development :: Libraries",
|
|
36
|
-
"Topic :: Software Development",
|
|
37
|
-
"Typing :: Typed",
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
[tool.poetry.dependencies]
|
|
41
|
-
python = "^3.9"
|
|
42
|
-
fastapi = ">=0.95.1"
|
|
43
|
-
pydantic = ">=1"
|
|
44
|
-
sqlalchemy = ">=1.3"
|
|
45
|
-
structlog = ">=20"
|
|
46
|
-
|
|
47
|
-
alembic = { version = "^1.4.3", optional = true}
|
|
48
|
-
asgi_lifespan = { version = "^1.0.1", optional = true}
|
|
49
|
-
asyncpg = {version = "^0.28.0", optional = true}
|
|
50
|
-
Faker = {version = "^14.2.0", optional = true}
|
|
51
|
-
httpx = {version = "^0.23.0", optional = true}
|
|
52
|
-
pdbpp = { version = "^0.10.2", optional = true}
|
|
53
|
-
psycopg2 = { version = "^2.8.6", optional = true}
|
|
54
|
-
pytest = {version = "^7.2.1", optional = true}
|
|
55
|
-
pytest-asyncio = {version = "^0.19.0", optional = true}
|
|
56
|
-
pytest-cov = { version = "^2.10.1", optional = true}
|
|
57
|
-
ruff = {version = "^0.4.5", optional = true}
|
|
58
|
-
tox = {version = "^3.26.0", optional = true}
|
|
59
|
-
boto3 = {version = "^1.24.74", optional = true}
|
|
60
|
-
greenlet = {version = "^3.0.3", optional = true}
|
|
61
|
-
mypy = {version = "^1.0.0", extras = ["tests"], optional = true}
|
|
62
|
-
sqlmodel = { version = "^0.0.14", optional = true }
|
|
63
|
-
|
|
64
|
-
[tool.poetry.extras]
|
|
65
|
-
# Test dependencies as extras so they can be set as extras in tox config
|
|
66
|
-
# More info on https://github.com/python-poetry/poetry/issues/1941
|
|
67
|
-
tests = [
|
|
68
|
-
"alembic",
|
|
69
|
-
"asgi_lifespan",
|
|
70
|
-
"coverage",
|
|
71
|
-
"Faker",
|
|
72
|
-
"greenlet",
|
|
73
|
-
"httpx",
|
|
74
|
-
"mypy",
|
|
75
|
-
"pdbpp",
|
|
76
|
-
"psycopg2",
|
|
77
|
-
"pytest",
|
|
78
|
-
"pytest-asyncio",
|
|
79
|
-
"pytest-cov",
|
|
80
|
-
"pytest-watch",
|
|
81
|
-
"ruff",
|
|
82
|
-
"tox",
|
|
83
|
-
]
|
|
84
|
-
asyncpg = ["asyncpg"]
|
|
85
|
-
aws_rds_iam = ["boto3"]
|
|
86
|
-
sqlmodel = ["sqlmodel"]
|
|
87
|
-
|
|
88
|
-
[build-system]
|
|
89
|
-
requires = ["poetry>=1.3.0"]
|
|
90
|
-
build-backend = "poetry.masonry.api"
|
|
91
|
-
|
|
92
|
-
[tool.semantic_release]
|
|
93
|
-
version_toml = ["pyproject.toml:tool.poetry.version"]
|
|
94
|
-
upload_to_pypi = false
|
|
95
|
-
commit_message = "{version}\n\nVersion generated by python-semantic-release [ci skip]"
|
|
96
|
-
|
|
97
|
-
[tool.poetry.plugins."pytest11"]
|
|
98
|
-
fastapi-sqla = "fastapi_sqla._pytest_plugin"
|
|
99
|
-
|
|
100
|
-
[tool.ruff]
|
|
101
|
-
target-version = "py39"
|
|
102
|
-
|
|
103
|
-
[tool.ruff.lint]
|
|
104
|
-
select = [
|
|
105
|
-
"E", # pycodestyle
|
|
106
|
-
"W", # pycodestyle warnings
|
|
107
|
-
"F", # pyflakes
|
|
108
|
-
"I", # isort
|
|
109
|
-
"N", # pep8-naming
|
|
110
|
-
"D", # pydocstyle
|
|
111
|
-
"UP", # pyupgrade
|
|
112
|
-
"ASYNC", # flake8-async
|
|
113
|
-
"S", # flake8-bandit
|
|
114
|
-
"B", # flake8-bugbear
|
|
115
|
-
"C4", # flake8-comprehensions
|
|
116
|
-
"SIM", # flake8-simplify
|
|
117
|
-
"TD", # flake8-todos
|
|
118
|
-
"ERA", # eradicate
|
|
119
|
-
"PL", # pylint
|
|
120
|
-
"RUF" # ruff
|
|
121
|
-
]
|
|
122
|
-
|
|
123
|
-
# Ignore some pydocstyle rules that Google convention enables
|
|
124
|
-
ignore = [
|
|
125
|
-
"D100",
|
|
126
|
-
"D101",
|
|
127
|
-
"D102",
|
|
128
|
-
"D103",
|
|
129
|
-
"D104",
|
|
130
|
-
"D105",
|
|
131
|
-
"D106",
|
|
132
|
-
"D107",
|
|
133
|
-
"D212",
|
|
134
|
-
"D415",
|
|
135
|
-
"B008", # Enable using functions in default function args. Easier to work with FastAPI dependencies that way
|
|
136
|
-
"C408", # Enable using dict/list/tuple
|
|
137
|
-
"PLR0911", # Disable max number of return
|
|
138
|
-
"PLR0912", # Disable max number of branches
|
|
139
|
-
"PLR0913", # Disable max number of args
|
|
140
|
-
"PLR0915", # Disable max number of statements
|
|
141
|
-
"PLR2004", # Enable magic values
|
|
142
|
-
"SIM105", # Allow using try - except - pass
|
|
143
|
-
"TD001", # Enable FIXMEs
|
|
144
|
-
"TD002", # Enable TODOs without author
|
|
145
|
-
"TD003", # Enable TODOs without issue link
|
|
146
|
-
"N802", # FastAPI dependency conventions is title cased
|
|
147
|
-
"N803", # Same as N802
|
|
148
|
-
"N806", # Same as N802
|
|
149
|
-
]
|
|
150
|
-
|
|
151
|
-
[tool.ruff.lint.extend-per-file-ignores]
|
|
152
|
-
"tests/*" = [
|
|
153
|
-
"S101", # Enable assert
|
|
154
|
-
"S105", # Disable passwords check
|
|
155
|
-
"S106", # Disable passwords check
|
|
156
|
-
"S608", # Allow SQL string construction
|
|
157
|
-
]
|
|
158
|
-
|
|
159
|
-
[tool.ruff.lint.pydocstyle]
|
|
160
|
-
convention = "google"
|
|
161
|
-
|
|
162
|
-
[tool.pytest.ini_options]
|
|
163
|
-
asyncio_mode = "auto"
|
|
164
|
-
testpaths = "tests"
|
|
165
|
-
norecursedirs = ".git,.venv"
|
|
166
|
-
xfail_strict = "true"
|
|
167
|
-
addopts = """
|
|
168
|
-
-p no:fastapi-sqla
|
|
169
|
-
--cov-config pyproject.toml
|
|
170
|
-
--cov-report term
|
|
171
|
-
--cov-report term-missing
|
|
172
|
-
"""
|
|
173
|
-
|
|
174
|
-
# https://nedbatchelder.com/blog/201810/why_warnings_is_mysterious.html
|
|
175
|
-
filterwarnings = [
|
|
176
|
-
"error:.*removed in version 2.0.*:",
|
|
177
|
-
]
|
|
178
|
-
|
|
179
|
-
[tool.pytest-watch.run]
|
|
180
|
-
ext = ".py, .yaml, .cfg"
|
|
181
|
-
|
|
182
|
-
[tool.coverage.run]
|
|
183
|
-
branch = true
|
|
184
|
-
omit = [
|
|
185
|
-
"tests/*",
|
|
186
|
-
".venv/*"
|
|
187
|
-
]
|
|
188
|
-
concurrency = ["thread", "greenlet"]
|
|
189
|
-
|
|
190
|
-
[tool.coverage.report]
|
|
191
|
-
skip_covered = true
|
|
192
|
-
|
|
193
|
-
[tool.tox]
|
|
194
|
-
legacy_tox_ini = """
|
|
195
|
-
[tox]
|
|
196
|
-
envlist = sqlalchemy{ 1.3, 1.4, 2.0, 2.0-sqlmodel }-{ asyncpg, noasyncpg }-{aws_rds_iam, noaws_rds_iam }-pydantic{ 1, 2 }
|
|
197
|
-
|
|
198
|
-
[testenv]
|
|
199
|
-
passenv = CI
|
|
200
|
-
deps =
|
|
201
|
-
sqlalchemy1.3: sqlalchemy<1.4
|
|
202
|
-
sqlalchemy1.4: sqlalchemy>=1.4,<2
|
|
203
|
-
sqlalchemy2.0: sqlalchemy>=2
|
|
204
|
-
sqlalchemy2.0-sqlmodel: sqlalchemy>=2
|
|
205
|
-
sqlalchemy2.0-sqlmodel: sqlmodel
|
|
206
|
-
asyncpg: asyncpg
|
|
207
|
-
aws_rds_iam: boto3
|
|
208
|
-
pydantic1: pydantic<2
|
|
209
|
-
pydantic2: pydantic>=2
|
|
210
|
-
|
|
211
|
-
extras =
|
|
212
|
-
tests
|
|
213
|
-
|
|
214
|
-
commands = pytest -vv --cov={envsitepackagesdir}/fastapi_sqla --cov-report xml --cov-report html --junitxml=test-reports/pytest/junit.xml
|
|
215
|
-
"""
|
|
216
|
-
|
|
217
|
-
[tool.mypy]
|
|
218
|
-
exclude = ["tests"]
|
|
219
|
-
ignore_missing_imports = true
|
|
220
|
-
plugins = "sqlalchemy.ext.mypy.plugin"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|