Jak wysłać e-mail przez API w Pythonie (Szybki samouczek)

Spis treści
Spis treści 11 sekcji
Pierwsze kroki
Wysyłanie e-maili
Produkcja
Odniesienie
Samouczek Pythona

Jak Wyślij e-mail przez API w Python (Szybki Samouczek)

Pomiń standardowy tekst SMTP. Ten przewodnik pokazuje, jak używać Unipile ujednolicone API poczty e-mail aby wysłać e-mail w Pythonie - z przykładami copy-paste dla Gmail, Outlook i IMAP za pomocą żądania biblioteka.

api email python api do wysyłania e-maili w Pythonie Gmail / Outlook / IMAP żądania / aiohttp Flask / Django / FastAPI
send_email.py
import żądania, os Klucz API = os.environ['UNIPILE_API_KEY'] DSN = os.environ['UNIPILE_DSN'] IDENTYFIKATOR_KONTA = os.environ['UNIPILE_ID_KONTA'] response = requests.stanowisko( f'{DSN}/api/v1/emails', nagłówki={'Klucz API X': Klucz API}, dane={ 'id_konta': IDENTYFIKATOR_KONTA, 'do': '[{"display_name":"Alice","identifier":"alice@acme.com"}]', 'temat': 'Witaj z Pythona', 'ciało': '

Wysłano przez Unipile!

'
} ) print(odpowiedź.json())
Email dostarczony - 202 Zaakceptowano
Współpracuje z: Gmail Perspektywy IMAP
W skrócie

5-wierszowy przykład w Pythonie

Jeśli już wiesz Czym jest API do wysyłania wiadomości e-mail i po prostu chcę działającego kodu API poczty e-mail w Pythonie, oto on. Pełny samouczek znajduje się poniżej.

1
Zainstaluj requests
pip install requests python-dotenv
2
Ustaw zmienne środowiskowe
Dodaj UNIPILE_DSN, UNIPILE_API_KEYoraz UNIPILE_ID_KONTA do twojego .env plik.
3
Połącz konto e-mail
OAuth dla Gmail/Outlook lub dane uwierzytelniające SMTP dla dowolnego serwera IMAP. Jedno wywołanie API - wykonujesz to tylko raz na konto.
4
POST do /api/v1/emails
Podanie account_id, do, podmiotoraz ciało. Zrobione.
Ten sam kod w Pythonie działa z Gmail, Outlook i dowolnym serwerem IMAP, nie potrzebuje logiki specyficznej dla dostawcy. Sprawdź Przewodnik po API poczty elektronicznej po pełny przegląd koncepcji.
send_email.py
import żądania, os z dotenv import load_dotenv load_dotenv() Klucz API = os.environ['UNIPILE_API_KEY'] DSN = os.environ['UNIPILE_DSN'] IDENTYFIKATOR_KONTA = os.environ['UNIPILE_ID_KONTA'] resp = requests.stanowisko( f'{DSN}/api/v1/emails', nagłówki={'Klucz API X': Klucz API}, dane={ 'id_konta': IDENTYFIKATOR_KONTA, 'do': '[{"display_name":"Alice","identifier":"alice@acme.com"}]', 'temat': 'Witaj z Pythona', 'ciało': '

Wysłano przez Unipile!

'
} ) print(odpowiednio.json()) # {'tracking_id': 'msg_...'}
Konfiguracja

Wymagania wstępne i konfiguracja

Zanim będziesz mógł użyć przepływu pracy w Pythonie z interfejsem API poczty e-mail w środowisku produkcyjnym, potrzebujesz czterech rzeczy: Python 3.9+, żądania biblioteka, klucz API z DSN i powiązane konto e-mail.

