You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/index.md
+54-53Lines changed: 54 additions & 53 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -79,16 +79,18 @@ This section will show the endpoints created for later tests. For this example,
79
79
In the database, besides the `id` field, the ticket table has: a `price` field, a boolean field `is_sold` to identify if it's sold or not, and a `sold_to` field to identify who the ticket was sold to. The `models.py` file contains this information, using the [`SQLAlchemy`](https://www.sqlalchemy.org/){:target="\_blank"} ORM.
80
80
81
81
```py title="src/models.py" linenums="1"
82
-
from sqlalchemy.orm import Mapped, mapped_column, registry
82
+
from sqlalchemy.ext.asyncio import AsyncAttrs
83
+
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
The `database.py` contains the database connection, as well as the `get_session()` generator, responsible for creating asynchronous sessions to perform transactions in the database.
@@ -155,7 +157,7 @@ The previous three files are imported in `app.py`, which contains the API routes
155
157
156
158
To keep things simple and avoid database migrations, the database creation is handled using [lifespan events](https://fastapi.tiangolo.com/advanced/events/){:target="\_blank"}. This guarantees that every time we run the application, a database will be created if it doesn't already exist.
status_code=HTTPStatus.NOT_FOUND, detail='Ticket was not found'
228
-
)
227
+
ifnot ticket_db:
228
+
raise HTTPException(
229
+
status_code=HTTPStatus.NOT_FOUND, detail='Ticket was not found'
230
+
)
229
231
230
-
asyncwith session.begin():
231
232
stm = (
232
233
update(Ticket)
233
234
.where(
@@ -303,8 +304,9 @@ The `postgres_container` will be passed to `async_session`, which will be used i
303
304
304
305
The first fixture inserted in `conftest.py` is the `anyio_backend`, highlighted in the code below. This function will be used in `postgres_container` and marked for the AnyIO pytest plugin, as well as setting `asyncio` as the backend to run the tests. This function was not included in the previous diagram because it is an AnyIO specification. You can check more details about it [here](https://anyio.readthedocs.io/en/stable/testing.html#specifying-the-backends-to-run-on).
from collections.abc import AsyncGenerator, Generator
309
+
from typing import Literal
308
310
309
311
import pytest
310
312
from httpx import ASGITransport, AsyncClient
@@ -317,47 +319,45 @@ from testcontainers.postgres import PostgresContainer
317
319
318
320
from src.app import app
319
321
from src.database import get_session
320
-
from src.models importtable_register
322
+
from src.models importBase
321
323
322
324
323
325
@pytest.fixture
324
-
defanyio_backend() -> str:
326
+
defanyio_backend() -> Literal['asyncio']:
325
327
return'asyncio'
326
-
327
328
```
328
329
329
330
Now, in the `postgres_container`, the `anyio_backend` is passed, and all the tests that use the `postgres_container` as a fixture at any level will be marked to run asynchronously.
330
331
331
332
Below is the `postgres_container` function, which will be responsible for creating the `PostgresContainer` instance from `testcontainers`. The `asyncpg` driver is passed as an argument to specify that it will be the driver used.
with PostgresContainer('postgres:16', driver='asyncpg') as postgres:
339
340
yield postgres
340
341
```
341
342
342
343
The `async_session` takes the connection URL from the `PostgresContainer` object returned by the `postgres_container` function and uses it to create the tables inside the database, as well as the session that will handle all interactions with the PostgreSQL instance created. The function will return and persist a session to be used, and then restore the database for the next test by deleting the tables.
@@ -492,16 +492,16 @@ Fixtures are created when first requested by a test and are destroyed based on t
492
492
493
493
As we want to create just one Docker instance and reuse it for all the tests, we changed the `@pytest.fixture` in the `conftest.py` file in the following highlighted lines.
0 commit comments