Klasör Yapısı¶
Kopyalacağınız proje ile ilgili klasör ve dosya yapısı aşağıdaki gibidir. ChannelTemplateApp projesini kullanan firmaların yeni satış kanalı geliştirmek için channel klasörü altındaki ilgili sınıfları geliştirmeleri beklenmektedir.
channel_app_template├── akinon└── integration.py├── channel└── integration.py└── commands.py└── setup.py└── products.py└── product_prices.py└── product_stocks.py└── product_images.py└── orders└── orders.py├── app└── tasks.py└── celery_app└── celery.py└── celery_schedule_conf.py└── celeryconfig.py
Başlangıç Adımı¶
Dikkat
Geliştirmeye başlamadan önce aşağıdaki ayarları yapmak gerekiyor.
setup.py dosyasına yer alan proje adı, versiyon bilgisi, uygulamanın depolandığı (bitbucket, github vb…) reponun url’i, uygulamanın tanımı, uygulamanın yazar veya yazarları, python versiyon zorunluluğu ve kurulu olması gereken paketlerin listesi gibi bilgilerin girilmesi gerekiyor.
channel_app_template/celery_app/celery_schedule_conf.py içerisinde yer alan CELERYBEAT_SCHEDULE objesi içerisinde çalışmasını istediğiniz süreçler bulunmaktadır. Akinon ile yapılacak satış kanalı entegrasyonunda kullanılacak süreçler ön tanımlı olarak yazılmış ve yorum satırına alınmıştır. Düzenli aralıklar ile çalışmasını gereken süreçleri yorum satırından kaldırıp, ne sıklık ile çalışması gerektiğini yazabilirsiniz.
- class channel_app_template.channel.integration.ChannelIntegration¶
Actions özelliğinde yer alan komutlar aracılığı ile Satış Kanalının servisleri haberleşir. Her komut üzerinde get_data, validated_data, transform_data, send_request ve normalize_response fonksiyonlarını barındırmak zorundadır
- channel¶
Satış kanalı objesidir. Channel Detaylı Bilgi Örnek channel objesi.
Schema alanında FAILED_INTEGRATION, ATTRIBUTE_SET_STRATEGY eklenmsi zorunlu alanlardır.
1. ATTRIBUTE_SET_STRATEGY: “CategoryNode” veya “None” değerleri alabilir. Category nodeların attribute setlerin category bağlı olup olmadığı bilgisi için gereklidir.
FAILED_INTEGRATION: Hata alınan işlemlerin tekrar edilmesi için gereken sürelerin girildiği alandır.
{ "pk": 1, "name": "test1:1_Channel", "channel_type": "sales_channel", "catalog": 1, "modified_date": "2022-04-01T11:35:56.485644Z", "created_date": "2022-02-18T14:17:35.169367Z", "category_tree": 24, "is_active": True, "conf": { "FAILED_INTEGRATION": { "DEFAULT": { "EXPIRATION_DATE": 213, "RETRY_INTERVAL": 0, "MAX_RETRY_COUNT": 3 } }, "base_url": "https://vendor-api-staging.saleschannel.com/", "client_id": "69b5c9c1-20e1-4c62-89f9-7186bde1b13f", "ATTRIBUTE_SET_STRATEGY": "CategoryNode" }, "schema": { "FAILED_INTEGRATION": { "label": "FAILED_INTEGRATION", "key": "FAILED_INTEGRATION", "data_type": "json", "required": True}, "ATTRIBUTE_SET_STRATEGY": { "key": "ATTRIBUTE_SET_STRATEGY", "label": "ATTRIBUTE_SET_STRATEGY", "required": True, "data_type": "text"}} } >>> self.channel.pk 1 >>> self.name test1:1_Channel >>> self.conf.get("base_url") https://vendor-api-staging.saleschannel.com/
- catalog¶
Katalog objesidir. Katalog Detaylı Bilgi. Örnek katalog objesi
{ "pk": 1, "name": "test1:1_Catalog", "stock_list": None, "price_list": None, "category_tree": None, "modified_date": "2022-02-18T14:17:35.159703Z", "created_date": "2022-02-18T14:17:35.159683Z", "priority_list": None, "extra_stock_lists": [], "extra_price_lists": [] } >>> self.catalog.pk 1
- create_session()¶
Session nesnesi, belirli parametreleri istekler arasında kalıcı hale getirmenize olanak tanır. Ayrıca, Session ile yapılan tüm isteklerde tanımlama bilgilerini(Çerezleri) taşır. Bu nedenle, aynı ana bilgisayara birden fazla istekte bulunuyorsanız, temeldeki TCP bağlantısı yeniden kullanılacak ve bu da önemli bir performans artışına neden olacaktır. Daha detaylı bilgi için Session Objects
- session¶
Satış kanalının servislerine istek atılırken kullanılacak objedir. Session objesi komutlar içerisinde ki send_request fonksiyonu içerisinde kullanılabilir.
>>> session.get("google.com")
- do_action(key: str, **kwargs) Any¶
Servisler aracılığı ile tetiklenir. Çağırabilmek için öncesinde bir entegrasyon nesnesi yaratılmış olmalıdır. Parametre olarak verilen key çalışacak olan komutu temsil eder. Bu komut ilgili entegrasyonun actions özelliği içerisinde olmalıdır. kwargs olarak verilen parametreler doğrudan Komut nesnesi oluşturmak için kullanılır. Son olarak ilgili komutun run fonksiyonunu çağırarak komutun çalışmasını sağlar.
with OmnitronIntegration(content_type=ContentType.category_tree.value) as omnitron_integration: channel_integration = ChannelIntegration() category_tree, report, _ = channel_integration.do_action( key='get_category_tree_and_nodes', batch_request=omnitron_integration.batch_request)
Satış Kanalının Kodlanması¶
Bu klasör içerisinde uygulamanın yazılma amacı olan satış kanalının kodlamasının yapılacağı yerdir.
Entegre olunacak satış kanalı için kodlanlamasını istediğimiz commandların listesi aşağıdaki gibidir.
Module |
Açıklama |
|---|---|
Kurulum aşamasına ait komutlar |
|
Ürün ile ilgili komutlar |
|
Fiyat ile ilgili komutlar |
|
Stok ile ilgili komutlar |
|
Resim ile ilgili komutlar |
|
Sipariş ile ilgili komutlar |
Akinon’a Yeni Komut Eklemek¶
Uygulama içerisindeki akinon klasör içerisinde Akinon’nun omnitron ürününe ait ihtiyaç duyduğu servisler ile haberleşen süreçler kodlanmıştır. Geliştirmenin yapılacağı satış kanalı için omnitron servislerinde veya süreçlerinde bir eksiklik duyulması halinde buradaki geliştirmeye hazır yapıdan faydalanılır.
Mevcut süreçlerin ve servislerin ihtiyacı karşılamaması durumunda
channel_app_template.akinon.integration.OmnitronIntegration
kısmına yeni yazmış olduğunuz command’larınızı aşağıdaki adımları takip ederek
ekleyebilirsiniz.
Komut oluşturmak
Komut oluşturmak için yaratacağınız class OmnitronCommandInterface i miras almalıdır.
Komutun istek atacağı uç nokta için OmnitronApiEndpoint i miras alan bir class oluşturmak ve yaratılan komutun endpoint özelliğine atamak gerekmektedir.
Opsiyonel olarak yarattığınız OmnitronApiEndpoint üzerinden birden farklı istek atmak isterseniz yaratılan komuta path özelliğini girip gerekli özelleştirme yapılabilir.
Opsiyonel olarak komutun bir seferde işleyeceği veri sayısını belirtmek için BATCH_SIZE isminde bir özellik tanımlayıp gerekli özelleştirme yapılabilir.
Komutun işleyeceği veri tipini tutmak ve olası bir hata durumunda daha detaylı log oluşturmak için content_type özelliği kullanılır. Atanabilecek content_type lara bakmak için channel_app.omnitron.constants.ContentType kontrol edebilirsiniz.
Oluşturduğumuz komutu OmnitronIntegration içerisinde ki new_actions özelliğine atayacağımız bir key(isim) ile birlikte eklenmeli.
Komutu çağırmak için
channel_app.channel.integration.ChannelIntegration.do_actionörneğinden faydalanılabilir.
Dış İsteklerin Dinlenmesi¶
Channel App Template üzerinden herhangi bir kaynaktan gelebilecek isteklerin ele alınması ve dinlenebilmesi için temel olarak bir http sunucusuna ihtiyaç duyulmaktadır. Bu sunucu üzerinden gelen isteklerin dinlenmesi için popüler geliştirme yapılarından herhangi birisi tercih edilebilir. Bu doküman içerisinde geliştirme yapısı olarak FastAPI kullanılmıştır.
Not
Geliştirme yapısı olarak FastAPI kullanılmıştır. Ancak, geliştirme yapısı olarak FastAPI kullanılmak zorunda değildir.
FastAPI kullanarak bir isteği dinlemek oldukça basittir. İlk olarak, FastAPI kütüphanesini projenize ekleyin. Daha sonra, aşağıdaki örnekte olduğu gibi bir sunucu oluşturun.
Örnek Kod¶
1from fastapi import FastAPI
2
3app = FastAPI()
4
5@app.post("/webhook")
6async def handle_webhook(payload: dict):
7 """
8 Webhook tarafından gönderilen veriyi işleyin.
9 """
10 # payload burada webhook'tan gelen veriyi temsil eder
11 # İşlemlerinizi gerçekleştirin
12 return {"message": "Webhook alındı!"}
Yukarıdaki örnek, /webhook yoluna gelen POST isteklerini dinler ve gelen veriyi payload olarak alır. Burada payload adında bir sözlük beklediğimizi belirttik, ancak gelen veriye göre bunu uygun şekilde değiştirebilirsiniz.
Notlar¶
Bu örnek, gelen webhook verisini ele alır ve işler, ancak gerçek projelerde güvenlik, hata işleme ve diğer durumlar da dikkate alınmalıdır.
Bu kodu çalıştırmadan önce, FastAPI’yi yüklemeniz ve çalıştırmanız gerekir. Ayrıca, bu kodu çalıştırmak için Python 3.6 veya daha yeni bir sürüm gerektirir.
$ pip install fastapi
$ uvicorn main:app --reload
Bu örnek, webhook’u dinlemek için /webhook yolunu kullanır. Webhook’un gönderdiği verinin beklenen formata uygun olduğundan emin olunmalıdır.
- ::: warning Uyarı
Gerçek projelerde, güvenlik önlemleri, hata işleme ve diğer durumlar dikkate alınmalıdır.
Bu şekilde bir FastAPI uygulaması oluşturarak, webhook’ları dinleyebilir ve gelen verilere göre işlemler yapabilirsiniz.
Ek olarak bu örnekteki gibi bir geliştirme sonrasında Procfile güncellenmeli ve geliştirme yapısı olarak FastAPI kullanıldığı belirtilmelidir.
web: uvicorn channel_app_template.main:app --address=0.0.0.0 --port=8008