fastapi/docs/tr/docs/tutorial/query-params-str-validation...

18 KiB
Raw Blame History

Query Parametreleri ve String Doğrulamaları

FastAPI, parametreleriniz için ek bilgi ve doğrulamalar (validation) tanımlamanıza izin verir.

Örnek olarak şu uygulamayı ele alalım:

{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}

Query parametresi q, str | None tipindedir. Yani tipi strdir ama None da olabilir. Nitekim varsayılan değer None olduğu için FastAPI bunun zorunlu olmadığını anlar.

/// note | Not

FastAPI, qnun zorunlu olmadığını = None varsayılan değerinden anlar.

str | None kullanmak, editörünüzün daha iyi destek vermesini ve hataları yakalamasını sağlar.

///

Ek doğrulama

q opsiyonel olsa bile, verildiği durumda uzunluğunun 50 karakteri geçmemesini zorlayacağız.

Query ve Annotated import edin

Bunu yapmak için önce şunları import edin:

  • fastapi içinden Query
  • typing içinden Annotated

{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}

/// info | Bilgi

FastAPI, 0.95.0 sürümünde Annotated desteğini ekledi (ve önermeye başladı).

Daha eski bir sürüm kullanıyorsanız Annotated kullanmaya çalışırken hata alırsınız.

Annotated kullanmadan önce FastAPI sürümünü en az 0.95.1e yükseltmek için FastAPI sürümünü yükseltin{.internal-link target=_blank}.

///

q parametresinin tipinde Annotated kullanın

Python Types Intro{.internal-link target=_blank} içinde Annotated ile parametrelerinize metadata ekleyebileceğinizi söylemiştim, hatırlıyor musunuz?

Şimdi bunu FastAPI ile kullanmanın zamanı. 🚀

Şu tip anotasyonuna sahiptik:

//// tab | Python 3.10+

q: str | None = None

////

//// tab | Python 3.9+

q: Union[str, None] = None

////

Şimdi bunu Annotated ile saracağız; şöyle olacak:

//// tab | Python 3.10+

q: Annotated[str | None] = None

////

//// tab | Python 3.9+

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 Nonedır.

Şimdi işin eğlenceli kısmına geçelim. 🎉

q parametresindeki Annotated içine Query ekleyin

Artık ek bilgi (bu durumda ek doğrulama) koyabildiğimiz bir Annotatedımız olduğuna göre, Annotated içine Query ekleyin ve max_length parametresini 50 olarak ayarlayın:

{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}

Varsayılan değerin hâlâ None olduğuna dikkat edin; yani parametre hâlâ opsiyonel.

Ama şimdi Annotated içinde Query(max_length=50) kullanarak FastAPIye bu değer için ek doğrulama istediğimizi söylüyoruz: en fazla 50 karakter. 😎

/// tip | İpucu

Burada Query() kullanıyoruz çünkü bu bir query parametresi. İleride Path(), Body(), Header() ve Cookie() gibi, Query() ile aynı argümanları kabul eden diğerlerini de göreceğiz.

///

FastAPI artık şunları yapacak:

  • Verinin uzunluğunun en fazla 50 karakter olduğundan emin olacak şekilde doğrulayacak
  • Veri geçerli değilse client için net bir hata gösterecek
  • Parametreyi OpenAPI şemasındaki path operation içinde dokümante edecek (dolayısıyla otomatik dokümantasyon arayüzünde görünecek)

Alternatif (eski): Varsayılan değer olarak Query

FastAPInin önceki sürümlerinde (0.95.0 öncesi) Queryyi 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

Yeni kodlarda ve mümkün olduğunda, yukarıda anlatıldığı gibi Annotated kullanın. Birden fazla avantajı vardır (aşağıda anlatılıyor) ve dezavantajı yoktur. 🍰

///

Fonksiyon parametresinin varsayılan değeri olarak Query() kullanıp max_length parametresini 50 yapmak şöyle olurdu:

{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}

Bu senaryoda (Annotated kullanmadığımız için) fonksiyondaki None varsayılan değerini Query() ile değiştirmemiz gerekiyor. Bu durumda varsayılan değeri Query(default=None) ile vermeliyiz; bu, (en azından FastAPI açısından) aynı varsayılan değeri tanımlama amacına hizmet eder.

Yani:

q: str | None = Query(default=None)

...parametreyi None varsayılan değeriyle opsiyonel yapar; şununla aynı:

q: str | None = None

Ancak Query sürümü bunun bir query parametresi olduğunu açıkça belirtir.

Sonrasında Queryye daha fazla parametre geçebiliriz. Bu örnekte stringler için geçerli olan max_length:

q: str | None = Query(default=None, max_length=50)

Bu, veriyi doğrular, veri geçerli değilse net bir hata gösterir ve parametreyi OpenAPI şemasındaki path operation içinde dokümante eder.

Varsayılan değer olarak Query veya Annotated içinde Query

Annotated içinde Query kullanırken Query için default parametresini kullanamayacağınızı unutmayın.

Bunun yerine fonksiyon parametresinin gerçek varsayılan değerini kullanın. Aksi halde tutarsız olur.

Örneğin şu kullanım izinli değildir:

q: Annotated[str, Query(default="rick")] = "morty"

...çünkü varsayılan değerin "rick" mi "morty" mi olması gerektiği belli değildir.

Bu nedenle (tercihen) şöyle kullanırsınız:

q: Annotated[str, Query()] = "rick"

...veya eski kod tabanlarında şuna rastlarsınız:

q: str = Query(default="rick")

Annotatedın avantajları

Fonksiyon parametrelerindeki varsayılan değer stiline göre Annotated kullanmanız önerilir; birden fazla nedenle daha iyidir. 🤓

Fonksiyon parametresinin varsayılan değeri, gerçek varsayılan değerdir; bu genel olarak Python açısından daha sezgiseldir. 😌

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 birden fazla metadata anotasyonu alabildiği için, artık aynı fonksiyonu Typer gibi başka araçlarla da kullanabilirsiniz. 🚀

Daha fazla doğrulama ekleyin

min_length parametresini de ekleyebilirsiniz:

{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}

Regular expression ekleyin

Parametrenin eşleşmesi gereken bir pattern regular expression tanımlayabilirsiniz:

{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}

Bu özel regular expression patterni, gelen parametre değerinin şunları sağladığını kontrol eder:

  • ^: Aşağıdaki karakterlerle başlar; öncesinde karakter yoktur.
  • fixedquery: Tam olarak fixedquery değerine sahiptir.
  • $: Orada biter; fixedquery sonrasında başka karakter yoktur.

Bu "regular expression" konuları gözünüzü korkutuyorsa sorun değil. Birçok kişi için zor bir konudur. Regular expressionlara ihtiyaç duymadan da pek çok şey yapabilirsiniz.

Artık ihtiyaç duyduğunuzda FastAPI içinde kullanabileceğinizi biliyorsunuz.

Varsayılan değerler

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

/// note | Not

None dahil herhangi bir tipte varsayılan değere sahip olmak, parametreyi opsiyonel (zorunlu değil) yapar.

///

Zorunlu parametreler

Daha fazla doğrulama veya metadata tanımlamamız gerekmiyorsa, q query parametresini yalnızca varsayılan değer tanımlamayarak zorunlu yapabiliriz:

q: str

şunun yerine:

q: str | None = None

Ancak biz artık Query ile tanımlıyoruz; örneğin şöyle:

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

Zorunlu ama None olabilir

Bir parametrenin None kabul edebileceğini söyleyip yine de zorunlu olmasını sağlayabilirsiniz. Bu, clientların değer göndermesini zorunlu kılar; değer None olsa bile.

Bunu yapmak için Noneı geçerli bir tip olarak tanımlayın ama varsayılan değer vermeyin:

{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}

Query parametresi listesi / birden fazla değer

Bir query parametresini Query ile açıkça tanımladığınızda, bir değer listesi alacak şekilde (başka bir deyişle, birden fazla değer alacak şekilde) de tanımlayabilirsiniz.

Örneğin URLde q query parametresinin birden fazla kez görünebilmesini istiyorsanız şöyle yazabilirsiniz:

{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}

Sonra şu URL ile:

http://localhost:8000/items/?q=foo&q=bar

path operation function içinde, function parameter olan q parametresinde, birden fazla q query parameters değerini (foo ve bar) bir Python listi olarak alırsınız.

Dolayısıyla bu URLye response şöyle olur:

{
  "q": [
    "foo",
    "bar"
  ]
}

/// tip | İpucu

Yukarıdaki örnekte olduğu gibi tipi list olan bir query parametresi tanımlamak için Queryyi açıkça kullanmanız gerekir; aksi halde request body olarak yorumlanır.

///

Etkileşimli API dokümanları da buna göre güncellenir ve birden fazla değere izin verir:

Varsayılanlarla query parametresi listesi / 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] *}

Şu adrese giderseniz:

http://localhost:8000/items/

qnun varsayılanı ["foo", "bar"] olur ve response şöyle olur:

{
  "q": [
    "foo",
    "bar"
  ]
}

Sadece list kullanmak

list[str] yerine doğrudan list de kullanabilirsiniz:

{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}

/// note | Not

Bu durumda FastAPI, listenin içeriğini kontrol etmez.

Örneğin list[int], listenin içeriğinin integer olduğunu kontrol eder (ve dokümante eder). Ancak tek başına list bunu yapmaz.

///

Daha fazla metadata tanımlayın

Parametre hakkında daha fazla bilgi ekleyebilirsiniz.

Bu bilgiler oluşturulan OpenAPIa dahil edilir ve dokümantasyon arayüzleri ile harici araçlar tarafından kullanılır.

/// note | Not

Farklı araçların OpenAPI desteği farklı seviyelerde olabilir.

Bazıları tanımladığınız ek bilgilerin hepsini göstermeyebilir; ancak çoğu durumda eksik özellik geliştirme planındadır.

///

Bir title ekleyebilirsiniz:

{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}

Ve bir description:

{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}

Alias parametreleri

Parametrenin adının item-query olmasını istediğinizi düşünün.

Örneğin:

http://127.0.0.1:8000/items/?item-query=foobaritems

Ancak item-query geçerli bir Python değişken adı değildir.

En yakın seçenek item_query olur.

Ama sizin hâlâ tam olarak item-query olmasına ihtiyacınız var...

O zaman bir alias tanımlayabilirsiniz; bu alias, parametre değerini bulmak için kullanılacaktır:

{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}

Parametreleri deprecated yapmak

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 deprecated olarak göstermesini istiyorsunuz.

O zaman Queryye deprecated=True parametresini geçin:

{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}

Dokümanlarda şöyle görünür:

Parametreleri OpenAPIdan hariç tutun

Oluşturulan OpenAPI şemasından (dolayısıyla otomatik dokümantasyon sistemlerinden) bir query parametresini hariç tutmak için Querynin include_in_schema parametresini False yapın:

{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}

Özel Doğrulama

Yukarıdaki parametrelerle yapılamayan bazı özel doğrulama ihtiyaçlarınız olabilir.

Bu durumlarda, normal doğrulamadan sonra (ör. değerin str olduğunun doğrulanmasından sonra) uygulanacak bir custom validator function kullanabilirsiniz.

Bunu, Annotated içinde Pydanticin AfterValidatorını kullanarak yapabilirsiniz.

/// tip | İpucu

Pydanticte BeforeValidator ve başka validatorlar da vardır. 🤓

///

Örneğin bu custom validator, bir item IDsinin ISBN kitap numarası için isbn- ile veya IMDB 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] *}

/// info | Bilgi

Bu özellik Pydantic 2 ve üzeri sürümlerde mevcuttur. 😎

///

/// tip | İpucu

Veritabanı veya başka bir API gibi herhangi bir harici bileşen ile iletişim gerektiren bir doğrulama yapmanız gerekiyorsa, bunun yerine FastAPI Dependencies kullanmalısınız; onları ileride öğreneceksiniz.

Bu custom validatorlar, requestte sağlanan yalnızca aynı veri ile kontrol edilebilen şeyler içindir.

///

O Kodu Anlamak

Önemli nokta, Annotated içinde bir fonksiyonla birlikte AfterValidator kullanmak. İsterseniz bu kısmı atlayabilirsiniz. 🤸


Ama bu örnek kodun detaylarını merak ediyorsanız, birkaç ek bilgi:

value.startswith() ile String

Fark ettiniz mi? value.startswith() ile bir string, tuple alabilir ve tuple içindeki her değeri kontrol eder:

{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}

Rastgele Bir Item

data.items() ile, her dictionary öğesi için key ve value içeren tuplelardan oluşan bir iterable object elde ederiz.

Bu iterable objecti list(data.items()) ile düzgün bir liste ç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").

Sonra tuple içindeki bu iki değeri id ve name değişkenlerine atarız.

Böylece kullanıcı bir item IDsi vermemiş olsa bile yine de rastgele bir öneri alır.

...bütün bunları tek bir basit satırda yapıyoruz. 🤯 Pythonu sevmemek elde mi? 🐍

{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}

Özet

Parametreleriniz için ek doğrulamalar ve metadata tanımlayabilirsiniz.

Genel doğrulamalar ve metadata:

  • alias
  • title
  • description
  • deprecated

Stringlere özel doğrulamalar:

  • min_length
  • max_length
  • pattern

AfterValidator ile custom doğrulamalar.

Bu örneklerde str değerleri için doğrulamanın nasıl tanımlanacağını gördünüz.

Sayılar gibi diğer tipler için doğrulamaları nasıl tanımlayacağınızı öğrenmek için sonraki bölümlere geçin.