Yapılandırma
İstemci oluşturmanın üç yolu, tüm seçenekler ve bir istek gönderilmeden önce nelerin reddedildiği.
Seçenekler
import os from openemail import AsyncOpenEmail, OpenEmail, init, openemail init(os.environ['OPENEMAIL_API_KEY'])openemail.me.ping() billing = OpenEmail(os.environ['BILLING_API_KEY']) pinned = OpenEmail('oe_live_...', base_url='https://api.openemail.uk') background = AsyncOpenEmail()| Giriş noktası | Size ne verir |
|---|---|
| init(...) | Paylaşılan istemciyi yapılandırır ve döndürür. openemail o andan itibaren her modülde bu istemcidir ve belirtmediğiniz her şey ortamdan okunur. |
| openemail | Paylaşılan istemci. init çağrılmadan kullanılırsa ilk çağrıda kendini OPENEMAIL_API_KEY ve OPENEMAIL_BASE_URL üzerinden kurar. |
| OpenEmail(...) | Ayrı bir istemci; paylaşılan anahtarın yanında ikinci bir anahtar için ya da kendi modülünüzün dışa aktardığı örneği oluşturmak için. Belirtmediğiniz her şey, init gibi, ortamdan okunur ve create_client aynı sınıfın başka bir adıdır. |
| AsyncOpenEmail(...) | Aynı seçeneklere sahip, her metodu await ile çağrılan ayrı bir asenkron istemci. Paylaşılan openemail senkron olduğundan bunu kendiniz oluşturursunuz. |
| get_client() ve reset_client() | get_client paylaşılan istemcinin kendisini döndürür; init çalışmamışsa onu ortamdan oluşturur. reset_client onu unutur, böylece bir sonraki kullanım yeni bir istemci oluşturur. |
import httpxfrom openemail import init init( 'oe_live_...', base_url='https://api.openemail.uk', timeout=30, max_retries=2, http_client=httpx.Client(proxy='http://proxy.internal:3128'), headers={'X-Team': 'billing'}, user_agent='billing-service/1.4', disable_update_notice=True,)| Seçenek | Varsayılan | Notlar |
|---|---|---|
| api_key | OPENEMAIL_API_KEY | init ve OpenEmail tarafından ortamdan okunur. oe_live_ veya oe_test_ ile başlamalıdır. |
| access_token | OPENEMAIL_ACCESS_TOKEN | api_key yerine bir OAuth erişim tokenı ya da onu döndüren bir fonksiyon. Aşağıdaki OAuth erişim tokenları bölümüne bakın. |
| base_url | https://api.openemail.uk | Ya da OPENEMAIL_BASE_URL. Sondaki eğik çizgi kırpılır; init ve OpenEmail, çıplak bir konak adının önüne https://, bu makinedeki bir konağın önüne ise http:// ekler: localhost, bir 127.x.x.x adresi ya da ::1. Bir kimlik bilgisi hiçbir zaman düz http üzerinden başka bir konağa gönderilmez ve 0.0.0.0 ya da [::] istemci oluşturulurken hata fırlatır, çünkü bunlar bir sunucunun dinlediği adreslerdir, istek gönderilecek adresler değildir. |
| timeout | 30 | Saniye cinsinden; çağrı başına değil, deneme başınadır. Yalnızca başlıkları değil, gövdenin okunmasını da kapsar. 0 devre dışı bırakır. files.upload, çağrı kendi timeout değerini geçirmedikçe en az 600 saniye bekler. |
| max_retries | 2 | İlkinden sonraki ek denemeler; yalnızca yinelenmesi güvenli çağrılarda. Çağrı başına değil, istemci üzerinde ayarlanır. |
| http_client | yeni bir httpx.Client | Bir proxy, kendi TLS ayarlarınız, mount edilmiş bir transport ya da bir test sahtesi için kendi istemcinizi geçirin: OpenEmail'e bir httpx.Client, AsyncOpenEmail'e bir httpx.AsyncClient. İstemciyi kapatmak, sizin geçirdiğiniz istemciyi açık bırakır. |
| headers | {} | Her istekte gönderilir. |
| user_agent | openemail-python/<version> | Her istekte gönderilir. |
| disable_update_notice | False | PyPI üzerinde daha yeni bir sürüm olup olmadığına dair süreç başına bir kez yapılan denetimi atlar. Denetim yalnızca çıktı bir terminale gittiğinde çalışır ve OPENEMAIL_DISABLE_UPDATE_NOTICE da onu kapatır. |
Göndermeden önce neleri reddeder
Bunlar, ilk gönderiminizde kafa karıştırıcı bir hata olarak ortaya çıkmak yerine, herhangi bir istek gönderilmeden önce ValueError ya da tablonun belirttiği yerlerde TypeError fırlatır. Mesaj, neyin yanlış olduğunu ve yerine ne geçirilmesi gerektiğini söyler.
| Reddedilen | Neden |
|---|---|
| Hiç anahtar yok | Ne api_key ne de OPENEMAIL_API_KEY ayarlanmış; dolayısıyla kimlik doğrulaması yapacak bir şey yok. |
| Bir oturum çerezi veya oturum token'ı | Burada yalnızca oe_live_ ve oe_test_ kimlik doğrular ve API da aynı şeyi söyler. Denetim yalnızca bir ön ek denetimidir, fazlası değil; bu yüzden iptal edilmiş bir anahtar yine de ağ üzerinde başarısız olur. |
| http veya https URL'si olmayan bir base_url | Başka hiçbir şey getirilemez; bu yüzden istemci ilk istekte başarısız olmak yerine bunu daha oluşturulurken reddeder. |
| 0.0.0.0 ya da [::] üzerindeki bir base_url | Bir sunucunun dinlediği bir adres, istek gönderilecek bir adres değil. Mesaj bunun yerine aynı portla 127.0.0.1 ya da [::1] adresini önerir. |
| Düz http üzerinden bir kimlik bilgisi | Sunucu bu makinede değilse, istek çıkmadan önce çağrıda reddedilir. Ağdaki herkes onu okuyabilirdi. |
| Herhangi bir metotta boş veya tamamı noktadan oluşan bir id | Metot çağrıldığında fırlatılır. Noktalardan oluşan bir yol parçası her URL ayrıştırıcısı tarafından kaldırılır; dolayısıyla istek başka bir uç noktaya ulaşırdı. |
| Yanlış türde bir http_client | İstemci oluşturulurken bir TypeError. OpenEmail bir httpx.Client, AsyncOpenEmail ise bir httpx.AsyncClient alır. |
| JSON'un taşıyamayacağı bir gövde değeri | Türünü adıyla belirten bir TypeError. JSON türleri olduğu gibi geçer; bir datetime, bir date ya da bir set sizin için dönüştürülür. |
test_mode diye bir seçenek yok ve olmayacak. Anahtar şeması bir ipucu değil, kimlik bilgisinin parçasıdır; dolayısıyla mod anahtarın bir özelliğidir. client.mode ön eki okur ve hiçbir karar vermez.
Tek istemci, birkaç anahtar
İstemciyi bir kez oluşturup paylaşın. İstek başına yeni bir örnek, bağlantı havuzunu ve yapılandırmayı boşuna çöpe atar ve üzerindeki durumların hiçbiri çağıran başına değildir.
Tek bir istemciyi iş parçacıkları arasında paylaşmak güvenlidir. close() ya da bir with bloğunun sonu, istemcinin açtığı bağlantı havuzunu kapatır; sizin geçirdiğiniz bir http_client ise kapatmanız için açık kalır.
Birkaç çalışma alanı adına gönderim yapan bir iş gibi, aksi hâlde anahtar başına bir örnek gerektirecek durumlarda api_key değerini çağrıda geçirin. O istek için Authorization başlığının yerini alır ve istemcide arkasında hiçbir iz bırakmaz.
from openemail.types import EmailSend workspace_key = 'oe_live_...' message: EmailSend = {'from': sender, 'to': recipient, 'subject': subject, 'text': text} client.emails.send(message) client.emails.send(message, api_key=workspace_key) client.threads.list(folder='inbox', api_key=workspace_key)client.webhooks.list(api_key=workspace_key)temp_mail dışındaki her metot bunu timeout ile birlikte bir anahtar sözcük argümanı olarak alır. İstek gönderilmeden önce, oluşturucunun kullandığı kuralla denetlenir; böylece bir yazım hatası, sonradan aramak zorunda kalacağınız bir kimlik bilgisi hakkında 401 yerine api_key= on this call diyen bir ValueError fırlatır. Yeniden denenen bir çağrı kendisine verilen anahtarı korur.
timeout saniye cinsindendir ve yalnızca o tek çağrı için, her denemesinde, istemcinin zaman aşımının yerini alır.
client.mode, istemcinin KURULDUĞU anahtarı tanımlar ve bir geçersiz kılmayı izlemez. Tek bir istemci birkaç anahtara hizmet ettiğinde bildirilecek tek bir mod kalmaz; bu yüzden modu geçirdiğiniz anahtardan okuyun.
Hiçbir metodun sarmalamadığı bir uç nokta
client.raw.request, istemcinin kimlik bilgisi, temel URL'si, zaman aşımı ve yeniden deneme politikası uygulanmış olarak bir istek gönderir ve ayrıştırılmış JSON'u döndürür. method, query, body, api_key ve timeout alır. Bir GET isteğini yeniden dener, geri kalan her şeyi ise repeatable=True geçirmediğiniz sürece bir kez gönderir. idempotent=True bir Idempotency-Key ekler: idempotency_key olarak geçirdiğiniz anahtarı ya da yeni bir anahtarı.
result = client.raw.request('/something-new', method='POST', body={'name': 'Invoices'})Yol tek bir / ile başlamalıdır. //host/x gibi başka herhangi bir şey istek gönderilmeden önce hata fırlatır; tamamlanmış URL'si temel URL'nin kökeninin dışına çıkan bir yol da öyle. Böylece taşıdığı kimlik bilgisi hiçbir zaman başka bir konağa ulaşmaz.
Tek kullanımlık gelen kutuları
create_temp_mail(), hiç API anahtarı taşımayan bir istemci kurar ve create_async_temp_mail() onun asenkron ikizidir. Gelen kutularını anonim olarak oluşturur ve her okuma, create çağrısının döndürdüğü gelen kutusu token'ını ya da extend çağrısının döndürdüğü daha yeni token'ı gönderir: ya çağrı başına inbox_token olarak ya da bir kez create_temp_mail(inbox_token=...) şeklinde.
from openemail import create_temp_mail temp_mail = create_temp_mail() inbox = temp_mail.create()messages = temp_mail.list_messages(inbox['id'], inbox_token=inbox['token']) print(messages['items'], messages['expiresAt'])OAuth erişim tokenları
Henüz yayımlanmadıBir kişinin OAuth ile bağladığı bir uygulama, örneğin bir komut satırı aracı ya da bir ajan, API anahtarı yerine bir erişim tokenı tutar. Onu access_token olarak geçirin: ya tokenın kendisini ya da onu döndüren bir fonksiyonu; bu fonksiyon AsyncOpenEmail üzerinde async olabilir. Fonksiyon her çağrı için bir kez çağrılır ve o çağrının yeniden denemeleri onun döndürdüğünü kullanır; bu yüzden token süresinin dolmasına yaklaştığında onu fonksiyonun içinde yenileyin, istemcinin hiç yeniden kurulması gerekmez.
from openemail import OpenEmail client = OpenEmail(access_token=session.fresh_access_token) me = client.me.get() if me['object'] == 'oauth_token': print(me['clientId'], me['expiresAt'])| Durum | Ne olur |
|---|---|
| api_key ile access_token birlikte ya da hiçbiri | Oluşturucu ValueError fırlatır. Hiçbiri yoksa ileti OPENEMAIL_API_KEY ve OPENEMAIL_ACCESS_TOKEN adlarını verir. |
| Token olmayan bir değer | Bir token 1 ile 512 karakter arasındadır ve oe_ ile başlamaz; is_access_token bu denetimi yapar. Bu denetimi geçemeyen bir dize oluşturucuda hata fırlatır; böyle bir değer döndüren bir fonksiyon ise hiçbir şey gönderilmeden çağrıyı başarısız kılar. |
| OPENEMAIL_ACCESS_TOKEN | Hiçbir kimlik bilgisini geçirmediğinizde ve OPENEMAIL_API_KEY tanımlı olmadığında init, OpenEmail ve paylaşılan openemail tarafından okunur; yani ortamdaki bir anahtar önceliklidir. |
| Hata fırlatan bir fonksiyon | Çağrı aynı hatayı değiştirmeden fırlatır ve hiçbir şey gönderilmez. |
| OpenEmail üzerinde awaitable döndüren bir fonksiyon | Bir ValueError, çünkü senkron istemci onu bekleyemez. AsyncOpenEmail üzerinde fonksiyon async olabilir. |
| Çağrı başına bir api_key | O tek istek için tokenın yerini alır ve fonksiyon çağrılmaz. |
| mode | Bir tokenla her zaman live. |
| create_temp_mail() | Ortamda ne olursa olsun hiçbir kimlik bilgisi göndermez. |
| me.get() ve me.ping() | Bir token için get, object değeri oauth_token, id ve roleId değerleri None, bağlı uygulamanın clientId değeri ve kişinin uygulamaya verdiği onayın sona erdiği an olan expiresAt ile yanıt verir. ping, kind değeri oauth, keyId değeri None ve clientId ile yanıt verir. KeyResource ve PingResource birleşim türleridir, bu yüzden clientId ya da expiresAt okumadan önce object veya kind ile ayırt edin. |
Bir token bir kişi adına çalışır ve onun postasını onun okuyabildiği gibi okur, bu yüzden onu bir anahtar gibi sunucuda tutun.
Doğrulama kodları
Henüz yayımlanmadıBir alan adını silmek ya da bir webhook'u değiştirmek gibi hassas bir değişiklikten önce API, bir erişim tokenından web uygulamasının kişiden isteyeceği doğrulama kodunu ister. Çağrı, is_step_up_required değeri True olan bir OpenEmailApiError fırlatır ve hiçbir şey değişmemiştir. Bir kod isteyin, kişinin size verdiğini doğrulayın, sonra çağrıyı yeniden yapın. Bir API anahtarından asla istenmez.
from openemail import OpenEmailApiError try: client.domains.delete(domain_id)except OpenEmailApiError as error: if not error.is_step_up_required: raise challenge = client.security.begin_step_up() if challenge['method'] == 'email': prompt = f'Enter the code we emailed to {challenge.get("sentTo")}: ' else: prompt = 'Enter the code from your authenticator app, or a backup code: ' client.security.verify_step_up({'code': input(prompt)}) client.domains.delete(domain_id)| Metot | Ne yapar |
|---|---|
| security.step_up_status() | Uygulamanın şu anda doğrulanmış olup olmadığı (elevated, elevatedUntil), sonraki kodun nasıl denetleneceği (method, email ya da totp) ve pencerenin uzunluğu minutes. Hiçbir şey göndermez ve bir duraklamayı bildirmez. |
| security.begin_step_up(body=None) | Bir doğrulama açar. email ile kişinin oturum açtığı adrese altı haneli bir kod gider ve sentTo adresi maskelenmiş gösterir. totp ile kişi kodu kimlik doğrulama uygulamasından okur ya da bir kurtarma kodu kullanır. Hâlâ açık ve deneme hakkı olan bir doğrulama, {'resend': True} geçirmediğiniz sürece yeniden kullanılır; kilitlenmiş ya da süresi dolmuş olanın yerine düz bir çağrı yenisini açar. Her uygulama her kişi için saatte 5 ve 24 saatte 20 doğrulama açabilir ve sonraki 429 step_up_throttled fırlatır. |
| security.verify_step_up({'code': code}) | Kodu denetler ve bu uygulama için hassas değişikliklerin kilidini 60 dakika boyunca, elevatedUntil anına kadar, REST üzerinden ve aynı değişiklikleri yapan MCP araçları üzerinden açar. Bu uygulamadan 24 saatte 10 yanlış koddan ya da kişinin tüm uygulamalarından birlikte 20 yanlış koddan sonra bu çağrı ve begin_step_up, doğrulamanın ne zaman yeniden başlayacağını söyleyen bir iletiyle 429 step_up_locked fırlatır. |
İstemci asla kendiliğinden kod istemez ya da çağrıyı tekrarlamaz ve ne begin_step_up ne de verify_step_up otomatik olarak yeniden denenir, çünkü kaybolan bir yanıttan sonraki yeniden deneme ikinci bir e-posta gönderebilir ya da ikinci bir denemeyi harcayabilir. Kapsam gerektirmezler ve bunlardan birini çağıran bir API anahtarı 400 step_up_not_applicable alır. STEP_UP_ERROR_CODES bir doğrulamanın başarısız olabileceği her yolu adlandırır ve API hatalar sayfası her biri için ne yapılacağını söyler.