Python 3.9+ (zalecane 3.11)
Wszystkie przykłady używają f-stringów., | typów unii, oraz funkcje standardowej biblioteki z 3.9+. Python 3.11 LTS jest zalecany do produkcji. Sprawdź swoją wersję za pomocą python --version.
Klucz API Unipile i DSN
Zaloguj się w panelu Unipile, aby uzyskać swój token dostępu i DSN (osobisty punkt końcowy HTTPS, taki jak api4.unipile.com:13444. Oba są wymagane w każdym nagłówku żądania.
Środowisko wirtualne
Zawsze używaj venv do izolowania zależności: python -m venv .venv && source .venv/bin/activate. Nigdy nie instaluj pakietów w systemowym Pythonie – jest to szczególnie ważne przy obsłudze poświadczeń.
Połączone konto e-mail
Wysyłasz e-mail przez powiązane konto (Gmail, Outlook lub IMAP). Następna sekcja przeprowadzi Cię przez przepływ OAuth, aby je powiązać. Robisz to tylko raz dla każdego konta.
Instalowanie zależności
pip
pipenv
poezja
pip install requests python-dotenv # Opcjonalnie: wsparcie asynchroniczne pip instal aiohttp httpx # Opcjonalnie: logika ponawiania pip install tenacity
pipenv install requests python-dotenv tenacity
poetry dodaj żądania python-dotenv wytrwałość
.env
# Poświadczenia Unipile - nigdy nie zatwierdzaj tego pliku UNIPILE_DSN=https://api4.unipile.com:13444 UNIPILE_API_KEY=twój_token_dostępu_tutaj # Identyfikator konta powiązanego konta e-mail UNIPILE_ID_KONTA=acc_xxxxxxxxxxxxxxxx

Dodaj .env do twojego .gitignore. Załaduj z python-dotenv przez wczytaj_zmienne_srodowiskowe() na górze swojego skryptu. W produkcji preferuj zmienne środowiskowe faktycznie wstrzykiwane przez platformę wdrażania (Heroku, Railway, Docker Compose).

Gotowi do wysłania pierwszego e-maila?
Uzyskaj darmowy klucz API - zajmuje to 30 sekund, nie jest wymagana karta kredytowa.
Pobierz swój darmowy klucz API
Łączenie kont

Konfiguracja pierwszego konta e-mail

Zanim będziesz mógł wysyłać wiadomości, musisz połączyć konto e-mail z Unipile. Jest to jednorazowy krok dla każdego konta. Zobacz pełny Zintegrowany przewodnik po integracji interfejsu API poczty e-mail więcej o przepływach wielu kont.

Unipile używa hostowanego kreatora uwierzytelniania – Twój skrypt w Pythonie generuje link uwierzytelniający, użytkownik klika w niego i kończy proces OAuth w przeglądarce, a następnie Unipile wywołuje Twój webhook z nowymi account_id. Żadne dane uwierzytelniające SMTP do Gmaila ani Outlooka nie są przechowywane w Twoim kodzie.

GmailGmail OAuth
PerspektywyOutlook OAuth
IMAPIMAP / SMTP
connect_gmail.py
import żądania, os z dotenv import load_dotenv load_dotenv() Klucz API = os.environ['UNIPILE_API_KEY'] DSN = os.environ['UNIPILE_DSN'] # Krok 1: Utwórz hostowany link autoryzacyjny dla Gmail OAuth resp = requests.stanowisko( f'{DSN}/api/v1/hosted/accounts/link', nagłówki={'Klucz API X': Klucz API}, dane={ 'typ': 'GOOGLE', 'imię': 'Alice Gmail', 'url_powodzenia': 'https://yourapp.com/oauth/success', 'adres_błędu': 'https://yourapp.com/oauth/niepowodzenie' } ) # Krok 2: wyślij ten URL do użytkownika auth_url = resp.json()['adres URL'] print(Przekieruj użytkownika do: {auth_url}') # Krok 3: Unipile wysyła POSTy z {account_id} do Twojego webhooka po OAuth # Zobacz /gmail-api-send-email-a-comprehensive-guide-for-developers/ dla szczegółów Gmail
import żądania, os z dotenv import load_dotenv load_dotenv() # Outlook OAuth - obejmuje osobisty Outlook + Microsoft 365 # Zobacz /microsoft-graph-api-email-integration-guide/ resp = requests.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/hosted/accounts/link', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, dane={ 'typ': 'MICROSOFT', 'imię': 'Bob Outlook', 'url_powodzenia': 'https://yourapp.com/oauth/success', 'adres_błędu': 'https://yourapp.com/oauth/niepowodzenie' } ) print(odpowiednio.json()['adres URL'])
import requests, os, json # IMAP: przekazuj poświadczenia SMTP/IMAP bezpośrednio (przekierowanie OAuth nie jest wymagane) # Zobacz /the-developers-guide-to-imap-api-solution/ po pełne szczegóły IMAP resp = requests.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/accounts', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, json={ 'dostawca': 'IMAP', 'nazwa użytkownika': 'alice@company.com', 'hasło': 'hasło_aplikacji_tutaj', 'imap_host': 'imap.company.com', 'smtp_host': 'smtp.company.com' } ) identyfikator_konta = resp.json()['id_konta'] print(Połączone konto: {account_id}')
Gmail
Gmail
Wykorzystuje Google OAuth 2.0. Hasła nie są przechowywane. Odświeżanie tokenów jest automatyczne. Zobacz Przewodnik po wysyłaniu e-maili za pomocą Gmail API szczegóły zakresu.
Perspektywy
Outlook / Microsoft 365
Używa protokołu OAuth Microsoft Graph. Dotyczy osobistego programu Outlook oraz Microsoft 365 / Exchange Online. Zobacz Przewodnik po wiadomościach e-mail programu Microsoft Graph dla przepływów zgody administratora.
IMAP
IMAP / SMTP
Przekazuj poświadczenia bezpośrednio. Działa z każdym serwerem IMAP: Zoho, Yahoo, FastMail, niestandardowy Exchange. Zobacz Przewodnik po rozwiązaniu API IMAP dla konfiguracji portu.
Rdzeń API

Wysyłanie pierwszego e-maila z Pythona

Punkt końcowy wysyłania akceptuje multipart/form-data. Użyj dane= nie json=) w requests.post(). The do, ccoraz Dw. kopia pola są ciągami znaków zakodowanymi w JSON w danych formularza.

