mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-25 07:08:11 -05:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a174f01901 | ||
|
|
9b76ad1870 | ||
|
|
f1c367aead | ||
|
|
8291c664b9 | ||
|
|
e8472ebbd1 | ||
|
|
f4391e2a87 | ||
|
|
11c755bee3 | ||
|
|
35054a450c | ||
|
|
da60de33c1 | ||
|
|
c0758dfe71 | ||
|
|
1112ac7538 | ||
|
|
ac2b18bf40 | ||
|
|
b89a24448b | ||
|
|
e76216dd26 | ||
|
|
123d778a0c | ||
|
|
829ad209a6 | ||
|
|
b15a65c37e | ||
|
|
0eed798aac | ||
|
|
2caca42b9e | ||
|
|
7658d0af16 |
@@ -15,3 +15,9 @@ script:
|
||||
|
||||
after_script:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
script: bash scripts/trigger-docker.sh
|
||||
on:
|
||||
branch: master
|
||||
|
||||
1
Pipfile
1
Pipfile
@@ -22,6 +22,7 @@ ujson = "*"
|
||||
flake8 = "*"
|
||||
python-multipart = "*"
|
||||
sqlalchemy = "*"
|
||||
uvicorn = "*"
|
||||
|
||||
[packages]
|
||||
starlette = "==0.11.1"
|
||||
|
||||
274
Pipfile.lock
generated
274
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "6b55a2dcce8b6bd5a1be8f170acb18478149218a01d1b026981a6297800cd3fa"
|
||||
"sha256": "f1f1b7fb88822fcf89e5073263c5a42234fa68d18ce0b1b82e4dd926bcdf12e9"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -57,10 +57,10 @@
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
|
||||
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
|
||||
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
|
||||
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
|
||||
],
|
||||
"version": "==18.2.0"
|
||||
"version": "==19.1.0"
|
||||
},
|
||||
"autoflake": {
|
||||
"hashes": [
|
||||
@@ -199,11 +199,11 @@
|
||||
},
|
||||
"flake8": {
|
||||
"hashes": [
|
||||
"sha256:6d8c66a65635d46d54de59b027a1dda40abbe2275b3164b634835ac9c13fd048",
|
||||
"sha256:6eab21c6e34df2c05416faa40d0c59963008fff29b6f0ccfe8fa28152ab3e383"
|
||||
"sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661",
|
||||
"sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.7.6"
|
||||
"version": "==3.7.7"
|
||||
},
|
||||
"flit": {
|
||||
"hashes": [
|
||||
@@ -213,6 +213,20 @@
|
||||
"index": "pypi",
|
||||
"version": "==1.3"
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:acca6a44cb52a32ab442b1779adf0875c443c689e9e028f8d831a3769f9c5208",
|
||||
"sha256:f2b1ca39bfed357d1f19ac732913d5f9faa54a5062eca7d2ec3a916cfb7ae4c7"
|
||||
],
|
||||
"version": "==0.8.1"
|
||||
},
|
||||
"httptools": {
|
||||
"hashes": [
|
||||
"sha256:e00cbd7ba01ff748e494248183abc6e153f49181169d8a3d41bb49132ca01dfc"
|
||||
],
|
||||
"markers": "sys_platform != 'win32' and sys_platform != 'cygwin' and platform_python_implementation != 'pypy'",
|
||||
"version": "==0.0.13"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
||||
@@ -251,19 +265,18 @@
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af",
|
||||
"sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8",
|
||||
"sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497"
|
||||
"sha256:38a74a5ccf3a15a7a99f975071164f48d4d10eed4154879009c18e6e8933e5aa",
|
||||
"sha256:abbb2684aa234d5eb8a67ef36d4aa62ea080d46c2eba36ad09e2990ae52e4305"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.3.4"
|
||||
"version": "==4.3.13"
|
||||
},
|
||||
"jedi": {
|
||||
"hashes": [
|
||||
"sha256:571702b5bd167911fe9036e5039ba67f820d6502832285cde8c881ab2b2149fd",
|
||||
"sha256:c8481b5e59d34a5c7c42e98f6625e633f6ef59353abea6437472c7ec2093f191"
|
||||
"sha256:2bb0603e3506f708e792c7f4ad8fc2a7a9d9c2d292a358fbbd58da531695595b",
|
||||
"sha256:2c6bcd9545c7d6440951b12b44d373479bf18123a401a52025cf98563fbd826c"
|
||||
],
|
||||
"version": "==0.13.2"
|
||||
"version": "==0.13.3"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
@@ -274,10 +287,10 @@
|
||||
},
|
||||
"jsonschema": {
|
||||
"hashes": [
|
||||
"sha256:683fe7ed58763ea0be572de5aad47cd3cc1297640916f9a8ccd222b287da7d2f",
|
||||
"sha256:b42d7a292addb57370e6260bcbadb77e00a899fe6ec998c453f45893c41c658b"
|
||||
"sha256:0c0a81564f181de3212efa2d17de1910f8732fa1b71c42266d983cd74304e20d",
|
||||
"sha256:a5f6559964a3851f59040d3b961de5e68e70971afb88ba519d27e6a039efff1a"
|
||||
],
|
||||
"version": "==3.0.0b3"
|
||||
"version": "==3.0.1"
|
||||
},
|
||||
"jupyter": {
|
||||
"hashes": [
|
||||
@@ -332,36 +345,36 @@
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
|
||||
"sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
|
||||
"sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
|
||||
"sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
|
||||
"sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
|
||||
"sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
|
||||
"sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
|
||||
"sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
|
||||
"sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
|
||||
"sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
|
||||
"sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
|
||||
"sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
|
||||
"sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
|
||||
"sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
|
||||
"sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
|
||||
"sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
|
||||
"sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
|
||||
"sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
|
||||
"sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
|
||||
"sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
|
||||
"sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
|
||||
"sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
|
||||
"sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
|
||||
"sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
|
||||
"sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
|
||||
"sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
|
||||
"sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
|
||||
"sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
|
||||
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
|
||||
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
|
||||
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
|
||||
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
|
||||
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
|
||||
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
|
||||
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
|
||||
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
|
||||
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
|
||||
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
|
||||
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
|
||||
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
|
||||
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
|
||||
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
|
||||
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
|
||||
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
|
||||
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
|
||||
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
|
||||
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
|
||||
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
|
||||
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
|
||||
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
|
||||
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
|
||||
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
|
||||
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
|
||||
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
|
||||
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
|
||||
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
@@ -387,11 +400,11 @@
|
||||
},
|
||||
"mkdocs-material": {
|
||||
"hashes": [
|
||||
"sha256:63c49a7020e5d187d5adcd441b259e0b81ad418599b22e2c2574b419ed833851",
|
||||
"sha256:90a240f268f182a96098490d35bb75d5efc86b2f67d63a82b8750da20a72ef60"
|
||||
"sha256:762a71f82c1e291c3ff067cecd9d581557da777332fd98bc0af20fd5ab4a2dd0",
|
||||
"sha256:b2c7174ecaa81fb1d62a5f4906f99fa0e7062ced8f9a14ec4f60b1bef9feebbf"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.0.1"
|
||||
"version": "==4.0.2"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
@@ -432,10 +445,10 @@
|
||||
},
|
||||
"notebook": {
|
||||
"hashes": [
|
||||
"sha256:3ab2db8bc10e6edbd264c3c4b800bee276c99818386ee0c146d98d7e6bcf0a67",
|
||||
"sha256:d908673a4010787625c8952e91a22adf737db031f2aa0793ad92f6558918a74a"
|
||||
"sha256:9ca7f597ce4f5a24611c589fa320a7af2861f0ca1dc20839129c91ae354453fe",
|
||||
"sha256:c5011449a1a6d9f96bf65c4c2d6713802a21125476312b39c99010ccd7a2e2ed"
|
||||
],
|
||||
"version": "==5.7.4"
|
||||
"version": "==5.7.5"
|
||||
},
|
||||
"pandocfilters": {
|
||||
"hashes": [
|
||||
@@ -467,24 +480,24 @@
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616",
|
||||
"sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a"
|
||||
"sha256:19ecf9ce9db2fce065a7a0586e07cfb4ac8614fe96edf628a264b1c70116cf8f",
|
||||
"sha256:84d306a647cc805219916e62aab89caa97a33a1dd8c342e87a37f91073cd4746"
|
||||
],
|
||||
"version": "==0.8.1"
|
||||
"version": "==0.9.0"
|
||||
},
|
||||
"prometheus-client": {
|
||||
"hashes": [
|
||||
"sha256:e8c11ff5ca53de6c3d91e1510500611cafd1d247a937ec6c588a0a7cc3bef93c"
|
||||
"sha256:1b38b958750f66f208bcd9ab92a633c0c994d8859c831f7abc1f46724fcee490"
|
||||
],
|
||||
"version": "==0.5.0"
|
||||
"version": "==0.6.0"
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:88002cc618cacfda8760c4539e76c3b3f148ecdb7035a3d422c7ecdc90c2a3ba",
|
||||
"sha256:c6655a12e9b08edb8cf5aeab4815fd1e1bdea4ad73d3bbf269cf2e0c4eb75d5e",
|
||||
"sha256:df5835fb8f417aa55e5cafadbaeb0cf630a1e824aad16989f9f0493e679ec010"
|
||||
"sha256:11adf3389a996a6d45cc277580d0d53e8a5afd281d0c9ec71b28e6f121463780",
|
||||
"sha256:2519ad1d8038fd5fc8e770362237ad0364d16a7650fb5724af6997ed5515e3c1",
|
||||
"sha256:977c6583ae813a37dc1c2e1b715892461fcbdaa57f6fc62f33a528c4886c8f55"
|
||||
],
|
||||
"version": "==2.0.8"
|
||||
"version": "==2.0.9"
|
||||
},
|
||||
"ptyprocess": {
|
||||
"hashes": [
|
||||
@@ -496,10 +509,10 @@
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694",
|
||||
"sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6"
|
||||
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
|
||||
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
|
||||
],
|
||||
"version": "==1.7.0"
|
||||
"version": "==1.8.0"
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
@@ -510,10 +523,10 @@
|
||||
},
|
||||
"pyflakes": {
|
||||
"hashes": [
|
||||
"sha256:5e8c00e30c464c99e0b501dc160b13a14af7f27d4dffb529c556e30a159e231d",
|
||||
"sha256:f277f9ca3e55de669fba45b7393a1449009cff5a37d1af10ebb76c52765269cd"
|
||||
"sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0",
|
||||
"sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"
|
||||
],
|
||||
"version": "==2.1.0"
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
@@ -531,9 +544,9 @@
|
||||
},
|
||||
"pyrsistent": {
|
||||
"hashes": [
|
||||
"sha256:07f7ae71291af8b0dbad8c2ab630d8223e4a8c4e10fc37badda158c02e753acf"
|
||||
"sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"
|
||||
],
|
||||
"version": "==0.14.10"
|
||||
"version": "==0.14.11"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
@@ -573,33 +586,49 @@
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:254bf6fda2b7c651837acb2c718e213df29d531eebf00edb54743d10bcb694eb",
|
||||
"sha256:3108529b78577327d15eec243f0ff348a0640b0c3478d67ad7f5648f93bac3e2",
|
||||
"sha256:3c17fb92c8ba2f525e4b5f7941d850e7a48c3a59b32d331e2502a3cdc6648e76",
|
||||
"sha256:8d6d96001aa7f0a6a4a95e8143225b5d06e41b1131044913fecb8f85a125714b",
|
||||
"sha256:c8a88edd93ee29ede719080b2be6cb2333dfee1dccba213b422a9c8e97f2967b"
|
||||
"sha256:544a0050e76e9b60751c58617fa28c253ad5d23af2e5f0b1c250390bf90bb0df",
|
||||
"sha256:594bf80477a58b6fd53e8b3f24ccf965c25eeeb6e05e4b1fb18c82c2d2090603",
|
||||
"sha256:75e20ca689d0a2bf0c84f0e2028cc68ebef34b213fa66d73c410c53f870c49f4",
|
||||
"sha256:994da68a1dc1050f290f8017f044172360b608c0f2562b47645ecc69d7a61c0a",
|
||||
"sha256:ad902e00088c50bdced94a57b819c24fdadaeaed5494df7a9a67d63774f210fd",
|
||||
"sha256:b11aff75875ffc73541c4e4b1ac2f5e21717c1fc4396238943b9a44d962e74e1",
|
||||
"sha256:bc733b5a9047c3e4848c0e80eeacfa6a799139242606410260c5450d665ea58c",
|
||||
"sha256:d960c68931b96bb215f385baa8ef867b8ebac66af60fa06cc1008f963848c7ad",
|
||||
"sha256:dd461c04e6a91e4eef7d5b75c1fc1c7013d3f8d354033b16526baadddd524079",
|
||||
"sha256:e4d6b5d6218a06f3141189d75c93876dd525a6d15f1b00ef4f274726c93719f1",
|
||||
"sha256:f3c386fa12415bde8a0162745c4badf98fe171c6dfd67e54831f05ec88feeebb"
|
||||
],
|
||||
"version": "==4.2b4"
|
||||
"version": "==5.1b5"
|
||||
},
|
||||
"pyzmq": {
|
||||
"hashes": [
|
||||
"sha256:15f0bf7cd80020f165635595e197603aedb37fddf4164ad5ae226afc43242f7b",
|
||||
"sha256:1756dc72e192c670490e38c788c3a35f901adc74ee436e5131d5a3e85fdd7dc6",
|
||||
"sha256:1d1eb490da54679d724b08ef3ee04530849023670c4ba7e400ed2cdf906720c4",
|
||||
"sha256:228402625796821f08706f58cc42a3c51c9897d723550babaefe4feec2b6dacc",
|
||||
"sha256:3928534fa00a2aabfcfdb439c08ba37fbe99ab0cf57776c8db8d2b73a51693ba",
|
||||
"sha256:3d2a295b1086d450981f73d3561ac204a0cc9c8ded386a4a34327d918f3b1d0a",
|
||||
"sha256:4fd8621a309db6ec23ef1369f43cdf7a9b0dc217d8ff9ca4095a6e932b379bda",
|
||||
"sha256:54fe55a1694ffe608c8e4c5183e83cab7a91f3e5c84bd6f188868d6676c12aba",
|
||||
"sha256:618887be4ad754228c0cbba7631f6574608b4430fe93974e6322324f1304fdac",
|
||||
"sha256:69130efb6efa936de601cb135a8a4eec1caccd4ea2b784237145ff4075c2d3ae",
|
||||
"sha256:6e7f78eeac82140bde7e60e975c6e6b1b678a4dd377782ab63319c1c78bf3aa1",
|
||||
"sha256:6ee760cdb84e43574da6b3f2f1fc1251e8acf87253900d28a06451c5f5de39e9",
|
||||
"sha256:97cb1b7cd2c46e87b0a26651eccd2bbb8c758035efd1635ebb81ac36aa76a88c",
|
||||
"sha256:abfa774dbadacc849121ed92eae05189d226daab583388b499472e1bbb17ef69",
|
||||
"sha256:b30c339eb58355f51f4f54dd61d785f1ff58c86bca1c3a5916977631d121867b"
|
||||
"sha256:1651e52ed91f0736afd6d94ef9f3259b5534ce8beddb054f3d5ca989c4ef7c4f",
|
||||
"sha256:5ccb9b3d4cd20c000a9b75689d5add8cd3bce67fcbd0f8ae1b59345247d803af",
|
||||
"sha256:5e120c4cd3872e332fb35d255ad5998ebcee32ace4387b1b337416b6b90436c7",
|
||||
"sha256:5e2a3707c69a7281a9957f83718815fd74698cba31f6d69f9ed359921f662221",
|
||||
"sha256:63d51add9af8d0442dc90f916baf98fdc04e3b0a32afec4bfc83f8d85e72959f",
|
||||
"sha256:65c5a0bdc49e20f7d6b03a661f71e2fda7a99c51270cafe71598146d09810d0d",
|
||||
"sha256:66828fabe911aa545d919028441a585edb7c9c77969a5fea6722ef6e6ece38ab",
|
||||
"sha256:7d79427e82d9dad6e9b47c0b3e7ae5f9d489b1601e3a36ea629bb49501a4daf3",
|
||||
"sha256:824ee5d3078c4eae737ffc500fbf32f2b14e6ec89b26b435b7834febd70120cf",
|
||||
"sha256:89dc0a83cccec19ff3c62c091e43e66e0183d1e6b4658c16ee4e659518131494",
|
||||
"sha256:8b319805f6f7c907b101c864c3ca6cefc9db8ce0791356f180b1b644c7347e4c",
|
||||
"sha256:90facfb379ab47f94b19519c1ecc8ec8d10813b69d9c163117944948bdec5d15",
|
||||
"sha256:a0a178c7420021fc0730180a914a4b4b3092ce9696ceb8e72d0f60f8ce1655dd",
|
||||
"sha256:a7a89591ae315baccb8072f216614b3e59aed7385aef4393a6c741783d6ee9cf",
|
||||
"sha256:ba2578f0ae582452c02ed9fac2dc477b08e80ce05d2c0885becf5fff6651ccb0",
|
||||
"sha256:c69b0055c55702f5b0b6b354133e8325b9a56dbc80e1be2d240bead253fb9825",
|
||||
"sha256:ca434e1858fe222380221ddeb81e86f45522773344c9da63c311d17161df5e06",
|
||||
"sha256:d4b8ecfc3d92f114f04d5c40f60a65e5196198b827503341521dda12d8b14939",
|
||||
"sha256:d706025c47b09a54f005953ebe206f6d07a22516776faa4f509aaff681cc5468",
|
||||
"sha256:d8f27e958f8a2c0c8ffd4d8855c3ce8ac3fa1e105f0491ce31729aa2b3229740",
|
||||
"sha256:dbd264298f76b9060ce537008eb989317ca787c857e23cbd1b3ddf89f190a9b1",
|
||||
"sha256:e926d66f0df8fdbf03ba20583af0f215e475c667fb033d45fd031c66c63e34c9",
|
||||
"sha256:efc3bd48237f973a749f7312f68062f1b4ca5c2032a0673ca3ea8e46aa77187b",
|
||||
"sha256:f59bc782228777cbfe04555707a9c56d269c787ed25d6d28ed9d0fbb41cb1ad2",
|
||||
"sha256:f8da5322f4ff5f667a0d5a27e871b560c6637153c81e318b35cb012b2a98835c"
|
||||
],
|
||||
"version": "==18.0.0"
|
||||
"version": "==18.0.1"
|
||||
},
|
||||
"qtconsole": {
|
||||
"hashes": [
|
||||
@@ -632,10 +661,10 @@
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"hashes": [
|
||||
"sha256:7dede29f121071da9873e7b8c98091874617858e790dc364ffaab4b09d81216c"
|
||||
"sha256:11ead7047ff3f394ed0d4b62aded6c5d970a9b718e1dc6add9f5e79442cc5b14"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.3.0b3"
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"terminado": {
|
||||
"hashes": [
|
||||
@@ -660,9 +689,15 @@
|
||||
},
|
||||
"tornado": {
|
||||
"hashes": [
|
||||
"sha256:d3b719a0cb7094e2b1ca94b31f4b601639fa7ad01a548a1a2ccdd6cbdfd56671"
|
||||
"sha256:1a58f2d603476d5e462f7c28ca1dbb5ac7e51348b27a9cac849cdec3471101f8",
|
||||
"sha256:33f93243cd46dd398e5d2bbdd75539564d1f13f25d704cfc7541db74066d6695",
|
||||
"sha256:34e59401afcecf0381a28228daad8ed3275bcb726810654612d5e9c001f421b7",
|
||||
"sha256:35817031611d2c296c69e5023ea1f9b5720be803e3bb119464bb2a0405d5cd70",
|
||||
"sha256:666b335cef5cc2759c21b7394cff881f71559aaf7cb8c4458af5bb6cb7275b47",
|
||||
"sha256:81203efb26debaaef7158187af45bc440796de9fb1df12a75b65fae11600a255",
|
||||
"sha256:de274c65f45f6656c375cdf1759dbf0bc52902a1e999d12a35eb13020a641a53"
|
||||
],
|
||||
"version": "==6.0b1"
|
||||
"version": "==6.0.1"
|
||||
},
|
||||
"traitlets": {
|
||||
"hashes": [
|
||||
@@ -709,6 +744,29 @@
|
||||
],
|
||||
"version": "==1.24.1"
|
||||
},
|
||||
"uvicorn": {
|
||||
"hashes": [
|
||||
"sha256:8d523d0a003a874245025295b0c1233a762402c0d4c3988017401c6b461c83e9"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"uvloop": {
|
||||
"hashes": [
|
||||
"sha256:198fe0c196056930ec6c4a0a878e531a66d15467ca7c74a875aa90271f0c6e3f",
|
||||
"sha256:1c175f47d34b84e33c0e312f4987c927ea004afc3a5f05d2f0f610d71d0e4c89",
|
||||
"sha256:1c47f197be8f0a3c651dd20be1e1bd43268186246f246d4e86c91e95a89e4865",
|
||||
"sha256:3fd4943570d20e8cd4d9f0a3190ebd5cf040e5610b685e05c878128a11f7ad14",
|
||||
"sha256:435e232869923fd2248e4ca0ad73e24a5b4debf40bed9dcde133cfe1bef98a7a",
|
||||
"sha256:9cfdb966ae804c46b96c92207dfd2174935ffc70e706e42e1c94c60d16dbe860",
|
||||
"sha256:a585781443eeb2edb858f8c08c503aac237a5f1bebf0c84ea8340cc337afa408",
|
||||
"sha256:b296493e033846e46488a6aa227a75c790091f5ee5456ec637bb0badad1e8851",
|
||||
"sha256:c684047c6cf6d697ba37872fb1b4489012ea91f3f802c8fbb9c367c4902e88dc",
|
||||
"sha256:da5a59d8812188b57b5783c7fb78891d14dd1050b6259680e0dbd4253d7d0f64"
|
||||
],
|
||||
"markers": "sys_platform != 'win32' and sys_platform != 'cygwin' and platform_python_implementation != 'pypy'",
|
||||
"version": "==0.12.1"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
@@ -723,6 +781,32 @@
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"websockets": {
|
||||
"hashes": [
|
||||
"sha256:04b42a1b57096ffa5627d6a78ea1ff7fad3bc2c0331ffc17bc32a4024da7fea0",
|
||||
"sha256:08e3c3e0535befa4f0c4443824496c03ecc25062debbcf895874f8a0b4c97c9f",
|
||||
"sha256:10d89d4326045bf5e15e83e9867c85d686b612822e4d8f149cf4840aab5f46e0",
|
||||
"sha256:232fac8a1978fc1dead4b1c2fa27c7756750fb393eb4ac52f6bc87ba7242b2fa",
|
||||
"sha256:4bf4c8097440eff22bc78ec76fe2a865a6e658b6977a504679aaf08f02c121da",
|
||||
"sha256:51642ea3a00772d1e48fb0c492f0d3ae3b6474f34d20eca005a83f8c9c06c561",
|
||||
"sha256:55d86102282a636e195dad68aaaf85b81d0bef449d7e2ef2ff79ac450bb25d53",
|
||||
"sha256:564d2675682bd497b59907d2205031acbf7d3fadf8c763b689b9ede20300b215",
|
||||
"sha256:5d13bf5197a92149dc0badcc2b699267ff65a867029f465accfca8abab95f412",
|
||||
"sha256:5eda665f6789edb9b57b57a159b9c55482cbe5b046d7db458948370554b16439",
|
||||
"sha256:5edb2524d4032be4564c65dc4f9d01e79fe8fad5f966e5b552f4e5164fef0885",
|
||||
"sha256:79691794288bc51e2a3b8de2bc0272ca8355d0b8503077ea57c0716e840ebaef",
|
||||
"sha256:7fcc8681e9981b9b511cdee7c580d5b005f3bb86b65bde2188e04a29f1d63317",
|
||||
"sha256:8e447e05ec88b1b408a4c9cde85aa6f4b04f06aa874b9f0b8e8319faf51b1fee",
|
||||
"sha256:90ea6b3e7787620bb295a4ae050d2811c807d65b1486749414f78cfd6fb61489",
|
||||
"sha256:9e13239952694b8b831088431d15f771beace10edfcf9ef230cefea14f18508f",
|
||||
"sha256:d40f081187f7b54d7a99d8a5c782eaa4edc335a057aa54c85059272ed826dc09",
|
||||
"sha256:e1df1a58ed2468c7b7ce9a2f9752a32ad08eac2bcd56318625c3647c2cd2da6f",
|
||||
"sha256:e98d0cec437097f09c7834a11c69d79fe6241729b23f656cfc227e93294fc242",
|
||||
"sha256:f8d59627702d2ff27cb495ca1abdea8bd8d581de425c56e93bff6517134e0a9b",
|
||||
"sha256:fc30cdf2e949a2225b012a7911d1d031df3d23e99b7eda7dfc982dc4a860dae9"
|
||||
],
|
||||
"version": "==7.0"
|
||||
},
|
||||
"widgetsnbextension": {
|
||||
"hashes": [
|
||||
"sha256:14b2c65f9940c9a7d3b70adbe713dbd38b5ec69724eebaba034d1036cf3d4740",
|
||||
|
||||
14
README.md
14
README.md
@@ -31,10 +31,10 @@ The key features are:
|
||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
||||
|
||||
* **Fast to code**: Increase the speed to develop features by about 200% to 300% *.
|
||||
* **Less bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
|
||||
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
|
||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Less bugs.
|
||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
|
||||
* **Robust**: Get production-ready code. With automatic interactive documentation.
|
||||
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="http://json-schema.org/" target="_blank">JSON Schema</a>.
|
||||
|
||||
@@ -116,17 +116,17 @@ If you don't know, check the _"In a hurry?"_ section about <a href="https://fast
|
||||
Run the server with:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>uvicorn main:app --debug</code>...</summary>
|
||||
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--debug`: make the server restart after code changes. Only do this for development.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -199,7 +199,7 @@ def create_item(item_id: int, item: Item):
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
The server should reload automatically (because you added `--debug` to the `uvicorn` command above).
|
||||
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
|
||||
|
||||
### Interactive API docs upgrade
|
||||
|
||||
@@ -344,7 +344,7 @@ For a more complete example including more features, see the <a href="https://fa
|
||||
|
||||
## Performance
|
||||
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=a979de55-980d-4721-a46f-77298b3f3923&hw=ph&test=fortune&l=zijzen-7" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" target="_blank">Benchmarks</a>.
|
||||
|
||||
|
||||
@@ -377,6 +377,10 @@ All that is what powers FastAPI (through Starlette) and what makes it have such
|
||||
|
||||
When you declare a *path operation function* with normal `def` instead of `async def`, it is run in an external threadpool that is then awaited, instead of being called directly (as it would block the server).
|
||||
|
||||
If you are coming from another async framework that does not work in the way described above and you are used to define trivial compute-only *path operation functions* with plain `def` for a tiny performance gain (about 100 nanoseconds), please note that in **FastAPI** the effect would be quite opposite. In these cases, it's better to use `async def` unless your *path operation functions* use code that performs blocking <abbr title="Input/Output: disk reading or writing, network communications.">IO</abbr>.
|
||||
|
||||
Still, in both situations, chances are that **FastAPI** will <a href="https://fastapi.tiangolo.com/#performance" target="_blank">still be faster</a> than (or at least comparable to) your previous framework.
|
||||
|
||||
### Dependencies
|
||||
|
||||
The same applies for dependencies. If a dependency is a standard `def` function instead of `async def`, it is run in the external threadpool.
|
||||
|
||||
@@ -106,7 +106,7 @@ That way, you can edit the documentation/source files and see the changes live.
|
||||
And if you run the examples with, e.g.:
|
||||
|
||||
```bash
|
||||
uvicorn tutorial001:app --debug
|
||||
uvicorn tutorial001:app --reload
|
||||
```
|
||||
|
||||
as Uvicorn by default will use the port `8000`, the documentation on port `8008` won't clash.
|
||||
|
||||
@@ -26,7 +26,7 @@ But you can still change and update all the configurations with environment vari
|
||||
To see all the configurations and options, go to the Docker image page: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
|
||||
|
||||
|
||||
### Build your Image
|
||||
### Create a `Dockerfile`
|
||||
|
||||
* Go to your project directory.
|
||||
* Create a `Dockerfile` with:
|
||||
@@ -37,6 +37,37 @@ FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
|
||||
COPY ./app /app
|
||||
```
|
||||
|
||||
#### Bigger Applications
|
||||
|
||||
If you followed the section about creating <a href="" target="_blank">Bigger Applications with Multiple Files
|
||||
</a>, your `Dockerfile` might instead look like:
|
||||
|
||||
```Dockerfile
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
|
||||
|
||||
COPY ./app /app/app
|
||||
```
|
||||
|
||||
#### Raspberry Pi and other architectures
|
||||
|
||||
If you are running Docker in a Raspberry Pi (that has an ARM processor) or any other architecture, you can create a `Dockerfile` from scratch, based on a Python base image (that is multi-architecture) and use Uvicorn alone.
|
||||
|
||||
In this case, your `Dockerfile` could look like:
|
||||
|
||||
```Dockerfile
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install fastapi uvicorn
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
### Create the **FastAPI** Code
|
||||
|
||||
* Create an `app` directory and enter in it.
|
||||
* Create a `main.py` file with:
|
||||
|
||||
@@ -65,6 +96,8 @@ def read_item(item_id: int, q: str = None):
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
### Build the Docker image
|
||||
|
||||
* Go to the project directory (in where your `Dockerfile` is, containing your `app` directory).
|
||||
* Build your FastAPI image:
|
||||
|
||||
@@ -72,6 +105,8 @@ def read_item(item_id: int, q: str = None):
|
||||
docker build -t myimage .
|
||||
```
|
||||
|
||||
### Start the Docker container
|
||||
|
||||
* Run a container based on your image:
|
||||
|
||||
```bash
|
||||
@@ -81,18 +116,6 @@ docker run -d --name mycontainer -p 80:80 myimage
|
||||
Now you have an optimized FastAPI server in a Docker container. Auto-tuned for your current server (and number of CPU cores).
|
||||
|
||||
|
||||
#### Bigger Applications
|
||||
|
||||
If you followed the section about creating <a href="" target="_blank">Bigger Applications with Multiple Files
|
||||
</a>, your `Dockerfile` might instead look like:
|
||||
|
||||
```Dockerfile
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
|
||||
|
||||
COPY ./app /app/app
|
||||
```
|
||||
|
||||
|
||||
### Check it
|
||||
|
||||
You should be able to check it in your Docker container's URL, for example: <a href="http://192.168.99.100/items/5?q=somequery" target="_blank">http://192.168.99.100/items/5?q=somequery</a> or <a href="http://127.0.0.1/items/5?q=somequery" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (or equivalent, using your Docker host).
|
||||
@@ -216,7 +239,7 @@ You can deploy **FastAPI** directly without Docker too.
|
||||
|
||||
You just need to install <a href="https://www.uvicorn.org/" target="_blank">Uvicorn</a> (or any other ASGI server).
|
||||
|
||||
And run your application the same way you have done in the tutorials, but without the `--debug` option, e.g.:
|
||||
And run your application the same way you have done in the tutorials, but without the `--reload` option, e.g.:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --host 0.0.0.0 --port 80
|
||||
|
||||
@@ -31,10 +31,10 @@ The key features are:
|
||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
||||
|
||||
* **Fast to code**: Increase the speed to develop features by about 200% to 300% *.
|
||||
* **Less bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
|
||||
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
|
||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Less bugs.
|
||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
|
||||
* **Robust**: Get production-ready code. With automatic interactive documentation.
|
||||
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="http://json-schema.org/" target="_blank">JSON Schema</a>.
|
||||
|
||||
@@ -116,17 +116,17 @@ If you don't know, check the _"In a hurry?"_ section about <a href="https://fast
|
||||
Run the server with:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>uvicorn main:app --debug</code>...</summary>
|
||||
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--debug`: make the server restart after code changes. Only do this for development.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -199,7 +199,7 @@ def create_item(item_id: int, item: Item):
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
The server should reload automatically (because you added `--debug` to the `uvicorn` command above).
|
||||
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
|
||||
|
||||
### Interactive API docs upgrade
|
||||
|
||||
@@ -344,7 +344,7 @@ For a more complete example including more features, see the <a href="https://fa
|
||||
|
||||
## Performance
|
||||
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=a979de55-980d-4721-a46f-77298b3f3923&hw=ph&test=fortune&l=zijzen-7" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" target="_blank">Benchmarks</a>.
|
||||
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
## Next
|
||||
## Next release
|
||||
|
||||
## 0.8.0
|
||||
|
||||
* Make development scripts executable. PR <a href="htthttps://github.com/tiangolo/fastapi/pull/76" target="_blank">#76</a> by <a href="https://github.com/euri10" target="_blank">@euri10</a>.
|
||||
|
||||
* Add support for adding `tags` in `app.include_router()`. PR <a href="https://github.com/tiangolo/fastapi/pull/55" target="_blank">#55</a> by <a href="https://github.com/euri10" target="_blank">@euri10</a>. Documentation updated in the section: <a href="https://fastapi.tiangolo.com/tutorial/bigger-applications/" target="_blank">Bigger Applications</a>.
|
||||
|
||||
* Update docs related to Uvicorn to use new `--reload` option from version `0.5.x`. PR <a href="https://github.com/tiangolo/fastapi/pull/74" target="_blank">#74</a>.
|
||||
|
||||
* Update `isort` imports and scripts to be compatible with newer versions. PR <a href="https://github.com/tiangolo/fastapi/pull/75" target="_blank">#75</a>.
|
||||
|
||||
## 0.7.1
|
||||
|
||||
* Update <a href="https://fastapi.tiangolo.com/async/#path-operation-functions" target="_blank">technical details about `async def` handling</a> with respect to previous frameworks. PR <a href="https://github.com/tiangolo/fastapi/pull/64" target="_blank">#64</a> by <a href="https://github.com/haizaar" target="_blank">@haizaar</a>.
|
||||
|
||||
* Add <a href="https://fastapi.tiangolo.com/deployment/#raspberry-pi-and-other-architectures" target="_blank">deployment documentation for Docker in Raspberry Pi</a> and other architectures.
|
||||
|
||||
* Trigger Docker images build on Travis CI automatically. PR <a href="https://github.com/tiangolo/fastapi/pull/65" target="_blank">#65</a>.
|
||||
|
||||
## 0.7.0
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from fastapi import FastAPI
|
||||
|
||||
from .routers.items import router as items_router
|
||||
from .routers.users import router as users_router
|
||||
from .routers import items
|
||||
from .routers import users
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
app.include_router(users_router)
|
||||
app.include_router(items_router, prefix="/items")
|
||||
app.include_router(users.router)
|
||||
app.include_router(items.router, prefix="/items", tags=["items"])
|
||||
|
||||
@@ -3,11 +3,11 @@ from fastapi import APIRouter
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/", tags=["items"])
|
||||
@router.get("/")
|
||||
async def read_items():
|
||||
return [{"name": "Item Foo"}, {"name": "item Bar"}]
|
||||
|
||||
|
||||
@router.get("/{item_id}", tags=["items"])
|
||||
@router.get("/{item_id}")
|
||||
async def read_item(item_id: str):
|
||||
return {"name": "Fake Specific Item", "item_id": item_id}
|
||||
|
||||
@@ -2,6 +2,8 @@ If you are building an application or a web API, it's rarely the case that you c
|
||||
|
||||
**FastAPI** provides a convenience tool to structure your application while keeping all the flexibility.
|
||||
|
||||
!!! info
|
||||
If you come from Flask, this would be the equivalent of Flask's Blueprints.
|
||||
|
||||
## An example file structure
|
||||
|
||||
@@ -99,13 +101,12 @@ It's all the same structure as with `app/routers/users.py`.
|
||||
|
||||
But let's say that this time we are more lazy.
|
||||
|
||||
And we don't want to have to explicitly type `/items/` in every path operation, we can do it later:
|
||||
And we don't want to have to explicitly type `/items/` and `tags=["items"]` in every *path operation* (we will be able to do it later):
|
||||
|
||||
```Python hl_lines="6 11 16"
|
||||
{!./src/bigger_applications/app/routers/items.py!}
|
||||
```
|
||||
|
||||
|
||||
## The main `FastAPI`
|
||||
|
||||
Now, let's see the module at `app/main.py`.
|
||||
@@ -124,9 +125,9 @@ You import and create a `FastAPI` class as normally:
|
||||
|
||||
### Import the `APIRouter`
|
||||
|
||||
But this time we are not adding path operations directly with the `FastAPI` `app`.
|
||||
But this time we are not adding *path operations* directly with the `FastAPI` `app`.
|
||||
|
||||
We import the `APIRouter`s from the other files:
|
||||
We import the other submodules that have `APIRouter`s:
|
||||
|
||||
```Python hl_lines="3 4"
|
||||
{!./src/bigger_applications/app/main.py!}
|
||||
@@ -140,22 +141,21 @@ As the file `app/routers/items.py` is part of the same Python package, we can im
|
||||
The section:
|
||||
|
||||
```Python
|
||||
from .routers.items import router
|
||||
from .routers import items
|
||||
```
|
||||
|
||||
Means:
|
||||
|
||||
* Starting in the same package that this module (the file `app/main.py`) lives in (the directory `app/`)...
|
||||
* look for the subpackage `routers` (the directory at `app/routers/`)...
|
||||
* and from it, the submodule `items` (the file at `app/routers/items.py`)...
|
||||
* and from that submodule, import the variable `router`.
|
||||
* and from it, import the submodule `items` (the file at `app/routers/items.py`)...
|
||||
|
||||
The variable `router` is the same one we created in the file `app/routers/items.py`. It's an `APIRouter`.
|
||||
The module `items` will have a variable `router` (`items.router`). This is the same one we created in the file `app/routers/items.py`. It's an `APIRouter`.
|
||||
|
||||
We could also import it like:
|
||||
|
||||
```Python
|
||||
from app.routers.items import router
|
||||
from app.routers import items
|
||||
```
|
||||
|
||||
!!! info
|
||||
@@ -168,20 +168,20 @@ from app.routers.items import router
|
||||
|
||||
### Avoid name collisions
|
||||
|
||||
We are importing a variable named `router` from the submodule `items`.
|
||||
We are importing the submodule `items` directly, instead of importing just its variable `router`.
|
||||
|
||||
But we also have another variable named `router` in the submodule `users`.
|
||||
This is because we also have another variable named `router` in the submodule `users`.
|
||||
|
||||
If we import one after the other, like:
|
||||
If we had imported one after the other, like:
|
||||
|
||||
```Python
|
||||
from .routers.items import router
|
||||
from .routers.users import router
|
||||
```
|
||||
|
||||
The `router` from `users` will overwrite the one form `items` and we won't be able to use them at the same time.
|
||||
The `router` from `users` would overwrite the one from `items` and we wouldn't be able to use them at the same time.
|
||||
|
||||
So, to be able to use both of them in the same file, we rename them while importing them using `as`:
|
||||
So, to be able to use both of them in the same file, we import the submodules directly:
|
||||
|
||||
```Python hl_lines="3 4"
|
||||
{!./src/bigger_applications/app/main.py!}
|
||||
@@ -190,18 +190,21 @@ So, to be able to use both of them in the same file, we rename them while import
|
||||
|
||||
### Include an `APIRouter`
|
||||
|
||||
Now, let's include the router from the submodule `users`, now in the variable `users_router`:
|
||||
Now, let's include the `router` from the submodule `users`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!./src/bigger_applications/app/main.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
`users.router` contains the `APIRouter` inside of the file `app/routers/users.py`.
|
||||
|
||||
With `app.include_router()` we can add an `APIRouter` to the main `FastAPI` application.
|
||||
|
||||
It will include all the routes from that router as part of it.
|
||||
|
||||
!!! note "Technical Details"
|
||||
It will actually internally create a path operation for each path operation that was declared in the `APIRouter`.
|
||||
It will actually internally create a *path operation* for each *path operation* that was declared in the `APIRouter`.
|
||||
|
||||
So, behind the scenes, it will actually work as if everything was the same single app.
|
||||
|
||||
@@ -216,23 +219,25 @@ It will include all the routes from that router as part of it.
|
||||
|
||||
### Include an `APIRouter` with a prefix
|
||||
|
||||
Now, let's include the router form the `items` submodule, now in the variable `items_router`.
|
||||
Now, let's include the router form the `items` submodule.
|
||||
|
||||
But, remember that we were lazy and didn't add `/items/` to all the path operations?
|
||||
But, remember that we were lazy and didn't add `/items/` nor `tags` to all the *path operations*?
|
||||
|
||||
We can add a prefix to all the path operations using the parameter `prefix` of `app.include_router()`.
|
||||
|
||||
As the path of each path operation has to start with `/`, like in:
|
||||
|
||||
```Python hl_lines="1"
|
||||
@router.get("/{item_id}", tags=["items"])
|
||||
@router.get("/{item_id}")
|
||||
async def read_item(item_id: str):
|
||||
...
|
||||
```
|
||||
|
||||
...the prefix must not include a final `/`.
|
||||
|
||||
So, the prefix in this case would be `/items`:
|
||||
So, the prefix in this case would be `/items`.
|
||||
|
||||
And we can also add a list of `tags` that will be applied to all the *path operations* included in this router:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!./src/bigger_applications/app/main.py!}
|
||||
@@ -245,8 +250,12 @@ The end result is that the item paths are now:
|
||||
|
||||
...as we intended.
|
||||
|
||||
And they are marked with a list of tags that contain a single string `"items"`.
|
||||
|
||||
These "tags" are especially useful for the automatic interactive documentation systems (using OpenAPI).
|
||||
|
||||
!!! check
|
||||
The `prefix` parameter is (as in many other cases) just a feature from **FastAPI** to help you avoid code duplication.
|
||||
The `prefix` and `tags` parameters are (as in many other cases) just a feature from **FastAPI** to help you avoid code duplication.
|
||||
|
||||
|
||||
!!! tip
|
||||
@@ -274,11 +283,11 @@ The end result is that the item paths are now:
|
||||
Now, run `uvicorn`, using the module `app.main` and the variable `app`:
|
||||
|
||||
```bash
|
||||
uvicorn app.main:app --debug
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
And open the docs at <a href="http://127.0.0.1:8000/docs" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic API docs, including the paths from all the submodules:
|
||||
You will see the automatic API docs, including the paths from all the submodules, using the correct paths (and prefixes) and the correct tags:
|
||||
|
||||
<img src="/img/tutorial/bigger-applications/image01.png">
|
||||
|
||||
@@ -9,7 +9,7 @@ Copy that to a file `main.py`.
|
||||
Run the live server:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
!!! note
|
||||
@@ -17,7 +17,7 @@ uvicorn main:app --debug
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--debug`: make the server restart after code changes. Only use for development.
|
||||
* `--reload`: make the server restart after code changes. Only use for development.
|
||||
|
||||
You will see an output like:
|
||||
|
||||
@@ -146,7 +146,7 @@ This will be the main point of interaction to create all your API.
|
||||
This `app` is the same one referred by `uvicorn` in the command:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
If you create your app like:
|
||||
@@ -158,7 +158,7 @@ If you create your app like:
|
||||
And put it in a file `main.py`, then you would call `uvicorn` like:
|
||||
|
||||
```bash
|
||||
uvicorn main:my_awesome_api --debug
|
||||
uvicorn main:my_awesome_api --reload
|
||||
```
|
||||
|
||||
### Step 3: create a path operation
|
||||
@@ -311,4 +311,4 @@ There are many other objects and models that will be automatically converted to
|
||||
* Create an `app` instance.
|
||||
* Write a **path operation decorator** (like `@app.get("/")`).
|
||||
* Write a **path operation function** (like `def root(): ...` above).
|
||||
* Run the debugging server (like `uvicorn main:app --debug`).
|
||||
* Run the development server (like `uvicorn main:app --reload`).
|
||||
@@ -13,7 +13,7 @@ All the code blocks can be copied and used directly (they are actually tested Py
|
||||
To run any of the examples, copy the code to a file `main.py`, and start `uvicorn` with:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
It is **HIGHLY encouraged** that you write or copy the code, edit it and run it locally.
|
||||
|
||||
@@ -63,8 +63,8 @@ Using `UploadFile` has several advantages over `bytes`:
|
||||
* `write(data)`: Writes `data` (`str` or `bytes`) to the file.
|
||||
* `read(size)`: Reads `size` (`int`) bytes/characters of the file.
|
||||
* `seek(offset)`: Goes to the byte position `offset` (`int`) in the file.
|
||||
* E.g., `myfile.seek(0)` would go to the start of the file.
|
||||
* This is especially useful if you run `myfile.read()` once and then need to read the contents again.
|
||||
* E.g., `await myfile.seek(0)` would go to the start of the file.
|
||||
* This is especially useful if you run `await myfile.read()` once and then need to read the contents again.
|
||||
* `close()`: Closes the file.
|
||||
|
||||
As all these methods are `async` methods, you need to "await" them.
|
||||
|
||||
@@ -27,7 +27,7 @@ Copy the example in a file `main.py`:
|
||||
Run the example with:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
## Check it
|
||||
|
||||
@@ -270,7 +270,7 @@ You can copy it, let's say, to a file `main.py`.
|
||||
Then you can run it with Uvicorn:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
And then, you can open your browser at <a href="http://127.0.0.1:8000/docs" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
@@ -75,7 +75,7 @@ Here you need to make sure you use the same path that you used for the `openapi_
|
||||
Now, run `uvicorn`, if your file is at `main.py`, it would be:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
And open the docs at <a href="http://127.0.0.1:8000/docs" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
@@ -69,7 +69,7 @@ To learn more about the options, check Starlette's documentation for:
|
||||
If your file is named `main.py`, run your application with:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --debug
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000" target="_blank">http://127.0.0.1:8000</a>.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
|
||||
|
||||
__version__ = "0.7.0"
|
||||
__version__ = "0.8.0"
|
||||
|
||||
from .applications import FastAPI
|
||||
from .routing import APIRouter
|
||||
from .params import Body, Path, Query, Header, Cookie, Form, File, Security, Depends
|
||||
from .exceptions import HTTPException
|
||||
from .datastructures import UploadFile
|
||||
from .exceptions import HTTPException
|
||||
from .params import Body, Cookie, Depends, File, Form, Header, Path, Query, Security
|
||||
from .routing import APIRouter
|
||||
|
||||
@@ -176,8 +176,10 @@ class FastAPI(Starlette):
|
||||
|
||||
return decorator
|
||||
|
||||
def include_router(self, router: routing.APIRouter, *, prefix: str = "") -> None:
|
||||
self.router.include_router(router, prefix=prefix)
|
||||
def include_router(
|
||||
self, router: routing.APIRouter, *, prefix: str = "", tags: List[str] = None
|
||||
) -> None:
|
||||
self.router.include_router(router, prefix=prefix, tags=tags)
|
||||
|
||||
def get(
|
||||
self,
|
||||
|
||||
@@ -237,7 +237,9 @@ class APIRouter(routing.Router):
|
||||
|
||||
return decorator
|
||||
|
||||
def include_router(self, router: "APIRouter", *, prefix: str = "") -> None:
|
||||
def include_router(
|
||||
self, router: "APIRouter", *, prefix: str = "", tags: List[str] = None
|
||||
) -> None:
|
||||
if prefix:
|
||||
assert prefix.startswith("/"), "A path prefix must start with '/'"
|
||||
assert not prefix.endswith(
|
||||
@@ -250,7 +252,7 @@ class APIRouter(routing.Router):
|
||||
route.endpoint,
|
||||
response_model=route.response_model,
|
||||
status_code=route.status_code,
|
||||
tags=route.tags or [],
|
||||
tags=(route.tags or []) + (tags or []),
|
||||
summary=route.summary,
|
||||
description=route.description,
|
||||
response_description=route.response_description,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from .api_key import APIKeyQuery, APIKeyHeader, APIKeyCookie
|
||||
from .api_key import APIKeyCookie, APIKeyHeader, APIKeyQuery
|
||||
from .http import (
|
||||
HTTPAuthorizationCredentials,
|
||||
HTTPBasic,
|
||||
HTTPBasicCredentials,
|
||||
HTTPBearer,
|
||||
HTTPDigest,
|
||||
HTTPBasicCredentials,
|
||||
HTTPAuthorizationCredentials,
|
||||
)
|
||||
from .oauth2 import OAuth2PasswordRequestForm, OAuth2, OAuth2PasswordBearer
|
||||
from .oauth2 import OAuth2, OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
from .open_id_connect_url import OpenIdConnect
|
||||
|
||||
0
scripts/build-docs.sh
Normal file → Executable file
0
scripts/build-docs.sh
Normal file → Executable file
0
scripts/docs-live.sh
Normal file → Executable file
0
scripts/docs-live.sh
Normal file → Executable file
2
scripts/lint.sh
Normal file → Executable file
2
scripts/lint.sh
Normal file → Executable file
@@ -3,4 +3,4 @@ set -x
|
||||
|
||||
autoflake --remove-all-unused-imports --recursive --remove-unused-variables --in-place docs/src/ fastapi tests --exclude=__init__.py
|
||||
black fastapi tests docs/src
|
||||
isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --apply fastapi tests docs/src
|
||||
isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --thirdparty fastapi --apply fastapi tests docs/src
|
||||
|
||||
0
scripts/netlify-docs.sh
Normal file → Executable file
0
scripts/netlify-docs.sh
Normal file → Executable file
0
scripts/test-cov-html.sh
Normal file → Executable file
0
scripts/test-cov-html.sh
Normal file → Executable file
@@ -19,4 +19,4 @@ if [ "${PYTHON_VERSION}" = '3.7' ]; then
|
||||
else
|
||||
black fastapi tests --check
|
||||
fi
|
||||
isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --check-only fastapi tests
|
||||
isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --check-only --thirdparty fastapi fastapi tests
|
||||
|
||||
17
scripts/trigger-docker.sh
Executable file
17
scripts/trigger-docker.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
body='{
|
||||
"request": {
|
||||
"branch":"master"
|
||||
}}'
|
||||
|
||||
curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Travis-API-Version: 3" \
|
||||
-H "Authorization: token $TRAVIS_TOKEN" \
|
||||
-d "$body" \
|
||||
https://api.travis-ci.org/repo/tiangolo%2Fuvicorn-gunicorn-fastapi-docker/requests
|
||||
Reference in New Issue
Block a user