fastapi/docs/tr/docs/advanced/custom-response.md

13 KiB
Raw Blame History

Özel Response - HTML, Stream, File ve Diğerleri

Varsayılan olarak FastAPI, response'ları JSONResponse kullanarak döndürür.

Bunu, Doğrudan bir Response döndür{.internal-link target=_blank} bölümünde gördüğünüz gibi doğrudan bir Response döndürerek geçersiz kılabilirsiniz.

Ancak doğrudan bir Response döndürürseniz (veya JSONResponse gibi herhangi bir alt sınıfını), veri otomatik olarak dönüştürülmez (bir response_model tanımlamış olsanız bile) ve dokümantasyon da otomatik üretilmez (örneğin, üretilen OpenAPInin parçası olarak HTTP header Content-Type içindeki ilgili "media type" dahil edilmez).

Bununla birlikte, path operation decorator içinde response_class parametresini kullanarak hangi Responseun (örn. herhangi bir Response alt sınıfı) kullanılacağını da ilan edebilirsiniz.

path operation functionınızdan döndürdüğünüz içerik, o Responseun içine yerleştirilir.

Ve eğer bu Response ( JSONResponse ve UJSONResponseta olduğu gibi) bir JSON media typea (application/json) sahipse, döndürdüğünüz veri; path operation decorator içinde tanımladığınız herhangi bir Pydantic response_model ile otomatik olarak dönüştürülür (ve filtrelenir).

/// note | Not

Media typeı olmayan bir response class kullanırsanız, FastAPI responseunuzun content içermediğini varsayar; bu yüzden ürettiği OpenAPI dokümanında response formatını dokümante etmez.

///

ORJSONResponse Kullan

Örneğin performansı sıkıştırmaya çalışıyorsanız, orjson kurup kullanabilir ve responseu ORJSONResponse olarak ayarlayabilirsiniz.

Kullanmak istediğiniz Response classını (alt sınıfını) import edin ve path operation decorator içinde tanımlayın.

Büyük response'larda, doğrudan bir Response döndürmek bir dictionary döndürmekten çok daha hızlıdır.

Çünkü varsayılan olarak FastAPI, içindeki her itemı inceleyip JSON olarak serialize edilebilir olduğundan emin olur; tutorialda anlatılan aynı JSON Compatible Encoder{.internal-link target=_blank} mekanizmasını kullanır. Bu da örneğin veritabanı modelleri gibi keyfi objeleri döndürebilmenizi sağlar.

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] *}

/// info | Bilgi

response_class parametresi, responseun "media type"ını tanımlamak için de kullanılır.

Bu durumda HTTP header Content-Type, application/json olarak ayarlanır.

Ve OpenAPIde de bu şekilde dokümante edilir.

///

/// tip | İpucu

ORJSONResponse yalnızca FastAPIde vardır, Starlettete yoktur.

///

HTML Response

FastAPIden doğrudan HTML içeren bir response döndürmek için HTMLResponse kullanın.

  • 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] *}

/// info | Bilgi

response_class parametresi, responseun "media type"ını tanımlamak için de kullanılır.

Bu durumda HTTP header Content-Type, text/html olarak ayarlanır.

Ve OpenAPIde de bu şekilde dokümante edilir.

///

Bir Response Döndür

Doğrudan bir Response döndür{.internal-link target=_blank} bölümünde görüldüğü gibi, path operation içinde doğrudan bir response döndürerek responseu override edebilirsiniz.

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] *}

/// warning | Uyarı

path operation functionınızın doğrudan döndürdüğü bir Response, OpenAPIde dokümante edilmez (örneğin Content-Type dokümante edilmez) ve otomatik interaktif dokümanlarda görünmez.

///

/// info | Bilgi

Elbette gerçek Content-Type headerı, status code vb. değerler, döndürdüğünüz Response objesinden gelir.

///

OpenAPIde Dokümante Et ve Responseu Override Et

Responseu fonksiyonun içinden override etmek ama aynı zamanda OpenAPIde "media type"ı dokümante etmek istiyorsanız, response_class parametresini kullanıp ayrıca bir Response objesi döndürebilirsiniz.

Bu durumda response_class sadece OpenAPI path operationını dokümante etmek için kullanılır; sizin Responseunuz ise olduğu gibi kullanılır.

Doğrudan bir HTMLResponse Döndür

Örneğin şöyle bir şey olabilir:

{* ../../docs_src/custom_response/tutorial004_py39.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.

generate_html_response() çağrısının sonucunu döndürerek, varsayılan FastAPI davranışını override edecek bir Response döndürmüş olursunuz.

Ama response_class içinde HTMLResponse da verdiğiniz için FastAPI, bunu OpenAPIde ve interaktif dokümanlarda text/html ile HTML olarak nasıl dokümante edeceğini bilir:

Mevcut Response'lar

Mevcut response'lardan bazıları aşağıdadır.

Unutmayın: Response ile başka herhangi bir şeyi döndürebilir, hatta özel bir alt sınıf da oluşturabilirsiniz.

/// note | Teknik Detaylar

from starlette.responses import HTMLResponse da kullanabilirsiniz.

FastAPI, geliştirici için kolaylık olsun diye starlette.responses içindekileri fastapi.responses olarak da sağlar. Ancak mevcut response'ların çoğu doğrudan Starletteten gelir.

///

Response

Ana Response classıdır; diğer tüm response'lar bundan türetilir.

Bunu doğrudan döndürebilirsiniz.

Şu parametreleri kabul eder:

  • content - Bir str veya bytes.
  • status_code - Bir int HTTP status code.
  • headers - Stringlerden oluşan bir dict.
  • media_type - Media typeı veren bir str. Örn. "text/html".

FastAPI (aslında Starlette) otomatik olarak bir Content-Length headerı ekler. Ayrıca media_typea 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] *}