1
E-mail w postaci zwykłego tekstu
Podstawowy
import requests, os, json żądania.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, dane={ 'id_konta': os.environ['UNIPILE_ID_KONTA'], 'do': json.zrzuty([{'nazwa_wyświetlana': 'Alicja', 'identyfikator': 'alice@acme.com'}]), 'temat': 'Szybka aktualizacja', 'ciało': 'Cześć Alice, tylko się odzywam.' } )
Uwaga: The ciało pole akceptuje zarówno zwykły tekst, jak i kod HTML. Użyj

tagi formatowania HTML.

2
HTML e-mail z DW i UDW
Wspólny
import requests, os, json response = requests.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, dane={ 'id_konta': os.environ['UNIPILE_ID_KONTA'], 'do': json.zrzuty([{'identyfikator': 'alice@acme.com'}]), 'Dwój dwój': json.zrzuty([{'identyfikator': 'manager@acme.com'}]), 'DW': json.zrzuty([{'identyfikator': 'crm@yourapp.com'}]), 'temat': 'Twoja faktura jest gotowa', 'ciało': '

Faktura #1042

Proszę znaleźć swoją fakturę w załączniku.

'
} ) # 202 Zaakceptowano = kolejkowane do dostarczenia print(status_kodu_odpowiedzi, odpowiedź.json())
3
Obsługa odpowiedzi
Produkcja
import requests, os, json def wyślij_e-maildo_email: str, temat: str, ciało: str) -> słownik: "Wyślij e-mail za pomocą Python wrappera API e-mail Unipile." response = requests.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, dane={ 'id_konta': os.environ['UNIPILE_ID_KONTA'], 'do'json.zrzuty([{'identyfikator': do_email}]), 'temat'temat, 'ciało'ciało, }, timeout=30 ) odzew.podnieś_status() # podnosi HTTPError przy statusach 4xx/5xx return odzew.json() # {'tracking_id': 'msg_...'}
Wskazówka: Zawsze przechodź timeout=30 aby uniknąć wiecznego zawieszania się z powodu problemów z siecią. Użyj podnieś_status przechowywać błędy HTTP jako wyjątki w Pythonie.
Darmowe na start
Wypróbuj teraz – darmowy klucz API w 30 sekund

Uzyskaj klucz API, połącz konto Gmail lub Outlook w kilka minut i uruchom przykłady Pythona z tego przewodnika na rzeczywistych skrzynkach pocztowych.

Załączniki

Wysyłanie załączników w Pythonie

