FastAPI | Basit Hızlı Örnekle İnceleme

Nabi Güzel
Huawei Developers - Türkiye
5 min readJul 1, 2022
FastAPI framework, high performance, easy to learn, fast to code, ready for production

Giriş

Herkese merhaba,

Daha önce bir kaç yerde duyduğum FastAPI teknolojisi kısa bir süre önce temelde inceleyip basit bir örnek oluşturma fırsatım oldu. Bu makalemde çalışma sürecinde tuttuğum notlarımı, birinin işine yarar düşüncesi ile derleyip paylaşıyorum.

Nedir bu FastAPI?

FastAPI bir RestAPI geliştirme aracıdır. Kendilerinin deyimi ile “FastAPI kütüphanesi, yüksek performans, öğrenmesi kolay, kodlaması hızlı, üretime hazır” bir kütüphanedir.

Nasıl yüklerim? (Setup)

FastAPI yüklemek için öncelikle bilgisayarınızda “pip -V” komutunun bir karşılığı olmak zorunda. Yüklemek için ise doküman sitesi olan pip.pypa.io yer alan adımları izleyebilirsiniz.

“pip” yükleme işlemi tamamlandıktan sonra FastAPI yüklemesi için çalıştırmanız gereken komut:

pip install fastapi

Ayrıca localde bir sunucuya ihtiyacınız olacak. Bunun için çalıştırmanız gereken komut:

pip install "uvicorn[standart]"

Proje Oluşturma ve Çalıştırma

Yüklemeler bittikten sonra bir proje klasörü açıp içinde bir tane “main.py” dosyası oluşturalım. (Bu çalışma için oluşturduğum “main.py” dosyasına ait gisti, kodları bir bütün halinde içerir şekilde makale sonunda paylaştım.)

Dosya oluşturduktan sonra geliştirmeye sürecinde yapacağımız değişiklikleri bize anlık olarak test imkanı sunan bir sunucu çalıştırmak gerekiyor. Anlık değişiklikleri algılayan bir sunucu için çalıştırmanız gereken komut:

uvicorn main:app --reload

Proje Yapısı

Ben bu projede temelde sadece bir dosya üzerinden geliştirme yapıyorum, amacım en temelde birer GET, POST, PUT, DELETE istekleri oluşturmak, bunun için ise klasik “Todo” uygulamasını ele aldım.

İsteğe bağlı olarak bu klasör altında ilerleyişe göre hiyerarşik bir dosya yapısı kurulabilir. Örneğin “routers” isminde oluşturulacak bir klasör altında farklı dosyalarda “routing” kümelemesi oluşturulabilir.

Hello World, nasıl yazarım?

“Hello World” öğrenmeye yeni başlanan bir dilin veya teknolojinin öncelikli ilk kodlamasıdır. :) Bu amaçla oluşturduğum aşağıdaki kodda, en temelde bir GET isteği oluşturmuş oldum. Aynı zamanda FastAPI otomatik olarak Swagger arayüzüne sahip bir döküman sayfası oluşturmuş oldu.

Swagger dosyasını, komut ekranında (cmd, terminal) sunucu başlatıldıktan sonra yazan local çalışma linkini, taratıcıdan sonuna “/docs” ekleyerek açabiliriz. Örneğin:

http://127.0.0.1:8000/docs

Dokümantasyon için Swagger özelliklerini nasıl uygularım?

Yukarıdaki örnekte yazan fonksiyon ismi “camelCase” olursa, dokümanda aşağıda görüldüğü üzere “Saygreeting” gibi yazar, ama “say_greeting” şeklinde yazsaydık “Say Greeting” yazacaktı.

Fonksiyon isimlerini belirttiğime bağlı kalarak yazmak yerine, istediğimiz gibi yazıp, aşağıda yazıldığı gibi istek türünü yazdığımız yerde de, ikinci bir parametre olarak, FastAPI OpenAPI 3.0 uyumlu olduğu için, “summary” parametresini kullanarak da yazabiliriz.

@app.get("/", summary="Say Greeting")

Kullanılabilecek diğer parametreler için Swagger dokümanını gözden geçirebilirsiniz.

http://127.0.0.1:8000/docs

CRUD nasıl yazarım?

Ben bu çalışmada şimdilik herhangi bir veritabanı kullanmadan, boş bir dizi oluşturup onun içine ekleme, listeleme, güncelleme ve silme komutlarını gerçekleştirecek istekleri yazdım.

İstek türünü(GET, POST, PUT, DEL) nasıl tanımlarım?

