Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .flake8

This file was deleted.

71 changes: 26 additions & 45 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
build: [linux_3.9, windows_3.9, mac_3.9]
build: [linux_3.12, windows_3.12, mac_3.12]
include:
- build: linux_3.9
- build: linux_3.12
os: ubuntu-latest
python: 3.9
- build: windows_3.9
python: 3.12
- build: windows_3.12
os: windows-latest
python: 3.9
- build: mac_3.9
python: 3.12
- build: mac_3.12
os: macos-latest
python: 3.9
python: 3.12
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

Expand All @@ -38,59 +38,40 @@ jobs:
python -m pip install --upgrade pip wheel
pip install -r requirements.txt

# test all the builds apart from linux_3.8...
# test all the builds apart from linux_3.12...
- name: Test with pytest
if: matrix.build != 'linux_3.9'
if: matrix.build != 'linux_3.12'
run: pytest

# only do the test coverage for linux_3.8
# only do the test coverage for linux_3.12
- name: Produce coverage report
if: matrix.build == 'linux_3.9'
if: matrix.build == 'linux_3.12'
run: pytest --cov=fastapi_async_sqlalchemy --cov-report=xml

- name: Upload coverage report
if: matrix.build == 'linux_3.9'
uses: codecov/codecov-action@v1
if: matrix.build == 'linux_3.12'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}

lint:
name: lint
ruff:
name: ruff
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.9
python-version: 3.12

- name: Install dependencies
run: pip install flake8
run: pip install ruff

- name: Run flake8
run: flake8 --count .
- name: Run ruff linter
run: ruff check .

format:
name: format
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.9

- name: Install dependencies
# isort needs all of the packages to be installed so it can
# tell which are third party and which are first party
run: pip install -r requirements.txt

- name: Check formatting of imports
run: isort --check-only --diff --verbose

- name: Check formatting of code
run: black . --check --diff
- name: Run ruff formatter
run: ruff format --check .
8 changes: 4 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -54,7 +54,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v3

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -68,4 +68,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v3
4 changes: 2 additions & 2 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
Expand Down
43 changes: 10 additions & 33 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,47 +1,24 @@
exclude: (alembic|build|dist|docker|esign|kubernetes|migrations)

default_language_version:
python: python3.8
python: python3.12

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v5.0.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v2.28.0
hooks:
- id: pyupgrade
args:
- --py37-plus
- repo: https://github.com/myint/autoflake
rev: v1.4
hooks:
- id: autoflake
args:
- --in-place
- --remove-all-unused-imports
- --expand-star-imports
- --remove-duplicate-keys
- --remove-unused-variables
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.4
hooks:
- id: flake8
args:
- --max-line-length=100
- --ignore=E203, E501, W503
- id: ruff
args: [--fix, --unsafe-fixes]
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.982
rev: v1.17.0
hooks:
- id: mypy
additional_dependencies:
Expand Down
4 changes: 2 additions & 2 deletions fastapi_async_sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from fastapi_async_sqlalchemy.middleware import (
SQLAlchemyMiddleware,
db,
create_middleware_and_session_proxy,
db,
)

__all__ = ["db", "SQLAlchemyMiddleware", "create_middleware_and_session_proxy"]

__version__ = "0.7.0.dev4"
__version__ = "0.7.0.dev5"
39 changes: 27 additions & 12 deletions fastapi_async_sqlalchemy/middleware.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
import asyncio
from contextvars import ContextVar
from typing import Dict, Optional, Union
from typing import Dict, Optional, Type, Union

from sqlalchemy.engine import Engine
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.requests import Request
from starlette.types import ASGIApp

from fastapi_async_sqlalchemy.exceptions import MissingSessionError, SessionNotInitialisedError
from fastapi_async_sqlalchemy.exceptions import (
MissingSessionError,
SessionNotInitialisedError,
)

try:
from sqlalchemy.ext.asyncio import async_sessionmaker # noqa: F811
from sqlalchemy.ext.asyncio import async_sessionmaker
except ImportError:
from sqlalchemy.orm import sessionmaker as async_sessionmaker
from sqlalchemy.orm import sessionmaker as async_sessionmaker # type: ignore

# Try to import SQLModel's AsyncSession which has the .exec() method
try:
from sqlmodel.ext.asyncio.session import AsyncSession as SQLModelAsyncSession

DefaultAsyncSession: Type[AsyncSession] = SQLModelAsyncSession # type: ignore
except ImportError:
DefaultAsyncSession: Type[AsyncSession] = AsyncSession # type: ignore


def create_middleware_and_session_proxy():
def create_middleware_and_session_proxy() -> tuple:
_Session: Optional[async_sessionmaker] = None
_session: ContextVar[Optional[AsyncSession]] = ContextVar("_session", default=None)
_multi_sessions_ctx: ContextVar[bool] = ContextVar("_multi_sessions_context", default=False)
Expand All @@ -31,9 +41,9 @@ def __init__(
self,
app: ASGIApp,
db_url: Optional[Union[str, URL]] = None,
custom_engine: Optional[Engine] = None,
engine_args: Dict = None,
session_args: Dict = None,
custom_engine: Optional[AsyncEngine] = None,
engine_args: Optional[Dict] = None,
session_args: Optional[Dict] = None,
commit_on_exit: bool = False,
):
super().__init__(app)
Expand All @@ -44,13 +54,18 @@ def __init__(
if not custom_engine and not db_url:
raise ValueError("You need to pass a db_url or a custom_engine parameter.")
if not custom_engine:
if db_url is None:
raise ValueError("db_url cannot be None when custom_engine is not provided")
engine = create_async_engine(db_url, **engine_args)
else:
engine = custom_engine

nonlocal _Session
_Session = async_sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False, **session_args
engine,
class_=DefaultAsyncSession,
expire_on_commit=False,
**session_args,
)

async def dispatch(self, request: Request, call_next: RequestResponseEndpoint):
Expand Down Expand Up @@ -115,7 +130,7 @@ async def cleanup():
class DBSession(metaclass=DBSessionMeta):
def __init__(
self,
session_args: Dict = None,
session_args: Optional[Dict] = None,
commit_on_exit: bool = False,
multi_sessions: bool = False,
):
Expand Down
48 changes: 31 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
[tool.black]
[tool.ruff]
line-length = 100
target-version = ['py37']
include = '\.pyi?$'
exclude = '''
(
| .git
| .venv
| build
| dist
)
'''
target-version = "py37"
exclude = [
".git",
".venv",
"build",
"dist",
]

[tool.isort]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
line_length = 100
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
]
ignore = [
"E203", # whitespace before ':'
]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

[tool.ruff.lint.isort]
combine-as-imports = true
split-on-trailing-comma = true
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fastapi==0.90.0 # pyup: ignore
flake8==3.7.9
idna==3.7
importlib-metadata==1.5.0
isort==4.3.21
isort==5.13.2
mccabe==0.6.1
more-itertools==7.2.0
packaging>=22.0
Expand All @@ -25,9 +25,10 @@ pytest-cov==2.11.1
PyYAML>=5.4
regex>=2020.2.20
requests>=2.22.0
httpx>=0.20.0
httpx>=0.20.0,<0.28.0
six==1.12.0
SQLAlchemy>=1.4.19
sqlmodel>=0.0.24
asyncpg>=0.27.0
aiosqlite==0.20.0
sqlparse==0.5.1
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest
from fastapi import FastAPI
from starlette.testclient import TestClient
from fastapi.testclient import TestClient


@pytest.fixture
Expand Down
Loading
Loading