FastAPI
FastAPI framework, yüksek performanslı, öğrenmesi oldukça kolay, kodlaması hızlı, kullanıma hazır
Dokümantasyon: https://fastapi.tiangolo.com
Kaynak Kod: https://github.com/tiangolo/fastapi
FastAPI, Python 3.8+'nin standart tip belirteçlerine dayalı, modern ve hızlı (yüksek performanslı) API'lar oluşturmak için kullanılabilecek web framework'tür.
Temel özellikleri şunlardır:
- Hızlı: Çok yüksek performanslı, NodeJS ve Go ile eşit düzeyde (Starlette ve Pydantic sayesinde). En hızlı Python framework'lerinden bir tanesidir.
- Kodlaması Hızlı: Geliştirme hızını yaklaşık %200 ile %300 aralığında arttırır. *
- Daha az hata: İnsan (geliştirici) kaynaklı hataları yaklaşık %40 azaltır. *
- Sezgisel: Muhteşem bir editör desteği. Her yerde otomatik tamamlama. Hata ayıklama ile daha az zaman harcayacaksınız.
- Kolay: Öğrenmesi ve kullanması kolay olacak şekilde tasarlandı. Doküman okuma ile daha az zaman harcayacaksınız.
- Kısa: Kod tekrarı minimize edildi. Her parametre tanımlamasında birden fazla özellik ve daha az hatayla karşılaşacaksınız.
- Güçlü: Otomatik ve etkileşimli dokümantasyon ile birlikte, kullanıma hazır kod elde edebilirsiniz.
- Standard öncelikli: API'lar için açık standartlara dayalı (ve tamamen uyumlu); OpenAPI (eski adıyla Swagger) ve JSON Schema.
* ilgili kanılar, dahili geliştirme ekibinin geliştirdikleri ürünlere yaptıkları testlere dayanmaktadır.
Sponsorlar¶
Görüşler¶
"[...] Bugünlerde FastAPI'ı çok fazla kullanıyorum. [...] Aslında bunu ekibimin Microsoft'taki Machine Learning servislerinin tamamında kullanmayı planlıyorum. Bunlardan bazıları Windows'un ana ürünlerine ve Office ürünlerine entegre ediliyor."
"FastAPI'ı tahminlerimiz'i sorgulanabilir hale getirecek bir REST sunucu oluşturmak için benimsedik/kullanmaya başladık."
"Netflix, kriz yönetiminde orkestrasyon yapabilmek için geliştirdiği yeni framework'ü Dispatch'in, açık kaynak sürümünü paylaşmaktan gurur duyuyor. [FastAPI ile yapıldı.]"
"FastAPI için ayın üzerindeymişcesine heyecanlıyım. Çok eğlenceli!"
"Dürüst olmak gerekirse, inşa ettiğiniz şey gerçekten sağlam ve profesyonel görünüyor. Birçok açıdan Hug'ın olmasını istediğim şey tam da bu - böyle bir şeyi inşa eden birini görmek gerçekten ilham verici."
"Eğer REST API geliştirmek için modern bir framework öğrenme arayışında isen, FastAPI'a bir göz at [...] Hızlı, kullanımı ve öğrenmesi kolay. [...]"
"API servislerimizi FastAPI'a taşıdık [...] Sizin de beğeneceğinizi düşünüyoruz. [...]"
"Python ile kullanıma hazır bir API oluşturmak isteyen herhangi biri için, FastAPI'ı şiddetle tavsiye ederim. Harika tasarlanmış, kullanımı kolay ve yüksek ölçeklenebilir, API odaklı geliştirme stratejimizin ana bileşeni haline geldi ve Virtual TAC Engineer gibi birçok otomasyon ve servisi yönetiyor."
Komut Satırı Uygulamalarının FastAPI'ı: Typer¶
Eğer API yerine, terminalde kullanılmak üzere bir komut satırı uygulaması geliştiriyorsanız Typer'a göz atabilirsiniz.
Typer kısaca FastAPI'ın küçük kardeşi. Ve hedefi komut satırı uygulamalarının FastAPI'ı olmak. ⌨️ 🚀
Gereksinimler¶
Python 3.8+
FastAPI iki devin omuzları üstünde duruyor:
Kurulum¶
$ pip install fastapi
---> 100%
Uygulamamızı kullanılabilir hale getirmek için Uvicorn ya da Hypercorn gibi bir ASGI sunucusuna ihtiyacımız olacak.
$ pip install "uvicorn[standard]"
---> 100%
Örnek¶
Kodu Oluşturalım¶
main.py
adında bir dosya oluşturup içine şu kodu yapıştıralım:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Ya da async def
...
Eğer kodunuzda async
/ await
varsa, async def
kullanalım:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Not:
Eğer bu konu hakkında bilginiz yoksa async
ve await
dokümantasyonundaki "Aceleniz mi var?" kısmını kontrol edebilirsiniz.
Kodu Çalıştıralım¶
Sunucuyu aşağıdaki komutla çalıştıralım:
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
uvicorn main:app --reload
komutuyla ilgili...
uvicorn main:app
komutunu şu şekilde açıklayabiliriz:
main
: dosya olanmain.py
(yani Python "modülü").app
: isemain.py
dosyasının içerisindeapp = FastAPI()
satırında oluşturduğumuzFastAPI
nesnesi.--reload
: kod değişikliklerinin ardından sunucuyu otomatik olarak yeniden başlatır. Bu parameteyi sadece geliştirme aşamasında kullanmalıyız.
Şimdi de Kontrol Edelim¶
Tarayıcımızda şu bağlantıyı açalım http://127.0.0.1:8000/items/5?q=somequery.
Aşağıdaki gibi bir JSON yanıtıyla karşılaşacağız:
{"item_id": 5, "q": "somequery"}
Az önce oluşturduğumuz API:
/
ve/items/{item_id}
yollarına HTTP isteği alabilir.- İki yolda
GET
operasyonlarını (HTTP metodları olarak da bilinen) kabul ediyor. /items/{item_id}
yoluitem_id
adında bir yol parametresine sahip ve bu parametreint
değer almak zorundadır./items/{item_id}
yoluq
adında bir yol parametresine sahip ve bu parametre opsiyonel olmakla birlikte,str
değer almak zorundadır.
Etkileşimli API Dokümantasyonu¶
Şimdi http://127.0.0.1:8000/docs bağlantısını açalım.
Swagger UI tarafından sağlanan otomatik etkileşimli bir API dokümantasyonu göreceğiz:
Alternatif API Dokümantasyonu¶
Şimdi http://127.0.0.1:8000/redoc bağlantısını açalım.
ReDoc tarafından sağlanan otomatik dokümantasyonu göreceğiz:
Örneği Güncelleyelim¶
Şimdi main.py
dosyasını, PUT
isteğiyle birlikte bir gövde alacak şekilde değiştirelim.
Gövdeyi Pydantic sayesinde standart python tiplerini kullanarak tanımlayalım.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
Sunucu otomatik olarak yeniden başlamış olmalı (çünkü yukarıda uvicorn
komutuyla birlikte --reload
parametresini kullandık).
Etkileşimli API Dokümantasyonundaki Değişimi Görelim¶
Şimdi http://127.0.0.1:8000/docs bağlantısına tekrar gidelim.
- Etkileşimli API dokümantasyonu, yeni gövdede dahil olmak üzere otomatik olarak güncellenmiş olacak:
- "Try it out" butonuna tıklayalım, bu işlem API parametleri üzerinde değişiklik yapmamıza ve doğrudan API ile etkileşime geçmemize imkan sağlayacak:
- Şimdi "Execute" butonuna tıklayalım, kullanıcı arayüzü API'ımız ile bağlantı kurup parametreleri gönderecek ve sonucu ekranımıza getirecek:
Alternatif API Dokümantasyonundaki Değişimi Görelim¶
Şimdi ise http://127.0.0.1:8000/redoc bağlantısına tekrar gidelim.
- Alternatif dokümantasyonda yaptığımız değişiklikler ile birlikte yeni sorgu parametresi ve gövde bilgisi ile güncelemiş olacak:
Özet¶
Özetlemek gerekirse, parametrelerin, gövdenin, vb. veri tiplerini fonksiyon parametreleri olarak bir kere tanımlıyoruz.
Bu işlemi standart modern Python tipleriyle yapıyoruz.
Yeni bir sözdizimi yapısını, bir kütüphane özel metod veya sınıfları öğrenmeye gerek yoktur.
Hepsi sadece Python 3.8+ standartlarına dayalıdır.
Örnek olarak, int
tanımlamak için:
item_id: int
ya da daha kompleks herhangi bir python modelini tanımlayabiliriz, örneğin Item
modeli için:
item: Item
...ve sadece kısa bir parametre tipi belirterek elde ettiklerimiz:
- Editör desteğiyle birlikte:
- Otomatik tamamlama.
- Tip kontrolü.
- Veri Doğrulama:
- Veri geçerli değilse, otomatik olarak açıklayıcı hatalar gösterir.
- Çok derin JSON nesnelerinde bile doğrulama yapar.
- Gelen verinin dönüşümünü aşağıdaki veri tiplerini kullanarak gerçekleştirir:
- JSON.
- Yol parametreleri.
- Sorgu parametreleri.
- Çerezler.
- Headers.
- Formlar.
- Dosyalar.
- Giden verinin dönüşümünü aşağıdaki veri tiplerini kullanarak gerçekleştirir (JSON olarak):
- Python tiplerinin (
str
,int
,float
,bool
,list
, vb) dönüşümü. datetime
nesnesi.UUID
nesnesi.- Veritabanı modelleri.
- ve çok daha fazlası...
- Python tiplerinin (
- 2 alternatif kullanıcı arayüzü dahil olmak üzere, otomatik etkileşimli API dokümantasyonu sağlar:
- Swagger UI.
- ReDoc.
Az önceki örneğe geri dönelim, FastAPI'ın yapacaklarına bir bakış atalım:
item_id
'ninGET
vePUT
istekleri için, yolda olup olmadığının kontol edecek.item_id
'ninGET
vePUT
istekleri için, tipininint
olduğunu doğrulayacak.- Eğer değilse, sebebini belirten bir hata mesajı gösterecek.
- Opsiyonel bir
q
parametresininGET
isteği içinde (http://127.0.0.1:8000/items/foo?q=somequery
gibi) olup olmadığını kontrol edecekq
parametresini= None
ile oluşturduğumuz için, opsiyonel bir parametre olacak.- Eğer
None
olmasa zorunlu bir parametre olacaktı (PUT
metodunun gövdesinde olduğu gibi).
PUT
isteği için/items/{item_id}
'nin gövdesini, JSON olarak doğrulayıp okuyacak:name
adında zorunlu bir parametre olup olmadığını ve varsa tipininstr
olup olmadığını kontol edecek.price
adında zorunlu bir parametre olup olmadığını ve varsa tipininfloat
olup olmadığını kontol edecek.is_offer
adında opsiyonel bir parametre olup olmadığını ve varsa tipininfloat
olup olmadığını kontol edecek.- Bunların hepsi en derin JSON nesnelerinde bile çalışacak.
- Verilerin JSON'a ve JSON'ın python nesnesine dönüşümü otomatik olarak yapılacak.
- Her şeyi OpenAPI ile uyumlu bir şekilde otomatik olarak dokümanlayacak ve bunlarda aşağıdaki gibi kullanılabilecek:
- Etkileşimli dokümantasyon sistemleri.
- Bir çok programlama dili için otomatik istemci kodu üretim sistemleri.
- İki ayrı etkileşimli dokümantasyon arayüzünü doğrudan sağlayacak.
Daha yeni başladık ama çalışma mantığını çoktan anlamış oldunuz.
Şimdi aşağıdaki satırı değiştirmeyi deneyin:
return {"item_name": item.name, "item_id": item_id}
...bundan:
... "item_name": item.name ...
...buna:
... "item_price": item.price ...
...ve editörünün veri tiplerini bildiğini ve otomatik tamamladığını göreceksiniz:
Daha fazal özellik içeren, daha eksiksiz bir örnek için Öğretici - Kullanıcı Rehberi sayfasını ziyaret edebilirsin.
Spoiler: Öğretici - Kullanıcı rehberi şunları içerir:
- Parameterlerin, headers, çerezler, form alanları ve dosyalar olarak tanımlanması.
maximum_length
ya daregex
gibi doğrulama kısıtlamalarının nasıl yapılabileceği.- Çok güçlü ve kullanımı kolay Bağımlılık Enjeksiyonu sistemi oluşturmayı.
- Güvenlik ve kimlik doğrulama, JWT tokenleri ile OAuth2 desteği, ve HTTP Basic doğrulaması.
- İleri seviye fakat bir o kadarda basit olan çok derin JSON modelleri (Pydantic sayesinde).
- GraphQL entegrasyonu: Strawberry ve diğer kütüphaneleri kullanarak.
- Diğer ekstra özellikler (Starlette sayesinde):
- WebSocketler
- HTTPX ve
pytest
sayesinde aşırı kolay testler. - CORS
- Cookie Sessions
- ...ve daha fazlası.
Performans¶
Bağımsız TechEmpower kıyaslamaları gösteriyor ki, Uvicorn ile çalıştırılan FastAPI uygulamaları en hızlı Python framework'lerinden birisi, sadece Starlette ve Uvicorn'dan yavaş, ki FastAPI bunların üzerine kurulu bir kütüphanedir.
Daha fazla bilgi için, bu bölüme bir göz at Kıyaslamalar.
Opsiyonel Gereksinimler¶
Pydantic tarafında kullanılan:
email_validator
- email doğrulaması için.pydantic-settings
- ayar yönetimi için.pydantic-extra-types
- Pydantic ile birlikte kullanılabilecek ek tipler için.
Starlette tarafında kullanılan:
httpx
- EğerTestClient
yapısını kullanacaksanız gereklidir.jinja2
- Eğer varsayılan template konfigürasyonunu kullanacaksanız gereklidir.python-multipart
- Eğerrequest.form()
ile form dönüşümü desteğini kullanacaksanız gereklidir.itsdangerous
-SessionMiddleware
desteği için gerekli.pyyaml
-SchemaGenerator
desteği için gerekli (Muhtemelen FastAPI kullanırken ihtiyacınız olmaz).ujson
-UJSONResponse
kullanacaksanız gerekli.
Hem FastAPI hem de Starlette tarafından kullanılan:
uvicorn
- oluşturduğumuz uygulamayı servis edecek web sunucusu görevini üstlenir.orjson
-ORJSONResponse
kullanacaksanız gereklidir.
Bunların hepsini pip install fastapi[all]
ile yükleyebilirsin.
Lisans¶
Bu proje, MIT lisansı şartları altında lisanslanmıştır.