HTMLResponse

Yukarıda okuduğunuz gibi, bir miktar text veya bytes alır ve HTML response döndürür.

PlainTextResponse

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] *}

JSONResponse

Bir miktar veri alır ve application/json olarak encode edilmiş bir response döndürür.

Yukarıda okuduğunuz gibi, FastAPIde varsayılan response budur.

ORJSONResponse

Yukarıda okuduğunuz gibi orjson kullanan hızlı bir alternatif JSON response.

/// info | Bilgi

Bunun için orjson kurulmalıdır; örneğin pip install orjson.

///

UJSONResponse

ujson kullanan alternatif bir JSON response.

/// info | Bilgi

Bunun için ujson kurulmalıdır; örneğin pip install ujson.

///

/// warning | Uyarı

ujson, bazı edge-caseleri ele alma konusunda Pythonun built-in implementasyonu kadar dikkatli değildir.

///

{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}

/// tip | İpucu

ORJSONResponse daha hızlı bir alternatif olabilir.

///

RedirectResponse

HTTP redirect döndürür. Varsayılan olarak 307 status code (Temporary Redirect) kullanır.

RedirectResponseu doğrudan döndürebilirsiniz:

{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}


Veya response_class parametresi içinde kullanabilirsiniz:

{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}

Bunu yaparsanız, path operation functionınızdan doğrudan URL döndürebilirsiniz.

Bu durumda kullanılan status_code, RedirectResponse için varsayılan olan 307 olur.


Ayrıca status_code parametresini response_class parametresiyle birlikte kullanabilirsiniz:

{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}

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] *}

StreamingResponseu file-like objelerle kullanma

Bir file-like objeniz varsa (örn. open()ın döndürdüğü obje), o file-like obje üzerinde iterate eden bir generator function oluşturabilirsiniz.

Böylece önce hepsini memoryye okumak zorunda kalmazsınız; bu generator functionı StreamingResponsea verip döndürebilirsiniz.

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] *}

  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.

  3. Bu yield from, fonksiyona file_like isimli şeyi iterate etmesini söyler. Ardından iterate edilen her parça için, o parçayı bu generator functiondan (iterfile) geliyormuş gibi yield eder.

    Yani, içerdeki "üretme" (generating) işini başka bir şeye devreden bir generator functiondır.

    Bunu bu şekilde yaptığımızda with bloğu içinde tutabilir ve böylece iş bitince file-like objenin kapanmasını garanti edebiliriz.

/// tip | İpucu

Burada async ve await desteklemeyen standart open() kullandığımız için path operationı normal def ile tanımlarız.

///

FileResponse

Asenkron olarak bir dosyayı response olarak stream eder.

Diğer response türlerine göre instantiate ederken farklı argümanlar alır:

  • path - Stream edilecek dosyanın dosya path'i.
  • headers - Eklenecek özel headerlar; dictionary olarak.
  • media_type - Media typeı veren string. Ayarlanmazsa, dosya adı veya path kullanılarak media type tahmin edilir.
  • filename - Ayarlanırsa response içindeki Content-Dispositiona dahil edilir.

File response'ları uygun Content-Length, Last-Modified ve ETag headerlarını içerir.

{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}

response_class parametresini de kullanabilirsiniz:

{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}

Bu durumda path operation functionınızdan doğrudan dosya path'ini döndürebilirsiniz.

Özel response class

Responsedan türeterek kendi özel response classınızı oluşturabilir ve kullanabilirsiniz.

Örneğin, dahil gelen ORJSONResponse classında kullanılmayan bazı özel ayarlarla orjson kullanmak istediğinizi varsayalım.

Diyelim ki girintili ve biçimlendirilmiş JSON döndürmek istiyorsunuz; bunun için orjson.OPT_INDENT_2 seçeneğini kullanmak istiyorsunuz.

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] *}

Artık şunu döndürmek yerine:

{"message": "Hello World"}

...bu response şunu döndürür:

{
  "message": "Hello World"
}

Elbette JSONu formatlamaktan çok daha iyi şekillerde bundan faydalanabilirsiniz. 😉

Varsayılan response class

Bir FastAPI class instanceı veya bir APIRouter oluştururken, varsayılan olarak hangi response classının kullanılacağını belirtebilirsiniz.

Bunu tanımlayan parametre default_response_classtı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] *}

/// tip | İpucu

Daha önce olduğu gibi, path operations içinde response_classı yine override edebilirsiniz.

///

Ek dokümantasyon

OpenAPIde media typeı ve daha birçok detayı responses kullanarak da tanımlayabilirsiniz: OpenAPIde Ek Response'lar{.internal-link target=_blank}.