Türkçe
  • python
  • programlama
  • öğrenme
  • sdk

Bir hafta sonunda Python öğrenin: Sıfırdan tam bir projeye

Yeni bir programlama dili nasıl hızlı bir şekilde öğrenebiliriz? Bu makalede, bir hafta sonu boyunca Python öğrenme deneyimimizi, tam bir proje inşa ederek paylaşacağız.

Gao
Gao
Founder

Giriş

Logto, bir kimlik hizmeti olarak, çeşitli programlama dilleri ve frameworkler arasında sorunsuz bir deneyim sağlamak için önemli bir rol oynar. Bu genellikle Yazılım Geliştirme Kitlerinin (SDK'lar) oluşturulmasını içerir. Ancak, programlama dili teknik yığınımızın dışında olduğunda ve ekibimiz aşina olmadığında, sağlam bir SDK oluşturmak zorlu bir görev haline gelir.

Python bizim için böyle bir zorluk oluşturdu. Birçok Python kullanıcısına sahip olmamıza rağmen, bir Python SDK'mız eksikti ve bu bir endişe kaynağıydı. Bu durumu düzeltmeye kararlıydım, bu yüzden bu açığı kapatmaya başladım.

Yılların programlama deneyimi olmasına rağmen, Python benim için nispeten keşfedilmemiş bir alandır. Yıllar önce basit komut dosyaları için kısa bir süre Python 2 ile uğraşmıştım, fakat bilgilerim günceldi değil. Yine de, artık dalmaya hazırdım!

1. Gün: Temelleri Atmak

Amacı Tanımla

Deneyimlerime göre, yeni bir programlama dilini öğrenmenin en etkili yolu, tam bir proje yapmaktır. Neyse ki, amacımız belliydi: Web uygulamaları için bir Logto Python SDK'sı inşa etmek.

Kodlamaya dalmadan önce, işi parçalara ayıralım. İşte yapılacaklar listesi:

  1. Giriş yapma, çıkış yapma, kullanıcı bilgileri ve token yönetimi gibi görevler için Logto istemcisini oluşturun.
  2. SDK kullanımını gösteren bir öğretici ve örnek proje sağlayın.
  3. Kullanıcıların kolaylıkla kurabilmesi için SDK'yı bir yerde yayınlayın.

Görünüşe göre, görev 1 en çok işi gerektiriyor, bu yüzden kapsamı doğrulamalıyız ve daha da ayrıntılandırmalıyız. Bu adım, projenin sınırını güvence altına almak, kapsam genişlemesinden ve aşırı mühendislikten kaçınmak için çok önemlidir.

Ekibimizin önceki çalışmaları bana tonlarca zaman kazandırdı:

  • SDK'ların yapı ve API tasarımını tanımlayan bir SDK konvansiyonu vardı.
  • Farklı diller için mevcut SDK'lar, kalıplara ve Python için potansiyel iyileştirmelere ilişkin içgörüler sağladı.

Bu kaynaklara referans vererek, ne yapmam gerektiğine dair net bir resim gördüm. Spesifikler bu makalenin kapsamı dışında olduğundan, ilerlemeye devam edelim.

Ortamı Kurulum

Bir Mac kullanıyorum, bu yüzden Python zaten yüklü. Ancak, Python sürümlerini yönetmenin daha iyi bir yolu olup olmadığını merak ediyordum (sürüm uyumluluğunun acısını duydum), tıpkı Node.js için nvm gibi. Hızlı bir şekilde pyenv'i buldum ve doğrudan kurulumuna başladım.

Sıradaki gündemde, bir paket ve bağımlılık yöneticisi var. Genelde bunlar birleştirildiği için neden pip (Python'un varsayılanı) olmasın? requirements.txt'ye bir göz atarsanız, bunun sadece sürümlerle birlikte bir paket listesi olduğunu göreceksiniz. Bu, diğer projeler tarafından kullanılabilecek bir SDK için yeterli değil. Örneğin, geliştirme için bazı paketler eklememiz gerekebilir, ancak bunları nihai SDK'ya dahil etmek istemeyiz. requirements.txt bu durumu ele almak için çok basittir.

Başka programlama dillerinin teknik yığınızdadır olduğunda, "Python karşılığı" arayabilirsiniz. Bu yüzden "package.json Python karşılığı" için arama yaptım ve mükemmel bir aday olan Poetry ile karşılaştım:

  • Hem bir paket yöneticisi, bağımlılık yöneticisi, hem de sanal ortam yöneticisi olarak işlev görür.
  • Node.js'deki package.json'a benzer bir pyproject.toml dosyasına sahiptir.
  • Tam bağımlılık sürümleri kaydetmek için bir kilit dosyası kullanır.

Modern CLI'ler genellikle yeni projeler için uyarlanmış bir init komutunu içerir. Poetry de öyle. Komutu çalıştırdım ve benim için bir pyproject.toml dosyası oluşturdu.

İlk Satır Kod

Sonunda, kod yazma anı geldi. Klasik "Merhaba, Dünya!" programıyla başlamak her zaman iyi bir seçimdir. Bir programlama dili öğrenirken, tam teşekküllü IDE'ler her zaman gerekli değildir; güçlü bir topluluğa sahip bir editör, örneğin VS Code, tamamen yeterlidir.

SDK'mızın odak noktası web uygulamaları olduğundan, popüler frameworklerden Flask kullanarak basit bir web sunucusuyla başladım.

Poetry'nin yeteneklerinden yararlanarak, Flask'i kurmak poetry add flask komutunu çalıştırarak kolayca yapılabilir. Ardından, Flask'in resmi hızlı başlangıç kılavuzunu takip ederek, aşağıdaki parça ile bir 'hello.py' dosyası oluşturdum:

Sunucuyu flask --app hello run komutuyla başlattım, ardından tarayıcımda http://localhost:5000 adresine giderek arzuladığım sonuca ulaştım. Oldu!

Bir acemi olarak, daha fazla kod yazmak için acele etmedim. Bunun yerine, bu kod parçasından alınacak birçok bilgi var:

  • Bir modül veya sınıfı ithal etmek için from x import y kullanın.
  • Satır sonlandırmak için noktalı virgül kullanmamıza gerek yok (ah hayır).
  • Rastgele isim girerek yeni bir değişken tanımlayabileceğimiz ve ona bir değer atayabileceğimiz.
  • new anahtar kelimesi olmadan bir sınıfın bir örneğini oluşturabileceğimiz.
  • Python'un dekoratörleri desteklediği ve @app.route'nin bir işlevi route handler olarak kaydeden bir dekoratör olduğu.
    • İşleve döndürülen değer, yanıtın gövdesi olarak yorumlanır.
  • Bir fonksiyon tanımlamak için def anahtar kelimesinin kullanıldığı.

Gördüğünüz gibi, kodu "sadece çalıştırmak" yerine her satırını anlamaya çalışırsak, çok şey öğrenebiliriz. Bu arada, Flask'in resmi belgeleri de snippet'i ayrıntılı olarak açıkladı.

Proje Başlangıcı

Artık projeye başlama zamanı geldi. Kısa bir süre sonra bir LogtoClient sınıfı tanımladım ve dili hissetmek için bazı özellikler ve metodlar eklemeye çalıştım:

Ardından, sınıfı Flask ile entegre edin:

Gerçek bir proje gibi hissetmeye başladı. Ama bir şeyin eksik olduğunu hissettim: bir tür sistemi.

Tip Sistemi

Bu bir SDK olduğundan, bir tür sistemi eklemek kullanıcıların API'yi anlamasına ve geliştirme sırasında hata yapma olasılığını azaltmasına yardımcı olacaktır.

Python 3.5 sürümünde tür ipuçlarını tanıttı. TypeScript kadar güçlü olmasa da, hiç yoktan iyidir. LogtoClient sınıfına bazı tür ipuçları ekledim:

Şimdi çok daha iyi görünüyor. Ancak, önceden tanımlanmış anahtarlara sahip bir nesne gibi karmaşık bir tür geldiğinde zorluklar ortaya çıkıyor. Örneğin, yapılandırma nesnesini temsil etmek için bir LogtoConfig sınıfı tanımlamamız gerekiyor:

Bu iyi görünüyor, ancak kısa süre sonra, nesnenin JSON'dan kodlanması, çözülmesi ve doğrulanması sorunlarıyla karşılaşmamız gerekecek.

Biraz araştırma yaptıktan sonra, pydantic çözüm olarak seçtim. Verilerin doğrulanması için bir kütüphane ve tür ipuçları ile birlikte çalışır. Sıkıcı şablon kodları izlemeksizin çeşitli JSON işlevlerini destekler.

Böylece, LogtoConfig sınıfı şu şekilde yeniden yazılabilir:

Ayrıca, sınıf miras alma konusunu, sınıf adından sonra parantez ekleyerek Python'da nasıl yapılacağını öğretti.

Asenkron İşlemler

Logto SDK içinde, Logto sunucusuna HTTP istekleri yapmak zorundayız. JavaScript deneyiminiz varsa, "callback hell" ifadesi muhtemelen aklınıza gelir. Bu, asenkron işlemlerle uğraşırken sıkça karşılaşılan bir sorundur. Modern programlama dilleri, Promise veya coroutine gibi benzer çözümler sunar.

Neyse ki, Python'da yerleşik bir async ve await çözümü var. Onları kullanmadan önce, popüler framework'ler ile uyumluluğunu sağlamak gerekir. Flask'te, bu async ekstra'sını kurarak ve def yerine async def kullanarak yapılabilir:

Ardından, bir asenkron işlemin sonucunu beklemek için await kullanabiliriz.

HTTP İstekleri

HTTP istekleri ilginç bir konudur. Hemen hemen her programlama dilinin bir yerel çözümü vardır, ancak geliştiriciler genellikle kullanımı kolay bir üçüncü taraf kütüphanesini tercih ederler. Bazı örnekler:

  • JavaScript: XMLHttpRequest vs. fetch vs. axios
  • Swift: URLSession vs. Alamofire
  • Java: HttpURLConnection vs. OkHttp

Bu Python için de geçerlidir. Kararım aiohttp kullanmaktı çünkü async ve await'i destekler ve popülerdir.

Copilot Büyüsü

Copilot'tan önce, iş mantığı yazmanın sıkıcı kısmına gelmeliydik. SDK konvansiyonunun ve diğer SDK'ların yardımıyla, her yöntem için açıklayıcı yorumları yazabilir, ardından kodu yazabilirdim.

Bu, kodun okunabilirliğini artırır ve ayrıca geliştiricilerin API'yi IDE veya editör aracılığıyla kod zekası ile anlamalarına yardımcı olur.

Örneğin, generateCodeChallenge yöntemini göz önüne alırsak, yorumlar şu şekilde yazılabilir:

Bu, Büyük Dil Modelleri (LLM'ler) için mükemmel bir ipucu oluşturdu: açık yorumlarla yöntem tanımları yazmayı. Ve Copilot hayal kırıklığına uğratmadı:

Biraz ince ayar gerekebilir, ancak bu önemli değil. Olan şey zaten oyunu değiştirdi.

Günün Sonu

Bu, ilk gün elde edilen ilerlemeyi aşağı yukarı özetliyor. Uzun bir gündü, ancak modern araçlar ve teknolojiler sayesinde beklediğimden çok daha iyiydi.

2. Gün: Çıtayı Yükselmek

Birinci günün çalışmasına dayanarak, iş mantığı hızla tamamlandı. Ama bir SDK için hala yetersiz. İşte ikinci gün için görevler:

  • Birim testleri ekleyin.
  • Kod formatı zorlayın.
  • Python sürüm uygunluğunu doğrulayın.
  • Sürekli entegrasyon ekleyin.
  • SDK'yı yayınlayın.

Birim Testleri

Birim testleri bizi birçok kez kurtardı, bu yüzden atlamayacağım. İşte birim testi yazarken yaygın olarak dikkate alınanlar:

  • Testleri nasıl organize eder ve çalıştırırsınız?
  • Sonucu nasıl doğrularsınız?
  • Asenkron testleri nasıl çalıştırırsınız? (beleş bir şey gibi görünebilir, ancak bazı dillerde ara sıra sorun yaratabilir.)
  • Bağımlılıkları nasıl taklit ettiğiniz? (Bu konuya dalmadan önce kaçının çünkü yapıldığında tavşan deliğine yol açabilir.)
  • Kod kapsamı raporlarını nasıl oluşturursunuz?

Bu sorularla, bazı durumlar için yerleşik unittest modülünün yetersiz olduğunu gördüm. Bu yüzden test çerçevesi olarak pytest seçtim. Asenkron testleri destekler ve yeterince olgun görünüyor.

Yolculuk boyunca fixture gibi bazı ilginç yeni kavramlar keşfettim. Bu aynı zamanda diğer dillerde kod yazarken zihniyeti de olumlu yönde etkileyebilir.

Kod Formatı

Her dilin kendi kod formatı stilleri vardır. Kişisel olarak, tutarlı formatlama beni mutlu ve rahat hissettirir; aynı zamanda kod incelemesi ve işbirliği için de faydalıdır.

"En iyi" stil tartışmasını gözden geçirmek yerine, ben karar verdim ki bir kesin karar verici editör seçip buna sadık kalmak en iyisi.

Black iyi bir seçim gibi görünüyor. Tek can sıkıcı olan, kare boyutunun değiştirilememesi. Ama bu büyük bir sorun değil, onunla uyum sağlama kararı aldım.

Python Sürüm Uyumluluğu

Bir SDK olarak, yaygın Python sürümleri arasında uyumlu olmalıdır. "python sürüm kullanım istatistikleri" araması yaparak, Python 3.8'i minimum sürüm olarak kullanmaya karar verdim.

Çevre yöneticisinin kullanışlılığı şimdi ortaya çıkıyor. pyenv local 3.8 ve poetry env use 3.8 çalıştırarak Python sürümünü kolayca değiştirebilirim. Ardından, uyumluluk sorunlarını ortaya çıkarmak için testleri çalıştırabilirim.

Sürekli Entegrasyon

Sürekli entegrasyon, her kod değişikliğinin kalitesini garanti eder. Depomuz GitHub'da barındırıldığından, GitHub Actions doğal seçimdir.

Ana iş akışı temel prensiplere dayanır:

  • Ortamı ayarlayın.
  • Bağımlılıkları kurun.
  • Projeyi derleyin (Python için ihtiyaç yok).
  • Testleri çalıştırın.

GitHub Actions iyi bir topluluğa sahiptir, bu nedenle iş akışını oluşturmak birkaç dakikanızı alır.

Matrix stratejilerini kullanarak, iş akışını farklı Python sürümlerinde, hatta farklı işletim sistemlerinde çalıştırabiliriz.

SDK'yı Yayınlama

Son adım SDK'yı yayınlamaktır. Herkese açık paketler için bu genellikle resmi programlama dili spesifik paket kayıt defterine sunarak yapılır. Örneğin, Node.js için npm, Python için PyPI ve Swift için CocoaPods.

Poetry benim rehberim oldu. poetry publish çalıştırarak paketi PyPI'a yayınlayabilirsiniz. Bu kadar basit.

Kapanış Düşünceleri

Etkileyici bir yolculuktu. Açık kaynak topluluğunun yardımı olmadan, çok daha zor olurdu. Tüm katkıda bulunanlara alkışlar!

İşte bazı genel çıkarımlar:

  • Amacı tam olarak belirleyin ve bunu kırın, ardından her zaman amacı aklınızda tutun.
  • Kararlı ve yeniden üretilebilir bir geliştirme ortamı kurun.
  • (İyi) araçları olabildiğince kullanın.
  • Yerleşik veya mevcut çözümleri önceliklendirin.
  • Dil konvansiyonlarını ve yazdığınız her satır kodu anlayın.
    • Ancak, ayrıntılara takılıp kalmayın.
  • Copilot'u açık, tanımlayıcı görevler için kullanın.

Sonuçları bu depoda bulabilirsiniz. Aynı stratejiyle Logto PHP SDK'yı da hızlı bir şekilde inşa ettim. Herhangi bir öneriniz varsa, bize bildirmekten çekinmeyin.

Umarım bu makale yeni bir programlama dili öğrenmenize yardımcı olur. Keyifli hacklemeler!