fastapi-sqla 3.1.2__tar.gz → 3.3.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastapi-sqla
3
- Version: 3.1.2
3
+ Version: 3.3.0
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
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3
22
22
  Classifier: Programming Language :: Python :: 3.9
23
23
  Classifier: Programming Language :: Python :: 3.10
24
24
  Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
25
26
  Classifier: Programming Language :: Python :: 3 :: Only
26
27
  Classifier: Programming Language :: SQL
27
28
  Classifier: Topic :: Internet
@@ -40,20 +41,19 @@ Requires-Dist: Faker (>=14.2.0,<15.0.0) ; extra == "tests"
40
41
  Requires-Dist: alembic (>=1.4.3,<2.0.0) ; extra == "tests"
41
42
  Requires-Dist: asgi_lifespan (>=1.0.1,<2.0.0) ; extra == "tests"
42
43
  Requires-Dist: asyncpg (>=0.28.0,<0.29.0) ; extra == "asyncpg"
43
- Requires-Dist: black (>=22.8.0,<23.0.0) ; extra == "tests"
44
44
  Requires-Dist: boto3 (>=1.24.74,<2.0.0) ; extra == "aws-rds-iam"
45
+ Requires-Dist: deprecated (>=1.2)
45
46
  Requires-Dist: fastapi (>=0.95.1)
46
- Requires-Dist: greenlet (>=1.1.3,<2.0.0) ; extra == "tests"
47
+ Requires-Dist: greenlet (>=3.0.3,<4.0.0) ; extra == "tests"
47
48
  Requires-Dist: httpx (>=0.23.0,<0.24.0) ; extra == "tests"
48
- Requires-Dist: isort (>=5.5.3,<6.0.0) ; extra == "tests"
49
49
  Requires-Dist: mypy[tests] (>=1.0.0,<2.0.0) ; extra == "tests"
50
50
  Requires-Dist: pdbpp (>=0.10.2,<0.11.0) ; extra == "tests"
51
51
  Requires-Dist: psycopg2 (>=2.8.6,<3.0.0) ; extra == "tests"
52
52
  Requires-Dist: pydantic (>=1)
53
- Requires-Dist: pylama (>=8.4.1,<9.0.0) ; extra == "tests"
54
53
  Requires-Dist: pytest (>=7.2.1,<8.0.0) ; extra == "tests"
55
54
  Requires-Dist: pytest-asyncio (>=0.19.0,<0.20.0) ; extra == "tests"
56
55
  Requires-Dist: pytest-cov (>=2.10.1,<3.0.0) ; extra == "tests"
56
+ Requires-Dist: ruff (>=0.4.5,<0.5.0) ; extra == "tests"
57
57
  Requires-Dist: sqlalchemy (>=1.3)
58
58
  Requires-Dist: sqlmodel (>=0.0.14,<0.0.15) ; extra == "sqlmodel"
59
59
  Requires-Dist: structlog (>=20)
@@ -90,15 +90,22 @@ unique `email`:
90
90
 
91
91
  ```python
92
92
  # main.py
93
+ from contextlib import asynccontextmanager
93
94
  from fastapi import FastAPI, HTTPException
94
- from fastapi_sqla import Base, Item, Page, Paginate, Session, setup
95
+ from fastapi_sqla import Base, Item, Page, Paginate, Session, setup_middlewares, startup
95
96
  from pydantic import BaseModel, EmailStr
96
97
  from sqlalchemy import select
97
98
  from sqlalchemy.exc import IntegrityError
98
99
 
99
- app = FastAPI()
100
100
 
101
- setup(app)
101
+ @asynccontextmanager
102
+ async def lifespan(app: FastAPI):
103
+ await startup()
104
+ yield
105
+
106
+
107
+ app = FastAPI(lifespan=lifespan)
108
+ setup_middlewares(app)
102
109
 
103
110
 
104
111
  class User(Base):
@@ -203,7 +210,23 @@ And define the environment variable `sqlalchemy_url` with `postgres+asyncpg` sch
203
210
  export sqlalchemy_url=postgresql+asyncpg://postgres@localhost
204
211
  ```
205
212
 