Załączniki są wysyłane jako część danych formularza wieloczęściowego przy użyciu Pythona pliki= parametr. Otwórz plik w trybie binarnym ('rb') - bajty, nie ciągi znaków.

attach.py
import requests, os, json # Pojedynczy plik załącznika z otwórz('faktura.pdf', 'rb') jako f: resp = requests.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, dane={ 'id_konta': os.environ['UNIPILE_ID_KONTA'], 'do': json.zrzuty([{'identyfikator': 'client@example.com'}]), 'temat': 'Faktura w załączeniu', 'ciało': '

Proszę zobaczyć załączoną fakturę.

'
}, pliki={'załączniki': ('faktura.pdf', f, 'application/pdf')} ) # Multiple attachments: pass a list of tuples # pliki=[('załączniki', ('a.pdf', f1, 'application/pdf')), # [('załączniki', ('b.png', f2, 'image/png'))]
Zawsze otwieraj w trybie binarnym
Użycie open('file.pdf', 'rb'), nie 'er'. Przekazanie obiektu pliku tekstowego do pliki= podnosi Błąd typu. To częsta pułapka specyficzna dla Pythona podczas migracji z biblioteki smtplib.
Wiele załączników
Przekaż listę krotek do pliki=każda krotka jest ('załączniki', (nazwa_pliku, obiekt_pliku, typ_zawartości)). Requests automatycznie obsługuje granicę wieloczęściową.
Pliki w pamięci (BytesIO)
Dla dynamicznie generowanych plików PDF lub eksportów CSV, przekaż BytesIO obiekt bezpośrednio from io import BytesIO; buf = BytesIO(pdf_bytes) wtedy ('raport.pdf', buf, 'application/pdf').
Limity dostawcy: Gmail pozwala na wysłanie do 25 MB łącznie. Outlook pozwala na wysłanie do 20 MB. Limity IMAP zależą od konfiguracji serwera. Dla plików przekraczających te limity, zamiast tego wyślij link do pobrania.
Potrzebujesz większych załączników lub wyższych limitów wysyłania?
Unipile planuje skalowanie od prototypów do obciążeń produkcyjnych. Porównaj limity na stronie z cennikiem.
Unipile - Zaawansowane API Pythona
Zaawansowany

Odpowiedzi, Wątki i Śledzenie

Dla Wysyłanie wiadomości e-mail w imieniu użytkownika, wątkowanie i śledzenie dostaw oparte na webhookach, oto wzorce języka Python, których potrzebujesz.

01
Wątkowanie z in_reply_to

Aby odpowiedzieć w istniejącym wątku, przekaż w odpowiedzi na pole z identyfikator_śledzenia e-mail, na który chcesz odpowiedzieć. Unipile obsługuje Bibliografia oraz Odpowiedź-Do nagłówki automatycznie.

reply.py
żądania.stanowisko( f'{DSN}/api/v1/emails', nagłówki={'Klucz API X': Klucz API}, dane={ 'id_konta': IDENTYFIKATOR_KONTA, 'do': json.zrzuty([{'identyfikator': 'alice@acme.com'}]), 'temat': 'Re: Twoje pytanie', 'ciało': '

Nawiązując do Twojej wiadomości.

'
, 'odpowiedź_na': 'id_śledzenia_oryginalny' } )
02
Webhooki w Pythonie (przykład z Flaskiem)

Zarejestruj adres URL webhooka w swoim panelu Unipile, aby otrzymywać zdarzenia dostarczenia (wysłane, odrzucone, otwarte). Oto minimalny odbiornik Flask:

webhook_flask.py
z kieliszek import Flask, request, jsonify import logowanie aplikacja = Flaszka(__imię__) rejestrowanie.basicConfigpoziom=logging.INFORMACJA) @aplikacja.trasa('/webhook/email', methods=['POST']) def email_webhook(): zdarzenie = żądanie.get_json() typ_zdarzenia = zdarzenie.uzyskać('typ') tracking_id = zdarzenia.uzyskać('śledzący_id') rejestrowanie.informacje(f'Email z wydarzeniem: {event_type} dla {tracking_id}') return jsonify(zgoda=Prawda), 200
03
Klucze idempotencji

