🌐 Update translations for tr (update-all) (#14913)

* Update all

* 🎨 Auto format

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Motov Yurii
2026-02-13 13:41:38 +01:00
committed by GitHub
parent fdbbf74908
commit ea8db708f1
93 changed files with 833 additions and 883 deletions

View File

@@ -27,7 +27,7 @@ Bu bir code snippet: `foo`. Bu da başka bir code snippet: `bar`. Bir tane daha:
Code snippet'lerin içeriği olduğu gibi bırakılmalıdır.
`script/translate.py` içindeki genel prompt'ta `### Content of code snippets` bölümüne bakın.
`scripts/translate.py` içindeki genel prompt'ta `### Content of code snippets` bölümüne bakın.
////
@@ -116,7 +116,7 @@ works(foo="bar") # This works 🎉
Code block'ların içindeki code değiştirilmemelidir; tek istisna yorumlardır (comments).
`script/translate.py` içindeki genel prompt'ta `### Content of code blocks` bölümüne bakın.
`scripts/translate.py` içindeki genel prompt'ta `### Content of code blocks` bölümüne bakın.
////
@@ -125,31 +125,31 @@ Code block'ların içindeki code değiştirilmemelidir; tek istisna yorumlardır
//// tab | Test
/// info | Bilgi
Some text
Bazı metin
///
/// note | Not
Some text
Bazı metin
///
/// note | Teknik Detaylar
Some text
Bazı metin
///
/// check | Ek bilgi
Some text
Bazı metin
///
/// tip | İpucu
Some text
Bazı metin
///
/// warning | Uyarı
Some text
Bazı metin
///
/// danger | Tehlike
Some text
Bazı metin
///
////
@@ -158,7 +158,7 @@ Some text
Sekmelerin ve `Info`/`Note`/`Warning`/vb. blokların başlığı, dikey çizgiden (`|`) sonra çeviri olarak eklenmelidir.
`script/translate.py` içindeki genel prompt'ta `### Special blocks` ve `### Tab blocks` bölümlerine bakın.
`scripts/translate.py` içindeki genel prompt'ta `### Special blocks` ve `### Tab blocks` bölümlerine bakın.
////
@@ -170,10 +170,10 @@ Link metni çevrilmelidir, link adresi değişmeden kalmalıdır:
* [Yukarıdaki başlığa link](#code-snippets)
* [Internal link](index.md#installation){.internal-link target=_blank}
* <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">External link</a>
* <a href="https://fastapi.tiangolo.com/css/styles.css" class="external-link" target="_blank">Link to a style</a>
* <a href="https://fastapi.tiangolo.com/js/logic.js" class="external-link" target="_blank">Link to a script</a>
* <a href="https://fastapi.tiangolo.com/img/foo.jpg" class="external-link" target="_blank">Link to an image</a>
* <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">Harici link</a>
* <a href="https://fastapi.tiangolo.com/css/styles.css" class="external-link" target="_blank">Bir stile bağlantı</a>
* <a href="https://fastapi.tiangolo.com/js/logic.js" class="external-link" target="_blank">Bir betiğe bağlantı</a>
* <a href="https://fastapi.tiangolo.com/img/foo.jpg" class="external-link" target="_blank">Bir görsele bağlantı</a>
Link metni çevrilmelidir, link adresi çeviriye işaret etmelidir:
@@ -185,7 +185,7 @@ Link metni çevrilmelidir, link adresi çeviriye işaret etmelidir:
Link'ler çevrilmelidir, ancak adresleri değişmeden kalmalıdır. Bir istisna, FastAPI dokümantasyonunun sayfalarına verilen mutlak link'lerdir. Bu durumda link, çeviriye işaret etmelidir.
`script/translate.py` içindeki genel prompt'ta `### Links` bölümüne bakın.
`scripts/translate.py` içindeki genel prompt'ta `### Links` bölümüne bakın.
////
@@ -199,14 +199,9 @@ Burada HTML "abbr" öğeleriyle sarılmış bazı şeyler var (bazıları uydurm
* <abbr title="Getting Things Done - İşleri Bitirme">GTD</abbr>
* <abbr title="less than - küçüktür"><code>lt</code></abbr>
* <abbr title="XML Web Token - XML Web Token">XWT</abbr>
* <abbr title="XML Web Token">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface - Paralel Sunucu Gateway Interface">PSGI</abbr>
### abbr bir açıklama verir { #the-abbr-gives-an-explanation }
* <abbr title="Bir şekilde birbirine bağlanacak ve birlikte çalışacak şekilde yapılandırılmış makinelerden oluşan bir grup.">cluster</abbr>
* <abbr title="Girdi ve çıktı katmanları arasında çok sayıda gizli katman içeren yapay sinir ağlarını kullanan; böylece kapsamlı bir iç yapı geliştiren bir machine learning yöntemi">Deep Learning</abbr>
### abbr tam bir ifade ve bir açıklama verir { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbr title="Mozilla Developer Network - Mozilla Geliştirici Ağı: Firefox ekibi tarafından yazılmış, geliştiricilere yönelik dokümantasyon">MDN</abbr>
@@ -220,10 +215,15 @@ Burada HTML "abbr" öğeleriyle sarılmış bazı şeyler var (bazıları uydurm
Çeviriler, LLM'nin kaldırmaması gereken kendi "abbr" öğelerini ekleyebilir. Örneğin İngilizce kelimeleri açıklamak için.
`script/translate.py` içindeki genel prompt'ta `### HTML abbr elements` bölümüne bakın.
`scripts/translate.py` içindeki genel prompt'ta `### HTML abbr elements` bölümüne bakın.
////
## HTML "dfn" öğeleri { #html-dfn-elements }
* <dfn title="Bir şekilde birbirine bağlanacak ve birlikte çalışacak şekilde yapılandırılmış makinelerden oluşan bir grup.">küme</dfn>
* <dfn title="Girdi ve çıktı katmanları arasında çok sayıda gizli katman içeren yapay sinir ağlarını kullanan; böylece kapsamlı bir iç yapı geliştiren bir makine öğrenmesi yöntemi">Derin Öğrenme</dfn>
## Başlıklar { #headings }
//// tab | Test
@@ -246,7 +246,7 @@ Tekrar merhaba.
Başlıklarla ilgili tek katı kural, LLM'nin süslü parantezler içindeki hash kısmını değiştirmemesidir; böylece link'ler bozulmaz.
`script/translate.py` içindeki genel prompt'ta `### Headings` bölümüne bakın.
`scripts/translate.py` içindeki genel prompt'ta `### Headings` bölümüne bakın.
Dile özel bazı talimatlar için örneğin `docs/de/llm-prompt.md` içindeki `### Headings` bölümüne bakın.

View File

@@ -26,7 +26,7 @@ Bu response `dict`'lerinin her birinde, `response_model`'e benzer şekilde bir P
Örneğin, `404` status code'u ve `Message` Pydantic model'i ile başka bir response tanımlamak için şunu yazabilirsiniz:
{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
/// note | Not
@@ -203,7 +203,7 @@ Varsayılan `200` status code'unu (ya da gerekiyorsa özel bir tane) kullanarak
Ayrıca `response_model`'inizi kullanan, ancak özel bir `example` içeren `200` status code'lu bir response da tanımlayabilirsiniz:
{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
Bunların hepsi OpenAPI'nize birleştirilerek dahil edilir ve API dokümanlarında gösterilir:

View File

@@ -18,7 +18,7 @@ Class'ın kendisini değil (zaten callable'dır), o class'ın bir instance'ını
Bunu yapmak için `__call__` adında bir method tanımlarız:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
Bu durumda, ek parametreleri ve alt-dependency'leri kontrol etmek için **FastAPI**'nin kullanacağı şey bu `__call__` olacaktır; ayrıca daha sonra *path operation function* içindeki parametreye bir değer geçmek için çağrılacak olan da budur.
@@ -26,7 +26,7 @@ Bu durumda, ek parametreleri ve alt-dependency'leri kontrol etmek için **FastAP
Ve şimdi, dependency'yi "parametreleştirmek" için kullanacağımız instance parametrelerini tanımlamak üzere `__init__` kullanabiliriz:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
Bu durumda **FastAPI**, `__init__` ile asla uğraşmaz veya onu önemsemez; onu doğrudan kendi kodumuzda kullanırız.
@@ -34,7 +34,7 @@ Bu durumda **FastAPI**, `__init__` ile asla uğraşmaz veya onu önemsemez; onu
Bu class'tan bir instance'ı şöyle oluşturabiliriz:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
Böylece dependency'mizi "parametreleştirmiş" oluruz; artık içinde `"bar"` vardır ve bu değer `checker.fixed_content` attribute'u olarak durur.
@@ -50,7 +50,7 @@ checker(q="somequery")
...ve bunun döndürdüğü her şeyi, *path operation function* içinde `fixed_content_included` parametresine dependency değeri olarak geçirir:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
/// tip | İpucu

View File

@@ -0,0 +1,61 @@
# Gelişmiş Python Tipleri { #advanced-python-types }
Python tipleriyle çalışırken işinize yarayabilecek bazı ek fikirler.
## `Union` veya `Optional` Kullanımı { #using-union-or-optional }
Kodunuz herhangi bir nedenle `|` kullanamıyorsa — örneğin bir tip açıklamasında (type annotation) değil de `response_model=` gibi bir yerdeyse — dikey çizgi (`|`) yerine `typing` içindeki `Union`'ı kullanabilirsiniz.
Örneğin, bir şeyin `str` ya da `None` olabileceğini şöyle belirtebilirsiniz:
```python
from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
```
`typing`, bir şeyin `None` olabileceğini belirtmek için `Optional` ile bir kısayol da sunar.
Benim oldukça öznel bakış açıma göre küçük bir ipucu:
- 🚨 `Optional[SomeType]` kullanmaktan kaçının
- Bunun yerine ✨ **`Union[SomeType, None]` kullanın** ✨.
İkisi de eşdeğer ve temelde aynıdır; ancak "**optional**" kelimesi değerin isteğe bağlı olduğunu ima eder. Oysa aslında " `None` olabilir" demektir; değer isteğe bağlı olmasa ve hâlâ zorunlu olsa bile.
Bence `Union[SomeType, None]` ne demek istediğini daha açık anlatır.
Burada mesele sadece kelimeler ve isimler. Ancak bu kelimeler sizin ve ekip arkadaşlarınızın koda bakışını etkileyebilir.
Örnek olarak şu fonksiyona bakalım:
```python
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
`name` parametresi `Optional[str]` olarak tanımlıdır; ancak isteğe bağlı değildir, parametre olmadan fonksiyonu çağıramazsınız:
```Python
say_hi() # Ah hayır, bu hata fırlatır! 😱
```
`name` parametresi varsayılan bir değeri olmadığı için hâlâ zorunludur (yani *optional* değildir). Yine de `name`, değer olarak `None` kabul eder:
```Python
say_hi(name=None) # Bu çalışır, None geçerlidir 🎉
```
İyi haber şu ki, çoğu durumda tip birliklerini (union) tanımlamak için doğrudan `|` kullanabilirsiniz:
```python
def say_hi(name: str | None):
print(f"Hey {name}!")
```
Dolayısıyla, normalde `Optional` ve `Union` gibi isimler için endişelenmenize gerek yok. 😎

View File

@@ -32,11 +32,11 @@ Basit bir örnek için, [Bigger Applications](../tutorial/bigger-applications.md
`main.py` dosyası şöyle olur:
{* ../../docs_src/async_tests/app_a_py39/main.py *}
{* ../../docs_src/async_tests/app_a_py310/main.py *}
`test_main.py` dosyasında `main.py` için testler yer alır, artık şöyle görünebilir:
{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
## Çalıştırma { #run-it }
@@ -56,7 +56,7 @@ $ pytest
`@pytest.mark.anyio` marker'ı, pytest'e bu test fonksiyonunun asenkron olarak çağrılması gerektiğini söyler:
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
/// tip | İpucu
@@ -66,7 +66,7 @@ Test fonksiyonu artık `TestClient` kullanırken eskiden olduğu gibi sadece `de
Ardından app ile bir `AsyncClient` oluşturup `await` kullanarak ona async request'ler gönderebiliriz.
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
Bu, şu kullanıma denktir:

View File

@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
Örneğin `/items/` adında bir *path operation* tanımladığınızı düşünelim:
{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
Client `/items`'a gitmeye çalışırsa, varsayılan olarak `/items/`'a redirect edilir.
@@ -115,7 +115,7 @@ Bu durumda, orijinal `/app` path'i aslında `/api/v1/app` altında servis edilir
Kodunuzun tamamı sadece `/app` varmış gibi yazılmış olsa bile.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
Proxy, request'i app server'a (muhtemelen FastAPI CLI üzerinden Uvicorn) iletmeden önce **path prefix**'i anlık olarak **"kırpar"** (strip). Böylece uygulamanız hâlâ `/app` altında servis ediliyormuş gibi davranır ve tüm kodunuzu `/api/v1` prefix'ini içerecek şekilde güncellemeniz gerekmez.
@@ -149,14 +149,14 @@ Docs UI'nin, bu API `server`'ının (proxy arkasında) `/api/v1` altında bulund
```JSON hl_lines="4-8"
{
"openapi": "3.1.0",
// More stuff here
// Burada daha fazla şey var
"servers": [
{
"url": "/api/v1"
}
],
"paths": {
// More stuff here
// Burada daha fazla şey var
}
}
```
@@ -193,7 +193,7 @@ Uygulamanızın her request için kullandığı mevcut `root_path` değerini ala
Burada sadece göstermek için bunu mesaja dahil ediyoruz.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
Ardından Uvicorn'u şu şekilde başlatırsanız:
@@ -220,7 +220,7 @@ Response şöyle bir şey olur:
Alternatif olarak, `--root-path` gibi bir komut satırı seçeneği (veya muadili) sağlayamıyorsanız, FastAPI uygulamanızı oluştururken `root_path` parametresini ayarlayabilirsiniz:
{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
`FastAPI`'ye `root_path` vermek, Uvicorn veya Hypercorn'a `--root-path` komut satırı seçeneğini vermekle eşdeğerdir.
@@ -400,14 +400,14 @@ Ancak başka alternatif `servers` da sağlayabilirsiniz; örneğin *aynı* docs
Örneğin:
{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
Şöyle bir OpenAPI şeması üretir:
```JSON hl_lines="5-7"
{
"openapi": "3.1.0",
// More stuff here
// Burada daha fazla şey var
"servers": [
{
"url": "/api/v1"
@@ -422,7 +422,7 @@ Ancak başka alternatif `servers` da sağlayabilirsiniz; örneğin *aynı* docs
}
],
"paths": {
// More stuff here
// Burada daha fazla şey var
}
}
```
@@ -455,7 +455,7 @@ OpenAPI spesifikasyonunda `servers` özelliği opsiyoneldir.
**FastAPI**'nin `root_path` kullanarak otomatik bir server eklemesini istemiyorsanız, `root_path_in_servers=False` parametresini kullanabilirsiniz:
{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
Böylece OpenAPI şemasına dahil etmez.

View File

@@ -30,7 +30,7 @@ Büyük response'larda, doğrudan bir `Response` döndürmek bir dictionary dön
Ancak döndürdüğünüz içeriğin **JSON ile serialize edilebilir** olduğundan eminseniz, onu doğrudan response classına verebilir ve FastAPInin response classına vermeden önce dönüş içeriğinizi `jsonable_encoder` içinden geçirirken oluşturacağı ek yükten kaçınabilirsiniz.
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
/// info | Bilgi
@@ -55,7 +55,7 @@ Ve OpenAPIde de bu şekilde dokümante edilir.
* `HTMLResponse` import edin.
* *path operation decorator*ınızın `response_class` parametresi olarak `HTMLResponse` verin.
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// info | Bilgi
@@ -73,7 +73,7 @@ Ve OpenAPIde de bu şekilde dokümante edilir.
Yukarıdaki örneğin aynısı, bu sefer bir `HTMLResponse` döndürerek, şöyle görünebilir:
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
/// warning | Uyarı
@@ -97,7 +97,7 @@ Bu durumda `response_class` sadece OpenAPI *path operation*ını dokümante e
Örneğin şöyle bir şey olabilir:
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
Bu örnekte `generate_html_response()` fonksiyonu, HTMLi bir `str` olarak döndürmek yerine zaten bir `Response` üretip döndürmektedir.
@@ -136,7 +136,7 @@ Bunu doğrudan döndürebilirsiniz.
FastAPI (aslında Starlette) otomatik olarak bir Content-Length headerı ekler. Ayrıca `media_type`a göre bir Content-Type headerı ekler ve text türleri için sona bir charset ekler.
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
@@ -146,7 +146,7 @@ Yukarıda okuduğunuz gibi, bir miktar text veya bytes alır ve HTML response d
Bir miktar text veya bytes alır ve düz metin response döndürür.
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
@@ -180,7 +180,7 @@ Bunun için `ujson` kurulmalıdır; örneğin `pip install ujson`.
///
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
/// tip | İpucu
@@ -194,13 +194,13 @@ HTTP redirect döndürür. Varsayılan olarak 307 status code (Temporary Redirec
`RedirectResponse`u doğrudan döndürebilirsiniz:
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
---
Veya `response_class` parametresi içinde kullanabilirsiniz:
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
Bunu yaparsanız, *path operation* functionınızdan doğrudan URL döndürebilirsiniz.
@@ -210,13 +210,13 @@ Bu durumda kullanılan `status_code`, `RedirectResponse` için varsayılan olan
Ayrıca `status_code` parametresini `response_class` parametresiyle birlikte kullanabilirsiniz:
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
Bir async generator veya normal generator/iterator alır ve response bodyyi stream eder.
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
#### `StreamingResponse`u file-like objelerle kullanma { #using-streamingresponse-with-file-like-objects }
@@ -226,7 +226,7 @@ Böylece önce hepsini memoryye okumak zorunda kalmazsınız; bu generator fu
Buna cloud storage ile etkileşime giren, video işleyen ve benzeri birçok kütüphane dahildir.
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
1. Bu generator functiondır. İçinde `yield` ifadeleri olduğu için "generator function" denir.
2. Bir `with` bloğu kullanarak, generator function bittiğinde file-like objenin kapandığından emin oluruz. Yani response göndermeyi bitirdikten sonra kapanır.
@@ -255,11 +255,11 @@ Diğer response türlerine göre instantiate ederken farklı argümanlar alır:
File response'ları uygun `Content-Length`, `Last-Modified` ve `ETag` headerlarını içerir.
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
`response_class` parametresini de kullanabilirsiniz:
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
Bu durumda *path operation* functionınızdan doğrudan dosya path'ini döndürebilirsiniz.
@@ -273,7 +273,7 @@ Diyelim ki girintili ve biçimlendirilmiş JSON döndürmek istiyorsunuz; bunun
Bir `CustomORJSONResponse` oluşturabilirsiniz. Burada yapmanız gereken temel şey, contenti `bytes` olarak döndüren bir `Response.render(content)` metodu yazmaktır:
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
Artık şunu döndürmek yerine:
@@ -299,7 +299,7 @@ Bunu tanımlayan parametre `default_response_class`tır.
Aşağıdaki örnekte **FastAPI**, tüm *path operations* için varsayılan olarak `JSONResponse` yerine `ORJSONResponse` kullanır.
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
/// tip | İpucu

View File

@@ -64,7 +64,7 @@ Bu durumda standart `dataclasses` yerine, drop-in replacement olan `pydantic.dat
6. Burada `items` içeren bir dictionary döndürüyoruz; `items` bir dataclass listesi.
FastAPI, veriyi JSON'a <abbr title="converting the data to a format that can be transmitted - veriyi aktarılabilir bir formata dönüştürme">serializing</abbr> etmeyi yine başarır.
FastAPI, veriyi JSON'a <dfn title="veriyi aktarılabilir bir formata dönüştürme">serileştirme</dfn>yi yine başarır.
7. Burada `response_model`, `Author` dataclass'larından oluşan bir listenin type annotation'ını kullanıyor.

View File

@@ -30,7 +30,7 @@ Bu *startup* ve *shutdown* mantığını, `FastAPI` uygulamasının `lifespan` p
Aşağıdaki gibi `yield` kullanan async bir `lifespan()` fonksiyonu oluşturuyoruz:
{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
Burada, `yield` öncesinde (sahte) model fonksiyonunu machine learning modellerini içeren dictionarye koyarak, modeli yükleme gibi maliyetli bir *startup* işlemini simüle ediyoruz. Bu kod, *startup* sırasında, uygulama **request almaya başlamadan önce** çalıştırılır.
@@ -48,7 +48,7 @@ Belki yeni bir sürüm başlatmanız gerekiyordur, ya da çalıştırmaktan sık
Dikkat edilmesi gereken ilk şey, `yield` içeren async bir fonksiyon tanımlıyor olmamız. Bu, `yield` kullanan Dependenciese oldukça benzer.
{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
Fonksiyonun `yield`den önceki kısmı, uygulama başlamadan **önce** çalışır.
@@ -60,7 +60,7 @@ Bakarsanız, fonksiyon `@asynccontextmanager` ile dekore edilmiş.
Bu da fonksiyonu "**async context manager**" denen şeye dönüştürür.
{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
Pythonda **context manager**, `with` ifadesi içinde kullanabildiğiniz bir yapıdır. Örneğin `open()` bir context manager olarak kullanılabilir:
@@ -82,7 +82,7 @@ Yukarıdaki kod örneğimizde bunu doğrudan kullanmıyoruz; bunun yerine FastAP
`FastAPI` uygulamasının `lifespan` parametresi bir **async context manager** alır; dolayısıyla oluşturduğumuz yeni `lifespan` async context managerını buraya geçebiliriz.
{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
## Alternatif Events (kullanımdan kaldırıldı) { #alternative-events-deprecated }
@@ -104,7 +104,7 @@ Bu fonksiyonlar `async def` ile veya normal `def` ile tanımlanabilir.
Uygulama başlamadan önce çalıştırılacak bir fonksiyon eklemek için, `"startup"` eventi ile tanımlayın:
{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
Bu durumda `startup` event handler fonksiyonu, "database" öğesini (sadece bir `dict`) bazı değerlerle başlatır.
@@ -116,7 +116,7 @@ Ve tüm `startup` event handlerları tamamlanmadan uygulamanız request almay
Uygulama kapanırken çalıştırılacak bir fonksiyon eklemek için, `"shutdown"` eventi ile tanımlayın:
{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
Burada `shutdown` event handler fonksiyonu, `log.txt` dosyasına `"Application shutdown"` satırını yazar.
@@ -150,11 +150,11 @@ Bu nedenle artık bunun yerine, yukarıda açıklandığı gibi `lifespan` kulla
Meraklı nerdler için küçük bir teknik detay. 🤓
Altta, ASGI teknik spesifikasyonunda bu, <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Lifespan Protocol</a>ün bir parçasıdır ve `startup` ile `shutdown` adında eventler tanımlar.
Altta, ASGI teknik spesifikasyonunda bu, <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Lifespan Protokolü</a>nün bir parçasıdır ve `startup` ile `shutdown` adında eventler tanımlar.
/// info | Bilgi
Starlette `lifespan` handlerları hakkında daha fazlasını <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">Starlette's Lifespan docs</a> içinde okuyabilirsiniz.
Starlette `lifespan` handlerları hakkında daha fazlasını <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">Starlette Lifespan dokümanları</a> içinde okuyabilirsiniz.
Ayrıca kodunuzun başka bölgelerinde de kullanılabilecek lifespan statei nasıl yöneteceğinizi de kapsar.

View File

@@ -40,7 +40,7 @@ Bu çözümlerin bazılarıık kaynak olabilir veya ücretsiz katman sunabil
Basit bir FastAPI uygulamasıyla başlayalım:
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
*Path operation*'ların, request payload ve response payload için kullandıkları modelleri `Item` ve `ResponseMessage` modelleriyle tanımladıklarına dikkat edin.
@@ -98,7 +98,7 @@ Birçok durumda FastAPI uygulamanız daha büyük olacaktır ve farklı *path op
Örneğin **items** için bir bölüm, **users** için başka bir bölüm olabilir ve bunları tag'lerle ayırabilirsiniz:
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
### Tag'lerle TypeScript Client Üretme { #generate-a-typescript-client-with-tags }
@@ -145,7 +145,7 @@ Bu fonksiyonu özelleştirebilirsiniz. Bir `APIRoute` alır ve string döndürü
Sonrasında bu özel fonksiyonu `generate_unique_id_function` parametresiyle **FastAPI**'ye geçebilirsiniz:
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
### Özel Operation ID'lerle TypeScript Client Üretme { #generate-a-typescript-client-with-custom-operation-ids }
@@ -167,7 +167,7 @@ Ancak üretilen client için, client'ları üretmeden hemen önce OpenAPI operat
OpenAPI JSON'u `openapi.json` diye bir dosyaya indirip, şu tarz bir script ile **öndeki tag'i kaldırabiliriz**:
{* ../../docs_src/generate_clients/tutorial004_py39.py *}
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
//// tab | Node.js

View File

@@ -2,7 +2,7 @@
## Ek Özellikler { #additional-features }
Ana [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfası, **FastAPI**'ın tüm temel özelliklerini tanımanız için yeterli olmalıdır.
Ana [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfası, **FastAPI**'nin tüm temel özelliklerini tanımanız için yeterli olmalıdır.
Sonraki bölümlerde diğer seçenekleri, konfigürasyonları ve ek özellikleri göreceksiniz.
@@ -16,6 +16,6 @@ Ve kullanım amacınıza bağlı olarak, çözüm bunlardan birinde olabilir.
## Önce Tutorial'ı Okuyun { #read-the-tutorial-first }
Ana [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfasındaki bilgilerle **FastAPI**'nın çoğu özelliğini yine de kullanabilirsiniz.
Ana [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} sayfasındaki bilgilerle **FastAPI**'nin çoğu özelliğini yine de kullanabilirsiniz.
Ve sonraki bölümler, onu zaten okuduğunuzu ve bu temel fikirleri bildiğinizi varsayar.

View File

@@ -57,13 +57,13 @@ Gelen tüm request'lerin `https` veya `wss` olmasını zorunlu kılar.
`http` veya `ws` olarak gelen herhangi bir request, bunun yerine güvenli şemaya redirect edilir.
{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
HTTP Host Header saldırılarına karşı korunmak için, gelen tüm request'lerde `Host` header'ının doğru ayarlanmış olmasını zorunlu kılar.
{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
Aşağıdaki argümanlar desteklenir:
@@ -78,7 +78,7 @@ Gelen bir request doğru şekilde doğrulanmazsa `400` response gönderilir.
Middleware hem standart hem de streaming response'ları ele alır.
{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
Aşağıdaki argümanlar desteklenir:

View File

@@ -32,7 +32,7 @@ Webhook'lar OpenAPI 3.1.0 ve üzeri sürümlerde mevcuttur; FastAPI `0.99.0` ve
Bir **FastAPI** uygulaması oluşturduğunuzda, *webhook*'ları tanımlamak için kullanabileceğiniz bir `webhooks` attribute'u vardır; *path operation* tanımlar gibi, örneğin `@app.webhooks.post()` ile.
{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
Tanımladığınız webhook'lar **OpenAPI** şemasında ve otomatik **docs UI**'da yer alır.

View File

@@ -12,7 +12,7 @@ OpenAPI konusunda "uzman" değilseniz, muhtemelen buna ihtiyacınız yok.
Bunun her operation için benzersiz olduğundan emin olmanız gerekir.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
### operationId olarak *path operation function* adını kullanma { #using-the-path-operation-function-name-as-the-operationid }
@@ -20,7 +20,7 @@ APIlerinizin function adlarını `operationId` olarak kullanmak istiyorsanız
Bunu, tüm *path operation*ları ekledikten sonra yapmalısınız.
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
/// tip | İpucu
@@ -40,7 +40,7 @@ Farklı modüllerde (Python dosyalarında) olsalar bile.
Bir *path operation*ı üretilen OpenAPI şemasından (dolayısıyla otomatik dokümantasyon sistemlerinden) hariç tutmak için `include_in_schema` parametresini kullanın ve `False` yapın:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
## Docstringden İleri Düzey Açıklama { #advanced-description-from-docstring }
@@ -68,7 +68,7 @@ Uygulamanızda bir *path operation* tanımladığınızda, **FastAPI** OpenAPI
/// note | Teknik Detaylar
OpenAPI spesifikasyonunda buna <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation Object</a> denir.
OpenAPI spesifikasyonunda buna <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation Nesnesi</a> denir.
///
@@ -90,9 +90,9 @@ Bir *path operation* için OpenAPI şemasını `openapi_extra` parametresiyle ge
### OpenAPI Extensions { #openapi-extensions }
Örneğin bu `openapi_extra`, [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) tanımlamak için faydalı olabilir:
Örneğin bu `openapi_extra`, [OpenAPI Uzantıları](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) tanımlamak için faydalı olabilir:
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
Otomatik API dokümanlarını açtığınızda, extensionınız ilgili *path operation*ın en altında görünür.
@@ -139,9 +139,9 @@ Böylece otomatik üretilen şemaya ek veri ekleyebilirsiniz.
Bunu `openapi_extra` ile yapabilirsiniz:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
Bu örnekte herhangi bir Pydantic model tanımlamadık. Hatta request body JSON olarak <abbr title="converted from some plain format, like bytes, into Python objects - bytes gibi düz bir formattan Python nesnelerine dönüştürme">parsed</abbr> bile edilmiyor; doğrudan `bytes` olarak okunuyor ve `magic_data_reader()` fonksiyonu bunu bir şekilde parse etmekten sorumlu oluyor.
Bu örnekte herhangi bir Pydantic model tanımlamadık. Hatta request body JSON olarak <dfn title="bytes gibi düz bir formattan, ör. bytes, Python nesnelerine dönüştürme">ayrıştırılmıyor</dfn>; doğrudan `bytes` olarak okunuyor ve `magic_data_reader()` fonksiyonu bunu bir şekilde parse etmekten sorumlu oluyor.
Buna rağmen, request body için beklenen şemayı tanımlayabiliriz.
@@ -153,7 +153,7 @@ Ve bunu, request içindeki veri tipi JSON olmasa bile yapabilirsiniz.
Örneğin bu uygulamada, FastAPInin Pydantic modellerinden JSON Schema çıkarmaya yönelik entegre işlevselliğini ve JSON için otomatik doğrulamayı kullanmıyoruz. Hatta request content typeını JSON değil, YAML olarak tanımlıyoruz:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
Buna rağmen, varsayılan entegre işlevselliği kullanmasak da, YAML olarak almak istediğimiz veri için JSON Schemayı manuel üretmek üzere bir Pydantic model kullanmaya devam ediyoruz.
@@ -161,7 +161,7 @@ Ardından requesti doğrudan kullanıp bodyyi `bytes` olarak çıkarıyoru
Sonrasında kodumuzda bu YAML içeriğini doğrudan parse ediyor, ardından YAML içeriğini doğrulamak için yine aynı Pydantic modeli kullanıyoruz:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
/// tip | İpucu

View File

@@ -20,7 +20,7 @@ Bu tür durumlarda bir `Response` parametresi kullanabilirsiniz.
Ardından bu *geçici (temporal)* `Response` nesnesi üzerinde `status_code` değerini ayarlayabilirsiniz.
{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
Sonrasında, normalde yaptığınız gibi ihtiyacınız olan herhangi bir nesneyi döndürebilirsiniz (`dict`, bir veritabanı modeli, vb.).

View File

@@ -6,7 +6,7 @@
Ardından bu *geçici* response nesnesi üzerinde cookie'leri set edebilirsiniz.
{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
Sonrasında normalde yaptığınız gibi ihtiyaç duyduğunuz herhangi bir nesneyi döndürebilirsiniz (bir `dict`, bir veritabanı modeli vb.).
@@ -24,9 +24,9 @@ Bunu yapmak için, [Doğrudan Response Döndürme](response-directly.md){.intern
Sonra bunun içinde Cookie'leri set edin ve response'u döndürün:
{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
/// tip | İpucu
/// tip
`Response` parametresini kullanmak yerine doğrudan bir response döndürürseniz, FastAPI onu olduğu gibi (doğrudan) döndürür.

View File

@@ -2,7 +2,7 @@
**FastAPI** ile bir *path operation* oluşturduğunuzda, normalde ondan herhangi bir veri döndürebilirsiniz: bir `dict`, bir `list`, bir Pydantic model, bir veritabanı modeli vb.
Varsayılan olarak **FastAPI**, döndürdüğünüz bu değeri [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} bölümünde anlatılan `jsonable_encoder` ile otomatik olarak JSON'a çevirir.
Varsayılan olarak **FastAPI**, döndürdüğünüz bu değeri [JSON Uyumlu Encoder](../tutorial/encoder.md){.internal-link target=_blank} bölümünde anlatılan `jsonable_encoder` ile otomatik olarak JSON'a çevirir.
Ardından perde arkasında, JSON-uyumlu bu veriyi (ör. bir `dict`) client'a response göndermek için kullanılacak bir `JSONResponse` içine yerleştirir.
@@ -54,12 +54,12 @@ Diyelim ki <a href="https://en.wikipedia.org/wiki/XML" class="external-link" tar
XML içeriğinizi bir string içine koyabilir, onu bir `Response` içine yerleştirip döndürebilirsiniz:
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
## Notlar { #notes }
Bir `Response`'u doğrudan döndürdüğünüzde, verisi otomatik olarak validate edilmez, dönüştürülmez (serialize edilmez) veya dokümante edilmez.
Ancak yine de [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank} bölümünde anlatıldığı şekilde dokümante edebilirsiniz.
Ancak yine de [OpenAPI'de Ek Response'lar](additional-responses.md){.internal-link target=_blank} bölümünde anlatıldığı şekilde dokümante edebilirsiniz.
İlerleyen bölümlerde, otomatik veri dönüşümü, dokümantasyon vb. özellikleri korurken bu özel `Response`'ları nasıl kullanıp declare edebileceğinizi göreceksiniz.

View File

@@ -6,7 +6,7 @@
Sonra da bu *geçici* response nesnesi üzerinde header'ları ayarlayabilirsiniz.
{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
Ardından normalde yaptığınız gibi ihtiyacınız olan herhangi bir nesneyi döndürebilirsiniz (bir `dict`, bir veritabanı modeli vb.).
@@ -22,7 +22,7 @@ Doğrudan bir `Response` döndürdüğünüzde de header ekleyebilirsiniz.
[Bir Response'u Doğrudan Döndürün](response-directly.md){.internal-link target=_blank} bölümünde anlatıldığı gibi bir response oluşturun ve header'ları ek bir parametre olarak geçin:
{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
/// note | Teknik Detaylar

View File

@@ -20,7 +20,7 @@ Ardından kullanıcı adı ve şifreyi yazdığınızda tarayıcı bunları otom
* Bu, `HTTPBasicCredentials` tipinde bir nesne döndürür:
* İçinde gönderilen `username` ve `password` bulunur.
{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
URLyi ilk kez açmaya çalıştığınızda (veya dokümanlardaki "Execute" butonuna tıkladığınızda) tarayıcı sizden kullanıcı adınızı ve şifrenizi ister:
@@ -40,13 +40,13 @@ Bunu yönetmek için önce `username` ve `password` değerlerini UTF-8 ile encod
Sonra `secrets.compare_digest()` kullanarak `credentials.username`in `"stanleyjobson"` ve `credentials.password`ün `"swordfish"` olduğundan emin olabiliriz.
{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
Bu, kabaca şuna benzer olurdu:
```Python
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
# Return some error
# Bir hata döndür
...
```
@@ -104,4 +104,4 @@ Bu sayede uygulama kodunuzda `secrets.compare_digest()` kullanarak bu güvenlik
Credentialların hatalı olduğunu tespit ettikten sonra, 401 status code ile (credential verilmediğinde dönenle aynı) bir `HTTPException` döndürün ve tarayıcının giriş penceresini yeniden göstermesi için `WWW-Authenticate` headerını ekleyin:
{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}

View File

@@ -2,7 +2,7 @@
## Ek Özellikler { #additional-features }
[Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasında ele alınanların dışında güvenlikle ilgili bazı ek özellikler vardır.
[Öğretici - Kullanıcı Kılavuzu: Güvenlik](../../tutorial/security/index.md){.internal-link target=_blank} sayfasında ele alınanların dışında güvenlikle ilgili bazı ek özellikler vardır.
/// tip | İpucu
@@ -14,6 +14,6 @@ Ve kullanım durumunuza göre, çözüm bu bölümlerden birinde olabilir.
## Önce Öğreticiyi Okuyun { #read-the-tutorial-first }
Sonraki bölümler, ana [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasını zaten okuduğunuzu varsayar.
Sonraki bölümler, ana [Öğretici - Kullanıcı Kılavuzu: Güvenlik](../../tutorial/security/index.md){.internal-link target=_blank} sayfasını zaten okuduğunuzu varsayar.
Hepsi aynı kavramlara dayanır, ancak bazı ek işlevselliklere izin verir.

View File

@@ -16,7 +16,7 @@ Bu bölüm az çok ileri seviye sayılır. Yeni başlıyorsanız atlayabilirsini
OAuth2 scope'larına mutlaka ihtiyacınız yok; authentication ve authorization'ı istediğiniz şekilde ele alabilirsiniz.
Ancak scope'lu OAuth2, API'nize (OpenAPI ile) ve API dokümanlarınıza güzel biçimde entegre edilebilir.
Namun scope'lu OAuth2, API'nize (OpenAPI ile) ve API dokümanlarınıza güzel biçimde entegre edilebilir.
Buna rağmen, bu scope'ları (veya başka herhangi bir security/authorization gereksinimini) kodunuzda ihtiyaç duyduğunuz şekilde yine siz zorunlu kılarsınız.
@@ -257,7 +257,7 @@ Ancak başkalarının bağlanacağı bir OAuth2 uygulaması geliştiriyorsanız
En yaygını implicit flow'dur.
En güvenlisi code flow'dur; ancak daha fazla adım gerektirdiği için implementasyonu daha karmaşıktır. Daha karmaşık olduğundan, birçok sağlayıcı implicit flow'yu önermeye yönelir.
En güvenlisi code flow'dur; ancak daha fazla adım gerektirdiği için implementasyonu daha karmaşıktır. Daha karmaşıktır olduğundan, birçok sağlayıcı implicit flow'yu önermeye yönelir.
/// note | Not

View File

@@ -54,7 +54,7 @@ Pydantic model'lerinde olduğu gibi, type annotation'larla (ve gerekirse default
Pydantic model'lerinde kullandığınız aynı doğrulama özelliklerini ve araçlarını burada da kullanabilirsiniz; örneğin farklı veri tipleri ve `Field()` ile ek doğrulamalar.
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
/// tip | İpucu
@@ -70,7 +70,7 @@ Sonrasında veriyi dönüştürür ve doğrular. Böylece `settings` nesnesini k
Daha sonra uygulamanızda yeni `settings` nesnesini kullanabilirsiniz:
{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
### Server'ı çalıştırın { #run-the-server }
@@ -104,11 +104,11 @@ Böylece `admin_email` ayarı `"deadpool@example.com"` olur.
Örneğin `config.py` adında bir dosyanız şu şekilde olabilir:
{* ../../docs_src/settings/app01_py39/config.py *}
{* ../../docs_src/settings/app01_py310/config.py *}
Ve ardından bunu `main.py` dosyasında kullanabilirsiniz:
{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
/// tip | İpucu
@@ -126,7 +126,7 @@ Bu özellikle test sırasında çok işe yarar; çünkü bir dependency'yi kendi
Bir önceki örnekten devam edersek, `config.py` dosyanız şöyle görünebilir:
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
Dikkat edin, artık default bir instance `settings = Settings()` oluşturmuyoruz.
@@ -134,7 +134,7 @@ Dikkat edin, artık default bir instance `settings = Settings()` oluşturmuyoruz
Şimdi, yeni bir `config.Settings()` döndüren bir dependency oluşturuyoruz.
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
/// tip | İpucu
@@ -146,13 +146,13 @@ Dikkat edin, artık default bir instance `settings = Settings()` oluşturmuyoruz
Sonra bunu dependency olarak *path operation function*'dan talep edebilir ve ihtiyaç duyduğumuz her yerde kullanabiliriz.
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
### Ayarlar ve test { #settings-and-testing }
Ardından, `get_settings` için bir dependency override oluşturarak test sırasında farklı bir settings nesnesi sağlamak çok kolay olur:
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
Dependency override içinde, yeni `Settings` nesnesini oluştururken `admin_email` için yeni bir değer ayarlarız ve sonra bu yeni nesneyi döndürürüz.
@@ -193,7 +193,7 @@ APP_NAME="ChimichangApp"
Ardından `config.py` dosyanızı şöyle güncelleyin:
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
/// tip | İpucu
@@ -226,7 +226,7 @@ bu nesneyi her request için oluştururduk ve `.env` dosyasını her request'te
Fakat en üstte `@lru_cache` decorator'ünü kullandığımız için `Settings` nesnesi yalnızca bir kez, ilk çağrıldığı anda oluşturulur. ✔️
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
Sonraki request'lerde dependency'ler içinden `get_settings()` çağrıldığında, `get_settings()`'in iç kodu tekrar çalıştırılıp yeni bir `Settings` nesnesi yaratılmak yerine, ilk çağrıda döndürülen aynı nesne tekrar tekrar döndürülür.

View File

@@ -10,7 +10,7 @@ Kendi bağımsız OpenAPI şemaları ve kendi dokümantasyon arayüzleri olan ik
Önce ana, üst seviye **FastAPI** uygulamasını ve onun *path operation*larını oluşturun:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
### Alt uygulama { #sub-application }
@@ -18,7 +18,7 @@ Sonra alt uygulamanızı ve onun *path operation*larını oluşturun.
Bu alt uygulama da standart bir FastAPI uygulamasıdır; ancak "mount" edilecek olan budur:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
### Alt uygulamayı mount edin { #mount-the-sub-application }
@@ -26,7 +26,7 @@ Bu alt uygulama da standart bir FastAPI uygulamasıdır; ancak "mount" edilecek
Bu örnekte `/subapi` pathine mount edilecektir:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
### Otomatik API dokümanlarını kontrol edin { #check-the-automatic-api-docs }
@@ -64,4 +64,4 @@ Bu sayede alt uygulama, dokümantasyon arayüzü için o path önekini kullanmas
Ayrıca alt uygulamanın kendi mount edilmiş alt uygulamaları da olabilir; FastAPI tüm bu `root_path`leri otomatik olarak yönettiği için her şey doğru şekilde çalışır.
`root_path` hakkında daha fazlasını ve bunu açıkça nasıl kullanacağınızı [Behind a Proxy](behind-a-proxy.md){.internal-link target=_blank} bölümünde öğreneceksiniz.
`root_path` hakkında daha fazlasını ve bunu açıkça nasıl kullanacağınızı [Proxy Arkasında](behind-a-proxy.md){.internal-link target=_blank} bölümünde öğreneceksiniz.

View File

@@ -27,9 +27,9 @@ $ pip install jinja2
* Template döndürecek *path operation* içinde bir `Request` parametresi tanımlayın.
* Oluşturduğunuz `templates` nesnesini kullanarak bir `TemplateResponse` render edip döndürün; template'in adını, request nesnesini ve Jinja2 template'i içinde kullanılacak anahtar-değer çiftlerini içeren bir "context" sözlüğünü (dict) iletin.
{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
/// note | Not
/// note
FastAPI 0.108.0 ve Starlette 0.29.0 öncesinde, ilk parametre `name` idi.
@@ -37,7 +37,7 @@ Ayrıca, daha önceki sürümlerde `request` nesnesi, Jinja2 için context için
///
/// tip | İpucu
/// tip
`response_class=HTMLResponse` olarak tanımlarsanız doküman arayüzü (docs UI) response'un HTML olacağını anlayabilir.

View File

@@ -46,6 +46,7 @@ Sonrasında override'larınızı (yani kaldırıp sıfırlamayı) `app.dependenc
app.dependency_overrides = {}
```
/// tip | İpucu
Bir dependency'yi yalnızca bazı testler sırasında override etmek istiyorsanız, override'ı testin başında (test function'ının içinde) ayarlayıp testin sonunda (yine test function'ının sonunda) sıfırlayabilirsiniz.

View File

@@ -2,11 +2,11 @@
Test'lerinizde `lifespan`'ın çalışması gerektiğinde, `TestClient`'ı bir `with` ifadesiyle kullanabilirsiniz:
{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
Bu konuda daha fazla ayrıntıyı resmi Starlette dokümantasyon sitesindeki ["Running lifespan in tests in the official Starlette documentation site."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) bölümünde okuyabilirsiniz.
Bu konuda daha fazla ayrıntıyı resmi Starlette dokümantasyon sitesindeki ["Testlerde lifespan'ı çalıştırma"](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) bölümünde okuyabilirsiniz.
Kullanımdan kaldırılmış `startup` ve `shutdown` event'leri için ise `TestClient`'ı aşağıdaki gibi kullanabilirsiniz:
{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}

View File

@@ -4,7 +4,7 @@ WebSockets'i test etmek için aynı `TestClient`'ı kullanabilirsiniz.
Bunun için `TestClient`'ı bir `with` ifadesinde kullanarak WebSocket'e bağlanırsınız:
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
/// note | Not

View File

@@ -29,7 +29,7 @@ Ama bazı özel durumlarda `Request` nesnesini almak faydalıdır.
Bunun için request'e doğrudan erişmeniz gerekir.
{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
Tipi `Request` olan bir *path operation function* parameter'ı tanımladığınızda **FastAPI**, o parameter'a `Request` nesnesini geçmesi gerektiğini anlar.

View File

@@ -38,13 +38,13 @@ Production'da yukarıdaki seçeneklerden birini kullanırsınız.
Ama WebSockets'in server tarafına odaklanmak ve çalışan bir örnek görmek için en basit yol bu:
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
## Bir `websocket` Oluşturun { #create-a-websocket }
**FastAPI** uygulamanızda bir `websocket` oluşturun:
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
/// note | Teknik Detaylar
@@ -58,7 +58,7 @@ Ama WebSockets'in server tarafına odaklanmak ve çalışan bir örnek görmek i
WebSocket route'unuzda mesajları `await` edebilir ve mesaj gönderebilirsiniz.
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
Binary, text ve JSON verisi alıp gönderebilirsiniz.
@@ -154,7 +154,7 @@ Bununla WebSocket'e bağlanabilir, ardından mesaj gönderip alabilirsiniz:
Bir WebSocket bağlantısı kapandığında, `await websocket.receive_text()` bir `WebSocketDisconnect` exception'ı raise eder; ardından bunu bu örnekteki gibi yakalayıp (catch) yönetebilirsiniz.
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
Denemek için:

View File

@@ -18,7 +18,7 @@ Ardından WSGI (örn. Flask) uygulamasını middleware ile sarmalayın.
Ve sonra bunu bir path'in altına mount edin.
{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
/// note | Not

View File

@@ -137,7 +137,7 @@ Birçok Flask REST frameworkü var; ancak zaman ayırıp inceledikten sonra
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
API sistemlerinin ihtiyaç duyduğu temel özelliklerden biri, koddan (Python) veriyi alıp ağ üzerinden gönderilebilecek bir şeye dönüştürmek, yani veri “<abbr title="marshalling, conversion olarak da adlandırılır">dönüşüm</abbr>”üdür. Örneğin, bir veritabanından gelen verileri içeren bir objeyi JSON objesine dönüştürmek, `datetime` objelerini stringe çevirmek vb.
API sistemlerinin ihtiyaç duyduğu temel özelliklerden biri, koddan (Python) veriyi alıp ağ üzerinden gönderilebilecek bir şeye dönüştürmek, yani veri “<dfn title="marshalling, conversion olarak da adlandırılır">dönüşüm</dfn>”üdür. Örneğin, bir veritabanından gelen verileri içeren bir objeyi JSON objesine dönüştürmek, `datetime` objelerini stringe çevirmek vb.
APIların ihtiyaç duyduğu bir diğer önemli özellik, veri doğrulamadır; belirli parametreler göz önüne alındığında verinin geçerli olduğundan emin olmak. Örneğin, bir alanın `int` olması ve rastgele bir metin olmaması. Bu özellikle dışarıdan gelen veriler için kullanışlıdır.
@@ -145,7 +145,7 @@ Bir veri doğrulama sistemi olmadan, tüm bu kontrolleri kod içinde el ile yapm
Marshmallow, bu özellikleri sağlamak için inşa edildi. Harika bir kütüphanedir ve geçmişte çok kullandım.
Ancak Python tip belirteçlerinden önce yazılmıştır. Dolayısıyla her <abbr title="verinin nasıl oluşturulması gerektiğinin tanımı">şemayı</abbr> tanımlamak için Marshmallowun sağladığı belirli yardımcılar ve sınıflar kullanılır.
Ancak Python tip belirteçlerinden önce yazılmıştır. Dolayısıyla her <dfn title="verinin nasıl oluşturulması gerektiğinin tanımı">şemayı</dfn> tanımlamak için Marshmallowun sağladığı belirli yardımcılar ve sınıflar kullanılır.
/// check | **FastAPI**'a ilham olan
@@ -155,7 +155,7 @@ Kodla, veri tiplerini ve doğrulamayı otomatik sağlayan “şemalar” tanıml
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
APIların ihtiyaç duyduğu bir diğer büyük özellik, gelen isteklerden veriyi <abbr title="okuyup Python verisine dönüştürmek">ayrıştırma</abbr>dır.
APIların ihtiyaç duyduğu bir diğer büyük özellik, gelen isteklerden veriyi <dfn title="okuyup Python verisine dönüştürme">ayrıştırma</dfn>dır.
Webargs, Flask dahil birkaç frameworkün üzerinde bunu sağlamak için geliştirilmiş bir araçtır.
@@ -417,7 +417,7 @@ Tüm veri doğrulama, veri dönüşümü ve JSON Schema tabanlı otomatik model
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
Starlette, yüksek performanslı asyncio servisleri oluşturmak için ideal, hafif bir <abbr title="Asenkron Python web uygulamaları geliştirmek için yeni standart">ASGI</abbr> frameworkü/araç takımıdır.
Starlette, yüksek performanslı asyncio servisleri oluşturmak için ideal, hafif bir <dfn title="Asenkron Python web uygulamaları geliştirmek için yeni standart">ASGI</dfn> frameworkü/araç takımıdır.
Çok basit ve sezgiseldir. Kolayca genişletilebilir ve modüler bileşenlere sahip olacak şekilde tasarlanmıştır.

View File

@@ -1,18 +1,18 @@
# Concurrency ve async / await
# Eşzamanlılık ve async / await { #concurrency-and-async-await }
*path operasyon fonksiyonu* için `async def `sözdizimi, asenkron kod, eşzamanlılık ve paralellik hakkında bazı ayrıntılar.
*path operasyon fonksiyonları* için `async def` sözdizimi hakkında detaylar ve asenkron kod, eşzamanlılık (concurrency) ve paralellik üzerine arka plan bilgisi.
## Aceleniz mi var?
## Aceleniz mi var? { #in-a-hurry }
<abbr title="too long; didn't read"><strong>TL;DR:</strong></abbr>
<abbr title="too long; didn't read - çok uzun; okumadım"><strong>TL;DR:</strong></abbr>
Eğer `await` ile çağrılması gerektiğini belirten üçüncü taraf kütüphaneleri kullanıyorsanız, örneğin:
Eğer `await` ile çağırmanız gerektiğini söyleyen üçüncü taraf kütüphaneler kullanıyorsanız, örneğin:
```Python
results = await some_library()
```
O zaman *path operasyon fonksiyonunu* `async def` ile tanımlayın örneğin:
O zaman *path operasyon fonksiyonlarınızı* aşağıdaki gibi `async def` ile tanımlayın:
```Python hl_lines="2"
@app.get('/')
@@ -23,13 +23,13 @@ async def read_results():
/// note | Not
Sadece `async def` ile tanımlanan fonksiyonlar içinde `await` kullanabilirsiniz.
`await` yalnızca `async def` ile oluşturulan fonksiyonların içinde kullanılabilir.
///
---
Eğer bir veritabanı, bir API, dosya sistemi vb. ile iletişim kuran bir üçüncü taraf bir kütüphane kullanıyorsanız ve `await` kullanımını desteklemiyorsa, (bu şu anda çoğu veritabanı kütüphanesi için geçerli bir durumdur), o zaman *path operasyon fonksiyonunuzu* `def` kullanarak normal bir şekilde tanımlayın, örneğin:
Eğer bir veritabanı, bir API, dosya sistemi vb. ile iletişim kuran ve `await` desteği olmayan bir üçüncü taraf kütüphane kullanıyorsanız (bu şu anda çoğu veritabanı kütüphanesi için geçerlidir), o zaman *path operasyon fonksiyonlarınızı* normal olarak `def` ile tanımlayın:
```Python hl_lines="2"
@app.get('/')
@@ -40,279 +40,307 @@ def results():
---
Eğer uygulamanız (bir şekilde) başka bir şeyle iletişim kurmak ve onun cevap vermesini beklemek zorunda değilse, `async def` kullanın.
Uygulamanız (bir şekilde) başka bir şeyle iletişim kurmak ve onun yanıtını beklemek zorunda değilse, içinde `await` kullanmanız gerekmese bile `async def` kullanın.
---
Sadece bilmiyorsanız, normal `def` kullanın.
Emin değilseniz, normal `def` kullanın.
---
**Not**: *path operasyon fonksiyonlarınızda* `def` ve `async def`'i ihtiyaç duyduğunuz gibi karıştırabilir ve her birini sizin için en iyi seçeneği kullanarak tanımlayabilirsiniz. FastAPI onlarla doğru olanı yapacaktır.
Not: *path operasyon fonksiyonlarınızda* `def` ve `async def`'i ihtiyacınız kadar karıştırabilirsiniz, her birini sizin için en iyi seçenekle tanımlayın. FastAPI onlar için doğru olanı yapacaktır.
Her neyse, yukarıdaki durumlardan herhangi birinde, FastAPI yine de asenkron olarak çalışacak ve son derece hızlı olacaktır.
Yukarıdaki durumların herhangi birinde FastAPI yine de asenkron olarak çalışır ve son derece hızlıdır.
Ancak yukarıdaki adımları takip ederek, bazı performans optimizasyonları yapılabilecektir.
Ancak yukarıdaki adımları izleyerek bazı performans optimizasyonları mümkün olur.
## Teknik Detaylar
## Teknik Detaylar { #technical-details }
Python'un modern versiyonlarında **`async` ve `await`** sözdizimi ile **"coroutines"** kullanan **"asenkron kod"** desteğine sahiptir.
Pythonun modern sürümleri, **`async` ve `await`** sözdizimiyle, **"coroutines"** denilen bir yapıyı kullanarak **"asenkron kod"** desteğine sahiptir.
Bu ifadeyi aşağıdaki bölümlerde daha da ayrıntılııklayalım:
Aşağıdaki bölümlerde bu ifadeyi parça parça ele alalım:
* **Asenkron kod**
* **Asenkron Kod**
* **`async` ve `await`**
* **Coroutines**
* **Coroutine'ler**
## Asenkron kod
## Asenkron Kod { #asynchronous-code }
Asenkron kod programlama dilinin 💬 bilgisayara / programa 🤖 kodun bir noktasında, *başka bir kodun* bir yerde bitmesini 🤖 beklemesi gerektiğini söylemenin bir yoludur. Bu *başka koda* "slow-file" denir 📝.
Asenkron kod, dilin 💬 bilgisayara / programa 🤖 kodun bir noktasında, bir yerde *başka bir şeyin* bitmesini beklemesi gerektiğini söylemesinin bir yoludur. Diyelim ki bu *başka şeye* "slow-file" 📝 diyoruz.
Böylece, bu süreçte bilgisayar "slow-file" 📝 tamamlanırken gidip başka işler yapabilir.
Bu sırada bilgisayar, "slow-file" 📝 biterken gidip başka işler yapabilir.
Sonra bilgisayar / program 🤖 her fırsatı olduğunda o noktada yaptığı tüm işleri 🤖 bitirene kadar geri dönücek. Ve 🤖 yapması gerekeni yaparak, beklediği görevlerden herhangi birinin bitip bitmediğini görecek.
Sonra bilgisayar / program 🤖, ya tekrar beklediği için ya da o anda elindeki tüm işleri bitirdiğinde fırsat buldukça geri gelir. Ve beklediği görevlerden herhangi biri bittiyse, yapılması gerekenleri yapar.
Ardından, 🤖 bitirmek için ilk görevi alır ("slow-file" 📝) ve onunla ne yapması gerekiyorsa onu devam ettirir.
Ardından, 🤖 ilk biten görevi alır (örneğin bizim "slow-file" 📝) ve onunla yapması gerekenlere devam eder.
Bu "başka bir şey için bekle" normalde, aşağıdakileri beklemek gibi (işlemcinin ve RAM belleğinin hızına kıyasla) nispeten "yavaş" olan <abbr title="Input ve Output (Giriş ve Çıkış)">I/O</abbr> işlemlerine atıfta bulunur:
Bu "başka bir şeyi beklemek" genelde işlemci ve RAM hızına kıyasla nispeten "yavaş" olan <abbr title="Input and Output - Giriş ve Çıkış">I/O</abbr> işlemlerine atıfta bulunur, örneğin şunları beklemek gibi:
* istemci tarafından ağ üzerinden veri göndermek
* ağ üzerinden istemciye gönderilen veriler
* sistem tarafından okunacak ve programınıza verilecek bir dosya içeriği
* programınızın diske yazılmak üzere sisteme verdiği dosya içerikleri
* istemciden verinin ağ üzerinden gelmesi
* programınızın gönderdiği verinin ağ üzerinden istemciye ulaşması
* diskteki bir dosyanın içeriğinin sistem tarafından okunup programınıza verilmesi
* programınızın sisteme verdiği içeriğin diske yazılması
* uzak bir API işlemi
* bir veritabanı bitirme işlemi
* sonuçları döndürmek için bir veritabanı sorgusu
* bir veritabanı işleminin bitmesi
* bir veritabanı sorgusunun sonuç döndürmesi
* vb.
Yürütme süresi çoğunlukla <abbr title="Input ve Output (Giriş ve Çıkış)">I/O</abbr> işlemleri beklenerek tüketildiğinden bunlara "I/O bağlantılı" işlemler denir.
Çalışma süresi çoğunlukla <abbr title="Input and Output - Giriş ve Çıkış">I/O</abbr> işlemlerini beklemekle geçtiğinden, bunlara "I/O bound" işlemler denir.
Buna "asenkron" denir, çünkü bilgisayar/program yavaş görevle "senkronize" olmak zorunda değildir, görevin tam olarak biteceği anı bekler, hiçbir şey yapmadan, görev sonucunu alabilmek ve çalışmaya devam edebilmek için .
"Bunun" asenkron" denmesinin sebebi, bilgisayarın / programın yavaş görevle "senkronize" olmak, görev tam bittiği anda orada olup görev sonucunu almak ve işe devam etmek için hiçbir şey yapmadan beklemek zorunda olmamasıdır.
Bunun yerine, "asenkron" bir sistem olarak, bir kez bittiğinde, bilgisayarın / programın yapması gerekeni bitirmesi için biraz (birkaç mikrosaniye) sırada bekleyebilir ve ardından sonuçları almak için geri gelebilir ve onlarla çalışmaya devam edebilir.
Bunun yerine "asenkron" bir sistem olarak, görev bittiğinde, bilgisayarın / programın o sırada yaptığıi bitirmesi için biraz (birkaç mikrosaniye) sırada bekleyebilir ve sonra sonuçları almak üzere geri dönüp onlarla çalışmaya devam edebilir.
"Senkron" ("asenkron"un aksine) için genellikle "sıralı" terimini de kullanırlar, çünkü bilgisayar/program, bu adımlar beklemeyi içerse bile, farklı bir göreve geçmeden önce tüm adımları sırayla izler.
"Senkron" (asenkronun tersi) için genelde "sıralı" terimi de kullanılır; çünkü bilgisayar / program, farklı bir göreve geçmeden önce tüm adımları sırayla izler, bu adımlar beklemeyi içerse bile.
### Eşzamanlılık ve Burgerler { #concurrency-and-burgers }
### Eşzamanlılık (Concurrency) ve Burgerler
Yukarıda anlatılan **asenkron** kod fikrine bazen **"eşzamanlılık"** (concurrency) da denir. **"Paralellik"**ten (parallelism) farklıdır.
**Eşzamanlılık** ve **paralellik**, "aynı anda az çok birden fazla şeyin olması" ile ilgilidir.
Yukarıda açıklanan bu **asenkron** kod fikrine bazen **"eşzamanlılık"** da denir. **"Paralellikten"** farklıdır.
Ama *eşzamanlılık* ve *paralellik* arasındaki ayrıntılar oldukça farklıdır.
**Eşzamanlılık** ve **paralellik**, "aynı anda az ya da çok olan farklı işler" ile ilgilidir.
Farkı görmek için burgerlerle ilgili şu hikayeyi hayal edin:
Ancak *eşzamanlılık* ve *paralellik* arasındaki ayrıntılar oldukça farklıdır.
### Eşzamanlı Burgerler { #concurrent-burgers }
Aşkınla fast food almaya gidiyorsun, kasiyer senden önceki insanların siparişlerini alırken sıraya giriyorsun. 😍
Farkı görmek için burgerlerle ilgili aşağıdaki hikayeyi hayal edin:
<img src="/img/async/concurrent-burgers/concurrent-burgers-01.png" class="illustration">
### Eşzamanlı Burgerler
Sonra sıra size geliyor, sen ve aşkın için 2 çok havalı burger sipariş ediyorsun. 🍔🍔
<!-- Cinsiyetten bağımsız olan aşçı emojisi "🧑‍🍳" tarayıcılarda yeterince iyi görüntülenmiyor. Bu yüzden erken "👨‍🍳" ve kadın "👩‍🍳" aşçıları karışık bir şekilde kullanıcağım. -->
<img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration">
Aşkınla beraber 😍 dışarı hamburger yemeye çıktınız 🍔, kasiyer 💁 öndeki insanlardan sipariş alırken siz sıraya girdiniz.
Kasiyer, mutfaktaki aşçıya burgerlerini hazırlamaları gerektiğini söylüyor (o an önceki müşterilerin burgerlerini hazırlıyor olsalar bile).
Sıra sizde ve sen aşkın 😍 ve kendin için 2 çılgın hamburger 🍔 söylüyorsun.
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration">
Ödemeyi yaptın 💸.
Ödeme yapıyorsun. 💸
Kasiyer 💁 mutfakdaki aşçıya 👨‍🍳 hamburgerleri 🍔 hazırlaması gerektiğini söyler ve aşçı bunu bilir (o an önceki müşterilerin siparişlerini hazırlıyor olsa bile).
Kasiyer sana sıra numaranı veriyor.
Kasiyer 💁 size bir sıra numarası verir.
<img src="/img/async/concurrent-burgers/concurrent-burgers-04.png" class="illustration">
Beklerken askınla 😍 bir masaya oturur ve uzun bir süre konuşursunuz(Burgerleriniz çok çılgın olduğundan ve hazırlanması biraz zaman alıyor ✨🍔✨).
Beklerken aşkınla bir masa seçip oturuyorsunuz, uzun uzun sohbet ediyorsunuz (burgerler baya havalı ve hazırlanması biraz zaman alıyor).
Hamburgeri beklerkenki zamanı 🍔, aşkının ne kadar zeki ve tatlı olduğuna hayran kalarak harcayabilirsin ✨😍✨.
Masada aşkınla otururken, burgerleri beklerken, o zamanı aşkının ne kadar harika, tatlı ve zeki olduğuna hayran kalarak geçirebilirsin ✨😍✨.
Aşkınla 😍 konuşurken arada sıranın size gelip gelmediğini kontrol ediyorsun.
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration">
Nihayet sıra size geldi. Tezgaha gidip hamburgerleri 🍔kapıp masaya geri dönüyorsun.
Bekler ve sohbet ederken, ara ara tezgâhtaki numaraya bakıp sıranın size gelip gelmediğini kontrol ediyorsun.
Aşkınla hamburgerlerinizi yiyor 🍔 ve iyi vakit geçiriyorsunuz ✨.
Bir noktada, nihayet sıra size geliyor. Tezgâha gidiyor, burgerleri alıp masaya dönüyorsun.
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration">
Aşkınla burgerleri yiyip güzel vakit geçiriyorsunuz. ✨
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
/// info | Bilgi
Harika çizimler: <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
///
---
Bu hikayedeki bilgisayar / program 🤖 olduğunuzu hayal edin.
Bu hikâyede bilgisayar / program 🤖 olduğunu hayal et.
Sırada beklerken boştasın 😴, sıranı beklerken herhangi bir "üretim" yapmıyorsun. Ama bu sıra hızlı çünkü kasiyer sadece siparişleri alıyor (onları hazırlamıyor), burada bir sıknıtı yok.
Sıradayken sadece boştasın 😴, sıranı bekliyorsun, çok "üretken" bir şey yapmıyorsun. Ama sorun yok, çünkü kasiyer sadece sipariş alıyor (hazırlamıyor), bu yüzden sıra hızlı ilerliyor.
Sonra sıra size geldiğinde gerçekten "üretken" işler yapabilirsiniz 🤓, menüyü oku, ne istediğine larar ver, aşkının seçimini al 😍, öde 💸, doğru kartı çıkart, ödemeyi kontrol et, faturayı kontrol et, siparişin doğru olup olmadığını kontrol et, vb.
Sıra sana geldiğinde gerçekten "üretken" işler yapıyorsun: menüyü işliyorsun, ne istediğine karar veriyorsun, aşkının seçimini alıyorsun, ödüyorsun, doğru para ya da kartı verdiğini kontrol ediyorsun, doğru ücretlendirildiğini kontrol ediyorsun, sipariş kalemlerinin doğru olduğunu kontrol ediyorsun, vb.
Ama hamburgerler 🍔 hazır olmamasına rağmen Kasiyer 💁 ile işiniz "duraklıyor" ⏸, çünkü hamburgerlerin hazır olmasını bekliyoruz 🕙.
Ama sonra, burgerlerin hâlâ gelmemiş olsa da, kasiyerle olan işin "duraklatılıyor" ⏸, çünkü burgerlerin hazır olmasını 🕙 beklemen gerekiyor.
Ama tezgahtan uzaklaşıp sıranız gelene kadarmasanıza dönebilir 🔀 ve dikkatinizi aşkınıza 😍 verebilirsiniz vr bunun üzerine "çalışabilirsiniz" ⏯ 🤓. Artık "üretken" birşey yapıyorsunuz 🤓, sevgilinle 😍 flört eder gibi.
Fakat tezgâhtan uzaklaşıp masada sıra numaranla oturduğun için, dikkatinizi 🔀 aşkına çevirebilir, onunla "çalışmaya" ⏯ 🤓 odaklanabilirsin. Yani yine çok "üretken" bir şey yapıyorsun, aşkınla flört etmek gibi 😍.
Kasiyer 💁 "Hamburgerler hazır !" 🍔 dediğinde ve görüntülenen numara sizin numaranız olduğunda hemen koşup hamburgerlerinizi almaya çalışmıyorsunuz. Biliyorsunuzki kimse sizin hamburgerlerinizi 🍔 çalmayacak çünkü sıra sizin.
Ardından kasiyer 💁, tezgâh ekranına numaranı koyarak "burgerleri bitirdim" diyor; ama numara seninki olduğunda çılgınca sıçramıyorsun. Sıra numaran sende, herkesin kendi numarası var; kimse burgerlerini çalamaz.
Yani Aşkınızın😍 hikayeyi bitirmesini bekliyorsunuz (çalışmayı bitir ⏯ / görev işleniyor.. 🤓), nazikçe gülümseyin ve hamburger yemeye gittiğinizi söyleyin ⏸.
Bu yüzden aşkının hikâyeyi bitirmesini (mevcut işi ⏯ / işlenen görevi 🤓 bitirmesini) bekliyor, nazikçe gülümsüyor ve burgerleri almaya gittiğini söylüyorsun ⏸.
Ardından tezgaha 🔀, şimdi biten ilk göreve ⏯ gidin, Hamburgerleri 🍔 alın, teşekkür edin ve masaya götürün. sayacın bu adımı tamamlanır ⏹. Bu da yeni bir görev olan "hamburgerleri ye" 🔀 ⏯ görevini başlatırken "hamburgerleri al" görevini bitirir.
Sonra tezgâha 🔀 gidip artık bitmiş olan ilk göreve ⏯ dönüyor, burgerleri alıyor, teşekkür ediyor ve masaya getiriyorsun. Tezgâhla etkileşimin bu adımı / görevi böylece bitiyor ⏹. Bu da yeni bir görev olan "burgerleri yemek" 🔀 ⏯ görevini oluşturuyor, ama "burgerleri almak" görevi tamamlandı.
### Parallel Hamburgerler
### Paralel Burgerler { #parallel-burgers }
Şimdi bunların "Eşzamanlı Hamburger" değil, "Paralel Hamburger" olduğunu düşünelim.
Şimdi bunların "Eşzamanlı Burgerler" değil, "Paralel Burgerler" olduğunu hayal edelim.
Hamburger 🍔 almak için 😍 aşkınla Paralel fast food'a gidiyorsun.
Aşkınla paralel fast food almaya gidiyorsun.
Birden fazla kasiyer varken (varsayalım 8) sıraya girdiniz👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 ve sıranız gelene kadar bekliyorsunuz.
Aynı anda aşçı da olan birden fazla (8 diyelim) kasiyerin, senden önceki insanların siparişlerini aldığı bir sırada bekliyorsun.
Sizden önceki herkez ayrılmadan önce hamburgerlerinin 🍔 hazır olmasını bekliyor 🕙. Çünkü kasiyerlerin her biri bir hamburger hazırlanmadan önce bir sonraki siparişe geçmiiyor.
Senden önceki herkes, tezgâhtan ayrılmadan önce burgerlerinin hazırlanmasını bekliyor; çünkü 8 kasiyerin her biri bir sonraki siparişe geçmeden önce burgeri hemen gidip hazırlıyor.
Sonunda senin sıran, aşkın 😍 ve kendin için 2 hamburger 🍔 siparişi verdiniz.
<img src="/img/async/parallel-burgers/parallel-burgers-01.png" class="illustration">
Ödemeyi yaptınız 💸.
Sonunda sıra size geliyor, sen ve aşkın için 2 çok havalı burger siparişi veriyorsun.
Kasiyer mutfağa gider 👨‍🍳.
Ödüyorsun 💸.
Sırada bekliyorsunuz 🕙, kimse sizin burgerinizi 🍔 almaya çalışmıyor çünkü sıra sizin.
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration">
Sen ve aşkın 😍 sıranızı korumak ve hamburgerleri almakla o kadar meşgulsünüz ki birbirinize vakit 🕙 ayıramıyorsunuz 😞.
Kasiyer mutfağa gidiyor.
İşte bu "senkron" çalışmadır. Kasiyer/aşçı 👨🍳ile senkron hareket ediyorsunuz. Bu yüzden beklemek 🕙 ve kasiyer/aşçı burgeri 🍔bitirip size getirdiğinde orda olmak zorundasınız yoksa başka biri alabilir.
Tezgâhın önünde ayakta 🕙 bekliyorsun; sıra numarası olmadığından, burgerlerini senden önce kimsenin almaması için orada durman gerekiyor.
Sonra kasiyeri/aşçı 👨‍🍳 nihayet hamburgerlerinizle 🍔, uzun bir süre sonra 🕙 tezgaha geri geliyor.
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration">
Burgerlerinizi 🍔 al ve aşkınla masanıza doğru ilerle 😍.
Sen ve aşkın, kimsenin önünüze geçip burgerler gelince almaması için meşgul olduğunuzdan, aşkına dikkatini veremiyorsun. 😞
Sadece burgerini yiyorsun 🍔 ve bitti ⏹.
Bu "senkron" bir iştir; kasiyer/aşçı 👨‍🍳 ile "senkronize"sin. 🕙 Beklemen ve kasiyer/aşçı 👨‍🍳 burgerleri bitirip sana verdiği anda tam orada olman gerekir; yoksa bir başkası alabilir.
Bekleyerek çok fazla zaman geçtiğinden 🕙 konuşmaya çok fazla vakit kalmadı 😞.
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration">
Sonra kasiyer/aşçı 👨‍🍳, uzun süre tezgâhın önünde 🕙 bekledikten sonra nihayet burgerlerinle geri geliyor.
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration">
Burgerleri alıyor ve aşkınla masaya gidiyorsun.
Sadece yiyorsunuz ve iş bitiyor. ⏹
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration">
Vaktin çoğu tezgâhın önünde 🕙 beklemekle geçtiğinden, pek konuşma ya da flört olmadı. 😞
/// info | Bilgi
Harika çizimler: <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
///
---
Paralel burger senaryosunda ise, siz iki işlemcili birer robotsunuz 🤖 (sen ve sevgilin 😍), Beklıyorsunuz 🕙 hem konuşarak güzel vakit geçirirken ⏯ hem de sıranızı bekliyorsunuz 🕙.
Bu paralel burger senaryosunda, ikiniz (sen ve aşkın) iki işlemcili bir bilgisayar / programsınız 🤖; ikiniz de uzun süre tezgâhta "bekleme" işine 🕙 dikkat ⏯ ayırıyorsunuz.
Mağazada ise 8 işlemci bulunuyor (Kasiyer/aşçı) 👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳. Eşzamanlı burgerde yalnızca 2 kişi olabiliyordu (bir kasiyer ve bir aşçı) 💁 👨‍🍳.
Fast food dükkânında 8 işlemci var (kasiyer/aşçılar). Eşzamanlı burger dükkânında yalnızca 2 kişi olabilir (bir kasiyer ve bir aşçı).
Ama yine de bu en iyisi değil 😞.
Ama yine de nihai deneyim pek iyi değil. 😞
---
Bu hikaye burgerler 🍔 için paralel.
Bu, burgerler için paralel karşılık gelen hikâye olurdu. 🍔
Bir gerçek hayat örneği verelim. Bir banka hayal edin.
Daha "gerçek hayat" bir örnek için, bir banka hayal edin.
Bankaların çoğunda birkaç kasiyer 👨‍💼👨‍💼👨‍💼👨‍💼 ve uzun bir sıra var 🕙🕙🕙🕙🕙🕙🕙🕙.
Yakın zamana kadar, bankaların çoğunda birden çok gişe memuru 👨‍💼👨‍💼👨‍💼👨‍💼 ve uzun bir sıra 🕙🕙🕙🕙🕙🕙🕙🕙 vardı.
Tüm işi sırayla bir müşteri ile yapan tüm kasiyerler 👨‍💼⏯.
Tüm ge memurları bir müşteriyle tüm işi yapar, sonra sıradakiyle 👨‍💼⏯.
Ve uzun süre kuyrukta beklemek 🕙 zorundasın yoksa sıranı kaybedersin.
Ve sıranı kaybetmemek için uzun süre 🕙 kuyrukta beklemen gerekir.
Muhtemelen ayak işlerı yaparken sevgilini 😍 bankaya 🏦 getirmezsin.
Muhtemelen, bankada 🏦 işlerini hallederken aşkını 😍 yanında götürmek istemezsin.
### Burger Sonucu
### Burger Sonucu { #burger-conclusion }
Bu "aşkınla fast food burgerleri" senaryosunda, çok fazla bekleme olduğu için 🕙, eşzamanlı bir sisteme sahip olmak çok daha mantıklı ⏸🔀⏯.
"Fast food burgerleri ve aşkın" senaryosunda, çok fazla bekleme 🕙 olduğundan, eşzamanlı bir sistem ⏸🔀⏯ çok daha mantıklıdır.
Web uygulamalarının çoğu için durum böyledir.
Bu, çoğu web uygulaması için de geçerlidir.
Pek çok kullanıcı var, ama sunucunuz pek de iyi olmayan bir bağlantı ile istek atmalarını bekliyor.
Çok fazla kullanıcı vardır; ancak sunucunuz, iyi olmayan bağlantılarından gelen istekleri 🕙 bekler.
Ve sonra yanıtların geri gelmesi için tekrar 🕙 bekliyor
Ve sonra yanıtların geri gelmesini yine 🕙 bekler.
Bu "bekleme" 🕙 mikrosaniye cinsinden ölçülür, yine de, hepsini toplarsak çok fazla bekleme var.
Bu "beklemeler" 🕙 mikrosaniyelerle ölçülür; ama hepsi toplandığında sonuçta oldukça fazla bekleme olur.
Bu nedenle, web API'leri için asenkron ⏸🔀⏯ kod kullanmak çok daha mantıklı.
Bu yüzden web APIleri için asenkron ⏸🔀⏯ kod kullanmak çok mantıklıdır.
Mevcut popüler Python frameworklerinin çoğu (Flask ve Django gibi), Python'daki yeni asenkron özellikler mevcut olmadan önce yazıldı. Bu nedenle, dağıtılma biçimleri paralel yürütmeyi ve yenisi kadar güçlü olmayan eski bir eşzamansız yürütme biçimini destekler.
Bu tür asenkronluk, NodeJSi popüler yapan şeydir (NodeJS paralel olmasa bile) ve Go dilinin gücüdür.
Asenkron web (ASGI) özelliği, WebSockets için destek eklemek için Django'ya eklenmiş olsa da.
Ve **FastAPI** ile elde ettiğiniz performans seviyesi de budur.
Asenkron çalışabilme NodeJS in popüler olmasının sebebi (paralel olamasa bile) ve Go dilini güçlü yapan özelliktir.
Ayrıca, aynı anda hem paralellik hem de asenkronluk kullanabildiğiniz için, test edilen çoğu NodeJS frameworkünden daha yüksek ve Cye daha yakın derlenen bir dil olan Go ile başa baş performans elde edersiniz <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(hepsi Starlette sayesinde)</a>.
Ve bu **FastAPI** ile elde ettiğiniz performans düzeyiyle aynıdır.
### Eşzamanlılık paralellikten daha mı iyi? { #is-concurrency-better-than-parallelism }
Aynı anda paralellik ve asenkronluğa sahip olabildiğiniz için, test edilen NodeJS çerçevelerinin çoğundan daha yüksek performans elde edersiniz ve C'ye daha yakın derlenmiş bir dil olan Go ile eşit bir performans elde edersiniz <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(bütün teşekkürler Starlette'e )</a>.
Hayır! Hikâyenin özü bu değil.
### Eşzamanlılık paralellikten daha mı iyi?
Eşzamanlılık paralellikten farklıdır. Ve çok fazla bekleme içeren **belirli** senaryolarda daha iyidir. Bu nedenle, genellikle web uygulaması geliştirme için paralellikten çok daha iyidir. Ama her şey için değil.
Hayır! Hikayenin ahlakı bu değil.
Bunu dengelemek için, şu kısa hikâyeyi hayal edin:
Eşzamanlılık paralellikten farklıdır. Ve çok fazla bekleme içeren **belirli** senaryolarda daha iyidir. Bu nedenle, genellikle web uygulamaları için paralellikten çok daha iyidir. Ama her şey için değil.
> Büyük, kirli bir evi temizlemen gerekiyor.
Yanı, bunu aklınızda oturtmak için aşağıdaki kısa hikayeyi hayal edin:
> Büyük, kirli bir evi temizlemelisin.
*Evet, tüm hikaye bu*.
*Evet, tüm hikâye bu kadar*.
---
Beklemek yok 🕙. Hiçbir yerde. Sadece evin birden fazla yerinde yapılacak fazlasıyla iş var.
Hiçbir yerde 🕙 bekleme yok; sadece evin birden fazla yerinde yapılacak çok iş var.
You could have turns as in the burgers example, first the living room, then the kitchen, but as you are not waiting 🕙 for anything, just cleaning and cleaning, the turns wouldn't affect anything.
Hamburger örneğindeki gibi dönüşleriniz olabilir, önce oturma odası, sonra mutfak, ama hiçbir şey için 🕙 beklemediğinizden, sadece temizlik, temizlik ve temizlik, dönüşler hiçbir şeyi etkilemez.
Hamburger örneğindeki gibi dönüşlerle ilerleyebilirsin, önce salon, sonra mutfak; ama hiçbir şey 🕙 beklemediğin için, sadece temizlik yaptığından, dönüşlerin hiçbir etkisi olmaz.
Sıralı veya sırasız (eşzamanlılık) bitirmek aynı zaman alır ve aynı miktarda işi yaparsınız.
Dönüşlerle ya da dönüşsüz (eşzamanlılık) bitirmek aynı zaman alır ve aynı miktarda iş yapmış olursun.
Ama bu durumda, 8 eski kasiyer/aşçı - yeni temizlikçiyi getirebilseydiniz 👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳 ve her birini (artı siz) evin bir bölgesini temizlemek için görevlendirseydiniz, ekstra yardımla tüm işleri **paralel** olarak yapabilir ve çok daha erken bitirebilirdiniz.
Ama bu durumda, 8 eski kasiyer/aşçıyeni temizlikçiyi getirip her birine (artı sana) evin bir bölümünü versen, fazladan yardımla tüm işleri **paralel** yaparak çok daha çabuk bitirebilirdin.
Bu senaryoda, temizlikçilerin her biri (siz dahil) birer işlemci olacak ve üzerine düşeni yapacaktır.
Bu senaryoda, her bir temizlikçi (sen dâhil) birer işlemci olur ve kendi iş payını yapar.
Yürütme süresinin çoğu (beklemek yerine) iş yapıldığından ve bilgisayardaki iş bir <abbr title="Central Processing Unit">CPU</abbr> tarafından yapıldığından, bu sorunlara "CPU bound" diyorlar".
Ve yürütme süresinin çoğu gerçek işten (bekleme yerine) oluştuğu ve bilgisayardaki işi bir <abbr title="Central Processing Unit - Merkezi İşlem Birimi">CPU</abbr> yaptığı için, bu sorunlara "CPU bound" denir.
---
CPU'ya bağlı işlemlerin yaygın örnekleri, karmaşık matematik işlemleri gerektiren işlerdir.
CPUya bağlı işlemlerin yaygın örnekleri, karmaşık matematiksel işlem gerektiren iş yükleridir.
Örneğin:
* **Ses** veya **görüntü işleme**.
* **Bilgisayar görüsü**: bir görüntü milyonlarca pikselden oluşur, her pikselin 3 değeri / rengi vardır, bu pikseller üzerinde aynı anda bir şeyler hesaplamayı gerektiren işleme.
* **Makine Öğrenimi**: Çok sayıda "matris" ve "vektör" çarpımı gerektirir. Sayıları olan ve hepsini aynı anda çarpan büyük bir elektronik tablo düşünün.
* **Derin Öğrenme**: Bu, Makine Öğreniminin bir alt alanıdır, dolayısıyla aynısı geçerlidir. Sadece çarpılacak tek bir sayı tablosu değil, büyük bir sayı kümesi vardır ve çoğu durumda bu modelleri oluşturmak ve/veya kullanmak için özel işlemciler kullanırsınız.
* **Bilgisayar görüsü**: bir görüntü milyonlarca pikselden oluşur, her pikselin 3 değeri / rengi vardır; işleme genellikle bu pikseller üzerinde aynı anda bir şeyler hesaplamayı gerektirir.
* **Makine Öğrenimi**: genellikle çok sayıda "matris" ve "vektör" çarpımı gerekir. Sayılar içeren devasa bir elektronik tabloyu ve hepsini aynı anda çarpmayı düşünün.
* **Derin Öğrenme**: Makine Öğreniminin bir alt alanıdır, dolayısıyla aynısı geçerlidir. Sadece çarpılacak tek bir sayı tablosu değil, kocaman bir sayı kümesi vardır ve çoğu durumda bu modelleri kurmak ve/veya kullanmak için özel işlemciler kullanırsınız.
### Eşzamanlılık + Paralellik: Web + Makine Öğrenimi
### Eşzamanlılık + Paralellik: Web + Makine Öğrenimi { #concurrency-parallelism-web-machine-learning }
**FastAPI** ile web geliştirme için çok yaygın olan eşzamanlılıktan yararlanabilirsiniz (NodeJS'in aynı çekiciliği).
**FastAPI** ile web geliştirmede çok yaygın olan eşzamanlılıktan (NodeJSin başlıca cazibesiyle aynı) yararlanabilirsiniz.
Ancak, Makine Öğrenimi sistemlerindekile gibi **CPU'ya bağlı** iş yükleri için paralellik ve çoklu işlemenin (birden çok işlemin paralel olarak çalışması) avantajlarından da yararlanabilirsiniz.
Ama ayrıca **CPUya bağlı** iş yükleri (Makine Öğrenimi sistemlerindeki gibi) için paralellik ve çoklu işlemden (paralel çalışan birden çok işlem) de yararlanabilirsiniz.
Buna ek olarak Python'un **Veri Bilimi**, Makine Öğrenimi ve özellikle Derin Öğrenme için ana dil olduğu gerçeği, FastAPI'yi Veri Bilimi / Makine Öğrenimi web API'leri ve uygulamaları için çok iyi bir seçenek haline getirir.
Buna ek olarak Pythonun **Veri Bilimi**, Makine Öğrenimi ve özellikle Derin Öğrenme için ana dil olması, FastAPIyi Veri Bilimi / Makine Öğrenimi web APIleri ve uygulamaları için çok iyi bir seçenek yapar.
Production'da nasıl oldugunu görmek için şu bölüme bakın [Deployment](deployment/index.md){.internal-link target=_blank}.
Productionda bu paralelliği nasıl sağlayacağınızı görmek için [Deployment](deployment/index.md){.internal-link target=_blank} bölümüne bakın.
## `async` ve `await`
## `async` ve `await` { #async-and-await }
Python'un modern sürümleri, asenkron kodu tanımlamanın çok sezgisel bir yoluna sahiptir. Bu, normal "sequentıal" (sıralı) kod gibi görünmesini ve doğru anlarda sizin için "awaıt" ile bekleme yapmasını sağlar.
Pythonun modern sürümleri, asenkron kodu tanımlamak için oldukça sezgisel bir yol sunar. Bu sayede kod normal "sıralı" kod gibi görünür ve doğru anlarda sizin yerinize "beklemeyi" yapar.
Sonuçları vermeden önce beklemeyi gerektirecek ve yeni Python özelliklerini destekleyen bir işlem olduğunda aşağıdaki gibi kodlayabilirsiniz:
Sonuçları vermeden önce bekleme gerektiren ve bu yeni Python özelliklerini destekleyen bir işlem olduğunda, şöyle kodlayabilirsiniz:
```Python
burgers = await get_burgers(2)
```
Buradaki `await` anahtari Python'a, sonuçları `burgers` degiskenine atamadan önce `get_burgers(2)` kodunun işini bitirmesini 🕙 beklemesi gerektiğini söyler. Bununla Python, bu ara zamanda başka bir şey 🔀 ⏯ yapabileceğini bilecektir (başka bir istek almak gibi).
Buradaki kilit nokta `await`. Pythona, sonuçları `burgers` değişkenine koymadan önce `get_burgers(2)` çalışmasının bitmesini 🕙 beklemesi gerektiğini söyler. Böylece Python, bu arada başka bir şey 🔀 ⏯ yapabileceğini bilir (ör. başka bir request almak gibi).
`await`kodunun çalışması için, eşzamansızlığı destekleyen bir fonksiyonun içinde olması gerekir. Bunu da yapmak için fonksiyonu `async def` ile tanımlamamız yeterlidir:
`await`in çalışabilmesi için, bu asenkronluğu destekleyen bir fonksiyonun içinde olması gerekir. Bunu yapmak için fonksiyonu `async def` ile tanımlayın:
```Python hl_lines="1"
async def get_burgers(number: int):
# burgerleri oluşturmak için asenkron birkaç iş
# Burgerleri yaratmak için bazı asenkron işler yap
return burgers
```
...`def` yerine:
```Python hl_lines="2"
# bu kod asenkron değil
# Bu asenkron değildir
def get_sequential_burgers(number: int):
# burgerleri oluşturmak için senkron bırkaç iş
# Burgerleri yaratmak için bazı sıralı işler yap
return burgers
```
`async def` ile Python, bu fonksıyonun içinde, `await` ifadelerinin farkında olması gerektiğini ve çalışma zamanı gelmeden önce bu işlevin yürütülmesini "duraklatabileceğini" ve başka bir şey yapabileceğini 🔀 bilir.
`async def` ile Python, bu fonksiyonun içinde `await` ifadelerinin olabileceğini bilir ve bu fonksiyonun yürütülmesini "duraklatıp" ⏸ başka bir şey yapabileceğini 🔀, sonra geri dönebileceğini anlar.
`async def` fonksiyonunu çağırmak istediğinizde, onu "awaıt" ıle kullanmanız gerekir. Yani, bu işe yaramaz:
`async def` fonksiyonunu çağırmak istediğinizde, onu "await" etmeniz gerekir. Yani şu çalışmaz:
```Python
# Bu işe yaramaz, çünkü get_burgers, şu şekilde tanımlandı: async def
# Bu çalışmaz, çünkü get_burgers şöyle tanımlandı: async def
burgers = get_burgers(2)
```
---
Bu nedenle, size onu `await` ile çağırabileceğinizi söyleyen bir kitaplık kullanıyorsanız, onu `async def` ile tanımlanan *path fonksiyonu* içerisinde kullanmanız gerekir, örneğin:
Dolayısıyla, `await` ile çağrılabileceğini söyleyen bir kütüphane kullanıyorsanız, onu kullanan *path operasyon fonksiyonunu* `async def` ile oluşturmanız gerekir, örneğin:
```Python hl_lines="2-3"
@app.get('/burgers')
@@ -321,87 +349,96 @@ async def read_burgers():
return burgers
```
### Daha fazla teknik detay
### Daha teknik detaylar { #more-technical-details }
`await` in yalnızca `async def` ile tanımlanan fonksıyonların içinde kullanılabileceğini fark etmişsinizdir.
`await`in yalnızca `async def` ile tanımlanan fonksiyonların içinde kullanılabildiğini fark etmiş olabilirsiniz.
Ama aynı zamanda, `async def` ile tanımlanan fonksiyonların "await" ile beklenmesi gerekir. Bu nedenle, "`async def` içeren fonksiyonlar yalnızca "`async def` ile tanımlanan fonksiyonların içinde çağrılabilir.
Aynı zamanda, `async def` ile tanımlanan fonksiyonların da "await" edilmesi gerekir. Yani `async def` ile tanımlanan fonksiyonlar yalnızca `async def` ile tanımlanan fonksiyonların içinde çağrılabilir.
Peki, tavuk-yumurta meselesi: ilk `async` fonksiyon nasıl çağrılır?
Yani yumurta mı tavukdan, tavuk mu yumurtadan gibi ilk `async` fonksiyonu nasıl çağırılır?
**FastAPI** ile çalışıyorsanız bunu dert etmenize gerek yok; çünkü o "ilk" fonksiyon sizin *path operasyon fonksiyonunuz* olacaktır ve FastAPI doğru olanı yapmasını bilir.
**FastAPI** ile çalışıyorsanız bunun için endişelenmenize gerek yok, çünkü bu "ilk" fonksiyon sizin *path fonksiyonunuz* olacak ve FastAPI doğru olanı nasıl yapacağını bilecek.
Ama FastAPI olmadan da `async` / `await` kullanmak isterseniz, bunu da yapabilirsiniz.
Ancak FastAPI olmadan `async` / `await` kullanmak istiyorsanız, <a href="https://docs.python.org/3/library/asyncio-task.html#coroutine" class="external-link" target="_blank">resmi Python belgelerini kontrol edin</a>.
### Kendi async kodunuzu yazın { #write-your-own-async-code }
### Asenkron kodun diğer biçimleri
Starlette (ve **FastAPI**) <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> üzerine kuruludur; bu sayede Python standart kütüphanesindeki <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> ve <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a> ile uyumludur.
Bu `async` ve `await` kullanimi oldukça yenidir.
Özellikle, kendi kodunuzda daha gelişmiş desenler gerektiren ileri seviye eşzamanlılık kullanım senaryoları için doğrudan <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> kullanabilirsiniz.
Ancak asenkron kodla çalışmayı çok daha kolay hale getirir.
Hatta FastAPI kullanmıyor olsanız bile, yüksek uyumluluk ve avantajları (ör. *structured concurrency*) için <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> ile kendi async uygulamalarınızı yazabilirsiniz.
Aynı sözdizimi (hemen hemen aynı) son zamanlarda JavaScript'in modern sürümlerine de dahil edildi (Tarayıcı ve NodeJS'de).
AnyIOnun üzerine, tür açıklamalarını biraz iyileştirmek ve daha iyi **otomatik tamamlama**, **satır içi hatalar** vb. elde etmek için ince bir katman olarak başka bir kütüphane daha oluşturdum. Ayrıca **kendi async kodunuzu** anlamanıza ve yazmanıza yardımcı olacak dostça bir giriş ve eğitim içerir: <a href="https://asyncer.tiangolo.com/" class="external-link" target="_blank">Asyncer</a>. Özellikle **async kodu normal** (bloklayan/senkron) **kodla birleştirmeniz** gerektiğinde faydalı olacaktır.
Ancak bundan önce, asenkron kodu işlemek oldukça karmaşık ve zordu.
### Asenkron kodun diğer biçimleri { #other-forms-of-asynchronous-code }
Python'un önceki sürümlerinde, threadlerı veya <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a> kullanıyor olabilirdin. Ancak kodu anlamak, hata ayıklamak ve düşünmek çok daha karmaşık olurdu.
`async` ve `await` kullanma tarzı, dilde nispeten yenidir.
NodeJS / Browser JavaScript'in önceki sürümlerinde, "callback" kullanırdınız. Bu da "callbacks cehennemine" yol açar.
Ama asenkron kodla çalışmayı çok daha kolaylaştırır.
## Coroutine'ler
Aynı (ya da neredeyse aynı) sözdizimi yakın zamanda modern JavaScript sürümlerine (Tarayıcı ve NodeJS) de eklendi.
**Coroutine**, bir `async def` fonksiyonu tarafından döndürülen değer için çok süslü bir terimdir. Python bunun bir fonksiyon gibi bir noktada başlayıp biteceğini bilir, ancak içinde bir `await` olduğunda dahili olarak da duraklatılabilir ⏸.
Bundan önce, asenkron kodu ele almak oldukça daha karmaşık ve zordu.
Ancak, `async` ve `await` ile asenkron kod kullanmanın tüm bu işlevselliği, çoğu zaman "Coroutine" kullanmak olarak adlandırılır. Go'nun ana özelliği olan "Goroutines" ile karşılaştırılabilir.
Pythonun önceki sürümlerinde threadler veya <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a> kullanabilirdiniz. Ama kodu anlamak, hata ayıklamak ve üzerine düşünmek çok daha zordu.
## Sonuç
NodeJS / Tarayıcı JavaScriptin önceki sürümlerinde "callback" kullanırdınız. Bu da "callback cehennemi"ne yol açardı.
Aynı ifadeyi yukarıdan görelim:
## Coroutine'ler { #coroutines }
> Python'ın modern sürümleri, **"async" ve "await"** sözdizimi ile birlikte **"coroutines"** adlı bir özelliği kullanan **"asenkron kod"** desteğine sahiptir.
**Coroutine**, bir `async def` fonksiyonunun döndürdüğü şeye verilen süslü isimdir. Python bunun bir fonksiyona benzer bir şey olduğunu, bir noktada başlayıp biteceğini bilir; ama içinde bir `await` olduğunda dahili olarak duraklatılabileceğini ⏸ de bilir.
Şimdi daha mantıklı gelmeli. ✨
`async` ve `await` ile asenkron kod kullanmanın bu işlevselliği çoğu zaman "coroutine" kullanmak olarak özetlenir. Gonun ana kilit özelliği olan "Goroutines" ile karşılaştırılabilir.
FastAPI'ye (Starlette aracılığıyla) güç veren ve bu kadar etkileyici bir performansa sahip olmasını sağlayan şey budur.
## Sonuç { #conclusion }
## Çok Teknik Detaylar
Yukarıdaki cümleyi tekrar görelim:
/// warning
> Pythonun modern sürümleri, **`async` ve `await`** sözdizimiyle, **"coroutines"** denilen bir yapıyı kullanarak **"asenkron kod"** desteğine sahiptir.
Muhtemelen burayı atlayabilirsiniz.
Artık daha anlamlı gelmeli. ✨
Bunlar, **FastAPI**'nin altta nasıl çalıştığına dair çok teknik ayrıntılardır.
Bunların hepsi, FastAPIye (Starlette aracılığıyla) güç verir ve böylesine etkileyici bir performansa sahip olmasını sağlar.
Biraz teknik bilginiz varsa (co-routines, threads, blocking, vb)ve FastAPI'nin "async def" ile normal "def" arasındaki farkı nasıl işlediğini merak ediyorsanız, devam edin.
## Çok Teknik Detaylar { #very-technical-details }
/// warning | Uyarı
Büyük ihtimalle burayı atlayabilirsiniz.
Bunlar, **FastAPI**nin altında nasıl çalıştığına dair oldukça teknik ayrıntılardır.
Coroutineler, threadler, blocking vb. hakkında teknik bilginiz varsa ve FastAPInin `async def` ile normal `def` arasındaki farkı nasıl ele aldığını merak ediyorsanız, devam edin.
///
### Path fonksiyonu
### Path Operasyon Fonksiyonları { #path-operation-functions }
"async def" yerine normal "def" ile bir *yol işlem işlevi* bildirdiğinizde, doğrudan çağrılmak yerine (sunucuyu bloke edeceğinden) daha sonra beklenen harici bir iş parçacığı havuzunda çalıştırılır.
Bir *path operasyon fonksiyonunu* `async def` yerine normal `def` ile tanımladığınızda, (sunucuyu bloklayacağından) doğrudan çağrılmak yerine, harici bir thread poolda çalıştırılır ve ardından beklenir.
Yukarıda açıklanan şekilde çalışmayan başka bir asenkron framework'den geliyorsanız ve küçük bir performans kazancı (yaklaşık 100 nanosaniye) için "def" ile *path fonksiyonu* tanımlamaya alışkınsanız, **FastAPI**'de tam tersi olacağını unutmayın. Bu durumlarda, *path fonksiyonu* <abbr title="Input/Output: disk okuma veya yazma, ağ iletişimleri.">G/Ç</abbr> engelleyen durum oluşturmadıkça "async def" kullanmak daha iyidir.
Yukarıda açıklanan şekilde çalışmayan başka bir async frameworkten geliyorsanız ve ufak bir performans kazancı (yaklaşık 100 nanosaniye) için yalnızca hesaplama yapan basit *path operasyon fonksiyonlarını* düz `def` ile tanımlamaya alışkınsanız, **FastAPI**de etkinin tam tersi olacağını unutmayın. Bu durumlarda, *path operasyon fonksiyonlarınız* bloklayan <abbr title="Input/Output - Giriş/Çıkış: disk okuma veya yazma, ağ iletişimi.">I/O</abbr> yapan kod kullanmadıkça `async def` kullanmak daha iyidir.
Yine de, her iki durumda da, **FastAPI**'nin önceki frameworkden [hala daha hızlı](index.md#performans){.internal-link target=_blank} (veya en azından karşılaştırılabilir) olma olasılığı vardır.
Yine de her iki durumda da, **FastAPI**nin önceki frameworkünüzden [hala daha hızlı](index.md#performance){.internal-link target=_blank} (ya da en azından karşılaştırılabilir) olması muhtemeldir.
### Bagımlılıklar
### Bağımlılıklar { #dependencies }
Aynısı bağımlılıklar için de geçerlidir. Bir bağımlılık, "async def" yerine standart bir "def" işleviyse, harici iş parçacığı havuzunda çalıştırılır.
Aynısı [bağımlılıklar](tutorial/dependencies/index.md){.internal-link target=_blank} için de geçerlidir. Bir bağımlılık `async def` yerine standart bir `def` fonksiyonuysa, harici thread poolda çalıştırılır.
### Alt-bağımlıklar
### Alt-bağımlılıklar { #sub-dependencies }
Birbirini gerektiren (fonksiyonlarin parametreleri olarak) birden fazla bağımlılık ve alt bağımlılıklarınız olabilir, bazıları 'async def' ve bazıları normal 'def' ile oluşturulabilir. Yine de normal 'def' ile oluşturulanlar, "await" kulanilmadan harici bir iş parçacığında (iş parçacığı havuzundan) çağrılır.
Birbirini gerektiren birden çok bağımlılık ve [alt-bağımlılık](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} olabilir (fonksiyon tanımlarının parametreleri olarak). Bazıları `async def` ile, bazıları normal `def` ile oluşturulmuş olabilir. Yine de çalışır ve normal `def` ile oluşturulanlar "await" edilmek yerine harici bir threadde (thread pooldan) çağrılır.
### Diğer yardımcı fonksiyonlar
### Diğer yardımcı fonksiyonlar { #other-utility-functions }
Doğrudan çağırdığınız diğer herhangi bir yardımcı fonksiyonu, normal "def" veya "async def" ile tanimlayabilirsiniz. FastAPI onu çağırma şeklinizi etkilemez.
Doğrudan çağırdığınız diğer yardımcı fonksiyonları normal `def` veya `async def` ile tanımlayabilirsiniz ve FastAPI onları çağırma biçiminizi etkilemez.
Bu, FastAPI'nin sizin için çağırdığı fonksiyonlarin tam tersidir: *path fonksiyonu* ve bağımlılıklar.
Bu, FastAPInin sizin için çağırdığı fonksiyonların tersidir: *path operasyon fonksiyonları* ve bağımlılıklar.
Yardımcı program fonksiyonunuz 'def' ile normal bir işlevse, bir iş parçacığı havuzunda değil doğrudan (kodunuzda yazdığınız gibi) çağrılır, işlev 'async def' ile oluşturulmuşsa çağırıldığı yerde 'await' ile beklemelisiniz.
Yardımcı fonksiyonunuz `def` ile tanımlı normal bir fonksiyonsa, bir thread poolda değil doğrudan (kodunuzda yazdığınız gibi) çağrılır; fonksiyon `async def` ile tanımlıysa kodunuzda çağırırken onu `await` etmelisiniz.
---
Yeniden, bunlar, onları aramaya geldiğinizde muhtemelen işinize yarayacak çok teknik ayrıntılardır.
Yine, bunlar muhtemelen özellikle aradığınızda işinize yarayacak çok teknik ayrıntılardır.
Aksi takdirde, yukarıdaki bölümdeki yönergeleri iyi bilmelisiniz: <a href="#in-a-hurry">Aceleniz mi var?</a>.
Aksi hâlde, yukarıdaki bölümdeki yönergeler yeterlidir: <a href="#in-a-hurry">Aceleniz mi var?</a>.

View File

@@ -13,7 +13,7 @@ Bir **FastAPI** uygulamasını (hatta genel olarak herhangi bir web API'yi) depl
Bunların **deployment**'ları nasıl etkilediğine bakalım.
Nihai hedef, **API client**'larınıza **güvenli** bir şekilde hizmet verebilmek, **kesintileri** önlemek ve **hesaplama kaynaklarını** (ör. uzak server'lar/sanal makineler) olabildiğince verimli kullanmaktır.
Nihai hedef, **API client**'larınıza **güvenli** bir şekilde hizmet verebilmek, **kesintileri** önlemek ve **hesaplama kaynaklarını** (ör. uzak server'lar/sanal makineler) olabildiğince verimli kullanmaktır. 🚀
Burada bu **kavramlar** hakkında biraz daha bilgi vereceğim. Böylece, çok farklı ortamlarda—hatta bugün var olmayan **gelecekteki** ortamlarda bile—API'nizi nasıl deploy edeceğinize karar verirken ihtiyaç duyacağınız **sezgiyi** kazanmış olursunuz.
@@ -21,7 +21,7 @@ Bu kavramları dikkate alarak, **kendi API**'leriniz için en iyi deployment yak
Sonraki bölümlerde, FastAPI uygulamalarını deploy etmek için daha **somut tarifler** (recipes) paylaşacağım.
Ama şimdilik, bu önemli **kavramsal fikirleri** inceleyelim. Bu kavramlar diğer tüm web API türleri için de geçerlidir.
Ama şimdilik, bu önemli **kavramsal fikirleri** inceleyelim. Bu kavramlar diğer tüm web API türleri için de geçerlidir. 💡
## Güvenlik - HTTPS { #security-https }
@@ -36,16 +36,16 @@ Ve **HTTPS sertifikalarını yenilemekten** sorumlu bir şey olmalıdır; bu ayn
TLS Termination Proxy olarak kullanabileceğiniz bazı araçlar:
* Traefik
* Sertifika yenilemelerini otomatik yönetir
* Sertifika yenilemelerini otomatik yönetir
* Caddy
* Sertifika yenilemelerini otomatik yönetir
* Sertifika yenilemelerini otomatik yönetir
* Nginx
* Sertifika yenilemeleri için Certbot gibi harici bir bileşenle
* HAProxy
* Sertifika yenilemeleri için Certbot gibi harici bir bileşenle
* Nginx gibi bir Ingress Controller ile Kubernetes
* Sertifika yenilemeleri için cert-manager gibi harici bir bileşenle
* Bir cloud provider tarafından servislerinin parçası olarak içeride yönetilmesi (aşağıyı okuyun)
* Bir cloud provider tarafından servislerinin parçası olarak içeride yönetilmesi (aşağıyı okuyun 👇)
Bir diğer seçenek de, HTTPS kurulumunu da dahil olmak üzere işin daha büyük kısmını yapan bir **cloud service** kullanmaktır. Bunun bazı kısıtları olabilir veya daha pahalı olabilir vb. Ancak bu durumda TLS Termination Proxy'yi kendiniz kurmak zorunda kalmazsınız.
@@ -100,7 +100,7 @@ Bu yöntem çalışır ve **geliştirme sırasında** faydalıdır.
Ancak server'a olan bağlantınız koparsa, **çalışan process** muhtemelen ölür.
Ve server yeniden başlatılırsa (örneğin update'lerden sonra ya da cloud provider'ın migration'larından sonra) bunu muhtemelen **fark etmezsiniz**. Dolayısıyla process'i manuel yeniden başlatmanız gerektiğini de bilmezsiniz. Sonuçta API'niz ölü kalır.
Ve server yeniden başlatılırsa (örneğin update'lerden sonra ya da cloud provider'ın migration'larından sonra) bunu muhtemelen **fark etmezsiniz**. Dolayısıyla process'i manuel yeniden başlatmanız gerektiğini de bilmezsiniz. Sonuçta API'niz ölü kalır. 😱
### Startup'ta Otomatik Çalıştırma { #run-automatically-on-startup }
@@ -131,19 +131,19 @@ Uygulamanızın startup'ta çalıştığından emin olmaya benzer şekilde, hata
### Hata Yaparız { #we-make-mistakes }
Biz insanlar sürekli **hata** yaparız. Yazılımın neredeyse *her zaman* farklı yerlerinde gizli **bug**'lar vardır.
Biz insanlar sürekli **hata** yaparız. Yazılımın neredeyse *her zaman* farklı yerlerinde gizli **bug**'lar vardır. 🐛
Ve biz geliştiriciler bu bug'ları buldukça ve yeni özellikler ekledikçe code'u iyileştiririz (muhtemelen yeni bug'lar da ekleyerek).
Ve biz geliştiriciler bu bug'ları buldukça ve yeni özellikler ekledikçe code'u iyileştiririz (muhtemelen yeni bug'lar da ekleyerek 😅).
### Küçük Hatalar Otomatik Yönetilir { #small-errors-automatically-handled }
FastAPI ile web API geliştirirken, code'umuzda bir hata olursa FastAPI genellikle bunu hatayı tetikleyen tek request ile sınırlar.
FastAPI ile web API geliştirirken, code'umuzda bir hata olursa FastAPI genellikle bunu hatayı tetikleyen tek request ile sınırlar. 🛡
Client o request için **500 Internal Server Error** alır; ancak uygulama tamamen çöküp durmak yerine sonraki request'ler için çalışmaya devam eder.
### Daha Büyük Hatalar - Çökmeler { #bigger-errors-crashes }
Yine de bazı durumlarda, yazdığımız bir code **tüm uygulamayı çökertip** Uvicorn ve Python'ın crash olmasına neden olabilir.
Yine de bazı durumlarda, yazdığımız bir code **tüm uygulamayı çökertip** Uvicorn ve Python'ın crash olmasına neden olabilir. 💥
Böyle bir durumda, tek bir noktadaki hata yüzünden uygulamanın ölü kalmasını istemezsiniz; bozuk olmayan *path operations* en azından çalışmaya devam etsin istersiniz.
@@ -206,7 +206,7 @@ Ve birden fazla process normalde **belleği paylaşmaz**. Yani her çalışan pr
Örneğin code'unuz **1 GB** boyutunda bir Machine Learning modelini yüklüyorsa, API'niz tek process ile çalışırken en az 1 GB RAM tüketir. **4 process** (4 worker) başlatırsanız her biri 1 GB RAM tüketir. Yani toplamda API'niz **4 GB RAM** tüketir.
Uzak server'ınız veya sanal makineniz yalnızca 3 GB RAM'e sahipse, 4 GB'tan fazla RAM yüklemeye çalışmak sorun çıkarır.
Uzak server'ınız veya sanal makineniz yalnızca 3 GB RAM'e sahipse, 4 GB'tan fazla RAM yüklemeye çalışmak sorun çıkarır. 🚨
### Birden Fazla Process - Bir Örnek { #multiple-processes-an-example }
@@ -265,7 +265,7 @@ Elbette bazı durumlarda ön adımları birden fazla kez çalıştırmak sorun d
Ayrıca, kurulumunuza bağlı olarak bazı durumlarda uygulamanızı başlatmadan önce **hiç ön adıma ihtiyaç duymayabilirsiniz**.
Bu durumda bunların hiçbirini düşünmeniz gerekmez.
Bu durumda bunların hiçbirini düşünmeniz gerekmez. 🤷
///
@@ -291,7 +291,7 @@ Server(lar)ınız bir **kaynaktır**. Programlarınızla CPU'lardaki hesaplama z
Sistem kaynaklarının ne kadarını tüketmek/kullanmak istersiniz? "Az" demek kolaydır; ancak pratikte hedef genellikle **çökmeden mümkün olduğunca fazla** kullanmaktır.
3 server için para ödüyor ama onların RAM ve CPU'sunun yalnızca küçük bir kısmını kullanıyorsanız, muhtemelen **para israf ediyorsunuz** ve muhtemelen **elektrik tüketimini** de gereksiz yere artırıyorsunuz vb.
3 server için para ödüyor ama onların RAM ve CPU'sunun yalnızca küçük bir kısmını kullanıyorsanız, muhtemelen **para israf ediyorsunuz** 💸 ve muhtemelen **elektrik tüketimini** de gereksiz yere artırıyorsunuz 🌎 vb.
Bu durumda 2 server ile devam edip onların kaynaklarını (CPU, bellek, disk, ağ bant genişliği vb.) daha yüksek oranlarda kullanmak daha iyi olabilir.
@@ -316,6 +316,6 @@ Uygulamanızı nasıl deploy edeceğinize karar verirken aklınızda tutmanız g
* Bellek
* Başlatmadan önceki adımlar
Bu fikirleri ve nasıl uygulayacağınızı anlamak, deployment'larınızı yapılandırırken ve ince ayar yaparken ihtiyaç duyacağınız sezgiyi kazanmanızı sağlamalıdır.
Bu fikirleri ve nasıl uygulayacağınızı anlamak, deployment'larınızı yapılandırırken ve ince ayar yaparken ihtiyaç duyacağınız sezgiyi kazanmanızı sağlamalıdır. 🤓
Sonraki bölümlerde, izleyebileceğiniz stratejilere dair daha somut örnekler paylaşacağım.
Sonraki bölümlerde, izleyebileceğiniz stratejilere dair daha somut örnekler paylaşacağım. 🚀

View File

@@ -14,7 +14,7 @@ Aceleniz var ve bunları zaten biliyor musunuz? Aşağıdaki [`Dockerfile`'a atl
<summary>Dockerfile Önizleme 👀</summary>
```Dockerfile
FROM python:3.9
FROM python:3.14
WORKDIR /code
@@ -166,7 +166,7 @@ def read_item(item_id: int, q: str | None = None):
```{ .dockerfile .annotate }
# (1)!
FROM python:3.9
FROM python:3.14
# (2)!
WORKDIR /code
@@ -390,7 +390,7 @@ FastAPI uygulamanız tek bir dosyaysa; örneğin `./app` dizini olmadan sadece `
Bu durumda `Dockerfile` içinde dosyayı kopyaladığınız path'leri buna göre değiştirmeniz yeterlidir:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.9
FROM python:3.14
WORKDIR /code
@@ -454,7 +454,7 @@ Container kullanmadan, uygulamaları startup'ta çalıştırmak ve restart mekan
## Replication - Process Sayısı { #replication-number-of-processes }
Kubernetes, Docker Swarm Mode, Nomad veya benzeri, birden fazla makinede dağıtık container'ları yöneten karmaşık bir sistemle kurulmuş bir <abbr title="Bir şekilde birbirine bağlanacak ve birlikte çalışacak şekilde yapılandırılmış makineler grubu.">cluster</abbr>'ınız varsa, replication'ı her container içinde bir **process manager** (ör. worker'lı Uvicorn) kullanarak yönetmek yerine, muhtemelen **cluster seviyesinde** ele almak istersiniz.
Eğer bir <dfn title="Bir şekilde birbirine bağlanacak ve birlikte çalışacak şekilde yapılandırılmış makineler grubu.">küme</dfn> (cluster) olarak yapılandırılmış makineler grubunuz varsa ve bunları **Kubernetes**, Docker Swarm Mode, Nomad veya benzeri, birden çok makinede dağıtık container'ları yöneten karmaşık bir sistemle yönetiyorsanız, replication'ı her container içinde bir **process manager** (ör. worker'lı Uvicorn) kullanarak yönetmek yerine, muhtemelen **küme seviyesinde (cluster level)** ele almak istersiniz.
Kubernetes gibi dağıtık container yönetim sistemleri, gelen request'ler için **load balancing** desteği sunarken aynı zamanda **container replication**'ını yönetmek için entegre mekanizmalara sahiptir. Hepsi **cluster seviyesinde**.
@@ -499,7 +499,7 @@ Elbette bazı **özel durumlarda** bir container içinde birden fazla **Uvicorn
Bu durumlarda çalıştırmak istediğiniz worker sayısını `--workers` komut satırı seçeneğiyle ayarlayabilirsiniz:
```{ .dockerfile .annotate }
FROM python:3.9
FROM python:3.14
WORKDIR /code

View File

@@ -65,7 +65,7 @@ Burada, bir HTTPS APInin adım adım nasıl görünebileceğine dair, özelli
Muhtemelen her şey, bir **domain adı** **temin etmenizle** başlar. Sonra bunu bir DNS serverında (muhtemelen aynı cloud providerınızda) yapılandırırsınız.
Muhtemelen bir cloud server (virtual machine) ya da benzeri bir şey alırsınız ve bunun <abbr title="That doesn't change - Bu değişmez">fixed</abbr> bir **public IP adresi** olur.
Muhtemelen bir cloud server (virtual machine) ya da benzeri bir şey alırsınız ve bunun <dfn title="Zamanla değişmeyen. Dinamik olmayan.">sabit</dfn> bir **public IP adresi** olur.
DNS server(lar)ında, bir kaydı ("`A record`") **domain**inizi serverınızın **public IP adresine** yönlendirecek şekilde yapılandırırsınız.

View File

@@ -1,8 +1,8 @@
# Deployment { #deployment }
# Dıtım { #deployment }
**FastAPI** uygulamasını deploy etmek nispeten kolaydır.
## Deployment Ne Anlama Gelir? { #what-does-deployment-mean }
## Dıtım Ne Anlama Gelir? { #what-does-deployment-mean }
Bir uygulamayı **deploy** etmek, onu **kullanıcılara erişilebilir hale getirmek** için gerekli adımları gerçekleştirmek anlamına gelir.
@@ -10,7 +10,7 @@ Bir **web API** için bu süreç normalde uygulamayı **uzak bir makineye** yerl
Bu, kodu sürekli olarak değiştirdiğiniz, bozup düzelttiğiniz, geliştirme sunucusunu durdurup yeniden başlattığınız vb. **geliştirme** aşamalarının tam tersidir.
## Deployment Stratejileri { #deployment-strategies }
## Dıtım Stratejileri { #deployment-strategies }
Kullanım durumunuza ve kullandığınız araçlara bağlı olarak bunu yapmanın birkaç yolu vardır.

View File

@@ -46,7 +46,7 @@ Bu, çoğu durumda işinizi görür. 😎
Şimdi biraz daha detaya inelim.
FastAPI, Python web framework'leri ve sunucularını inşa etmek için kullanılan <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr> adlı bir standardı kullanır. FastAPI bir ASGI web framework'üdür.
FastAPI, Python web framework'leri ve sunucularını inşa etmek için kullanılan <abbr title="Asynchronous Server Gateway Interface - Asenkron Sunucu Ağ Geçidi Arayüzü">ASGI</abbr> adlı bir standardı kullanır. FastAPI bir ASGI web framework'üdür.
Uzak bir sunucu makinesinde **FastAPI** uygulamasını (veya herhangi bir ASGI uygulamasını) çalıştırmak için gereken ana şey, **Uvicorn** gibi bir ASGI server programıdır. `fastapi` komutuyla varsayılan olarak gelen de budur.
@@ -74,7 +74,7 @@ FastAPI'yi kurduğunuzda, production sunucusu olarak Uvicorn da beraberinde geli
Ancak bir ASGI server'ı manuel olarak da kurabilirsiniz.
Bir [virtual environment](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan, etkinleştirdiğinizden emin olun; ardından server uygulamasını kurabilirsiniz.
Bir [sanal ortam](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan, etkinleştirdiğinizden emin olun; ardından server uygulamasını kurabilirsiniz.
Örneğin Uvicorn'u kurmak için:

View File

@@ -153,7 +153,7 @@ Hello World from Python
/// tip | İpucu
Bu konuyla ilgili daha fazlasını <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a> bölümünde okuyabilirsiniz.
Bu konuyla ilgili daha fazlasını <a href="https://12factor.net/config" class="external-link" target="_blank">Twelve-Factor Uygulaması: Config</a> bölümünde okuyabilirsiniz.
///
@@ -291,7 +291,7 @@ Bu bilgiler, [Virtual Environments](virtual-environments.md){.internal-link targ
Buraya kadar **ortam değişkenleri**nin ne olduğuna ve Pythonda nasıl kullanılacağına dair temel bir fikir edinmiş olmalısınız.
Ayrıca <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a> sayfasından daha fazlasını da okuyabilirsiniz.
Ayrıca <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Ortam Değişkeni için Wikipedia</a> sayfasından daha fazlasını da okuyabilirsiniz.
Çoğu zaman ortam değişkenlerinin hemen nasıl işe yarayacağı ilk bakışta çok net olmayabilir. Ancak geliştirme yaparken birçok farklı senaryoda tekrar tekrar karşınıza çıkarlar; bu yüzden bunları bilmek faydalıdır.

View File

@@ -1,59 +1,55 @@
# Özelikler
# Özellikler { #features }
## FastAPI özellikleri
## FastAPI Özellikleri { #fastapi-features }
**FastAPI** sana bunları sağlıyor
**FastAPI** size şunları sağlar:
### Açık standartları temel alır
### Açık Standartlara Dayalı { #based-on-open-standards }
* API oluşturma işlemlerinde <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> buna <abbr title="also known as: endpoints, routes">path</abbr> <abbr title=" HTTP metodları olarak bilinen, POST, GET, PUT, DELETE">operasyonları </abbr>parametreleri, body talebi, güvenlik gibi şeyler dahil olmak üzere deklare bunların deklare edilmesi.
* Otomatik olarak data modelinin <a href="http://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> ile beraber dokümante edilmesi (OpenAPI'n kendisi zaten JSON Schema'ya dayanıyor).
* Titiz bir çalışmanın sonucunda yukarıdaki standartlara uygun bir framework oluşturduk. Standartları pastanın üzerine sonradan eklenmiş bir çilek olarak görmedik.
* Ayrıca bu bir çok dilde kullanılabilecek **client code generator** kullanımına da izin veriyor.
* API oluşturmada <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>, buna <dfn title="şöyle de bilinir: endpoints, routes">path</dfn> <dfn title="HTTP metodları olarak da bilinir; POST, GET, PUT, DELETE gibi">operasyonları</dfn>, parametreler, request body'leri, güvenlik vb. deklarasyonları dahildir.
* <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> ile otomatik veri modeli dokümantasyonu (OpenAPI zaten JSON Schema'ya dayanır).
* Bu standartlar etrafında, titiz bir çalışmanın ardından tasarlandı; sonradan eklenmiş bir katman değil.
* Bu sayede birçok dilde otomatik **client code generation** da kullanılabilir.
### Otomatik dokümantasyon
### Otomatik Dokümantasyon { #automatic-docs }
Etkileşimli API dokümantasyonu ve keşif için web arayüzleri. Framework OpenAPIye dayandığından, birden fazla seçenek vardır; varsayılan olarak 2si dahildir.
OpenAPI standartlarına dayalı olan bir framework olarak, geliştiricilerin birden çok seçeneği var, varsayılan olarak gelen 2 farklı interaktif API dokümantasyonu ve web kullanıcı arayüzü var.
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a> interaktif olarak API'ınızı tarayıcı üzerinden çağırıp test edebilmenize olanak sağlıyor.
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a> ile etkileşimli keşif; APInizi tarayıcıdan doğrudan çağırıp test edin.
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a> ile beraber alternatif API dokümantasyonu.
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a> ile alternatif API dokümantasyonu.
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Sadece modern Python
### Sadece Modern Python { #just-modern-python }
Tamamiyle standartlar **Python 3.8**'nın type hintlerine dayanıyor (Pydantic'in sayesinde). Yeni bir syntax öğrenmene gerek yok. Sadece modern Python.
Her şey standart **Python type** deklarasyonlarına dayanır (Pydantic sayesinde). Öğrenilecek yeni bir söz dizimi yok. Sadece standart, modern Python.
Python typelarını nasıl kullanacağınıza dair 2 dakikalık bir hatırlatmaya ihtiyacınız varsa (FastAPI kullanmasanız bile) kısa eğitime göz atın: [Python Types](python-types.md){.internal-link target=_blank}.
Eğer Python type hintlerini bilmiyorsan veya bir hatırlatmaya ihtiyacın var ise(FastAPI kullanmasan bile) şu iki dakikalık küçük bilgilendirici içeriğe bir göz at: [Python Types](python-types.md){.internal-link target=_blank}.
Standart Python'u typelarını belirterek yazıyorsun:
Türleriyle standart Python yazarsınız:
```Python
from typing import List, Dict
from datetime import date
from pydantic import BaseModel
# Değişkeni str olarak belirt
# ve o fonksiyon için harika bir editör desteği al
# Bir değişkeni str olarak belirt
# ve fonksiyon içinde editör desteği al
def main(user_id: str):
return user_id
# Pydantic modeli
# Bir Pydantic modeli
class User(BaseModel):
id: int
name: str
joined: date
```
Sonrasında bu şekilde kullanabilirsin
Sonra şöyle kullanabilirsiniz:
```Python
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
@@ -67,25 +63,26 @@ second_user_data = {
my_second_user: User = User(**second_user_data)
```
/// info
`**second_user_data` şu anlama geliyor:
`**second_user_data` şu anlama gelir:
Key-Value çiftini direkt olarak `second_user_data` dictionarysine kaydet , yaptığın şey buna eşit olacak: `User(id=4, name="Mary", joined="2018-11-30")`
`second_user_data` dictindeki anahtar ve değerleri doğrudan anahtar-değer argümanları olarak geç; şu ifadeye eşdeğerdir: `User(id=4, name="Mary", joined="2018-11-30")`
///
### Editor desteği
### Editör Desteği { #editor-support }
Bütün framework kullanılması kolay ve sezgileri güçlü olması için tasarlandı, verilen bütün kararlar geliştiricilere en iyi geliştirme deneyimini yaşatmak üzere, bir çok editör üzerinde test edildi.
Tüm framework, kullanımı kolay ve sezgisel olacak şekilde tasarlandı; en iyi geliştirme deneyimini sağlamak için geliştirmeye başlamadan önce bile alınan kararlar birden çok editörde test edildi.
Son yapılan Python geliştiricileri anketinde,ık ara <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">en çok kullanılan özellik "oto-tamamlama" idi.</a>.
Python geliştirici anketlerinde açıkça görülüyor ki <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">en çok kullanılan özelliklerden biri "otomatik tamamlama"</a>.
Bütün **FastAPI** frameworkü oto-tamamlama açısından geliştiriciyi tatmin etmek üzerine tasarlandı. Otomatik tamamlama her yerde çalışıyor.
Tüm **FastAPI** bunun tatmin edilmesi üzerine kuruldu. Otomatik tamamlama her yerde çalışır.
Dokümantasyona tekrardan çok nadir olarak geleceksin.
Dokümana geri dönmeniz nadiren gerekecek.
Editörün sana nasıl yardım ettiğine bir bak:
Editörünüz şöyle yardımcı olabilir:
* <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a> ile:
@@ -95,115 +92,111 @@ Editörün sana nasıl yardım ettiğine bir bak:
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
Daha önce imkânsız olduğunu düşünebileceğiniz yerlerde bile tamamlama alırsınız. Örneğin, bir requestten gelen (iç içe de olabilir) JSON body içindeki `price` anahtarı için.
Daha önceden düşünüp en imkansız diyebileceğin durumlarda bile otomatik tamamlama alacaksın, örnek olarak `price` JSON body içerisinde (nested bir JSON body de olabilirdi.) direkt olarak istekten geliyor, bu durumda bile oto-tammalama sağlıyor.
Artık anahtar adlarını yanlış yazmak, dokümana gidip gelmek ya da sonunda `username` mi `user_name` mi kullandığınızı bulmak için sayfayı yukarı aşağı kaydırmak yok.
Artık key isimlerini yanlış yazma, dokümantasyona dönüp deliler gibi yukarı aşağı sayfada gezmek ve en sonunda `username` mi yoksa `user_name` mi kullandım gibi sorular yok.
### Kısa { #short }
### Kısa
Her şey için mantıklı **varsayılanlar** ve her yerde isteğe bağlı yapılandırmalar vardır. Tüm parametreler, ihtiyacınızı karşılayacak şekilde ince ayar yapılarak tanımlamak istediğiniz APIyi oluşturabilir.
Her şey için mantıklı bir **varsayılanı** var. Parametrelerini opsiyonel olarak tanımlayıp API'nı istediğin gibi modifiye edebilirsin.
Ancak varsayılan hâliyle hepsi **“hemen çalışır”**.
Hepsi varsayılan olarak **çalışıyor**.
### Doğrulama { #validation }
* Çoğu (veya hepsi?) Python **veri tipi** için doğrulama, şunlar dâhil:
* JSON nesneleri (`dict`).
* Eleman tipleri tanımlanan JSON dizileri (`list`).
* Minimum ve maksimum uzunlukları tanımlanan String (`str`) alanları.
* Min ve max değerleri olan sayılar (`int`, `float`) vb.
### Doğrulama
* Neredeyse bütün (ya da hepsi?) Python **data typeları** için doğrulama, kapsadıkları:
* JSON objeleri (`dict`).
* JSON array (`list`) item type'ı belirtirken.
* String (`str`) parametresi, minimum ve maksimum uzunluk gibi sınırlandırmalar yaparken.
* Numaralar (`int`, `float`) maksimum ve minimum gibi sınırlandırmalar yaparken.
* Bunlar gibi en egzotik typelarla bile doğrulama yapabiliyorsunuz.:
* Daha “egzotik” tipler için doğrulama:
* URL.
* Email.
* UUID.
* ...ve diğerleri.
Bütün doğrulama olayları çok güçlü bir kütüphane sayesinde yapılıyor, **Pydantic**.
Tüm doğrulama köklü ve sağlam **Pydantic** tarafından yapılır.
### Güvenlik ve kimlik doğrulama
### Güvenlik ve Kimlik Doğrulama { #security-and-authentication }
Güvenlik ve doğrulama database ve data modellerinden taviz vermeden entegre edilebilir durumda.
Güvenlik ve kimlik doğrulama entegredir. Veritabanları veya veri modelleriyle ilgili hiçbir taviz yoktur.
n güvenlik şemaları OpenAPI'da tanımlanmış durumda, kapsadıkları:
OpenAPIda tanımlanan m güvenlik şemaları, şunlar dâhil:
* HTTP Basic.
* **OAuth2** (ve **JWT tokenleriyle** beraber). Bu öğretici içeriğe göz atabilirsin [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
* **OAuth2** (ayrıca **JWT token**larla). Şu eğitime göz atın: [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
* API anahtarları:
* Headerlar.
* Query parametreleri.
* Cookies, vs.
* Headerlarda.
* Query parametrelerinde.
* Cookielerde vb.
Bütün güvenlik özellikleri Starlette'den geliyor (**session cookies'de** dahil olmak üzere).
Buna ek olarak Starlettein tüm güvenlik özellikleri (**session cookies** dâhil).
Bütün hepsi tekrardan kullanılabilir aletler ve bileşenler olarak, kolayca sistemlerinize, data depolarınıza, ilişkisel ve NoSQL databaselerinize entegre edebileceğiniz şekilde yapıldı.
Tümü, sistemleriniz, veri depolarınız, ilişkisel ve NoSQL veritabanlarınız vb. ile kolayca entegre edilebilen, yeniden kullanılabilir araçlar ve bileşenler olarak inşa edilmiştir.
### Dependency injection
### Dependency Injection { #dependency-injection }
FastAPI'ın inanılmaz derecede kullanımı kolay, fakat inanılmaz derecede güçlü <abbr title='"components", "resources", "services", "providers" olarak da bilinen'><strong>Dependency Injection </strong></abbr> sistemi var.
FastAPI, son derece kolay kullanımlı ama son derece güçlü bir <dfn title='şöyle de bilinir: "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></dfn> sistemine sahiptir.
* Dependencylerin bile dependencies'i olabiliyor, FastAPI bunun için **graph of "dependency"** yaratıyor.
* Hepsi **otomatik olarak** FastAPI tarafından hallediliyor.
* Bütün zorunlulukların gelen datalara bağlı olarak farklı gereksinimleri olabiliyor, ilave path operasyonlarının kısıtlamaları ve otomatik dokümantasyonu da ayrıca yapılıyor .
* Path operasyonu parametreleri içerisinde belirtilen gereksinimler için bile **Otomatik doğrulama** yapılabiliyor.
* Kompleks kimlik doğrulama sistemleri için destek, **database bağlantıları**, vs.
* **Taviz yok** hiçbir şeyden taviz vermeden, database frontend vs. Bütün hepsinin kolayca entegre edilebiliyor.
* Bağımlılıkların da kendi bağımlılıkları olabilir; böylece bir hiyerarşi veya **bağımlılıklar "grafı"** oluşur.
* Tüm süreç framework tarafından **otomatik olarak yönetilir**.
* Tüm bağımlılıklar, requestlerden veri talep edebilir ve *path operation* kısıtlarını ve otomatik dokümantasyonu **zenginleştirebilir**.
* Bağımlılıklarda tanımlanan *path operation* parametreleri için bile **otomatik doğrulama**.
* Karmaşık kullanıcı kimlik doğrulama sistemleri, **veritabanı bağlantıları** vb. için destek.
* Veritabanları, frontendler vb. ile **taviz yok**; ancak hepsiyle kolay entegrasyon.
### Sınırsız "plug-inler"
### Sınırsız "Plug-in" { #unlimited-plug-ins }
Başka bir deyişle, plug-inlere ihtiyacımız yok, import edip direkt olarak kullanmaya başlayabiliriz.
Başka bir deyişle, onlara gerek yok; ihtiyaç duyduğunuz kodu import edin ve kullanın.
Bütün entegrasyonlar kullanımı kolay olmak üzere (zorunluluklar ile beraber) tasarlandı, sen bir "plug-in" yaratıp 2 satır kod ile, *path operasyonlarında* kullandığımız syntax ve aynı yapı ile koduna entregre edebilirsin.
Her entegrasyon (bağımlılıklar ile) o kadar basit olacak şekilde tasarlanmıştır ki, uygulamanız için, *path operations* ile kullandığınız aynı yapı ve söz dizimiyle sadece 2 satırda bir “plug-in” yazabilirsiniz.
### Test Edildi { #tested }
### Test edildi
* %100 <dfn title="Otomatik olarak test edilen kod miktarı">test kapsayıcılığı</dfn>.
* %100 <dfn title="Python type annotations; bununla editörünüz ve harici araçlar size daha iyi destek verebilir">type annotated</dfn> kod tabanı.
* Üretimde kullanılan uygulamalarda kullanılıyor.
* 100% <abbr title="Kodun ne kadarının test edildiği">test coverage</abbr>.
* 100% <abbr title="Python type annotations, with this your editor and external tools can give you better support">typeları belirtilmiş</abbr> codebase.
* FastAPI ile yapılan bir çok proje insanlar tarafından kullanılıyor.
## Starlette Özellikleri { #starlette-features }
## Starlette özellikleri
**FastAPI**, <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a> ile tamamen uyumludur (ve onun üzerine kuruludur). Dolayısıyla elinizdeki ek Starlette kodları da çalışır.
**FastAPI**, <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a> ile tamamiyle uyumlu ve üzerine kurulu. Yani FastAPI üzerine ekleme yapacağınız herhangi bir Starlette kodu da çalışacaktır.
`FastAPI` aslında `Starlette`in bir alt sınıfıdır. Starlettei zaten biliyor veya kullanıyorsanız, işlevlerin çoğu aynı şekilde çalışır.
`FastAPI` aslında `Starlette`'nin bir sub-class'ı. Eğer Starlette'nin nasıl kullanılacağını biliyor isen, çoğu işlevini aynı şekilde yapıyor.
**FastAPI** ile **Starlette**in tüm özelliklerini elde edersiniz (FastAPI, steroid basılmış Starlette gibidir):
**FastAPI** ile beraber **Starlette**'nin bütün özelliklerine de sahip olacaksınız (FastAPI aslında Starlette'nin steroid basmış hali):
* Gerçekten etkileyici bir performansa sahip.Python'un ise en hızlı frameworklerinden bir tanesi, <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">**NodeJS** ve **Go** ile ise eşdeğer performansa sahip.</a>.
* Cidden etkileyici performans. <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">Mevcut en hızlı Python frameworklerinden biridir; **NodeJS** ve **Go** ile aynı seviyededir</a>.
* **WebSocket** desteği.
* **GraphQL** desteği.
* Kullanım halinde arka plan işlevleri.
* Başlatma ve kapatma eventleri(startup and shutdown).
* Test sunucusu HTTPX üzerine kurulu.
* **CORS**, GZip, Static dosyalar, Streaming responseları.
* **Session and Cookie** desteği.
* 100% test kapsayıcılığı.
* 100% typeları belirtilmiş codebase.
* Süreç içi arka plan görevleri.
* Başlatma ve kapatma olayları.
* HTTPX üzerine kurulu test istemcisi.
* **CORS**, GZip, Static Files, Streaming responselar.
* **Session** ve **Cookie** desteği.
* %100 test kapsayıcılığı.
* %100 type annotated kod tabanı.
## Pydantic özellikleri
## Pydantic Özellikleri { #pydantic-features }
**FastAPI** ile <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a> tamamiyle uyumlu ve üzerine kurulu. Yani FastAPI üzerine ekleme yapacağınız herhangi bir Pydantic kodu da çalışacaktır.
**FastAPI**, <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a> ile tamamen uyumludur (ve onun üzerine kuruludur). Dolayısıyla elinizdeki ek Pydantic kodları da çalışır.
Bunlara Pydantic üzerine kurulu <abbr title="Object-Relational Mapper">ORM</abbr> databaseler ve , <abbr title="Object-Document Mapper">ODM</abbr> kütüphaneler de dahil olmak üzere.
Pydantice dayanan harici kütüphaneler de dâhildir; veritabanları için <abbr title="Object-Relational Mapper - Nesne-İlişkisel Eşleyici">ORM</abbr>ler, <abbr title="Object-Document Mapper - Nesne-Belge Eşleyici">ODM</abbr>ler gibi.
Bu ayrıca şu anlama da geliyor, bir çok durumda requestten gelen objeyi **direkt olarak database**'e her şeyi otomatik olarak doğrulanmış bir biçimde aktarabilirisin.
Bu aynı zamanda, birçok durumda requestten aldığınız nesneyi **doğrudan veritabanına** iletebileceğiniz anlamına gelir; zira her şey otomatik olarak doğrulanır.
Aynı şekilde, databaseden gelen objeyi de **direkt olarak isteğe** de tamamiyle doğrulanmış bir biçimde gönderebilirsiniz.
Tersi yönde de geçerlidir; birçok durumda veritabanından aldığınız nesneyi **doğrudan client**a gönderebilirsiniz.
**FastAPI** ile beraber **Pydantic**'in n özelliklerine sahip olacaksınız (FastAPI data kontrolünü Pydantic'in üzerine kurduğu için):
**FastAPI** ile **Pydantic**in tüm özelliklerini elde edersiniz (FastAPI, tüm veri işlemede Pydantice dayanır):
* **Kafa karıştırmaz**:
* Farklı bir syntax öğrenmenize gerek kalmaz,
* Eğer Python typelarını nasıl kullanacağını biliyorsan Pydantic kullanmayı da biliyorsundur.
* Kullandığın geliştirme araçları ile iyi çalışır **<abbr title="Integrated Development Environment, kod editörüne benzer">IDE</abbr>/<abbr title="Code errorlarınızı inceleyen program">linter</abbr>/brain**:
* Pydantic'in veri yapıları aslında sadece senin tanımladığın classlar; Bu yüzden doğrulanmış dataların ile otomatik tamamlama, linting ve mypy'ı kullanarak sorunsuz bir şekilde çalışabilirsin
* **En kompleks** yapıları bile doğrula:
* Hiyerarşik Pydantic modellerinin kullanımı ile beraber, Python `typing`s `List` and `Dict`, vs gibi şeyleri doğrula.
* Doğrulayıcılar en kompleks data şemalarının bile temiz ve kolay bir şekilde tanımlanmasına izin veriyor, ve hepsi JSON şeması olarak dokümante ediliyor
* Pydantic, JSON objen ne kadar derin (nested) olursa olsun doğrulamasını ve gösterimini yapıyor
* Öğrenmeniz gereken yeni bir şema tanımlama mikro-dili yok.
* Python typelarını biliyorsanız Pydantici nasıl kullanacağınızı da biliyorsunuz.
* **<abbr title="Integrated Development Environment - Tümleşik Geliştirme Ortamı: bir kod editörüne benzer">IDE</abbr>/<dfn title="koddaki hataları denetleyen bir program">linter</dfn>/beyin**inizle iyi anlaşır:
* Pydantic veri yapıları, sizin tanımladığınız sınıfların örnekleridir; bu nedenle doğrulanmış verilerinizle otomatik tamamlama, linting ve mypy sorunsuz çalışır, sezgileriniz de yol gösterir.
* **Karmaşık yapıları** doğrulayın:
* Hiyerarşik Pydantic modelleri, Python `typing`in `List` ve `Dict`i vb. kullanımı.
* Doğrulayıcılar (validators), karmaşık veri şemalarının net ve kolay şekilde tanımlanmasını, kontrol edilmesini ve JSON Schema olarak dokümante edilmesini sağlar.
* Derinlemesine iç içe **JSON** nesnelerine sahip olabilir, hepsinin doğrulanmasını ve anotasyonlanmasını sağlayabilirsiniz.
* **Genişletilebilir**:
* Pydantic özelleştirilmiş data tiplerinin tanımlanmasının yapılmasına izin veriyor ayrıca validator decoratorü ile senin doğrulamaları genişletip, kendi doğrulayıcılarını yazmana izin veriyor.
* 100% test kapsayıcılığı.
* Pydantic, özel veri tiplerinin tanımlanmasına izin verir; ayrıca validator decoratorüyle bir modeldeki metodlarla doğrulamayı genişletebilirsiniz.
* %100 test kapsayıcılığı.

View File

@@ -44,7 +44,7 @@ Sonrasında, (**FastAPI** kullanan bir geliştirici olarak) sahip olmak istediğ
Çeşitli fikirleri en popüler Python editörlerinde test ettim: PyCharm, VS Code, Jedi tabanlı editörler.
Bu test, en son <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">Python Developer Survey</a>'ine göre, kullanıcıların yaklaşık %80'inin kullandığı editörleri kapsıyor.
Bu test, en son <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">Python Geliştirici Anketi</a>'ine göre, kullanıcıların yaklaşık %80'inin kullandığı editörleri kapsıyor.
Bu da demek oluyor ki **FastAPI**, Python geliştiricilerinin %80'inin kullandığı editörlerle test edildi. Ve diğer editörlerin çoğu benzer şekilde çalıştığından, avantajları neredeyse tüm editörlerde çalışacaktır.

View File

@@ -8,7 +8,7 @@ Ancak herhangi bir nedenle client'larınız eski davranışa bağlıysa, securit
Örneğin, varsayılan `401 Unauthorized` hatası yerine `403 Forbidden` hatası döndüren bir `HTTPBearer` alt sınıfı oluşturabilirsiniz:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
/// tip | İpucu

View File

@@ -4,9 +4,9 @@ Gerekirse, ayarlar ve environment variable'ları kullanarak OpenAPI'yi ortama g
## Güvenlik, API'ler ve dokümantasyon hakkında { #about-security-apis-and-docs }
Production ortamında dokümantasyon arayüzlerini gizlemek, API'nizi korumanın yolu *olmamalıdır*.
Production ortamında dokümantasyon arayüzlerini gizlemek, API'nizi korumanın yolu olmamalıdır.
Bu, API'nize ekstra bir güvenlik katmanı eklemez; *path operation*'lar bulundukları yerde yine erişilebilir olacaktır.
Bu, API'nize ekstra bir güvenlik katmanı eklemez; path operation'lar bulundukları yerde yine erişilebilir olacaktır.
Kodunuzda bir güvenlik açığı varsa, o açık yine var olmaya devam eder.
@@ -29,7 +29,7 @@ Yine de, bazı ortamlarda (örn. production) veya environment variable'lardan ge
Örneğin:
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
Burada `openapi_url` ayarını, varsayılanı `"/openapi.json"` olacak şekilde tanımlıyoruz.

View File

@@ -18,7 +18,7 @@ Ayarları değiştirmeden bırakırsanız, syntax highlighting varsayılan olara
Ancak `syntaxHighlight` değerini `False` yaparak devre dışı bırakabilirsiniz:
{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
...ve ardından Swagger UI artık syntax highlighting'i göstermeyecektir:
@@ -28,7 +28,7 @@ Ancak `syntaxHighlight` değerini `False` yaparak devre dışı bırakabilirsini
Aynı şekilde, `"syntaxHighlight.theme"` anahtarıyla (ortasında bir nokta olduğuna dikkat edin) syntax highlighting temasını ayarlayabilirsiniz:
{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
Bu yapılandırma, syntax highlighting renk temasını değiştirir:
@@ -46,13 +46,13 @@ FastAPI, çoğu kullanım senaryosu için uygun bazı varsayılan yapılandırma
Örneğin `deepLinking`'i devre dışı bırakmak için `swagger_ui_parameters`'a şu ayarları geçebilirsiniz:
{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
## Diğer Swagger UI Parametreleri { #other-swagger-ui-parameters }
Kullanabileceğiniz diğer tüm olası yapılandırmaları görmek için, resmi <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/" class="external-link" target="_blank">Swagger UI parametreleri dokümantasyonunu</a> okuyun.
## Yalnızca JavaScript ayarları { #javascript-only-settings }
## Yalnızca JavaScript Ayarları { #javascript-only-settings }
Swagger UI ayrıca bazı yapılandırmaların **yalnızca JavaScript** nesneleri olmasına izin verir (örneğin JavaScript fonksiyonları).

View File

@@ -18,7 +18,7 @@ Bu, örneğin bazı URL'leri kısıtlayan bir ülkede yaşıyorsanız faydalı o
Bunları devre dışı bırakmak için `FastAPI` uygulamanızı oluştururken URL'lerini `None` olarak ayarlayın:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
### Özel dokümanları ekleyin { #include-the-custom-docs }
@@ -34,7 +34,7 @@ Dokümanlar için HTML sayfalarını üretmek üzere FastAPI'nin dahili fonksiyo
ReDoc için de benzer şekilde...
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
/// tip | İpucu
@@ -50,7 +50,7 @@ Swagger UI bunu arka planda sizin için yönetir, ancak bu "redirect" yardımcı
Şimdi her şeyin çalıştığını test edebilmek için bir *path operation* oluşturun:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
### Test edin { #test-it }
@@ -118,7 +118,7 @@ Bundan sonra dosya yapınız şöyle görünebilir:
* `StaticFiles` içe aktarın.
* Belirli bir path'te bir `StaticFiles()` instance'ını "mount" edin.
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
### Statik dosyaları test edin { #test-the-static-files }
@@ -144,7 +144,7 @@ Bu, uygulamanızdan statik dosyaları servis edebildiğinizi ve dokümanlar içi
Bunları devre dışı bırakmak için `FastAPI` uygulamanızı oluştururken URL'lerini `None` olarak ayarlayın:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
### Statik dosyalar için özel dokümanları ekleyin { #include-the-custom-docs-for-static-files }
@@ -160,7 +160,7 @@ Yine FastAPI'nin dahili fonksiyonlarını kullanarak dokümanlar için HTML sayf
ReDoc için de benzer şekilde...
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
/// tip | İpucu
@@ -176,7 +176,7 @@ Swagger UI bunu arka planda sizin için yönetir, ancak bu "redirect" yardımcı
Şimdi her şeyin çalıştığını test edebilmek için bir *path operation* oluşturun:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
### Statik Dosyalar UI'ını Test Edin { #test-static-files-ui }

View File

@@ -4,7 +4,7 @@ Oluşturulan OpenAPI şemasını değiştirmeniz gereken bazı durumlar olabilir
Bu bölümde bunun nasıl yapılacağını göreceksiniz.
## Normal süreç { #the-normal-process }
## Normal Süreç { #the-normal-process }
Normal (varsayılan) süreç şöyledir.
@@ -33,7 +33,7 @@ Ve `get_openapi()` fonksiyonu şu parametreleri alır:
///
## Varsayılanları ezme { #overriding-the-defaults }
## Varsayılanları Ezme { #overriding-the-defaults }
Yukarıdaki bilgileri kullanarak aynı yardımcı fonksiyonla OpenAPI şemasını üretebilir ve ihtiyacınız olan her parçayı override edebilirsiniz.
@@ -43,21 +43,21 @@ Yukarıdaki bilgileri kullanarak aynı yardımcı fonksiyonla OpenAPI şemasın
Önce, tüm **FastAPI** uygulamanızı her zamanki gibi yazın:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
### OpenAPI şemasını üretme { #generate-the-openapi-schema }
### OpenAPI Şemasını Üretme { #generate-the-openapi-schema }
Ardından, bir `custom_openapi()` fonksiyonunun içinde aynı yardımcı fonksiyonu kullanarak OpenAPI şemasını üretin:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
### OpenAPI şemasını değiştirme { #modify-the-openapi-schema }
### OpenAPI Şemasını Değiştirme { #modify-the-openapi-schema }
Artık OpenAPI şemasındaki `info` "object"'ine özel bir `x-logo` ekleyerek ReDoc extension'ını ekleyebilirsiniz:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
### OpenAPI şemasını cache'leme { #cache-the-openapi-schema }
### OpenAPI Şemasını Cache'leme { #cache-the-openapi-schema }
Ürettiğiniz şemayı saklamak için `.openapi_schema` özelliğini bir "cache" gibi kullanabilirsiniz.
@@ -65,15 +65,15 @@ Böylece bir kullanıcı API docs'larınızı her açtığında uygulamanız şe
Şema yalnızca bir kez üretilecektir; sonraki request'ler için de aynı cache'lenmiş şema kullanılacaktır.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
### Metodu override etme { #override-the-method }
### Metodu Override Etme { #override-the-method }
Şimdi `.openapi()` metodunu yeni fonksiyonunuzla değiştirebilirsiniz.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
### Kontrol edin { #check-it }
### Kontrol Edin { #check-it }
<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> adresine gittiğinizde, özel logonuzu kullandığınızı göreceksiniz (bu örnekte **FastAPI**'nin logosu):

View File

@@ -14,7 +14,7 @@ Döndürmeniz gerekenden daha fazla veri döndürmediğinizden emin olmak için,
*path operation*'larınıza özet ve açıklama eklemek ve bunları dokümantasyon arayüzünde göstermek için, [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank} dokümantasyonunu okuyun.
## Dokümantasyon Yanıtıklaması - OpenAPI { #documentation-response-description-openapi }
## Dokümantasyon Responseıklaması - OpenAPI { #documentation-response-description-openapi }
Dokümantasyon arayüzünde gösterilen response açıklamasını tanımlamak için, [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank} dokümantasyonunu okuyun.

View File

@@ -35,7 +35,7 @@ Kullanım senaryonuza göre farklı bir kütüphaneyi tercih edebilirsiniz; anca
Strawberry'yi FastAPI ile nasıl entegre edebileceğinize dair küçük bir ön izleme:
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
Strawberry hakkında daha fazlasını <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry dokümantasyonunda</a> öğrenebilirsiniz.

View File

@@ -8,6 +8,6 @@ Projeniz için ilginç ve yararlı görünen bir şey varsa devam edin ve incele
/// tip | İpucu
**FastAPI**'ı yapılandırılmış bir şekilde (önerilir) **öğrenmek** istiyorsanız bunun yerine [Öğretici - Kullanıcı Rehberi](../tutorial/index.md){.internal-link target=_blank}'ni bölüm bölüm okuyun.
**FastAPI**'yi yapılandırılmış bir şekilde (önerilir) **öğrenmek** istiyorsanız bunun yerine [Öğretici - Kullanıcı Rehberi](../tutorial/index.md){.internal-link target=_blank}'ni bölüm bölüm okuyun.
///

View File

@@ -88,7 +88,7 @@ graph TB
style V2Field fill:#f9fff3
```
...ancak aynı uygulamada Pydantic v1 ve v2 kullanarak **ayrı (separated)** modeller tanımlayabilirsiniz.
...ancak aynı uygulamada Pydantic v1 ve v2 kullanarak **ayrı** modeller tanımlayabilirsiniz.
```mermaid
graph TB

View File

@@ -40,7 +40,7 @@ Temel özellikleri şunlardır:
* **Hızlı**: Çok yüksek performanslı, **NodeJS** ve **Go** ile eşit düzeyde (Starlette ve Pydantic sayesinde). [Mevcut en hızlı Python framework'lerinden biri](#performance).
* **Kodlaması Hızlı**: Özellik geliştirme hızını yaklaşık %200 ile %300 aralığında artırır. *
* **Daha az hata**: İnsan (geliştirici) kaynaklı hataları yaklaşık %40 azaltır. *
* **Sezgisel**: Harika bir editör desteği. Her yerde <abbr title="auto-complete, autocompletion, IntelliSense olarak da bilinir">Completion</abbr>. Hata ayıklamaya daha az zaman.
* **Sezgisel**: Harika bir editör desteği. Her yerde <dfn title="oto-tamamlama, autocompletion, IntelliSense olarak da bilinir">Tamamlama</dfn>. Hata ayıklamaya daha az zaman.
* **Kolay**: Kullanımı ve öğrenmesi kolay olacak şekilde tasarlandı. Doküman okumaya daha az zaman.
* **Kısa**: Kod tekrarını minimize eder. Her parametre tanımından birden fazla özellik. Daha az hata.
* **Sağlam**: Production'a hazır kod elde edersiniz. Otomatik etkileşimli dokümantasyon ile birlikte.
@@ -127,7 +127,7 @@ Temel özellikleri şunlardır:
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
Web API yerine terminalde kullanılacak bir <abbr title="Command Line Interface">CLI</abbr> uygulaması geliştiriyorsanız <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>'a göz atın.
Web API yerine terminalde kullanılacak bir <abbr title="Command Line Interface - Komut Satırı Arayüzü">CLI</abbr> uygulaması geliştiriyorsanız <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>'a göz atın.
**Typer**, FastAPI'ın küçük kardeşi. Ve hedefi CLI'ların **FastAPI'ı** olmak. ⌨️ 🚀
@@ -368,7 +368,7 @@ item: Item
* Verinin doğrulanması:
* Veri geçersiz olduğunda otomatik ve anlaşılır hatalar.
* Çok derin iç içe JSON nesneleri için bile doğrulama.
* Girdi verisinin <abbr title="serialization, parsing, marshalling olarak da bilinir">Dönüşümü</abbr>: network'ten gelen veriyi Python verisine ve type'larına çevirir. Şunlardan okur:
* Girdi verisinin <dfn title="şöyle de bilinir: serileştirme, ayrıştırma, marshalling">Dönüşümü</dfn>: network'ten gelen veriyi Python verisine ve type'larına çevirir. Şunlardan okur:
* JSON.
* Path parameter'lar.
* Query parameter'lar.
@@ -376,7 +376,7 @@ item: Item
* Header'lar.
* Form'lar.
* File'lar.
* Çıktı verisinin <abbr title="serialization, parsing, marshalling olarak da bilinir">Dönüşümü</abbr>: Python verisini ve type'larını network verisine çevirir (JSON olarak):
* Çıktı verisinin <dfn title="şöyle de bilinir: serileştirme, ayrıştırma, marshalling">Dönüşümü</dfn>: Python verisini ve type'larını network verisine çevirir (JSON olarak):
* Python type'larını dönüştürür (`str`, `int`, `float`, `bool`, `list`, vb.).
* `datetime` nesneleri.
* `UUID` nesneleri.
@@ -439,7 +439,7 @@ Daha fazla özellik içeren daha kapsamlı bir örnek için <a href="https://fas
* **parameter**'ların farklı yerlerden: **header**'lar, **cookie**'ler, **form alanları** ve **file**'lar olarak tanımlanması.
* `maximum_length` ya da `regex` gibi **doğrulama kısıtlamalarının** nasıl ayarlanacağı.
* Çok güçlü ve kullanımı kolay bir **<abbr title="components, resources, providers, services, injectables olarak da bilinir">Dependency Injection</abbr>** sistemi.
* Çok güçlü ve kullanımı kolay bir **<dfn title="şöyle de bilinir: bileşenler, kaynaklar, sağlayıcılar, servisler, enjekte edilebilirler">Bağımlılık Enjeksiyonu</dfn>** sistemi.
* **JWT tokens** ve **HTTP Basic** auth ile **OAuth2** desteği dahil güvenlik ve kimlik doğrulama.
* **Çok derin iç içe JSON modelleri** tanımlamak için daha ileri (ama aynı derecede kolay) teknikler (Pydantic sayesinde).
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> ve diğer kütüphaneler ile **GraphQL** entegrasyonu.
@@ -524,7 +524,7 @@ Starlette tarafından kullanılanlar:
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - `TestClient` kullanmak istiyorsanız gereklidir.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - varsayılan template yapılandırmasını kullanmak istiyorsanız gereklidir.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()` ile, form <abbr title="HTTP request'inden gelen string'i Python verisine dönüştürme">"parsing"</abbr> desteği istiyorsanız gereklidir.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()` ile, form <dfn title="HTTP request'ten gelen string'i Python verisine dönüştürme">"ayrıştırma"</dfn> desteği istiyorsanız gereklidir.
FastAPI tarafından kullanılanlar:
@@ -534,7 +534,7 @@ FastAPI tarafından kullanılanlar:
### `standard` Bağımlılıkları Olmadan { #without-standard-dependencies }
`standard` opsiyonel bağımlılıklarını dahil etmek istemiyorsanız, `pip install "fastapi[standard]"` yerine `pip install fastapi` ile kurabilirsiniz.
`standard` opsiyonel bağımlılıklarını dahil etmek istemiyorsanız, `pip install fastapi` ile kurabilirsiniz.
### `fastapi-cloud-cli` Olmadan { #without-fastapi-cloud-cli }

View File

@@ -2,9 +2,9 @@
Python, isteğe bağlı "type hints" (diğer adıyla "type annotations") desteğine sahiptir.
Bu **"type hints"** veya annotations, bir değişkenin <abbr title="örneğin: str, int, float, bool">type</abbr>'ını bildirmeye yarayan özel bir sözdizimidir.
Bu **"type hints"** veya annotations, bir değişkenin <dfn title="örneğin: str, int, float, bool">tip</dfn>'ini bildirmeye yarayan özel bir sözdizimidir.
Değişkenleriniz için type bildirerek, editörler ve araçlar size daha iyi destek sağlayabilir.
Değişkenleriniz için tip bildirerek, editörler ve araçlar size daha iyi destek sağlayabilir.
Bu, Python type hints hakkında sadece **hızlı bir eğitim / bilgi tazeleme** dokümanıdır. **FastAPI** ile kullanmak için gereken minimum bilgiyi kapsar... ki aslında bu çok azdır.
@@ -22,7 +22,7 @@ Eğer bir Python uzmanıysanız ve type hints hakkında her şeyi zaten biliyors
Basit bir örnekle başlayalım:
{* ../../docs_src/python_types/tutorial001_py39.py *}
{* ../../docs_src/python_types/tutorial001_py310.py *}
Bu programı çalıştırınca şu çıktıyı alırsınız:
@@ -34,9 +34,9 @@ Fonksiyon şunları yapar:
* `first_name` ve `last_name` değerlerini alır.
* `title()` ile her birinin ilk harfini büyük harfe çevirir.
* Ortada bir boşluk olacak şekilde <abbr title="Hepsini, tek bir bütün olacak şekilde bir araya koyar. İçerikler ardışık şekilde yer alır.">Concatenates</abbr> eder.
* Ortada bir boşluk olacak şekilde <dfn title="Onları tek bir bütün olarak bir araya getirir. İçerikler art arda gelir.">Birleştirir</dfn>.
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
### Düzenleyelim { #edit-it }
@@ -78,7 +78,7 @@ Bu kadar.
Bunlar "type hints":
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
Bu, aşağıdaki gibi default değerler bildirmekle aynı şey değildir:
@@ -106,7 +106,7 @@ Bununla birlikte, seçenekleri görerek kaydırabilirsiniz; ta ki "tanıdık gel
Şu fonksiyona bakın, zaten type hints içeriyor:
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
Editör değişkenlerin tiplerini bildiği için, sadece completion değil, aynı zamanda hata kontrolleri de alırsınız:
@@ -114,9 +114,9 @@ Editör değişkenlerin tiplerini bildiği için, sadece completion değil, ayn
Artık bunu düzeltmeniz gerektiğini, `age`'i `str(age)` ile string'e çevirmeniz gerektiğini biliyorsunuz:
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
## Tipleri bildirmek { #declaring-types }
## Tipleri Bildirmek { #declaring-types }
Type hints bildirmek için ana yeri az önce gördünüz: fonksiyon parametreleri.
@@ -133,29 +133,32 @@ Sadece `str` değil, tüm standart Python tiplerini bildirebilirsiniz.
* `bool`
* `bytes`
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
### Tip parametreleri ile Generic tipler { #generic-types-with-type-parameters }
### `typing` modülü { #typing-module }
`dict`, `list`, `set` ve `tuple` gibi, başka değerler içerebilen bazı veri yapıları vardır. Ve iç değerlerin kendi tipi de olabilir.
Bazı ek kullanım durumları için standart kütüphanedeki `typing` modülünden bazı şeyleri import etmeniz gerekebilir. Örneğin bir şeyin "herhangi bir tip" olabileceğini bildirmek istediğinizde, `typing` içindeki `Any`'yi kullanabilirsiniz:
İç tipleri olan bu tiplere "**generic**" tipler denir. Ve bunları, iç tipleriyle birlikte bildirmek mümkündür.
```python
from typing import Any
Bu tipleri ve iç tipleri bildirmek için standart Python modülü `typing`'i kullanabilirsiniz. Bu modül, özellikle bu type hints desteği için vardır.
#### Python'un daha yeni sürümleri { #newer-versions-of-python }
def some_function(data: Any):
print(data)
```
`typing` kullanan sözdizimi, Python 3.6'dan en yeni sürümlere kadar (Python 3.9, Python 3.10, vb. dahil) tüm sürümlerle **uyumludur**.
### Generic tipler { #generic-types }
Python geliştikçe, **daha yeni sürümler** bu type annotations için daha iyi destekle gelir ve çoğu durumda type annotations bildirmek için `typing` modülünü import edip kullanmanız bile gerekmez.
Bazı tipler, köşeli parantez içinde "type parameters" alarak iç tiplerini tanımlayabilir; örneğin "string listesi" `list[str]` olarak bildirilir.
Projeniz için daha yeni bir Python sürümü seçebiliyorsanız, bu ek sadelikten yararlanabilirsiniz.
Bu şekilde type parameter alabilen tiplere **Generic types** veya **Generics** denir.
Tüm dokümanlarda her Python sürümüyle uyumlu örnekler vardır (fark olduğunda).
Aynı builtin tipleri generics olarak kullanabilirsiniz (köşeli parantez ve içinde tiplerle):
Örneğin "**Python 3.6+**", Python 3.6 veya üstüyle (3.7, 3.8, 3.9, 3.10, vb. dahil) uyumludur. "**Python 3.9+**" ise Python 3.9 veya üstüyle (3.10 vb. dahil) uyumludur.
Eğer **Python'un en güncel sürümlerini** kullanabiliyorsanız, en güncel sürüme ait örnekleri kullanın; bunlar **en iyi ve en basit sözdizimine** sahip olur, örneğin "**Python 3.10+**".
* `list`
* `tuple`
* `set`
* `dict`
#### List { #list }
@@ -163,11 +166,11 @@ Eğer **Python'un en güncel sürümlerini** kullanabiliyorsanız, en güncel s
Değişkeni, aynı iki nokta (`:`) sözdizimiyle bildirin.
Type olarak `list` yazın.
Tip olarak `list` yazın.
`list`, bazı iç tipleri barındıran bir tip olduğundan, bunları köşeli parantez içine yazarsınız:
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
/// info | Bilgi
@@ -193,7 +196,7 @@ Ve yine de editör bunun bir `str` olduğunu bilir ve buna göre destek sağlar.
`tuple`'ları ve `set`'leri bildirmek için de aynısını yaparsınız:
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
Bu şu anlama gelir:
@@ -208,7 +211,7 @@ Bir `dict` tanımlamak için, virgülle ayrılmış 2 type parameter verirsiniz.
İkinci type parameter, `dict`'in value'ları içindir:
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
Bu şu anlama gelir:
@@ -220,44 +223,20 @@ Bu şu anlama gelir:
Bir değişkenin **birkaç tipten herhangi biri** olabileceğini bildirebilirsiniz; örneğin bir `int` veya bir `str`.
Python 3.6 ve üzeri sürümlerde (Python 3.10 dahil), `typing` içinden `Union` tipini kullanabilir ve köşeli parantez içine kabul edilecek olası tipleri yazabilirsiniz.
Bunu tanımlamak için, her iki tipi ayırmak üzere <dfn title='başka adıyla "bit düzeyinde veya operatörü", ancak burada o anlamı önemli değil'>dikey çizgi (`|`)</dfn> kullanırsınız.
Python 3.10'da ayrıca, olası tipleri <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> ile ayırabildiğiniz **yeni bir sözdizimi** de vardır.
//// tab | Python 3.10+
Buna "union" denir, çünkü değişken bu iki tip kümesinin birleşimindeki herhangi bir şey olabilir.
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
```
////
Her iki durumda da bu, `item`'ın `int` veya `str` olabileceği anlamına gelir.
Bu, `item`'ın `int` veya `str` olabileceği anlamına gelir.
#### Muhtemelen `None` { #possibly-none }
Bir değerin `str` gibi bir tipi olabileceğini ama aynı zamanda `None` da olabileceğini bildirebilirsiniz.
Python 3.6 ve üzeri sürümlerde (Python 3.10 dahil), `typing` modülünden `Optional` import edip kullanarak bunu bildirebilirsiniz.
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009_py39.py!}
```
Sadece `str` yerine `Optional[str]` kullanmak, aslında değer `None` olabilecekken her zaman `str` olduğunu varsaydığınız hataları editörün yakalamanıza yardımcı olmasını sağlar.
`Optional[Something]`, aslında `Union[Something, None]` için bir kısayoldur; eşdeğerdirler.
Bu aynı zamanda Python 3.10'da `Something | None` kullanabileceğiniz anlamına gelir:
//// tab | Python 3.10+
```Python hl_lines="1"
@@ -266,96 +245,7 @@ Bu aynı zamanda Python 3.10'da `Something | None` kullanabileceğiniz anlamına
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009_py39.py!}
```
////
//// tab | Python 3.9+ alternatif
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
```
////
#### `Union` veya `Optional` kullanmak { #using-union-or-optional }
Python sürümünüz 3.10'un altındaysa, benim oldukça **öznel** bakış açıma göre küçük bir ipucu:
* 🚨 `Optional[SomeType]` kullanmaktan kaçının
* Bunun yerine ✨ **`Union[SomeType, None]` kullanın** ✨.
İkisi eşdeğerdir ve altta aynı şeydir; ama ben `Optional` yerine `Union` önermeyi tercih ederim. Çünkü "**optional**" kelimesi değerin optional olduğunu ima ediyor gibi durur; ama gerçekte anlamı "değer `None` olabilir"dir. Değer optional olmasa ve hâlâ required olsa bile.
Bence `Union[SomeType, None]` ne anlama geldiğini daha açık şekilde ifade ediyor.
Bu, tamamen kelimeler ve isimlendirmelerle ilgili. Ancak bu kelimeler, sizin ve ekip arkadaşlarınızın kod hakkında nasıl düşündüğünü etkileyebilir.
Örnek olarak şu fonksiyonu ele alalım:
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
`name` parametresi `Optional[str]` olarak tanımlanmış, ama **optional değil**; parametre olmadan fonksiyonu çağıramazsınız:
```Python
say_hi() # Oh, no, this throws an error! 😱
```
`name` parametresi **hâlâ required**'dır (*optional* değildir) çünkü bir default değeri yoktur. Yine de `name`, değer olarak `None` kabul eder:
```Python
say_hi(name=None) # This works, None is valid 🎉
```
İyi haber şu ki, Python 3.10'a geçtiğinizde bununla uğraşmanız gerekmeyecek; çünkü tiplerin union'larını tanımlamak için doğrudan `|` kullanabileceksiniz:
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
Ve böylece `Optional` ve `Union` gibi isimlerle de uğraşmanız gerekmeyecek. 😎
#### Generic tipler { #generic-types }
Köşeli parantez içinde type parameter alan bu tiplere **Generic types** veya **Generics** denir, örneğin:
//// tab | Python 3.10+
Aynı builtin tipleri generics olarak kullanabilirsiniz (köşeli parantez ve içindeki tiplerle):
* `list`
* `tuple`
* `set`
* `dict`
Ve önceki Python sürümlerinde olduğu gibi `typing` modülünden:
* `Union`
* `Optional`
* ...and others.
Python 3.10'da, `Union` ve `Optional` generics'lerini kullanmaya alternatif olarak, tip union'larını bildirmek için <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> kullanabilirsiniz; bu çok daha iyi ve daha basittir.
////
//// tab | Python 3.9+
Aynı builtin tipleri generics olarak kullanabilirsiniz (köşeli parantez ve içindeki tiplerle):
* `list`
* `tuple`
* `set`
* `dict`
Ve `typing` modülünden gelen generics:
* `Union`
* `Optional`
* ...and others.
////
Sadece `str` yerine `str | None` kullanmak, aslında değer `None` olabilecekken her zaman `str` olduğunu varsaydığınız hataları editörün yakalamanıza yardımcı olur.
### Tip olarak sınıflar { #classes-as-types }
@@ -363,11 +253,11 @@ Bir sınıfı da bir değişkenin tipi olarak bildirebilirsiniz.
Örneğin, adı olan bir `Person` sınıfınız olsun:
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
Sonra bir değişkeni `Person` tipinde olacak şekilde bildirebilirsiniz:
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
Ve sonra, yine tüm editör desteğini alırsınız:
@@ -401,21 +291,15 @@ Daha fazlasını öğrenmek için <a href="https://docs.pydantic.dev/" class="ex
**FastAPI** tamamen Pydantic üzerine kuruludur.
Bunların pratikte nasıl çalıştığını [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank} içinde çok daha fazla göreceksiniz.
/// tip | İpucu
Pydantic, default value olmadan `Optional` veya `Union[Something, None]` kullandığınızda özel bir davranışa sahiptir; bununla ilgili daha fazla bilgiyi Pydantic dokümanlarında <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a> bölümünde okuyabilirsiniz.
///
Bunların pratikte nasıl çalıştığını [Eğitim - Kullanım Kılavuzu](tutorial/index.md){.internal-link target=_blank} içinde çok daha fazla göreceksiniz.
## Metadata Annotations ile Type Hints { #type-hints-with-metadata-annotations }
Python'da ayrıca, `Annotated` kullanarak bu type hints içine **ek <abbr title="Veri hakkında veri; bu durumda type hakkında bilgi, örneğin bir açıklama.">metadata</abbr>** koymayı sağlayan bir özellik de vardır.
Python'da ayrıca, `Annotated` kullanarak bu type hints içine **ek <dfn title="Veri hakkında veri; bu durumda tip hakkında bilgi, örneğin bir açıklama.">üstveri</dfn>** koymayı sağlayan bir özellik de vardır.
Python 3.9'dan itibaren `Annotated`, standart kütüphanenin bir parçasıdır; bu yüzden `typing` içinden import edebilirsiniz.
`Annotated`'ı `typing` içinden import edebilirsiniz.
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
Python'un kendisi bu `Annotated` ile bir şey yapmaz. Editörler ve diğer araçlar için tip hâlâ `str`'dir.
@@ -446,14 +330,14 @@ Ayrıca kodunuzun pek çok başka Python aracı ve kütüphanesiyle çok uyumlu
...ve **FastAPI** aynı bildirimleri şunlar için de kullanır:
* **Gereksinimleri tanımlamak**: request path parameters, query parameters, headers, bodies, dependencies, vb.
* **Gereksinimleri tanımlamak**: request path parameters, query parameters, headers, bodies, bağımlılıklar (dependencies), vb.
* **Veriyi dönüştürmek**: request'ten gerekli tipe.
* **Veriyi doğrulamak**: her request'ten gelen veriyi:
* Veri geçersiz olduğunda client'a dönen **otomatik hatalar** üretmek.
* OpenAPI kullanarak API'yi **dokümante etmek**:
* bu, daha sonra otomatik etkileşimli dokümantasyon kullanıcı arayüzleri tarafından kullanılır.
Bunların hepsi kulağa soyut gelebilir. Merak etmeyin. Tüm bunları [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank} içinde çalışırken göreceksiniz.
Bunların hepsi kulağa soyut gelebilir. Merak etmeyin. Tüm bunları [Eğitim - Kullanım Kılavuzu](tutorial/index.md){.internal-link target=_blank} içinde çalışırken göreceksiniz.
Önemli olan, standart Python tiplerini tek bir yerde kullanarak (daha fazla sınıf, decorator vb. eklemek yerine), **FastAPI**'nin sizin için işin büyük kısmını yapmasıdır.

View File

@@ -4,7 +4,7 @@ Bu çeviri, insanlar tarafından yönlendirilen bir yapay zekâ ile oluşturuldu
Orijinal anlamın yanlış anlaşılması ya da kulağa doğal gelmeme gibi hatalar içerebilir. 🤖
[Yapay zekâyı daha iyi yönlendirmemize yardımcı olarak](https://fastapi.tiangolo.com/tr/contributing/#translations) bu çeviriyi iyileştirebilirsiniz.
[Yapay zekâ LLM'ini daha iyi yönlendirmemize yardımcı olarak](https://fastapi.tiangolo.com/tr/contributing/#translations) bu çeviriyi iyileştirebilirsiniz.
[İngilizce sürüm](ENGLISH_VERSION_URL)

View File

@@ -15,7 +15,7 @@ Bu, requestten sonra yapılması gereken; ancak clientın responseu alm
Önce `BackgroundTasks`i import edin ve *path operation function*ınızda `BackgroundTasks` tip bildirimi olan bir parametre tanımlayın:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
**FastAPI**, sizin için `BackgroundTasks` tipinde bir obje oluşturur ve onu ilgili parametre olarak geçirir.
@@ -31,13 +31,13 @@ Bu örnekte görev fonksiyonu bir dosyaya yazacaktır (email göndermeyi simüle
Ve yazma işlemi `async` ve `await` kullanmadığı için fonksiyonu normal `def` ile tanımlarız:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
## Arka Plan Görevini Ekleyin { #add-the-background-task }
*Path operation function*ınızın içinde, görev fonksiyonunuzu `.add_task()` metodu ile *background tasks* objesine ekleyin:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
`.add_task()` şu argümanları alır:

View File

@@ -85,7 +85,7 @@ Bu module için *path operation*ları `APIRouter` kullanarak oluşturabilirsi
`FastAPI` classında yaptığınız gibi import edip bir "instance" oluşturursunuz:
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### `APIRouter` ile *Path Operations* { #path-operations-with-apirouter }
@@ -93,7 +93,7 @@ Sonra bunu kullanarak *path operation*larınızı tanımlarsınız.
`FastAPI` classını nasıl kullanıyorsanız aynı şekilde kullanın:
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
`APIRouter`ı "mini bir `FastAPI`" classı gibi düşünebilirsiniz.
@@ -117,7 +117,7 @@ Bu yüzden onları ayrı bir `dependencies` moduleüne koyuyoruz (`app/depend
Şimdi, özel bir `X-Token` header'ını okumak için basit bir dependency kullanalım:
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip | İpucu
@@ -149,7 +149,7 @@ Bu moduledeki tüm *path operation*ların şu ortak özelliklere sahip old
Dolayısıyla bunları her *path operation*a tek tek eklemek yerine `APIRouter`a ekleyebiliriz.
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
Her *path operation*ın pathi aşağıdaki gibi `/` ile başlamak zorunda olduğundan:
@@ -208,7 +208,7 @@ Dependency functionını ise `app.dependencies` moduleünden, yani `app/de
Bu yüzden dependencyler için `..` ile relative import kullanıyoruz:
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
#### Relative Import Nasıl Çalışır { #how-relative-imports-work }
@@ -279,7 +279,7 @@ Artık nasıl çalıştığını bildiğinize göre, uygulamalarınız ne kadar
Ama yine de belirli bir *path operation*a uygulanacak _ek_ `tags` tanımlayabilir, ayrıca o *path operation*a özel `responses` ekleyebiliriz:
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip | İpucu
@@ -305,13 +305,13 @@ Normal şekilde bir `FastAPI` classı oluşturursunuz.
Hatta her `APIRouter` için olan dependencylerle birleştirilecek [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} bile tanımlayabilirsiniz:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
### `APIRouter` Import Edin { #import-the-apirouter }
Şimdi `APIRouter` içeren diğer submoduleleri import ediyoruz:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
`app/routers/users.py` ve `app/routers/items.py` dosyaları aynı Python packagei olan `app`in parçası olan submoduleler olduğu için, onları "relative import" ile tek bir nokta `.` kullanarak import edebiliriz.
@@ -374,13 +374,13 @@ from .routers.users import router
Bu yüzden ikisini de aynı dosyada kullanabilmek için submoduleleri doğrudan import ediyoruz:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
### `users` ve `items` için `APIRouter`ları Dahil Edin { #include-the-apirouters-for-users-and-items }
Şimdi `users` ve `items` submodulelerindeki `router`ları dahil edelim:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
/// info | Bilgi
@@ -420,13 +420,13 @@ Bu dosyada, kurumunuzun birden fazla proje arasında paylaştığı bazı admin
Bu örnekte çok basit olacak. Ancak kurum içinde başka projelerle paylaşıldığı için, bunu değiştirip `prefix`, `dependencies`, `tags` vs. doğrudan `APIRouter`a ekleyemediğimizi varsayalım:
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
Yine de bu `APIRouter`ı dahil ederken özel bir `prefix` ayarlamak istiyoruz ki tüm *path operation*ları `/admin` ile başlasın; ayrıca bu projede hâlihazırda kullandığımız `dependencies` ile güvene almak, `tags` ve `responses` eklemek istiyoruz.
Orijinal `APIRouter`ı değiştirmeden, bu parametreleri `app.include_router()`a vererek hepsini tanımlayabiliriz:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
Böylece orijinal `APIRouter` değişmeden kalır; yani aynı `app/internal/admin.py` dosyasını kurum içindeki diğer projelerle de paylaşmaya devam edebiliriz.
@@ -447,7 +447,7 @@ Dolayısıyla örneğin diğer projeler aynı `APIRouter`ı farklı bir authe
Burada bunu yapıyoruz... sadece yapabildiğimizi göstermek için 🤷:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
ve `app.include_router()` ile eklenen diğer tüm *path operation*larla birlikte doğru şekilde çalışır.

View File

@@ -106,12 +106,6 @@ Varsayılan olarak tekil değerler query parametresi olarak yorumlandığı içi
q: str | None = None
```
Ya da Python 3.9'da:
```Python
q: Union[str, None] = None
```
Örneğin:
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}

View File

@@ -95,7 +95,7 @@ Yine, sadece bu tanımı yaparak **FastAPI** ile şunları elde edersiniz:
`str`, `int`, `float` vb. normal tekil tiplerin yanında, `str`den türeyen daha karmaşık tekil tipleri de kullanabilirsiniz.
Tüm seçenekleri görmek için <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Pydantic Type Overview</a> sayfasına göz atın. Sonraki bölümde bazı örnekleri göreceksiniz.
Tüm seçenekleri görmek için <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Pydantic Türlerine Genel Bakış</a> sayfasına göz atın. Sonraki bölümde bazı örnekleri göreceksiniz.
Örneğin `Image` modelinde bir `url` alanımız olduğuna göre, bunu `str` yerine Pydanticin `HttpUrl` tipinden bir instance olacak şekilde tanımlayabiliriz:
@@ -163,7 +163,7 @@ images: list[Image]
şu örnekte olduğu gibi:
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
## Her yerde editör desteği { #editor-support-everywhere }
@@ -193,7 +193,7 @@ Burada göreceğimiz şey de bu.
Bu durumda, `int` keylere ve `float` valuelara sahip olduğu sürece herhangi bir `dict` kabul edersiniz:
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
/// tip | İpucu

View File

@@ -155,7 +155,7 @@ Fonksiyon parametreleri şu şekilde tanınır:
FastAPI, `q` değerinin zorunlu olmadığını `= None` default değerinden anlayacaktır.
`str | None` (Python 3.10+) veya `Union[str, None]` (Python 3.9+) içindeki `Union`, FastAPI tarafından bu değerin zorunlu olmadığını belirlemek için kullanılmaz; FastAPI bunun zorunlu olmadığını `= None` default değeri olduğu için bilir.
`str | None`, FastAPI tarafından bu değerin zorunlu olmadığını belirlemek için kullanılmaz; FastAPI bunun zorunlu olmadığını `= None` default değeri olduğu için bilir.
Ancak type annotation'larını eklemek, editor'ünüzün size daha iyi destek vermesini ve hataları yakalamasını sağlar.

View File

@@ -1,18 +1,18 @@
# Cookie Parameter Models { #cookie-parameter-models }
# Cookie Parametre Modelleri { #cookie-parameter-models }
Birbirleriyle ilişkili bir **cookie** grubunuz varsa, bunları tanımlamak için bir **Pydantic model** oluşturabilirsiniz.
Birbirleriyle ilişkili bir **cookie** grubunuz varsa, bunları tanımlamak için bir **Pydantic model** oluşturabilirsiniz. 🍪
Bu sayede **model'i yeniden kullanabilir**, **birden fazla yerde** tekrar tekrar kullanabilir ve tüm parametreler için validation ve metadata'yı tek seferde tanımlayabilirsiniz.
Bu sayede **model'i yeniden kullanabilir**, **birden fazla yerde** tekrar tekrar kullanabilir ve tüm parametreler için validation ve metadata'yı tek seferde tanımlayabilirsiniz. 😎
/// note | Not
Bu özellik FastAPI `0.115.0` sürümünden beri desteklenmektedir.
This is supported since FastAPI version `0.115.0`. 🤓
///
/// tip | İpucu
Aynı teknik `Query`, `Cookie` ve `Header` için de geçerlidir.
Aynı teknik `Query`, `Cookie` ve `Header` için de geçerlidir. 😎
///
@@ -42,11 +42,11 @@ Ancak verileri **doldurup** "Execute" düğmesine tıklasanız bile, docs UI **J
///
## Fazladan Cookies'leri Yasaklayın { #forbid-extra-cookies }
## Fazladan Cookie'leri Yasaklayın { #forbid-extra-cookies }
Bazı özel kullanım senaryolarında (muhtemelen çok yaygın değildir) almak istediğiniz cookie'leri **kısıtlamak** isteyebilirsiniz.
API'niz artık kendi <abbr title="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</abbr>'ını kontrol etme gücüne sahip.
API'niz artık kendi <dfn title="Bu bir şaka, sadece bilginize. Cookie onaylarıyla ilgisi yok, ama API'nin de artık zavallı cookie'leri reddedebilmesi komik. Bir cookie alın. 🍪">cookie onayı</dfn>'nı kontrol etme gücüne sahip. 🤪🍪
Pydantic'in model configuration'ını kullanarak `extra` olan herhangi bir field'ı `forbid` edebilirsiniz:
@@ -54,9 +54,9 @@ Pydantic'in model configuration'ını kullanarak `extra` olan herhangi bir field
Bir client **fazladan cookie** göndermeye çalışırsa, bir **error** response alır.
Onayınızı almak için bunca çaba harcayan zavallı cookie banner'ları... <abbr title="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API'nin bunu reddetmesi için</abbr>.
Onayınızı almak için bunca çaba harcayan zavallı cookie banner'ları... <dfn title="Bu da başka bir şaka. Dikkate almayın. Cookie'niz için biraz kahve alın. ☕">API'nin bunu reddetmesi için</dfn>. 🍪
Örneğin client, değeri `good-list-please` olan bir `santa_tracker` cookie'si göndermeye çalışırsa, client `santa_tracker` <abbr title="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">cookie is not allowed</abbr> diyen bir **error** response alır:
Örneğin client, değeri `good-list-please` olan bir `santa_tracker` cookie'si göndermeye çalışırsa, client `santa_tracker` <dfn title="Noel Baba cookie eksikliğini onaylamıyor. 🎅 Tamam, artık cookie şakası yok.">cookie'ye izin verilmiyor</dfn> diyen bir **error** response alır:
```json
{
@@ -73,4 +73,4 @@ Onayınızı almak için bunca çaba harcayan zavallı cookie banner'ları... <a
## Özet { #summary }
**FastAPI**'de <abbr title="Have a last cookie before you go. 🍪">**cookies**</abbr> tanımlamak için **Pydantic model**'lerini kullanabilirsiniz. 😎
**FastAPI**'de <dfn title="Gitmeden önce son bir cookie alın. 🍪">**cookie**</dfn> tanımlamak için **Pydantic model**'lerini kullanabilirsiniz. 😎

View File

@@ -1,4 +1,4 @@
# Çerez (Cookie) Parametreleri { #cookie-parameters }
# Cookie (Çerez) Parametreleri { #cookie-parameters }
`Query` ve `Path` parametrelerini tanımladığınız şekilde Cookie parametreleri tanımlayabilirsiniz.
@@ -26,20 +26,20 @@ Ancak `fastapi`'dan `Query`, `Path`, `Cookie` ve diğerlerini import ettiğinizd
/// info | Bilgi
Çerezleri tanımlamak için `Cookie` kullanmanız gerekir, aksi halde parametreler query parametreleri olarak yorumlanır.
Cookie'leri tanımlamak için `Cookie` kullanmanız gerekir, aksi halde parametreler query parametreleri olarak yorumlanır.
///
/// info | Bilgi
**Tarayıcılar çerezleri** özel şekillerde ve arka planda işlediği için, **JavaScript**'in onlara dokunmasına kolayca izin **vermezler**.
**Tarayıcılar cookie'leri** özel şekillerde ve arka planda işlediği için, **JavaScript**'in onlara dokunmasına kolayca izin **vermezler**.
`/docs` adresindeki **API docs UI**'a giderseniz, *path operation*'larınız için çerezlerin **dokümantasyonunu** görebilirsiniz.
`/docs` adresindeki **API docs UI**'a giderseniz, *path operation*'larınız için cookie'lerin **dokümantasyonunu** görebilirsiniz.
Ancak **veriyi doldurup** "Execute" düğmesine tıklasanız bile, docs UI **JavaScript** ile çalıştığı için çerezler gönderilmez ve herhangi bir değer yazmamışsınız gibi bir **hata** mesajı görürsünüz.
Ancak **veriyi doldurup** "Execute" düğmesine tıklasanız bile, docs UI **JavaScript** ile çalıştığı için cookie'ler gönderilmez ve herhangi bir değer yazmamışsınız gibi bir **hata** mesajı görürsünüz.
///
## Özet { #recap }
`Query` ve `Path` ile aynı ortak deseni kullanarak, çerezleri `Cookie` ile tanımlayın.
`Query` ve `Path` ile aynı ortak deseni kullanarak, cookie'leri `Cookie` ile tanımlayın.

View File

@@ -46,7 +46,7 @@ Ayrıca backendin şunlara izin verip vermediğini de belirtebilirsiniz:
* Belirli HTTP methodları (`POST`, `PUT`) veya wildcard `"*"` ile hepsini.
* Belirli HTTP headerları veya wildcard `"*"` ile hepsini.
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
`CORSMiddleware` implementasyonu tarafından kullanılan varsayılan parametreler kısıtlayıcıdır; bu nedenle tarayıcıların Cross-Domain bağlamında kullanmasına izin vermek için belirli originleri, methodları veya headerlarııkça etkinleştirmeniz gerekir.
@@ -78,7 +78,7 @@ Bu durumda middleware gelen requesti intercept eder ve uygun CORS headerla
## Daha Fazla Bilgi { #more-info }
<abbr title="Cross-Origin Resource Sharing">CORS</abbr> hakkında daha fazla bilgi için <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS dokümantasyonu</a>na bakın.
<abbr title="Cross-Origin Resource Sharing - Kökenler Arası Kaynak Paylaşımı">CORS</abbr> hakkında daha fazla bilgi için <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS dokümantasyonu</a>na bakın.
/// note | Teknik Detaylar

View File

@@ -6,7 +6,7 @@ Visual Studio Code veya PyCharm gibi editörünüzde debugger'ı bağlayabilirsi
FastAPI uygulamanızda `uvicorn`'ı import edip doğrudan çalıştırın:
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
### `__name__ == "__main__"` Hakkında { #about-name-main }

View File

@@ -101,7 +101,7 @@ Artık bu class'ı kullanarak dependency'nizi tanımlayabilirsiniz.
Yukarıdaki kodda `CommonQueryParams`'ı iki kez yazdığımıza dikkat edin:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ Annotated Olmadan
//// tab | Python 3.10+ Annotated Olmadan
/// tip | İpucu
@@ -137,7 +137,7 @@ FastAPI tanımlanan parametreleri buradan çıkarır ve aslında çağıracağı
Bu durumda, şuradaki ilk `CommonQueryParams`:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
////
//// tab | Python 3.9+ Annotated Olmadan
//// tab | Python 3.10+ Annotated Olmadan
/// tip | İpucu
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
Hatta şunu bile yazabilirsiniz:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ Annotated Olmadan
//// tab | Python 3.10+ Annotated Olmadan
/// tip | İpucu
@@ -197,7 +197,7 @@ Ancak type'ı belirtmeniz önerilir; böylece editor'ünüz `commons` parametres
Ama burada bir miktar kod tekrarımız olduğunu görüyorsunuz; `CommonQueryParams`'ı iki kez yazıyoruz:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ Annotated Olmadan
//// tab | Python 3.10+ Annotated Olmadan
/// tip | İpucu
@@ -225,7 +225,7 @@ Bu özel durumlarda şunu yapabilirsiniz:
Şunu yazmak yerine:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ Annotated Olmadan
//// tab | Python 3.10+ Annotated Olmadan
/// tip | İpucu
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
...şunu yazarsınız:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
////
//// tab | Python 3.9+ Annotated Olmadan
//// tab | Python 3.10+ Annotated Olmadan
/// tip | İpucu

View File

@@ -14,7 +14,7 @@ Bu gibi durumlarda, `Depends` ile bir *path operation function* parametresi tan
Bu, `Depends()` öğelerinden oluşan bir `list` olmalıdır:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
Bu dependency'ler normal dependency'lerle aynı şekilde çalıştırılır/çözülür. Ancak (eğer bir değer döndürüyorlarsa) bu değer *path operation function*'ınıza aktarılmaz.
@@ -44,13 +44,13 @@ Normalde kullandığınız aynı dependency *function*'larını burada da kullan
Request gereksinimleri (header'lar gibi) veya başka alt dependency'ler tanımlayabilirler:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
### Exception Fırlatmak { #raise-exceptions }
Bu dependency'ler, normal dependency'lerde olduğu gibi `raise` ile exception fırlatabilir:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
### Return Değerleri { #return-values }
@@ -58,7 +58,7 @@ Ayrıca değer döndürebilirler ya da döndürmeyebilirler; dönen değer kulla
Yani başka bir yerde zaten kullandığınız, değer döndüren normal bir dependency'yi tekrar kullanabilirsiniz; değer kullanılmasa bile dependency çalıştırılacaktır:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
## Bir *Path Operation* Grubu İçin Dependency'ler { #dependencies-for-a-group-of-path-operations }

View File

@@ -1,12 +1,12 @@
# `yield` ile Dependency'ler { #dependencies-with-yield }
FastAPI, işini bitirdikten sonra <abbr title='bazen "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code" vb. olarak da adlandırılır'>ek adımlar çalıştıran</abbr> dependency'leri destekler.
FastAPI, işini bitirdikten sonra <dfn title='bazen "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code" vb. olarak da adlandırılır'>ek adımlar</dfn> çalıştıran dependency'leri destekler.
Bunu yapmak için `return` yerine `yield` kullanın ve ek adımları (kodu) `yield` satırından sonra yazın.
/// tip | İpucu
Her dependency için yalnızca **bir kez** `yield` kullandığınızdan emin olun.
Her dependency için yalnızca bir kez `yield` kullandığınızdan emin olun.
///
@@ -29,15 +29,15 @@ Hatta FastAPI bu iki decorator'ı içeride (internally) kullanır.
Response oluşturulmadan önce yalnızca `yield` satırına kadar olan (ve `yield` dahil) kod çalıştırılır:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
`yield` edilen değer, *path operation*'lara ve diğer dependency'lere enjekte edilen (injected) değerdir:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
Response'dan sonra `yield` satırını takip eden kod çalıştırılır:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
/// tip | İpucu
@@ -57,7 +57,7 @@ Dolayısıyla `except SomeException` ile dependency içinde o spesifik exception
Aynı şekilde, exception olsun ya da olmasın çıkış (exit) adımlarının çalıştırılmasını garanti etmek için `finally` kullanabilirsiniz.
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
## `yield` ile Alt Dependency'ler { #sub-dependencies-with-yield }
@@ -67,7 +67,7 @@ Her boyutta ve şekilde alt dependency'ler ve alt dependency "ağaçları" (tree
Örneğin, `dependency_c`, `dependency_b`'ye; `dependency_b` de `dependency_a`'ya bağlı olabilir:
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
Ve hepsi `yield` kullanabilir.
@@ -75,7 +75,7 @@ Bu durumda `dependency_c`, exit code'unu çalıştırabilmek için `dependency_b
Aynı şekilde `dependency_b` de exit code'u için `dependency_a`'dan gelen değerin (burada `dep_a`) erişilebilir olmasına ihtiyaç duyar.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
Benzer şekilde, bazı dependency'ler `yield`, bazıları `return` kullanabilir ve bunların bazıları diğerlerine bağlı olabilir.
@@ -109,7 +109,7 @@ Ama ihtiyaç duyarsanız diye burada. 🤓
///
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
Exception yakalayıp buna göre özel bir response oluşturmak istiyorsanız bir [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} oluşturun.
@@ -117,7 +117,7 @@ Exception yakalayıp buna göre özel bir response oluşturmak istiyorsanız bir
`yield` kullanan bir dependency içinde `except` ile bir exception yakalar ve bunu tekrar fırlatmazsanız (ya da yeni bir exception fırlatmazsanız), FastAPI normal Python'da olduğu gibi bir exception olduğunu fark edemez:
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
Bu durumda client, biz `HTTPException` veya benzeri bir şey fırlatmadığımız için olması gerektiği gibi *HTTP 500 Internal Server Error* response'u görür; ancak server **hiç log üretmez** ve hatanın ne olduğuna dair başka bir işaret de olmaz. 😱
@@ -127,7 +127,7 @@ Bu durumda client, biz `HTTPException` veya benzeri bir şey fırlatmadığımı
Aynı exception'ı `raise` ile tekrar fırlatabilirsiniz:
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
Artık client yine aynı *HTTP 500 Internal Server Error* response'unu alır, ama server log'larda bizim özel `InternalError`'ımızı görür. 😎
@@ -190,7 +190,7 @@ Normalde `yield` kullanan dependency'lerin exit code'u, client'a response gönde
Ama *path operation function*'dan döndükten sonra dependency'yi kullanmayacağınızı biliyorsanız, `Depends(scope="function")` kullanarak FastAPI'ye dependency'yi *path operation function* döndükten sonra kapatmasını, ancak **response gönderilmeden önce** kapatmasını söyleyebilirsiniz.
{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
`Depends()` şu değerleri alabilen bir `scope` parametresi alır:
@@ -234,7 +234,6 @@ participant operation as Path Operation
`yield` kullanan dependency'ler, zaman içinde farklı kullanım senaryolarını kapsamak ve bazı sorunları düzeltmek için gelişti.
FastAPI'nin farklı sürümlerinde nelerin değiştiğini görmek isterseniz, advanced guide'da şu bölümü okuyabilirsiniz: [Advanced Dependencies - Dependencies with `yield`, `HTTPException`, `except` and Background Tasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
## Context Managers { #context-managers }
### "Context Managers" Nedir? { #what-are-context-managers }
@@ -269,7 +268,7 @@ Python'da Context Manager'ları, <a href="https://docs.python.org/3/reference/da
Ayrıca dependency fonksiyonunun içinde `with` veya `async with` ifadeleri kullanarak **FastAPI**'de `yield` kullanan dependency'lerin içinde de kullanabilirsiniz:
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
/// tip | İpucu

View File

@@ -6,7 +6,7 @@ Bazı uygulama türlerinde, tüm uygulama için dependency eklemek isteyebilirsi
Bu durumda, uygulamadaki tüm *path operation*'lara uygulanırlar:
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
Ve [*path operation decorator*'larına `dependencies` ekleme](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} bölümündeki tüm fikirler hâlâ geçerlidir; ancak bu sefer, uygulamadaki tüm *path operation*'lar için geçerli olur.

View File

@@ -1,6 +1,6 @@
# Bağımlılıklar { #dependencies }
**FastAPI**, çok güçlü ama aynı zamanda sezgisel bir **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** sistemine sahiptir.
**FastAPI**, çok güçlü ama aynı zamanda sezgisel bir **<dfn title="diğer adları: components, resources, providers, services, injectables">Bağımlılık Enjeksiyonu</dfn>** sistemine sahiptir.
Kullanımı çok basit olacak şekilde tasarlanmıştır ve herhangi bir geliştiricinin diğer bileşenleri **FastAPI** ile entegre etmesini kolaylaştırır.

View File

@@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
Bağımlılıklarınızdan biri aynı *path operation* için birden fazla kez tanımlanırsa (örneğin birden fazla bağımlılığın ortak bir alt bağımlılığı varsa), **FastAPI** o alt bağımlılığı request başına yalnızca bir kez çağıracağını bilir.
Dönen değeri bir <abbr title="A utility/system to store computed/generated values, to reuse them instead of computing them again. - Hesaplanan/üretilen değerleri saklayıp, onları tekrar hesaplamak yerine yeniden kullanmayı sağlayan bir yardımcı araç/sistem.">"cache"</abbr> içinde saklar ve aynı request içinde buna ihtiyaç duyan tüm "dependant"lara aktarır; böylece aynı request için bağımlılığı tekrar tekrar çağırmaz.
Dönen değeri bir <dfn title="Hesaplanan/üretilen değerleri saklayıp, tekrar hesaplamak yerine yeniden kullanmayı sağlayan bir yardımcı araç/sistem.">"önbellek"</dfn> içinde saklar ve aynı request içinde buna ihtiyaç duyan tüm "dependant"lara aktarır; böylece aynı request için bağımlılığı tekrar tekrar çağırmaz.
Daha ileri bir senaryoda, "cached" değeri kullanmak yerine aynı request içinde her adımda (muhtemelen birden fazla kez) bağımlılığın çağrılması gerektiğini biliyorsanız, `Depends` kullanırken `use_cache=False` parametresini ayarlayabilirsiniz:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python hl_lines="1"
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
////
//// tab | Python 3.9+ Annotated olmayan
//// tab | Python 3.10+ Annotated olmayan
/// tip | İpucu

View File

@@ -23,32 +23,32 @@ Kullanabileceğiniz ek veri tiplerinden bazıları şunlardır:
* `UUID`:
* Birçok veritabanı ve sistemde ID olarak yaygın kullanılan, standart bir "Universally Unique Identifier".
* request ve response'larda `str` olarak temsil edilir.
* request'lerde ve response'larda `str` olarak temsil edilir.
* `datetime.datetime`:
* Python `datetime.datetime`.
* request ve response'larda ISO 8601 formatında bir `str` olarak temsil edilir, örn: `2008-09-15T15:53:00+05:00`.
* request'lerde ve response'larda ISO 8601 formatında bir `str` olarak temsil edilir, örn: `2008-09-15T15:53:00+05:00`.
* `datetime.date`:
* Python `datetime.date`.
* request ve response'larda ISO 8601 formatında bir `str` olarak temsil edilir, örn: `2008-09-15`.
* request'lerde ve response'larda ISO 8601 formatında bir `str` olarak temsil edilir, örn: `2008-09-15`.
* `datetime.time`:
* Python `datetime.time`.
* request ve response'larda ISO 8601 formatında bir `str` olarak temsil edilir, örn: `14:23:55.003`.
* request'lerde ve response'larda ISO 8601 formatında bir `str` olarak temsil edilir, örn: `14:23:55.003`.
* `datetime.timedelta`:
* Python `datetime.timedelta`.
* request ve response'larda toplam saniye sayısını ifade eden bir `float` olarak temsil edilir.
* request'lerde ve response'larda toplam saniye sayısını ifade eden bir `float` olarak temsil edilir.
* Pydantic, bunu ayrıca bir "ISO 8601 time diff encoding" olarak temsil etmeye de izin verir, daha fazla bilgi için <a href="https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers" class="external-link" target="_blank">dokümanlara bakın</a>.
* `frozenset`:
* request ve response'larda, `set` ile aynı şekilde ele alınır:
* request'lerde ve response'larda, `set` ile aynı şekilde ele alınır:
* request'lerde bir list okunur, tekrarlar kaldırılır ve `set`'e dönüştürülür.
* response'larda `set`, `list`'e dönüştürülür.
* Üretilen schema, `set` değerlerinin benzersiz olduğunu belirtir (JSON Schema'nın `uniqueItems` özelliğini kullanarak).
* `bytes`:
* Standart Python `bytes`.
* request ve response'larda `str` gibi ele alınır.
* request'lerde ve response'larda `str` gibi ele alınır.
* Üretilen schema, bunun `binary` "format"ına sahip bir `str` olduğunu belirtir.
* `Decimal`:
* Standart Python `Decimal`.
* request ve response'larda `float` ile aynı şekilde işlenir.
* request'lerde ve response'larda `float` ile aynı şekilde işlenir.
* Geçerli tüm Pydantic veri tiplerini burada görebilirsiniz: <a href="https://docs.pydantic.dev/latest/usage/types/types/" class="external-link" target="_blank">Pydantic data types</a>.
## Örnek { #example }

View File

@@ -8,7 +8,7 @@ Bu durum özellikle kullanıcı modellerinde sık görülür, çünkü:
* **output modeli** `password` içermemelidir.
* **database modeli** büyük ihtimalle hash'lenmiş bir `password` tutmalıdır.
/// danger
/// danger | Tehlike
Kullanıcının düz metin (plaintext) `password`'ünü asla saklamayın. Her zaman sonradan doğrulayabileceğiniz "güvenli bir hash" saklayın.
@@ -132,7 +132,7 @@ UserInDB(
)
```
/// warning
/// warning | Uyarı
Ek destek fonksiyonları olan `fake_password_hasher` ve `fake_save_user` sadece verinin olası bir akışını göstermek içindir; elbette gerçek bir güvenlik sağlamazlar.
@@ -164,7 +164,7 @@ OpenAPI'de bu `anyOf` ile tanımlanır.
Bunu yapmak için standart Python type hint'i olan <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>'ı kullanın:
/// note
/// note | Not
Bir <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a> tanımlarken en spesifik type'ı önce, daha az spesifik olanı sonra ekleyin. Aşağıdaki örnekte daha spesifik olan `PlaneItem`, `Union[PlaneItem, CarItem]` içinde `CarItem`'dan önce gelir.
@@ -190,9 +190,9 @@ Ancak bunu `response_model=PlaneItem | CarItem` atamasına koyarsak hata alırı
Aynı şekilde, nesne listesi döndüren response'ları da tanımlayabilirsiniz.
Bunun için standart Python `typing.List`'i (ya da Python 3.9 ve üzeri için sadece `list`) kullanın:
Bunun için standart Python `list`'i kullanın:
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
## Rastgele `dict` ile Response { #response-with-arbitrary-dict }
@@ -200,9 +200,9 @@ Bir Pydantic modeli kullanmadan, sadece key ve value type'larını belirterek d
Bu, geçerli field/attribute adlarını (Pydantic modeli için gerekli olurdu) önceden bilmiyorsanız kullanışlıdır.
Bu durumda `typing.Dict` (ya da Python 3.9 ve üzeri için sadece `dict`) kullanabilirsiniz:
Bu durumda `dict` kullanabilirsiniz:
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
## Özet { #recap }

View File

@@ -2,7 +2,7 @@
En sade FastAPI dosyası şu şekilde görünür:
{* ../../docs_src/first_steps/tutorial001_py39.py *}
{* ../../docs_src/first_steps/tutorial001_py310.py *}
Yukarıdakini `main.py` adlı bir dosyaya kopyalayın.
@@ -183,7 +183,7 @@ Bu kadar! Artık uygulamanıza o URL üzerinden erişebilirsiniz. ✨
### Adım 1: `FastAPI` import edin { #step-1-import-fastapi }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
`FastAPI`, API'nız için tüm işlevselliği sağlayan bir Python class'ıdır.
@@ -197,7 +197,7 @@ Bu kadar! Artık uygulamanıza o URL üzerinden erişebilirsiniz. ✨
### Adım 2: bir `FastAPI` "instance"ı oluşturun { #step-2-create-a-fastapi-instance }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
Burada `app` değişkeni `FastAPI` class'ının bir "instance"ı olacaktır.
@@ -266,12 +266,12 @@ Biz de bunlara "**operation**" diyeceğiz.
#### Bir *path operation decorator* tanımlayın { #define-a-path-operation-decorator }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
`@app.get("/")`, **FastAPI**'a hemen altındaki fonksiyonun şuraya giden request'leri ele almakla sorumlu olduğunu söyler:
* path `/`
* <abbr title="bir HTTP GET method'u"><code>get</code> operation</abbr> kullanarak
* <dfn title="bir HTTP GET methodu"><code>get</code> operation</dfn> kullanarak
/// info | `@decorator` Bilgisi
@@ -320,7 +320,7 @@ Bu bizim "**path operation function**"ımız:
* **operation**: `get`.
* **function**: "decorator"ün altındaki fonksiyondur (`@app.get("/")`'in altındaki).
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
Bu bir Python fonksiyonudur.
@@ -332,7 +332,7 @@ Bu durumda, bu bir `async` fonksiyondur.
Bunu `async def` yerine normal bir fonksiyon olarak da tanımlayabilirsiniz:
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
/// note | Not
@@ -342,7 +342,7 @@ Eğer farkı bilmiyorsanız, [Async: *"Aceleniz mi var?"*](../async.md#in-a-hurr
### Adım 5: içeriği döndürün { #step-5-return-the-content }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
Bir `dict`, `list`, `str`, `int` vb. tekil değerler döndürebilirsiniz.

View File

@@ -25,7 +25,7 @@ Clienta hata içeren HTTP responseları döndürmek için `HTTPException`
### `HTTPException`ı Import Etme { #import-httpexception }
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
### Kodunuzda Bir `HTTPException` Raise Etme { #raise-an-httpexception-in-your-code }
@@ -39,7 +39,7 @@ Bir değer döndürmek yerine exception raise etmenin faydası, Dependencies ve
Bu örnekte, client var olmayan bir ID ile bir item istediğinde, `404` status codeu ile bir exception raise edelim:
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
### Ortaya Çıkan Response { #the-resulting-response }
@@ -77,7 +77,7 @@ Muhtemelen bunu doğrudan kendi kodunuzda kullanmanız gerekmeyecek.
Ama ileri seviye bir senaryo için ihtiyaç duyarsanız, özel headerlar ekleyebilirsiniz:
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
## Özel Exception Handlerları Kurmak { #install-custom-exception-handlers }
@@ -89,7 +89,7 @@ Ve bu exceptionı FastAPI ile global olarak handle etmek istiyorsunuz.
`@app.exception_handler()` ile özel bir exception handler ekleyebilirsiniz:
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
Burada `/unicorns/yolo` için request atarsanız, *path operation* bir `UnicornException` `raise` eder.
@@ -127,7 +127,7 @@ Override etmek için `RequestValidationError`ı import edin ve exception hand
Exception handler, bir `Request` ve exceptionı alır.
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
Artık `/items/foo`ya giderseniz, şu varsayılan JSON hatası yerine:
@@ -159,7 +159,7 @@ Benzer şekilde `HTTPException` handlerını da override edebilirsiniz.
Örneğin bu hatalar için JSON yerine plain text response döndürmek isteyebilirsiniz:
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
/// note | Teknik Detaylar
@@ -183,7 +183,7 @@ Ancak bu, eğer sadece stringe çevirip bu bilgiyi doğrudan response olarak
Uygulamanızı geliştirirken bodyyi loglamak, debug etmek, kullanıcıya döndürmek vb. için bunu kullanabilirsiniz.
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
Şimdi şu gibi geçersiz bir item göndermeyi deneyin:
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
Exceptionı, **FastAPI**nin aynı varsayılan exception handlerlarıyla birlikte kullanmak isterseniz, varsayılan exception handlerları `fastapi.exception_handlers` içinden import edip yeniden kullanabilirsiniz:
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
Bu örnekte sadece oldukça açıklayıcı bir mesajla hatayı yazdırıyorsunuz; ama fikir anlaşılıyor. Exceptionı kullanıp ardından varsayılan exception handlerları olduğu gibi yeniden kullanabilirsiniz.

View File

@@ -62,7 +62,7 @@ Editörünüzde kullanmak FastAPI'nin avantajlarını gerçekten gösterir: ne k
İlk adım FastAPI'yi kurmaktır.
Bir [virtual environment](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan emin olun, etkinleştirin ve ardından **FastAPI'yi kurun**:
Bir [sanal ortam](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan emin olun, etkinleştirin ve ardından **FastAPI'yi kurun**:
<div class="termy">

View File

@@ -18,7 +18,7 @@ OpenAPI spesifikasyonunda ve otomatik API doküman arayüzlerinde kullanılan ş
Şu şekilde ayarlayabilirsiniz:
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
/// tip | İpucu
@@ -36,7 +36,7 @@ OpenAPI 3.1.0 ve FastAPI 0.99.0 sürümünden itibaren, `license_info` içinde `
Örneğin:
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
## Tag'ler için Metadata { #metadata-for-tags }
@@ -58,7 +58,7 @@ Her sözlük şunları içerebilir:
Tag'leriniz için metadata oluşturup `openapi_tags` parametresine geçin:
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
ıklamaların içinde Markdown kullanabileceğinizi unutmayın; örneğin "login" kalın (**login**) ve "fancy" italik (_fancy_) olarak gösterilecektir.
@@ -72,7 +72,7 @@ Kullandığınız tüm tag'ler için metadata eklemek zorunda değilsiniz.
*path operation*'larınızı (ve `APIRouter`'ları) farklı tag'lere atamak için `tags` parametresini kullanın:
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
/// info | Bilgi
@@ -100,7 +100,7 @@ Ancak bunu `openapi_url` parametresiyle yapılandırabilirsiniz.
Örneğin `/api/v1/openapi.json` adresinden sunulacak şekilde ayarlamak için:
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
OpenAPI şemasını tamamen kapatmak isterseniz `openapi_url=None` ayarlayabilirsiniz; bu, onu kullanan dokümantasyon arayüzlerini de devre dışı bırakır.
@@ -117,4 +117,4 @@ Dahil gelen iki dokümantasyon arayüzünü yapılandırabilirsiniz:
Örneğin Swagger UI'yi `/documentation` adresinden sunup ReDoc'u kapatmak için:
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}

View File

@@ -31,7 +31,7 @@ Middleware fonksiyonu şunları alır:
* Ardından ilgili *path operation* tarafından üretilen `response`'u döndürür.
* Sonrasında `response`'u döndürmeden önce ayrıca değiştirebilirsiniz.
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
/// tip | İpucu
@@ -57,7 +57,7 @@ Ayrıca `response` üretildikten sonra, geri döndürmeden önce de kod çalış
Örneğin, request'i işleyip response üretmenin kaç saniye sürdüğünü içeren `X-Process-Time` adlı özel bir header ekleyebilirsiniz:
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
/// tip | İpucu
@@ -92,4 +92,4 @@ Bu stack davranışı, middleware'lerin öngörülebilir ve kontrol edilebilir b
Diğer middleware'ler hakkında daha fazlasını daha sonra [Advanced User Guide: Advanced Middleware](../advanced/middleware.md){.internal-link target=_blank} bölümünde okuyabilirsiniz.
Bir sonraki bölümde, middleware ile <abbr title="Cross-Origin Resource Sharing">CORS</abbr>'un nasıl ele alınacağını göreceksiniz.
Bir sonraki bölümde, middleware ile <abbr title="Cross-Origin Resource Sharing - Çapraz Kaynak Paylaşımı">CORS</abbr>'un nasıl ele alınacağını göreceksiniz.

View File

@@ -46,7 +46,7 @@ Bu durumlarda tagleri bir `Enum` içinde tutmak mantıklı olabilir.
**FastAPI** bunu düz stringlerde olduğu gibi aynı şekilde destekler:
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
## Özet ve açıklama { #summary-and-description }
@@ -54,9 +54,9 @@ Bir `summary` ve `description` ekleyebilirsiniz:
{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[17:18] *}
## Docstringden Description { #description-from-docstring }
## Docstringden ıklama { #description-from-docstring }
ıklamalar genelde uzun olur ve birden fazla satıra yayılır; bu yüzden *path operation*ıklamasını, fonksiyonun içinde <abbr title="dokümantasyon için, fonksiyon içinde ilk ifade olarak yazılan (herhangi bir değişkene atanmayan) çok satırlı string">docstring</abbr> olarak tanımlayabilirsiniz; **FastAPI** de onu buradan okur.
ıklamalar genelde uzun olur ve birden fazla satıra yayılır; bu yüzden *path operation*ıklamasını, fonksiyonun içinde <dfn title="dokümantasyon için kullanılan, fonksiyon içinde ilk ifade olarak yer alan (herhangi bir değişkene atanmayan) çok satırlı string">docstring</dfn> olarak tanımlayabilirsiniz; **FastAPI** de onu buradan okur.
Docstring içinde <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> yazabilirsiniz; doğru şekilde yorumlanır ve gösterilir (docstring girintisi dikkate alınarak).
@@ -90,9 +90,9 @@ Bu yüzden siz sağlamazsanız, **FastAPI** otomatik olarak "Successful response
## Bir *path operation*ı Deprecate Etmek { #deprecate-a-path-operation }
Bir *path operation*ı kaldırmadan, <abbr title="kullanım dışı, kullanılması önerilmez">deprecated</abbr> olarak işaretlemeniz gerekiyorsa `deprecated` parametresini verin:
Bir *path operation*ı kaldırmadan, <dfn title="eskimiş, kullanılması önerilmez">deprecated</dfn> olarak işaretlemeniz gerekiyorsa `deprecated` parametresini verin:
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
Interactive docsta deprecated olduğu net şekilde işaretlenecektir:

View File

@@ -54,11 +54,11 @@ Bu **FastAPI** için önemli değildir. FastAPI parametreleri isimlerine, tipler
Dolayısıyla fonksiyonunuzu şöyle tanımlayabilirsiniz:
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
Ancak şunu unutmayın: `Annotated` kullanırsanız bu problem olmaz; çünkü `Query()` veya `Path()` için fonksiyon parametresi default değerlerini kullanmıyorsunuz.
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
## Parametreleri İhtiyacınıza Göre Sıralayın: Küçük Hileler { #order-the-parameters-as-you-need-tricks }
@@ -81,15 +81,15 @@ Ancak şunu unutmayın: `Annotated` kullanırsanız bu problem olmaz; çünkü `
Fonksiyonun ilk parametresi olarak `*` geçin.
Python bu `*` ile bir şey yapmaz; ama bundan sonraki tüm parametrelerin keyword argument (anahtar-değer çiftleri) olarak çağrılması gerektiğini bilir; buna <abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr> da denir. Default değerleri olmasa bile.
Python bu `*` ile bir şey yapmaz; ama bundan sonraki tüm parametrelerin keyword argument (anahtar-değer çiftleri) olarak çağrılması gerektiğini bilir; buna <abbr title="Kökeni: K-ey W-ord Arg-uments"><code>kwargs</code></abbr> da denir. Default değerleri olmasa bile.
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
### `Annotated` ile Daha İyi { #better-with-annotated }
Şunu da unutmayın: `Annotated` kullanırsanız, fonksiyon parametresi default değerlerini kullanmadığınız için bu sorun ortaya çıkmaz ve muhtemelen `*` kullanmanız da gerekmez.
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
## Sayı Doğrulamaları: Büyük Eşit { #number-validations-greater-than-or-equal }
@@ -97,7 +97,7 @@ Python bu `*` ile bir şey yapmaz; ama bundan sonraki tüm parametrelerin keywor
Burada `ge=1` ile, `item_id` değerinin `1`'den "`g`reater than or `e`qual" olacak şekilde bir tam sayı olması gerekir.
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
## Sayı Doğrulamaları: Büyük ve Küçük Eşit { #number-validations-greater-than-and-less-than-or-equal }
@@ -106,19 +106,19 @@ Aynısı şunlar için de geçerlidir:
* `gt`: `g`reater `t`han
* `le`: `l`ess than or `e`qual
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
## Sayı Doğrulamaları: `float` Değerler, Büyük ve Küçük { #number-validations-floats-greater-than-and-less-than }
Sayı doğrulamaları `float` değerler için de çalışır.
Burada <abbr title="greater than"><code>gt</code></abbr> tanımlayabilmek (sadece <abbr title="greater than or equal"><code>ge</code></abbr> değil) önemli hale gelir. Çünkü örneğin bir değerin `0`'dan büyük olmasını isteyebilirsiniz; `1`'den küçük olsa bile.
Burada <abbr title="greater than - büyüktür"><code>gt</code></abbr> tanımlayabilmek (sadece <abbr title="greater than or equal - büyük veya eşittir"><code>ge</code></abbr> değil) önemli hale gelir. Çünkü örneğin bir değerin `0`'dan büyük olmasını isteyebilirsiniz; `1`'den küçük olsa bile.
Bu durumda `0.5` geçerli bir değer olur. Ancak `0.0` veya `0` geçerli olmaz.
Aynısı <abbr title="less than"><code>lt</code></abbr> için de geçerlidir.
Aynısı <abbr title="less than - küçüktür"><code>lt</code></abbr> için de geçerlidir.
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
## Özet { #recap }

View File

@@ -2,7 +2,7 @@
Python <abbr title="String Biçimleme: Format String">string biçimlemede</abbr> kullanılan sözdizimiyle path "parametreleri"ni veya "değişkenleri"ni tanımlayabilirsiniz:
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
Path parametresi `item_id`'nin değeri, fonksiyonunuza `item_id` argümanı olarak aktarılacaktır.
@@ -16,7 +16,7 @@ Yani, bu örneği çalıştırıp <a href="http://127.0.0.1:8000/items/foo" clas
Standart Python tip belirteçlerini kullanarak path parametresinin tipini fonksiyonun içinde tanımlayabilirsiniz:
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
Bu durumda, `item_id` bir `int` olarak tanımlanır.
@@ -26,7 +26,7 @@ Bu sayede, fonksiyon içinde hata denetimi, kod tamamlama vb. konularda editör
///
## Veri <abbr title="also known as: endpoints, routes">conversion</abbr> { #data-conversion }
## Veri <dfn title="diğer adlarıyla: serileştirme, ayrıştırma, marshalling">dönüştürme</dfn> { #data-conversion }
Bu örneği çalıştırıp tarayıcınızda <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a> adresini açarsanız, şöyle bir response görürsünüz:
@@ -38,7 +38,7 @@ Bu örneği çalıştırıp tarayıcınızda <a href="http://127.0.0.1:8000/item
Dikkat edin: fonksiyonunuzun aldığı (ve döndürdüğü) değer olan `3`, string `"3"` değil, bir Python `int`'idir.
Yani, bu tip tanımıyla birlikte **FastAPI** size otomatik request <abbr title="HTTP isteği ile birlikte gelen string'i Python verisine dönüştürme">"parsing"</abbr> sağlar.
Yani, bu tip tanımıyla birlikte **FastAPI** size otomatik request "<dfn title="HTTP request'ten gelen string'i Python verisine dönüştürme">ayrıştırma</dfn>" sağlar.
///
@@ -118,13 +118,13 @@ Sonra belirli bir kullanıcı hakkında, kullanıcı ID'si ile veri almak için
*Path operation*'lar sırayla değerlendirildiği için, `/users/me` için olan path'in `/users/{user_id}` olandan önce tanımlandığından emin olmanız gerekir:
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
Aksi halde, `/users/{user_id}` için olan path, `"me"` değerini `user_id` parametresi olarak aldığını "düşünerek" `/users/me` için de eşleşir.
Benzer şekilde, bir path operation'ı yeniden tanımlayamazsınız:
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
Path önce eşleştiği için her zaman ilk olan kullanılır.
@@ -140,11 +140,11 @@ Bir *path operation*'ınız *path parameter* alıyorsa ama olası geçerli *path
Sonra, kullanılabilir geçerli değerler olacak sabit değerli class attribute'ları oluşturun:
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
/// tip | İpucu
Merak ediyorsanız: "AlexNet", "ResNet" ve "LeNet", Makine Öğrenmesi <abbr title="Technically, Deep Learning model architectures">modelleri</abbr>nin sadece isimleridir.
Merak ediyorsanız: "AlexNet", "ResNet" ve "LeNet", Makine Öğrenmesi <dfn title="Teknik olarak, Derin Öğrenme model mimarileri">modelleri</dfn>nin sadece isimleridir.
///
@@ -152,7 +152,7 @@ Merak ediyorsanız: "AlexNet", "ResNet" ve "LeNet", Makine Öğrenmesi <abbr tit
Ardından oluşturduğunuz enum sınıfını (`ModelName`) kullanarak tip belirteciyle bir *path parameter* oluşturun:
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
### Dokümana Göz Atalım { #check-the-docs }
@@ -168,13 +168,13 @@ Ardından oluşturduğunuz enum sınıfını (`ModelName`) kullanarak tip belirt
Bunu, oluşturduğunuz enum `ModelName` içindeki *enumeration member* ile karşılaştırabilirsiniz:
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
#### *Enumeration Value*'yu Alalım { #get-the-enumeration-value }
Gerçek değeri (bu durumda bir `str`) `model_name.value` ile veya genel olarak `your_enum_member.value` ile alabilirsiniz:
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
/// tip | İpucu
@@ -188,7 +188,7 @@ Gerçek değeri (bu durumda bir `str`) `model_name.value` ile veya genel olarak
İstemciye dönmeden önce, karşılık gelen değerlerine (bu durumda string) dönüştürülürler:
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
İstemcinizde şöyle bir JSON response alırsınız:
@@ -227,7 +227,7 @@ Bu durumda parametrenin adı `file_path`'tir ve son kısım olan `:path`, parame
Yani şununla kullanabilirsiniz:
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
/// tip | İpucu
@@ -242,7 +242,7 @@ Bu durumda URL, `files` ile `home` arasında çift eğik çizgi (`//`) olacak ş
**FastAPI** ile kısa, sezgisel ve standart Python tip tanımlarını kullanarak şunları elde edersiniz:
* Editör desteği: hata denetimleri, otomatik tamamlama vb.
* Veri "<abbr title="HTTP isteği ile birlikte gelen string'i Python verisine dönüştürme">parsing</abbr>"
* Veri "<dfn title="HTTP request'ten gelen string'i Python verisine dönüştürme">ayrıştırma</dfn>"
* Veri doğrulama
* API annotation ve otomatik dokümantasyon

View File

@@ -16,7 +16,7 @@ FastAPI, `q`nun zorunlu olmadığını `= None` varsayılan değerinden anlar
///
## Ek doğrulama { #additional-validation }
## Ek Doğrulama { #additional-validation }
`q` opsiyonel olsa bile, verildiği durumda **uzunluğunun 50 karakteri geçmemesini** zorlayacağız.
@@ -47,40 +47,16 @@ Daha eski bir sürüm kullanıyorsanız `Annotated` kullanmaya çalışırken ha
Şu tip anotasyonuna sahiptik:
//// tab | Python 3.10+
```Python
q: str | None = None
```
////
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
```
////
Şimdi bunu `Annotated` ile saracağız; şöyle olacak:
//// tab | Python 3.10+
```Python
q: Annotated[str | None] = None
```
////
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
```
////
Bu iki sürüm de aynı anlama gelir: `q`, `str` veya `None` olabilen bir parametredir ve varsayılan olarak `None`dır.
Şimdi işin eğlenceli kısmına geçelim. 🎉
@@ -109,7 +85,7 @@ FastAPI artık şunları yapacak:
## Alternatif (eski): Varsayılan değer olarak `Query` { #alternative-old-query-as-the-default-value }
FastAPInin önceki sürümlerinde (<abbr title="before 2023-03 - 2023-03ten önce">0.95.0</abbr> öncesi) `Query`yi `Annotated` içine koymak yerine, parametrenizin varsayılan değeri olarak kullanmanız gerekiyordu. Etrafta bu şekilde yazılmış kod görme ihtimaliniz yüksek; bu yüzden açıklayalım.
FastAPInin önceki sürümlerinde ( <dfn title="2023-03ten önce">0.95.0</dfn> öncesi) `Query`yi `Annotated` içine koymak yerine, parametrenizin varsayılan değeri olarak kullanmanız gerekiyordu. Etrafta bu şekilde yazılmış kod görme ihtimaliniz yüksek; bu yüzden açıklayalım.
/// tip | İpucu
@@ -131,6 +107,7 @@ q: str | None = Query(default=None)
...parametreyi `None` varsayılan değeriyle opsiyonel yapar; şununla aynı:
```Python
q: str | None = None
```
@@ -179,7 +156,7 @@ Fonksiyon parametrelerindeki varsayılan değer stiline göre **`Annotated` kull
Aynı fonksiyonu FastAPI olmadan **başka yerlerde** de **çağırabilirsiniz** ve **beklendiği gibi çalışır**. Eğer **zorunlu** bir parametre varsa (varsayılan değer yoksa) editörünüz hata ile bunu belirtir; ayrıca gerekli parametreyi vermeden çalıştırırsanız **Python** da şikayet eder.
`Annotated` kullanmayıp bunun yerine **(eski) varsayılan değer stilini** kullanırsanız, o fonksiyonu FastAPI olmadan **başka yerlerde** çağırdığınızda doğru çalışması için argümanları geçmeniz gerektiğini **hatırlamak** zorunda kalırsınız; yoksa değerler beklediğinizden farklı olur (ör. `str` yerine `QueryInfo` veya benzeri). Üstelik editörünüz de şikayet etmez ve Python da fonksiyonu çalıştırırken şikayet etmez; ancak içerideki operasyonlar hata verince ortaya çıkar.
`Annotated` kullanmayıp bunun yerine **(eski) varsayılan değer stilini** kullanırsanız, o fonksiyonu FastAPI olmadan **başka yerlerde** çağırdığınızda doğru çalışması için argümanları geçmeniz gerektiğini **hatırlamak** zorunda kalırsınız; yoksa değerler beklediğinizden farklı olur (ör. `QueryInfo` veya benzeri). Üstelik editörünüz de şikayet etmez ve Python da fonksiyonu çalıştırırken şikayet etmez; ancak içerideki operasyonlar hata verince ortaya çıkar.
`Annotated` birden fazla metadata anotasyonu alabildiği için, artık aynı fonksiyonu <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a> gibi başka araçlarla da kullanabilirsiniz. 🚀
@@ -191,7 +168,7 @@ Aynı fonksiyonu FastAPI olmadan **başka yerlerde** de **çağırabilirsiniz**
## Regular expression ekleyin { #add-regular-expressions }
Parametrenin eşleşmesi gereken bir `pattern` <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings. - Regular expression (regex/regexp), stringler için arama deseni tanımlayan karakter dizisidir.">regular expression</abbr> tanımlayabilirsiniz:
Parametrenin eşleşmesi gereken bir `pattern` <dfn title="String'ler için arama deseni tanımlayan karakter dizisi">düzenli ifade</dfn> tanımlayabilirsiniz:
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@@ -211,7 +188,7 @@ Elbette `None` dışında varsayılan değerler de kullanabilirsiniz.
Örneğin `q` query parametresi için `min_length` değerini `3` yapmak ve varsayılan değer olarak `"fixedquery"` vermek istediğinizi düşünelim:
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
/// note | Not
@@ -233,7 +210,7 @@ q: str
q: str | None = None
```
Ancak biz artık `Query` ile tanımlıyoruz; örneğin şöyle:
Acak biz artık `Query` ile tanımlıyoruz; örneğin şöyle:
```Python
q: Annotated[str | None, Query(min_length=3)] = None
@@ -241,7 +218,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
Dolayısıyla `Query` kullanırken bir değeri zorunlu yapmak istediğinizde, varsayılan değer tanımlamamanız yeterlidir:
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
### Zorunlu ama `None` olabilir { #required-can-be-none }
@@ -292,7 +269,7 @@ Etkileşimli API dokümanları da buna göre güncellenir ve birden fazla değer
Hiç değer verilmezse varsayılan bir `list` de tanımlayabilirsiniz:
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
Şu adrese giderseniz:
@@ -315,7 +292,7 @@ http://localhost:8000/items/
`list[str]` yerine doğrudan `list` de kullanabilirsiniz:
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
/// note | Not
@@ -371,7 +348,7 @@ O zaman bir `alias` tanımlayabilirsiniz; bu alias, parametre değerini bulmak i
Diyelim ki artık bu parametreyi istemiyorsunuz.
Bazı clientlar hâlâ kullandığı için bir süre tutmanız gerekiyor, ama dokümanların bunu açıkça <abbr title="obsolete, recommended not to use it - kullanımdan kalkmış, kullanmamanız önerilir">deprecated</abbr> olarak göstermesini istiyorsunuz.
Bazı clientlar hâlâ kullandığı için bir süre tutmanız gerekiyor, ama dokümanların bunu açıkça <dfn title="kullanımdan kalkmış, kullanmamanız önerilir">deprecated</dfn> olarak göstermesini istiyorsunuz.
O zaman `Query`ye `deprecated=True` parametresini geçin:
@@ -401,7 +378,7 @@ Pydanticte <a href="https://docs.pydantic.dev/latest/concepts/validators/#fie
///
Örneğin bu custom validator, bir item IDsinin <abbr title="ISBN means International Standard Book Number - ISBN, International Standard Book Number (Uluslararası Standart Kitap Numarası) anlamına gelir">ISBN</abbr> kitap numarası için `isbn-` ile veya <abbr title="IMDB (Internet Movie Database) is a website with information about movies - IMDB (Internet Movie Database), filmler hakkında bilgi içeren bir web sitesidir">IMDB</abbr> film URL IDsi için `imdb-` ile başladığını kontrol eder:
Örneğin bu custom validator, bir item IDsinin <abbr title="International Standard Book Number - Uluslararası Standart Kitap Numarası">ISBN</abbr> kitap numarası için `isbn-` ile veya <abbr title="Internet Movie Database - İnternet Film Veritabanı: filmler hakkında bilgi içeren bir web sitesi">IMDB</abbr> film URL IDsi için `imdb-` ile başladığını kontrol eder:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@@ -435,9 +412,9 @@ Fark ettiniz mi? `value.startswith()` ile bir string, tuple alabilir ve tuple i
#### Rastgele Bir Item { #a-random-item }
`data.items()` ile, her dictionary öğesi için key ve value içeren tuplelardan oluşan bir <abbr title="Something we can iterate on with a for loop, like a list, set, etc. - for döngüsüyle üzerinde gezebileceğimiz (iterate edebileceğimiz) bir nesne; list, set vb.">iterable object</abbr> elde ederiz.
`data.items()` ile, her dictionary öğesi için key ve value içeren tuplelardan oluşan bir <dfn title="for döngüsüyle üzerinde gezinebileceğimiz bir şey; list, set vb.">yinelemeli nesne</dfn> elde ederiz.
Bu iterable objecti `list(data.items())` ile düzgün bir `list`e çeviririz.
Bu yinelemeli nesneyi `list(data.items())` ile düzgün bir `list`e çeviririz.
Ardından `random.choice()` ile listten **rastgele bir değer** alırız; yani `(id, name)` içeren bir tuple elde ederiz. Şuna benzer: `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.

View File

@@ -2,7 +2,7 @@
Fonksiyonda path parametrelerinin parçası olmayan diğer parametreleri tanımladığınızda, bunlar otomatik olarak "query" parametreleri olarak yorumlanır.
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
Query, bir URL'de `?` işaretinden sonra gelen ve `&` karakterleriyle ayrılan anahtar-değer çiftlerinin kümesidir.
@@ -24,7 +24,7 @@ Ancak, bunları Python tipleriyle (yukarıdaki örnekte `int` olarak) tanımlad
Path parametreleri için geçerli olan aynı süreç query parametreleri için de geçerlidir:
* Editör desteği (tabii ki)
* Veri <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>
* Veri <dfn title="bir HTTP request'ten gelen string'i Python verisine dönüştürme">"ayrıştırma"</dfn>
* Veri doğrulama
* Otomatik dokümantasyon
@@ -46,7 +46,7 @@ http://127.0.0.1:8000/items/
http://127.0.0.1:8000/items/?skip=0&limit=10
```
Ancak örneğin şuraya giderseniz:
Namunak örneğin şuraya giderseniz:
```
http://127.0.0.1:8000/items/?skip=20
@@ -128,7 +128,7 @@ Belirli bir değer eklemek istemiyor ama sadece opsiyonel olmasını istiyorsan
Ancak bir query parametresini zorunlu yapmak istediğinizde, herhangi bir varsayılan değer tanımlamamanız yeterlidir:
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
Burada query parametresi `needy`, `str` tipinde zorunlu bir query parametresidir.

View File

@@ -20,13 +20,13 @@ Bunun nedeni, upload edilen dosyaların "form data" olarak gönderilmesidir.
`fastapi` içinden `File` ve `UploadFile` import edin:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
## `File` Parametrelerini Tanımlayın { #define-file-parameters }
`Body` veya `Form` için yaptığınız gibi dosya parametreleri oluşturun:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
/// info | Bilgi
@@ -54,7 +54,7 @@ Ancak bazı durumlarda `UploadFile` kullanmak size fayda sağlayabilir.
Tipi `UploadFile` olan bir dosya parametresi tanımlayın:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
`UploadFile` kullanmanın `bytes`a göre birkaç avantajı vardır:
@@ -121,7 +121,7 @@ Formlardan gelen veri, dosya içermiyorsa normalde "media type" olarak `applicat
Ancak form dosya içeriyorsa `multipart/form-data` olarak encode edilir. `File` kullanırsanız, **FastAPI** dosyaları bodynin doğru kısmından alması gerektiğini bilir.
Bu encodingler ve form alanları hakkında daha fazla okumak isterseniz <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> web dokümanlarındaki <code>POST</code></a> sayfasına bakın.
Bu encodingler ve form alanları hakkında daha fazla okumak isterseniz <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla Geliştirici Ağı">MDN</abbr> web dokümanlarındaki <code>POST</code></a> sayfasına bakın.
///
@@ -143,7 +143,7 @@ Standart type annotationları kullanıp varsayılan değeri `None` yaparak bi
Ek metadata ayarlamak için `UploadFile` ile birlikte `File()` da kullanabilirsiniz. Örneğin:
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
## Birden Fazla Dosya Upload { #multiple-file-uploads }
@@ -153,7 +153,7 @@ Bu dosyalar, "form data" ile gönderilen aynı "form field" ile ilişkilendirili
Bunu kullanmak için `bytes` veya `UploadFile` listesini tanımlayın:
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
Tanımladığınız gibi, `bytes` veya `UploadFile`lardan oluşan bir `list` alırsınız.
@@ -169,7 +169,7 @@ Tanımladığınız gibi, `bytes` veya `UploadFile`lardan oluşan bir `list`
Daha önce olduğu gibi, `UploadFile` için bile ek parametreler ayarlamak amacıyla `File()` kullanabilirsiniz:
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
## Özet { #recap }

View File

@@ -24,7 +24,7 @@ Bu özellik FastAPI `0.113.0` sürümünden itibaren desteklenmektedir. 🤓
Sadece, **form field** olarak almak istediğiniz alanlarla bir **Pydantic model** tanımlayın ve ardından parametreyi `Form` olarak bildirin:
{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
**FastAPI**, request içindeki **form data**'dan **her bir field** için veriyi **çıkarır** ve size tanımladığınız Pydantic model'ini verir.
@@ -48,7 +48,7 @@ Bu özellik FastAPI `0.114.0` sürümünden itibaren desteklenmektedir. 🤓
Herhangi bir `extra` field'ı `forbid` etmek için Pydantic'in model konfigürasyonunu kullanabilirsiniz:
{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
Bir client fazladan veri göndermeye çalışırsa, bir **error** response alır.

View File

@@ -16,13 +16,13 @@ $ pip install python-multipart
## `File` ve `Form` Import Edin { #import-file-and-form }
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
## `File` ve `Form` Parametrelerini Tanımlayın { #define-file-and-form-parameters }
Dosya ve form parametrelerini, `Body` veya `Query` için yaptığınız şekilde oluşturun:
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
Dosyalar ve form alanları form data olarak upload edilir ve siz de dosyaları ve form alanlarını alırsınız.

View File

@@ -18,17 +18,17 @@ $ pip install python-multipart
`Form`'u `fastapi`'den import edin:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
## `Form` Parametrelerini Tanımlayın { #define-form-parameters }
Form parametrelerini `Body` veya `Query` için yaptığınız gibi oluşturun:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
Örneğin OAuth2 spesifikasyonunun kullanılabileceği ("password flow" olarak adlandırılan) yollardan birinde, form alanları olarak bir `username` ve `password` göndermek zorunludur.
<abbr title="specification - spesifikasyon">spec</abbr>, alanların adının tam olarak `username` ve `password` olmasını ve JSON değil form alanları olarak gönderilmesini gerektirir.
<dfn title="spesifikasyon">Spesifikasyon</dfn>, alanların adının tam olarak `username` ve `password` olmasını ve JSON değil form alanları olarak gönderilmesini gerektirir.
`Form` ile `Body` (ve `Query`, `Path`, `Cookie`) ile yaptığınız aynı konfigürasyonları tanımlayabilirsiniz; validasyon, örnekler, alias (örn. `username` yerine `user-name`) vb. dahil.
@@ -56,13 +56,13 @@ Formlardan gelen veri normalde "media type" `application/x-www-form-urlencoded`
Ancak form dosyalar içerdiğinde `multipart/form-data` olarak encode edilir. Dosyaları ele almayı bir sonraki bölümde okuyacaksınız.
Bu encoding'ler ve form alanları hakkında daha fazla okumak isterseniz, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> web docs for <code>POST</code></a> sayfasına gidin.
Bu encoding'ler ve form alanları hakkında daha fazla okumak isterseniz, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla Geliştirici Ağı">MDN</abbr> web docs for <code>POST</code></a> sayfasına gidin.
///
/// warning | Uyarı
Bir *path operation* içinde birden fazla `Form` parametresi tanımlayabilirsiniz, ancak JSON olarak almayı beklediğiniz `Body` alanlarını da ayrıca tanımlayamazsınız; çünkü bu durumda request'in body'si `application/json` yerine `application/x-www-form-urlencoded` ile encode edilmiş olur.
Bir *path operation* içinde birden fazla `Form` parametresi tanımlayabilirsiniz, ancak JSON olarak almayı beklediğiniz `Body` alanlarını da ayrıca tanımlayamazsınız; çünkü bu durumda request'in body'si `application/x-www-form-urlencoded` ile encode edilmiş olur.
Bu **FastAPI**'ın bir kısıtlaması değildir, HTTP protokolünün bir parçasıdır.

View File

@@ -97,7 +97,7 @@ Artık bir browser password ile user oluşturduğunda, API response içinde ayn
Bu örnekte sorun olmayabilir; çünkü passwordü gönderen kullanıcı zaten aynı kişi.
Ancak aynı modeli başka bir *path operation* için kullanırsak, kullanıcının passwordlerini her clienta gönderiyor olabiliriz.
Namun ancak aynı modeli başka bir *path operation* için kullanırsak, kullanıcının passwordlerini her clienta gönderiyor olabiliriz.
/// danger
@@ -183,7 +183,7 @@ Bazı durumlarda Pydantic field olarak geçerli olmayan bir şey döndürebilir
En yaygın durum, [ileri seviye dokümanlarda daha sonra anlatıldığı gibi doğrudan bir Response döndürmektir](../advanced/response-directly.md){.internal-link target=_blank}.
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
Bu basit durum FastAPI tarafından otomatik olarak ele alınır; çünkü dönüş tipi annotationı `Response` classıdır (veya onun bir subclassı).
@@ -193,7 +193,7 @@ Araçlar da memnun olur; çünkü hem `RedirectResponse` hem `JSONResponse`, `Re
Type annotation içinde `Response`un bir subclassını da kullanabilirsiniz:
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
Bu da çalışır; çünkü `RedirectResponse`, `Response`un subclassıdır ve FastAPI bu basit durumu otomatik olarak yönetir.
@@ -201,7 +201,7 @@ Bu da çalışır; çünkü `RedirectResponse`, `Response`un subclassıdı
Ancak geçerli bir Pydantic tipi olmayan başka rastgele bir obje (ör. bir veritabanı objesi) döndürür ve fonksiyonu da öyle annotate ederseniz, FastAPI bu type annotationdan bir Pydantic response model oluşturmaya çalışır ve başarısız olur.
Aynı şey, farklı tipler arasında bir <abbr title='Birden fazla tip arasında union, "bu tiplerden herhangi biri" anlamına gelir.'>union</abbr> kullandığınızda ve bu tiplerden biri veya birkaçı geçerli bir Pydantic tipi değilse de olur; örneğin şu kullanım patlar 💥:
Aynı şey, farklı tipler arasında bir <dfn title="Birden fazla tip arasındaki bir birleşim, 'bu tiplerden herhangi biri' anlamına gelir.">birleşim</dfn> kullandığınızda ve bu tiplerden biri veya birkaçı geçerli bir Pydantic tipi değilse de olur; örneğin şu kullanım patlar 💥:
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}

View File

@@ -8,7 +8,7 @@ Bir response model tanımlayabildiğiniz gibi, herhangi bir *path operation* iç
* `@app.delete()`
* vb.
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
/// note | Not
@@ -66,7 +66,7 @@ Kısaca:
/// tip | İpucu
Her bir status code hakkında daha fazla bilgi almak ve hangi kodun ne için kullanıldığını görmek için <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank">HTTP status code'lar hakkında <abbr title="Mozilla Developer Network">MDN</abbr> dokümantasyonuna</a> göz atın.
Her bir status code hakkında daha fazla bilgi almak ve hangi kodun ne için kullanıldığını görmek için <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla Geliştirici Ağı">MDN</abbr> dokümantasyonu: HTTP status code'lar hakkında</a> göz atın.
///
@@ -74,7 +74,7 @@ Her bir status code hakkında daha fazla bilgi almak ve hangi kodun ne için kul
Önceki örneğe tekrar bakalım:
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
`201`, "Created" için kullanılan status code'dur.
@@ -82,7 +82,7 @@ Ancak bu kodların her birinin ne anlama geldiğini ezberlemek zorunda değilsin
`fastapi.status` içindeki kolaylık değişkenlerini (convenience variables) kullanabilirsiniz.
{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
Bunlar sadece kolaylık sağlar; aynı sayıyı taşırlar. Ancak bu şekilde editörün autocomplete özelliğiyle kolayca bulabilirsiniz:

View File

@@ -74,7 +74,7 @@ Elbette birden fazla `examples` da geçebilirsiniz:
Bunu yaptığınızda, örnekler bu body verisi için dahili **JSON Schema**nın bir parçası olur.
Buna rağmen, <abbr title="2023-08-26 - bunun yazıldığı tarihte">time of writing this</abbr>, doküman arayüzünü gösteren araç olan Swagger UI, **JSON Schema** içindeki veriler için birden fazla örneği göstermeyi desteklemiyor. Ancak aşağıda bir çözüm yolu var.
Buna rağmen, <dfn title="2023-08-26">bu yazı yazılırken</dfn>, doküman arayüzünü gösteren araç olan Swagger UI, **JSON Schema** içindeki veriler için birden fazla örneği göstermeyi desteklemiyor. Ancak aşağıda bir çözüm yolu var.
### OpenAPIye özel `examples` { #openapi-specific-examples }

View File

@@ -20,7 +20,7 @@ Güvenliği yönetmek için **FastAPI**nin sunduğu araçları kullanalım.
Örneği `main.py` adlı bir dosyaya kopyalayın:
{* ../../docs_src/security/tutorial001_an_py39.py *}
{* ../../docs_src/security/tutorial001_an_py310.py *}
## Çalıştırın { #run-it }
@@ -132,7 +132,7 @@ Bu durumda bile **FastAPI**, onu oluşturabilmeniz için gereken araçları suna
`OAuth2PasswordBearer` sınıfının bir instanceını oluştururken `tokenUrl` parametresini veririz. Bu parametre, clientın (kullanıcının browserında çalışan frontendin) token almak için `username` ve `password` göndereceği URLyi içerir.
{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
/// tip | İpucu
@@ -170,7 +170,7 @@ Dolayısıyla `Depends` ile kullanılabilir.
Artık `Depends` ile bir dependency olarak `oauth2_scheme`i geçebilirsiniz.
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
Bu dependency, *path operation function* içindeki `token` parametresine atanacak bir `str` sağlar.

View File

@@ -2,7 +2,7 @@
Önceki bölümde güvenlik sistemi (dependency injection sistemine dayanır) *path operation function*'a `str` olarak bir `token` veriyordu:
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
Ancak bu hâlâ pek kullanışlı değil.

View File

@@ -116,7 +116,11 @@ Sonra, alınan password'ün kayıttaki hash ile eşleşip eşleşmediğini doğr
Bir tane de kullanıcıyı authenticate edip geri döndüren bir yardımcı fonksiyon ekleyelim.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
`authenticate_user`, veritabanında var olmayan bir username ile çağrıldığında, yine de sahte (dummy) bir hash'e karşı `verify_password` çalıştırıyoruz.
Bu, username geçerli olsun ya da olmasın endpoint'in yaklaşık aynı sürede yanıt vermesini sağlar; böylece mevcut username'leri saymaya yarayabilecek zamanlama saldırılarını (timing attacks) engeller.
/// note | Not
@@ -152,7 +156,7 @@ Response için token endpoint'inde kullanılacak bir Pydantic Model tanımlayın
Yeni bir access token üretmek için bir yardımcı fonksiyon oluşturun.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
## Dependency'leri güncelleme { #update-the-dependencies }
@@ -162,7 +166,7 @@ Gelen token'ı decode edin, doğrulayın ve mevcut kullanıcıyı döndürün.
Token geçersizse, hemen bir HTTP hatası döndürün.
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
## `/token` *path operation*'ını güncelleme { #update-the-token-path-operation }
@@ -170,7 +174,7 @@ Token'ın süre sonu için bir `timedelta` oluşturun.
Gerçek bir JWT access token üretip döndürün.
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
### JWT "subject" `sub` Hakkında Teknik Detaylar { #technical-details-about-the-jwt-subject-sub }

View File

@@ -8,7 +8,7 @@ Burada <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_b
/// tip | İpucu
İstediğiniz başka bir SQL veya NoSQL veritabanı kütüphanesini kullanabilirsiniz (bazı durumlarda <abbr title="Object Relational Mapper: a fancy term for a library where some classes represent SQL tables and instances represent rows in those tables">"ORMs"</abbr> olarak adlandırılır). FastAPI sizi hiçbir şeye zorlamaz.
İstediğiniz başka bir SQL veya NoSQL veritabanı kütüphanesini kullanabilirsiniz (bazı durumlarda <abbr title="Object Relational Mapper - Obje-İlişkisel Eşleyici: bazı sınıfların SQL tablolarını ve örneklerin bu tablolardaki satırları temsil ettiği bir kütüphane için süslü bir terim">"ORMs"</abbr> olarak adlandırılır). FastAPI sizi hiçbir şeye zorlamaz. 😎
///
@@ -49,7 +49,7 @@ $ pip install sqlmodel
Önce, tek bir **SQLModel** modeliyle uygulamanın en basit ilk sürümünü oluşturacağız.
Aşağıda, **birden fazla model** kullanarak güvenliği ve esnekliği artırıp geliştireceğiz.
Aşağıda, **birden fazla model** kullanarak güvenliği ve esnekliği artırıp geliştireceğiz. 🤓
### Modelleri Oluşturma { #create-models }
@@ -93,7 +93,7 @@ Sonra `SQLModel.metadata.create_all(engine)` kullanan bir fonksiyon ekleyerek t
Bir **`Session`**, **nesneleri memoryde** tutar ve verideki gerekli değişiklikleri takip eder; ardından veritabanıyla iletişim kurmak için **`engine` kullanır**.
`yield` ile, her request için yeni bir `Session` sağlayacak bir FastAPI **dependency** oluşturacağız. Bu da her requestte tek session kullanmamızı garanti eder.
`yield` ile, her request için yeni bir `Session` sağlayacak bir FastAPI **dependency** oluşturacağız. Bu da her requestte tek session kullanmamızı garanti eder. 🤓
Ardından bu dependencyyi kullanacak kodun geri kalanını sadeleştirmek için `Annotated` ile `SessionDep` dependencysini oluştururuz.
@@ -107,7 +107,7 @@ Uygulama başlarken veritabanı tablelarını oluşturacağız.
Burada bir uygulama startup eventinde tableları oluşturuyoruz.
Productionda büyük ihtimalle uygulamayı başlatmadan önce çalışan bir migration scripti kullanırsınız.
Productionda büyük ihtimalle uygulamayı başlatmadan önce çalışan bir migration scripti kullanırsınız. 🤓
/// tip | İpucu
@@ -169,19 +169,19 @@ Sonra `/docs` arayüzüne gidin; **FastAPI**nin APIyi **dokümante etmek**
Şimdi bu uygulamayı biraz **refactor** edelim ve **güvenliği** ile **esnekliği** artıralım.
Önceki uygulamaya bakarsanız, UIda şu ana kadar clientın oluşturulacak `Hero`nun `id` değerini belirlemesine izin verdiğini görebilirsiniz.
Önceki uygulamaya bakarsanız, UIda şu ana kadar clientın oluşturulacak `Hero`nun `id` değerini belirlemesine izin verdiğini görebilirsiniz. 😱
Buna izin vermemeliyiz; DBde zaten atanmış bir `id`yi ezebilirler. `id` belirlemek **client** tarafından değil, **backend** veya **veritabanı** tarafından yapılmalıdır.
Ayrıca hero için bir `secret_name` oluşturuyoruz ama şimdiye kadar her yerde geri döndürüyoruz; bu pek de **secret** sayılmaz...
Ayrıca hero için bir `secret_name` oluşturuyoruz ama şimdiye kadar her yerde geri döndürüyoruz; bu pek de **secret** sayılmaz... 😅
Bunları birkaç **ek model** ekleyerek düzelteceğiz. SQLModelin parlayacağı yer de burası.
Bunları birkaç **ek model** ekleyerek düzelteceğiz. SQLModelin parlayacağı yer de burası.
### Birden Fazla Model Oluşturma { #create-multiple-models }
**SQLModel**de, `table=True` olan herhangi bir model sınıfı bir **table model**dir.
`table=True` olmayan her model sınıfı ise bir **data model**dir; bunlar aslında sadece Pydantic modelleridir (bazı küçük ek özelliklerle).
`table=True` olmayan her model sınıfı ise bir **data model**dir; bunlar aslında sadece Pydantic modelleridir (bazı küçük ek özelliklerle). 🤓
SQLModel ile **inheritance** kullanarak her durumda tüm alanları tekrar tekrar yazmaktan **kaçınabiliriz**.
@@ -216,7 +216,7 @@ Sonraki adımda `HeroPublic` modelini oluştururuz; bu model API clientların
`HeroBase` ile aynı alanlara sahiptir; dolayısıyla `secret_name` içermez.
Sonunda kahramanlarımızın kimliği korunmuş oldu!
Sonunda kahramanlarımızın kimliği korunmuş oldu! 🥷
Ayrıca `id: int` alanını yeniden tanımlar. Bunu yaparak API clientlarıyla bir **contract** (sözleşme) oluşturmuş oluruz; böylece `id` alanının her zaman var olacağını ve `int` olacağını (asla `None` olmayacağını) bilirler.
@@ -224,7 +224,7 @@ Ayrıca `id: int` alanını yeniden tanımlar. Bunu yaparak API clientlarıyl
Return modelin bir değerin her zaman mevcut olduğunu ve her zaman `int` olduğunu (`None` değil) garanti etmesi API clientları için çok faydalıdır; bu kesinlik sayesinde daha basit kod yazabilirler.
Ayrıca **otomatik üretilen client**ların arayüzleri de daha basit olur; böylece APInizle çalışan geliştiriciler için süreç çok daha rahat olur.
Ayrıca **otomatik üretilen client**ların arayüzleri de daha basit olur; böylece APInizle çalışan geliştiriciler için süreç çok daha rahat olur. 😎
///
@@ -262,13 +262,13 @@ Ayrıca password değerlerini saklamadan önce **hash** etmelisiniz; **asla plai
#### `HeroUpdate` - hero güncellemek için *data model* { #heroupdate-the-data-model-to-update-a-hero }
Uygulamanın önceki sürümünde bir heroyu **güncellemenin** bir yolu yoktu; ancak artık **birden fazla model** ile bunu yapabiliriz.
Uygulamanın önceki sürümünde bir heroyu **güncellemenin** bir yolu yoktu; ancak artık **birden fazla model** ile bunu yapabiliriz. 🎉
`HeroUpdate` *data model* biraz özeldir: yeni bir hero oluşturmak için gereken alanların **tamamına** sahiptir, ancak tüm alanlar **opsiyoneldir** (hepsinin bir default değeri vardır). Bu sayede hero güncellerken sadece güncellemek istediğiniz alanları gönderebilirsiniz.
Tüm **alanlar aslında değiştiği** için (tip artık `None` içeriyor ve default değerleri `None` oluyor), onları **yeniden tanımlamamız** gerekir.
Aslında `HeroBase`ten miras almamız gerekmiyor; çünkü tüm alanları yeniden tanımlıyoruz. Tutarlılık için miras almayı bırakıyorum ama bu gerekli değil. Daha çok kişisel tercih meselesi.
Aslında `HeroBase`ten miras almamız gerekmiyor; çünkü tüm alanları yeniden tanımlıyoruz. Tutarlılık için miras almayı bırakıyorum ama bu gerekli değil. Daha çok kişisel tercih meselesi. 🤷
`HeroUpdate` alanları:
@@ -316,7 +316,7 @@ Tek bir heroyu **okuyabiliriz**:
Bir heroyu **güncelleyebiliriz**. Bunun için HTTP `PATCH` operasyonu kullanırız.
Kodda, clientın gönderdiği tüm verilerle bir `dict` alırız; **yalnızca clientın gönderdiği veriler**, yani sadece default değer oldukları için orada bulunan değerler hariç. Bunu yapmak için `exclude_unset=True` kullanırız. Asıl numara bu.
Kodda, clientın gönderdiği tüm verilerle bir `dict` alırız; **yalnızca clientın gönderdiği veriler**, yani sadece default değer oldukları için orada bulunan değerler hariç. Bunu yapmak için `exclude_unset=True` kullanırız. Asıl numara bu. 🪄
Sonra `hero_db.sqlmodel_update(hero_data)` ile `hero_db`yi `hero_data` içindeki verilerle güncelleriz.
@@ -326,7 +326,7 @@ Sonra `hero_db.sqlmodel_update(hero_data)` ile `hero_db`yi `hero_data` içind
Bir heroyu **silmek** büyük ölçüde aynı kalıyor.
Bu örnekte her şeyi refactor etme isteğimizi bastıracağız.
Bu örnekte her şeyi refactor etme isteğimizi bastıracağız. 😅
{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *}
@@ -354,4 +354,4 @@ $ fastapi dev main.py
Bir SQL veritabanıyla etkileşim kurmak için <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">**SQLModel**</a> kullanabilir ve *data model* ile *table model* yaklaşımıyla kodu sadeleştirebilirsiniz.
**SQLModel** dokümantasyonunda çok daha fazlasını öğrenebilirsiniz; **FastAPI** ile SQLModel kullanımı için daha uzun bir mini <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">tutorial</a> da bulunuyor.
**SQLModel** dokümantasyonunda çok daha fazlasını öğrenebilirsiniz; **FastAPI** ile SQLModel kullanımı için daha uzun bir mini <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">tutorial</a> da bulunuyor. 🚀

View File

@@ -7,7 +7,7 @@
* `StaticFiles`'ı import edin.
* Belirli bir path'te bir `StaticFiles()` örneğini "mount" edin.
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
/// note | Teknik Detaylar
@@ -23,7 +23,7 @@
Bu, bir `APIRouter` kullanmaktan farklıdır; çünkü mount edilen uygulama tamamen bağımsızdır. Ana uygulamanızın OpenAPI ve docs'ları, mount edilen uygulamadan hiçbir şey içermez, vb.
Bununla ilgili daha fazla bilgiyi [Advanced User Guide](../advanced/index.md){.internal-link target=_blank} içinde okuyabilirsiniz.
Bununla ilgili daha fazla bilgiyi [Gelişmiş Kullanıcı Kılavuzu](../advanced/index.md){.internal-link target=_blank} içinde okuyabilirsiniz.
## Detaylar { #details }

View File

@@ -12,7 +12,7 @@ Bununla birlikte **FastAPI** ile <a href="https://docs.pytest.org/" class="exter
`TestClient` kullanmak için önce <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a>'i kurun.
Bir [virtual environment](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan, onu aktifleştirdiğinizden ve sonra kurulumu yaptığınızdan emin olun; örneğin:
Bir [Sanal Ortam](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan, onu aktifleştirdiğinizden ve sonra kurulumu yaptığınızdan emin olun; örneğin:
```console
$ pip install httpx
@@ -30,7 +30,7 @@ Adı `test_` ile başlayan fonksiyonlar oluşturun (bu, `pytest`'in standart kon
Kontrol etmeniz gereken şeyler için standart Python ifadeleriyle basit `assert` satırları yazın (bu da `pytest` standardıdır).
{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
/// tip | İpucu
@@ -52,7 +52,7 @@ Bu sayede `pytest`'i ek bir karmaşıklık olmadan doğrudan kullanabilirsiniz.
/// tip | İpucu
FastAPI uygulamanıza request göndermenin dışında testlerinizde `async` fonksiyonlar çağırmak istiyorsanız (örn. asenkron veritabanı fonksiyonları), ileri seviye bölümdeki [Async Tests](../advanced/async-tests.md){.internal-link target=_blank} dokümanına göz atın.
FastAPI uygulamanıza request göndermenin dışında testlerinizde `async` fonksiyonlar çağırmak istiyorsanız (örn. asenkron veritabanı fonksiyonları), ileri seviye bölümdeki [Asenkron Testler](../advanced/async-tests.md){.internal-link target=_blank} dokümanına göz atın.
///
@@ -64,7 +64,7 @@ Ayrıca **FastAPI** uygulamanız birden fazla dosya/modül vb. ile de oluşturul
### **FastAPI** Uygulama Dosyası { #fastapi-app-file }
[Bigger Applications](bigger-applications.md){.internal-link target=_blank}'te anlatılan şekilde bir dosya yapınız olduğunu varsayalım:
[Daha Büyük Uygulamalar](bigger-applications.md){.internal-link target=_blank}'te anlatılan şekilde bir dosya yapınız olduğunu varsayalım:
```
.
@@ -75,7 +75,7 @@ Ayrıca **FastAPI** uygulamanız birden fazla dosya/modül vb. ile de oluşturul
`main.py` dosyasında **FastAPI** uygulamanız bulunuyor olsun:
{* ../../docs_src/app_testing/app_a_py39/main.py *}
{* ../../docs_src/app_testing/app_a_py310/main.py *}
### Test Dosyası { #testing-file }
@@ -91,7 +91,7 @@ Sonra testlerinizin olduğu bir `test_main.py` dosyanız olabilir. Bu dosya ayn
Bu dosya aynı package içinde olduğu için, `main` modülünden (`main.py`) `app` nesnesini import etmek üzere relative import kullanabilirsiniz:
{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
...ve test kodunu da öncekiyle aynı şekilde yazabilirsiniz.
@@ -145,7 +145,7 @@ Backend'e veri geçme hakkında daha fazla bilgi için (`httpx` veya `TestClient
`TestClient`'ın Pydantic model'lerini değil, JSON'a dönüştürülebilen verileri aldığını unutmayın.
Testinizde bir Pydantic model'iniz varsa ve test sırasında verisini uygulamaya göndermek istiyorsanız, [JSON Compatible Encoder](encoder.md){.internal-link target=_blank} içinde açıklanan `jsonable_encoder`'ı kullanabilirsiniz.
Testinizde bir Pydantic model'iniz varsa ve test sırasında verisini uygulamaya göndermek istiyorsanız, [JSON Uyumlu Encoder](encoder.md){.internal-link target=_blank} içinde açıklanan `jsonable_encoder`'ı kullanabilirsiniz.
///
@@ -153,7 +153,7 @@ Testinizde bir Pydantic model'iniz varsa ve test sırasında verisini uygulamaya
Bundan sonra yapmanız gereken tek şey `pytest`'i kurmaktır.
Bir [virtual environment](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan, onu aktifleştirdiğinizden ve sonra kurulumu yaptığınızdan emin olun; örneğin:
Bir [Sanal Ortam](../virtual-environments.md){.internal-link target=_blank} oluşturduğunuzdan, onu aktifleştirdiğinizden ve sonra kurulumu yaptığınızdan emin olun; örneğin:
<div class="termy">

View File

@@ -53,7 +53,7 @@ $ cd awesome-project
## Virtual Environment Oluşturun { #create-a-virtual-environment }
Bir Python projesi üzerinde **ilk kez** çalışmaya başladığınızda, projenizin içinde **<abbr title="there are other options, this is a simple guideline">virtual environment</abbr>** oluşturun.
Bir Python projesi üzerinde **ilk kez** çalışmaya başladığınızda, **virtual environment**'i <dfn title="başka seçenekler de var, bu basit bir yönergedir">projenizin içinde</dfn> oluşturun.
/// tip | İpucu