11# FastSQLA
22
3- _ Async SQLAlchemy for FastAPI — boilerplate, pagination, and seamless session management._
3+ _ Async SQLAlchemy 2 for FastAPI — boilerplate, pagination, and seamless session management._
44
55[ ![ PyPI - Version] ( https://img.shields.io/pypi/v/FastSQLA?color=brightgreen )] ( https://pypi.org/project/FastSQLA/ )
66[ ![ GitHub Actions Workflow Status] ( https://img.shields.io/github/actions/workflow/status/hadrien/fastsqla/ci.yml?branch=main&logo=github&label=CI )] ( https://github.com/hadrien/FastSQLA/actions?query=branch%3Amain+event%3Apush )
@@ -17,88 +17,82 @@ following [`SQLAlchemy`'s best practices](https://docs.sqlalchemy.org/en/20/orm/
1717
1818## Features
1919
20- < details >
21- <summary>Automatic SQLAlchemy configuration at app startup.</summary>
20+ * Automatic SQLAlchemy setup at app startup using
21+ [ ` FastAPI ` Lifespan ] ( https://fastapi.tiangolo.com/advanced/events/#lifespan ) :
2222
23- Using [ ` FastAPI ` Lifespan] ( https://fastapi.tiangolo.com/advanced/events/#lifespan ) :
24- ``` python
25- from fastapi import FastAPI
26- from fastsqla import lifespan
23+ ``` python
24+ from fastapi import FastAPI
25+ from fastsqla import lifespan
2726
28- app = FastAPI(lifespan = lifespan)
29- ```
30- </details >
31- <details >
32- <summary>Async SQLAlchemy session as a FastAPI dependency.</summary>
27+ app = FastAPI(lifespan = lifespan)
28+ ```
3329
34- ``` python
35- ...
36- from fastsqla import Session
37- from sqlalchemy import select
38- ...
30+ * Async SQLAlchemy session as a FastAPI dependency:
3931
40- @app.get ( " /heros " )
41- async def get_heros ( session :Session):
42- stmt = select( ... )
43- result = await session.execute(stmt)
32+ ```python
33+ ...
34+ from fastsqla import Session
35+ from sqlalchemy import select
4436 ...
45- ```
46- </details >
47- <details >
48- <summary>Built-in pagination.</summary>
4937
50- ``` python
51- ...
52- from fastsqla import Page, Paginate
53- from sqlalchemy import select
54- ...
38+ @app.get (" /heros" )
39+ async def get_heros (session :Session):
40+ stmt = select(... )
41+ result = await session.execute(stmt)
42+ ...
43+ ```
5544
56- @app.get (" /heros" , response_model = Page[HeroModel])
57- async def get_heros (paginate :Paginate):
58- return paginate(select(Hero))
59- ```
60- Which would return something like:
61- ``` json
62- {
63- "data" : [
64- {
65- "name" : " The Flash" ,
66- "secret_identity" : " Barry Allen" ,
67- "id" : 11
68- },
45+ * Built- in pagination:
46+
47+ ```python
48+ ...
49+ from fastsqla import Page, Paginate
50+ from sqlalchemy import select
51+ ...
52+
53+ @app.get (" /heros" , response_model = Page[HeroModel])
54+ async def get_heros (paginate :Paginate):
55+ return paginate(select(Hero))
56+ ```
57+ Returning data & pagination metadata:
58+ ```json
6959 {
70- "name" : " Green Lantern" ,
71- "secret_identity" : " Hal Jordan" ,
72- "id" : 12
60+ " data" : [
61+ {
62+ " name" : " The Flash" ,
63+ " secret_identity" : " Barry Allen" ,
64+ " id" : 11
65+ },
66+ {
67+ " name" : " Green Lantern" ,
68+ " secret_identity" : " Hal Jordan" ,
69+ " id" : 12
70+ }
71+ ],
72+ " meta" : {
73+ " offset" : 10 ,
74+ " total_items" : 12 ,
75+ " total_pages" : 2 ,
76+ " page_number" : 2
77+ }
7378 }
74- ],
75- "meta" : {
76- "offset" : 10 ,
77- "total_items" : 12 ,
78- "total_pages" : 2 ,
79- "page_number" : 2
80- }
81- }
82- ```
83- </details >
84- <details >
85- <summary>Pagination customization.</summary>
79+ ```
8680
87- ``` python
88- ...
89- from fastapi import Page, new_pagination
90- ...
81+ * Pagination customization:
82+ ```python
83+ ...
84+ from fastapi import Page, new_pagination
85+ ...
9186
92- Paginate = new_pagination(min_page_size = 5 , max_page_size = 500 )
87+ Paginate = new_pagination(min_page_size = 5 , max_page_size = 500 )
9388
94- @app.get (" /heros" , response_model = Page[HeroModel])
95- async def get_heros (paginate :Paginate):
96- return paginate(select(Hero))
97- ```
98- </details >
89+ @app.get (" /heros" , response_model = Page[HeroModel])
90+ async def get_heros (paginate :Paginate):
91+ return paginate(select(Hero))
92+ ```
9993
10094And more ...
101- <!-- <details><summary></summary></details> -->
95+
10296
10397# # Installing
10498
@@ -114,6 +108,14 @@ pip install fastsqla
114108
115109## Quick Example
116110
111+ 💡 The example uses an ` SQLite ` database for simplicity.
112+
113+ ` FastSQLA ` is compatible with all asynchronous db drivers that ` SQLAlchemy ` is
114+ compatible with.
115+
116+ <details >
117+ <summary >Write the application code in <code >example.py</code ></summary >
118+
117119``` python
118120# example.py
119121from http import HTTPStatus
@@ -169,13 +171,11 @@ async def create_user(new_hero: HeroBase, session: Session):
169171 raise HTTPException(HTTPStatus.CONFLICT , " Duplicate hero name" )
170172 return {" data" : hero}
171173```
174+ </details >
172175
173- > [ !NOTE]
174- > Sqlite is used for the sake of the example.
175- > FastSQLA is compatible with all async db drivers that SQLAlchemy is compatible with.
176176
177177<details >
178- <summary>Create an <code>sqlite3 </code> db:</summary>
178+ <summary >Create an <code >SQLite </code > using `sqlite3` db:</summary >
179179
180180``` bash
181181sqlite3 db.sqlite << EOF
@@ -186,39 +186,36 @@ CREATE TABLE hero (
186186);
187187
188188-- Insert heroes with hero name and secret identity
189- INSERT INTO hero (name, secret_identity) VALUES ('Superman', 'Clark Kent');
190- INSERT INTO hero (name, secret_identity) VALUES ('Batman', 'Bruce Wayne');
191- INSERT INTO hero (name, secret_identity) VALUES ('Wonder Woman', 'Diana Prince');
192- INSERT INTO hero (name, secret_identity) VALUES ('Iron Man', 'Tony Stark');
193- INSERT INTO hero (name, secret_identity) VALUES ('Spider-Man', 'Peter Parker');
189+ INSERT INTO hero (name, secret_identity) VALUES ('Superman', 'Clark Kent');
190+ INSERT INTO hero (name, secret_identity) VALUES ('Batman', 'Bruce Wayne');
191+ INSERT INTO hero (name, secret_identity) VALUES ('Wonder Woman', 'Diana Prince');
192+ INSERT INTO hero (name, secret_identity) VALUES ('Iron Man', 'Tony Stark');
193+ INSERT INTO hero (name, secret_identity) VALUES ('Spider-Man', 'Peter Parker');
194194INSERT INTO hero (name, secret_identity) VALUES ('Captain America', 'Steve Rogers');
195- INSERT INTO hero (name, secret_identity) VALUES ('Black Widow', 'Natasha Romanoff');
196- INSERT INTO hero (name, secret_identity) VALUES ('Thor', 'Thor Odinson');
197- INSERT INTO hero (name, secret_identity) VALUES ('Scarlet Witch', 'Wanda Maximoff');
198- INSERT INTO hero (name, secret_identity) VALUES ('Doctor Strange', 'Stephen Strange');
199- INSERT INTO hero (name, secret_identity) VALUES ('The Flash', 'Barry Allen');
200- INSERT INTO hero (name, secret_identity) VALUES ('Green Lantern', 'Hal Jordan');
195+ INSERT INTO hero (name, secret_identity) VALUES ('Black Widow', 'Natasha Romanoff');
196+ INSERT INTO hero (name, secret_identity) VALUES ('Thor', 'Thor Odinson');
197+ INSERT INTO hero (name, secret_identity) VALUES ('Scarlet Witch', 'Wanda Maximoff');
198+ INSERT INTO hero (name, secret_identity) VALUES ('Doctor Strange', 'Stephen Strange');
199+ INSERT INTO hero (name, secret_identity) VALUES ('The Flash', 'Barry Allen');
200+ INSERT INTO hero (name, secret_identity) VALUES ('Green Lantern', 'Hal Jordan');
201201EOF
202202```
203-
204203</details >
205204
206205<details >
207- <summary>Install dependencies & run the app</summary>
206+ <summary >Install dependencies & run the app</summary >
208207
209208``` bash
210209pip install uvicorn aiosqlite fastsqla
211210sqlalchemy_url=sqlite+aiosqlite:///db.sqlite? check_same_thread=false uvicorn example:app
212211```
213-
214212</details >
215-
216- Execute ` GET /heros?offset=10 ` :
213+ < details >
214+ < summary > Execute < code > GET /heros?offset=10</ code > using `curl`</ summary >
217215
218216``` bash
219- curl -X ' GET' \
220- ' http://127.0.0.1:8000/heros?offset=10&limit=10' \
221- -H ' accept: application/json'
217+ curl -X ' GET' -H ' accept: application/json' ' http://127.0.0.1:8000/heros?offset=10&limit=10'
218+
222219```
223220Returns:
224221``` json
@@ -243,6 +240,3 @@ Returns:
243240 }
244241}
245242```
246-
247- [ `FastAPI` ] : https://fastapi.tiangolo.com/
248- [ `SQLAlchemy` ] : http://sqlalchemy.org/
0 commit comments