Aby zapobiec wielokrotnemu wysyłaniu podczas ponawiania próby sieci, przekaż unikalny Klucz idempotencji Nagłówek. Jeśli ten sam klucz zostanie wysłany dwukrotnie, Unipile zwróci pierwotną odpowiedź bez wysyłania drugiej wiadomości e-mail.

idempotency.py
import uuid, żądania, os, json klucz = stridentyfikator UUID.uuid4()) # generuj raz, przechowuj w bazie danych żądania.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', nagłówki={ 'Klucz API X'os.environ['UNIPILE_API_KEY'], 'Idempotency-Key'Klucz }, dane={'id_konta': os.environ['UNIPILE_ID_KONTA'], 'do': json.zrzuty([{'identyfikator': 'alice@acme.com'}]), 'temat': 'Witamy!', 'ciało': 'Cześć!'} )
Produkcja

Obsługa błędów i ponawianie prób

Kod produkcyjny API e-mail wymaga prawidłowej obsługi wyjątków, strukturalnego logowania i automatycznych ponownych prób z wykładniczym wycofywaniem za pomocą wytrwałość biblioteka.

Kod HTTPZnaczenieAkcja
202Zaakceptowano - kolejkowane do dostarczeniaPrzechowaj identyfikator śledzenia
400Nieprawidłowe żądanie (nieprawidłowe pola)Popraw ładunek, nie próbuj ponownie
401Nieprawidłowy klucz APISprawdź UNIPILE_API_KEY
403Konto nieautoryzowanePołącz ponownie konto
404Nie znaleziono identyfikatora kontaSprawdź UNIPILE_ACCOUNT_ID
429Ograniczony limitWycofaj się + ponów próbę (patrz kod)
500Błąd serweraPonów próbę po 5 sekundach opóźnienia
retry.py
import żądania, os, json, logowanie z wytrwałość import ( ponów, zatrzymaj_po_próbie, wait_exponential, retry_if_exception_type ) rejestrowanie.basicConfigpoziom=logging.INFORMACJA) logger = logging.pobierzLoger(__imię__) klasa BłądLimitUstawień(Wyjątek): przejść @ponów( zatrzymaćzatrzymaj_po_próbie(4), czekaj=czekaj_wykładniczo(mnożnik=1, min=2, maks=30), ponówponów_jeśli_typ_wyjątku(BłądLimitUstawień) ) def wyślij_z_ponowieniem(do: str, temat: str, ciało: str) -> słownik: resp = requests.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, dane={ 'id_konta': os.environ['UNIPILE_ID_KONTA'], 'do'json.zrzuty([{'identyfikator': do}]), 'temat'temat, 'ciało'ciało }, timeout=30 ) jeśli resp.status_code == 429: rejestrator.ostrzeżenie('Ograniczono liczbę żądań, wycofuję się...') wzrastać BłądLimitUstawień() lub.podnieś_status() return lub.json()
Bezpieczeństwo

Najlepsze praktyki bezpieczeństwa w Pythonie

Aby uzyskać pełny przewodnik po ochronie integracji API poczty e-mail, zobacz Przewodnik po zabezpieczaniu API poczty elektronicznej. Oto podstawy specyficzne dla Pythona.

Nigdy nie umieszczaj kluczy w kodzie
Użycie os.environ lub python-dotenv. Nigdy nie kładź UNIPILE_API_KEY jako literał ciągu znaków w kodzie źródłowym. Jeśli przypadkowo trafi na Git, natychmiast obróć klucz z poziomu panelu.
Środowiska wirtualne
Zawsze izoluj zależności za pomocą venv lub conda. Zapobiega to atakom polegającym na pomieszaniu zależności i sprawia, że Twoje requirements.txt audytowalny. Zapewnij wersje w produkcji.
Odświeżenie tokena OAuth
Unipile automatycznie odświeża tokeny OAuth dla Gmaila i Outlooka. Nigdy nie przechowujesz ani nie rotujesz samodzielnie tokenów dostawcy – wystarczy zachować swój UNIPILE_API_KEY ważny.
Tylko po stronie serwera
Nigdy nie wywołuj API Unipile z kodu po stronie klienta (przeglądarka lub aplikacja mobilna). W Flask/Django/FastAPI zawsze przechowuj wywołania API w widokach po stronie serwera lub w zadaniach w tle (Celery).
Waliduj ładunki webhooków
Podczas odbierania webhooków Unipile w Flask lub FastAPI, zweryfikuj pochodzenie żądania za pomocą nagłówka sekretu lub podpisu HMAC przed przetworzeniem zdarzenia. Nigdy nie ufaj surowym przychodzącym ładunkom bezkrytycznie.
Audyt i logowanie
Log identyfikator_śledzenia dla każdego wysłanego e-maila, aby włączyć audyty dostarczenia. Użyj standardowych technik Pythona logowanie moduł - nigdy druk() w produkcji. Wysyłaj dzienniki do SIEM do zastosowań wymagających dużej zgodności.
DKIM i SPF: Są to konfiguracje na poziomie DNS, a nie kod Pythona. Skonfiguruj rekordy SPF i DKIM dla swojej domeny wysyłającej. Przeczytaj pełne Przewodnik po zabezpieczaniu API poczty elektronicznej krok po kroku konfiguracji DNS.
Pułapki