Öncelikle istek türünü, ilgili işlemi yapacak fonksiyonun üzerinde yazılan kısım belirlemekte. Yukarıdaki örnekte olduğu gibi “@app.get(“/”) hemen altında yazan fonksiyona GET isteği ile erişilebileceğini belirtmiştir.

“id” gibi “query” değişken parametreleri ise süslü parantez içinde yazmanız yeterli olacaktır.

Ben yazdığım istekleri swagger dokümanında “todo” altında gruplandırabilmek için, aşağıdaki görselde yer aldığı gibi, istek türüne “tags” parametresini ekleyip içine “Todo” eklemem yeterli oldu.

Parametreleri(path, query, body) nasıl belirlerim?

Fonksiyona gelecek parametre türünün “Path” mi yoksa “Query” mi olacağını fonksiyon parametresi olarak belirleyebiliriz, yukarıdaki örnekte “getTodoDetail” fonksiyonda “Path” kullanımında olduğu gibi. Ayrıca parametrenin yanında görünmesini istediğiniz notu, “Query” veya “Path” içinde “description” parameresini kullanarak yazabilirsiniz.

“getToDetail” fonksiyonu parametre “description” metin gösterimi
“Body” ile gönderilen “TodoCreate” parametre gösterimi

Validasyonları nasıl belirlerim?

“Post”, “Patch”, “Put” gibi isteklerde, isteğin “body” elemanı olarak gelecek objenin ne olacağını parametre içinde ilgili obje tip ataması ile belirleyebiliyoruz. Ayrıca bu belirleme otomatik validasyonu da aktif etmektedir. Örneğin gerçekleştireceğim bir “post” isteği şayet “body” içinde 20 karakterden uzun bir değeri olan “title” parametresine sahip ise, “title” değeri maksimum 20 karakter olabildiği için sistem otomatik olarak bana aşağıdaki görselde yer alan hatayı döndürmekte.

Dönüş tipini doğrudan yazacağınız “JSON” yapısı ile belirleyebildiğimiz gibi ayrıca yukarıdaki “get” kod görselinde yer alan “JSONResponse” kullanımı ile dönüşün “status” değerini de belirleyebilmekteyiz.

Her ne kadar FastAPI ile değil de “python” ile ilgili olmasına rağmen not olarak kalması açısından yazıyorum; “getTodoDetail” fonksiyonunda yazan “… next(filter(lambda…” ile başlayan kısımda “next” ifadesi sayesinde filtreleme sonucunda tek bir eleman dönmektedir. Şayet dizi olarak, yani liste halinde dönmesini istediğimde “getTodoList” fonksiyonunda olduğu gibi “list” ifadesini “ … list(filter(lambda…” olduğu gibi yazmam gerekiyordu.

Modelleri nasıl yazarım?

Kullanılacak istekte kısıtlamaları model üzerinde yapılmakta olup ilgili isteğe özel model yazmak gerekiyor.

Örneğin “Update” modelini BaseModel olarak ele aldım çünkü burada yer alacak tüm parametreler güncellemede opsiyonel olarak gelmekte. Yani kullanıcı sadece zorunlu alan olmayan bir parametre olan “tags” üzerinde güncelleme yapmak isteyebilir. Ayrıca “id” değerini Update modelinde yazmadım çünkü kullanıcı bu parametreye güncellemede erişememesi gerekiyor. “Create” için oluşturduğum model parametrelerine dikkat ederseniz, onların opsiyonel olma durumlarını kaldırdım, böylelikle kullanıcı o parametreleri göndermek zorunda kalıyor.

Çıktı

Yukarıda parça parça verdiğim kodları bir bütün haline getirdiğimizde aşağıda yer alan gist dökümanında olduğu gibi bir kod elde ederiz. Ayrıca bu kodu çalıştırdığımızda tarayıcıdan da aşağıdaki Swagger dokümanı arayüzüne erişim sağlayabiliriz.

“main.py” dosyası Swagger doküman çıktısı
Üzerinde çalıştığım tüm kodları içeren “main.py” dosyası

Sonuç

Gördüğünüz üzere FastAPI ile servis istekleri oluşturmak oldukça basit. Bu aşamadan sonra kendi mantıksal işlemlerimizi içeren kodlamaların eklenmesi ile daha kullanışlı bir projenin hızlı bir şekilde üretilmesi mümkündür. Örneğin; bir veritabanı entegrasyonu ekleyip o veri tabanı üzerinde işlemleri yapacak kodları kolaylıkla ekleyebiliriz.

İyi kodlamalar…

--

--