From 955e9fcb3198e1f34c562fc240591df783ae1725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 12 Feb 2019 23:02:21 +0400 Subject: [PATCH] Update fix SQLAlchemy support with ORM (#30) :sparkles: SQLAlchemy ORM support Improved jsonable_encoder with SQLAlchemy support, tests running with SQLite, improved and updated SQL docs * :heavy_plus_sign: Add SQLAlchemy to development dependencies (not required for using FastAPI) * :heavy_plus_sign: Add sqlalchemy to testing dependencies (not required to use FastAPI) --- Pipfile | 1 + Pipfile.lock | 110 +++++++------- docs/img/tutorial/sql-databases/image01.png | Bin 0 -> 78949 bytes docs/src/sql_databases/tutorial001.py | 28 +++- docs/tutorial/sql-databases.md | 137 +++++++++++++++--- fastapi/encoders.py | 75 ++++++---- pyproject.toml | 3 +- scripts/test.sh | 5 + .../test_sql_databases/__init__.py | 0 .../test_sql_databases/test_tutorial001.py | 88 +++++++++++ 10 files changed, 338 insertions(+), 109 deletions(-) create mode 100644 docs/img/tutorial/sql-databases/image01.png create mode 100644 tests/test_tutorial/test_sql_databases/__init__.py create mode 100644 tests/test_tutorial/test_sql_databases/test_tutorial001.py diff --git a/Pipfile b/Pipfile index 5857a08eb..3a7e2e9ea 100644 --- a/Pipfile +++ b/Pipfile @@ -21,6 +21,7 @@ email-validator = "*" ujson = "*" flake8 = "*" python-multipart = "*" +sqlalchemy = "*" [packages] starlette = "==0.10.1" diff --git a/Pipfile.lock b/Pipfile.lock index 26bf2ffe6..5723c712d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "20483e725e92e679c4c21ea3ff0043d759c74102b181f16b67908f979f854d5c" + "sha256": "37b34bb892b6b4dc0f7c941434d0e08199aa7a7ca83efb6294b89ace44168bba" }, "pipfile-spec": 6, "requires": { @@ -50,10 +50,10 @@ }, "atomicwrites": { "hashes": [ - "sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0", - "sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee" + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" ], - "version": "==1.2.1" + "version": "==1.3.0" }, "attrs": { "hashes": [ @@ -199,19 +199,19 @@ }, "flake8": { "hashes": [ - "sha256:09b9bb539920776da542e67a570a5df96ff933c9a08b62cfae920bcc789e4383", - "sha256:e0f8cd519cfc0072c0ee31add5def09d2b3ef6040b34dc426445c3af9b02163c" + "sha256:c3ba1e130c813191db95c431a18cb4d20a468e98af7a77e2181b68574481ad36", + "sha256:fd9ddf503110bf3d8b1d270e8c673aab29ccb3dd6abf29bae1f54e5116ab4a91" ], "index": "pypi", - "version": "==3.7.4" + "version": "==3.7.5" }, "flit": { "hashes": [ - "sha256:6aefa6ff89a993af7a7af40d3df3d0387d6663df99797981ec41b1431ec6d1e1", - "sha256:9969db9708305b64fd8acf20043fcff144f910222397a221fd29871f02ed4a6f" + "sha256:1d93f7a833ed8a6e120ddc40db5c4763bc39bccc75c05081ec8285ece718aefb", + "sha256:6f6f0fb83c51ffa3a150fa41b5ac118df9ea4a87c2c06dff4ebf9adbe7b52b36" ], "index": "pypi", - "version": "==1.2.1" + "version": "==1.3" }, "idna": { "hashes": [ @@ -395,19 +395,18 @@ }, "more-itertools": { "hashes": [ - "sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4", - "sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc", - "sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9" + "sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40", + "sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1" ], - "version": "==5.0.0" + "version": "==6.0.0" }, "mypy": { "hashes": [ - "sha256:986a7f97808a865405c5fd98fae5ebfa963c31520a56c783df159e9a81e41b3e", - "sha256:cc5df73cc11d35655a8c364f45d07b13c8db82c000def4bd7721be13356533b4" + "sha256:308c274eb8482fbf16006f549137ddc0d69e5a589465e37b99c4564414363ca7", + "sha256:e80fd6af34614a0e898a57f14296d0dacb584648f0339c2e000ddbf0f4cc2f8d" ], "index": "pypi", - "version": "==0.660" + "version": "==0.670" }, "mypy-extensions": { "hashes": [ @@ -418,10 +417,10 @@ }, "nbconvert": { "hashes": [ - "sha256:08d21cf4203fabafd0d09bbd63f06131b411db8ebeede34b0fd4be4548351779", - "sha256:a8a2749f972592aa9250db975304af6b7337f32337e523a2c995cc9e12c07807" + "sha256:302554a2e219bc0fc84f3edd3e79953f3767b46ab67626fdec16e38ba3f7efe4", + "sha256:5de8fb2284422272a1d45abc77c07b888127550a6d602ce619592a2b08a474ff" ], - "version": "==5.4.0" + "version": "==5.4.1" }, "nbformat": { "hashes": [ @@ -445,10 +444,10 @@ }, "parso": { "hashes": [ - "sha256:4b8f9ed80c3a4a3191aa3261505d868aa552dd25649cb13a7d73b6b7315edf2d", - "sha256:5a120be2e8863993b597f1c0437efca799e90e0793c98ae5d4e34ebd00140e31" + "sha256:6ecf7244be8e7283ec9009c72d074830e7e0e611c974f813d76db0390a4e0dd6", + "sha256:8162be7570ffb34ec0b8d215d7f3b6c5fab24f51eb3886d6dee362de96b6db94" ], - "version": "==0.3.2" + "version": "==0.3.3" }, "pexpect": { "hashes": [ @@ -531,9 +530,9 @@ }, "pyrsistent": { "hashes": [ - "sha256:5a3827d57ad3e46820e5ee4ed5b9e0ee7bc4686df6634a7368bc1863a5c48a77" + "sha256:07f7ae71291af8b0dbad8c2ab630d8223e4a8c4e10fc37badda158c02e753acf" ], - "version": "==0.14.9" + "version": "==0.14.10" }, "pytest": { "hashes": [ @@ -553,10 +552,10 @@ }, "python-dateutil": { "hashes": [ - "sha256:063df5763652e21de43de7d9e00ccf239f953a832941e37be541614732cdfc93", - "sha256:88f9287c0174266bb0d8cedd395cfba9c58e87e5ad86b2ce58859bc11be3cf02" + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" ], - "version": "==2.7.5" + "version": "==2.8.0" }, "python-multipart": { "hashes": [ @@ -640,6 +639,13 @@ ], "version": "==1.12.0" }, + "sqlalchemy": { + "hashes": [ + "sha256:7dede29f121071da9873e7b8c98091874617858e790dc364ffaab4b09d81216c" + ], + "index": "pypi", + "version": "==1.3.0b3" + }, "terminado": { "hashes": [ "sha256:55abf9ade563b8f9be1f34e4233c7b7bde726059947a593322e8a553cc4c067a", @@ -663,9 +669,9 @@ }, "tornado": { "hashes": [ - "sha256:00ebd485a52bd7eaa3f35bdf8ab43c109aaa2edc722849b6905c1ffd8c958e82" + "sha256:d3b719a0cb7094e2b1ca94b31f4b601639fa7ad01a548a1a2ccdd6cbdfd56671" ], - "version": "==6.0a1" + "version": "==6.0b1" }, "traitlets": { "hashes": [ @@ -676,29 +682,27 @@ }, "typed-ast": { "hashes": [ - "sha256:023625bfa9359e29bd6e24cac2a4503495b49761d48a5f1e38333fc4ac4d93fe", - "sha256:07591f7a5fdff50e2e566c4c1e9df545c75d21e27d98d18cb405727ed0ef329c", - "sha256:153e526b0f4ffbfada72d0bb5ffe8574ba02803d2f3a9c605c8cf99dfedd72a2", - "sha256:3ad2bdcd46a4a1518d7376e9f5016d17718a9ed3c6a3f09203d832f6c165de4a", - "sha256:3ea98c84df53ada97ee1c5159bb3bc784bd734231235a1ede14c8ae0775049f7", - "sha256:51a7141ccd076fa561af107cfb7a8b6d06a008d92451a1ac7e73149d18e9a827", - "sha256:52c93cd10e6c24e7ac97e8615da9f224fd75c61770515cb323316c30830ddb33", - "sha256:6344c84baeda3d7b33e157f0b292e4dd53d05ddb57a63f738178c01cac4635c9", - "sha256:64699ca1b3bd5070bdeb043e6d43bc1d0cebe08008548f4a6bee782b0ecce032", - "sha256:74903f2e56bbffe29282ef8a5487d207d10be0f8513b41aff787d954a4cf91c9", - "sha256:7891710dba83c29ee2bd51ecaa82f60f6bede40271af781110c08be134207bf2", - "sha256:91976c56224e26c256a0de0f76d2004ab885a29423737684b4f7ebdd2f46dde2", - "sha256:9bad678a576ecc71f25eba9f1e3fd8d01c28c12a2834850b458428b3e855f062", - "sha256:b4726339a4c180a8b6ad9d8b50d2b6dc247e1b79b38fe2290549c98e82e4fd15", - "sha256:ba36f6aa3f8933edf94ea35826daf92cbb3ec248b89eccdc053d4a815d285357", - "sha256:bbc96bde544fd19e9ef168e4dfa5c3dfe704bfa78128fa76f361d64d6b0f731a", - "sha256:c0c927f1e44469056f7f2dada266c79b577da378bbde3f6d2ada726d131e4824", - "sha256:c0f9a3708008aa59f560fa1bd22385e05b79b8e38e0721a15a8402b089243442", - "sha256:f0bf6f36ff9c5643004171f11d2fdc745aa3953c5aacf2536a0685db9ceb3fb1", - "sha256:f5be39a0146be663cbf210a4d95c3c58b2d7df7b043c9047c5448e358f0550a2", - "sha256:fcd198bf19d9213e5cbf2cde2b9ef20a9856e716f76f9476157f90ae6de06cc6" - ], - "version": "==1.2.0" + "sha256:035a54ede6ce1380599b2ce57844c6554666522e376bd111eb940fbc7c3dad23", + "sha256:037c35f2741ce3a9ac0d55abfcd119133cbd821fffa4461397718287092d9d15", + "sha256:049feae7e9f180b64efacbdc36b3af64a00393a47be22fa9cb6794e68d4e73d3", + "sha256:19228f7940beafc1ba21a6e8e070e0b0bfd1457902a3a81709762b8b9039b88d", + "sha256:2ea681e91e3550a30c2265d2916f40a5f5d89b59469a20f3bad7d07adee0f7a6", + "sha256:3a6b0a78af298d82323660df5497bcea0f0a4a25a0b003afd0ce5af049bd1f60", + "sha256:5385da8f3b801014504df0852bf83524599df890387a3c2b17b7caa3d78b1773", + "sha256:606d8afa07eef77280c2bf84335e24390055b478392e1975f96286d99d0cb424", + "sha256:69245b5b23bbf7fb242c9f8f08493e9ecd7711f063259aefffaeb90595d62287", + "sha256:6f6d839ab09830d59b7fa8fb6917023d8cb5498ee1f1dbd82d37db78eb76bc99", + "sha256:730888475f5ac0e37c1de4bd05eeb799fdb742697867f524dc8a4cd74bcecc23", + "sha256:9819b5162ffc121b9e334923c685b0d0826154e41dfe70b2ede2ce29034c71d8", + "sha256:9e60ef9426efab601dd9aa120e4ff560f4461cf8442e9c0a2b92548d52800699", + "sha256:af5fbdde0690c7da68e841d7fc2632345d570768ea7406a9434446d7b33b0ee1", + "sha256:b64efdbdf3bbb1377562c179f167f3bf301251411eb5ac77dec6b7d32bcda463", + "sha256:bac5f444c118aeb456fac1b0b5d14c6a71ea2a42069b09c176f75e9bd4c186f6", + "sha256:bda9068aafb73859491e13b99b682bd299c1b5fd50644d697533775828a28ee0", + "sha256:d659517ca116e6750101a1326107d3479028c5191f0ecee3c7203c50f5b915b0", + "sha256:eddd3fb1f3e0f82e5915a899285a39ee34ce18fd25d89582bc89fc9fb16cd2c6" + ], + "version": "==1.3.1" }, "ujson": { "hashes": [ diff --git a/docs/img/tutorial/sql-databases/image01.png b/docs/img/tutorial/sql-databases/image01.png new file mode 100644 index 0000000000000000000000000000000000000000..8e575abd65aaf37a33fed5bdae4029955dffb090 GIT binary patch literal 78949 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

Y^^(*eiD{sbfJ%(&*CDpE(Ud6wW` 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 literal 0 HcmV?d00001 diff --git a/docs/src/sql_databases/tutorial001.py b/docs/src/sql_databases/tutorial001.py index a847c5c7b..00eef4c13 100644 --- a/docs/src/sql_databases/tutorial001.py +++ b/docs/src/sql_databases/tutorial001.py @@ -1,13 +1,15 @@ from fastapi import FastAPI - from sqlalchemy import Boolean, Column, Integer, String, create_engine from sqlalchemy.ext.declarative import declarative_base, declared_attr from sqlalchemy.orm import scoped_session, sessionmaker # SQLAlchemy specific code, as with any other app -SQLALCHEMY_DATABASE_URI = "postgresql://user:password@postgresserver/db" +SQLALCHEMY_DATABASE_URI = "sqlite:///./test.db" +# SQLALCHEMY_DATABASE_URI = "postgresql://user:password@postgresserver/db" -engine = create_engine(SQLALCHEMY_DATABASE_URI, convert_unicode=True) +engine = create_engine( + SQLALCHEMY_DATABASE_URI, connect_args={"check_same_thread": False} +) db_session = scoped_session( sessionmaker(autocommit=False, autoflush=False, bind=engine) ) @@ -30,15 +32,25 @@ class User(Base): is_active = Column(Boolean(), default=True) -def get_user(username, db_session): - return db_session.query(User).filter(User.id == username).first() +Base.metadata.create_all(bind=engine) + +first_user = db_session.query(User).first() +if not first_user: + u = User(email="johndoe@example.com", hashed_password="notreallyhashed") + db_session.add(u) + db_session.commit() + + +# Utility +def get_user(db_session, user_id: int): + return db_session.query(User).filter(User.id == user_id).first() # FastAPI specific code app = FastAPI() -@app.get("/users/{username}") -def read_user(username: str): - user = get_user(username, db_session) +@app.get("/users/{user_id}") +def read_user(user_id: int): + user = get_user(db_session, user_id=user_id) return user diff --git a/docs/tutorial/sql-databases.md b/docs/tutorial/sql-databases.md index ef5a2b6c6..1103af48b 100644 --- a/docs/tutorial/sql-databases.md +++ b/docs/tutorial/sql-databases.md @@ -12,7 +12,9 @@ You can easily adapt it to any database supported by SQLAlchemy, like: * Oracle * Microsoft SQL Server, etc. -In this example, we'll use **PostgreSQL**. +In this example, we'll use **SQLite**, because it uses a single file and Python has integrated support. So, you can copy this example and run it as is. + +Later, for your production application, you might want to use a database server like **PostgreSQL**. !!! note Notice that most of the code is the standard `SQLAlchemy` code you would use with any framework. @@ -23,30 +25,58 @@ In this example, we'll use **PostgreSQL**. For now, don't pay attention to the rest, only the imports: -```Python hl_lines="3 4 5" +```Python hl_lines="2 3 4" {!./src/sql_databases/tutorial001.py!} ``` ## Define the database -Define the database that SQLAlchemy should connect to: +Define the database that SQLAlchemy should "connect" to: -```Python hl_lines="8" +```Python hl_lines="7" {!./src/sql_databases/tutorial001.py!} ``` +In this example, we are "connecting" to a SQLite database (opening a file with the SQLite database). + +The file will be located at the same directory in the file `test.db`. That's why the last part is `./test.db`. + +If you were using a **PostgreSQL** database instead, you would just have to uncomment the line: + +```Python +SQLALCHEMY_DATABASE_URI = "postgresql://user:password@postgresserver/db" +``` + +...and adapt it with your database data and credentials (equivalently for MySQL, MariaDB or any other). + !!! tip - This is the main line that you would have to modify if you wanted to use a different database than **PostgreSQL**. + + This is the main line that you would have to modify if you wanted to use a different database. ## Create the SQLAlchemy `engine` -```Python hl_lines="10" +```Python hl_lines="10 11 12" {!./src/sql_databases/tutorial001.py!} ``` +### Note + +The argument: + +```Python +connect_args={"check_same_thread": False} +``` + +...is needed only for `SQLite`. It's not needed for other databases. + +!!! info "Technical Details" + + That argument `check_same_thread` is there mainly to be able to run the tests that cover this example. + + ## Create a `scoped_session` -```Python hl_lines="11 12 13" +```Python hl_lines="13 14 15" {!./src/sql_databases/tutorial001.py!} ``` @@ -55,9 +85,9 @@ Define the database that SQLAlchemy should connect to: This `scoped_session` is a feature of SQLAlchemy. - The resulting object, the `db_session` can then be used anywhere a a normal SQLAlchemy session. + The resulting object, the `db_session` can then be used anywhere as a normal SQLAlchemy session. - It can be used as a global because it is implemented to work independently on each "thread", so the actions you perform with it in one path operation function won't affect the actions performed (possibly concurrently) by other path operation functions. + It can be used as a "global" variable because it is implemented to work independently on each "thread", so the actions you perform with it in one path operation function won't affect the actions performed (possibly concurrently) by other path operation functions. ## Create a `CustomBase` model @@ -65,17 +95,17 @@ This is more of a trick to facilitate your life than something required. But by creating this `CustomBase` class and inheriting from it, your models will have automatic `__tablename__` attributes (that are required by SQLAlchemy). -That way you don't have to declare them explicitly. +That way you don't have to declare them explicitly in every model. So, your models will behave very similarly to, for example, Flask-SQLAlchemy. -```Python hl_lines="16 17 18 19 20" +```Python hl_lines="18 19 20 21 22" {!./src/sql_databases/tutorial001.py!} ``` ## Create the SQLAlchemy `Base` model -```Python hl_lines="23" +```Python hl_lines="25" {!./src/sql_databases/tutorial001.py!} ``` @@ -85,15 +115,36 @@ Now this is finally code specific to your app. Here's a user model that will be a table in the database: -```Python hl_lines="26 27 28 29 30" +```Python hl_lines="28 29 30 31 32" +{!./src/sql_databases/tutorial001.py!} +``` + +## Initialize your application + +In a very simplistic way, initialize your database (create the tables, etc) and make sure you have a first user: + +```Python hl_lines="35 37 38 39 40 41" {!./src/sql_databases/tutorial001.py!} ``` +### Note + +Normally you would probably initialize your database (create tables, etc) with Alembic. + +And you would also use Alembic for migrations (that's its main job). For whenever you change the structure of your database, add a new column, a new table, etc. + +The same way, you would probably make sure there's a first user in an external script that runs before your application, or as part of the application startup. + +In this example we are doing those two operations in a very simple way, directly in the code, to focus on the main points. + +Also, as all the functionality is self-contained in the same code, you can copy it and run it directly, and it will work as is. + + ## Get a user -By creating a function that is only dedicated to getting your user from a `username` (or any other parameter) independent of your path operation function, you can more easily re-use it in multiple parts and also add unit tests for it: +By creating a function that is only dedicated to getting your user from a `user_id` (or any other parameter) independent of your path operation function, you can more easily re-use it in multiple parts and also add unit tests for it: -```Python hl_lines="33 34" +```Python hl_lines="45 46" {!./src/sql_databases/tutorial001.py!} ``` @@ -103,7 +154,7 @@ Now, finally, here's the standard **FastAPI** code. Create your app and path operation function: -```Python hl_lines="38 41 42 43 44" +```Python hl_lines="50 53 54 55 56" {!./src/sql_databases/tutorial001.py!} ``` @@ -113,25 +164,25 @@ We can just call `get_user` directly from inside of the path operation function ## Create the path operation function -Here we are using SQLAlchemy code inside of the path operation function, and it in turn will go and communicate with an external database. +Here we are using SQLAlchemy code inside of the path operation function, and in turn it will go and communicate with an external database. That could potentially require some "waiting". -But as SQLAlchemy doesn't have compatibility for using `await`, as would be with something like: +But as SQLAlchemy doesn't have compatibility for using `await` directly, as would be with something like: ```Python -user = await get_user(username, db_session) +user = await get_user(db_session, user_id=user_id) ``` ...and instead we are using: ```Python -user = get_user(username, db_session) +user = get_user(db_session, user_id=user_id) ``` Then we should declare the path operation without `async def`, just with a normal `def`: -```Python hl_lines="42" +```Python hl_lines="54" {!./src/sql_databases/tutorial001.py!} ``` @@ -140,3 +191,47 @@ Then we should declare the path operation without `async def`, just with a norma Because we are using SQLAlchemy directly and we don't require any kind of plug-in for it to work with **FastAPI**, we could integrate database migrations with Alembic directly. You would probably want to declare your database and models in a different file or set of files, this would allow Alembic to import it and use it without even needing to have **FastAPI** installed for the migrations. + +## Check it + +You can copy this code and use it as is. + +!!! info + + In fact, the code shown here is part of the tests. As most of the code in these docs. + + +You can copy it, let's say, to a file `main.py`. + +Then you can run it with Uvicorn: + +```bash +uvicorn main:app --debug +``` + +And then, you can open your browser at http://127.0.0.1:8000/docs. + +And you will be able to interact with your **FastAPI** application, reading data from a real database: + + + +## Response schema and security + +This section has the minimum code to show how it works and how you can integrate SQLAlchemy with FastAPI. + +But it is recommended that you also create a response model with Pydantic, as described in the section about Extra Models. + +That way you will document the schema of the responses of your API, and you will be able to limit/filter the returned data. + +Limiting the returned data is important for security, as for example, you shouldn't be returning the `hashed_password` to the clients. + +That's something that you can improve in this example application, here's the current response data: + +```JSON +{ + "is_active": true, + "hashed_password": "notreallyhashed", + "email": "johndoe@example.com", + "id": 1 +} +``` diff --git a/fastapi/encoders.py b/fastapi/encoders.py index f5059a76f..07e3c3dfb 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -13,6 +13,7 @@ def jsonable_encoder( by_alias: bool = False, include_none: bool = True, custom_encoder: dict = {}, + sqlalchemy_safe: bool = True, ) -> Any: if isinstance(obj, BaseModel): encoder = getattr(obj.Config, "json_encoders", custom_encoder) @@ -20,39 +21,55 @@ def jsonable_encoder( obj.dict(include=include, exclude=exclude, by_alias=by_alias), include_none=include_none, custom_encoder=encoder, + sqlalchemy_safe=sqlalchemy_safe, ) if isinstance(obj, Enum): return obj.value if isinstance(obj, (str, int, float, type(None))): return obj if isinstance(obj, dict): - return { - jsonable_encoder( - key, - by_alias=by_alias, - include_none=include_none, - custom_encoder=custom_encoder, - ): jsonable_encoder( - value, - by_alias=by_alias, - include_none=include_none, - custom_encoder=custom_encoder, - ) - for key, value in obj.items() - if value is not None or include_none - } + encoded_dict = {} + for key, value in obj.items(): + if ( + ( + not sqlalchemy_safe + or (not isinstance(key, str)) + or (not key.startswith("_sa")) + ) + and (value is not None or include_none) + and ((include and key in include) or key not in exclude) + ): + encoded_key = jsonable_encoder( + key, + by_alias=by_alias, + include_none=include_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) + encoded_value = jsonable_encoder( + value, + by_alias=by_alias, + include_none=include_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) + encoded_dict[encoded_key] = encoded_value + return encoded_dict if isinstance(obj, (list, set, frozenset, GeneratorType, tuple)): - return [ - jsonable_encoder( - item, - include=include, - exclude=exclude, - by_alias=by_alias, - include_none=include_none, - custom_encoder=custom_encoder, + encoded_list = [] + for item in obj: + encoded_list.append( + jsonable_encoder( + item, + include=include, + exclude=exclude, + by_alias=by_alias, + include_none=include_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) ) - for item in obj - ] + return encoded_list errors = [] try: if custom_encoder and type(obj) in custom_encoder: @@ -71,4 +88,10 @@ def jsonable_encoder( except Exception as e: errors.append(e) raise ValueError(errors) - return jsonable_encoder(data, by_alias=by_alias, include_none=include_none) + return jsonable_encoder( + data, + by_alias=by_alias, + include_none=include_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) diff --git a/pyproject.toml b/pyproject.toml index e788fbf53..c7273cc4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,8 @@ test = [ "black", "isort", "requests", - "email_validator" + "email_validator", + "sqlalchemy" ] doc = [ "mkdocs", diff --git a/scripts/test.sh b/scripts/test.sh index 79f66c321..a9b912bbe 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -6,6 +6,11 @@ set -x export VERSION_SCRIPT="import sys; print('%s.%s' % sys.version_info[0:2])" export PYTHON_VERSION=`python -c "$VERSION_SCRIPT"` +# Remove temporary DB +if [ -f ./test.db ]; then + rm ./test.db +fi + export PYTHONPATH=./docs/src pytest --cov=fastapi --cov=tests --cov=docs/src --cov-report=term-missing ${@} mypy fastapi --disallow-untyped-defs diff --git a/tests/test_tutorial/test_sql_databases/__init__.py b/tests/test_tutorial/test_sql_databases/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_tutorial/test_sql_databases/test_tutorial001.py b/tests/test_tutorial/test_sql_databases/test_tutorial001.py new file mode 100644 index 000000000..583c233ee --- /dev/null +++ b/tests/test_tutorial/test_sql_databases/test_tutorial001.py @@ -0,0 +1,88 @@ +from starlette.testclient import TestClient + +from sql_databases.tutorial001 import app + +client = TestClient(app) + +openapi_schema = { + "openapi": "3.0.2", + "info": {"title": "Fast API", "version": "0.1.0"}, + "paths": { + "/users/{user_id}": { + "get": { + "responses": { + "200": { + "description": "Successful Response", + "content": {"application/json": {"schema": {}}}, + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + }, + }, + "summary": "Read User Get", + "operationId": "read_user_users__user_id__get", + "parameters": [ + { + "required": True, + "schema": {"title": "User_Id", "type": "integer"}, + "name": "user_id", + "in": "path", + } + ], + } + } + }, + "components": { + "schemas": { + "ValidationError": { + "title": "ValidationError", + "required": ["loc", "msg", "type"], + "type": "object", + "properties": { + "loc": { + "title": "Location", + "type": "array", + "items": {"type": "string"}, + }, + "msg": {"title": "Message", "type": "string"}, + "type": {"title": "Error Type", "type": "string"}, + }, + }, + "HTTPValidationError": { + "title": "HTTPValidationError", + "type": "object", + "properties": { + "detail": { + "title": "Detail", + "type": "array", + "items": {"$ref": "#/components/schemas/ValidationError"}, + } + }, + }, + } + }, +} + + +def test_openapi_schema(): + response = client.get("/openapi.json") + assert response.status_code == 200 + assert response.json() == openapi_schema + + +def test_first_user(): + response = client.get("/users/1") + assert response.status_code == 200 + assert response.json() == { + "is_active": True, + "hashed_password": "notreallyhashed", + "email": "johndoe@example.com", + "id": 1, + }