Typowe pułapki specyficzne dla Pythona

Oto najczęstsze błędy popełniane przez programistów Pythona podczas integrowania API poczty e-mail. Jeśli zamiast tego korzystasz z Node.js, zobacz nasze JavaScript API do wysyłania poczty e-mail tutorial.

Korzystanie z json= zamiast dane=
Punkt końcowy wysyłania Unipile wymaga multipart/form-data, nie JSON. Zawsze używaj requests.post(..., data={...}). Używanie json={...} zwróci błąd 400. do, ccoraz Dw. kopia pola są ciągami znaków JSON w danych formularza - użyj json.dumps() aby zakodować tablicę odbiorców.
Poprawka: Użyj data= z json.dumps() dla tablic odbiorców
Otwieranie plików załączników w trybie tekstowym
Zawsze otwieraj załączniki plików z open('file.pdf', 'rb') - tryb binarny. Tryb tekstowy'er') podnosi ) powoduje ) wzbudza Błąd typu po przekazaniu do pliki= parametru. Dla zawartości w pamięci, użyj io.BytesIO.
Poprawka: zawsze otwieraj pliki w trybie 'rb'
Mieszanie sync i async (asyncio)
The żądania biblioteka jest synchroniczna. Wywołanie jej wewnątrz asynchroniczne def funkcja blokuje pętlę zdarzeń. Użyj httpx.AsyncClient lub aiohttp.ClientSession dla asynchronicznych kontekstów Pythona (FastAPI, asynchroniczne widoki Django, skrypty asyncio).
Poprawka: użyj httpx.AsyncClient w kontekstach async/await
Brak limitu czasu na żądania
Domyślnie, requests.post() czeka wiecznie. Zawieszone połączenie zablokuje twój wątek (lub pracownika Celery) w nieskończoność. Zawsze przekazuj timeout=30 (limit czasu połączenia, limit czasu odczytu w sekundach).
Poprawka: zawsze przekazuj timeout=(5, 30) do requests.post()
Daty i godziny niezawierające strefy czasowej w planowaniu
Jeśli planujesz wysyłki e-maili z polem znacznika czasu, zawsze używaj świadomych strefy czasowej dat i godzin: from datetime import datetime, timezone; datetime.now(timezone.utc). Naiwne daty i godziny powodują ciche błędy "off-by-hours" wdrożeń wieloregionalnych.
Napraw: zawsze używaj timezone.utc dla obiektów datetime
Wpływ GIL na wątkowe wysyłanie dużej ilości danych
GIL Pythona ogranicza prawdziwe wątkowe równoległe przetwarzanie dla zadań procesorowych, ale żądania HTTP są związane z operacjami wejścia/wyjścia (I/O) – wątki działają wtedy dobrze. Dla dużej liczby wysyłek (1000+/dzień) użyj puli wątków (concurrent.futures.ThreadPoolExecutor) lub oddelegować do kolejki Celery.
Poprawka: użyj ThreadPoolExecutor lub Celery do wysyłek wsadowych

Często zadawane pytania

Najczęściej zadawane pytania dotyczące korzystania z API poczty e-mail w Pythonie z ujednoliconym API poczty e-mail Unipile.

