16 changed files with 2128 additions and 412 deletions
@ -1,495 +1,495 @@ |
|||||
- name: full-stack-fastapi-template |
- name: full-stack-fastapi-template |
||||
html_url: https://github.com/fastapi/full-stack-fastapi-template |
html_url: https://github.com/fastapi/full-stack-fastapi-template |
||||
stars: 28796 |
stars: 29409 |
||||
owner_login: fastapi |
owner_login: fastapi |
||||
owner_html_url: https://github.com/fastapi |
owner_html_url: https://github.com/fastapi |
||||
- name: Hello-Python |
- name: Hello-Python |
||||
html_url: https://github.com/mouredev/Hello-Python |
html_url: https://github.com/mouredev/Hello-Python |
||||
stars: 27554 |
stars: 28113 |
||||
owner_login: mouredev |
owner_login: mouredev |
||||
owner_html_url: https://github.com/mouredev |
owner_html_url: https://github.com/mouredev |
||||
- name: serve |
- name: serve |
||||
html_url: https://github.com/jina-ai/serve |
html_url: https://github.com/jina-ai/serve |
||||
stars: 21225 |
stars: 21264 |
||||
owner_login: jina-ai |
owner_login: jina-ai |
||||
owner_html_url: https://github.com/jina-ai |
owner_html_url: https://github.com/jina-ai |
||||
- name: sqlmodel |
- name: sqlmodel |
||||
html_url: https://github.com/fastapi/sqlmodel |
html_url: https://github.com/fastapi/sqlmodel |
||||
stars: 14921 |
stars: 15109 |
||||
owner_login: fastapi |
owner_login: fastapi |
||||
owner_html_url: https://github.com/fastapi |
owner_html_url: https://github.com/fastapi |
||||
- name: HivisionIDPhotos |
- name: HivisionIDPhotos |
||||
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos |
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos |
||||
stars: 14025 |
stars: 14564 |
||||
owner_login: Zeyi-Lin |
owner_login: Zeyi-Lin |
||||
owner_html_url: https://github.com/Zeyi-Lin |
owner_html_url: https://github.com/Zeyi-Lin |
||||
- name: Douyin_TikTok_Download_API |
- name: Douyin_TikTok_Download_API |
||||
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API |
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API |
||||
stars: 10001 |
stars: 10701 |
||||
owner_login: Evil0ctal |
owner_login: Evil0ctal |
||||
owner_html_url: https://github.com/Evil0ctal |
owner_html_url: https://github.com/Evil0ctal |
||||
- name: fastapi-best-practices |
- name: fastapi-best-practices |
||||
html_url: https://github.com/zhanymkanov/fastapi-best-practices |
html_url: https://github.com/zhanymkanov/fastapi-best-practices |
||||
stars: 9820 |
stars: 10180 |
||||
owner_login: zhanymkanov |
owner_login: zhanymkanov |
||||
owner_html_url: https://github.com/zhanymkanov |
owner_html_url: https://github.com/zhanymkanov |
||||
- name: awesome-fastapi |
- name: awesome-fastapi |
||||
html_url: https://github.com/mjhea0/awesome-fastapi |
html_url: https://github.com/mjhea0/awesome-fastapi |
||||
stars: 8899 |
stars: 9061 |
||||
owner_login: mjhea0 |
owner_login: mjhea0 |
||||
owner_html_url: https://github.com/mjhea0 |
owner_html_url: https://github.com/mjhea0 |
||||
- name: FastUI |
- name: FastUI |
||||
html_url: https://github.com/pydantic/FastUI |
html_url: https://github.com/pydantic/FastUI |
||||
stars: 8400 |
stars: 8644 |
||||
owner_login: pydantic |
owner_login: pydantic |
||||
owner_html_url: https://github.com/pydantic |
owner_html_url: https://github.com/pydantic |
||||
- name: nonebot2 |
- name: nonebot2 |
||||
html_url: https://github.com/nonebot/nonebot2 |
html_url: https://github.com/nonebot/nonebot2 |
||||
stars: 6235 |
stars: 6312 |
||||
owner_login: nonebot |
owner_login: nonebot |
||||
owner_html_url: https://github.com/nonebot |
owner_html_url: https://github.com/nonebot |
||||
- name: serge |
- name: serge |
||||
html_url: https://github.com/serge-chat/serge |
html_url: https://github.com/serge-chat/serge |
||||
stars: 5685 |
stars: 5686 |
||||
owner_login: serge-chat |
owner_login: serge-chat |
||||
owner_html_url: https://github.com/serge-chat |
owner_html_url: https://github.com/serge-chat |
||||
- name: fastapi-users |
|
||||
html_url: https://github.com/fastapi-users/fastapi-users |
|
||||
stars: 4787 |
|
||||
owner_login: fastapi-users |
|
||||
owner_html_url: https://github.com/fastapi-users |
|
||||
- name: FileCodeBox |
- name: FileCodeBox |
||||
html_url: https://github.com/vastsa/FileCodeBox |
html_url: https://github.com/vastsa/FileCodeBox |
||||
stars: 4479 |
stars: 4933 |
||||
owner_login: vastsa |
owner_login: vastsa |
||||
owner_html_url: https://github.com/vastsa |
owner_html_url: https://github.com/vastsa |
||||
|
- name: fastapi-users |
||||
|
html_url: https://github.com/fastapi-users/fastapi-users |
||||
|
stars: 4849 |
||||
|
owner_login: fastapi-users |
||||
|
owner_html_url: https://github.com/fastapi-users |
||||
- name: hatchet |
- name: hatchet |
||||
html_url: https://github.com/hatchet-dev/hatchet |
html_url: https://github.com/hatchet-dev/hatchet |
||||
stars: 4413 |
stars: 4514 |
||||
owner_login: hatchet-dev |
owner_login: hatchet-dev |
||||
owner_html_url: https://github.com/hatchet-dev |
owner_html_url: https://github.com/hatchet-dev |
||||
- name: chatgpt-web-share |
- name: chatgpt-web-share |
||||
html_url: https://github.com/chatpire/chatgpt-web-share |
html_url: https://github.com/chatpire/chatgpt-web-share |
||||
stars: 4322 |
stars: 4319 |
||||
owner_login: chatpire |
owner_login: chatpire |
||||
owner_html_url: https://github.com/chatpire |
owner_html_url: https://github.com/chatpire |
||||
- name: atrilabs-engine |
- name: polar |
||||
html_url: https://github.com/Atri-Labs/atrilabs-engine |
html_url: https://github.com/polarsource/polar |
||||
stars: 4115 |
stars: 4216 |
||||
owner_login: Atri-Labs |
owner_login: polarsource |
||||
owner_html_url: https://github.com/Atri-Labs |
owner_html_url: https://github.com/polarsource |
||||
- name: strawberry |
- name: strawberry |
||||
html_url: https://github.com/strawberry-graphql/strawberry |
html_url: https://github.com/strawberry-graphql/strawberry |
||||
stars: 4084 |
stars: 4126 |
||||
owner_login: strawberry-graphql |
owner_login: strawberry-graphql |
||||
owner_html_url: https://github.com/strawberry-graphql |
owner_html_url: https://github.com/strawberry-graphql |
||||
|
- name: atrilabs-engine |
||||
|
html_url: https://github.com/Atri-Labs/atrilabs-engine |
||||
|
stars: 4114 |
||||
|
owner_login: Atri-Labs |
||||
|
owner_html_url: https://github.com/Atri-Labs |
||||
- name: dynaconf |
- name: dynaconf |
||||
html_url: https://github.com/dynaconf/dynaconf |
html_url: https://github.com/dynaconf/dynaconf |
||||
stars: 3844 |
stars: 3874 |
||||
owner_login: dynaconf |
owner_login: dynaconf |
||||
owner_html_url: https://github.com/dynaconf |
owner_html_url: https://github.com/dynaconf |
||||
- name: poem |
- name: poem |
||||
html_url: https://github.com/poem-web/poem |
html_url: https://github.com/poem-web/poem |
||||
stars: 3698 |
stars: 3746 |
||||
owner_login: poem-web |
owner_login: poem-web |
||||
owner_html_url: https://github.com/poem-web |
owner_html_url: https://github.com/poem-web |
||||
- name: polar |
|
||||
html_url: https://github.com/polarsource/polar |
|
||||
stars: 3355 |
|
||||
owner_login: polarsource |
|
||||
owner_html_url: https://github.com/polarsource |
|
||||
- name: opyrator |
- name: opyrator |
||||
html_url: https://github.com/ml-tooling/opyrator |
html_url: https://github.com/ml-tooling/opyrator |
||||
stars: 3114 |
stars: 3117 |
||||
owner_login: ml-tooling |
owner_login: ml-tooling |
||||
owner_html_url: https://github.com/ml-tooling |
owner_html_url: https://github.com/ml-tooling |
||||
- name: farfalle |
- name: farfalle |
||||
html_url: https://github.com/rashadphz/farfalle |
html_url: https://github.com/rashadphz/farfalle |
||||
stars: 3022 |
stars: 3094 |
||||
owner_login: rashadphz |
owner_login: rashadphz |
||||
owner_html_url: https://github.com/rashadphz |
owner_html_url: https://github.com/rashadphz |
||||
- name: fastapi-admin |
- name: fastapi-admin |
||||
html_url: https://github.com/fastapi-admin/fastapi-admin |
html_url: https://github.com/fastapi-admin/fastapi-admin |
||||
stars: 3002 |
stars: 3040 |
||||
owner_login: fastapi-admin |
owner_login: fastapi-admin |
||||
owner_html_url: https://github.com/fastapi-admin |
owner_html_url: https://github.com/fastapi-admin |
||||
- name: docarray |
- name: docarray |
||||
html_url: https://github.com/docarray/docarray |
html_url: https://github.com/docarray/docarray |
||||
stars: 2998 |
stars: 3007 |
||||
owner_login: docarray |
owner_login: docarray |
||||
owner_html_url: https://github.com/docarray |
owner_html_url: https://github.com/docarray |
||||
- name: datamodel-code-generator |
- name: datamodel-code-generator |
||||
html_url: https://github.com/koxudaxi/datamodel-code-generator |
html_url: https://github.com/koxudaxi/datamodel-code-generator |
||||
stars: 2845 |
stars: 2914 |
||||
owner_login: koxudaxi |
owner_login: koxudaxi |
||||
owner_html_url: https://github.com/koxudaxi |
owner_html_url: https://github.com/koxudaxi |
||||
- name: fastapi-realworld-example-app |
- name: fastapi-realworld-example-app |
||||
html_url: https://github.com/nsidnev/fastapi-realworld-example-app |
html_url: https://github.com/nsidnev/fastapi-realworld-example-app |
||||
stars: 2832 |
stars: 2840 |
||||
owner_login: nsidnev |
owner_login: nsidnev |
||||
owner_html_url: https://github.com/nsidnev |
owner_html_url: https://github.com/nsidnev |
||||
- name: uvicorn-gunicorn-fastapi-docker |
|
||||
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker |
|
||||
stars: 2727 |
|
||||
owner_login: tiangolo |
|
||||
owner_html_url: https://github.com/tiangolo |
|
||||
- name: WrenAI |
|
||||
html_url: https://github.com/Canner/WrenAI |
|
||||
stars: 2699 |
|
||||
owner_login: Canner |
|
||||
owner_html_url: https://github.com/Canner |
|
||||
- name: LitServe |
- name: LitServe |
||||
html_url: https://github.com/Lightning-AI/LitServe |
html_url: https://github.com/Lightning-AI/LitServe |
||||
stars: 2664 |
stars: 2804 |
||||
owner_login: Lightning-AI |
owner_login: Lightning-AI |
||||
owner_html_url: https://github.com/Lightning-AI |
owner_html_url: https://github.com/Lightning-AI |
||||
|
- name: uvicorn-gunicorn-fastapi-docker |
||||
|
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker |
||||
|
stars: 2730 |
||||
|
owner_login: tiangolo |
||||
|
owner_html_url: https://github.com/tiangolo |
||||
- name: logfire |
- name: logfire |
||||
html_url: https://github.com/pydantic/logfire |
html_url: https://github.com/pydantic/logfire |
||||
stars: 2495 |
stars: 2620 |
||||
owner_login: pydantic |
owner_login: pydantic |
||||
owner_html_url: https://github.com/pydantic |
owner_html_url: https://github.com/pydantic |
||||
- name: huma |
- name: huma |
||||
html_url: https://github.com/danielgtaylor/huma |
html_url: https://github.com/danielgtaylor/huma |
||||
stars: 2479 |
stars: 2567 |
||||
owner_login: danielgtaylor |
owner_login: danielgtaylor |
||||
owner_html_url: https://github.com/danielgtaylor |
owner_html_url: https://github.com/danielgtaylor |
||||
- name: tracecat |
- name: tracecat |
||||
html_url: https://github.com/TracecatHQ/tracecat |
html_url: https://github.com/TracecatHQ/tracecat |
||||
stars: 2446 |
stars: 2494 |
||||
owner_login: TracecatHQ |
owner_login: TracecatHQ |
||||
owner_html_url: https://github.com/TracecatHQ |
owner_html_url: https://github.com/TracecatHQ |
||||
- name: RasaGPT |
|
||||
html_url: https://github.com/paulpierre/RasaGPT |
|
||||
stars: 2378 |
|
||||
owner_login: paulpierre |
|
||||
owner_html_url: https://github.com/paulpierre |
|
||||
- name: best-of-web-python |
- name: best-of-web-python |
||||
html_url: https://github.com/ml-tooling/best-of-web-python |
html_url: https://github.com/ml-tooling/best-of-web-python |
||||
stars: 2374 |
stars: 2433 |
||||
owner_login: ml-tooling |
owner_login: ml-tooling |
||||
owner_html_url: https://github.com/ml-tooling |
owner_html_url: https://github.com/ml-tooling |
||||
|
- name: RasaGPT |
||||
|
html_url: https://github.com/paulpierre/RasaGPT |
||||
|
stars: 2386 |
||||
|
owner_login: paulpierre |
||||
|
owner_html_url: https://github.com/paulpierre |
||||
- name: fastapi-react |
- name: fastapi-react |
||||
html_url: https://github.com/Buuntu/fastapi-react |
html_url: https://github.com/Buuntu/fastapi-react |
||||
stars: 2274 |
stars: 2293 |
||||
owner_login: Buuntu |
owner_login: Buuntu |
||||
owner_html_url: https://github.com/Buuntu |
owner_html_url: https://github.com/Buuntu |
||||
- name: nextpy |
- name: nextpy |
||||
html_url: https://github.com/dot-agent/nextpy |
html_url: https://github.com/dot-agent/nextpy |
||||
stars: 2244 |
stars: 2256 |
||||
owner_login: dot-agent |
owner_login: dot-agent |
||||
owner_html_url: https://github.com/dot-agent |
owner_html_url: https://github.com/dot-agent |
||||
- name: 30-Days-of-Python |
- name: 30-Days-of-Python |
||||
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python |
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python |
||||
stars: 2154 |
stars: 2155 |
||||
owner_login: codingforentrepreneurs |
owner_login: codingforentrepreneurs |
||||
owner_html_url: https://github.com/codingforentrepreneurs |
owner_html_url: https://github.com/codingforentrepreneurs |
||||
- name: FastAPI-template |
- name: FastAPI-template |
||||
html_url: https://github.com/s3rius/FastAPI-template |
html_url: https://github.com/s3rius/FastAPI-template |
||||
stars: 2067 |
stars: 2121 |
||||
owner_login: s3rius |
owner_login: s3rius |
||||
owner_html_url: https://github.com/s3rius |
owner_html_url: https://github.com/s3rius |
||||
- name: langserve |
|
||||
html_url: https://github.com/langchain-ai/langserve |
|
||||
stars: 1980 |
|
||||
owner_login: langchain-ai |
|
||||
owner_html_url: https://github.com/langchain-ai |
|
||||
- name: sqladmin |
- name: sqladmin |
||||
html_url: https://github.com/aminalaee/sqladmin |
html_url: https://github.com/aminalaee/sqladmin |
||||
stars: 1980 |
stars: 2021 |
||||
owner_login: aminalaee |
owner_login: aminalaee |
||||
owner_html_url: https://github.com/aminalaee |
owner_html_url: https://github.com/aminalaee |
||||
|
- name: langserve |
||||
|
html_url: https://github.com/langchain-ai/langserve |
||||
|
stars: 2006 |
||||
|
owner_login: langchain-ai |
||||
|
owner_html_url: https://github.com/langchain-ai |
||||
- name: fastapi-utils |
- name: fastapi-utils |
||||
html_url: https://github.com/fastapiutils/fastapi-utils |
html_url: https://github.com/fastapiutils/fastapi-utils |
||||
stars: 1970 |
stars: 2002 |
||||
owner_login: fastapiutils |
owner_login: fastapiutils |
||||
owner_html_url: https://github.com/fastapiutils |
owner_html_url: https://github.com/fastapiutils |
||||
- name: solara |
- name: solara |
||||
html_url: https://github.com/widgetti/solara |
html_url: https://github.com/widgetti/solara |
||||
stars: 1950 |
stars: 1967 |
||||
owner_login: widgetti |
owner_login: widgetti |
||||
owner_html_url: https://github.com/widgetti |
owner_html_url: https://github.com/widgetti |
||||
- name: python-week-2022 |
|
||||
html_url: https://github.com/rochacbruno/python-week-2022 |
|
||||
stars: 1836 |
|
||||
owner_login: rochacbruno |
|
||||
owner_html_url: https://github.com/rochacbruno |
|
||||
- name: supabase-py |
- name: supabase-py |
||||
html_url: https://github.com/supabase/supabase-py |
html_url: https://github.com/supabase/supabase-py |
||||
stars: 1803 |
stars: 1848 |
||||
owner_login: supabase |
owner_login: supabase |
||||
owner_html_url: https://github.com/supabase |
owner_html_url: https://github.com/supabase |
||||
|
- name: python-week-2022 |
||||
|
html_url: https://github.com/rochacbruno/python-week-2022 |
||||
|
stars: 1832 |
||||
|
owner_login: rochacbruno |
||||
|
owner_html_url: https://github.com/rochacbruno |
||||
- name: mangum |
- name: mangum |
||||
html_url: https://github.com/Kludex/mangum |
html_url: https://github.com/Kludex/mangum |
||||
stars: 1760 |
stars: 1789 |
||||
owner_login: Kludex |
owner_login: Kludex |
||||
owner_html_url: https://github.com/Kludex |
owner_html_url: https://github.com/Kludex |
||||
- name: manage-fastapi |
- name: manage-fastapi |
||||
html_url: https://github.com/ycd/manage-fastapi |
html_url: https://github.com/ycd/manage-fastapi |
||||
stars: 1704 |
stars: 1711 |
||||
owner_login: ycd |
owner_login: ycd |
||||
owner_html_url: https://github.com/ycd |
owner_html_url: https://github.com/ycd |
||||
- name: ormar |
- name: ormar |
||||
html_url: https://github.com/collerek/ormar |
html_url: https://github.com/collerek/ormar |
||||
stars: 1688 |
stars: 1701 |
||||
owner_login: collerek |
owner_login: collerek |
||||
owner_html_url: https://github.com/collerek |
owner_html_url: https://github.com/collerek |
||||
- name: agentkit |
- name: agentkit |
||||
html_url: https://github.com/BCG-X-Official/agentkit |
html_url: https://github.com/BCG-X-Official/agentkit |
||||
stars: 1615 |
stars: 1630 |
||||
owner_login: BCG-X-Official |
owner_login: BCG-X-Official |
||||
owner_html_url: https://github.com/BCG-X-Official |
owner_html_url: https://github.com/BCG-X-Official |
||||
- name: langchain-serve |
- name: langchain-serve |
||||
html_url: https://github.com/jina-ai/langchain-serve |
html_url: https://github.com/jina-ai/langchain-serve |
||||
stars: 1615 |
stars: 1617 |
||||
owner_login: jina-ai |
owner_login: jina-ai |
||||
owner_html_url: https://github.com/jina-ai |
owner_html_url: https://github.com/jina-ai |
||||
- name: termpair |
- name: termpair |
||||
html_url: https://github.com/cs01/termpair |
html_url: https://github.com/cs01/termpair |
||||
stars: 1613 |
stars: 1612 |
||||
owner_login: cs01 |
owner_login: cs01 |
||||
owner_html_url: https://github.com/cs01 |
owner_html_url: https://github.com/cs01 |
||||
- name: coronavirus-tracker-api |
- name: coronavirus-tracker-api |
||||
html_url: https://github.com/ExpDev07/coronavirus-tracker-api |
html_url: https://github.com/ExpDev07/coronavirus-tracker-api |
||||
stars: 1591 |
stars: 1590 |
||||
owner_login: ExpDev07 |
owner_login: ExpDev07 |
||||
owner_html_url: https://github.com/ExpDev07 |
owner_html_url: https://github.com/ExpDev07 |
||||
- name: piccolo |
- name: piccolo |
||||
html_url: https://github.com/piccolo-orm/piccolo |
html_url: https://github.com/piccolo-orm/piccolo |
||||
stars: 1477 |
stars: 1519 |
||||
owner_login: piccolo-orm |
owner_login: piccolo-orm |
||||
owner_html_url: https://github.com/piccolo-orm |
owner_html_url: https://github.com/piccolo-orm |
||||
- name: fastapi-crudrouter |
- name: fastapi-crudrouter |
||||
html_url: https://github.com/awtkns/fastapi-crudrouter |
html_url: https://github.com/awtkns/fastapi-crudrouter |
||||
stars: 1435 |
stars: 1449 |
||||
owner_login: awtkns |
owner_login: awtkns |
||||
owner_html_url: https://github.com/awtkns |
owner_html_url: https://github.com/awtkns |
||||
- name: fastapi-cache |
- name: fastapi-cache |
||||
html_url: https://github.com/long2ice/fastapi-cache |
html_url: https://github.com/long2ice/fastapi-cache |
||||
stars: 1412 |
stars: 1447 |
||||
owner_login: long2ice |
owner_login: long2ice |
||||
owner_html_url: https://github.com/long2ice |
owner_html_url: https://github.com/long2ice |
||||
- name: openapi-python-client |
- name: openapi-python-client |
||||
html_url: https://github.com/openapi-generators/openapi-python-client |
html_url: https://github.com/openapi-generators/openapi-python-client |
||||
stars: 1398 |
stars: 1434 |
||||
owner_login: openapi-generators |
owner_login: openapi-generators |
||||
owner_html_url: https://github.com/openapi-generators |
owner_html_url: https://github.com/openapi-generators |
||||
- name: awesome-fastapi-projects |
- name: awesome-fastapi-projects |
||||
html_url: https://github.com/Kludex/awesome-fastapi-projects |
html_url: https://github.com/Kludex/awesome-fastapi-projects |
||||
stars: 1386 |
stars: 1398 |
||||
owner_login: Kludex |
owner_login: Kludex |
||||
owner_html_url: https://github.com/Kludex |
owner_html_url: https://github.com/Kludex |
||||
- name: awesome-python-resources |
- name: awesome-python-resources |
||||
html_url: https://github.com/DjangoEx/awesome-python-resources |
html_url: https://github.com/DjangoEx/awesome-python-resources |
||||
stars: 1371 |
stars: 1380 |
||||
owner_login: DjangoEx |
owner_login: DjangoEx |
||||
owner_html_url: https://github.com/DjangoEx |
owner_html_url: https://github.com/DjangoEx |
||||
- name: budgetml |
- name: budgetml |
||||
html_url: https://github.com/ebhy/budgetml |
html_url: https://github.com/ebhy/budgetml |
||||
stars: 1342 |
stars: 1344 |
||||
owner_login: ebhy |
owner_login: ebhy |
||||
owner_html_url: https://github.com/ebhy |
owner_html_url: https://github.com/ebhy |
||||
- name: slowapi |
- name: slowapi |
||||
html_url: https://github.com/laurentS/slowapi |
html_url: https://github.com/laurentS/slowapi |
||||
stars: 1289 |
stars: 1339 |
||||
owner_login: laurentS |
owner_login: laurentS |
||||
owner_html_url: https://github.com/laurentS |
owner_html_url: https://github.com/laurentS |
||||
- name: fastapi-pagination |
- name: fastapi-pagination |
||||
html_url: https://github.com/uriyyo/fastapi-pagination |
html_url: https://github.com/uriyyo/fastapi-pagination |
||||
stars: 1240 |
stars: 1263 |
||||
owner_login: uriyyo |
owner_login: uriyyo |
||||
owner_html_url: https://github.com/uriyyo |
owner_html_url: https://github.com/uriyyo |
||||
- name: fastapi-boilerplate |
- name: fastapi-boilerplate |
||||
html_url: https://github.com/teamhide/fastapi-boilerplate |
html_url: https://github.com/teamhide/fastapi-boilerplate |
||||
stars: 1173 |
stars: 1206 |
||||
owner_login: teamhide |
owner_login: teamhide |
||||
owner_html_url: https://github.com/teamhide |
owner_html_url: https://github.com/teamhide |
||||
- name: fastapi-tutorial |
- name: fastapi-tutorial |
||||
html_url: https://github.com/liaogx/fastapi-tutorial |
html_url: https://github.com/liaogx/fastapi-tutorial |
||||
stars: 1162 |
stars: 1178 |
||||
owner_login: liaogx |
owner_login: liaogx |
||||
owner_html_url: https://github.com/liaogx |
owner_html_url: https://github.com/liaogx |
||||
- name: fastapi-amis-admin |
- name: fastapi-amis-admin |
||||
html_url: https://github.com/amisadmin/fastapi-amis-admin |
html_url: https://github.com/amisadmin/fastapi-amis-admin |
||||
stars: 1118 |
stars: 1142 |
||||
owner_login: amisadmin |
owner_login: amisadmin |
||||
owner_html_url: https://github.com/amisadmin |
owner_html_url: https://github.com/amisadmin |
||||
- name: fastapi-code-generator |
- name: fastapi-code-generator |
||||
html_url: https://github.com/koxudaxi/fastapi-code-generator |
html_url: https://github.com/koxudaxi/fastapi-code-generator |
||||
stars: 1095 |
stars: 1119 |
||||
owner_login: koxudaxi |
owner_login: koxudaxi |
||||
owner_html_url: https://github.com/koxudaxi |
owner_html_url: https://github.com/koxudaxi |
||||
- name: bolt-python |
- name: bolt-python |
||||
html_url: https://github.com/slackapi/bolt-python |
html_url: https://github.com/slackapi/bolt-python |
||||
stars: 1086 |
stars: 1116 |
||||
owner_login: slackapi |
owner_login: slackapi |
||||
owner_html_url: https://github.com/slackapi |
owner_html_url: https://github.com/slackapi |
||||
- name: odmantic |
- name: odmantic |
||||
html_url: https://github.com/art049/odmantic |
html_url: https://github.com/art049/odmantic |
||||
stars: 1085 |
stars: 1096 |
||||
owner_login: art049 |
owner_login: art049 |
||||
owner_html_url: https://github.com/art049 |
owner_html_url: https://github.com/art049 |
||||
- name: langchain-extract |
- name: langchain-extract |
||||
html_url: https://github.com/langchain-ai/langchain-extract |
html_url: https://github.com/langchain-ai/langchain-extract |
||||
stars: 1068 |
stars: 1093 |
||||
owner_login: langchain-ai |
owner_login: langchain-ai |
||||
owner_html_url: https://github.com/langchain-ai |
owner_html_url: https://github.com/langchain-ai |
||||
- name: fastapi_production_template |
- name: fastapi_production_template |
||||
html_url: https://github.com/zhanymkanov/fastapi_production_template |
html_url: https://github.com/zhanymkanov/fastapi_production_template |
||||
stars: 1059 |
stars: 1078 |
||||
owner_login: zhanymkanov |
owner_login: zhanymkanov |
||||
owner_html_url: https://github.com/zhanymkanov |
owner_html_url: https://github.com/zhanymkanov |
||||
- name: fastapi-alembic-sqlmodel-async |
- name: fastapi-alembic-sqlmodel-async |
||||
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async |
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async |
||||
stars: 1031 |
stars: 1055 |
||||
owner_login: jonra1993 |
owner_login: jonra1993 |
||||
owner_html_url: https://github.com/jonra1993 |
owner_html_url: https://github.com/jonra1993 |
||||
|
- name: Kokoro-FastAPI |
||||
|
html_url: https://github.com/remsky/Kokoro-FastAPI |
||||
|
stars: 1047 |
||||
|
owner_login: remsky |
||||
|
owner_html_url: https://github.com/remsky |
||||
- name: prometheus-fastapi-instrumentator |
- name: prometheus-fastapi-instrumentator |
||||
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator |
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator |
||||
stars: 1013 |
stars: 1036 |
||||
owner_login: trallnag |
owner_login: trallnag |
||||
owner_html_url: https://github.com/trallnag |
owner_html_url: https://github.com/trallnag |
||||
|
- name: SurfSense |
||||
|
html_url: https://github.com/MODSetter/SurfSense |
||||
|
stars: 1018 |
||||
|
owner_login: MODSetter |
||||
|
owner_html_url: https://github.com/MODSetter |
||||
|
- name: bedrock-claude-chat |
||||
|
html_url: https://github.com/aws-samples/bedrock-claude-chat |
||||
|
stars: 1010 |
||||
|
owner_login: aws-samples |
||||
|
owner_html_url: https://github.com/aws-samples |
||||
- name: runhouse |
- name: runhouse |
||||
html_url: https://github.com/run-house/runhouse |
html_url: https://github.com/run-house/runhouse |
||||
stars: 988 |
stars: 1000 |
||||
owner_login: run-house |
owner_login: run-house |
||||
owner_html_url: https://github.com/run-house |
owner_html_url: https://github.com/run-house |
||||
- name: lanarky |
- name: lanarky |
||||
html_url: https://github.com/ajndkr/lanarky |
html_url: https://github.com/ajndkr/lanarky |
||||
stars: 982 |
stars: 986 |
||||
owner_login: ajndkr |
owner_login: ajndkr |
||||
owner_html_url: https://github.com/ajndkr |
owner_html_url: https://github.com/ajndkr |
||||
- name: autollm |
- name: autollm |
||||
html_url: https://github.com/viddexa/autollm |
html_url: https://github.com/viddexa/autollm |
||||
stars: 981 |
stars: 982 |
||||
owner_login: viddexa |
owner_login: viddexa |
||||
owner_html_url: https://github.com/viddexa |
owner_html_url: https://github.com/viddexa |
||||
- name: bedrock-claude-chat |
|
||||
html_url: https://github.com/aws-samples/bedrock-claude-chat |
|
||||
stars: 977 |
|
||||
owner_login: aws-samples |
|
||||
owner_html_url: https://github.com/aws-samples |
|
||||
- name: SurfSense |
|
||||
html_url: https://github.com/MODSetter/SurfSense |
|
||||
stars: 971 |
|
||||
owner_login: MODSetter |
|
||||
owner_html_url: https://github.com/MODSetter |
|
||||
- name: restish |
- name: restish |
||||
html_url: https://github.com/danielgtaylor/restish |
html_url: https://github.com/danielgtaylor/restish |
||||
stars: 954 |
stars: 970 |
||||
owner_login: danielgtaylor |
owner_login: danielgtaylor |
||||
owner_html_url: https://github.com/danielgtaylor |
owner_html_url: https://github.com/danielgtaylor |
||||
|
- name: fastcrud |
||||
|
html_url: https://github.com/igorbenav/fastcrud |
||||
|
stars: 929 |
||||
|
owner_login: igorbenav |
||||
|
owner_html_url: https://github.com/igorbenav |
||||
- name: secure |
- name: secure |
||||
html_url: https://github.com/TypeError/secure |
html_url: https://github.com/TypeError/secure |
||||
stars: 911 |
stars: 921 |
||||
owner_login: TypeError |
owner_login: TypeError |
||||
owner_html_url: https://github.com/TypeError |
owner_html_url: https://github.com/TypeError |
||||
- name: langcorn |
- name: langcorn |
||||
html_url: https://github.com/msoedov/langcorn |
html_url: https://github.com/msoedov/langcorn |
||||
stars: 909 |
stars: 915 |
||||
owner_login: msoedov |
owner_login: msoedov |
||||
owner_html_url: https://github.com/msoedov |
owner_html_url: https://github.com/msoedov |
||||
- name: energy-forecasting |
|
||||
html_url: https://github.com/iusztinpaul/energy-forecasting |
|
||||
stars: 884 |
|
||||
owner_login: iusztinpaul |
|
||||
owner_html_url: https://github.com/iusztinpaul |
|
||||
- name: vue-fastapi-admin |
- name: vue-fastapi-admin |
||||
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin |
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin |
||||
stars: 863 |
stars: 915 |
||||
owner_login: mizhexiaoxiao |
owner_login: mizhexiaoxiao |
||||
owner_html_url: https://github.com/mizhexiaoxiao |
owner_html_url: https://github.com/mizhexiaoxiao |
||||
|
- name: energy-forecasting |
||||
|
html_url: https://github.com/iusztinpaul/energy-forecasting |
||||
|
stars: 891 |
||||
|
owner_login: iusztinpaul |
||||
|
owner_html_url: https://github.com/iusztinpaul |
||||
- name: authx |
- name: authx |
||||
html_url: https://github.com/yezz123/authx |
html_url: https://github.com/yezz123/authx |
||||
stars: 850 |
stars: 862 |
||||
owner_login: yezz123 |
owner_login: yezz123 |
||||
owner_html_url: https://github.com/yezz123 |
owner_html_url: https://github.com/yezz123 |
||||
- name: titiler |
- name: titiler |
||||
html_url: https://github.com/developmentseed/titiler |
html_url: https://github.com/developmentseed/titiler |
||||
stars: 809 |
stars: 823 |
||||
owner_login: developmentseed |
owner_login: developmentseed |
||||
owner_html_url: https://github.com/developmentseed |
owner_html_url: https://github.com/developmentseed |
||||
- name: marker-api |
- name: marker-api |
||||
html_url: https://github.com/adithya-s-k/marker-api |
html_url: https://github.com/adithya-s-k/marker-api |
||||
stars: 792 |
stars: 798 |
||||
owner_login: adithya-s-k |
owner_login: adithya-s-k |
||||
owner_html_url: https://github.com/adithya-s-k |
owner_html_url: https://github.com/adithya-s-k |
||||
|
- name: FastAPI-boilerplate |
||||
|
html_url: https://github.com/igorbenav/FastAPI-boilerplate |
||||
|
stars: 774 |
||||
|
owner_login: igorbenav |
||||
|
owner_html_url: https://github.com/igorbenav |
||||
- name: fastapi_best_architecture |
- name: fastapi_best_architecture |
||||
html_url: https://github.com/fastapi-practices/fastapi_best_architecture |
html_url: https://github.com/fastapi-practices/fastapi_best_architecture |
||||
stars: 742 |
stars: 766 |
||||
owner_login: fastapi-practices |
owner_login: fastapi-practices |
||||
owner_html_url: https://github.com/fastapi-practices |
owner_html_url: https://github.com/fastapi-practices |
||||
- name: fastapi-mail |
- name: fastapi-mail |
||||
html_url: https://github.com/sabuhish/fastapi-mail |
html_url: https://github.com/sabuhish/fastapi-mail |
||||
stars: 728 |
stars: 735 |
||||
owner_login: sabuhish |
owner_login: sabuhish |
||||
owner_html_url: https://github.com/sabuhish |
owner_html_url: https://github.com/sabuhish |
||||
- name: fastcrud |
|
||||
html_url: https://github.com/igorbenav/fastcrud |
|
||||
stars: 727 |
|
||||
owner_login: igorbenav |
|
||||
owner_html_url: https://github.com/igorbenav |
|
||||
- name: annotated-py-projects |
- name: annotated-py-projects |
||||
html_url: https://github.com/hhstore/annotated-py-projects |
html_url: https://github.com/hhstore/annotated-py-projects |
||||
stars: 722 |
stars: 725 |
||||
owner_login: hhstore |
owner_login: hhstore |
||||
owner_html_url: https://github.com/hhstore |
owner_html_url: https://github.com/hhstore |
||||
- name: FastAPI-boilerplate |
- name: fastapi-do-zero |
||||
html_url: https://github.com/igorbenav/FastAPI-boilerplate |
html_url: https://github.com/dunossauro/fastapi-do-zero |
||||
stars: 716 |
stars: 723 |
||||
owner_login: igorbenav |
owner_login: dunossauro |
||||
owner_html_url: https://github.com/igorbenav |
owner_html_url: https://github.com/dunossauro |
||||
- name: lccn_predictor |
- name: lccn_predictor |
||||
html_url: https://github.com/baoliay2008/lccn_predictor |
html_url: https://github.com/baoliay2008/lccn_predictor |
||||
stars: 707 |
stars: 718 |
||||
owner_login: baoliay2008 |
owner_login: baoliay2008 |
||||
owner_html_url: https://github.com/baoliay2008 |
owner_html_url: https://github.com/baoliay2008 |
||||
|
- name: fastapi-observability |
||||
|
html_url: https://github.com/blueswen/fastapi-observability |
||||
|
stars: 718 |
||||
|
owner_login: blueswen |
||||
|
owner_html_url: https://github.com/blueswen |
||||
- name: chatGPT-web |
- name: chatGPT-web |
||||
html_url: https://github.com/mic1on/chatGPT-web |
html_url: https://github.com/mic1on/chatGPT-web |
||||
stars: 706 |
stars: 708 |
||||
owner_login: mic1on |
owner_login: mic1on |
||||
owner_html_url: https://github.com/mic1on |
owner_html_url: https://github.com/mic1on |
||||
- name: fastapi-do-zero |
- name: learn-generative-ai |
||||
html_url: https://github.com/dunossauro/fastapi-do-zero |
html_url: https://github.com/panaverse/learn-generative-ai |
||||
stars: 702 |
stars: 701 |
||||
owner_login: dunossauro |
owner_login: panaverse |
||||
owner_html_url: https://github.com/dunossauro |
owner_html_url: https://github.com/panaverse |
||||
- name: linbing |
- name: linbing |
||||
html_url: https://github.com/taomujian/linbing |
html_url: https://github.com/taomujian/linbing |
||||
stars: 699 |
stars: 700 |
||||
owner_login: taomujian |
owner_login: taomujian |
||||
owner_html_url: https://github.com/taomujian |
owner_html_url: https://github.com/taomujian |
||||
- name: fastapi-observability |
|
||||
html_url: https://github.com/blueswen/fastapi-observability |
|
||||
stars: 698 |
|
||||
owner_login: blueswen |
|
||||
owner_html_url: https://github.com/blueswen |
|
||||
- name: FastAPI-Backend-Template |
- name: FastAPI-Backend-Template |
||||
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template |
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template |
||||
stars: 682 |
stars: 692 |
||||
owner_login: Aeternalis-Ingenium |
owner_login: Aeternalis-Ingenium |
||||
owner_html_url: https://github.com/Aeternalis-Ingenium |
owner_html_url: https://github.com/Aeternalis-Ingenium |
||||
- name: learn-generative-ai |
- name: starlette-admin |
||||
html_url: https://github.com/panaverse/learn-generative-ai |
html_url: https://github.com/jowilf/starlette-admin |
||||
stars: 673 |
stars: 692 |
||||
owner_login: panaverse |
owner_login: jowilf |
||||
owner_html_url: https://github.com/panaverse |
owner_html_url: https://github.com/jowilf |
||||
- name: fastapi-jwt-auth |
- name: fastapi-jwt-auth |
||||
html_url: https://github.com/IndominusByte/fastapi-jwt-auth |
html_url: https://github.com/IndominusByte/fastapi-jwt-auth |
||||
stars: 668 |
stars: 674 |
||||
owner_login: IndominusByte |
owner_login: IndominusByte |
||||
owner_html_url: https://github.com/IndominusByte |
owner_html_url: https://github.com/IndominusByte |
||||
- name: pity |
- name: pity |
||||
html_url: https://github.com/wuranxu/pity |
html_url: https://github.com/wuranxu/pity |
||||
stars: 660 |
stars: 663 |
||||
owner_login: wuranxu |
owner_login: wuranxu |
||||
owner_html_url: https://github.com/wuranxu |
owner_html_url: https://github.com/wuranxu |
||||
- name: starlette-admin |
|
||||
html_url: https://github.com/jowilf/starlette-admin |
|
||||
stars: 653 |
|
||||
owner_login: jowilf |
|
||||
owner_html_url: https://github.com/jowilf |
|
||||
- name: fastapi_login |
- name: fastapi_login |
||||
html_url: https://github.com/MushroomMaula/fastapi_login |
html_url: https://github.com/MushroomMaula/fastapi_login |
||||
stars: 650 |
stars: 656 |
||||
owner_login: MushroomMaula |
owner_login: MushroomMaula |
||||
owner_html_url: https://github.com/MushroomMaula |
owner_html_url: https://github.com/MushroomMaula |
||||
|
@ -0,0 +1,189 @@ |
|||||
|
# Функціональні можливості |
||||
|
|
||||
|
## Функціональні можливості FastAPI |
||||
|
|
||||
|
**FastAPI** надає вам такі можливості: |
||||
|
|
||||
|
### Використання відкритих стандартів |
||||
|
|
||||
|
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> для створення API, включаючи оголошення <abbr title="також відомі як: endpoints, маршрути">шляхів</abbr>, <abbr title="також відомі як HTTP-методи, наприклад, POST, GET, PUT, DELETE">операцій</abbr>, параметрів, тіл запитів, безпеки тощо. |
||||
|
* Автоматична документація моделей даних за допомогою <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (оскільки OpenAPI базується саме на JSON Schema). |
||||
|
* Розроблено на основі цих стандартів після ретельного аналізу, а не як додатковий рівень поверх основної архітектури. |
||||
|
* Це також дає змогу автоматично **генерувати код клієнта** багатьма мовами. |
||||
|
|
||||
|
### Автоматична генерація документації |
||||
|
|
||||
|
Інтерактивна документація API та вебінтерфейс для його дослідження. Оскільки фреймворк базується на OpenAPI, є кілька варіантів, два з яких включені за замовчуванням. |
||||
|
|
||||
|
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a> — дозволяє інтерактивно переглядати API, викликати та тестувати його прямо у браузері. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* Альтернативна документація API за допомогою <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### Тільки сучасний Python |
||||
|
|
||||
|
FastAPI використовує стандартні **типи Python** (завдяки Pydantic). Вам не потрібно вивчати новий синтаксис — лише стандартний сучасний Python. |
||||
|
|
||||
|
Якщо вам потрібне коротке нагадування про використання типів у Python (навіть якщо ви не використовуєте FastAPI), перегляньте короткий підручник: [Вступ до типів Python](python-types.md){.internal-link target=_blank}. |
||||
|
|
||||
|
Ось приклад стандартного Python-коду з типами: |
||||
|
|
||||
|
```Python |
||||
|
from datetime import date |
||||
|
from pydantic import BaseModel |
||||
|
|
||||
|
# Оголошення змінної як str |
||||
|
# з підтримкою автодоповнення у редакторі |
||||
|
def main(user_id: str): |
||||
|
return user_id |
||||
|
|
||||
|
# Модель Pydantic |
||||
|
class User(BaseModel): |
||||
|
id: int |
||||
|
name: str |
||||
|
joined: date |
||||
|
``` |
||||
|
|
||||
|
Приклад використання цієї моделі: |
||||
|
|
||||
|
```Python |
||||
|
my_user: User = User(id=3, name="John Doe", joined="2018-07-19") |
||||
|
|
||||
|
second_user_data = { |
||||
|
"id": 4, |
||||
|
"name": "Mary", |
||||
|
"joined": "2018-11-30", |
||||
|
} |
||||
|
|
||||
|
my_second_user: User = User(**second_user_data) |
||||
|
``` |
||||
|
|
||||
|
/// info | Інформація |
||||
|
|
||||
|
`**second_user_data` означає: |
||||
|
|
||||
|
Передати ключі та значення словника `second_user_data` як аргументи у вигляді "ключ-значення", еквівалентно `User(id=4, name="Mary", joined="2018-11-30")`. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Підтримка редакторів (IDE) |
||||
|
|
||||
|
Фреймворк спроєктований так, щоб бути легким і інтуїтивно зрозумілим. Усі рішення тестувалися у різних редакторах ще до початку розробки, щоб забезпечити найкращий досвід програмування. |
||||
|
|
||||
|
За результатами опитувань розробників Python <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">однією з найпопулярніших функцій є "автодоповнення"</a>. |
||||
|
|
||||
|
**FastAPI** повністю підтримує автодоповнення у всіх місцях, тому вам рідко доведеться повертатися до документації. |
||||
|
|
||||
|
Приклад автодоповнення у редакторах: |
||||
|
|
||||
|
* у <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* у <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### Короткий код |
||||
|
FastAPI має розумні налаштування **за замовчуванням**, але всі параметри можна налаштовувати відповідно до ваших потреб. Однак за замовчуванням все "просто працює". |
||||
|
|
||||
|
### Валідація |
||||
|
* Підтримка валідації для більшості (або всіх?) **типів даних Python**, зокрема: |
||||
|
* JSON-об'єктів (`dict`). |
||||
|
* JSON-списків (`list`) з визначенням типів елементів. |
||||
|
* Рядків (`str`) із мінімальною та максимальною довжиною. |
||||
|
* Чисел (`int`, `float`) з обмеженнями мінімальних та максимальних значень тощо. |
||||
|
|
||||
|
* Валідація складніших типів, таких як: |
||||
|
* URL. |
||||
|
* Email. |
||||
|
* UUID. |
||||
|
* ...та інші. |
||||
|
|
||||
|
Уся валідація виконується через надійний та перевірений **Pydantic**. |
||||
|
|
||||
|
### Безпека та автентифікація |
||||
|
|
||||
|
**FastAPI** підтримує вбудовану автентифікацію та авторизацію, без прив’язки до конкретних баз даних чи моделей даних. |
||||
|
|
||||
|
Підтримуються всі схеми безпеки OpenAPI, включаючи: |
||||
|
|
||||
|
* HTTP Basic. |
||||
|
* **OAuth2** (також із підтримкою **JWT-токенів**). Див. підручник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. |
||||
|
* Ключі API в: |
||||
|
* Заголовках. |
||||
|
* Параметрах запиту. |
||||
|
* Cookies тощо. |
||||
|
|
||||
|
А також усі можливості безпеки від Starlette (зокрема **сесійні cookies**). |
||||
|
|
||||
|
Усі вони створені як багаторазові інструменти та компоненти, які легко інтегруються з вашими системами, сховищами даних, реляційними та NoSQL базами даних тощо. |
||||
|
|
||||
|
### Впровадження залежностей |
||||
|
|
||||
|
**FastAPI** містить надзвичайно просту у використанні, але потужну систему впровадження залежностей. |
||||
|
|
||||
|
* Залежності можуть мати власні залежності, утворюючи ієрархію або **"граф залежностей"**. |
||||
|
* Усі залежності автоматично керуються фреймворком. |
||||
|
* Усі залежності можуть отримувати дані з запитів і розширювати **обмеження операції за шляхом** та автоматичну документацію. |
||||
|
* **Автоматична валідація** навіть для параметрів *операцій шляху*, визначених у залежностях. |
||||
|
* Підтримка складних систем автентифікації користувачів, **з'єднань із базами даних** тощо. |
||||
|
* **Жодних обмежень** щодо використання баз даних, фронтендів тощо, але водночас проста інтеграція з усіма ними. |
||||
|
|
||||
|
### Немає обмежень на "плагіни" |
||||
|
|
||||
|
Або іншими словами, вони не потрібні – просто імпортуйте та використовуйте необхідний код. |
||||
|
|
||||
|
Будь-яка інтеграція спроєктована настільки просто (з використанням залежностей), що ви можете створити "плагін" для свого застосунку всього у 2 рядках коду, використовуючи ту саму структуру та синтаксис, що й для ваших *операцій шляху*. |
||||
|
|
||||
|
### Протестовано |
||||
|
|
||||
|
* 100% <abbr title="Обсяг коду, що автоматично тестується">покриття тестами</abbr>. |
||||
|
* 100% <abbr title="Анотації типів у Python, завдяки яким ваш редактор і зовнішні інструменти можуть надавати кращу підтримку">анотована типами</abbr> кодова база. |
||||
|
* Використовується у робочих середовищах. |
||||
|
|
||||
|
## Можливості Starlette |
||||
|
|
||||
|
**FastAPI** повністю сумісний із (та побудований на основі) <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Тому будь-який додатковий код Starlette, який ви маєте, також працюватиме. |
||||
|
|
||||
|
**FastAPI** фактично є підкласом **Starlette**. Тому, якщо ви вже знайомі зі Starlette або використовуєте його, більшість функціональності працюватиме так само. |
||||
|
|
||||
|
З **FastAPI** ви отримуєте всі можливості **Starlette** (адже FastAPI — це, по суті, Starlette на стероїдах): |
||||
|
|
||||
|
* Разюча продуктивність. Це <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">один із найшвидших фреймворків на Python</a>, на рівні з **NodeJS** і **Go**. |
||||
|
* Підтримка **WebSocket**. |
||||
|
* Фонові задачі у процесі. |
||||
|
* Події запуску та завершення роботи. |
||||
|
* Клієнт для тестування, побудований на HTTPX. |
||||
|
* Підтримка **CORS**, **GZip**, статичних файлів, потокових відповідей. |
||||
|
* Підтримка **сесій** і **cookie**. |
||||
|
* 100% покриття тестами. |
||||
|
* 100% анотована типами кодова база. |
||||
|
|
||||
|
## Можливості Pydantic |
||||
|
|
||||
|
**FastAPI** повністю сумісний із (та побудований на основі) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Тому будь-який додатковий код Pydantic, який ви маєте, також працюватиме. |
||||
|
|
||||
|
Включаючи зовнішні бібліотеки, побудовані також на Pydantic, такі як <abbr title="Object-Relational Mapper">ORM</abbr>, <abbr title="Object-Document Mapper">ODM</abbr> для баз даних. |
||||
|
|
||||
|
Це також означає, що в багатьох випадках ви можете передати той самий об'єкт, який отримуєте з запиту, **безпосередньо в базу даних**, оскільки все автоматично перевіряється. |
||||
|
|
||||
|
Те ж саме відбувається й у зворотному напрямку — у багатьох випадках ви можете просто передати об'єкт, який отримуєте з бази даних, **безпосередньо клієнту**. |
||||
|
|
||||
|
З **FastAPI** ви отримуєте всі можливості **Pydantic** (адже FastAPI базується на Pydantic для обробки всіх даних): |
||||
|
|
||||
|
* **Ніякої плутанини** : |
||||
|
* Не потрібно вчити нову мову для визначення схем. |
||||
|
* Якщо ви знаєте типи Python, ви знаєте, як використовувати Pydantic. |
||||
|
* Легко працює з вашим **<abbr title="Інтегроване середовище розробки, схоже на редактор коду">IDE</abbr>/<abbr title="Програма, яка перевіряє помилки в коді">лінтером</abbr>/мозком**: |
||||
|
* Оскільки структури даних Pydantic є просто екземплярами класів, які ви визначаєте; автодоповнення, лінтинг, mypy і ваша інтуїція повинні добре працювати з вашими перевіреними даними. |
||||
|
* Валідація **складних структур**: |
||||
|
* Використання ієрархічних моделей Pydantic. Python `typing`, `List` і `Dict` тощо. |
||||
|
* Валідатори дозволяють чітко і просто визначати, перевіряти й документувати складні схеми даних у вигляді JSON-схеми. |
||||
|
* Ви можете мати глибоко **вкладені JSON об'єкти** та перевірити та анотувати їх всі. |
||||
|
* **Розширюваність**: |
||||
|
* Pydantic дозволяє визначати користувацькі типи даних або розширювати валідацію методами в моделі декоратором `validator`. |
||||
|
* 100% покриття тестами. |
@ -0,0 +1,5 @@ |
|||||
|
# Навчання |
||||
|
|
||||
|
У цьому розділі надані вступні та навчальні матеріали для вивчення FastAPI. |
||||
|
|
||||
|
Це можна розглядати як **книгу**, **курс**, або **офіційний** та рекомендований спосіб освоїти FastAPI. 😎 |
@ -0,0 +1,40 @@ |
|||||
|
# Статичні файли |
||||
|
|
||||
|
Ви можете автоматично надавати статичні файли з каталогу, використовуючи `StaticFiles`. |
||||
|
|
||||
|
## Використання `StaticFiles` |
||||
|
|
||||
|
* Імпортуйте `StaticFiles`. |
||||
|
* "Під'єднати" екземпляр `StaticFiles()` з вказанням необхідного шляху. |
||||
|
|
||||
|
{* ../../docs_src/static_files/tutorial001.py hl[2,6] *} |
||||
|
|
||||
|
/// note | Технічні деталі |
||||
|
|
||||
|
Ви також можете використовувати `from starlette.staticfiles import StaticFiles`. |
||||
|
|
||||
|
**FastAPI** надає той самий `starlette.staticfiles`, що й `fastapi.staticfiles` для зручності розробників. Але фактично він безпосередньо походить із Starlette. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Що таке "Під'єднання" |
||||
|
|
||||
|
"Під'єднання" означає додавання повноцінного "незалежного" застосунку за певним шляхом, який потім обробляє всі під шляхи. |
||||
|
|
||||
|
Це відрізняється від використання `APIRouter`, оскільки під'єднаний застосунок є повністю незалежним. OpenAPI та документація вашого основного застосунку не будуть знати нічого про ваш під'єднаний застосунок. |
||||
|
|
||||
|
Ви можете дізнатися більше про це в [Посібнику для просунутих користувачів](../advanced/index.md){.internal-link target=_blank}. |
||||
|
|
||||
|
## Деталі |
||||
|
|
||||
|
Перше `"/static"` вказує на під шлях, за яким буде "під'єднано" цей новий "застосунок". Тому будь-який шлях, який починається з `"/static"`, буде оброблятися ним. |
||||
|
|
||||
|
`directory="static"` визначає каталог, що містить ваші статичні файли. |
||||
|
|
||||
|
`name="static"` це ім'я, яке можна використовувати всередині **FastAPI**. |
||||
|
|
||||
|
Усі ці параметри можуть бути змінені відповідно до потреб і особливостей вашого застосунку. |
||||
|
|
||||
|
## Додаткова інформація |
||||
|
|
||||
|
Детальніше про налаштування та можливості можна дізнатися в <a href="https://www.starlette.io/staticfiles/" class="external-link" target="_blank">документації Starlette про статичні файли</a>. |
@ -0,0 +1,300 @@ |
|||||
|
# Biến môi trường (Environment Variables) |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Nếu bạn đã biết về "biến môi trường" và cách sử dụng chúng, bạn có thể bỏ qua phần này. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Một biến môi trường (còn được gọi là "**env var**") là một biến mà tồn tại **bên ngoài** đoạn mã Python, ở trong **hệ điều hành**, và có thể được đọc bởi đoạn mã Python của bạn (hoặc bởi các chương trình khác). |
||||
|
|
||||
|
Các biến môi trường có thể được sử dụng để xử lí **các thiết lập** của ứng dụng, như một phần của **các quá trình cài đặt** Python, v.v. |
||||
|
|
||||
|
## Tạo và Sử dụng các Biến Môi Trường |
||||
|
|
||||
|
Bạn có thể **tạo** và sử dụng các biến môi trường trong **shell (terminal)**, mà không cần sử dụng Python: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Bạn có thể tạo một biến môi trường MY_NAME với |
||||
|
$ export MY_NAME="Wade Wilson" |
||||
|
|
||||
|
// Sau đó bạn có thể sử dụng nó với các chương trình khác, như |
||||
|
$ echo "Hello $MY_NAME" |
||||
|
|
||||
|
Hello Wade Wilson |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Tạo một biến môi trường MY_NAME |
||||
|
$ $Env:MY_NAME = "Wade Wilson" |
||||
|
|
||||
|
// Sử dụng nó với các chương trình khác, như là |
||||
|
$ echo "Hello $Env:MY_NAME" |
||||
|
|
||||
|
Hello Wade Wilson |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Đọc các Biến Môi Trường trong Python |
||||
|
|
||||
|
Bạn cũng có thể tạo các biến môi trường **bên ngoài** đoạn mã Python, trong terminal (hoặc bằng bất kỳ phương pháp nào khác), và sau đó **đọc chúng trong Python**. |
||||
|
|
||||
|
Ví dụ, bạn có một file `main.py` với: |
||||
|
|
||||
|
```Python hl_lines="3" |
||||
|
import os |
||||
|
|
||||
|
name = os.getenv("MY_NAME", "World") |
||||
|
print(f"Hello {name} from Python") |
||||
|
``` |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Tham số thứ hai cho <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> là giá trị mặc định để trả về. |
||||
|
|
||||
|
Nếu không được cung cấp, nó mặc định là `None`, ở đây chúng ta cung cấp `"World"` là giá trị mặc định để sử dụng. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Sau đó bạn có thể gọi chương trình Python: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Ở đây chúng ta chưa cài đặt biến môi trường |
||||
|
$ python main.py |
||||
|
|
||||
|
// Vì chúng ta chưa cài đặt biến môi trường, chúng ta nhận được giá trị mặc định |
||||
|
|
||||
|
Hello World from Python |
||||
|
|
||||
|
// Nhưng nếu chúng ta tạo một biến môi trường trước đó |
||||
|
$ export MY_NAME="Wade Wilson" |
||||
|
|
||||
|
// Và sau đó gọi chương trình lại |
||||
|
$ python main.py |
||||
|
|
||||
|
// Bây giờ nó có thể đọc biến môi trường |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Ở đây chúng ta chưa cài đặt biến môi trường |
||||
|
$ python main.py |
||||
|
|
||||
|
// Vì chúng ta chưa cài đặt biến môi trường, chúng ta nhận được giá trị mặc định |
||||
|
|
||||
|
Hello World from Python |
||||
|
|
||||
|
// Nhưng nếu chúng ta tạo một biến môi trường trước đó |
||||
|
$ $Env:MY_NAME = "Wade Wilson" |
||||
|
|
||||
|
// Và sau đó gọi chương trình lại |
||||
|
$ python main.py |
||||
|
|
||||
|
// Bây giờ nó có thể đọc biến môi trường |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Vì các biến môi trường có thể được tạo bên ngoài đoạn mã Python, nhưng có thể được đọc bởi đoạn mã Python, và không cần được lưu trữ (commit vào `git`) cùng với các file khác, nên chúng thường được sử dụng để lưu các thiết lập hoặc **cấu hình**. |
||||
|
|
||||
|
Bạn cũng có thể tạo ra một biến môi trường dành riêng cho một **lần gọi chương trình**, chỉ có thể được sử dụng bởi chương trình đó, và chỉ trong thời gian chạy của chương trình. |
||||
|
|
||||
|
Để làm điều này, tạo nó ngay trước chương trình đó, trên cùng một dòng: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Tạo một biến môi trường MY_NAME cho lần gọi chương trình này |
||||
|
$ MY_NAME="Wade Wilson" python main.py |
||||
|
|
||||
|
// Bây giờ nó có thể đọc biến môi trường |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
|
||||
|
// Biến môi trường không còn tồn tại sau đó |
||||
|
$ python main.py |
||||
|
|
||||
|
Hello World from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Bạn có thể đọc thêm về điều này tại <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Các Kiểu (Types) và Kiểm tra (Validation) |
||||
|
|
||||
|
Các biến môi trường có thể chỉ xử lí **chuỗi ký tự**, vì chúng nằm bên ngoài đoạn mã Python và phải tương thích với các chương trình khác và phần còn lại của hệ thống (và thậm chí với các hệ điều hành khác, như Linux, Windows, macOS). |
||||
|
|
||||
|
Điều này có nghĩa là **bất kỳ giá trị nào** được đọc trong Python từ một biến môi trường **sẽ là một `str`**, và bất kỳ hành động chuyển đổi sang kiểu dữ liệu khác hoặc hành động kiểm tra nào cũng phải được thực hiện trong đoạn mã. |
||||
|
|
||||
|
Bạn sẽ học thêm về việc sử dụng biến môi trường để xử lí **các thiết lập ứng dụng** trong [Hướng dẫn nâng cao - Các thiết lập và biến môi trường](./advanced/settings.md){.internal-link target=_blank}. |
||||
|
|
||||
|
## Biến môi trường `PATH` |
||||
|
|
||||
|
Có một biến môi trường **đặc biệt** được gọi là **`PATH`** được sử dụng bởi các hệ điều hành (Linux, macOS, Windows) nhằm tìm các chương trình để thực thi. |
||||
|
|
||||
|
Giá trị của biến môi trường `PATH` là một chuỗi dài được tạo bởi các thư mục được phân tách bởi dấu hai chấm `:` trên Linux và macOS, và bởi dấu chấm phẩy `;` trên Windows. |
||||
|
|
||||
|
Ví dụ, biến môi trường `PATH` có thể có dạng như sau: |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
```plaintext |
||||
|
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin |
||||
|
``` |
||||
|
|
||||
|
Điều này có nghĩa là hệ thống sẽ tìm kiếm các chương trình trong các thư mục: |
||||
|
|
||||
|
* `/usr/local/bin` |
||||
|
* `/usr/bin` |
||||
|
* `/bin` |
||||
|
* `/usr/sbin` |
||||
|
* `/sbin` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 |
||||
|
``` |
||||
|
|
||||
|
Điều này có nghĩa là hệ thống sẽ tìm kiếm các chương trình trong các thư mục: |
||||
|
|
||||
|
* `C:\Program Files\Python312\Scripts` |
||||
|
* `C:\Program Files\Python312` |
||||
|
* `C:\Windows\System32` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Khi bạn gõ một **lệnh** trong terminal, hệ điều hành **tìm kiếm** chương trình trong **mỗi thư mục** được liệt kê trong biến môi trường `PATH`. |
||||
|
|
||||
|
Ví dụ, khi bạn gõ `python` trong terminal, hệ điều hành tìm kiếm một chương trình được gọi `python` trong **thư mục đầu tiên** trong danh sách đó. |
||||
|
|
||||
|
Nếu tìm thấy, nó sẽ **sử dụng** nó. Nếu không tìm thấy, nó sẽ tiếp tục tìm kiếm trong **các thư mục khác**. |
||||
|
|
||||
|
### Cài đặt Python và cập nhật biến môi trường `PATH` |
||||
|
|
||||
|
Khi bạn cài đặt Python, bạn có thể được hỏi nếu bạn muốn cập nhật biến môi trường `PATH`. |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
Giả sử bạn cài đặt Python vào thư mục `/opt/custompython/bin`. |
||||
|
|
||||
|
Nếu bạn chọn cập nhật biến môi trường `PATH`, thì cài đặt sẽ thêm `/opt/custompython/bin` vào biến môi trường `PATH`. |
||||
|
|
||||
|
Nó có thể có dạng như sau: |
||||
|
|
||||
|
```plaintext |
||||
|
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin |
||||
|
``` |
||||
|
|
||||
|
Như vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong `/opt/custompython/bin` (thư mục cuối) và sử dụng nó. |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
Giả sử bạn cài đặt Python vào thư mục `C:\opt\custompython\bin`. |
||||
|
|
||||
|
Nếu bạn chọn cập nhật biến môi trường `PATH`, thì cài đặt sẽ thêm `C:\opt\custompython\bin` vào biến môi trường `PATH`. |
||||
|
|
||||
|
Nó có thể có dạng như sau: |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin |
||||
|
``` |
||||
|
|
||||
|
Như vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong `C:\opt\custompython\bin` (thư mục cuối) và sử dụng nó. |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Vậy, nếu bạn gõ: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
Hệ thống sẽ **tìm kiếm** chương trình `python` trong `/opt/custompython/bin` và thực thi nó. |
||||
|
|
||||
|
Nó tương đương với việc bạn gõ: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ /opt/custompython/bin/python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
Hệ thống sẽ **tìm kiếm** chương trình `python` trong `C:\opt\custompython\bin\python` và thực thi nó. |
||||
|
|
||||
|
Nó tương đương với việc bạn gõ: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ C:\opt\custompython\bin\python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Thông tin này sẽ hữu ích khi bạn học về [Môi trường ảo](virtual-environments.md){.internal-link target=_blank}. |
||||
|
|
||||
|
## Kết luận |
||||
|
|
||||
|
Với những thông tin này, bạn có thể hiểu được **các biến môi trường là gì** và **cách sử dụng chúng trong Python**. |
||||
|
|
||||
|
Bạn có thể đọc thêm về chúng tại <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia cho Biến môi trường</a>. |
||||
|
|
||||
|
Trong nhiều trường hợp, cách các biến môi trường trở nên hữu ích và có thể áp dụng không thực sự rõ ràng ngay từ đầu, nhưng chúng sẽ liên tục xuất hiện trong rất nhiều tình huống khi bạn phát triển ứng dụng, vì vậy việc hiểu biết về chúng là hữu ích. |
||||
|
|
||||
|
Chẳng hạn, bạn sẽ cần những thông tin này khi bạn học về [Môi trường ảo](virtual-environments.md). |
@ -0,0 +1,75 @@ |
|||||
|
# FastAPI CLI |
||||
|
|
||||
|
**FastAPI CLI** là một chương trình dòng lệnh có thể được sử dụng để phục vụ ứng dụng FastAPI của bạn, quản lý dự án FastAPI của bạn và nhiều hoạt động khác. |
||||
|
|
||||
|
Khi bạn cài đặt FastAPI (vd với `pip install "fastapi[standard]"`), nó sẽ bao gồm một gói được gọi là `fastapi-cli`, gói này cung cấp lệnh `fastapi` trong terminal. |
||||
|
|
||||
|
Để chạy ứng dụng FastAPI của bạn cho quá trình phát triển (development), bạn có thể sử dụng lệnh `fastapi dev`: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u> |
||||
|
|
||||
|
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀 |
||||
|
|
||||
|
Searching for package file structure from directories with |
||||
|
<font color="#3465A4">__init__.py</font> files |
||||
|
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with the |
||||
|
following code: |
||||
|
|
||||
|
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span> Running in development mode, for production use: |
||||
|
<b>fastapi run</b> |
||||
|
|
||||
|
Logs: |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Will watch for changes in these directories: |
||||
|
<b>[</b><font color="#4E9A06">'/home/user/code/awesomeapp'</font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C to |
||||
|
quit<b>)</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Chương trình dòng lệnh `fastapi` là **FastAPI CLI**. |
||||
|
|
||||
|
FastAPI CLI nhận đường dẫn đến chương trình Python của bạn (vd `main.py`) và tự động phát hiện đối tượng `FastAPI` (thường được gọi là `app`), xác định quá trình nhập đúng, và sau đó chạy nó (serve). |
||||
|
|
||||
|
Đối với vận hành thực tế (production), bạn sẽ sử dụng `fastapi run` thay thế. 🚀 |
||||
|
|
||||
|
Ở bên trong, **FastAPI CLI** sử dụng <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>, một server ASGI có hiệu suất cao, sẵn sàng cho vận hành thực tế (production). 😎 |
||||
|
|
||||
|
## `fastapi dev` |
||||
|
|
||||
|
Chạy `fastapi dev` sẽ khởi động quá trình phát triển. |
||||
|
|
||||
|
Mặc định, **auto-reload** được bật, tự động tải lại server khi bạn thay đổi code của bạn. Điều này tốn nhiều tài nguyên và có thể kém ổn định hơn khi nó bị tắt. Bạn nên sử dụng nó cho quá trình phát triển. Nó cũng lắng nghe địa chỉ IP `127.0.0.1`, đó là địa chỉ IP của máy tính để tự giao tiếp với chính nó (`localhost`). |
||||
|
|
||||
|
## `fastapi run` |
||||
|
|
||||
|
Chạy `fastapi run` mặc định sẽ khởi động FastAPI cho quá trình vận hành thực tế. |
||||
|
|
||||
|
Mặc định, **auto-reload** bị tắt. Nó cũng lắng nghe địa chỉ IP `0.0.0.0`, đó là tất cả các địa chỉ IP có sẵn, như vậy nó sẽ được truy cập công khai bởi bất kỳ ai có thể giao tiếp với máy tính. Đây là cách bạn thường chạy nó trong sản phẩm hoàn thiện, ví dụ trong một container. |
||||
|
|
||||
|
Trong hầu hết các trường hợp, bạn sẽ (và nên) có một "proxy điểm cuối (termination proxy)" xử lý HTTPS cho bạn, điều này sẽ phụ thuộc vào cách bạn triển khai ứng dụng của bạn, nhà cung cấp có thể làm điều này cho bạn, hoặc bạn có thể cần thiết lập nó. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Bạn có thể tìm hiểu thêm về FastAPI CLI trong [tài liệu triển khai](deployment/index.md){.internal-link target=_blank}. |
||||
|
|
||||
|
/// |
@ -0,0 +1,842 @@ |
|||||
|
# Môi trường ảo (Virtual Environments) |
||||
|
|
||||
|
Khi bạn làm việc trong các dự án Python, bạn có thể sử dụng một **môi trường ảo** (hoặc một cơ chế tương tự) để cách ly các gói bạn cài đặt cho mỗi dự án. |
||||
|
|
||||
|
/// info |
||||
|
Nếu bạn đã biết về các môi trường ảo, cách tạo chúng và sử dụng chúng, bạn có thể bỏ qua phần này. 🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Một **môi trường ảo** khác với một **biến môi trường (environment variable)**. |
||||
|
|
||||
|
Một **biến môi trường** là một biến trong hệ thống có thể được sử dụng bởi các chương trình. |
||||
|
|
||||
|
Một **môi trường ảo** là một thư mục với một số tệp trong đó. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// info |
||||
|
|
||||
|
Trang này sẽ hướng dẫn bạn cách sử dụng các **môi trường ảo** và cách chúng hoạt động. |
||||
|
|
||||
|
Nếu bạn đã sẵn sàng sử dụng một **công cụ có thể quản lý tất cả mọi thứ** cho bạn (bao gồm cả việc cài đặt Python), hãy thử <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Tạo một Dự án |
||||
|
|
||||
|
Đầu tiên, tạo một thư mục cho dự án của bạn. |
||||
|
|
||||
|
Cách tôi thường làm là tạo một thư mục có tên `code` trong thư mục `home/user`. |
||||
|
|
||||
|
Và trong thư mục đó, tôi tạo một thư mục cho mỗi dự án. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Đi đến thư mục home |
||||
|
$ cd |
||||
|
// Tạo một thư mục cho tất cả các dự án của bạn |
||||
|
$ mkdir code |
||||
|
// Vào thư mục code |
||||
|
$ cd code |
||||
|
// Tạo một thư mục cho dự án này |
||||
|
$ mkdir awesome-project |
||||
|
// Vào thư mục dự án |
||||
|
$ cd awesome-project |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## Tạo một Môi trường ảo |
||||
|
|
||||
|
Khi bạn bắt đầu làm việc với một dự án Python **trong lần đầu**, hãy tạo một môi trường ảo **<abbr title="có nhiều cách thực hiện khác nhau, đây là một hướng dẫn đơn giản">trong thư mục dự án của bạn</abbr>**. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Bạn cần làm điều này **một lần cho mỗi dự án**, không phải mỗi khi bạn làm việc. |
||||
|
/// |
||||
|
|
||||
|
//// tab | `venv` |
||||
|
|
||||
|
Để tạo một môi trường ảo, bạn có thể sử dụng module `venv` có sẵn của Python. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python -m venv .venv |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// details | Cách các lệnh hoạt động |
||||
|
|
||||
|
* `python`: sử dụng chương trình `python` |
||||
|
* `-m`: gọi một module như một script, chúng ta sẽ nói về module đó sau |
||||
|
* `venv`: sử dụng module `venv` được cài đặt sẵn của Python |
||||
|
* `.venv`: tạo môi trường ảo trong thư mục mới `.venv` |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | `uv` |
||||
|
|
||||
|
Nếu bạn có <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> được cài đặt, bạn có thể sử dụng nó để tạo một môi trường ảo. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uv venv |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Mặc định, `uv` sẽ tạo một môi trường ảo trong một thư mục có tên `.venv`. |
||||
|
|
||||
|
Nhưng bạn có thể tùy chỉnh nó bằng cách thêm một đối số với tên thư mục. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Lệnh này tạo một môi trường ảo mới trong một thư mục có tên `.venv`. |
||||
|
|
||||
|
/// details | `.venv` hoặc tên khác |
||||
|
|
||||
|
Bạn có thể tạo môi trường ảo trong một thư mục khác, nhưng thường người ta quy ước đặt nó là `.venv`. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Kích hoạt Môi trường ảo |
||||
|
|
||||
|
Kích hoạt môi trường ảo mới để bất kỳ lệnh Python nào bạn chạy hoặc gói nào bạn cài đặt sẽ sử dụng nó. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Làm điều này **mỗi khi** bạn bắt đầu một **phiên terminal mới** để làm việc trên dự án. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ source .venv/bin/activate |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ .venv\Scripts\Activate.ps1 |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows Bash |
||||
|
|
||||
|
Nếu bạn sử dụng Bash cho Windows (ví dụ: <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>): |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ source .venv/Scripts/activate |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Mỗi khi bạn cài đặt thêm một **package mới** trong môi trường đó, hãy **kích hoạt** môi trường đó lại. |
||||
|
|
||||
|
Điều này đảm bảo rằng khi bạn sử dụng một **chương trình dòng lệnh (<abbr title="command line interface">CLI</abbr>)** được cài đặt từ gói đó, bạn sẽ dùng bản cài đặt từ môi trường ảo của mình thay vì bản được cài đặt toàn cục khác có thể có phiên bản khác với phiên bản bạn cần. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Kiểm tra xem Môi trường ảo đã được Kích hoạt chưa |
||||
|
|
||||
|
Kiểm tra xem môi trường ảo đã được kích hoạt chưa (lệnh trước đó đã hoạt động). |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Điều này là **không bắt buộc**, nhưng nó là một cách tốt để **kiểm tra** rằng mọi thứ đang hoạt động như mong đợi và bạn đang sử dụng đúng môi trường ảo mà bạn đã định. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ which python |
||||
|
|
||||
|
/home/user/code/awesome-project/.venv/bin/python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Nếu nó hiển thị `python` binary tại `.venv/bin/python`, trong dự án của bạn (trong trường hợp `awesome-project`), thì tức là nó hoạt động. 🎉 |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ Get-Command python |
||||
|
|
||||
|
C:\Users\user\code\awesome-project\.venv\Scripts\python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Nếu nó hiển thị `python` binary tại `.venv\Scripts\python`, trong dự án của bạn (trong trường hợp `awesome-project`), thì tức là nó hoạt động. 🎉 |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Nâng cấp `pip` |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Nếu bạn sử dụng <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> bạn sử dụng nó để cài đặt thay vì `pip`, thì bạn không cần cập nhật `pip`. 😎 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Nếu bạn sử dụng `pip` để cài đặt gói (nó được cài đặt mặc định với Python), bạn nên **nâng cấp** nó lên phiên bản mới nhất. |
||||
|
|
||||
|
Nhiều lỗi khác nhau trong khi cài đặt gói được giải quyết chỉ bằng cách nâng cấp `pip` trước. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Bạn thường làm điều này **một lần**, ngay sau khi bạn tạo môi trường ảo. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Đảm bảo rằng môi trường ảo đã được kích hoạt (với lệnh trên) và sau đó chạy: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python -m pip install --upgrade pip |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## Thêm `.gitignore` |
||||
|
|
||||
|
Nếu bạn sử dụng **Git** (nên làm), hãy thêm một file `.gitignore` để Git bỏ qua mọi thứ trong `.venv`. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Nếu bạn sử dụng <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> để tạo môi trường ảo, nó đã tự động làm điều này cho bạn, bạn có thể bỏ qua bước này. 😎 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Làm điều này **một lần**, ngay sau khi bạn tạo môi trường ảo. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ echo "*" > .venv/.gitignore |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// details | Cách lệnh hoạt động |
||||
|
|
||||
|
* `echo "*"`: sẽ "in" văn bản `*` trong terminal (phần tiếp theo sẽ thay đổi điều đó một chút) |
||||
|
* `>`: bất kỳ văn bản nào được in ra terminal bởi lệnh trước `>` không được in ra mà thay vào đó được viết vào file ở phía bên phải của `>` |
||||
|
* `.gitignore`: tên của file mà văn bản sẽ được viết vào |
||||
|
|
||||
|
Và `*` với Git có nghĩa là "mọi thứ". Vì vậy, nó sẽ bỏ qua mọi thứ trong thư mục `.venv`. |
||||
|
|
||||
|
Lệnh này sẽ tạo một file `.gitignore` với nội dung: |
||||
|
|
||||
|
```gitignore |
||||
|
* |
||||
|
``` |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Cài đặt gói (packages) |
||||
|
|
||||
|
Sau khi kích hoạt môi trường, bạn có thể cài đặt các gói trong đó. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Thực hiện điều này **một lần** khi cài đặt hoặc cập nhật gói cần thiết cho dự án của bạn. |
||||
|
|
||||
|
Nếu bạn cần cập nhật phiên bản hoặc thêm một gói mới, bạn sẽ **thực hiện điều này lại**. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Cài đặt gói trực tiếp |
||||
|
|
||||
|
Nếu bạn cần cập nhật phiên bản hoặc thêm một gói mới, bạn sẽ **thực hiện điều này lại**. |
||||
|
|
||||
|
/// tip |
||||
|
Để quản lý dự án tốt hơn, hãy liệt kê tất cả các gói và phiên bản cần thiết trong một file (ví dụ `requirements.txt` hoặc `pyproject.toml`). |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
//// tab | `pip` |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "fastapi[standard]" |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | `uv` |
||||
|
|
||||
|
Nếu bạn có <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uv pip install "fastapi[standard]" |
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
### Cài đặt từ `requirements.txt` |
||||
|
|
||||
|
Nếu bạn có một tệp `requirements.txt`, bạn có thể sử dụng nó để cài đặt các gói. |
||||
|
|
||||
|
//// tab | `pip` |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install -r requirements.txt |
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | `uv` |
||||
|
|
||||
|
Nếu bạn có <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uv pip install -r requirements.txt |
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
/// details | `requirements.txt` |
||||
|
|
||||
|
Một tệp `requirements.txt` với một số gói sẽ trông như thế này: |
||||
|
|
||||
|
```requirements.txt |
||||
|
fastapi[standard]==0.113.0 |
||||
|
pydantic==2.8.0 |
||||
|
``` |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Chạy Chương trình của bạn |
||||
|
|
||||
|
Sau khi kích hoạt môi trường ảo, bạn có thể chạy chương trình của mình, nó sẽ sử dụng Python trong môi trường ảo của bạn với các gói bạn đã cài đặt. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python main.py |
||||
|
|
||||
|
Hello World |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## Cấu hình Trình soạn thảo của bạn |
||||
|
|
||||
|
Nếu bạn sử dụng một trình soạn thảo, hãy đảm bảo bạn cấu hình nó để sử dụng cùng môi trường ảo mà bạn đã tạo (trình soạn thảo sẽ tự động phát hiện môi trường ảo) để bạn có thể nhận được tính năng tự động hoàn thành câu lệnh (autocomplete) và in lỗi trực tiếp trong trình soạn thảo (inline errors). |
||||
|
|
||||
|
Ví dụ: |
||||
|
|
||||
|
* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a> |
||||
|
* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a> |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Bạn thường chỉ cần làm điều này **một lần**, khi bạn tạo môi trường ảo. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Huỷ kích hoạt Môi trường ảo |
||||
|
|
||||
|
Khi bạn hoàn tất việc làm trên dự án của bạn, bạn có thể **huỷ kích hoạt** môi trường ảo. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ deactivate |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Như vậy, khi bạn chạy `python`, nó sẽ không chạy từ môi trường ảo đó với các gói đã cài đặt. |
||||
|
|
||||
|
## Sẵn sàng để Làm việc |
||||
|
|
||||
|
Bây giờ bạn đã sẵn sàng để làm việc trên dự án của mình rồi đấy. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Bạn muốn hiểu tất cả những gì ở trên? |
||||
|
|
||||
|
Tiếp tục đọc. 👇🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Tại sao cần Môi trường ảo |
||||
|
|
||||
|
Để làm việc với FastAPI, bạn cần cài đặt <a href="https://www.python.org/" class="external-link" target="_blank">Python</a>. |
||||
|
|
||||
|
Sau đó, bạn sẽ cần **cài đặt** FastAPI và bất kỳ **gói** nào mà bạn muốn sử dụng. |
||||
|
|
||||
|
Để cài đặt gói, bạn thường sử dụng lệnh `pip` có sẵn với Python (hoặc các phiên bản tương tự). |
||||
|
|
||||
|
Tuy nhiên, nếu bạn sử dụng `pip` trực tiếp, các gói sẽ được cài đặt trong **môi trường Python toàn cục** của bạn (phần cài đặt toàn cục của Python). |
||||
|
|
||||
|
### Vấn đề |
||||
|
|
||||
|
Vậy, vấn đề gì khi cài đặt gói trong môi trường Python toàn cục? |
||||
|
|
||||
|
Trong một vài thời điểm, bạn sẽ phải viết nhiều chương trình khác nhau phụ thuộc vào **các gói khác nhau**. Và một số dự án bạn thực hiện lại phụ thuộc vào **các phiên bản khác nhau** của cùng một gói. 😱 |
||||
|
|
||||
|
Ví dụ, bạn có thể tạo một dự án được gọi là `philosophers-stone`, chương trình này phụ thuộc vào một gói khác được gọi là **`harry`, sử dụng phiên bản `1`**. Vì vậy, bạn cần cài đặt `harry`. |
||||
|
|
||||
|
```mermaid |
||||
|
flowchart LR |
||||
|
stone(philosophers-stone) -->|phụ thuộc| harry-1[harry v1] |
||||
|
``` |
||||
|
|
||||
|
Sau đó, vào một vài thời điểm sau, bạn tạo một dự án khác được gọi là `prisoner-of-azkaban`, và dự án này cũng phụ thuộc vào `harry`, nhưng dự án này cần **`harry` phiên bản `3`**. |
||||
|
|
||||
|
```mermaid |
||||
|
flowchart LR |
||||
|
azkaban(prisoner-of-azkaban) --> |phụ thuộc| harry-3[harry v3] |
||||
|
``` |
||||
|
|
||||
|
Bây giờ, vấn đề là, nếu bạn cài đặt các gói toàn cục (trong môi trường toàn cục) thay vì trong một **môi trường ảo cục bộ**, bạn sẽ phải chọn phiên bản `harry` nào để cài đặt. |
||||
|
|
||||
|
Nếu bạn muốn chạy `philosophers-stone` bạn sẽ cần phải cài đặt `harry` phiên bản `1`, ví dụ với: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "harry==1" |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Và sau đó bạn sẽ có `harry` phiên bản `1` được cài đặt trong môi trường Python toàn cục của bạn. |
||||
|
|
||||
|
```mermaid |
||||
|
flowchart LR |
||||
|
subgraph global[môi trường toàn cục] |
||||
|
harry-1[harry v1] |
||||
|
end |
||||
|
subgraph stone-project[dự án philosophers-stone ] |
||||
|
stone(philosophers-stone) -->|phụ thuộc| harry-1 |
||||
|
end |
||||
|
``` |
||||
|
|
||||
|
Nhưng sau đó, nếu bạn muốn chạy `prisoner-of-azkaban`, bạn sẽ cần phải gỡ bỏ `harry` phiên bản `1` và cài đặt `harry` phiên bản `3` (hoặc chỉ cần cài đặt phiên bản `3` sẽ tự động gỡ bỏ phiên bản `1`). |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "harry==3" |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Và sau đó bạn sẽ có `harry` phiên bản `3` được cài đặt trong môi trường Python toàn cục của bạn. |
||||
|
|
||||
|
Và nếu bạn cố gắng chạy `philosophers-stone` lại, có khả năng nó sẽ **không hoạt động** vì nó cần `harry` phiên bản `1`. |
||||
|
|
||||
|
```mermaid |
||||
|
flowchart LR |
||||
|
subgraph global[môi trường toàn cục] |
||||
|
harry-1[<strike>harry v1</strike>] |
||||
|
style harry-1 fill:#ccc,stroke-dasharray: 5 5 |
||||
|
harry-3[harry v3] |
||||
|
end |
||||
|
subgraph stone-project[dự án philosophers-stone ] |
||||
|
stone(philosophers-stone) -.-x|⛔️| harry-1 |
||||
|
end |
||||
|
subgraph azkaban-project[dự án prisoner-of-azkaban ] |
||||
|
azkaban(prisoner-of-azkaban) --> |phụ thuộc| harry-3 |
||||
|
end |
||||
|
``` |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Mặc dù các gói Python thường cố gắng **tránh các thay đổi làm hỏng code** trong **phiên bản mới**, nhưng để đảm bảo an toàn, bạn nên chủ động cài đặt phiên bản mới và chạy kiểm thử để xác nhận mọi thứ vẫn hoạt động đúng. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Bây giờ, hãy hình dung về **nhiều** gói khác nhau mà tất cả các dự án của bạn phụ thuộc vào. Rõ ràng rất khó để quản lý. Điều này dẫn tới việc là bạn sẽ có nhiều dự án với **các phiên bản không tương thích** của các gói, và bạn có thể không biết tại sao một số thứ không hoạt động. |
||||
|
|
||||
|
Hơn nữa, tuỳ vào hệ điều hành của bạn (vd Linux, Windows, macOS), có thể đã có Python được cài đặt sẵn. Trong trường hợp ấy, một vài gói nhiều khả năng đã được cài đặt trước với các phiên bản **cần thiết cho hệ thống của bạn**. Nếu bạn cài đặt các gói trong môi trường Python toàn cục, bạn có thể sẽ **phá vỡ** một số chương trình đã được cài đặt sẵn cùng hệ thống. |
||||
|
|
||||
|
## Nơi các Gói được Cài đặt |
||||
|
|
||||
|
Khi bạn cài đặt Python, nó sẽ tạo ra một vài thư mục và tệp trong máy tính của bạn. |
||||
|
|
||||
|
Một vài thư mục này là những thư mục chịu trách nhiệm có tất cả các gói bạn cài đặt. |
||||
|
|
||||
|
Khi bạn chạy: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Đừng chạy lệnh này ngay, đây chỉ là một ví dụ 🤓 |
||||
|
$ pip install "fastapi[standard]" |
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Lệnh này sẽ tải xuống một tệp nén với mã nguồn FastAPI, thường là từ <a href="https://pypi.org/project/fastapi/" class="external-link" target="_blank">PyPI</a>. |
||||
|
|
||||
|
Nó cũng sẽ **tải xuống** các tệp cho các gói khác mà FastAPI phụ thuộc vào. |
||||
|
|
||||
|
Sau đó, nó sẽ **giải nén** tất cả các tệp đó và đưa chúng vào một thư mục trong máy tính của bạn. |
||||
|
|
||||
|
Mặc định, nó sẽ đưa các tệp đã tải xuống và giải nén vào thư mục được cài đặt cùng Python của bạn, đó là **môi trường toàn cục**. |
||||
|
|
||||
|
## Những Môi trường ảo là gì? |
||||
|
|
||||
|
Cách giải quyết cho vấn đề có tất cả các gói trong môi trường toàn cục là sử dụng một **môi trường ảo cho mỗi dự án** bạn làm việc. |
||||
|
|
||||
|
Một môi trường ảo là một **thư mục**, rất giống với môi trường toàn cục, trong đó bạn có thể cài đặt các gói cho một dự án. |
||||
|
|
||||
|
Vì vậy, mỗi dự án sẽ có một môi trường ảo riêng của nó (thư mục `.venv`) với các gói riêng của nó. |
||||
|
|
||||
|
```mermaid |
||||
|
flowchart TB |
||||
|
subgraph stone-project[dự án philosophers-stone ] |
||||
|
stone(philosophers-stone) --->|phụ thuộc| harry-1 |
||||
|
subgraph venv1[.venv] |
||||
|
harry-1[harry v1] |
||||
|
end |
||||
|
end |
||||
|
subgraph azkaban-project[dự án prisoner-of-azkaban ] |
||||
|
azkaban(prisoner-of-azkaban) --->|phụ thuộc| harry-3 |
||||
|
subgraph venv2[.venv] |
||||
|
harry-3[harry v3] |
||||
|
end |
||||
|
end |
||||
|
stone-project ~~~ azkaban-project |
||||
|
``` |
||||
|
|
||||
|
## Kích hoạt Môi trường ảo nghĩa là gì |
||||
|
|
||||
|
Khi bạn kích hoạt một môi trường ảo, ví dụ với: |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ source .venv/bin/activate |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ .venv\Scripts\Activate.ps1 |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows Bash |
||||
|
|
||||
|
Nếu bạn sử dụng Bash cho Windows (ví dụ <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>): |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ source .venv/Scripts/activate |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Lệnh này sẽ tạo hoặc sửa đổi một số [biến môi trường](environment-variables.md){.internal-link target=_blank} mà sẽ được sử dụng cho các lệnh tiếp theo. |
||||
|
|
||||
|
Một trong số đó là biến `PATH`. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Bạn có thể tìm hiểu thêm về biến `PATH` trong [Biến môi trường](environment-variables.md#path-environment-variable){.internal-link target=_blank} section. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Kích hoạt môi trường ảo thêm đường dẫn `.venv/bin` (trên Linux và macOS) hoặc `.venv\Scripts` (trên Windows) vào biến `PATH`. |
||||
|
|
||||
|
Giả sử rằng trước khi kích hoạt môi trường, biến `PATH` như sau: |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
```plaintext |
||||
|
/usr/bin:/bin:/usr/sbin:/sbin |
||||
|
``` |
||||
|
|
||||
|
Nghĩa là hệ thống sẽ tìm kiếm chương trình trong: |
||||
|
|
||||
|
* `/usr/bin` |
||||
|
* `/bin` |
||||
|
* `/usr/sbin` |
||||
|
* `/sbin` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Windows\System32 |
||||
|
``` |
||||
|
|
||||
|
Nghĩa là hệ thống sẽ tìm kiếm chương trình trong: |
||||
|
|
||||
|
* `C:\Windows\System32` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Sau khi kích hoạt môi trường ảo, biến `PATH` sẽ như sau: |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
```plaintext |
||||
|
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin |
||||
|
``` |
||||
|
|
||||
|
Nghĩa là hệ thống sẽ bắt đầu tìm kiếm chương trình trong: |
||||
|
|
||||
|
```plaintext |
||||
|
/home/user/code/awesome-project/.venv/bin |
||||
|
``` |
||||
|
|
||||
|
trước khi tìm kiếm trong các thư mục khác. |
||||
|
|
||||
|
Vì vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong: |
||||
|
|
||||
|
```plaintext |
||||
|
/home/user/code/awesome-project/.venv/bin/python |
||||
|
``` |
||||
|
|
||||
|
và sử dụng chương trình đó. |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32 |
||||
|
``` |
||||
|
|
||||
|
Nghĩa là hệ thống sẽ bắt đầu tìm kiếm chương trình trong: |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Users\user\code\awesome-project\.venv\Scripts |
||||
|
``` |
||||
|
|
||||
|
trước khi tìm kiếm trong các thư mục khác. |
||||
|
|
||||
|
Vì vậy, khi bạn gõ `python` trong terminal, hệ thống sẽ tìm thấy chương trình Python trong: |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Users\user\code\awesome-project\.venv\Scripts\python |
||||
|
``` |
||||
|
|
||||
|
và sử dụng chương trình đó. |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Một chi tiết quan trọng là nó sẽ đưa địa chỉ của môi trường ảo vào **đầu** của biến `PATH`. Hệ thống sẽ tìm kiếm nó **trước** khi tìm kiếm bất kỳ Python nào khác có sẵn. Vì vậy, khi bạn chạy `python`, nó sẽ sử dụng Python **từ môi trường ảo** thay vì bất kỳ Python nào khác (ví dụ, Python từ môi trường toàn cục). |
||||
|
|
||||
|
Kích hoạt một môi trường ảo cũng thay đổi một vài thứ khác, nhưng đây là một trong những điều quan trọng nhất mà nó thực hiện. |
||||
|
|
||||
|
## Kiểm tra một Môi trường ảo |
||||
|
|
||||
|
Khi bạn kiểm tra một môi trường ảo đã được kích hoạt chưa, ví dụ với: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ which python |
||||
|
|
||||
|
/home/user/code/awesome-project/.venv/bin/python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ Get-Command python |
||||
|
|
||||
|
C:\Users\user\code\awesome-project\.venv\Scripts\python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
|
||||
|
Điều đó có nghĩa là chương trình `python` sẽ được sử dụng là chương trình **trong môi trường ảo**. |
||||
|
|
||||
|
Bạn sử dụng `which` trên Linux và macOS và `Get-Command` trên Windows PowerShell. |
||||
|
|
||||
|
Cách hoạt động của lệnh này là nó sẽ đi và kiểm tra biến `PATH`, đi qua **mỗi đường dẫn theo thứ tự**, tìm kiếm chương trình được gọi là `python`. Khi nó tìm thấy nó, nó sẽ **hiển thị cho bạn đường dẫn** đến chương trình đó. |
||||
|
|
||||
|
Điều quan trọng nhất là khi bạn gọi `python`, đó chính là chương trình `python` được thực thi. |
||||
|
|
||||
|
Vì vậy, bạn có thể xác nhận nếu bạn đang ở trong môi trường ảo đúng. |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Dễ dàng kích hoạt một môi trường ảo, cài đặt Python, và sau đó **chuyển đến một dự án khác**. |
||||
|
|
||||
|
Và dự án thứ hai **sẽ không hoạt động** vì bạn đang sử dụng **Python không đúng**, từ một môi trường ảo cho một dự án khác. |
||||
|
|
||||
|
Thật tiện lợi khi có thể kiểm tra `python` nào đang được sử dụng 🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Tại sao lại Huỷ kích hoạt một Môi trường ảo |
||||
|
|
||||
|
Ví dụ, bạn có thể làm việc trên một dự án `philosophers-stone`, **kích hoạt môi trường ảo**, cài đặt các gói và làm việc với môi trường ảo đó. |
||||
|
|
||||
|
Sau đó, bạn muốn làm việc trên **dự án khác** `prisoner-of-azkaban`. |
||||
|
|
||||
|
Bạn đi đến dự án đó: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ cd ~/code/prisoner-of-azkaban |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Nếu bạn không tắt môi trường ảo cho `philosophers-stone`, khi bạn chạy `python` trong terminal, nó sẽ cố gắng sử dụng Python từ `philosophers-stone`. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ cd ~/code/prisoner-of-azkaban |
||||
|
|
||||
|
$ python main.py |
||||
|
|
||||
|
// Lỗi khi import sirius, nó không được cài đặt 😱 |
||||
|
Traceback (most recent call last): |
||||
|
File "main.py", line 1, in <module> |
||||
|
import sirius |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Nếu bạn huỷ kích hoạt môi trường ảo hiện tại và kích hoạt môi trường ảo mới cho `prisoner-of-azkaban`, khi bạn chạy `python`, nó sẽ sử dụng Python từ môi trường ảo trong `prisoner-of-azkaban`. |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ cd ~/code/prisoner-of-azkaban |
||||
|
|
||||
|
// Bạn không cần phải ở trong thư mục trước để huỷ kích hoạt, bạn có thể làm điều đó ở bất kỳ đâu, ngay cả sau khi đi đến dự án khác 😎 |
||||
|
$ deactivate |
||||
|
|
||||
|
// Kích hoạt môi trường ảo trong prisoner-of-azkaban/.venv 🚀 |
||||
|
$ source .venv/bin/activate |
||||
|
|
||||
|
// Bây giờ khi bạn chạy python, nó sẽ tìm thấy gói sirius được cài đặt trong môi trường ảo này ✨ |
||||
|
$ python main.py |
||||
|
|
||||
|
I solemnly swear 🐺 |
||||
|
|
||||
|
(Tôi long trọng thề 🐺 - câu này được lấy từ Harry Potter, chú thích của người dịch) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## Các cách làm tương tự |
||||
|
|
||||
|
Đây là một hướng dẫn đơn giản để bạn có thể bắt đầu và hiểu cách mọi thứ hoạt động **bên trong**. |
||||
|
|
||||
|
Có nhiều **cách khác nhau** để quản lí các môi trường ảo, các gói phụ thuộc (requirements), và các dự án. |
||||
|
|
||||
|
Một khi bạn đã sẵn sàng và muốn sử dụng một công cụ để **quản lí cả dự án**, các gói phụ thuộc, các môi trường ảo, v.v. Tôi sẽ khuyên bạn nên thử <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>. |
||||
|
|
||||
|
`uv` có thể làm nhiều thứ, chẳng hạn: |
||||
|
|
||||
|
* **Cài đặt Python** cho bạn, bao gồm nhiều phiên bản khác nhau |
||||
|
* Quản lí **các môi trường ảo** cho các dự án của bạn |
||||
|
* Cài đặt **các gói (packages)** |
||||
|
* Quản lí **các thành phần phụ thuộc và phiên bản** của các gói cho dự án của bạn |
||||
|
* Đảm bảo rằng bạn có một **tập hợp chính xác** các gói và phiên bản để cài đặt, bao gồm các thành phần phụ thuộc của chúng, để bạn có thể đảm bảo rằng bạn có thể chạy dự án của bạn trong sản xuất chính xác như trong máy tính của bạn trong khi phát triển, điều này được gọi là **locking** |
||||
|
* Và còn nhiều thứ khác nữa |
||||
|
|
||||
|
## Kết luận |
||||
|
|
||||
|
Nếu bạn đã đọc và hiểu hết những điều này, khá chắc là bây giờ bạn đã **biết nhiều hơn** về môi trường ảo so với kha khá lập trình viên khác đấy. 🤓 |
||||
|
|
||||
|
Những hiểu biết chi tiết này có thể sẽ hữu ích với bạn trong tương lai khi mà bạn cần gỡ lỗi một vài thứ phức tạp, và bạn đã có những hiểu biết về **ngọn ngành gốc rễ cách nó hoạt động**. 😎 |
Loading…
Reference in new issue