206
- ## Setup the app:
213
+ ## Setup the app AsyncContextManager (recommended):
214
+
215
+ ```python
216
+ import fastapi_sqla
217
+ from fastapi import FastAPI
218
+
219
+ @asynccontextmanager
220
+ async def lifespan(app: FastAPI):
221
+ await fastapi_sqla.startup()
222
+ yield
223
+
224
+
225
+ app = FastAPI(lifespan=lifespan)
226
+ fastapi_sqla.setup_middlewares(app)
227
+ ```
228
+
229
+ ## Setup the app using startup/shutdown events (deprecated):
207
230
 
208
231
  ```python
209
232
  import fastapi_sqla
@@ -27,15 +27,22 @@ unique `email`:
27
27
 
28
28
  ```python
29
29
  # main.py
30
+ from contextlib import asynccontextmanager
30
31
  from fastapi import FastAPI, HTTPException
31
- from fastapi_sqla import Base, Item, Page, Paginate, Session, setup
32
+ from fastapi_sqla import Base, Item, Page, Paginate, Session, setup_middlewares, startup
32
33
  from pydantic import BaseModel, EmailStr
33
34
  from sqlalchemy import select
34
35
  from sqlalchemy.exc import IntegrityError
35
36
 
36
- app = FastAPI()
37
37
 
38
- setup(app)
38
+ @asynccontextmanager
39
+ async def lifespan(app: FastAPI):
40
+ await startup()
41
+ yield
42
+
43
+
44
+ app = FastAPI(lifespan=lifespan)
45
+ setup_middlewares(app)
39
46
 
40
47
 
41
48
  class User(Base):
@@ -140,7 +147,23 @@ And define the environment variable `sqlalchemy_url` with `postgres+asyncpg` sch
140
147
  export sqlalchemy_url=postgresql+asyncpg://postgres@localhost
141
148
  ```
142
149
 
143
- ## Setup the app:
150
+ ## Setup the app AsyncContextManager (recommended):
151
+
152
+ ```python
153
+ import fastapi_sqla
154
+ from fastapi import FastAPI
155
+
156
+ @asynccontextmanager
157
+ async def lifespan(app: FastAPI):
158
+ await fastapi_sqla.startup()
159
+ yield
160
+
161
+
162
+ app = FastAPI(lifespan=lifespan)
163
+ fastapi_sqla.setup_middlewares(app)
164
+ ```
165
+
166
+ ## Setup the app using startup/shutdown events (deprecated):
144
167
 
145
168
  ```python
146
169
  import fastapi_sqla
@@ -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
 
@@ -28,7 +28,6 @@ def db_host():
28
28
  When CI key is set in environment variables, it uses `postgres` as host name else,
29
29
  host used is `localhost`
30
30
  """
31
-
32
31
  return "postgres" if "CI" in os.environ else "localhost"
33
32
 
34
33
 
@@ -38,7 +37,6 @@ def db_user():
38
37
 
39
38
  postgres
40
39
  """
41
-
42
40
  return "postgres"
43
41
 
44
42
 
@@ -48,7 +46,6 @@ def db_url(db_host, db_user):
48
46
 
49
47
  db url example postgresql://{db_user}@{db_host}/postgres
