Skip to content

Commit 35f280a

Browse files
committed
Merge branch 'release/4.17.0' into master
2 parents a1f779a + 2c1eb9f commit 35f280a

File tree

22 files changed

+615
-2
lines changed

22 files changed

+615
-2
lines changed

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ Choose one of the following:
161161
- `Sanic example <https://python-dependency-injector.ets-labs.org/examples/sanic.html>`_
162162
- `FastAPI example <https://python-dependency-injector.ets-labs.org/examples/fastapi.html>`_
163163
- `FastAPI + Redis example <https://python-dependency-injector.ets-labs.org/examples/fastapi-redis.html>`_
164+
- `FastAPI + SQLAlchemy example <https://python-dependency-injector.ets-labs.org/examples/fastapi-sqlalchemy.html>`_
164165

165166
Tutorials
166167
---------

docs/examples/fastapi-sqlalchemy.rst

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
.. _fastapi-sqlalchemy-example:
2+
3+
FastAPI + SQLAlchemy example
4+
============================
5+
6+
.. meta::
7+
:keywords: Python,Dependency Injection,FastAPI,SQLAlchemy,Example
8+
:description: This example demonstrates a usage of the FastAPI, SQLAlchemy, and Dependency Injector.
9+
10+
This example shows how to use ``Dependency Injector`` with `FastAPI <https://fastapi.tiangolo.com/>`_ and
11+
`SQLAlchemy <https://www.sqlalchemy.org/>`_.
12+
13+
The source code is available on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/fastapi-sqlalchemy>`_.
14+
15+
Thanks to `@ShvetsovYura <https://github.com/ShvetsovYura>`_ for providing initial example:
16+
`FastAPI_DI_SqlAlchemy <https://github.com/ShvetsovYura/FastAPI_DI_SqlAlchemy>`_.
17+
18+
Application structure
19+
---------------------
20+
21+
Application has next structure:
22+
23+
.. code-block:: bash
24+
25+
./
26+
├── webapp/
27+
│ ├── __init__.py
28+
│ ├── application.py
29+
│ ├── containers.py
30+
│ ├── database.py
31+
│ ├── endpoints.py
32+
│ ├── models.py
33+
│ ├── repositories.py
34+
│ ├── services.py
35+
│ └── tests.py
36+
├── config.yml
37+
├── docker-compose.yml
38+
├── Dockerfile
39+
└── requirements.txt
40+
41+
Application factory
42+
-------------------
43+
44+
Application factory creates container, wires it with the ``endpoints`` module, creates
45+
``FastAPI`` app, and setup routes.
46+
47+
Application factory also creates database if it does not exist.
48+
49+
Listing of ``webapp/application.py``:
50+
51+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/application.py
52+
:language: python
53+
54+
Endpoints
55+
---------
56+
57+
Module ``endpoints`` contains example endpoints. Endpoints have a dependency on user service.
58+
User service is injected using :ref:`wiring` feature. See ``webapp/endpoints.py``:
59+
60+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/endpoints.py
61+
:language: python
62+
63+
Container
64+
---------
65+
66+
Declarative container wires example user service, user repository, and utility database class.
67+
See ``webapp/containers.py``:
68+
69+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/containers.py
70+
:language: python
71+
72+
Services
73+
--------
74+
75+
Module ``services`` contains example user service. See ``webapp/services.py``:
76+
77+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/services.py
78+
:language: python
79+
80+
Repositories
81+
------------
82+
83+
Module ``repositories`` contains example user repository. See ``webapp/repositories.py``:
84+
85+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/repositories.py
86+
:language: python
87+
88+
Models
89+
------
90+
91+
Module ``models`` contains example SQLAlchemy user model. See ``webapp/models.py``:
92+
93+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/models.py
94+
:language: python
95+
96+
Database
97+
-----
98+
99+
Module ``database`` defines declarative base and utility class with engine and session factory.
100+
See ``webapp/database.py``:
101+
102+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/database.py
103+
:language: python
104+
105+
Tests
106+
-----
107+
108+
Tests use :ref:`provider-overriding` feature to replace repository with a mock. See ``webapp/tests.py``:
109+
110+
.. literalinclude:: ../../examples/miniapps/fastapi-sqlalchemy/webapp/tests.py
111+
:language: python
112+
:emphasize-lines: 25, 45, 58, 74, 86, 97
113+
114+
Sources
115+
-------
116+
117+
The source code is available on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/fastapi-sqlalchemy>`_.
118+
119+
.. disqus::

docs/examples/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ Explore the examples to see the ``Dependency Injector`` in action.
2020
sanic
2121
fastapi
2222
fastapi-redis
23+
fastapi-sqlalchemy
2324

2425
.. disqus::

docs/introduction/di_in_python.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ Choose one of the following as a next step:
288288
- :ref:`sanic-example`
289289
- :ref:`fastapi-example`
290290
- :ref:`fastapi-redis-example`
291+
- :ref:`fastapi-sqlalchemy-example`
291292
- Pass the tutorials:
292293
- :ref:`flask-tutorial`
293294
- :ref:`aiohttp-tutorial`

docs/main/changelog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ that were made in every particular version.
77
From version 0.7.6 *Dependency Injector* framework strictly
88
follows `Semantic versioning`_
99

10+
4.17.0
11+
------
12+
- Add ``FastAPI`` + ``SQLAlchemy`` example.
13+
Thanks to `@ShvetsovYura <https://github.com/ShvetsovYura>`_ for providing initial example:
14+
`FastAPI_DI_SqlAlchemy <https://github.com/ShvetsovYura/FastAPI_DI_SqlAlchemy>`_.
15+
1016
4.16.0
1117
------
1218
- Add container base class ``containers.Container``. ``DynamicContainer``

