Die OpenAI-Python-Bibliothek bietet bequemen Zugriff auf die OpenAI-REST-API von jeder Python 3.8+-Anwendung aus. Die Bibliothek enthält Typdefinitionen für alle Anforderungsparameter und Antwortfelder und bietet sowohl synchrone als auch asynchrone Clients mit httpx-Unterstützung.
Es wird aus unserer OpenAPI-Spezifikation mit Stainless generiert.
Die REST-API-Dokumentation finden Sie auf platform.openai.com. Die vollständige API dieser Bibliothek finden Sie in api.md.
Wichtig
Das SDK wurde in Version 1 neu geschrieben, die am 6. November 2023 veröffentlicht wurde. Sehen Sie sich den Migrationsleitfaden für Version 1 an, der Skripte zur automatischen Aktualisierung Ihres Codes enthält.
# install from PyPI
pip install openai
Die vollständige API dieser Bibliothek finden Sie in api.md.
import os
from openai import OpenAI
client = OpenAI (
api_key = os . environ . get ( "OPENAI_API_KEY" ), # This is the default and can be omitted
)
chat_completion = client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
)
Sie können zwar ein api_key
Schlüsselwortargument angeben, wir empfehlen jedoch die Verwendung von python-dotenv, um OPENAI_API_KEY="My API Key"
zu Ihrer .env
Datei hinzuzufügen, damit Ihr API-Schlüssel nicht in der Quellcodeverwaltung gespeichert wird.
Mit einem gehosteten Bild:
response = client . chat . completions . create (
model = "gpt-4o-mini" ,
messages = [
{
"role" : "user" ,
"content" : [
{ "type" : "text" , "text" : prompt },
{
"type" : "image_url" ,
"image_url" : { "url" : f" { img_url } " },
},
],
}
],
)
Mit dem Bild als Base64-codierter String:
response = client . chat . completions . create (
model = "gpt-4o-mini" ,
messages = [
{
"role" : "user" ,
"content" : [
{ "type" : "text" , "text" : prompt },
{
"type" : "image_url" ,
"image_url" : { "url" : f"data: { img_type } ;base64, { img_b64_str } " },
},
],
}
],
)
Bei der Interaktion mit der API sind einige Aktionen wie das Starten eines Laufs und das Hinzufügen von Dateien zu Vektorspeichern asynchron und nehmen Zeit in Anspruch. Das SDK enthält Hilfsfunktionen, die den Status abfragen, bis ein Endstatus erreicht ist, und dann das resultierende Objekt zurückgeben. Wenn eine API-Methode zu einer Aktion führt, die von der Abfrage profitieren könnte, gibt es eine entsprechende Version der Methode, die auf „_and_poll“ endet.
Um beispielsweise einen Lauf zu erstellen und abzufragen, bis ein Endzustand erreicht ist, können Sie Folgendes ausführen:
run = client . beta . threads . runs . create_and_poll (
thread_id = thread . id ,
assistant_id = assistant . id ,
)
Weitere Informationen zum Lebenszyklus eines Laufs finden Sie in der Run Lifecycle-Dokumentation
Beim Erstellen und Interagieren mit Vektorspeichern können Sie Polling-Helfer verwenden, um den Status von Vorgängen zu überwachen. Der Einfachheit halber bieten wir auch einen Bulk-Upload-Assistenten an, mit dem Sie mehrere Dateien gleichzeitig hochladen können.
sample_files = [ Path ( "sample-paper.pdf" ), ...]
batch = await client . vector_stores . file_batches . upload_and_poll (
store . id ,
files = sample_files ,
)
Das SDK enthält außerdem Helfer zum Verarbeiten von Streams und zum Behandeln eingehender Ereignisse.
with client . beta . threads . runs . stream (
thread_id = thread . id ,
assistant_id = assistant . id ,
instructions = "Please address the user as Jane Doe. The user has a premium account." ,
) as stream :
for event in stream :
# Print the text from text delta events
if event . type == "thread.message.delta" and event . data . delta . content :
print ( event . data . delta . content [ 0 ]. text )
Weitere Informationen zu Streaming-Helfern finden Sie in der entsprechenden Dokumentation: helpers.md
Importieren Sie einfach AsyncOpenAI
anstelle von OpenAI
und verwenden Sie await
bei jedem API-Aufruf:
import os
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI (
api_key = os . environ . get ( "OPENAI_API_KEY" ), # This is the default and can be omitted
)
async def main () -> None :
chat_completion = await client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
)
asyncio . run ( main ())
Die Funktionalität zwischen den synchronen und asynchronen Clients ist ansonsten identisch.
Wir bieten Unterstützung für das Streamen von Antworten mithilfe von Server Side Events (SSE).
from openai import OpenAI
client = OpenAI ()
stream = client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
stream = True ,
)
for chunk in stream :
print ( chunk . choices [ 0 ]. delta . content or "" , end = "" )
Der asynchrone Client verwendet genau dieselbe Schnittstelle.
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI ()
async def main ():
stream = await client . chat . completions . create (
model = "gpt-4" ,
messages = [{ "role" : "user" , "content" : "Say this is a test" }],
stream = True ,
)
async for chunk in stream :
print ( chunk . choices [ 0 ]. delta . content or "" , end = "" )
asyncio . run ( main ())
Wichtig
Wir empfehlen dringend, Clientinstanzen zu instanziieren, anstatt sich auf den globalen Client zu verlassen.
Wir stellen außerdem eine globale Client-Instanz bereit, auf die auf ähnliche Weise wie bei Versionen vor Version 1 zugegriffen werden kann.
import openai
# optional; defaults to `os.environ['OPENAI_API_KEY']`
openai . api_key = '...'
# all client options can be configured just like the `OpenAI` instantiation counterpart
openai . base_url = "https://..."
openai . default_headers = { "x-foo" : "true" }
completion = openai . chat . completions . create (
model = "gpt-4o" ,
messages = [
{
"role" : "user" ,
"content" : "How do I output all files in a directory using Python?" ,
},
],
)
print ( completion . choices [ 0 ]. message . content )
Die API ist genau die gleiche wie die Standard-Client-Instanz-basierte API.
Dies soll zur schnelleren Iteration in REPLs oder Notebooks verwendet werden, nicht im Anwendungscode.
Wir empfehlen, dass Sie im Anwendungscode immer einen Client instanziieren (z. B. mit client = OpenAI()
), weil:
Verschachtelte Anforderungsparameter sind TypedDicts. Antworten sind Pydantic-Modelle, die auch Hilfsmethoden für Dinge bereitstellen wie:
model.to_json()
model.to_dict()
Eingegebene Anfragen und Antworten ermöglichen die automatische Vervollständigung und Dokumentation in Ihrem Editor. Wenn Sie Typfehler in VS-Code sehen möchten, um Fehler früher zu erkennen, legen Sie python.analysis.typeCheckingMode
auf basic
fest.
Listenmethoden in der OpenAI-API sind paginiert.
Diese Bibliothek stellt automatisch paginierende Iteratoren für jede Listenantwort bereit, sodass Sie aufeinanderfolgende Seiten nicht manuell anfordern müssen:
from openai import OpenAI
client = OpenAI ()
all_jobs = []
# Automatically fetches more pages as needed.
for job in client . fine_tuning . jobs . list (
limit = 20 ,
):
# Do something with job here
all_jobs . append ( job )
print ( all_jobs )
Oder asynchron:
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI ()
async def main () -> None :
all_jobs = []
# Iterate through items across all pages, issuing requests as needed.
async for job in client . fine_tuning . jobs . list (
limit = 20 ,
):
all_jobs . append ( job )
print ( all_jobs )
asyncio . run ( main ())
Alternativ können Sie die Methoden .has_next_page()
, .next_page_info()
oder .get_next_page()
für eine detailliertere Steuerung der Arbeit mit Seiten verwenden:
first_page = await client . fine_tuning . jobs . list (
limit = 20 ,
)
if first_page . has_next_page ():
print ( f"will fetch next page using these details: { first_page . next_page_info () } " )
next_page = await first_page . get_next_page ()
print ( f"number of items we just fetched: { len ( next_page . data ) } " )
# Remove `await` for non-async usage.
Oder arbeiten Sie einfach direkt mit den zurückgegebenen Daten:
first_page = await client . fine_tuning . jobs . list (
limit = 20 ,
)
print ( f"next page cursor: { first_page . after } " ) # => "next page cursor: ..."
for job in first_page . data :
print ( job . id )
# Remove `await` for non-async usage.
Verschachtelte Parameter sind Wörterbücher, die mit TypedDict
eingegeben werden, zum Beispiel:
from openai import OpenAI
client = OpenAI ()
completion = client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Can you generate an example json object describing a fruit?" ,
}
],
model = "gpt-4o" ,
response_format = { "type" : "json_object" },
)
Anforderungsparameter, die Datei-Uploads entsprechen, können als bytes
, eine PathLike
Instanz oder ein Tupel von (filename, contents, media type)
übergeben werden.
from pathlib import Path
from openai import OpenAI
client = OpenAI ()
client . files . create (
file = Path ( "input.jsonl" ),
purpose = "fine-tune" ,
)
Der asynchrone Client verwendet genau dieselbe Schnittstelle. Wenn Sie eine PathLike
Instanz übergeben, werden die Dateiinhalte asynchron automatisch gelesen.
Wenn die Bibliothek keine Verbindung zur API herstellen kann (z. B. aufgrund von Netzwerkverbindungsproblemen oder einer Zeitüberschreitung), wird eine Unterklasse von openai.APIConnectionError
ausgelöst.
Wenn die API einen nicht erfolgreichen Statuscode zurückgibt (d. h. eine 4xx- oder 5xx-Antwort), wird eine Unterklasse von openai.APIStatusError
ausgelöst, status_code
und response
enthält.
Alle Fehler erben von openai.APIError
.
import openai
from openai import OpenAI
client = OpenAI ()
try :
client . fine_tuning . jobs . create (
model = "gpt-4o" ,
training_file = "file-abc123" ,
)
except openai . APIConnectionError as e :
print ( "The server could not be reached" )
print ( e . __cause__ ) # an underlying Exception, likely raised within httpx.
except openai . RateLimitError as e :
print ( "A 429 status code was received; we should back off a bit." )
except openai . APIStatusError as e :
print ( "Another non-200-range status code was received" )
print ( e . status_code )
print ( e . response )
Die Fehlercodes lauten wie folgt:
Statuscode | Fehlertyp |
---|---|
400 | BadRequestError |
401 | AuthenticationError |
403 | PermissionDeniedError |
404 | NotFoundError |
422 | UnprocessableEntityError |
429 | RateLimitError |
>=500 | InternalServerError |
N / A | APIConnectionError |
Weitere Informationen zu Debugging-Anfragen finden Sie in diesen Dokumenten
Alle Objektantworten im SDK stellen eine _request_id
Eigenschaft bereit, die aus dem x-request-id
-Antwortheader hinzugefügt wird, sodass Sie fehlgeschlagene Anforderungen schnell protokollieren und an OpenAI zurückmelden können.
completion = await client . chat . completions . create (
messages = [{ "role" : "user" , "content" : "Say this is a test" }], model = "gpt-4"
)
print ( completion . _request_id ) # req_123
Beachten Sie, dass die Eigenschaft _request_id
im Gegensatz zu anderen Eigenschaften, die ein _
Präfix verwenden, öffentlich ist . Sofern nicht anders dokumentiert, sind alle anderen _
Präfixeigenschaften, -Methoden und -Module privat .
Bestimmte Fehler werden standardmäßig automatisch zweimal wiederholt, mit einem kurzen exponentiellen Backoff. Verbindungsfehler (z. B. aufgrund eines Netzwerkverbindungsproblems), 408 Request Timeout, 409 Conflict, 429 Rate Limit und >=500 Internal Errors werden standardmäßig alle erneut versucht.
Mit der Option max_retries
können Sie Wiederholungseinstellungen konfigurieren oder deaktivieren:
from openai import OpenAI
# Configure the default for all requests:
client = OpenAI (
# default is 2
max_retries = 0 ,
)
# Or, configure per-request:
client . with_options ( max_retries = 5 ). chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "How can I get the name of the current day in JavaScript?" ,
}
],
model = "gpt-4o" ,
)
Standardmäßig läuft das Zeitlimit für Anfragen nach 10 Minuten ab. Sie können dies mit einer timeout
Option konfigurieren, die ein Float- oder ein httpx.Timeout
-Objekt akzeptiert:
from openai import OpenAI
# Configure the default for all requests:
client = OpenAI (
# 20 seconds (default is 10 minutes)
timeout = 20.0 ,
)
# More granular control:
client = OpenAI (
timeout = httpx . Timeout ( 60.0 , read = 5.0 , write = 10.0 , connect = 2.0 ),
)
# Override per-request:
client . with_options ( timeout = 5.0 ). chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "How can I list all files in a directory using Python?" ,
}
],
model = "gpt-4o" ,
)
Bei einer Zeitüberschreitung wird ein APITimeoutError
ausgelöst.
Beachten Sie, dass Anfragen, bei denen eine Zeitüberschreitung auftritt, standardmäßig zweimal wiederholt werden.
Wir verwenden das Standard- logging
.
Sie können die Protokollierung aktivieren, indem Sie die Umgebungsvariable OPENAI_LOG
auf info
setzen.
$ export OPENAI_LOG=info
Oder zum debug
für eine ausführlichere Protokollierung.
None
null
oder fehlend bedeutet In einer API-Antwort kann ein Feld explizit null
sein oder ganz fehlen; In beiden Fällen ist der Wert in dieser Bibliothek None
. Sie können die beiden Fälle mit .model_fields_set
unterscheiden:
if response . my_field is None :
if 'my_field' not in response . model_fields_set :
print ( 'Got json like {}, without a "my_field" key present at all.' )
else :
print ( 'Got json like {"my_field": null}.' )
Auf das „rohe“ Antwortobjekt kann durch das Präfix .with_raw_response.
zu jedem HTTP-Methodenaufruf, z. B.
from openai import OpenAI
client = OpenAI ()
response = client . chat . completions . with_raw_response . create (
messages = [{
"role" : "user" ,
"content" : "Say this is a test" ,
}],
model = "gpt-4o" ,
)
print ( response . headers . get ( 'X-My-Header' ))
completion = response . parse () # get the object that `chat.completions.create()` would have returned
print ( completion )
Diese Methoden geben ein LegacyAPIResponse
Objekt zurück. Dies ist eine Legacy-Klasse, da wir sie in der nächsten Hauptversion leicht ändern.
Für den Synchronisierungsclient ist dies größtenteils dasselbe, mit der Ausnahme, dass es sich bei content
und text
um Methoden und nicht um Eigenschaften handelt. Im asynchronen Client sind alle Methoden asynchron.
Es wird ein Migrationsskript bereitgestellt und die Migration sollte im Allgemeinen reibungslos verlaufen.
.with_streaming_response
Die obige Schnittstelle liest eifrig den vollständigen Antworttext, wenn Sie die Anfrage stellen, was möglicherweise nicht immer Ihren Wünschen entspricht.
Um den Antworttext zu streamen, verwenden Sie stattdessen .with_streaming_response
, was einen Kontextmanager erfordert und den Antworttext erst liest, wenn Sie .read()
, .text()
, .json()
, .iter_bytes()
, .iter_text()
aufrufen. .iter_lines()
oder .parse()
. Im asynchronen Client sind dies asynchrone Methoden.
Daher geben .with_streaming_response
-Methoden ein anderes APIResponse
Objekt zurück, und der asynchrone Client gibt ein AsyncAPIResponse
-Objekt zurück.
with client . chat . completions . with_streaming_response . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
) as response :
print ( response . headers . get ( "X-My-Header" ))
for line in response . iter_lines ():
print ( line )
Der Kontextmanager ist erforderlich, damit die Antwort zuverlässig geschlossen wird.
Diese Bibliothek ist für den bequemen Zugriff auf die dokumentierte API typisiert.
Wenn Sie auf undokumentierte Endpunkte, Parameter oder Antworteigenschaften zugreifen müssen, kann die Bibliothek weiterhin verwendet werden.
Um Anfragen an undokumentierte Endpunkte zu stellen, können Sie Anfragen mit client.get
, client.post
und anderen http-Verben stellen. Optionen auf dem Client werden berücksichtigt (z. B. Wiederholungsversuche), wenn diese Anfrage gestellt wird.
import httpx
response = client . post (
"/foo" ,
cast_to = httpx . Response ,
body = { "my_param" : True },
)
print ( response . headers . get ( "x-foo" ))
Wenn Sie explizit einen zusätzlichen Parameter senden möchten, können Sie dies mit den Anforderungsoptionen extra_query
, extra_body
und extra_headers
tun.
Um auf undokumentierte Antworteigenschaften zuzugreifen, können Sie auf zusätzliche Felder wie response.unknown_prop
zugreifen. Sie können alle zusätzlichen Felder des Pydantic-Modells auch als Diktat mit response.model_extra
abrufen.
Sie können den httpx-Client direkt überschreiben, um ihn an Ihren Anwendungsfall anzupassen, einschließlich:
from openai import OpenAI , DefaultHttpxClient
client = OpenAI (
# Or use the `OPENAI_BASE_URL` env var
base_url = "http://my.test.server.example.com:8083/v1" ,
http_client = DefaultHttpxClient (
proxies = "http://my.test.proxy.example.com" ,
transport = httpx . HTTPTransport ( local_address = "0.0.0.0" ),
),
)
Sie können den Client auch auf Anfragebasis anpassen, indem Sie with_options()
verwenden:
client . with_options ( http_client = DefaultHttpxClient (...))
Standardmäßig schließt die Bibliothek zugrunde liegende HTTP-Verbindungen, wenn der Client einer Garbage Collection unterzogen wird. Sie können den Client bei Bedarf manuell mit der Methode .close()
oder mit einem Kontextmanager schließen, der beim Beenden geschlossen wird.
Um diese Bibliothek mit Azure OpenAI zu verwenden, verwenden Sie die AzureOpenAI
-Klasse anstelle der OpenAI
-Klasse.
Wichtig
Die Azure-API-Form unterscheidet sich von der Kern-API-Form, was bedeutet, dass die statischen Typen für Antworten/Parameter nicht immer korrekt sind.
from openai import AzureOpenAI
# gets the API Key from environment variable AZURE_OPENAI_API_KEY
client = AzureOpenAI (
# https://learn.microsoft.com/azure/ai-services/openai/reference#rest-api-versioning
api_version = "2023-07-01-preview" ,
# https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource
azure_endpoint = "https://example-endpoint.openai.azure.com" ,
)
completion = client . chat . completions . create (
model = "deployment-name" , # e.g. gpt-35-instant
messages = [
{
"role" : "user" ,
"content" : "How do I output all files in a directory using Python?" ,
},
],
)
print ( completion . to_json ())
Zusätzlich zu den im Basis OpenAI
Client bereitgestellten Optionen stehen die folgenden Optionen zur Verfügung:
azure_endpoint
(oder die Umgebungsvariable AZURE_OPENAI_ENDPOINT
)azure_deployment
api_version
(oder die Umgebungsvariable OPENAI_API_VERSION
)azure_ad_token
(oder die Umgebungsvariable AZURE_OPENAI_AD_TOKEN
)azure_ad_token_provider
Ein Beispiel für die Verwendung des Clients mit Microsoft Entra ID (früher bekannt als Azure Active Directory) finden Sie hier.
Dieses Paket folgt im Allgemeinen den SemVer-Konventionen, obwohl bestimmte abwärtsinkompatible Änderungen möglicherweise als Nebenversionen veröffentlicht werden:
Wir nehmen die Abwärtskompatibilität ernst und arbeiten hart, um sicherzustellen, dass Sie sich auf ein reibungsloses Upgrade-Erlebnis verlassen können.
Wir freuen uns über Ihr Feedback; Bitte öffnen Sie ein Problem mit Fragen, Fehlern oder Vorschlägen.
Wenn Sie auf die neueste Version aktualisiert haben, aber keine erwarteten neuen Funktionen sehen, verwendet Ihre Python-Umgebung wahrscheinlich immer noch eine ältere Version.
Sie können die zur Laufzeit verwendete Version ermitteln mit:
import openai
print ( openai . __version__ )
Python 3.8 oder höher.
Siehe die beitragende Dokumentation.