|
| 1 | +# Veri Akışı { #stream-data } |
| 2 | + |
| 3 | +Veriyi JSON olarak yapılandırabiliyorsanız, [JSON Lines Akışı](../tutorial/stream-json-lines.md) kullanın. |
| 4 | + |
| 5 | +Ancak saf ikili (binary) veri ya da string akıtmak istiyorsanız, bunu şöyle yapabilirsiniz. |
| 6 | + |
| 7 | +/// info | Bilgi |
| 8 | + |
| 9 | +FastAPI 0.134.0 ile eklendi. |
| 10 | + |
| 11 | +/// |
| 12 | + |
| 13 | +## Kullanım Senaryoları { #use-cases } |
| 14 | + |
| 15 | +Doğrudan bir AI LLM (Büyük Dil Modeli) servisinin çıktısından saf string'leri akıtmak istediğinizde kullanabilirsiniz. |
| 16 | + |
| 17 | +Ayrıca **büyük ikili (binary) dosyaları** akıtmak için de kullanabilirsiniz; veriyi okurken her parçayı (chunk) sırayla gönderirsiniz, tamamını belleğe almak zorunda kalmazsınız. |
| 18 | + |
| 19 | +Bu şekilde **video** veya **ses** de akıtabilirsiniz; hatta işledikçe üretilip gönderilebilir. |
| 20 | + |
| 21 | +## `yield` ile bir `StreamingResponse` { #a-streamingresponse-with-yield } |
| 22 | + |
| 23 | +*Path operation function* içinde `response_class=StreamingResponse` belirtirseniz, her veri parçasını sırayla göndermek için `yield` kullanabilirsiniz. |
| 24 | + |
| 25 | +{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *} |
| 26 | + |
| 27 | +FastAPI her veri parçasını olduğu gibi `StreamingResponse`'a verir; JSON'a ya da benzeri bir formata dönüştürmeye çalışmaz. |
| 28 | + |
| 29 | +### Async Olmayan Path Operation Function'lar { #non-async-path-operation-functions } |
| 30 | + |
| 31 | +Normal `def` fonksiyonlarını (yani `async` olmadan) da kullanabilir ve aynı şekilde `yield` yazabilirsiniz. |
| 32 | + |
| 33 | +{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *} |
| 34 | + |
| 35 | +### Tip Annotasyonu Yok { #no-annotation } |
| 36 | + |
| 37 | +İkili (binary) veri akıtıyorsanız dönüş tipi annotasyonu belirtmeniz şart değildir. |
| 38 | + |
| 39 | +FastAPI veriyi Pydantic ile JSON'a çevirmeye veya herhangi bir şekilde serileştirmeye çalışmayacağı için, bu durumda tip annotasyonu sadece editörünüz ve araçlarınız içindir; FastAPI tarafından kullanılmaz. |
| 40 | + |
| 41 | +{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *} |
| 42 | + |
| 43 | +Bu aynı zamanda `StreamingResponse` ile veriyi tam olarak ihtiyaç duyduğunuz biçimde üretme ve encode etme konusunda hem bir özgürlük hem de bir sorumluluk verdiği anlamına gelir; tip annotasyonlarından bağımsızdır. 🤓 |
| 44 | + |
| 45 | +### Bytes Akışı { #stream-bytes } |
| 46 | + |
| 47 | +Başlıca kullanım senaryolarından biri string yerine `bytes` akıtmaktır; elbette bunu yapabilirsiniz. |
| 48 | + |
| 49 | +{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *} |
| 50 | + |
| 51 | +## Özel bir `PNGStreamingResponse` { #a-custom-pngstreamingresponse } |
| 52 | + |
| 53 | +Yukarıdaki örneklerde veri baytları akıtıldı, ancak response'ta bir `Content-Type` header'ı yoktu; bu nedenle istemci hangi tür veriyi aldığını bilmiyordu. |
| 54 | + |
| 55 | +Akıttığınız veri türüne uygun `Content-Type` header'ını ayarlayan, `StreamingResponse`'tan türetilmiş özel bir alt sınıf (subclass) oluşturabilirsiniz. |
| 56 | + |
| 57 | +Örneğin, `media_type` özniteliğini kullanarak `Content-Type` header'ını `image/png` olarak ayarlayan bir `PNGStreamingResponse` oluşturabilirsiniz: |
| 58 | + |
| 59 | +{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *} |
| 60 | + |
| 61 | +Ardından bu yeni sınıfı *path operation function* içinde `response_class=PNGStreamingResponse` olarak kullanabilirsiniz: |
| 62 | + |
| 63 | +{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *} |
| 64 | + |
| 65 | +### Bir Dosyayı Simüle Etme { #simulate-a-file } |
| 66 | + |
| 67 | +Bu örnekte, yalnızca bellekte yaşayan ama aynı arayüzü kullanmamıza izin veren, dosya benzeri bir nesne olan `io.BytesIO` ile bir dosyayı simüle ediyoruz. |
| 68 | + |
| 69 | +Örneğin, bir dosyada yapabileceğimiz gibi, içeriğini tüketmek için üzerinde iterate edebiliriz. |
| 70 | + |
| 71 | +{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *} |
| 72 | + |
| 73 | +/// note | Teknik Detaylar |
| 74 | + |
| 75 | +Diğer iki değişken olan `image_base64` ve `binary_image`, Base64 ile encode edilmiş bir görüntüdür; daha sonra bayt'lara çevrilip `io.BytesIO`'ya aktarılır. |
| 76 | + |
| 77 | +Sadece bu örnek aynı dosyada yaşayabilsin, kopyalayıp olduğu gibi çalıştırabilesiniz diye. 🥚 |
| 78 | + |
| 79 | +/// |
| 80 | + |
| 81 | +`with` bloğu kullanarak, jeneratör fonksiyonu (içinde `yield` olan fonksiyon) tamamlandığında dosya benzeri nesnenin kapandığından emin oluruz. Yani response gönderimi bittikten sonra. |
| 82 | + |
| 83 | +Bu özel örnekte o kadar da önemli değil, çünkü sahte ve bellekte (yani `io.BytesIO` ile). Ancak gerçek bir dosyada, onunla işiniz bittiğinde dosyanın kapandığından emin olmak önemlidir. |
| 84 | + |
| 85 | +### Dosyalar ve Async { #files-and-async } |
| 86 | + |
| 87 | +Çoğu durumda dosya benzeri nesneler, varsayılan olarak async ve await ile uyumlu değildir. |
| 88 | + |
| 89 | +Örneğin, `await file.read()` ya da `async for chunk in file` gibi şeyler yoktur. |
| 90 | + |
| 91 | +Ve birçok durumda, diskte ya da ağda okundukları için, okumak engelleyici (event loop'u bloke edebilen) bir işlem olabilir. |
| 92 | + |
| 93 | +/// info | Bilgi |
| 94 | + |
| 95 | +Yukarıdaki örnek aslında bir istisna; çünkü `io.BytesIO` nesnesi zaten bellekte, dolayısıyla onu okumak hiçbir şeyi bloke etmez. |
| 96 | + |
| 97 | +Ancak çoğu durumda bir dosyayı veya dosya benzeri bir nesneyi okumak bloke edicidir. |
| 98 | + |
| 99 | +/// |
| 100 | + |
| 101 | +Event loop'u bloke etmemek için, *path operation function*'ı `async def` yerine normal `def` ile tanımlayabilirsiniz; böylece FastAPI ana döngüyü bloke etmemek için bunu bir thread pool worker (iş parçacığı havuzu çalışanı) üzerinde çalıştırır. |
| 102 | + |
| 103 | +{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *} |
| 104 | + |
| 105 | +/// tip | İpucu |
| 106 | + |
| 107 | +Async bir fonksiyonun içinden bloklayıcı kod çağırmanız ya da bloklayıcı bir fonksiyonun içinden async bir fonksiyon çağırmanız gerekirse, FastAPI'nin kardeş kütüphanesi olan [Asyncer](https://asyncer.tiangolo.com)'ı kullanabilirsiniz. |
| 108 | + |
| 109 | +/// |
| 110 | + |
| 111 | +### `yield from` { #yield-from } |
| 112 | + |
| 113 | +Bir şeyin (ör. dosya benzeri bir nesne) üzerinde iterate ederken, her öğe için `yield` yapıyorsanız, `for` döngüsünü yazmak yerine `yield from` ile her öğeyi doğrudan yield edebilirsiniz. |
| 114 | + |
| 115 | +Bu FastAPI'ye özgü değildir, tamamen Python'dur, ama bilinmesi güzel bir püf noktasıdır. 😎 |
| 116 | + |
| 117 | +{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *} |
0 commit comments