Translate 7 documents

This commit is contained in:
Yurii Motov committed 2026-10-26 21:54:03 +01:00
1 parent 5ddacf9a24
commit 1ec4977e42
7 files changed
+2446

No files matched your search

+495
View File
@@ -0,0 +1,495 @@
# Faili ya majaribio ya LLM { #llm-test-file }
Hati hii inajaribu kama <abbr title="Large Language Model - Modeli Kubwa ya Lugha">LLM</abbr>, inayotafsiri nyaraka, inaelewa `general_prompt` katika `scripts/translate.py` na prompt maalumu ya lugha katika `docs/{language code}/llm-prompt.md`. Prompt maalumu ya lugha huongezwa mwishoni mwa `general_prompt`.
Majaribio yanayoongezwa hapa yataonekana kwa wabunifu wote wa prompt maalumu za lugha.
Tumia kama ifuatavyo:
* Kuwa na prompt maalumu ya lugha - `docs/{language code}/llm-prompt.md`.
* Tafsiri hati hii upya kwenda lugha unayolenga (tazama, kwa mfano, amri ya `translate-page` ya `translate.py`). Hii itaunda tafsiri katika `docs/{language code}/docs/_llm-test.md`.
* Kagua kama kila kitu kiko sawa katika tafsiri.
* Ikihitajika, boresha prompt yako maalumu ya lugha, prompt ya jumla, au hati ya Kiingereza.
* Kisha rekebisha mwenyewe matatizo yaliyobaki katika tafsiri, ili iwe tafsiri nzuri.
* Tafsiri tena, huku tafsiri hiyo nzuri ikiwa tayari ipo. Matokeo bora yangekuwa kwamba LLM haifanyi tena mabadiliko yoyote kwenye tafsiri. Hiyo inamaanisha kwamba prompt ya jumla na prompt yako maalumu ya lugha ni bora kadiri iwezekanavyo (Wakati mwingine itafanya mabadiliko machache yanayoonekana kuwa ya nasibu; sababu ni kwamba [LLM si algoriti zinazotoa matokeo yaleyale kila mara kwa ingizo lilelile](https://doublespeak.chat/#/handbook#deterministic-output)).
Majaribio:
## Vipande vya msimbo { #code-snippets }
//// tab | Jaribio
Hiki ni kipande cha msimbo: `foo`. Na hiki ni kipande kingine cha msimbo: `bar`. Na kingine: `baz quux`.
////
//// tab | Maelezo
Maudhui ya vipande vya msimbo yanapaswa kuachwa kama yalivyo.
Tazama sehemu ya `### Content of code snippets` katika prompt ya jumla katika `scripts/translate.py`.
////
## Alama za kunukuu { #quotes }
//// tab | Jaribio
Jana, rafiki yangu aliandika: "Ukiandika neno kimakosa kwa usahihi, umeliandika kimakosa". Nikamjibu: "Sahihi, lakini 'kimakosa' ni kimakosa, si '"kimakosa"'".
/// note | Tanbihi
Huenda LLM ikatafsiri hili vibaya. Kinachovutia tu ni kama itahifadhi tafsiri iliyorekebishwa wakati wa kutafsiri tena.
///
////
//// tab | Maelezo
Mbunifu wa prompt anaweza kuchagua kama anataka kubadilisha alama za kunukuu zilizonyooka kuwa alama za kunukuu za uchapaji. Ni sawa kuziacha kama zilivyo.
Tazama, kwa mfano, sehemu ya `### Quotes` katika `docs/de/llm-prompt.md`.
////
## Alama za kunukuu katika vipande vya msimbo { #quotes-in-code-snippets }
//// tab | Jaribio
`pip install "foo[bar]"`
Mifano ya string literals katika vipande vya msimbo: `"this"`, `'that'`.
Mfano mgumu wa string literals katika vipande vya msimbo: `f"I like {'oranges' if orange else "apples"}"`
Mgumu sana: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"`
////
//// tab | Maelezo
... Hata hivyo, alama za kunukuu ndani ya vipande vya msimbo lazima zibaki kama zilivyo.
////
## Vitalu vya msimbo { #code-blocks }
//// tab | Jaribio
Mfano wa msimbo wa Bash...
```bash
# Chapisha salamu kwa ulimwengu
echo "Hello universe"
```
...na mfano wa msimbo wa console...
```console
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting server
Searching for package file structure
```
...na mfano mwingine wa msimbo wa console...
```console
// Unda saraka "Code"
$ mkdir code
// Hamia kwenye saraka hiyo
$ cd code
```
...na mfano wa msimbo wa Python...
```Python
wont_work() # Hii haitafanya kazi 😱
works(foo="bar") # Hii inafanya kazi 🎉
```
...na ni hayo tu.
////
//// tab | Maelezo
Msimbo katika vitalu vya msimbo haupaswi kubadilishwa, isipokuwa maoni.
Tazama sehemu ya `### Content of code blocks` katika prompt ya jumla katika `scripts/translate.py`.
////
## Vichupo na visanduku vya rangi { #tabs-and-colored-boxes }
//// tab | Jaribio
/// note | Tanbihi
Maandishi fulani
///
/// note | Maelezo ya kiufundi
Maandishi fulani
///
/// tip | Kidokezo
Maandishi fulani
///
/// warning | Onyo
Maandishi fulani
///
/// danger | Hatari
Maandishi fulani
///
////
//// tab | Maelezo
Vichupo na vitalu vya `Info`/`Note`/`Warning`/n.k. vinapaswa kuongezewa tafsiri ya kichwa chake baada ya mstari wima (`|`).
Tazama sehemu za `### Special blocks` na `### Tab blocks` katika prompt ya jumla katika `scripts/translate.py`.
////
## Viungo vya wavuti na vya ndani { #web-and-internal-links }
//// tab | Jaribio
Maandishi ya kiungo yanapaswa kutafsiriwa, anwani ya kiungo ibaki bila kubadilishwa:
* [Kiungo cha kichwa kilicho juu](#code-snippets)
* [Kiungo cha ndani](index.md#installation)
* [Kiungo cha nje](https://sqlmodel.tiangolo.com/)
* [Kiungo cha mtindo](https://fastapi.tiangolo.com/css/styles.css)
* [Kiungo cha script](https://fastapi.tiangolo.com/js/logic.js)
* [Kiungo cha picha](https://fastapi.tiangolo.com/img/foo.jpg)
Maandishi ya kiungo yanapaswa kutafsiriwa, anwani ya kiungo ielekeze kwenye tafsiri:
* [Kiungo cha FastAPI](https://fastapi.tiangolo.com/sw/)
////
//// tab | Maelezo
Viungo vinapaswa kutafsiriwa, lakini anwani zake zibaki bila kubadilishwa. Isipokuwa ni viungo vyenye anwani kamili vya kurasa za nyaraka za FastAPI. Katika hali hiyo, kiungo kinapaswa kuelekeza kwenye tafsiri.
Tazama sehemu ya `### Links` katika prompt ya jumla katika `scripts/translate.py`.
////
## Vipengele vya HTML vya "abbr" { #html-abbr-elements }
//// tab | Jaribio
Hapa kuna baadhi ya vitu vilivyowekwa ndani ya vipengele vya HTML vya "abbr" (Baadhi vimebuniwa):
### abbr inatoa kifungu kamili cha maneno { #the-abbr-gives-a-full-phrase }
* <abbr title="Getting Things Done - Kukamilisha Mambo">GTD</abbr>
* <abbr title="less than - ndogo kuliko"><code>lt</code></abbr>
* <abbr title="XML Web Token - Tokeni ya Wavuti ya XML">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface - Kiolesura cha Lango la Seva za Parallel">PSGI</abbr>
### abbr inatoa kifungu kamili cha maneno na ufafanuzi { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbr title="Mozilla Developer Network - Mtandao wa Watengenezaji wa Mozilla: nyaraka kwa watengenezaji, zilizoandikwa na watu wa Firefox">MDN</abbr>
* <abbr title="Input/Output - Ingizo/Tokeo: kusoma au kuandika kwenye diski, mawasiliano ya mtandao.">I/O</abbr>.
////
//// tab | Maelezo
Sifa za "title" za vipengele vya "abbr" hutafsiriwa kwa kufuata maagizo maalumu.
Tafsiri zinaweza kuongeza vipengele vyake vya "abbr" ambavyo LLM haipaswi kuondoa. Kwa mfano, ili kufafanua maneno ya Kiingereza.
Tazama sehemu ya `### HTML abbr elements` katika prompt ya jumla katika `scripts/translate.py`.
////
## Vipengele vya HTML vya "dfn" { #html-dfn-elements }
* <dfn title="Kundi la mashine zilizosanidiwa ili ziunganishwe na kufanya kazi pamoja kwa namna fulani.">cluster</dfn>
* <dfn title="Mbinu ya ujifunzaji wa mashine inayotumia mitandao bandia ya neva yenye tabaka nyingi zilizofichwa kati ya tabaka za ingizo na tokeo, na hivyo kujenga muundo wa ndani wenye kina">Ujifunzaji wa Kina</dfn>
## Vichwa { #headings }
//// tab | Jaribio
### Unda programu ya wavuti - mafunzo { #develop-a-webapp-a-tutorial }
Habari.
### Vidokezo na viashirio vya aina { #type-hints-and-annotations }
Habari tena.
### Madarasa ya msingi na madarasa yanayotokana nayo { #super-and-subclasses }
Habari tena.
////
//// tab | Maelezo
Kanuni pekee ya lazima kwa vichwa ni kwamba LLM iache sehemu ya hash iliyo ndani ya mabano ya mawimbi bila kubadilishwa, jambo linalohakikisha kwamba viungo haviathiriki.
Tazama sehemu ya `### Headings` katika prompt ya jumla katika `scripts/translate.py`.
Kwa baadhi ya maagizo maalumu ya lugha, tazama, kwa mfano, sehemu ya `### Headings` katika `docs/de/llm-prompt.md`.
////
## Istilahi zinazotumiwa katika nyaraka { #terms-used-in-the-docs }
//// tab | Jaribio
* wewe
* yako
* k.m.
* n.k.
* `foo` kama `int`
* `bar` kama `str`
* `baz` kama `list`
* Mafunzo - Mwongozo wa Mtumiaji
* Mwongozo wa Mtumiaji wa Kiwango cha Juu
* nyaraka za SQLModel
* nyaraka za API
* nyaraka zinazozalishwa kiotomatiki
* Sayansi ya Data
* Ujifunzaji wa Kina
* Ujifunzaji wa Mashine
* Uingizaji wa Vitegemezi
* uthibitishaji wa utambulisho wa HTTP Basic
* HTTP Digest
* umbizo la ISO
* kiwango cha JSON Schema
* schema ya JSON
* ufafanuzi wa schema
* Mtiririko wa Nenosiri
* Simu za mkononi
* iliyopitwa na wakati na isiyopendekezwa tena
* iliyoundwa
* isiyo halali
* wakati wa utekelezaji
* ya kawaida
* ya chaguo-msingi
* inayotofautisha herufi kubwa na ndogo
* isiyotofautisha herufi kubwa na ndogo
* kuendesha programu ili ipatikane kwa watumiaji
* kutoa ukurasa kwa mteja
* app
* programu
* ombi
* jibu
* jibu la hitilafu
* operesheni ya njia
* decorator ya operesheni ya njia
* function ya operesheni ya njia
* mwili
* mwili wa ombi
* mwili wa jibu
* mwili wa JSON
* mwili wa fomu
* mwili wa faili
* mwili wa function
* kigezo
* kigezo cha mwili
* kigezo cha njia
* kigezo cha query
* kigezo cha cookie
* kigezo cha kichwa
* kigezo cha fomu
* kigezo cha function
* tukio
* tukio la kuanza
* kuanza kwa seva
* tukio la kuzimwa
* tukio la muda wa uhai
* kishughulikiaji
* kishughulikiaji cha tukio
* kishughulikiaji cha exception
* kushughulikia
* modeli
* modeli ya Pydantic
* modeli ya data
* modeli ya hifadhidata
* modeli ya fomu
* objekti ya modeli
* darasa
* darasa la msingi
* darasa mzazi
* darasa linalotokana na darasa jingine
* darasa mtoto
* darasa lenye mzazi yuleyule
* method ya darasa
* kichwa
* vichwa
* kichwa cha uidhinishaji
* kichwa cha `Authorization`
* kichwa kilichopitishwa
* mfumo wa uingizaji wa vitegemezi
* kitegemezi
* kinachoweza kutegemewa
* kinachotegemea kingine
* I/O bound
* CPU bound
* concurrency
* parallelism
* multiprocessing
* env var
* kigeu cha mazingira
* `PATH`
* kigeu cha `PATH`
* uthibitishaji wa utambulisho
* mtoa huduma ya uthibitishaji wa utambulisho
* uidhinishaji
* fomu ya uidhinishaji
* mtoa huduma ya uidhinishaji
* mtumiaji anathibitisha utambulisho wake
* mfumo unathibitisha utambulisho wa mtumiaji
* CLI
* kiolesura cha mstari wa amri
* seva
* mteja
* mtoa huduma za wingu
* huduma ya wingu
* uundaji wa programu
* hatua za uundaji wa programu
* dict
* kamusi
* enumeration
* enum
* mwanachama wa enum
* kisimbaji
* kisimbuaji
* kusimba
* kusimbua
* exception
* kuibua exception
* expression
* statement
* frontend
* backend
* mjadala wa GitHub
* suala la GitHub
* utendaji
* uboreshaji wa utendaji
* aina ya thamani inayorudishwa
* thamani inayorudishwa
* usalama
* mpango wa usalama
* kazi
* kazi ya chinichini
* function ya kazi
* kiolezo
* injini ya violezo
* kiashirio cha aina
* kidokezo cha aina
* worker wa seva
* worker wa Uvicorn
* Worker wa Gunicorn
* mchakato wa worker
* darasa la worker
* mzigo wa kazi
* uwekaji wa programu ili iweze kuendeshwa
* kuweka programu ili iweze kuendeshwa
* SDK
* zana za uundaji wa programu
* `APIRouter`
* `requirements.txt`
* Tokeni ya Bearer
* mabadiliko yanayovunja utangamano
* hitilafu ya programu
* kitufe
* callable
* msimbo
* commit
* kidhibiti cha muktadha
* coroutine
* kipindi cha hifadhidata
* diski
* kikoa
* injini
* X bandia
* mbinu ya HTTP GET
* kipengee
* maktaba
* muda wa uhai
* kufuli
* middleware
* programu ya simu
* moduli
* mounting
* mtandao
* asili
* ubatilishaji
* payload
* kichakataji
* sifa
* seva wakilishi
* pull request
* query
* RAM
* mashine ya mbali
* msimbo wa hali
* mfuatano wa herufi
* lebo
* framework ya wavuti
* wildcard
* kurudisha
* kuhakiki uhalali
////
//// tab | Maelezo
Hii si orodha kamili wala orodha inayoweka kanuni za istilahi (nyingi zikiwa za kiufundi) zinazopatikana katika nyaraka. Inaweza kumsaidia mbunifu wa prompt kubaini istilahi ambazo LLM inahitaji msaada nazo. Kwa mfano, inapozidi kubadilisha tafsiri nzuri na kuirudisha kwenye tafsiri isiyo nzuri sana. Au inapokuwa na matatizo ya kunyambua au kupatanisha kisarufi istilahi katika lugha yako.
Tazama, kwa mfano, sehemu ya `### List of English terms and their preferred German translations` katika `docs/de/llm-prompt.md`.
////
+444
View File
@@ -0,0 +1,444 @@
# Concurrency na async / await { #concurrency-and-async-await }
Maelezo kuhusu sintaksia ya `async def` kwa *vitendakazi vya operesheni za njia* na maelezo ya msingi kuhusu msimbo wa asynchronous, concurrency, na parallelism.
## Una haraka? { #in-a-hurry }
<abbr title="too long; didn't read - ni ndefu sana; sikusoma"><strong>TL;DR:</strong></abbr>
Ikiwa unatumia maktaba za wahusika wengine zinazokuambia uziite kwa `await`, kama:
```Python
results = await some_library()
```
Basi, tangaza *vitendakazi vyako vya operesheni za njia* kwa `async def` kama:
```Python hl_lines="2"
@app.get("/")
async def read_results():
results = await some_library()
return results
```
/// note | Kumbuka
Unaweza kutumia `await` ndani ya vitendakazi vilivyoundwa kwa `async def` pekee.
///
---
Ikiwa unatumia maktaba ya mhusika mwingine inayowasiliana na kitu fulani (hifadhidata, API, mfumo wa faili, n.k.) na haina uwezo wa kutumia `await`, (kwa sasa hali hii inahusu maktaba nyingi za hifadhidata), basi tangaza *vitendakazi vyako vya operesheni za njia* kama kawaida, kwa `def` tu, kama:
```Python hl_lines="2"
@app.get("/")
def results():
results = some_library()
return results
```
---
Ikiwa programu yako (kwa namna fulani) haihitaji kuwasiliana na kitu kingine chochote na kusubiri kijibu, tumia `async def`, hata kama huhitaji kutumia `await` ndani yake.
---
Ikiwa hujui cha kuchagua, tumia `def` ya kawaida.
---
**Kumbuka**: Unaweza kuchanganya `def` na `async def` katika *vitendakazi vyako vya operesheni za njia* kadiri unavyohitaji na kufafanua kila kimoja kwa chaguo linalokufaa zaidi. FastAPI itavishughulikia ipasavyo.
Kwa vyovyote vile, katika hali zote zilizo hapo juu, FastAPI bado itafanya kazi kwa namna ya asynchronous na itakuwa na kasi kubwa sana.
Lakini kwa kufuata hatua zilizo hapo juu, itaweza kuboresha utendaji kwa namna fulani.
## Maelezo ya Kiufundi { #technical-details }
Matoleo ya kisasa ya Python yana uwezo wa kutumia **"msimbo wa asynchronous"** kwa kutumia kitu kinachoitwa **"coroutines"**, kwa sintaksia ya **`async` na `await`**.
Hebu tuangalie kauli hiyo sehemu kwa sehemu katika sehemu zilizo hapa chini:
* **Msimbo wa Asynchronous**
* **`async` na `await`**
* **Coroutines**
## Msimbo wa Asynchronous { #asynchronous-code }
Msimbo wa asynchronous unamaanisha tu kwamba lugha 💬 ina njia ya kuiambia kompyuta / programu 🤖 kwamba katika sehemu fulani ya msimbo, itabidi 🤖 isubiri *kitu kingine* kikamilike mahali pengine. Tuseme *kitu hicho kingine* kinaitwa "faili-linalochelewa" 📝.
Kwa hiyo, wakati huo, kompyuta inaweza kwenda kufanya kazi nyingine, huku "faili-linalochelewa" 📝 likikamilika.
Kisha kompyuta / programu 🤖 itarudi kila inapopata nafasi kwa sababu inasubiri tena, au kila inapomaliza 🤖 kazi zote ilizokuwa nazo wakati huo. Nayo 🤖 itaangalia kama kuna kazi zozote ilizokuwa ikizisubiri ambazo tayari zimemaliza kufanya zilichopaswa kufanya.
Halafu, 🤖 itachukua kazi ya kwanza kukamilika (tuseme, "faili-linalochelewa" 📝 letu) na kuendelea na chochote ilichopaswa kufanya nayo.
Huko "kusubiri kitu kingine" kwa kawaida kunarejelea operesheni za <abbr title="Input and Output - Ingizo na Tokeo">I/O</abbr> ambazo ni za "polepole" kwa kulinganisha (na kasi ya kichakataji na kumbukumbu ya RAM), kama kusubiri:
* data kutoka kwa mteja itumwe kupitia mtandao
* data iliyotumwa na programu yako ipokelewe na mteja kupitia mtandao
* yaliyomo kwenye faili lililo kwenye diski yasomwe na mfumo na kupewa programu yako
* yaliyomo ambayo programu yako iliupa mfumo yaandikwe kwenye diski
* operesheni ya API ya mbali
* operesheni ya hifadhidata ikamilike
* hoja ya hifadhidata irudishe matokeo
* n.k.
Kwa kuwa muda mwingi wa utekelezaji hutumika kusubiri operesheni za <abbr title="Input and Output - Ingizo na Tokeo">I/O</abbr>, operesheni hizo huitwa "I/O bound".
Inaitwa "asynchronous" kwa sababu kompyuta / programu haihitaji "kusawazishwa" na kazi ya polepole, ikisubiri wakati uleule ambapo kazi inakamilika, bila kufanya chochote, ili iweze kuchukua matokeo ya kazi na kuendelea kufanya kazi.
Badala yake, kwa kuwa ni mfumo wa "asynchronous", baada ya kukamilika, kazi inaweza kusubiri kwenye foleni kwa muda mfupi (mikrosekunde chache) ili kompyuta / programu imalize chochote ilichoenda kufanya, kisha irudi kuchukua matokeo na kuendelea kuyafanyia kazi.
Kwa "synchronous" (kinyume cha "asynchronous"), kwa kawaida pia hutumia neno "sequential", yaani kwa mfuatano, kwa sababu kompyuta / programu hufuata hatua zote kwa mfuatano kabla ya kuhamia kazi tofauti, hata kama hatua hizo zinahusisha kusubiri.
### Concurrency na Baga { #concurrency-and-burgers }
Wazo hili la msimbo wa **asynchronous** lililoelezwa hapo juu pia wakati mwingine huitwa **"concurrency"**. Ni tofauti na **"parallelism"**.
**Concurrency** na **parallelism** zote zinahusiana na "mambo tofauti yanayotokea takribani wakati mmoja".
Lakini maelezo ya *concurrency* na *parallelism* yanatofautiana sana.
Ili kuona tofauti, fikiria hadithi ifuatayo kuhusu baga:
### Baga kwa Concurrency { #concurrent-burgers }
Unaenda na mtu unayempenda kupata chakula cha haraka, unasimama kwenye foleni huku mhudumu wa malipo akipokea oda kutoka kwa watu walio mbele yako. 😍
<img src="/img/async/concurrent-burgers/concurrent-burgers-01.png" class="illustration">
Kisha zamu yako inafika, unaagiza baga 2 za kifahari sana kwa ajili yako na mtu unayempenda. 🍔🍔
<img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration">
Mhudumu wa malipo anamwambia mpishi aliye jikoni kitu fulani ili ajue kwamba anapaswa kuandaa baga zenu (hata ingawa kwa sasa anaandaa za wateja waliotangulia).
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration">
Unalipa. 💸
Mhudumu wa malipo anakupa namba ya zamu yako.
<img src="/img/async/concurrent-burgers/concurrent-burgers-04.png" class="illustration">
Wakati unasubiri, unaenda na mtu unayempenda kuchagua meza, mnaketi na kuzungumza kwa muda mrefu (kwa kuwa baga zenu ni za kifahari sana na zinachukua muda kuandaliwa).
Mkiwa mmeketi mezani pamoja, huku mkisubiri baga, unaweza kutumia muda huo kuvutiwa na jinsi mtu unayempenda alivyo wa ajabu, wa kupendeza na mwenye akili ✨😍✨.
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration">
Unaposubiri na kuzungumza na mtu unayempenda, mara kwa mara unaangalia namba inayoonyeshwa kwenye kaunta ili kuona kama zamu yako imefika tayari.
Kisha wakati fulani, hatimaye zamu yako inafika. Unaenda kwenye kaunta, unachukua baga zenu na kurudi mezani.
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration">
Wewe na mtu unayempenda mnakula baga na kufurahia muda wenu pamoja. ✨
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
/// note | Kumbuka
Michoro mizuri imetengenezwa na [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
///
---
Fikiria wewe ndiye kompyuta / programu 🤖 katika hadithi hiyo.
Ukiwa kwenye foleni, hufanyi kitu 😴, unasubiri zamu yako, bila kufanya chochote chenye "tija" sana. Lakini foleni inasonga haraka kwa sababu mhudumu wa malipo anapokea oda tu (haziandai), kwa hiyo hilo si tatizo.
Kisha, zamu yako inapofika, unafanya kazi halisi yenye "tija": unasoma menyu, unaamua unachotaka, unapata chaguo la mtu unayempenda, unalipa, unahakikisha unatoa noti au kadi sahihi, unahakikisha umetozwa kiasi sahihi, unahakikisha oda ina vitu sahihi, n.k.
Lakini baadaye, hata ingawa bado hamjapata baga zenu, kazi yako na mhudumu wa malipo "imesitishwa kwa muda" ⏸, kwa sababu unapaswa kusubiri 🕙 baga zenu ziwe tayari.
Lakini unapoondoka kauntani na kuketi mezani ukiwa na namba ya zamu yako, unaweza kuhamisha 🔀 umakini wako kwa mtu unayempenda, na "kufanyia kazi" ⏯ 🤓 hilo. Hapo unakuwa tena unafanya kitu chenye "tija" sana, kama vile kumtongoza mtu unayempenda 😍.
Kisha mhudumu wa malipo 💁 anasema "Nimemaliza kuandaa baga" kwa kuweka namba yako kwenye skrini ya kaunta, lakini huruki kama kichaa mara tu namba inayoonyeshwa inapobadilika kuwa namba ya zamu yako. Unajua hakuna atakayeiba baga zenu kwa sababu una namba ya zamu yako, na wengine wana zao.
Kwa hiyo unasubiri mtu unayempenda amalize hadithi yake (kumaliza kazi ya sasa ⏯ / kazi inayoshughulikiwa 🤓), unatabasamu kwa upole na kusema kwamba unaenda kuchukua baga ⏸.
Kisha unaenda kauntani 🔀, kwenye kazi ya awali ambayo sasa imekamilika ⏯, unachukua baga, unashukuru na kuzipeleka mezani. Hilo linakamilisha hatua / kazi hiyo ya kushughulika na kaunta ⏹. Hiyo nayo inaunda kazi mpya, ya "kula baga" 🔀 ⏯, lakini ile ya awali ya "kupata baga" imekamilika ⏹.
### Baga kwa Parallelism { #parallel-burgers }
Sasa hebu tufikirie hizi si "Baga kwa Concurrency", bali "Baga kwa Parallelism".
Unaenda na mtu unayempenda kupata chakula cha haraka kwa parallelism.
Unasimama kwenye foleni huku wahudumu kadhaa wa malipo (tuseme 8), ambao pia ni wapishi, wakipokea oda kutoka kwa watu walio mbele yako.
Kila mtu aliye mbele yako anasubiri baga zake ziwe tayari kabla ya kuondoka kauntani, kwa sababu kila mmoja wa wahudumu 8 wa malipo anaenda kuandaa baga mara moja kabla ya kupokea oda inayofuata.
<img src="/img/async/parallel-burgers/parallel-burgers-01.png" class="illustration">
Kisha hatimaye zamu yako inafika, unaagiza baga 2 za kifahari sana kwa ajili yako na mtu unayempenda.
Unalipa 💸.
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration">
Mhudumu wa malipo anaenda jikoni.
Unasubiri, ukiwa umesimama mbele ya kaunta 🕙, ili mtu mwingine asichukue baga zenu kabla yako, kwa kuwa hakuna namba za zamu.
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration">
Kwa kuwa wewe na mtu unayempenda mko bize kuzuia mtu yeyote asiingie mbele yenu na kuchukua baga zenu zinapofika, huwezi kumwelekezea umakini mtu unayempenda. 😞
Hii ni kazi ya "synchronous", "umesawazishwa" na mhudumu wa malipo/mpishi 👨‍🍳. Unapaswa kusubiri 🕙 na kuwepo wakati uleule mhudumu wa malipo/mpishi 👨‍🍳 anapomaliza baga na kukupa, la sivyo, mtu mwingine anaweza kuzichukua.
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration">
Kisha mhudumu wako wa malipo/mpishi 👨‍🍳 hatimaye anarudi na baga zenu, baada ya kusubiri 🕙 kwa muda mrefu hapo mbele ya kaunta.
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration">
Unachukua baga zenu na kwenda mezani na mtu unayempenda.
Mnazila tu, na mmemaliza. ⏹
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration">
Hakukuwa na mazungumzo mengi wala kutongozana kwani muda mwingi ulitumika kusubiri 🕙 mbele ya kaunta. 😞
/// note | Kumbuka
Michoro mizuri imetengenezwa na [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
///
---
Katika hali hii ya baga kwa parallelism, wewe ni kompyuta / programu 🤖 yenye vichakataji viwili (wewe na mtu unayempenda), vyote vikisubiri 🕙 na kuelekeza umakini wao ⏯ kwenye "kusubiri kauntani" 🕙 kwa muda mrefu.
Duka la chakula cha haraka lina vichakataji 8 (wahudumu wa malipo/wapishi). Ilhali duka la baga kwa concurrency huenda lilikuwa na 2 tu (mhudumu mmoja wa malipo na mpishi mmoja).
Lakini bado, uzoefu wa mwisho si mzuri zaidi. 😞
---
Hii ndiyo ingekuwa hadithi inayolingana ya baga kwa parallelism. 🍔
Kwa mfano wa hili ulio karibu zaidi na "maisha halisi", fikiria benki.
Hadi hivi karibuni, benki nyingi zilikuwa na wahudumu wengi wa malipo 👨‍💼👨‍💼👨‍💼👨‍💼 na foleni kubwa 🕙🕙🕙🕙🕙🕙🕙🕙.
Wahudumu wote wakifanya kazi yote na mteja mmoja baada ya mwingine 👨‍💼⏯.
Na unapaswa kusubiri 🕙 kwenye foleni kwa muda mrefu, la sivyo unapoteza zamu yako.
Huenda usingependa kwenda na mtu unayempenda 😍 kufanya shughuli zako benki 🏦.
### Hitimisho la Baga { #burger-conclusion }
Katika hali hii ya "baga za chakula cha haraka na mtu unayempenda", kwa kuwa kuna kusubiri kwingi 🕙, inaleta maana zaidi kuwa na mfumo wa concurrency ⏸🔀⏯.
Hii ndiyo hali ya programu nyingi za wavuti.
Watumiaji ni wengi sana, lakini seva yako inasubiri 🕙 miunganisho yao isiyo mizuri sana itume maombi yao.
Na kisha inasubiri 🕙 tena majibu yarudi.
Huku "kusubiri" 🕙 hupimwa kwa mikrosekunde, lakini bado, ukijumlisha yote, mwishowe ni muda mwingi wa kusubiri.
Ndiyo maana inaleta maana sana kutumia msimbo wa asynchronous ⏸🔀⏯ kwa API za wavuti.
Namna hii ya kufanya kazi kwa asynchronous ndiyo iliyofanya NodeJS iwe maarufu (hata ingawa NodeJS haitumii parallelism) na huo ndio uwezo mkuu wa Go kama lugha ya programu.
Na hicho ndicho kiwango cha utendaji unachopata kwa **FastAPI**.
Na kwa kuwa unaweza kuwa na parallelism na asynchronous kwa wakati mmoja, unapata utendaji wa juu kuliko framework nyingi za NodeJS zilizojaribiwa, na unaolingana na Go, ambayo ni lugha inayotumia compiler iliyo karibu zaidi na C [(yote haya kutokana na Starlette)](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1).
### Je, concurrency ni bora kuliko parallelism? { #is-concurrency-better-than-parallelism }
La hasha! Hilo si fundisho la hadithi hii.
Concurrency ni tofauti na parallelism. Na ni bora katika hali **maalumu** zinazohusisha kusubiri kwingi. Kwa sababu hiyo, kwa ujumla ni bora sana kuliko parallelism kwa uundaji wa programu za wavuti. Lakini si kwa kila kitu.
Kwa hiyo, ili kusawazisha hilo, fikiria hadithi fupi ifuatayo:
> Unapaswa kusafisha nyumba kubwa iliyo chafu.
*Ndiyo, hiyo ndiyo hadithi yote*.
---
Hakuna kusubiri 🕙 popote, ni kazi nyingi tu zinazopaswa kufanywa, katika sehemu nyingi za nyumba.
Unaweza kufanya kwa zamu kama katika mfano wa baga, kwanza sebule, kisha jikoni, lakini kwa kuwa husubiri 🕙 kitu chochote, unasafisha tu mfululizo, zamu hazitabadilisha kitu chochote.
Ingechukua muda uleule kumaliza ukiwa na zamu (concurrency) au bila zamu, na ungekuwa umefanya kiasi kilekile cha kazi.
Lakini katika hali hii, kama ungeweza kuwaleta wale 8 waliokuwa wahudumu wa malipo/wapishi na ambao sasa ni wasafishaji, na kila mmoja wao (pamoja na wewe) achukue sehemu ya nyumba aisafishe, mngeweza kufanya kazi yote kwa **parallelism**, kwa msaada huo wa ziada, na kumaliza mapema zaidi.
Katika hali hii, kila mmoja wa wasafishaji (pamoja na wewe) angekuwa kichakataji, akifanya sehemu yake ya kazi.
Na kwa kuwa muda mwingi wa utekelezaji unatumika kufanya kazi halisi (badala ya kusubiri), na kazi katika kompyuta hufanywa na <abbr title="Central Processing Unit - Kitengo Kikuu cha Uchakataji">CPU</abbr>, matatizo haya huitwa "CPU bound".
---
Mifano ya kawaida ya operesheni za CPU bound ni vitu vinavyohitaji uchakataji wa hesabu changamano.
Kwa mfano:
* **Uchakataji wa sauti** au **picha**.
* **Computer vision**: picha inaundwa na mamilioni ya pikseli, kila pikseli ina thamani / rangi 3, na kuichakata kwa kawaida kunahitaji kufanya hesabu fulani kwenye pikseli hizo, zote kwa wakati mmoja.
* **Machine Learning**: kwa kawaida inahitaji uzidishaji mwingi wa "matrix" na "vector". Fikiria lahajedwali kubwa lenye namba na kuzizidisha zote pamoja kwa wakati mmoja.
* **Deep Learning**: hii ni tawi la Machine Learning, kwa hiyo, hali hiyo hiyo inatumika. Tofauti ni kwamba hakuna lahajedwali moja tu la namba za kuzidisha, bali kuna kundi kubwa la lahajedwali hizo, na katika hali nyingi, unatumia kichakataji maalumu kujenga na / au kutumia modeli hizo.
### Concurrency + Parallelism: Wavuti + Machine Learning { #concurrency-parallelism-web-machine-learning }
Kwa **FastAPI** unaweza kunufaika na concurrency ambayo ni ya kawaida sana katika uundaji wa programu za wavuti (kivutio kikuu hichohicho cha NodeJS).
Lakini pia unaweza kutumia manufaa ya parallelism na multiprocessing (kuwa na michakato mingi inayotekelezwa kwa parallelism) kwa kazi za **CPU bound** kama zile za mifumo ya Machine Learning.
Hilo, pamoja na ukweli rahisi kwamba Python ndiyo lugha kuu ya **Sayansi ya Data**, Machine Learning na hasa Deep Learning, hufanya FastAPI ifae sana kwa API na programu za wavuti za Sayansi ya Data / Machine Learning (miongoni mwa nyingine nyingi).
Ili kuona jinsi ya kufanikisha parallelism hii katika mazingira ya matumizi halisi, angalia sehemu kuhusu [Deployment](deployment/index.md).
## `async` na `await` { #async-and-await }
Matoleo ya kisasa ya Python yana njia rahisi sana kueleweka ya kufafanua msimbo wa asynchronous. Hii hufanya uonekane kama msimbo wa kawaida wa "mfuatano" na kufanya "kusubiri" kwa niaba yako katika nyakati zinazofaa.
Kunapokuwa na operesheni itakayohitaji kusubiri kabla ya kutoa matokeo na ambayo ina uwezo wa kutumia vipengele hivi vipya vya Python, unaweza kuiandika hivi:
```Python
burgers = await get_burgers(2)
```
Jambo muhimu hapa ni `await`. Inaiambia Python kwamba inapaswa kusubiri ⏸ `get_burgers(2)` imalize kufanya kazi yake 🕙 kabla ya kuhifadhi matokeo kwenye `burgers`. Kwa hilo, Python itajua kwamba inaweza kwenda kufanya kitu kingine 🔀 ⏯ wakati huo (kama kupokea ombi jingine).
Ili `await` ifanye kazi, lazima iwe ndani ya kitendakazi kinachowezesha namna hii ya kufanya kazi kwa asynchronous. Ili kufanya hivyo, unakitangaza tu kwa `async def`:
```Python hl_lines="1"
async def get_burgers(number: int):
# Fanya mambo fulani kwa asynchronous ili kuandaa baga
return burgers
```
...badala ya `def`:
```Python hl_lines="2"
# Hii si asynchronous
def get_sequential_burgers(number: int):
# Fanya mambo fulani kwa mfuatano ili kuandaa baga
return burgers
```
Kwa `async def`, Python inajua kwamba, ndani ya kitendakazi hicho, inapaswa kuzingatia semi za `await`, na kwamba inaweza "kusitisha kwa muda" ⏸ utekelezaji wa kitendakazi hicho na kwenda kufanya kitu kingine 🔀 kabla ya kurudi.
Unapotaka kuita kitendakazi cha `async def`, unapaswa kukisubiri kwa `await`. Kwa hiyo, hii haitafanya kazi:
```Python
# Hii haitafanya kazi, kwa sababu get_burgers ilifafanuliwa kwa: async def
burgers = get_burgers(2)
```
---
Kwa hiyo, ikiwa unatumia maktaba inayokuambia kwamba unaweza kuiita kwa `await`, unahitaji kuunda *vitendakazi vya operesheni za njia* vinavyoitumia kwa `async def`, kama katika:
```Python hl_lines="2-3"
@app.get("/burgers")
async def read_burgers():
burgers = await get_burgers(2)
return burgers
```
### Maelezo zaidi ya kiufundi { #more-technical-details }
Huenda umeona kwamba `await` inaweza kutumika tu ndani ya vitendakazi vilivyofafanuliwa kwa `async def`.
Lakini wakati huo huo, vitendakazi vilivyofafanuliwa kwa `async def` vinapaswa "kusubiriwa" kwa `await`. Kwa hiyo, vitendakazi vyenye `async def` vinaweza kuitwa tu ndani ya vitendakazi ambavyo pia vimefafanuliwa kwa `async def`.
Kwa hiyo, kuhusu yai na kuku, unaitaje kitendakazi cha kwanza cha `async`?
Ikiwa unatumia **FastAPI**, huhitaji kuwa na wasiwasi kuhusu hilo, kwa sababu kitendakazi hicho cha "kwanza" kitakuwa *kitendakazi chako cha operesheni ya njia*, na FastAPI itajua jinsi ya kufanya jambo linalofaa.
Lakini ikiwa unataka kutumia `async` / `await` bila FastAPI, unaweza kufanya hivyo pia.
### Andika msimbo wako mwenyewe wa async { #write-your-own-async-code }
Starlette (na **FastAPI**) zimejengwa juu ya [AnyIO](https://anyio.readthedocs.io/en/stable/), ambayo inazifanya ziendane na [asyncio](https://docs.python.org/3/library/asyncio-task.html) ya maktaba ya kawaida ya Python pamoja na [Trio](https://trio.readthedocs.io/en/stable/).
Hasa, unaweza kutumia [AnyIO](https://anyio.readthedocs.io/en/stable/) moja kwa moja kwa matumizi yako ya hali ya juu ya concurrency yanayohitaji mifumo ya hali ya juu zaidi katika msimbo wako.
Na hata kama hutumii FastAPI, unaweza pia kuandika programu zako mwenyewe za async kwa [AnyIO](https://anyio.readthedocs.io/en/stable/) ili ziwe na uoanifu mkubwa na kupata manufaa yake (k.m. *structured concurrency*).
Niliunda maktaba nyingine juu ya AnyIO, kama tabaka jepesi juu yake, ili kuboresha kidogo maelezo ya aina na kupata **ukamilishaji wa kiotomatiki** bora zaidi, **makosa yanayoonyeshwa ndani ya msimbo**, n.k. Pia ina utangulizi na mafunzo rahisi kufuata ili kukusaidia **kuelewa** na kuandika **msimbo wako mwenyewe wa async**: [Asyncer](https://asyncer.tiangolo.com/). Ingefaa hasa ikiwa unahitaji **kuchanganya msimbo wa async na msimbo wa kawaida** (blocking/synchronous).
### Aina nyingine za msimbo wa asynchronous { #other-forms-of-asynchronous-code }
Mtindo huu wa kutumia `async` na `await` ni mpya kiasi katika lugha hii.
Lakini unafanya kazi na msimbo wa asynchronous iwe rahisi zaidi.
Sintaksia hii hii (au inayokaribia kufanana kabisa) pia iliongezwa hivi karibuni katika matoleo ya kisasa ya JavaScript (kwenye Kivinjari na NodeJS).
Lakini kabla ya hapo, kushughulikia msimbo wa asynchronous kulikuwa na uchangamano na ugumu zaidi.
Katika matoleo ya awali ya Python, ungeweza kutumia threads au [Gevent](https://www.gevent.org/). Lakini msimbo huo ni changamano zaidi kuuelewa, kutafuta na kurekebisha makosa yake, na kuufikiria.
Katika matoleo ya awali ya NodeJS / JavaScript ya Kivinjari, ungetumia "callbacks". Jambo linalosababisha "callback hell".
## Coroutines { #coroutines }
**Coroutine** ni neno la kitaalamu tu kwa kitu kinachorudishwa na kitendakazi cha `async def`. Python inajua kwamba ni kitu kinachofanana na kitendakazi, ambacho inaweza kukianzisha na ambacho kitakamilika wakati fulani, lakini ambacho pia kinaweza kusitishwa kwa muda ⏸ ndani yake, kila kunapokuwa na `await` ndani yake.
Lakini utendaji huu wote wa kutumia msimbo wa asynchronous kwa `async` na `await` mara nyingi hufupishwa kama kutumia "coroutines". Unalinganishwa na kipengele kikuu muhimu cha Go, "Goroutines".
## Hitimisho { #conclusion }
Hebu tuangalie kauli ileile ya hapo juu:
> Matoleo ya kisasa ya Python yana uwezo wa kutumia **"msimbo wa asynchronous"** kwa kutumia kitu kinachoitwa **"coroutines"**, kwa sintaksia ya **`async` na `await`**.
Hiyo sasa inapaswa kueleweka zaidi. ✨
Hayo yote ndiyo yanayowezesha FastAPI kufanya kazi (kupitia Starlette) na kuifanya iwe na utendaji wa kuvutia kiasi hicho.
## Maelezo ya Kina Sana ya Kiufundi { #very-technical-details }
/// warning | Onyo
Huenda unaweza kuruka sehemu hii.
Haya ni maelezo ya kina sana ya kiufundi kuhusu jinsi **FastAPI** inavyofanya kazi ndani yake.
Ikiwa una ujuzi wa kutosha wa kiufundi (coroutines, threads, blocking, n.k.) na una shauku ya kujua jinsi FastAPI inavyoshughulikia `async def` ikilinganishwa na `def` ya kawaida, endelea.
///
### Vitendakazi vya operesheni za njia { #path-operation-functions }
Unapotangaza *kitendakazi cha operesheni ya njia* kwa `def` ya kawaida badala ya `async def`, kinaendeshwa katika threadpool ya nje ambayo kisha husubiriwa kwa `await`, badala ya kuitwa moja kwa moja (kwani kingezuia seva kuendelea na kazi nyingine).
Ikiwa unatoka kwenye framework nyingine ya async ambayo haifanyi kazi kwa namna iliyoelezwa hapo juu na umezoea kufafanua *vitendakazi vya operesheni za njia* rahisi vya kufanya hesabu tu kwa `def` ya kawaida ili kupata ongezeko dogo la utendaji (takribani nanosekunde 100), tafadhali kumbuka kwamba katika **FastAPI** matokeo yatakuwa kinyume kabisa. Katika hali hizi, ni bora kutumia `async def` isipokuwa *vitendakazi vyako vya operesheni za njia* vinatumia msimbo unaofanya operesheni za <abbr title="Input/Output - Ingizo/Tokeo: kusoma au kuandika kwenye diski, mawasiliano ya mtandao.">I/O</abbr> zinazozuia utekelezaji kuendelea.
Hata hivyo, katika hali zote mbili, kuna uwezekano kwamba **FastAPI** [bado itakuwa na kasi zaidi](index.md#performance) kuliko (au angalau kulingana na) framework yako ya awali.
### Vitegemezi { #dependencies }
Hali hiyo hiyo inatumika kwa [vitegemezi](tutorial/dependencies/index.md). Ikiwa kitegemezi ni kitendakazi cha kawaida cha `def` badala ya `async def`, kinaendeshwa katika threadpool ya nje.
### Vitegemezi vya vitegemezi vingine { #sub-dependencies }
Unaweza kuwa na vitegemezi vingi na [vitegemezi vya vitegemezi vingine](tutorial/dependencies/sub-dependencies.md) vinavyohitajiana (kama vigezo katika ufafanuzi wa vitendakazi), baadhi yake vinaweza kuundwa kwa `async def` na vingine kwa `def` ya kawaida. Bado vitafanya kazi, na vile vilivyoundwa kwa `def` ya kawaida vitaitwa kwenye thread ya nje (kutoka kwenye threadpool) badala ya "kusubiriwa" kwa `await`.
### Vitendakazi vingine vya usaidizi { #other-utility-functions }
Kitendakazi kingine chochote cha usaidizi unachokiita moja kwa moja kinaweza kuundwa kwa `def` ya kawaida au `async def`, na FastAPI haitaathiri namna unavyokiita.
Hii ni tofauti na vitendakazi ambavyo FastAPI inaita kwa niaba yako: *vitendakazi vya operesheni za njia* na vitegemezi.
Ikiwa kitendakazi chako cha usaidizi ni kitendakazi cha kawaida chenye `def`, kitaitwa moja kwa moja (kama unavyokiandika katika msimbo wako), si katika threadpool; ikiwa kitendakazi kimeundwa kwa `async def`, basi unapaswa kutumia `await` kwa kitendakazi hicho unapokiita katika msimbo wako.
---
Kwa mara nyingine, haya ni maelezo ya kina sana ya kiufundi ambayo huenda yakawa na manufaa ikiwa ulikuja kuyatafuta.
Vinginevyo, miongozo ya sehemu iliyo hapo juu inapaswa kukutosha: <a href="#in-a-hurry">Una haraka?</a>.
+581
View File
@@ -0,0 +1,581 @@
---
include_yaml:
sponsors: data/sponsors.yml
---
# FastAPI { #fastapi }
<style>
.md-content .md-typeset h1 { display: none; }
</style>
<p align="center">
<a href="https://fastapi.tiangolo.com/sw"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
</p>
<p align="center">
<em>Framework ya FastAPI, yenye utendaji wa juu, rahisi kujifunza, ya haraka kuandika msimbo, tayari kwa matumizi halisi</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Majaribio">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Kiwango cha msimbo unaopimwa">
</a>
<a href="https://pypi.org/project/fastapi">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Toleo la kifurushi">
</a>
<a href="https://pypi.org/project/fastapi">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Matoleo ya Python yanayoungwa mkono">
</a>
</p>
---
**Nyaraka**: [https://fastapi.tiangolo.com/sw](https://fastapi.tiangolo.com/sw)
**Msimbo Chanzo**: [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)
---
FastAPI ni framework ya wavuti ya kisasa, ya haraka (yenye utendaji wa juu), ya kujenga API kwa Python kwa kutumia vidokezo vya aina vya kawaida vya Python.
Vipengele vyake muhimu ni:
* **Haraka**: Utendaji wa juu sana, sawa na **NodeJS** na **Go** (shukrani kwa Starlette na Pydantic). [Mojawapo ya framework za Python zenye kasi kubwa zaidi zinazopatikana](#performance).
* **Haraka kuandika msimbo**: Ongeza kasi ya kuunda vipengele kwa takribani 200% hadi 300%. *
* **Hitilafu chache**: Punguza takribani 40% ya makosa yanayosababishwa na binadamu (waundaji wa programu). *
* **Rahisi kuelewa**: Usaidizi mzuri katika kihariri. <dfn title="pia hujulikana kama ukamilishaji otomatiki, autocompletion, IntelliSense">Ukamilishaji</dfn> kila mahali. Muda mchache wa kutafuta na kurekebisha hitilafu.
* **Rahisi**: Imebuniwa kuwa rahisi kutumia na kujifunza. Muda mchache wa kusoma nyaraka.
* **Fupi**: Punguza urudiaji wa msimbo. Vipengele vingi kutokana na kila tamko la kigezo. Hitilafu chache.
* **Imara**: Pata msimbo ulio tayari kwa matumizi halisi. Pamoja na nyaraka shirikishi zinazozalishwa kiotomatiki.
* **Inafuata viwango**: Inategemea (na inaendana kikamilifu na) viwango huria vya API: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (iliyokuwa ikijulikana kama Swagger) na [JSON Schema](https://json-schema.org/).
<small>* makadirio yanayotokana na majaribio yaliyofanywa na timu ya ndani ya uundaji wa programu, ikijenga programu kwa matumizi halisi.</small>
## Wadhamini { #sponsors }
<!-- sponsors -->
### Mdhamini Mkuu { #keystone-sponsor }
<div class="fastapi-sponsors fastapi-sponsors--keystone">
{% for sponsor in sponsors.keystone -%}
<a class="fastapi-sponsors__card fastapi-sponsors__card--keystone" href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img class="fastapi-sponsors__banner" src="{{ sponsor.img }}" alt="{{ sponsor.title }}"></a>
{% endfor -%}
</div>
### Wadhamini wa Dhahabu { #gold-sponsors }
<div class="fastapi-sponsors fastapi-sponsors--gold">
{% for sponsor in sponsors.gold -%}
<a class="fastapi-sponsors__card fastapi-sponsors__card--gold" href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img class="fastapi-sponsors__banner" src="{{ sponsor.img }}" alt="{{ sponsor.title }}" loading="lazy"></a>
{% endfor -%}
</div>
### Wadhamini wa Fedha { #silver-sponsors }
<div class="fastapi-sponsors fastapi-sponsors--silver">
{% for sponsor in sponsors.silver -%}
<a class="fastapi-sponsors__card fastapi-sponsors__card--silver" href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img class="fastapi-sponsors__banner" src="{{ sponsor.img }}" alt="{{ sponsor.title }}" loading="lazy"></a>
{% endfor %}
</div>
<!-- /sponsors -->
[Wadhamini wengine](https://fastapi.tiangolo.com/sw/fastapi-people/#sponsors)
## Maoni { #opinions }
<!-- only-mkdocs -->
<div class="fastapi-opinions" data-fastapi-opinions>
<div class="fastapi-opinions__tabs" role="tablist" aria-label="Kampuni zinazotumia FastAPI">
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-microsoft" aria-controls="fo-panel-microsoft" aria-selected="true" tabindex="0">
<span class="fastapi-opinions__mark"><img src="/img/logos/microsoft.svg" alt="Microsoft" loading="lazy"></span>
</button>
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-uber" aria-controls="fo-panel-uber" aria-selected="false" tabindex="-1">
<span class="fastapi-opinions__mark"><img src="/img/logos/uber.svg" alt="Uber" loading="lazy"></span>
</button>
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-netflix" aria-controls="fo-panel-netflix" aria-selected="false" tabindex="-1">
<span class="fastapi-opinions__mark"><img src="/img/logos/netflix.svg" alt="Netflix" loading="lazy"></span>
</button>
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-cisco" aria-controls="fo-panel-cisco" aria-selected="false" tabindex="-1">
<span class="fastapi-opinions__mark"><img src="/img/logos/cisco.svg" alt="Cisco" loading="lazy"></span>
</button>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-microsoft" role="tabpanel" aria-labelledby="fo-tab-microsoft" tabindex="0">
<blockquote class="fastapi-opinions__quote">"Ninatumia <strong>FastAPI</strong> sana siku hizi. Kwa kweli ninapanga kuitumia kwa <strong>huduma zote za ML za timu yangu katika Microsoft</strong>. Baadhi yake zinaunganishwa kwenye bidhaa kuu ya <strong>Windows</strong> na baadhi ya bidhaa za <strong>Office</strong>."</blockquote>
<div class="fastapi-opinions__attr">— Kabir Khan, <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26">(rejea)</a></div>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-uber" role="tabpanel" aria-labelledby="fo-tab-uber" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"Tulichagua maktaba ya <strong>FastAPI</strong> kuanzisha seva ya <strong>REST</strong> inayoweza kuulizwa ili kupata <strong>utabiri</strong>." <em>[kwa Ludwig]</em></blockquote>
<div class="fastapi-opinions__attr">— Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/">(rejea)</a></div>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-netflix" role="tabpanel" aria-labelledby="fo-tab-netflix" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"<strong>Netflix</strong> inafuraha kutangaza kutolewa kwa framework yetu ya uratibu wa <strong>usimamizi wa migogoro</strong> kama programu ya msimbo huria: <strong>Dispatch</strong>!" <em>[imejengwa kwa FastAPI]</em></blockquote>
<div class="fastapi-opinions__attr">— Kevin Glisson, Marc Vilanova, Forest Monsen, <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072">(rejea)</a></div>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-cisco" role="tabpanel" aria-labelledby="fo-tab-cisco" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"Ikiwa mtu yeyote anataka kujenga API ya Python kwa matumizi halisi, ningependekeza sana <strong>FastAPI</strong>. <strong>Imebuniwa kwa ustadi</strong>, ni <strong>rahisi kutumia</strong> na <strong>ina uwezo mkubwa wa kukua kulingana na mahitaji</strong> — imekuwa <strong>sehemu muhimu</strong> ya mkakati wetu wa uundaji wa programu unaotanguliza API."</blockquote>
<div class="fastapi-opinions__attr">— Deon Pillsbury, <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/">(rejea)</a></div>
</div>
</div>
<!-- /only-mkdocs -->
<div class="only-github" markdown="1">
"_[...] Ninatumia **FastAPI** sana siku hizi. [...] Kwa kweli ninapanga kuitumia kwa **huduma zote za ML za timu yangu katika Microsoft**. Baadhi yake zinaunganishwa kwenye bidhaa kuu ya **Windows** na baadhi ya bidhaa za **Office**._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(rejea)</small></a></div>
---
"_Tulichagua maktaba ya **FastAPI** kuanzisha seva ya **REST** inayoweza kuulizwa ili kupata **utabiri**. [kwa Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, na Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/"><small>(rejea)</small></a></div>
---
"_**Netflix** inafuraha kutangaza kutolewa kwa framework yetu ya uratibu wa **usimamizi wa migogoro** kama programu ya msimbo huria: **Dispatch**! [imejengwa kwa **FastAPI**]_"
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(rejea)</small></a></div>
---
"_Ikiwa mtu yeyote anataka kujenga API ya Python kwa matumizi halisi, ningependekeza sana **FastAPI**. **Imebuniwa kwa ustadi**, ni **rahisi kutumia** na **ina uwezo mkubwa wa kukua kulingana na mahitaji**, imekuwa **sehemu muhimu** ya mkakati wetu wa uundaji wa programu unaotanguliza API na inaendesha kazi nyingi za kiotomatiki na huduma kama vile Virtual TAC Engineer yetu._"
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(rejea)</small></a></div>
---
</div>
## Filamu fupi ya makala kuhusu FastAPI { #fastapi-mini-documentary }
Kuna [filamu fupi ya makala kuhusu FastAPI](https://www.youtube.com/watch?v=mpR8ngthqiE) iliyotolewa mwishoni mwa 2025, unaweza kuitazama mtandaoni:
<a class="fastapi-feature-banner" href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="Filamu Fupi ya Makala kuhusu FastAPI"></a>
## **Typer**, FastAPI ya CLI { #typer-the-fastapi-of-clis }
<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
Ikiwa unajenga programu ya <abbr title="Command Line Interface - Kiolesura cha Mstari wa Amri">CLI</abbr> itakayotumika kwenye terminal badala ya API ya wavuti, angalia [**Typer**](https://typer.tiangolo.com/).
**Typer** ni mdogo wake FastAPI. Na imekusudiwa kuwa **FastAPI ya CLI**. ⌨️ 🚀
## Mahitaji { #requirements }
FastAPI imejengwa juu ya kazi kubwa za wengine:
* [Starlette](https://starlette.dev/) kwa sehemu za wavuti.
* [Pydantic](https://pydantic.dev/docs/) kwa sehemu za data.
## Usakinishaji { #installation }
Kwanza, [sakinisha `uv`](https://docs.astral.sh/uv/getting-started/installation/), kisha ongeza FastAPI kwenye mradi wako:
<div class="termy">
```console
$ uv add "fastapi[standard]"
---> 100%
```
</div>
**Kumbuka**: Hakikisha unaweka `"fastapi[standard]"` ndani ya alama za kunukuu ili ifanye kazi katika terminal zote.
Ikiwa unapendelea kutumia `pip`, sakinisha `fastapi[standard]` ndani ya mazingira pepe. Angalia [mwongozo wa usakinishaji](tutorial/#install-fastapi) kwa hatua mbadala.
## Mfano { #example }
### Iunde { #create-it }
Unda faili `main.py` yenye:
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
```
<details markdown="1">
<summary>Au tumia <code>async def</code>...</summary>
Ikiwa msimbo wako unatumia `async` / `await`, tumia `async def`:
```Python hl_lines="7 12"
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
```
**Kumbuka**:
Ikiwa huna uhakika, angalia sehemu ya _"Una haraka?"_ kuhusu [`async` na `await` kwenye nyaraka](https://fastapi.tiangolo.com/sw/async/#in-a-hurry).
</details>
### Iendeshe { #run-it }
Endesha seva kwa:
<div class="termy">
```console
$ uv run fastapi dev
╭────────── FastAPI CLI - Development mode ───────────╮
│ │
│ Serving at: http://127.0.0.1:8000 │
│ │
│ API docs: http://127.0.0.1:8000/docs │
│ │
│ Running in development mode, for production use: │
│ │
│ fastapi run │
│ │
╰─────────────────────────────────────────────────────╯
INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [2248755] using WatchFiles
INFO: Started server process [2248757]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
</div>
<details markdown="1">
<summary>Kuhusu amri <code>fastapi dev</code>...</summary>
Amri `fastapi dev` husoma faili lako la `main.py` kiotomatiki, hutambua programu ya **FastAPI** iliyomo, na huanzisha seva kwa kutumia [Uvicorn](https://uvicorn.dev).
Kwa chaguo-msingi, `fastapi dev` huanza ikiwa na upakiaji upya wa kiotomatiki uliowezeshwa kwa uundaji wa programu kwenye kompyuta yako.
Unaweza kusoma zaidi kuihusu kwenye [nyaraka za FastAPI CLI](https://fastapi.tiangolo.com/sw/fastapi-cli/).
</details>
### Iangalie { #check-it }
Fungua kivinjari chako kwenye [http://127.0.0.1:8000/items/5?q=somequery](http://127.0.0.1:8000/items/5?q=somequery).
Utaona jibu la JSON kama:
```JSON
{"item_id": 5, "q": "somequery"}
```
Tayari umeunda API ambayo:
* Inapokea maombi ya HTTP kwenye _njia_ `/` na `/items/{item_id}`.
* _Njia_ zote mbili zinakubali <em>operesheni</em> za `GET` (pia hujulikana kama _mbinu_ za HTTP).
* _Njia_ `/items/{item_id}` ina _kigezo cha njia_ `item_id` ambacho kinapaswa kuwa `int`.
* _Njia_ `/items/{item_id}` ina _kigezo cha hoja_ `q` cha hiari cha aina ya `str`.
### Nyaraka shirikishi za API { #interactive-api-docs }
Sasa nenda kwenye [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Utaona nyaraka shirikishi za API zinazozalishwa kiotomatiki (zinazotolewa na [Swagger UI](https://github.com/swagger-api/swagger-ui)):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Nyaraka mbadala za API { #alternative-api-docs }
Na sasa, nenda kwenye [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
Utaona nyaraka mbadala zinazozalishwa kiotomatiki (zinazotolewa na [ReDoc](https://github.com/Redocly/redoc)):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Kuboresha mfano { #example-upgrade }
Sasa rekebisha faili `main.py` ili lipokee mwili wa ombi la `PUT`.
Tamka mwili huo kwa kutumia aina za kawaida za Python, shukrani kwa Pydantic.
```Python hl_lines="2 7-10 23-25"
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool | None = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
Seva ya `fastapi dev` inapaswa kupakia upya kiotomatiki.
### Kuboresha nyaraka shirikishi za API { #interactive-api-docs-upgrade }
Sasa nenda kwenye [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
* Nyaraka shirikishi za API zitasasishwa kiotomatiki, zikijumuisha mwili mpya wa ombi:
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Bofya kitufe cha "Try it out", kinakuruhusu kujaza vigezo na kuingiliana moja kwa moja na API:
![Mwingiliano wa Swagger UI](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
* Kisha bofya kitufe cha "Execute", kiolesura cha mtumiaji kitawasiliana na API yako, kutuma vigezo, kupata matokeo na kuyaonyesha kwenye skrini:
![Mwingiliano wa Swagger UI](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### Kuboresha nyaraka mbadala za API { #alternative-api-docs-upgrade }
Na sasa, nenda kwenye [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
* Nyaraka mbadala pia zitaonyesha kigezo kipya cha hoja na mwili wa ombi:
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Muhtasari { #recap }
Kwa ufupi, unatamka **mara moja** aina za vigezo, mwili wa ombi, n.k. kama vigezo vya function.
Unafanya hivyo kwa kutumia aina za kawaida za kisasa za Python.
Huhitaji kujifunza sintaksia mpya, mbinu au madarasa ya maktaba fulani, n.k.
Ni **Python** ya kawaida tu.
Kwa mfano, kwa `int`:
```Python
item_id: int
```
au kwa modeli changamano zaidi ya `Item`:
```Python
item: Item
```
...na kwa tamko hilo moja unapata:
* Usaidizi wa kihariri, ukiwemo:
* Ukamilishaji.
* Ukaguzi wa aina.
* Uhakiki wa uhalali wa data:
* Ujumbe wa makosa ulio wazi unaotolewa kiotomatiki data inapokuwa si halali.
* Uhakiki hata kwa objekti za JSON zilizopachikwa ndani ya nyingine kwa kina.
* <dfn title="pia hujulikana kama: serialization, uchanganuzi, marshalling">Ubadilishaji</dfn> wa data ya ingizo: inayotoka kwenye mtandao kuwa data na aina za Python. Kusoma kutoka:
* JSON.
* Vigezo vya njia.
* Vigezo vya hoja.
* Vidakuzi.
* Vichwa.
* Fomu.
* Faili.
* <dfn title="pia hujulikana kama: serialization, uchanganuzi, marshalling">Ubadilishaji</dfn> wa data ya matokeo: kubadilisha data na aina za Python kuwa data ya mtandao (kama JSON):
* Kubadilisha aina za Python (`str`, `int`, `float`, `bool`, `list`, n.k.).
* Objekti za `datetime`.
* Objekti za `UUID`.
* Modeli za hifadhidata.
* ...na nyingine nyingi.
* Nyaraka shirikishi za API zinazozalishwa kiotomatiki, zikiwemo chaguo 2 za violesura vya mtumiaji:
* Swagger UI.
* ReDoc.
---
Tukirudi kwenye mfano wa msimbo uliotangulia, **FastAPI** itafanya yafuatayo:
* Kuhakiki kuwa kuna `item_id` kwenye njia kwa maombi ya `GET` na `PUT`.
* Kuhakiki kuwa `item_id` ni ya aina ya `int` kwa maombi ya `GET` na `PUT`.
* Ikiwa sivyo, mteja ataona ujumbe wa kosa ulio wazi na wenye manufaa.
* Kukagua ikiwa kuna kigezo cha hoja cha hiari kinachoitwa `q` (kama kwenye `http://127.0.0.1:8000/items/foo?q=somequery`) kwa maombi ya `GET`.
* Kwa kuwa kigezo cha `q` kimetamkwa na `= None`, ni cha hiari.
* Bila `None` kingehitajika (kama mwili wa ombi unavyohitajika kwa `PUT`).
* Kwa maombi ya `PUT` kwenda `/items/{item_id}`, kusoma mwili wa ombi kama JSON:
* Kukagua kuwa una sifa inayohitajika ya `name` ambayo inapaswa kuwa `str`.
* Kukagua kuwa una sifa inayohitajika ya `price` ambayo lazima iwe `float`.
* Kukagua kuwa una sifa ya hiari ya `is_offer`, ambayo inapaswa kuwa `bool`, ikiwa ipo.
* Yote haya yangefanya kazi pia kwa objekti za JSON zilizopachikwa ndani ya nyingine kwa kina.
* Kubadilisha kutoka na kwenda JSON kiotomatiki.
* Kuandika nyaraka za kila kitu kwa OpenAPI, zinazoweza kutumiwa na:
* Mifumo ya nyaraka shirikishi.
* Mifumo ya kuzalisha msimbo wa mteja kiotomatiki, kwa lugha nyingi.
* Kutoa moja kwa moja violesura 2 vya wavuti vya nyaraka shirikishi.
---
Tumegusia kwa juu juu tu, lakini tayari unaelewa jinsi yote yanavyofanya kazi.
Jaribu kubadilisha mstari wenye:
```Python
return {"item_name": item.name, "item_id": item_id}
```
...kutoka:
```Python
... "item_name": item.name ...
```
...kuwa:
```Python
... "item_price": item.price ...
```
...na uone jinsi kihariri chako kitakavyokamilisha sifa kiotomatiki na kujua aina zake:
![usaidizi wa kihariri](https://fastapi.tiangolo.com/img/vscode-completion.png)
Kwa mfano kamili zaidi unaojumuisha vipengele zaidi, angalia <a href="https://fastapi.tiangolo.com/sw/tutorial/">Mafunzo - Mwongozo wa Mtumiaji</a>.
**Dokezo la yaliyomo**: mafunzo - mwongozo wa mtumiaji unajumuisha:
* Utamkaji wa **vigezo** kutoka sehemu nyingine tofauti kama vile: **vichwa**, **vidakuzi**, **nyuga za fomu** na **faili**.
* Jinsi ya kuweka **vikwazo vya uhakiki wa uhalali** kama vile `maximum_length` au `regex`.
* Mfumo wenye uwezo mkubwa na rahisi kutumia wa **<dfn title="pia hujulikana kama vipengele, rasilimali, watoa huduma, huduma, vipengele vinavyoweza kudungwa">Udungaji wa Vitegemezi</dfn>**.
* Usalama na uthibitishaji wa utambulisho, ikiwemo usaidizi wa **OAuth2** yenye **tokeni za JWT** na uthibitishaji wa utambulisho wa **HTTP Basic**.
* Mbinu za kiwango cha juu zaidi (lakini rahisi vilevile) za kutamka **modeli za JSON zilizopachikwa ndani ya nyingine kwa kina** (shukrani kwa Pydantic).
* Uunganishaji wa **GraphQL** na [Strawberry](https://strawberry.rocks) na maktaba nyingine.
* Vipengele vingi vya ziada (shukrani kwa Starlette) kama vile:
* **WebSockets**
* majaribio rahisi sana yanayotumia HTTPX na `pytest`
* **CORS**
* **Vikao vya Vidakuzi**
* ...na zaidi.
### Weka programu yako iweze kuendeshwa (hiari) { #deploy-your-app-optional }
Ukipenda, unaweza kuweka programu yako ya FastAPI iweze kuendeshwa kwenye [FastAPI Cloud](https://fastapicloud.com) kwa amri moja. 🚀
<div class="termy">
```console
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
CLI itatambua programu yako ya FastAPI kiotomatiki na kuiweka iweze kuendeshwa kwenye wingu. Ikiwa hujaingia katika akaunti yako, kivinjari chako kitafunguka ili kukamilisha mchakato wa uthibitishaji wa utambulisho.
Ni hivyo tu! Sasa unaweza kufikia programu yako kwenye URL hiyo. ✨
#### Kuhusu FastAPI Cloud { #about-fastapi-cloud }
**[FastAPI Cloud](https://fastapicloud.com)** imejengwa na mtunzi yuleyule na timu iliyounda **FastAPI**.
Inarahisisha mchakato wa **kujenga**, **kuweka iweze kuendeshwa**, na **kufikia** API kwa juhudi ndogo sana.
Inaleta **urahisi uleule kwa waundaji wa programu** wanaojenga programu kwa FastAPI kwenye mchakato wa **kuziweka ziweze kuendeshwa** kwenye wingu. 🎉
FastAPI Cloud ndiyo mdhamini mkuu na mtoa ufadhili wa miradi ya msimbo huria ya *FastAPI na marafiki*. ✨
#### Weka programu iweze kuendeshwa kwa watoa huduma wengine wa wingu { #deploy-to-other-cloud-providers }
FastAPI ni ya msimbo huria na inafuata viwango. Unaweza kuweka programu za FastAPI ziweze kuendeshwa kwa mtoa huduma yeyote wa wingu unayemchagua.
Fuata miongozo ya mtoa huduma wako wa wingu ili kuweka programu za FastAPI ziweze kuendeshwa kwake. 🤓
## Utendaji { #performance }
Vipimo huru vya utendaji vya TechEmpower vinaonyesha programu za **FastAPI** zinazoendeshwa kwa Uvicorn zikiifanya iwe [mojawapo ya framework za Python zenye kasi kubwa zaidi zinazopatikana](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), ikizidiwa tu na Starlette na Uvicorn zenyewe (zinazotumiwa ndani ya FastAPI). (*)
Ili kuelewa zaidi kuhusu hili, angalia sehemu ya [Vipimo vya Utendaji](https://fastapi.tiangolo.com/sw/benchmarks/).
## Vitegemezi { #dependencies }
FastAPI inategemea Pydantic na Starlette.
### Vitegemezi vya `standard` { #standard-dependencies }
Unaposakinisha FastAPI kwa `uv add "fastapi[standard]"` inakuja na kundi la `standard` la vitegemezi vya hiari:
Vinavyotumiwa na Pydantic:
* [`email-validator`](https://github.com/JoshData/python-email-validator) - kwa uhakiki wa uhalali wa anwani za barua pepe.
Vinavyotumiwa na Starlette:
* [`httpx2`](https://pydantic.dev/docs/httpx2/) (au `httpx`) - Hutumiwa na `TestClient`.
* [`jinja2`](https://jinja.palletsprojects.com) - Inahitajika ikiwa unataka kutumia usanidi wa chaguo-msingi wa violezo.
* [`python-multipart`](https://github.com/Kludex/python-multipart) - Inahitajika ikiwa unataka kuwezesha <dfn title="kubadilisha mfuatano wa herufi unaotoka kwenye ombi la HTTP kuwa data ya Python">"uchanganuzi"</dfn> wa fomu, kwa `request.form()`.
Vinavyotumiwa na FastAPI:
* [`uvicorn`](https://uvicorn.dev) - kwa seva inayopakia na kuendesha programu yako ili kuhudumia maombi. Hii inajumuisha `uvicorn[standard]`, ambayo inajumuisha baadhi ya vitegemezi (k.m. `uvloop`) vinavyohitajika kwa kuhudumia maombi kwa utendaji wa juu.
* `fastapi-cli[standard]` - kutoa amri ya `fastapi`.
* Hii inajumuisha `fastapi-cloud-cli`, ambayo inakuwezesha kuweka programu yako ya FastAPI iweze kuendeshwa kwenye [FastAPI Cloud](https://fastapicloud.com).
### Bila Vitegemezi vya `standard` { #without-standard-dependencies }
Ikiwa hutaki kujumuisha vitegemezi vya hiari vya `standard`, unaweza kusakinisha kwa `uv add fastapi` badala ya `uv add "fastapi[standard]"`.
### Bila `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
Ikiwa unataka kusakinisha FastAPI pamoja na vitegemezi vya kawaida lakini bila `fastapi-cloud-cli`, unaweza kusakinisha kwa `uv add "fastapi[standard-no-fastapi-cloud-cli]"`.
### Vitegemezi vya Ziada vya Hiari { #additional-optional-dependencies }
Kuna baadhi ya vitegemezi vya ziada ambavyo huenda ukataka kusakinisha.
Vitegemezi vya ziada vya hiari vya Pydantic:
* [`pydantic-settings`](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/) - kwa usimamizi wa mipangilio.
* [`pydantic-extra-types`](https://github.com/pydantic/pydantic-extra-types) - kwa aina za ziada za kutumia na Pydantic.
Vitegemezi vya ziada vya hiari vya FastAPI:
* [`orjson`](https://github.com/ijl/orjson) - Inahitajika ikiwa unataka kutumia `ORJSONResponse`.
* [`ujson`](https://github.com/ultrajson/ultrajson) - Inahitajika ikiwa unataka kutumia `UJSONResponse`.
## Leseni { #license }
Mradi huu umepewa leseni chini ya masharti ya leseni ya MIT.
+11
View File
@@ -0,0 +1,11 @@
/// details | 🌐 Tafsiri ya AI na binadamu
Tafsiri hii ilifanywa na AI kwa mwongozo wa binadamu. 🤝
Inaweza kuwa na makosa ya kutoelewa maana ya asili, au lugha isiyo ya kawaida, n.k. 🤖
Unaweza kuboresha tafsiri hii kwa [kutusaidia kuiongoza AI LLM vizuri zaidi](https://fastapi.tiangolo.com/sw/contributing/#translations).
[Toleo la Kiingereza](ENGLISH_VERSION_URL)
///
@@ -0,0 +1,290 @@
# Vitegemezi vyenye yield { #dependencies-with-yield }
FastAPI inasaidia vitegemezi vinavyotekeleza <dfn title='wakati mwingine pia huitwa "msimbo wa kuachilia rasilimali", "msimbo wa usafishaji", "msimbo wa kufunga", "msimbo wa kuondoka kwenye context manager", n.k.'>hatua za ziada baada ya kumaliza</dfn>.
Ili kufanya hivyo, tumia `yield` badala ya `return`, kisha andika hatua za ziada (msimbo) baada yake.
/// tip | Kidokezo
Hakikisha unatumia `yield` mara moja tu kwa kila kitegemezi.
///
/// note | Maelezo ya Kiufundi
Function yoyote inayofaa kutumiwa na:
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) au
* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
inafaa kutumiwa kama kitegemezi cha **FastAPI**.
Kwa kweli, FastAPI hutumia decorators hizo mbili ndani yake.
///
## Kitegemezi cha hifadhidata chenye `yield` { #a-database-dependency-with-yield }
Kwa mfano, unaweza kutumia hili kuunda session ya hifadhidata na kuifunga baada ya kumaliza.
Ni msimbo ulio kabla ya kauli ya `yield`, pamoja na kauli hiyo yenyewe, pekee unaotekelezwa kabla ya kuunda jibu:
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
Thamani inayotolewa na `yield` ndiyo inayoingizwa kwenye *operesheni za njia* na vitegemezi vingine:
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
Msimbo unaofuata kauli ya `yield` hutekelezwa baada ya jibu:
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
/// tip | Kidokezo
Unaweza kutumia functions za `async` au za kawaida.
**FastAPI** itashughulikia kila moja ipasavyo, kama inavyofanya kwa vitegemezi vya kawaida.
///
## Kitegemezi chenye `yield` na `try` { #a-dependency-with-yield-and-try }
Ukitumia block ya `try` kwenye kitegemezi chenye `yield`, utapokea exception yoyote iliyozalishwa wakati wa kutumia kitegemezi hicho.
Kwa mfano, ikiwa msimbo fulani wakati wa utekelezaji, kwenye kitegemezi kingine au kwenye *operesheni ya njia*, ulisababisha muamala wa hifadhidata kufanya "rollback" au ulizalisha exception nyingine yoyote, ungepokea exception hiyo kwenye kitegemezi chako.
Kwa hiyo, unaweza kutambua exception hiyo mahususi ndani ya kitegemezi kwa kutumia `except SomeException`.
Vivyo hivyo, unaweza kutumia `finally` kuhakikisha kwamba hatua za kuachilia rasilimali zinatekelezwa, bila kujali kama kulikuwa na exception au la.
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
## Vitegemezi vya vitegemezi vingine vyenye `yield` { #sub-dependencies-with-yield }
Unaweza kuwa na vitegemezi vya vitegemezi vingine na "miti" ya vitegemezi hivyo ya ukubwa na umbo lolote, na chochote au vyote vinaweza kutumia `yield`.
**FastAPI** itahakikisha kwamba "msimbo wa kuachilia rasilimali" katika kila kitegemezi chenye `yield` unaendeshwa kwa mpangilio sahihi.
Kwa mfano, `dependency_c` kinaweza kutegemea `dependency_b`, na `dependency_b` kikategemea `dependency_a`:
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
Na vyote vinaweza kutumia `yield`.
Katika hali hii, ili `dependency_c` kitekeleze msimbo wake wa kuachilia rasilimali, kinahitaji thamani kutoka `dependency_b` (hapa inaitwa `dep_b`) iendelee kupatikana.
Nacho `dependency_b` kinahitaji thamani kutoka `dependency_a` (hapa inaitwa `dep_a`) ipatikane kwa ajili ya msimbo wake wa kuachilia rasilimali.
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
Vivyo hivyo, unaweza kuwa na baadhi ya vitegemezi vyenye `yield` na vingine vyenye `return`, na baadhi yake vikategemea vingine.
Na unaweza kuwa na kitegemezi kimoja kinachohitaji vitegemezi vingine kadhaa vyenye `yield`, n.k.
Unaweza kuwa na mchanganyiko wowote wa vitegemezi unaotaka.
**FastAPI** itahakikisha kila kitu kinaendeshwa kwa mpangilio sahihi.
/// note | Maelezo ya Kiufundi
Hili linawezekana kutokana na [Context Managers](https://docs.python.org/3/library/contextlib.html) za Python.
**FastAPI** huzitumia ndani yake kufanikisha hili.
///
## Vitegemezi vyenye `yield` na `HTTPException` { #dependencies-with-yield-and-httpexception }
Umeona kwamba unaweza kutumia vitegemezi vyenye `yield` na kuwa na block za `try` zinazojaribu kutekeleza msimbo fulani, kisha kuendesha msimbo wa kuachilia rasilimali baada ya `finally`.
Unaweza pia kutumia `except` kunasa exception iliyozalishwa na kuifanyia jambo fulani.
Kwa mfano, unaweza kuzalisha exception tofauti, kama `HTTPException`.
/// tip | Kidokezo
Hii ni mbinu ya kiwango cha juu kiasi, na katika hali nyingi hutaihitaji, kwa kuwa unaweza kuzalisha exceptions (ikiwemo `HTTPException`) kutoka sehemu nyingine za msimbo wa programu yako, kwa mfano, kwenye *function ya operesheni ya njia*.
Lakini ipo kwa ajili yako ukiihitaji. 🤓
///
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
Ikiwa unataka kunasa exceptions na kuunda jibu maalum kulingana nazo, unda [Kishughulikiaji Maalum cha Exceptions](../handling-errors.md#install-custom-exception-handlers).
## Vitegemezi vyenye `yield` na `except` { #dependencies-with-yield-and-except }
Ukinasa exception kwa kutumia `except` kwenye kitegemezi chenye `yield` na usiizalishe tena (au kuzalisha exception mpya), FastAPI haitaweza kutambua kwamba kulikuwa na exception, kama ambavyo ingetokea katika Python ya kawaida:
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
Katika hali hii, mteja ataona jibu la *HTTP 500 Internal Server Error* kama inavyopaswa, kwa kuwa hatuzalishi `HTTPException` au kitu kama hicho, lakini seva **haitakuwa na kumbukumbu zozote** wala dalili nyingine yoyote ya kosa lililokuwa limetokea. 😱
### Tumia `raise` kila wakati katika Vitegemezi vyenye `yield` na `except` { #always-raise-in-dependencies-with-yield-and-except }
Ukinasa exception kwenye kitegemezi chenye `yield`, isipokuwa kama unazalisha `HTTPException` nyingine au kitu kama hicho, **unapaswa kuzalisha tena exception ya awali**.
Unaweza kuzalisha tena exception ileile kwa kutumia `raise`:
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
Sasa mteja atapata jibu lilelile la *HTTP 500 Internal Server Error*, lakini seva itakuwa na `InternalError` yetu maalum katika kumbukumbu. 😎
## Utekelezaji wa vitegemezi vyenye `yield` { #execution-of-dependencies-with-yield }
Mfuatano wa utekelezaji unafanana kwa kiasi kikubwa na mchoro huu. Muda unasonga kutoka juu kwenda chini. Na kila safu wima ni mojawapo ya sehemu zinazowasiliana au kutekeleza msimbo.
```mermaid
sequenceDiagram
participant client as Client
participant handler as Exception handler
participant dep as Dep with yield
participant operation as Path Operation
participant tasks as Background tasks
Note over client,operation: Can raise exceptions, including HTTPException
client ->> dep: Start request
Note over dep: Run code up to yield
opt raise Exception
dep -->> handler: Raise Exception
handler -->> client: HTTP error response
end
dep ->> operation: Run dependency, e.g. DB session
opt raise
operation -->> dep: Raise Exception (e.g. HTTPException)
opt handle
dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
end
handler -->> client: HTTP error response
end
operation ->> client: Return response to client
Note over client,operation: Response is already sent, can't change it anymore
opt Tasks
operation -->> tasks: Send background tasks
end
opt Raise other exception
tasks -->> tasks: Handle exceptions in the background task code
end
```
/// note | Tanbihi
Ni **jibu moja** pekee litakalotumwa kwa mteja. Linaweza kuwa mojawapo ya majibu ya hitilafu au litakuwa jibu kutoka kwenye *operesheni ya njia*.
Baada ya mojawapo ya majibu hayo kutumwa, hakuna jibu jingine linaloweza kutumwa.
///
/// tip | Kidokezo
Ukizalisha exception yoyote katika msimbo wa *function ya operesheni ya njia*, itapitishwa kwa vitegemezi vyenye yield, ikiwemo `HTTPException`. Katika hali nyingi utataka kuzalisha tena exception ileile au mpya kutoka kwenye kitegemezi chenye `yield` ili kuhakikisha inashughulikiwa ipasavyo.
///
## Kuachilia rasilimali mapema na `scope` { #early-exit-and-scope }
Kwa kawaida, msimbo wa kuachilia rasilimali wa vitegemezi vyenye `yield` hutekelezwa **baada ya jibu** kutumwa kwa mteja.
Lakini ikiwa unajua kwamba hutahitaji kutumia kitegemezi baada ya *function ya operesheni ya njia* kurudisha matokeo, unaweza kutumia `Depends(scope="function")` kuiambia FastAPI kwamba inapaswa kufunga kitegemezi baada ya *function ya operesheni ya njia* kurudisha matokeo, lakini **kabla ya jibu kutumwa**.
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
`Depends()` hupokea kigezo cha `scope` kinachoweza kuwa:
* `"function"`: anza kitegemezi kabla ya *function ya operesheni ya njia* inayoshughulikia ombi, maliza kitegemezi baada ya *function ya operesheni ya njia* kumalizika, lakini **kabla** ya jibu kutumwa kwa mteja. Kwa hiyo, function ya kitegemezi itatekelezwa **kabla na baada ya** ***function* ya operesheni ya njia**.
* `"request"`: anza kitegemezi kabla ya *function ya operesheni ya njia* inayoshughulikia ombi (sawa na unapotumia `"function"`), lakini maliza **baada** ya jibu kutumwa kwa mteja. Kwa hiyo, function ya kitegemezi itatekelezwa **kabla na baada ya** mzunguko wa **ombi** na jibu.
Isipobainishwa na kitegemezi kina `yield`, kitakuwa na `scope` ya `"request"` kwa chaguomsingi.
### `scope` kwa vitegemezi vya vitegemezi vingine { #scope-for-sub-dependencies }
Unapotangaza kitegemezi chenye `scope="request"` (chaguomsingi), kitegemezi chochote kinachotegemewa nacho kinahitaji pia kuwa na `scope` ya `"request"`.
Lakini kitegemezi chenye `scope` ya `"function"` kinaweza kuwa na vitegemezi vyenye `scope` ya `"function"` na `scope` ya `"request"`.
Hii ni kwa sababu kila kitegemezi kinahitaji kuweza kuendesha msimbo wake wa kuachilia rasilimali kabla ya vitegemezi kinavyovitegemea, kwani kinaweza kuhitaji kuendelea kuvitumia wakati wa msimbo wake wa kuachilia rasilimali.
```mermaid
sequenceDiagram
participant client as Client
participant dep_req as Dep scope="request"
participant dep_func as Dep scope="function"
participant operation as Path Operation
client ->> dep_req: Start request
Note over dep_req: Run code up to yield
dep_req ->> dep_func: Pass dependency
Note over dep_func: Run code up to yield
dep_func ->> operation: Run path operation with dependency
operation ->> dep_func: Return from path operation
Note over dep_func: Run code after yield
Note over dep_func: ✅ Dependency closed
dep_func ->> client: Send response to client
Note over client: Response sent
Note over dep_req: Run code after yield
Note over dep_req: ✅ Dependency closed
```
## Vitegemezi vyenye `yield`, `HTTPException`, `except` na Kazi za Chinichini { #dependencies-with-yield-httpexception-except-and-background-tasks }
Vitegemezi vyenye `yield` vimebadilika kadiri muda ulivyopita ili kukidhi hali tofauti za matumizi na kurekebisha matatizo fulani.
Ikiwa unataka kuona kilichobadilika katika matoleo tofauti ya FastAPI, unaweza kusoma zaidi kuhusu hilo kwenye mwongozo wa kiwango cha juu, katika [Vitegemezi vya Kiwango cha Juu - Vitegemezi vyenye `yield`, `HTTPException`, `except` na Kazi za Chinichini](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
## Context Managers { #context-managers }
### "Context Managers" ni nini { #what-are-context-managers }
"Context Managers" ni objects zozote za Python unazoweza kutumia katika kauli ya `with`.
Kwa mfano, [unaweza kutumia `with` kusoma faili](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files):
```Python
with open("./somefile.txt") as f:
contents = f.read()
print(contents)
```
Kwa ndani, `open("./somefile.txt")` huunda object inayoitwa "Context Manager".
Block ya `with` inapomalizika, inahakikisha kwamba faili limefungwa, hata kama kulikuwa na exceptions.
Unapounda kitegemezi chenye `yield`, **FastAPI** itaunda context manager kwa ajili yake ndani kwa ndani, na kuiunganisha na zana nyingine zinazohusiana nayo.
### Kutumia context managers kwenye vitegemezi vyenye `yield` { #using-context-managers-in-dependencies-with-yield }
/// warning | Onyo
Hili ni wazo la "kiwango cha juu" kwa kiasi fulani.
Ikiwa ndio unaanza kutumia **FastAPI**, huenda ukataka kuliruka kwa sasa.
///
Katika Python, unaweza kuunda Context Managers kwa [kuunda class yenye methods mbili: `__enter__()` na `__exit__()`](https://docs.python.org/3/reference/datamodel.html#context-managers).
Unaweza pia kuzitumia ndani ya vitegemezi vya **FastAPI** vyenye `yield` kwa kutumia
kauli za `with` au `async with` ndani ya function ya kitegemezi:
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
/// tip | Kidokezo
Njia nyingine ya kuunda context manager ni kwa kutumia:
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) au
* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
kama decorators za function yenye `yield` moja tu.
Hivyo ndivyo **FastAPI** inavyofanya ndani yake kwa vitegemezi vyenye `yield`.
Lakini huhitaji kutumia decorators hizo kwa vitegemezi vya FastAPI (na hupaswi kufanya hivyo).
FastAPI itakufanyia hilo ndani kwa ndani.
///
+348
View File
@@ -0,0 +1,348 @@
# Modeli ya Jibu - Aina ya Thamani Inayorejeshwa { #response-model-return-type }
Unaweza kutangaza aina inayotumiwa kwa jibu kwa kuwekea *kitendakazi cha operesheni ya njia* **kidokezo cha aina ya thamani inayorejeshwa**.
Unaweza kutumia **vidokezo vya aina** kama unavyofanya kwa data ya ingizo katika **vigezo** vya kitendakazi; unaweza kutumia modeli za Pydantic, orodha, kamusi, thamani za skala kama vile namba kamili, thamani za boolean, n.k.
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
FastAPI itatumia aina hii ya thamani inayorejeshwa kufanya yafuatayo:
* **Kuhakiki uhalali** wa data inayorejeshwa.
* Ikiwa data si halali (k.m. kuna uga unaokosekana), inamaanisha kuwa msimbo wa programu *yako* una hitilafu, haurejeshi kinachotarajiwa, na itarejesha hitilafu ya seva badala ya kurejesha data isiyo sahihi. Kwa njia hii, wewe na wateja wa API yako mnaweza kuwa na uhakika kwamba watapokea data na muundo wa data unaotarajiwa.
* Kuongeza **JSON Schema** ya jibu katika *operesheni ya njia* ya OpenAPI.
* Hii itatumiwa na **nyaraka zinazozalishwa kiotomatiki**.
* Pia itatumiwa na zana zinazozalisha msimbo wa mteja kiotomatiki.
* **Kusirialisha** data inayorejeshwa kuwa JSON kwa kutumia Pydantic, ambayo imeandikwa kwa **Rust**, hivyo itakuwa **haraka zaidi**.
Lakini muhimu zaidi:
* **Itawekea mipaka na kuchuja** data ya matokeo ili ibaki ile tu iliyofafanuliwa katika aina ya thamani inayorejeshwa.
* Hili ni muhimu hasa kwa **usalama**, tutaona zaidi kuhusu hilo hapa chini.
## Kigezo cha `response_model` { #response-model-parameter }
Kuna hali ambapo unahitaji au unataka kurejesha data ambayo hailingani kabisa na aina iliyotangazwa.
Kwa mfano, huenda ukataka **kurejesha kamusi** au objekti ya hifadhidata, lakini **uitangaze kama modeli ya Pydantic**. Kwa njia hii modeli ya Pydantic ingeshughulikia uundaji wa nyaraka zote za data, uhakiki wa uhalali, n.k. kwa objekti uliyorejesha (k.m. kamusi au objekti ya hifadhidata).
Ukiweka kidokezo cha aina ya thamani inayorejeshwa, zana na vihariri vitaonyesha hitilafu (kwa usahihi) vikikuambia kwamba kitendakazi chako kinarejesha aina (k.m. dict) ambayo ni tofauti na uliyotangaza (k.m. modeli ya Pydantic).
Katika hali hizo, unaweza kutumia kigezo cha *decorator ya operesheni ya njia* cha `response_model` badala ya aina ya thamani inayorejeshwa.
Unaweza kutumia kigezo cha `response_model` katika *operesheni yoyote ya njia*:
* `@app.get()`
* `@app.post()`
* `@app.put()`
* `@app.delete()`
* n.k.
{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}
/// note | Kumbuka
Zingatia kwamba `response_model` ni kigezo cha method ya "decorator" (`get`, `post`, n.k.). Si cha *kitendakazi chako cha operesheni ya njia*, kama vilivyo vigezo vyote na mwili wa ombi.
///
`response_model` hupokea aina ileile ambayo ungetangaza kwa uga wa modeli ya Pydantic, hivyo inaweza kuwa modeli ya Pydantic, lakini pia inaweza kuwa, kwa mfano, `list` ya modeli za Pydantic, kama `List[Item]`.
FastAPI itatumia `response_model` hii kufanya uundaji wa nyaraka zote za data, uhakiki wa uhalali, n.k. na pia **kubadilisha na kuchuja data ya matokeo** ili ilingane na aina iliyotangazwa.
/// tip | Kidokezo
Ikiwa una ukaguzi mkali wa aina katika kihariri chako, mypy, n.k., unaweza kutangaza aina ya thamani inayorejeshwa na kitendakazi kuwa `Any`.
Kwa njia hiyo unakiambia kihariri kwamba unarejesha chochote kwa makusudi. Lakini FastAPI bado itafanya uundaji wa nyaraka za data, uhakiki wa uhalali, uchujaji, n.k. kwa kutumia `response_model`.
///
### Kipaumbele cha `response_model` { #response-model-priority }
Ukitangaza aina ya thamani inayorejeshwa pamoja na `response_model`, `response_model` itapewa kipaumbele na kutumiwa na FastAPI.
Kwa njia hii unaweza kuongeza vidokezo sahihi vya aina kwenye vitendakazi vyako hata unaporejesha aina tofauti na modeli ya jibu, ili vitumiwe na kihariri na zana kama mypy. Na bado unaweza kuifanya FastAPI ihakiki uhalali wa data, itengeneze nyaraka, n.k. kwa kutumia `response_model`.
Unaweza pia kutumia `response_model=None` kuzima uundaji wa modeli ya jibu kwa *operesheni hiyo ya njia*. Huenda ukahitaji kufanya hivyo ikiwa unaongeza vidokezo vya aina kwa vitu ambavyo si nyuga halali za Pydantic; utaona mfano wa hilo katika mojawapo ya sehemu zilizo hapa chini.
## Rejesha data ileile ya ingizo { #return-the-same-input-data }
Hapa tunatangaza modeli ya `UserIn`, ambayo itakuwa na nenosiri katika maandishi wazi:
{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
/// note | Kumbuka
Ili kutumia `EmailStr`, kwanza sakinisha [`email-validator`](https://github.com/JoshData/python-email-validator).
Iongeze kwenye mradi wako:
```console
$ uv add email-validator
```
au kwa kutumia:
```console
$ uv add "pydantic[email]"
```
///
Na tunatumia modeli hii kutangaza ingizo letu na modeli hiyohiyo kutangaza matokeo yetu:
{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}
Sasa, kila wakati kivinjari kinapounda mtumiaji mwenye nenosiri, API itarejesha nenosiri hilohilo katika jibu.
Katika hali hii, huenda lisiwe tatizo, kwa sababu ni mtumiaji yuleyule anayetuma nenosiri.
Lakini tukitumia modeli hiyohiyo kwa *operesheni nyingine ya njia*, tunaweza kuwa tunatuma manenosiri ya watumiaji wetu kwa kila mteja.
/// danger | Hatari
Kamwe usihifadhi nenosiri la mtumiaji katika maandishi wazi wala kulituma katika jibu kama hili, isipokuwa kama unajua tahadhari zote na unajua unachofanya.
///
## Ongeza modeli ya matokeo { #add-an-output-model }
Badala yake tunaweza kuunda modeli ya ingizo yenye nenosiri katika maandishi wazi na modeli ya matokeo isiyo nalo:
{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}
Hapa, ingawa *kitendakazi chetu cha operesheni ya njia* kinarejesha data ileile ya mtumiaji iliyoingizwa yenye nenosiri:
{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
...tulitangaza `response_model` kuwa modeli yetu ya `UserOut`, ambayo haijumuishi nenosiri:
{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
Kwa hiyo, **FastAPI** itashughulikia uchujaji wa kuondoa data yote ambayo haijatangazwa katika modeli ya matokeo (kwa kutumia Pydantic).
### `response_model` au Aina ya Thamani Inayorejeshwa { #response-model-or-return-type }
Katika hali hii, kwa sababu modeli hizi mbili ni tofauti, tukiwekea kitendakazi kidokezo cha aina ya thamani inayorejeshwa kuwa `UserOut`, kihariri na zana zitaonyesha hitilafu kwamba tunarejesha aina isiyo halali, kwa kuwa hizo ni class tofauti.
Ndiyo sababu katika mfano huu tunapaswa kuitangaza katika kigezo cha `response_model`.
...lakini endelea kusoma hapa chini uone jinsi ya kushinda kikwazo hicho.
## Aina ya Thamani Inayorejeshwa na Uchujaji wa Data { #return-type-and-data-filtering }
Tuendelee na mfano uliopita. Tulitaka **kuwekea kitendakazi kidokezo cha aina moja**, lakini tulitaka kuweza kurejesha kutoka kwenye kitendakazi kitu ambacho kwa kweli kinajumuisha **data zaidi**.
Tunataka FastAPI iendelee **kuchuja** data kwa kutumia modeli ya jibu. Ili hata kama kitendakazi kinarejesha data zaidi, jibu lijumuishe tu nyuga zilizotangazwa katika modeli ya jibu.
Katika mfano uliopita, kwa sababu class zilikuwa tofauti, tulilazimika kutumia kigezo cha `response_model`. Lakini hilo pia linamaanisha kwamba hatupati usaidizi wa kihariri na zana zinazokagua aina ya thamani inayorejeshwa na kitendakazi.
Lakini katika hali nyingi ambapo tunahitaji kufanya kitu kama hiki, tunataka modeli **ichuje/iondoe** tu baadhi ya data kama katika mfano huu.
Na katika hali hizo, tunaweza kutumia class na urithi ili kunufaika na **vidokezo vya aina** vya kitendakazi kupata usaidizi bora katika kihariri na zana, na bado kupata **uchujaji wa data** wa FastAPI.
{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
Kwa hili, tunapata usaidizi wa zana, kutoka kwa vihariri na mypy kwa kuwa msimbo huu ni sahihi kwa upande wa aina, lakini pia tunapata uchujaji wa data kutoka FastAPI.
Hili linafanyaje kazi? Hebu tuangalie. 🤓
### Vidokezo vya Aina na Zana { #type-annotations-and-tooling }
Kwanza tuone jinsi vihariri, mypy na zana nyingine zingechukulia hili.
`BaseUser` ina nyuga za msingi. Kisha `UserIn` hurithi kutoka `BaseUser` na kuongeza uga wa `password`, hivyo itajumuisha nyuga zote kutoka modeli zote mbili.
Tunaweka kidokezo cha aina ya thamani inayorejeshwa na kitendakazi kuwa `BaseUser`, lakini kwa kweli tunarejesha instance ya `UserIn`.
Kihariri, mypy, na zana nyingine hazitaonyesha hitilafu kuhusu hili kwa sababu, kwa upande wa aina, `UserIn` ni class inayotokana na `BaseUser`, ambayo inamaanisha ni aina *halali* wakati kinachotarajiwa ni kitu chochote kilicho `BaseUser`.
### Uchujaji wa Data wa FastAPI { #fastapi-data-filtering }
Sasa, kwa upande wa FastAPI, itaangalia aina ya thamani inayorejeshwa na kuhakikisha kwamba unachorejesha kinajumuisha **tu** nyuga zilizotangazwa katika aina hiyo.
FastAPI hufanya mambo kadhaa ndani kwa ndani kwa kutumia Pydantic ili kuhakikisha kwamba kanuni hizo za urithi wa class hazitumiki katika uchujaji wa data inayorejeshwa, la sivyo unaweza kuishia kurejesha data nyingi zaidi kuliko ulivyotarajia.
Kwa njia hii, unaweza kupata faida za pande zote mbili: vidokezo vya aina vyenye **usaidizi wa zana** na **uchujaji wa data**.
## Ione katika nyaraka { #see-it-in-the-docs }
Unapoangalia nyaraka zinazozalishwa kiotomatiki, unaweza kuona kwamba modeli ya ingizo na modeli ya matokeo zitakuwa na JSON Schema zao wenyewe:
<img src="/img/tutorial/response-model/image01.png">
Na modeli zote mbili zitatumiwa katika nyaraka shirikishi za API:
<img src="/img/tutorial/response-model/image02.png">
## Vidokezo Vingine vya Aina ya Thamani Inayorejeshwa { #other-return-type-annotations }
Huenda kukawa na hali ambapo unarejesha kitu ambacho si uga halali wa Pydantic na unakiwekea kidokezo cha aina katika kitendakazi, ili tu kupata usaidizi unaotolewa na zana (kihariri, mypy, n.k.).
### Rejesha Response Moja kwa Moja { #return-a-response-directly }
Hali ya kawaida zaidi ingekuwa [kurejesha Response moja kwa moja kama ilivyoelezwa baadaye katika nyaraka za kina](../advanced/response-directly.md).
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
Hali hii rahisi hushughulikiwa kiotomatiki na FastAPI kwa sababu kidokezo cha aina ya thamani inayorejeshwa ni class ya `Response` (au class inayotokana nayo).
Na zana pia hazitaonyesha hitilafu kwa sababu `RedirectResponse` na `JSONResponse` zote mbili ni class zinazotokana na `Response`, hivyo kidokezo cha aina ni sahihi.
### Tumia Kidokezo cha Aina ya Class Inayotokana na Response { #annotate-a-response-subclass }
Unaweza pia kutumia class inayotokana na `Response` katika kidokezo cha aina:
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
Hili pia litafanya kazi kwa sababu `RedirectResponse` ni class inayotokana na `Response`, na FastAPI itashughulikia hali hii rahisi kiotomatiki.
### Vidokezo Visivyo Halali vya Aina ya Thamani Inayorejeshwa { #invalid-return-type-annotations }
Lakini unaporejesha objekti nyingine yoyote ambayo si aina halali ya Pydantic (k.m. objekti ya hifadhidata) na kuiwekea kidokezo hicho katika kitendakazi, FastAPI itajaribu kuunda modeli ya jibu ya Pydantic kutokana na kidokezo hicho cha aina, na itashindwa.
Hilo pia lingetokea ikiwa ungekuwa na kitu kama <dfn title='Muungano wa aina nyingi unamaanisha "yoyote kati ya aina hizi".'>muungano</dfn> wa aina tofauti ambapo moja au zaidi si aina halali za Pydantic, kwa mfano hili lingeshindwa 💥:
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
...hili linashindwa kwa sababu kidokezo cha aina si aina ya Pydantic wala si class moja tu ya `Response` au class inayotokana nayo; ni muungano (yoyote kati ya hizo mbili) wa `Response` na `dict`.
### Zima Modeli ya Jibu { #disable-response-model }
Tukiendelea na mfano hapo juu, huenda usitake uhakiki wa uhalali wa data, uundaji wa nyaraka, uchujaji, n.k. unaofanywa na FastAPI kwa chaguo-msingi.
Lakini huenda bado ukataka kuweka kidokezo cha aina ya thamani inayorejeshwa katika kitendakazi ili kupata usaidizi kutoka kwa zana kama vihariri na vikaguzi vya aina (k.m. mypy).
Katika hali hii, unaweza kuzima uzalishaji wa modeli ya jibu kwa kuweka `response_model=None`:
{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
Hili litaifanya FastAPI iruke uzalishaji wa modeli ya jibu na kwa njia hiyo unaweza kuwa na vidokezo vyovyote vya aina ya thamani inayorejeshwa unavyohitaji bila kuathiri programu yako ya FastAPI. 🤓
## Vigezo vya usimbaji wa Modeli ya Jibu { #response-model-encoding-parameters }
Modeli yako ya jibu inaweza kuwa na thamani za chaguo-msingi, kama vile:
{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}
* `description: Union[str, None] = None` (au `str | None = None` katika Python 3.10) ina thamani ya chaguo-msingi ya `None`.
* `tax: float = 10.5` ina thamani ya chaguo-msingi ya `10.5`.
* `tags: List[str] = []` ina thamani ya chaguo-msingi ya orodha tupu: `[]`.
lakini huenda ukataka kuziondoa kwenye matokeo ikiwa hazikuhifadhiwa kwa kweli.
Kwa mfano, ikiwa una modeli zenye sifa nyingi za hiari katika hifadhidata ya NoSQL, lakini hutaki kutuma majibu marefu sana ya JSON yaliyojaa thamani za chaguo-msingi.
### Tumia kigezo cha `response_model_exclude_unset` { #use-the-response-model-exclude-unset-parameter }
Unaweza kuweka kigezo cha *decorator ya operesheni ya njia* kuwa `response_model_exclude_unset=True`:
{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}
na thamani hizo za chaguo-msingi hazitajumuishwa katika jibu, ila thamani zilizowekwa kweli pekee.
Kwa hiyo, ukituma ombi kwa *operesheni hiyo ya njia* kwa kipengee chenye ID `foo`, jibu (bila kujumuisha thamani za chaguo-msingi) litakuwa:
```JSON
{
"name": "Foo",
"price": 50.2
}
```
/// note | Kumbuka
Unaweza pia kutumia:
* `response_model_exclude_defaults=True`
* `response_model_exclude_none=True`
kama ilivyoelezwa katika [nyaraka za Pydantic](https://pydantic.dev/docs/validation/latest/concepts/serialization/#excluding-and-including-fields-based-on-their-value) kuhusu `exclude_defaults` na `exclude_none`.
///
#### Data yenye thamani za nyuga zenye chaguo-msingi { #data-with-values-for-fields-with-defaults }
Lakini ikiwa data yako ina thamani za nyuga za modeli zilizo na thamani za chaguo-msingi, kama kipengee chenye ID `bar`:
<!-- fmt:off -->
```Python hl_lines="3 5"
{
"name": "Bar",
"description": "The bartenders",
"price": 62,
"tax": 20.2
}
```
<!-- fmt:on -->
thamani hizo zitajumuishwa katika jibu.
#### Data yenye thamani zinazolingana na za chaguo-msingi { #data-with-the-same-values-as-the-defaults }
Ikiwa data ina thamani zinazolingana na zile za chaguo-msingi, kama kipengee chenye ID `baz`:
<!-- fmt:off -->
```Python hl_lines="3 5-6"
{
"name": "Baz",
"description": None,
"price": 50.2,
"tax": 10.5,
"tags": []
}
```
<!-- fmt:on -->
FastAPI ina uwezo wa kutambua (kwa kweli, Pydantic ndiyo yenye uwezo huo) kwamba, ingawa `description`, `tax`, na `tags` zina thamani zinazolingana na zile za chaguo-msingi, ziliwekwa waziwazi (badala ya kuchukuliwa kutoka kwenye chaguo-msingi).
Kwa hiyo, zitajumuishwa katika jibu la JSON.
/// tip | Kidokezo
Zingatia kwamba thamani za chaguo-msingi zinaweza kuwa chochote, si `None` pekee.
Zinaweza kuwa orodha (`[]`), `float` ya `10.5`, n.k.
///
### `response_model_include` na `response_model_exclude` { #response-model-include-and-response-model-exclude }
Unaweza pia kutumia vigezo vya *decorator ya operesheni ya njia* vya `response_model_include` na `response_model_exclude`.
Vinapokea `set` ya `str` yenye majina ya sifa za kujumuisha (ukiacha nyingine zote) au za kuondoa (ukijumuisha nyingine zote).
Hii inaweza kutumiwa kama njia ya mkato ya haraka ikiwa una modeli moja tu ya Pydantic na unataka kuondoa baadhi ya data kutoka kwenye matokeo.
/// tip | Kidokezo
Lakini bado inapendekezwa kutumia mawazo yaliyo hapo juu, ya kutumia class nyingi, badala ya vigezo hivi.
Hii ni kwa sababu JSON Schema inayozalishwa katika OpenAPI ya programu yako (na nyaraka) bado itakuwa ya modeli nzima, hata ukitumia `response_model_include` au `response_model_exclude` kuondoa baadhi ya sifa.
Hili pia linahusu `response_model_by_alias` inayofanya kazi kwa namna inayofanana.
///
{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}
/// tip | Kidokezo
Sintaksia ya `{"name", "description"}` huunda `set` yenye thamani hizo mbili.
Ni sawa na `set(["name", "description"])`.
///
#### Kutumia `list` badala ya `set` { #using-lists-instead-of-sets }
Ukisahau kutumia `set` na badala yake ukatumia `list` au `tuple`, FastAPI bado itaibadilisha kuwa `set` na itafanya kazi kwa usahihi:
{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
## Muhtasari { #recap }
Tumia kigezo cha `response_model` cha *decorator ya operesheni ya njia* kufafanua modeli za jibu na hasa kuhakikisha kwamba data ya faragha inachujwa na kuondolewa.
Tumia `response_model_exclude_unset` kurejesha tu thamani zilizowekwa waziwazi.
@@ -0,0 +1,277 @@
# OAuth2 yenye Nenosiri (na hashing), Bearer yenye tokeni za JWT { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
Sasa kwa kuwa tuna mtiririko mzima wa usalama, tuifanye programu iwe salama kweli, kwa kutumia tokeni za <abbr title="JSON Web Tokens - Tokeni za Wavuti za JSON">JWT</abbr> na hashing salama ya nywila.
Huu ni msimbo unaoweza kuutumia katika programu yako, kuhifadhi hash za nywila kwenye hifadhidata yako, n.k.
Tutaanzia pale tulipoishia katika sura iliyotangulia na kuuongeza.
## Kuhusu JWT { #about-jwt }
JWT inamaanisha "JSON Web Tokens".
Ni kiwango cha kusimba object ya JSON kuwa mfuatano mrefu wa herufi ulioshikamana bila nafasi. Inaonekana hivi:
```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```
Haijasimbwa kwa njia fiche, kwa hivyo mtu yeyote anaweza kurejesha taarifa kutoka kwenye yaliyomo.
Lakini imetiwa saini. Kwa hivyo, unapopokea tokeni uliyotoa, unaweza kuthibitisha kuwa wewe ndiye uliyeitoa.
Kwa njia hiyo, unaweza kuunda tokeni yenye muda wa kuisha wa, tuseme, wiki 1. Kisha mtumiaji anaporudi siku inayofuata akiwa na tokeni hiyo, unajua kuwa mtumiaji huyo bado ameingia kwenye mfumo wako.
Baada ya wiki moja, tokeni itakuwa imeisha muda wake na mtumiaji hataruhusiwa kuendelea; itabidi aingie tena ili apate tokeni mpya. Na ikiwa mtumiaji (au mtu mwingine) angejaribu kurekebisha tokeni ili kubadilisha muda wake wa kuisha, ungeweza kugundua hilo, kwa sababu saini hazingelingana.
Ikiwa unataka kufanya majaribio na tokeni za JWT na kuona jinsi zinavyofanya kazi, angalia [https://jwt.io](https://jwt.io/).
## Sakinisha `PyJWT` { #install-pyjwt }
Tunahitaji kusakinisha `PyJWT` ili kutengeneza na kuthibitisha tokeni za JWT katika Python.
Ongeza `pyjwt` kwenye mradi wako:
<div class="termy">
```console
$ uv add pyjwt
---> 100%
```
</div>
/// note | Tanbihi
Ikiwa unapanga kutumia algoriti za saini za kidijitali kama RSA au ECDSA, unapaswa kusakinisha kitegemezi cha maktaba ya cryptography cha `pyjwt[crypto]`.
Unaweza kusoma zaidi kuhusu hilo katika [nyaraka za usakinishaji wa PyJWT](https://pyjwt.readthedocs.io/en/latest/installation.html).
///
## Hashing ya nywila { #password-hashing }
"Hashing" inamaanisha kubadilisha maudhui fulani (nenosiri katika hali hii) kuwa mfuatano wa baiti (string tu) unaoonekana kama maandishi yasiyo na maana.
Kila unapopitisha maudhui yale yale kabisa (nenosiri lile lile kabisa), unapata maandishi yale yale yasiyo na maana.
Lakini huwezi kuyabadilisha maandishi hayo kurudi kuwa nenosiri.
### Kwa nini utumie hashing ya nywila { #why-use-password-hashing }
Ikiwa hifadhidata yako itaibiwa, mwizi hatakuwa na nywila za watumiaji wako zilizo katika maandishi ya kawaida, bali hash zake tu.
Kwa hivyo, mwizi hataweza kujaribu kutumia nenosiri hilo katika mfumo mwingine (kwa kuwa watumiaji wengi hutumia nenosiri lile lile kila mahali, hilo lingekuwa hatari).
## Sakinisha `pwdlib` { #install-pwdlib }
pwdlib ni kifurushi kizuri cha Python cha kushughulikia hash za nywila.
Kinaunga mkono algoriti nyingi salama za hashing na zana za kuzitumia.
Algoriti inayopendekezwa ni "Argon2".
Ongeza `pwdlib` yenye Argon2 kwenye mradi wako:
<div class="termy">
```console
$ uv add "pwdlib[argon2]"
---> 100%
```
</div>
/// tip | Kidokezo
Ukiwa na `pwdlib`, unaweza hata kuisanidi iweze kusoma nywila zilizoundwa na **Django**, programu-jalizi ya usalama ya **Flask** au nyingine nyingi.
Kwa hivyo, kwa mfano, ungeweza kushiriki data ile ile ya programu ya Django iliyo katika hifadhidata na programu ya FastAPI. Au kuhamisha programu ya Django hatua kwa hatua huku ukitumia hifadhidata ile ile.
Na watumiaji wako wangeweza kuingia kupitia programu yako ya Django au kupitia programu yako ya **FastAPI**, wakati huo huo.
///
## Tengeneza hash na uhakiki nywila { #hash-and-verify-the-passwords }
Ingiza zana tunazohitaji kutoka `pwdlib`.
Unda instance ya PasswordHash yenye mipangilio inayopendekezwa — itatumika kutengeneza hash na kuhakiki nywila.
/// tip | Kidokezo
pwdlib pia inaunga mkono algoriti ya hashing ya bcrypt lakini haijumuishi algoriti za zamani — ili kufanya kazi na hash zilizopitwa na wakati, inapendekezwa kutumia maktaba ya passlib.
Kwa mfano, ungeweza kuitumia kusoma na kuhakiki nywila zilizotengenezwa na mfumo mwingine (kama Django) lakini ukatengeneza hash za nywila zozote mpya kwa algoriti tofauti kama Argon2 au Bcrypt.
Na kuwa na uoanifu na zote kwa wakati mmoja.
///
Unda function saidizi ya kutengeneza hash ya nenosiri linalotoka kwa mtumiaji.
Na nyingine ya kuhakiki kama nenosiri lililopokewa linalingana na hash iliyohifadhiwa.
Na nyingine ya kuthibitisha utambulisho wa mtumiaji na kumrudisha.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
Wakati `authenticate_user` inapoitwa kwa jina la mtumiaji lisilokuwepo kwenye hifadhidata, bado tunaendesha `verify_password` dhidi ya hash mbadala.
Hii inahakikisha kuwa endpoint inachukua takribani muda ule ule kujibu iwe jina la mtumiaji ni halali au la, na hivyo kuzuia **mashambulizi ya kupima muda (timing attacks)** yanayoweza kutumiwa kubaini majina ya watumiaji yaliyopo.
/// note | Tanbihi
Ukiangalia hifadhidata mpya (ya mfano) `fake_users_db`, utaona jinsi hash ya nenosiri inavyoonekana sasa: `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
///
## Shughulikia tokeni za JWT { #handle-jwt-tokens }
Ingiza moduli zilizosakinishwa.
Unda ufunguo wa siri wa nasibu utakaotumika kutia saini tokeni za JWT.
Ili kutengeneza ufunguo wa siri wa nasibu ulio salama, tumia amri hii:
<div class="termy">
```console
$ openssl rand -hex 32
09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
```
</div>
Na unakili matokeo kwenye kigeu `SECRET_KEY` (usitumie ule ulio kwenye mfano).
Unda kigeu `ALGORITHM` chenye algoriti inayotumika kutia saini tokeni ya JWT na ukipe thamani `"HS256"`.
Unda kigeu cha muda wa kuisha wa tokeni.
Fafanua modeli ya Pydantic itakayotumika katika endpoint ya tokeni kwa ajili ya jibu.
Unda function saidizi ya kutengeneza tokeni mpya ya ufikiaji.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
## Sasisha vitegemezi { #update-the-dependencies }
Sasisha `get_current_user` ili ipokee tokeni kama hapo awali, lakini wakati huu kwa kutumia tokeni za JWT.
Fumbua usimbaji wa tokeni iliyopokewa, ithibitishe, na urudishe mtumiaji wa sasa.
Ikiwa tokeni si halali, rudisha hitilafu ya HTTP mara moja.
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
## Sasisha *operesheni ya njia* ya `/token` { #update-the-token-path-operation }
Unda `timedelta` yenye muda wa kuisha wa tokeni.
Unda tokeni halisi ya ufikiaji ya JWT na uirudishe.
{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
### Maelezo ya kiufundi kuhusu "subject" ya JWT `sub` { #technical-details-about-the-jwt-subject-sub }
Vipimo vya JWT vinasema kuwa kuna ufunguo `sub`, wenye mhusika wa tokeni.
Kuutumia ni hiari, lakini hapo ndipo ungeweka kitambulisho cha mtumiaji, kwa hivyo tunautumia hapa.
JWT inaweza kutumika kwa mambo mengine mbali na kumtambua mtumiaji na kumruhusu kufanya operesheni moja kwa moja kwenye API yako.
Kwa mfano, ungeweza kutambua "gari" au "chapisho la blogu".
Kisha ungeweza kuongeza ruhusa zinazohusu kitu hicho, kama "endesha" (kwa gari) au "hariri" (kwa blogu).
Na kisha, ungeweza kumpa mtumiaji (au bot) tokeni hiyo ya JWT, na angeweza kuitumia kufanya vitendo hivyo (kuendesha gari, au kuhariri chapisho la blogu) bila hata kuhitaji kuwa na akaunti, kwa kutumia tu tokeni ya JWT ambayo API yako ilitengeneza kwa ajili hiyo.
Kwa kutumia mawazo haya, JWT inaweza kutumika katika hali changamani zaidi.
Katika hali hizo, vitu kadhaa vinaweza kuwa na ID ile ile, tuseme `foo` (mtumiaji `foo`, gari `foo`, na chapisho la blogu `foo`).
Kwa hivyo, ili kuepuka migongano ya ID, unapounda tokeni ya JWT kwa ajili ya mtumiaji, ungeweza kuongeza kiambishi mwanzoni mwa thamani ya ufunguo `sub`, k.m. `username:`. Kwa hivyo, katika mfano huu, thamani ya `sub` ingeweza kuwa: `username:johndoe`.
Jambo muhimu la kukumbuka ni kwamba ufunguo `sub` unapaswa kuwa na kitambulisho cha kipekee katika programu nzima, na unapaswa kuwa string.
## Ijaribu { #check-it }
Endesha seva na uende kwenye nyaraka: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Utaona kiolesura cha mtumiaji kama hiki:
<img src="/img/tutorial/security/image07.png">
Idhinisha programu kwa njia ile ile ya awali.
Kwa kutumia taarifa hizi za kuingia:
Jina la mtumiaji: `johndoe`
Nenosiri: `secret`
/// tip | Kidokezo
Tambua kuwa hakuna mahali popote kwenye msimbo palipo na nenosiri la maandishi ya kawaida "`secret`", tuna hash yake tu.
///
<img src="/img/tutorial/security/image08.png">
Ita endpoint `/users/me/`, utapata jibu kama hili:
```JSON
{
"username": "johndoe",
"email": "johndoe@example.com",
"full_name": "John Doe",
"disabled": false
}
```
<img src="/img/tutorial/security/image09.png">
Ukifungua zana za msanidi programu, unaweza kuona jinsi data inayotumwa inavyojumuisha tokeni pekee; nenosiri hutumwa tu katika ombi la kwanza ili kuthibitisha utambulisho wa mtumiaji na kupata tokeni hiyo ya ufikiaji, lakini si baada ya hapo:
<img src="/img/tutorial/security/image10.png">
/// note | Tanbihi
Tambua kichwa `Authorization`, chenye thamani inayoanza na `Bearer `.
///
## Matumizi ya hali ya juu yenye `scopes` { #advanced-usage-with-scopes }
OAuth2 ina dhana ya "scopes".
Unaweza kuzitumia kuongeza seti maalumu ya ruhusa kwenye tokeni ya JWT.
Kisha unaweza kumpa mtumiaji tokeni hiyo moja kwa moja au kuipatia mhusika mwingine, ili kuwasiliana na API yako kwa kufuata vizuizi fulani.
Unaweza kujifunza jinsi ya kuzitumia na jinsi zinavyounganishwa na **FastAPI** baadaye katika **Mwongozo wa Kina wa Mtumiaji**.
## Muhtasari { #recap }
Kwa yale ambayo umeona hadi sasa, unaweza kuandaa programu salama ya **FastAPI** kwa kutumia viwango kama OAuth2 na JWT.
Katika takribani kila framework, kushughulikia usalama huwa jambo changamani kwa haraka sana.
Vifurushi vingi vinavyorahisisha jambo hilo sana hulazimika kuweka vikwazo vingi kwenye modeli ya data, hifadhidata, na vipengele vinavyopatikana. Na baadhi ya vifurushi hivi vinavyorahisisha mambo kupita kiasi kwa kweli vina dosari za usalama zisizoonekana wazi.
---
**FastAPI** haiweki vikwazo katika uchaguzi wa hifadhidata, modeli ya data au zana yoyote.
Inakupa unyumbufu wote wa kuchagua zile zinazofaa zaidi mradi wako.
Na unaweza kutumia moja kwa moja vifurushi vingi vinavyotunzwa vizuri na vinavyotumika sana kama `pwdlib` na `PyJWT`, kwa sababu **FastAPI** haihitaji mifumo changamani ya kuunganisha vifurushi vya nje.
Lakini inakupa zana za kurahisisha mchakato kadiri iwezekanavyo bila kuathiri unyumbufu, uimara, au usalama.
Na unaweza kutumia na kutekeleza itifaki salama za viwango vinavyokubalika, kama OAuth2, kwa njia rahisi kiasi.
Unaweza kujifunza zaidi katika **Mwongozo wa Kina wa Mtumiaji** kuhusu jinsi ya kutumia "scopes" za OAuth2, kwa mfumo wa ruhusa wenye udhibiti wa kina zaidi, kwa kufuata viwango hivi hivi. OAuth2 yenye scopes ndiyo njia inayotumiwa na watoa huduma wengi wakubwa wa uthibitishaji wa utambulisho, kama Facebook, Google, GitHub, Microsoft, X (Twitter), n.k. kuidhinisha programu za wahusika wengine kuwasiliana na API zao kwa niaba ya watumiaji wao.