Użyj ujednoliconego API poczty e-mail Unipile zamiast smtplib lub bezpośredniego połączenia SMTP. Zainstaluj żądania, pobierz swój klucz API i DSN z pulpitu nawigacyjnego Unipile, połącz konto Gmail lub Outlook za pomocą OAuth, a następnie wyślij POST na adres /api/v1/emails z twoim account_id, do, podmiotoraz ciało. Żaden serwer SMTP, żaden port 587, żadna konfiguracja TLS nie jest potrzebna w twoim kodzie Pythona.

Django: wywołaj API we widoku lub poleceniu zarządzania. W przypadku asynchronicznego Django (3.1+) użyj httpx.AsyncClient w asynchronicznych widokach.

Piwko Wywołuj API w obsługującym trasę programie po stronie serwera. Nigdy nie wywołuj go z szablonu Jinja ani z kodu JavaScript po stronie klienta. Użyj Flask-Celery do oddelegowania masowych wysyłek do pracowników w tle.

FastAPI: użyj httpx.AsyncClient wewnątrz asynchroniczne def końcówki. Synchroniczne żądania biblioteka blokuje asynchroniczną pętlę zdarzeń - zawsze używaj asynchronicznego klienta HTTP w FastAPI.

smtplib łączy się bezpośrednio z serwerem SMTP z Twojego procesu Pythona. Zarządzasz poświadczeniami SMTP, konfiguracją TLS i specyfiką poszczególnych dostawców (hasła aplikacji Gmail, nowoczesne uwierzytelnianie Outlook). Jest też tylko synchroniczny.

API pocztowe Unipile to abstrakcja chmurowa: połącz konta przez OAuth (bez danych logowania SMTP w Twoim kodzie dla Gmail/Outlook), uzyskaj jednolity, spójny interfejs HTTP API dla wszystkich dostawców, a Unipile zajmie się transportem, odświeżaniem tokenów i ponownymi próbami. Kompromisem jest to, że wysyłki będą kierowane przez infrastrukturę Unipile zamiast bezpośredniego połączenia SMTP.

Tak, ale potrzebujesz asynchronicznego klienta HTTP – standardowego żądania biblioteka jest synchroniczna i zablokuje twoją pętlę zdarzeń. Użyj httpx (zalecana, asynchroniczna alternatywa typu drop-in) lub aiohttp.

import httpx, os, json asynchroniczne def wyślij_email_asynchronicznie(do: str, temat: str, ciało: str): async with httpx.AsyncClient() jako klient: odp = czekać klient.stanowisko( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', nagłówki={'Klucz API X': os.environ['UNIPILE_API_KEY']}, dane={'id_konta': os.environ['UNIPILE_ID_KONTA'], 'do': json.zrzuty([{'identyfikator': do}]), 'temat'temat, 'ciało'ciało ) lub.podnieś_status() return lub.json()

Użyj kolejki zadań Celery z brokerem Redis lub RabbitMQ. Każdy e-mail staje się zadaniem – Celery automatycznie zarządza równoległością i ponownymi próbami. Ogranicz równoległość na pracownika, aby uniknąć limitów wysyłania (zazwyczaj 5-10 równoczesnych wysyłek na powiązane konto). W przypadku wysyłek marketingowych o bardzo dużej skali (miliony dziennie), połącz Unipile do transakcyjnych wysyłek opartych na OAuth z dedykowanym ESP do kampanii masowych.

W przypadku lżejszych zastosowań, concurrent.futures.ThreadPoolExecutor(max_workers=5) z żądania biblioteka to prostsze podejście, które eliminuje narzut Celery.

Tak. Stwórz zadanie Celery, które wywoła requests.post() do punktu końcowego Unipile. Procesy robocze Celery to standardowe synchroniczne procesy Pythona, więc żądania działa idealnie. Użyj wbudowanych funkcji Celery autoretry_for=(requests.exceptions.HTTPError,) z max_prób=3 oraz domyślne_opóźnienie_ponownej_próby=5 do automatycznego ponawiania prób w przypadku tymczasowych błędów. Połącz z Klucz idempotencji nagłówki zapobiegające wielokrotnemu wysyłaniu danych po ponownym uruchomieniu pracowników.

Masz jeszcze jakieś pytania? Nasz zespół służy pomocą.

pl_PLPL