docs/wiring.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,5 +336,6 @@ Take a look at other application examples:
336336
- :ref:`sanic-example`
337337
- :ref:`fastapi-example`
338338
- :ref:`fastapi-redis-example`
339+
- :ref:`fastapi-sqlalchemy-example`
339340

340341
.. disqus::
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM python:3.9-buster
2+
3+
ENV PYTHONUNBUFFERED=1
4+
ENV HOST=0.0.0.0
5+
ENV PORT=8000
6+
7+
WORKDIR /code
8+
COPY . /code/
9+
10+
RUN pip install --upgrade pip \
11+
&& pip install -r requirements.txt
12+
13+
CMD uvicorn webapp.application:app --host ${HOST} --port ${PORT}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
FastAPI + SQLAlchemy + Dependency Injector Example
2+
==================================================
3+
4+
This is a `FastAPI <https://fastapi.tiangolo.com/>`_ +
5+
`SQLAlchemy <https://www.sqlalchemy.org/>`_ +
6+
`Dependency Injector <https://python-dependency-injector.ets-labs.org/>`_ example application.
7+
8+
Thanks to `@ShvetsovYura <https://github.com/ShvetsovYura>`_ for providing initial example:
9+
`FastAPI_DI_SqlAlchemy <https://github.com/ShvetsovYura/FastAPI_DI_SqlAlchemy>`_.
10+
11+
Run
12+
---
13+
14+
Build the Docker image:
15+
16+
.. code-block:: bash
17+
18+
docker-compose build
19+
20+
Run the docker-compose environment:
21+
22+
.. code-block:: bash
23+
24+
docker-compose up
25+
26+
The output should be something like:
27+
28+
.. code-block::
29+
30+
Starting fastapi-sqlalchemy_webapp_1 ... done
31+
Attaching to fastapi-sqlalchemy_webapp_1
32+
webapp_1 | 2021-02-04 22:07:19,804 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
33+
webapp_1 | 2021-02-04 22:07:19,804 INFO sqlalchemy.engine.base.Engine ()
34+
webapp_1 | 2021-02-04 22:07:19,804 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
35+
webapp_1 | 2021-02-04 22:07:19,804 INFO sqlalchemy.engine.base.Engine ()
36+
webapp_1 | 2021-02-04 22:07:19,805 INFO sqlalchemy.engine.base.Engine PRAGMA main.table_info("users")
37+
webapp_1 | 2021-02-04 22:07:19,805 INFO sqlalchemy.engine.base.Engine ()
38+
webapp_1 | 2021-02-04 22:07:19,808 INFO sqlalchemy.engine.base.Engine PRAGMA temp.table_info("users")
39+
webapp_1 | 2021-02-04 22:07:19,808 INFO sqlalchemy.engine.base.Engine ()
40+
webapp_1 | 2021-02-04 22:07:19,809 INFO sqlalchemy.engine.base.Engine
41+
webapp_1 | CREATE TABLE users (
42+
webapp_1 | id INTEGER NOT NULL,
43+
webapp_1 | email VARCHAR,
44+
webapp_1 | hashed_password VARCHAR,
45+
webapp_1 | is_active BOOLEAN,
46+
webapp_1 | PRIMARY KEY (id),
47+
webapp_1 | UNIQUE (email),
48+
webapp_1 | CHECK (is_active IN (0, 1))
49+
webapp_1 | )
50+
webapp_1 |
51+
webapp_1 |
52+
webapp_1 | 2021-02-04 22:07:19,810 INFO sqlalchemy.engine.base.Engine ()
53+
webapp_1 | 2021-02-04 22:07:19,821 INFO sqlalchemy.engine.base.Engine COMMIT
54+
webapp_1 | INFO: Started server process [8]
55+
webapp_1 | INFO: Waiting for application startup.
56+
webapp_1 | INFO: Application startup complete.
57+
webapp_1 | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
58+
59+
After that visit http://127.0.0.1:8000/docs in your browser.
60+
61+
Test
62+
----
63+
64+
This application comes with the unit tests.
65+
66+
To run the tests do:
67+
68+
.. code-block:: bash
69+
70+
docker-compose run --rm webapp py.test webapp/tests.py --cov=webapp
71+
72+
The output should be something like:
73+
74+
.. code-block::
75+
76+
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
77+
rootdir: /code
78+
plugins: cov-2.11.1
79+
collected 7 items
80+
81+
webapp/tests.py ....... [100%]
82+
83+
----------- coverage: platform linux, python 3.9.1-final-0 -----------
84+
Name Stmts Miss Cover
85+
--------------------------------------------
86+
webapp/__init__.py 0 0 100%
87+
webapp/application.py 14 0 100%
88+
webapp/containers.py 9 0 100%
89+
webapp/database.py 24 8 67%
90+
webapp/endpoints.py 32 0 100%
91+
webapp/models.py 10 1 90%
92+
webapp/repositories.py 36 20 44%
93+
webapp/services.py 16 0 100%
94+
webapp/tests.py 59 0 100%
95+
--------------------------------------------
96+
TOTAL 200 29 86%
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
db:
2+
url: "sqlite:///./webapp.db"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: "3.7"
2+
3+
services:
4+
5+
webapp:
6+
build: ./
7+
image: webapp
8+
ports:
9+
- "8000:8000"
10+
volumes:
11+
- "./:/code"

0 commit comments

Comments
 (0)