50
48
  """
51
-
52
49
  return f"postgresql://{db_user}@{db_host}/postgres"
53
50
 
54
51
 
@@ -107,7 +104,6 @@ def sqla_reflection(sqla_modules, sqla_connection):
107
104
  @fixture
108
105
  def patch_engine_from_config(request, sqla_connection):
109
106
  """So that all DB operations are never written to db for real."""
110
-
111
107
  if "dont_patch_engines" in request.keywords:
112
108
  yield
113
109
  else:
@@ -153,7 +149,7 @@ def async_sqlalchemy_url(db_url):
153
149
  return format_async_async_sqlalchemy_url(db_url)
154
150
 
155
151
 
156
- if asyncio_support: # noqa: C901
152
+ if asyncio_support:
157
153
 
158
154
  @fixture
159
155
  def async_engine(async_sqlalchemy_url):
@@ -167,7 +163,6 @@ if asyncio_support: # noqa: C901
167
163
  @fixture
168
164
  async def patch_new_engine(request, async_sqla_connection):
169
165
  """So that all async DB operations are never written to db for real."""
170
-
171
166
  if "dont_patch_engines" in request.keywords:
172
167
  yield
173
168
  else:
@@ -1,6 +1,6 @@
1
1
  import math
2
- from collections.abc import Awaitable, Callable
3
- from typing import Annotated, Iterator, Optional, Union, cast
2
+ from collections.abc import Awaitable, Callable, Iterator
3
+ from typing import Annotated, Optional, Union, cast
4
4
 
5
5
  from fastapi import Depends, Query
6
6
  from sqlalchemy.sql import Select, func, select
@@ -20,7 +20,8 @@ def setup(engine: Engine):
20
20
  aws_rds_iam_enabled = lc_environ.get("fastapi_sqla_aws_rds_iam_enabled") == "true"
21
21
 
22
22
  if aws_rds_iam_enabled:
23
- assert boto3_installed, boto3_installed_err
23
+ if not boto3_installed:
24
+ raise ImportError(f"boto3 is required for RDS IAM : {boto3_installed_err}")
24
25
  # Cache the client at startup
25
26
  get_rds_client()
26
27
  event.listen(engine, "do_connect", set_connection_token)
@@ -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}
@@ -30,7 +58,6 @@ def setup(app: FastAPI):
30
58
  functools.partial(sqla.add_session_to_request, key=key)
31
59
  )
32
60
  else:
33
- assert has_asyncio_support, asyncio_support_err
34
61
  app.add_event_handler(
35
62
  "startup", functools.partial(async_sqla.startup, key=key)
36
63
  )
@@ -3,7 +3,7 @@ from typing import Generic, TypeVar
3
3
  from pydantic import BaseModel, Field
4
4
  from pydantic import __version__ as pydantic_version
5
5
 
6
- major, _, _ = [int(v) for v in pydantic_version.split(".")]
6
+ major, _, _ = (int(v) for v in pydantic_version.split("."))
7
7
  is_pydantic2 = major == 2
8
8
  if is_pydantic2:
9
9
  GenericModel = BaseModel
@@ -1,7 +1,7 @@
1
1
  import math
2
- from collections.abc import Callable
2
+ from collections.abc import Callable, Iterator
3
3
  from functools import singledispatch
4
- from typing import Annotated, Iterator, Optional, Union, cast
4
+ from typing import Annotated, Optional, Union, cast
5
5
 
6
6
  from fastapi import Depends, Query
7
7
  from sqlalchemy.orm import Query as LegacyQuery
@@ -52,7 +52,7 @@ def paginate_query(
52
52
  limit: int,
53
53
  scalars: bool = True,
54
54
  ) -> Page: # pragma: no cover
55
- "Dispatch on registered functions based on `query` type"
55
+ """Dispatch on registered functions based on `query` type"""
56
56
  raise NotImplementedError(f"no paginate_query registered for type {type(query)!r}")
57
57
 
58
58
 
@@ -24,7 +24,7 @@ except ImportError:
24
24
  DeclarativeBase = declarative_base() # type: ignore
25
25
 
26
26
  try:
27
- from sqlmodel import Session as SqlaSession # type: ignore # noqa
27
+ from sqlmodel import Session as SqlaSession # type: ignore
28
28
 
29
29
  except ImportError:
30
30
  pass
@@ -0,0 +1,219 @@
1
+ [tool.poetry]
2
+ name = "fastapi-sqla"
3
+ version = "3.3.0"
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
+ deprecated = ">=1.2"
47
+
48
+ alembic = { version = "^1.4.3", optional = true }
49
+ asgi_lifespan = { version = "^1.0.1", optional = true }
50
+ asyncpg = { version = "^0.28.0", optional = true }
51
+ Faker = { version = "^14.2.0", optional = true }
52
+ httpx = { version = "^0.23.0", optional = true }
53
+ pdbpp = { version = "^0.10.2", optional = true }
54
+ psycopg2 = { version = "^2.8.6", optional = true }
55
+ pytest = { version = "^7.2.1", optional = true }
56
+ pytest-asyncio = { version = "^0.19.0", optional = true }
57
+ pytest-cov = { version = "^2.10.1", optional = true }
58
+ ruff = { version = "^0.4.5", optional = true }
59
+ tox = { version = "^3.26.0", optional = true }
60
+ boto3 = { version = "^1.24.74", optional = true }
61
+ greenlet = { version = "^3.0.3", optional = true }
62
+ mypy = { version = "^1.0.0", extras = ["tests"], optional = true }
63
+ sqlmodel = { version = "^0.0.14", optional = true }
64
+
65
+ [tool.poetry.extras]
66
+ # Test dependencies as extras so they can be set as extras in tox config
67
+ # More info on https://github.com/python-poetry/poetry/issues/1941
68
+ tests = [
69
+ "alembic",
70
+ "asgi_lifespan",
71
+ "coverage",
72
+ "Faker",
73
+ "greenlet",
74
+ "httpx",
75
+ "mypy",
76
+ "pdbpp",
77
+ "psycopg2",
78
+ "pytest",
79
+ "pytest-asyncio",
80
+ "pytest-cov",
81
+ "pytest-watch",
82
+ "ruff",
83
+ "tox",
84
+ ]
85
+ asyncpg = ["asyncpg"]
86
+ aws_rds_iam = ["boto3"]
87
+ sqlmodel = ["sqlmodel"]
88
+
89
+ [build-system]
90
+ requires = ["poetry>=1.3.0"]
91
+ build-backend = "poetry.masonry.api"
92
+
93
+ [tool.semantic_release]
94
+ version_toml = ["pyproject.toml:tool.poetry.version"]
95
+ upload_to_pypi = false
96
+ commit_message = "{version}\n\nVersion generated by python-semantic-release [ci skip]"
97
+
98
+ [tool.poetry.plugins."pytest11"]
99
+ fastapi-sqla = "fastapi_sqla._pytest_plugin"
100
+
101
+ [tool.ruff]
102
+ target-version = "py39"
103
+
104
+ [tool.ruff.lint]
105
+ select = [
106
+ "E", # pycodestyle
107
+ "W", # pycodestyle warnings
108
+ "F", # pyflakes
109
+ "I", # isort
110
+ "N", # pep8-naming
111
+ "D", # pydocstyle
112
+ "UP", # pyupgrade
113
+ "ASYNC", # flake8-async
114
+ "S", # flake8-bandit
115
+ "B", # flake8-bugbear
116
+ "C4", # flake8-comprehensions
117
+ "SIM", # flake8-simplify
118
+ "TD", # flake8-todos
119
+ "ERA", # eradicate
120
+ "PL", # pylint
121
+ "RUF", # ruff
122
+ ]
123
+
124
+ # Ignore some pydocstyle rules that Google convention enables
125
+ ignore = [
126
+ "D100",
127
+ "D101",
128
+ "D102",
129
+ "D103",
130
+ "D104",
131
+ "D105",
132
+ "D106",
133
+ "D107",
134
+ "D212",
135
+ "D415",
136
+ "B008", # Enable using functions in default function args. Easier to work with FastAPI dependencies that way
137
+ "C408", # Enable using dict/list/tuple
138
+ "PLR0911", # Disable max number of return
139
+ "PLR0912", # Disable max number of branches
140
+ "PLR0913", # Disable max number of args
141
+ "PLR0915", # Disable max number of statements
142
+ "PLR2004", # Enable magic values
143
+ "SIM105", # Allow using try - except - pass
144
+ "TD001", # Enable FIXMEs
145
+ "TD002", # Enable TODOs without author
146
+ "TD003", # Enable TODOs without issue link
147
+ "N802", # FastAPI dependency conventions is title cased
148
+ "N803", # Same as N802
149
+ "N806", # Same as N802
150
+ ]
151
+
152
+ [tool.ruff.lint.extend-per-file-ignores]
153
+ "tests/*" = [
154
+ "S101", # Enable assert
155
+ "S105", # Disable passwords check
156
+ "S106", # Disable passwords check
157
+ "S608", # Allow SQL string construction
158
+ ]
159
+
160
+ [tool.ruff.lint.pydocstyle]
161
+ convention = "google"
162
+
163
+ [tool.pytest.ini_options]
164
+ asyncio_mode = "auto"
165
+ testpaths = "tests"
166
+ norecursedirs = ".git,.venv"
167
+ xfail_strict = "true"
168
+ addopts = """
169
+ -p no:fastapi-sqla
170
+ --cov-config pyproject.toml
171
+ --cov-report term
172
+ --cov-report term-missing
173
+ """
174
+
175
+ # https://nedbatchelder.com/blog/201810/why_warnings_is_mysterious.html
176
+ filterwarnings = ["error:.*removed in version 2.0.*:"]
177
+
178
+ [tool.pytest-watch.run]
179
+ ext = ".py, .yaml, .cfg"
180
+
181
+ [tool.coverage.run]
182
+ branch = true
183
+ omit = ["tests/*", ".venv/*"]
184
+ concurrency = ["thread", "greenlet"]
185
+
186
+ [tool.coverage.report]
187
+ skip_covered = true
188
+
189
+ [tool.tox]
190
+ legacy_tox_ini = """
191
+ [tox]
192
+ envlist = sqlalchemy{ 1.3, 1.4, 2.0, 2.0-sqlmodel }-{ asyncpg, noasyncpg }-{aws_rds_iam, noaws_rds_iam }-pydantic{ 1, 2 }
193
+
194
+ [testenv]
195
+ passenv = CI
196
+ deps =
197
+ sqlalchemy1.3: sqlalchemy<1.4
198
+ sqlalchemy1.4: sqlalchemy>=1.4,<2
199
+ sqlalchemy2.0: sqlalchemy>=2
200
+ sqlalchemy2.0-sqlmodel: sqlalchemy>=2
201
+ sqlalchemy2.0-sqlmodel: sqlmodel
202
+ asyncpg: asyncpg
203
+ aws_rds_iam: boto3
204
+ pydantic1: pydantic<2
205
+ pydantic2: pydantic>=2
206
+
207
+ extras =
208
+ tests
209
+
210
+ commands = pytest -vv --cov={envsitepackagesdir}/fastapi_sqla --cov-report xml --cov-report html --junitxml=test-reports/pytest/junit.xml
211
+ """
212
+
213
+ [tool.mypy]
214
+ exclude = ["tests"]
215
+ plugins = ["sqlalchemy.ext.mypy.plugin"]
216
+
217
+ [[tool.mypy.overrides]]
218
+ module = ["asyncpg", "boto3", "deprecated"]
219
+ ignore_missing_imports = true
@@ -1,132 +0,0 @@
1
- [tool]
2
- [tool.poetry]
3
- name = "fastapi-sqla"
4
- version = "3.1.2"
5
- description = "SQLAlchemy extension for FastAPI with support for pagination, asyncio, SQLModel, and pytest, ready for production."
6
- authors = ["Hadrien David <hadrien.david@dialogue.co>", "Victor Repkow <victor.repkow@dialogue.co>"]
7
- license = "MIT"
8
- readme = "README.md"
9
- repository = "https://github.com/dialoguemd/fastapi-sqla"
10
- keywords = ["FastAPI", "SQLAlchemy", "asyncio", "pytest", "alembic"]
11
- classifiers = ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: AsyncIO", "Framework :: FastAPI", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.9", "Programming Language :: Python", "Programming Language :: SQL", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Libraries", "Topic :: Software Development", "Typing :: Typed"]
12
- [tool.poetry.dependencies]
13
- python = "^3.9"
14
- fastapi = ">=0.95.1"
15
- pydantic = ">=1"
16
- sqlalchemy = ">=1.3"
17
- structlog = ">=20"
18
- [tool.poetry.dependencies.alembic]
19
- version = "^1.4.3"
20
- optional = true
21
- [tool.poetry.dependencies.asgi_lifespan]
22
- version = "^1.0.1"
23
- optional = true
24
- [tool.poetry.dependencies.asyncpg]
25
- version = "^0.28.0"
26
- optional = true
27
- [tool.poetry.dependencies.black]
28
- version = "^22.8.0"
29
- optional = true
30
- [tool.poetry.dependencies.Faker]
31
- version = "^14.2.0"
32
- optional = true
33
- [tool.poetry.dependencies.httpx]
34
- version = "^0.23.0"
35
- optional = true
36
- [tool.poetry.dependencies.isort]
37
- version = "^5.5.3"
38
- optional = true
39
- [tool.poetry.dependencies.pdbpp]
40
- version = "^0.10.2"
41
- optional = true
42
- [tool.poetry.dependencies.psycopg2]
43
- version = "^2.8.6"
44
- optional = true
45
- [tool.poetry.dependencies.pylama]
46
- version = "^8.4.1"
47
- optional = true
48
- [tool.poetry.dependencies.pytest]
49
- version = "^7.2.1"
50
- optional = true
51
- [tool.poetry.dependencies.pytest-asyncio]
52
- version = "^0.19.0"
53
- optional = true
54
- [tool.poetry.dependencies.pytest-cov]
55
- version = "^2.10.1"
56
- optional = true
57
- [tool.poetry.dependencies.tox]
58
- version = "^3.26.0"
59
- optional = true
60
- [tool.poetry.dependencies.boto3]
61
- version = "^1.24.74"
62
- optional = true
63
- [tool.poetry.dependencies.greenlet]
64
- version = "^1.1.3"
65
- optional = true
66
- [tool.poetry.dependencies.mypy]
67
- version = "^1.0.0"
68
- extras = ["tests"]
69
- optional = true
70
- [tool.poetry.dependencies.sqlmodel]
71
- version = "^0.0.14"
72
- optional = true
73
- [tool.poetry.extras]
74
- tests = ["alembic", "asgi_lifespan", "black", "coverage", "Faker", "greenlet", "httpx", "isort", "mypy", "pdbpp", "psycopg2", "pylama", "pytest", "pytest-asyncio", "pytest-cov", "pytest-watch", "tox"]
75
- asyncpg = ["asyncpg"]
76
- aws_rds_iam = ["boto3"]
77
- sqlmodel = ["sqlmodel"]
78
- [tool.poetry.plugins]
79
- [tool.poetry.plugins.pytest11]
80
- fastapi-sqla = "fastapi_sqla._pytest_plugin"
81
-
82
- [[tool.poetry.source]]
83
- name = "dialogue-private"
84
- url = "https://dialogue-527641002329.d.codeartifact.us-east-1.amazonaws.com/pypi/distribution-readonly/simple/"
85
- default = true
86
- [tool.semantic_release]
87
- version_variable = "pyproject.toml:version"
88
- upload_to_pypi = false
89
- commit_message = "Version generated by python-semantic-release [ci skip]"
90
- [tool.pylama]
91
- paths = "fastapi_sqla tests"
92
- linters = "pycodestyle,mccabe,pyflakes"
93
- [tool.pylama.linter]
94
- [tool.pylama.linter.pycodestyle]
95
- max_line_length = 88
96
- [tool.isort]
97
- profile = "black"
98
- lines_between_sections = 1
99
- multi_line_output = 3
100
- include_trailing_comma = "True"
101
- line_length = 88
102
- [tool.pytest]
103
- [tool.pytest.ini_options]
104
- asyncio_mode = "auto"
105
- testpaths = "tests"
106
- norecursedirs = ".git,.venv"
107
- xfail_strict = "true"
108
- addopts = " -p no:fastapi-sqla\n --cov-config pyproject.toml\n --cov-report term\n --cov-report term-missing\n"
109
- filterwarnings = ["error:.*removed in version 2.0.*:"]
110
- [tool.pytest-watch]
111
- [tool.pytest-watch.run]
112
- ext = ".py, .yaml, .cfg"
113
- [tool.coverage]
114
- [tool.coverage.run]
115
- branch = true
116
- omit = ["tests/*", ".venv/*"]
117
- concurrency = ["thread", "greenlet"]
118
- [tool.coverage.report]
119
- skip_covered = true
120
- [tool.tox]
121
- legacy_tox_ini = "[tox]\nenvlist = sqlalchemy{ 1.3, 1.4, 2.0, 2.0-sqlmodel }-{ asyncpg, noasyncpg }-{aws_rds_iam, noaws_rds_iam }-pydantic{ 1, 2 }\n\n[testenv]\npassenv = CI\ndeps =\n sqlalchemy1.3: sqlalchemy<1.4\n sqlalchemy1.4: sqlalchemy>=1.4,<2\n sqlalchemy2.0: sqlalchemy>=2\n sqlalchemy2.0-sqlmodel: sqlalchemy>=2\n sqlalchemy2.0-sqlmodel: sqlmodel\n asyncpg: asyncpg\n aws_rds_iam: boto3\n pydantic1: pydantic<2\n pydantic2: pydantic>=2\n\nextras =\n tests\n\ncommands = pytest -vv --cov={envsitepackagesdir}/fastapi_sqla --cov-report xml --cov-report html --junitxml=test-reports/pytest/junit.xml\n"
122
- [tool.black]
123
- exclude = ".mypy_cache|.pytest_cache|.vscode|.eggs|venv"
124
- --skip-magic-trailing-comma = true
125
- [tool.mypy]
126
- exclude = ["tests"]
127
- ignore_missing_imports = true
128
- plugins = "sqlalchemy.ext.mypy.plugin"
129
-
130
- [build-system]
131
- requires = ["poetry>=1.3.0"]
132
- build-backend = "poetry.masonry.api"
File without changes