From af9b4ef6c76c5b2ca2d8f91e88e5c34523172b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Tue, 11 Jun 2024 01:40:54 +0300 Subject: [PATCH] Updated code to work with the latest changes in the core --- .pre-commit-config.yaml | 6 +++--- docs/configuration.rst | 3 +-- docs/usage.rst | 25 ++++--------------------- examples/csvimport.py | 2 +- examples/csvimport_orm.py | 2 +- tests/test_testing_recipe.py | 34 +++++++++++++++++----------------- 6 files changed, 27 insertions(+), 45 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 337227b..15c6963 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ # * Run "pre-commit install". repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-toml - id: check-yaml @@ -16,14 +16,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.4 + rev: v0.4.8 hooks: - id: ruff args: [--fix, --show-fixes] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.9.0 + rev: v1.10.0 hooks: - id: mypy additional_dependencies: diff --git a/docs/configuration.rst b/docs/configuration.rst index 3773a02..181079a 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -63,8 +63,7 @@ of the ``sqlalchemy`` component:: sqlalchemy: resource_name: db1 url: postgresql+asyncpg:///mydatabase - sqlalchemy2: - type: sqlalchemy + sqlalchemy/db2: resource_name: db2 url: sqlite+aiosqlite:///mydb.sqlite diff --git a/docs/usage.rst b/docs/usage.rst index 0e2638c..a28a304 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -51,26 +51,10 @@ wrapped in worker threads. Another thing to watch out for is lazy loading of relationships and deferred columns which triggers implicit queries when those attributes are accessed. -On Python 3.9 and above, you would do:: - - from asyncio import to_thread - - from asphalt.core import inject, resource - from sqlalchemy.orm import Session - from sqlalchemy.future import select - - from yourapp.model import Person - - - @inject - async def handler(*, dbsession: Session = resource()) -> None: - people = await to_thread(dbsession.scalars, select(Person)) - - -On earlier Python versions:: - - from asyncio import get_running_loop +Here's an example of how you could use worker threads to run a blocking database +operation:: + from anyio import to_thread from asphalt.core import inject, resource from sqlalchemy.orm import Session from sqlalchemy.future import select @@ -80,8 +64,7 @@ On earlier Python versions:: @inject async def handler(*, dbsession: Session = resource()) -> None: - loop = get_running_loop() - people = await loop.run_in_executor(None, dbsession.scalars, select(Person)) + people = await to_thread.run_sync(dbsession.scalars, select(Person)) Releasing database resources during a long operation ---------------------------------------------------- diff --git a/examples/csvimport.py b/examples/csvimport.py index cd2bc08..e3c15f6 100644 --- a/examples/csvimport.py +++ b/examples/csvimport.py @@ -71,4 +71,4 @@ def insert_rows_in_thread() -> int: logger.info("Imported %d rows of data", inserted_rows) -run_application(CSVImporterComponent()) +run_application(CSVImporterComponent) diff --git a/examples/csvimport_orm.py b/examples/csvimport_orm.py index 7d8216b..79e753e 100644 --- a/examples/csvimport_orm.py +++ b/examples/csvimport_orm.py @@ -76,4 +76,4 @@ def insert_rows_in_thread() -> int: logger.info("Imported %d rows of data", inserted_rows) -run_application(CSVImporterComponent()) +run_application(CSVImporterComponent) diff --git a/tests/test_testing_recipe.py b/tests/test_testing_recipe.py index 1dbb912..8acf1e1 100644 --- a/tests/test_testing_recipe.py +++ b/tests/test_testing_recipe.py @@ -9,7 +9,7 @@ from typing import Any import pytest -from asphalt.core import ContainerComponent, Context, get_resource_nowait +from asphalt.core import Component, Context, get_resource_nowait, start_component from sqlalchemy.engine import Connection, Engine from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, AsyncSession @@ -49,8 +49,8 @@ def person(self, connection: Connection) -> Person: return person @pytest.fixture - def root_component(self, connection: Connection) -> ContainerComponent: - return ContainerComponent({"sqlalchemy": {"bind": connection}}) + def component_config(self, connection: Connection) -> dict[str, Any]: + return {"components": {"sqlalchemy": {"bind": connection}}} @pytest.fixture def dbsession(self, connection: Connection) -> Generator[Session, Any, None]: @@ -59,11 +59,11 @@ def dbsession(self, connection: Connection) -> Generator[Session, Any, None]: yield session async def test_rollback( - self, dbsession: Session, root_component: ContainerComponent + self, dbsession: Session, component_config: dict[str, Any] ) -> None: # Simulate a rollback happening in a subcontext async with Context(): - await root_component.start() + await start_component(Component, component_config) async with Context(): session = get_resource_nowait(Session) try: @@ -81,11 +81,11 @@ async def test_rollback( assert dbsession.scalar(func.count(Person.id)) == 2 async def test_add_person( - self, dbsession: Session, root_component: ContainerComponent + self, dbsession: Session, component_config: dict[str, Any] ) -> None: # Simulate adding a row to the "people" table in the application async with Context(): - await root_component.start() + await start_component(Component, component_config) async with Context(): session = get_resource_nowait(Session) session.add(Person(name="Another person")) @@ -94,11 +94,11 @@ async def test_add_person( assert dbsession.scalar(func.count(Person.id)) == 2 async def test_delete_person( - self, dbsession: Session, root_component: ContainerComponent + self, dbsession: Session, component_config: dict[str, Any] ) -> None: # Simulate removing the test person in the application async with Context(): - await root_component.start() + await start_component(Component, component_config) async with Context(): session = get_resource_nowait(Session) session.execute(delete(Person)) @@ -135,8 +135,8 @@ async def person(self, connection: AsyncConnection) -> Person: return person @pytest.fixture - def root_component(self, connection: AsyncConnection) -> ContainerComponent: - return ContainerComponent({"sqlalchemy": {"bind": connection}}) + def component_config(self, connection: Connection) -> dict[str, Any]: + return {"components": {"sqlalchemy": {"bind": connection}}} @pytest.fixture async def dbsession( @@ -147,11 +147,11 @@ async def dbsession( yield session async def test_rollback( - self, dbsession: AsyncSession, root_component: ContainerComponent + self, dbsession: AsyncSession, component_config: dict[str, Any] ) -> None: # Simulate a rollback happening in a subcontext async with Context(): - await root_component.start() + await start_component(Component, component_config) async with Context(): session = get_resource_nowait(AsyncSession) try: @@ -169,11 +169,11 @@ async def test_rollback( assert await dbsession.scalar(func.count(Person.id)) == 2 async def test_add_person( - self, dbsession: AsyncSession, root_component: ContainerComponent + self, dbsession: AsyncSession, component_config: dict[str, Any] ) -> None: # Simulate adding a row to the "people" table in the application async with Context(): - await root_component.start() + await start_component(Component, component_config) async with Context(): session = get_resource_nowait(AsyncSession) session.add(Person(name="Another person")) @@ -182,11 +182,11 @@ async def test_add_person( assert await dbsession.scalar(select(func.count(Person.id))) == 2 async def test_delete_person( - self, dbsession: AsyncSession, root_component: ContainerComponent + self, dbsession: AsyncSession, component_config: dict[str, Any] ) -> None: # Simulate removing the test person in the application async with Context(): - await root_component.start() + await start_component(Component, component_config) async with Context(): session = get_resource_nowait(AsyncSession) await session.execute(delete(Person))