A biblioteca OpenAI Python fornece acesso conveniente à API REST OpenAI de qualquer aplicativo Python 3.8+. A biblioteca inclui definições de tipo para todos os parâmetros de solicitação e campos de resposta e oferece clientes síncronos e assíncronos com tecnologia httpx.
Ele é gerado a partir de nossa especificação OpenAPI com Stainless.
A documentação da API REST pode ser encontrada em platform.openai.com. A API completa desta biblioteca pode ser encontrada em api.md.
Importante
O SDK foi reescrito na v1, lançada em 6 de novembro de 2023. Consulte o guia de migração v1, que inclui scripts para atualizar automaticamente seu código.
# install from PyPI
pip install openai
A API completa desta biblioteca pode ser encontrada em 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" ,
)
Embora você possa fornecer um argumento de palavra-chave api_key
, recomendamos usar python-dotenv para adicionar OPENAI_API_KEY="My API Key"
ao seu arquivo .env
para que sua chave de API não seja armazenada no controle de origem.
Com uma imagem hospedada:
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 } " },
},
],
}
],
)
Com a imagem como uma string codificada em base64:
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 } " },
},
],
}
],
)
Ao interagir com a API, algumas ações, como iniciar uma execução e adicionar arquivos aos armazenamentos de vetores, são assíncronas e demoram para serem concluídas. O SDK inclui funções auxiliares que pesquisarão o status até atingir um estado terminal e então retornarão o objeto resultante. Se um método API resultar em uma ação que possa se beneficiar da pesquisa, haverá uma versão correspondente do método terminando em '_and_poll'.
Por exemplo, para criar uma execução e pesquisa até atingir um estado terminal, você pode executar:
run = client . beta . threads . runs . create_and_poll (
thread_id = thread . id ,
assistant_id = assistant . id ,
)
Mais informações sobre o ciclo de vida de uma execução podem ser encontradas na documentação do ciclo de vida da execução
Ao criar e interagir com armazenamentos de vetores, você pode usar auxiliares de sondagem para monitorar o status das operações. Por conveniência, também fornecemos um auxiliar de upload em massa para permitir que você carregue vários arquivos simultaneamente.
sample_files = [ Path ( "sample-paper.pdf" ), ...]
batch = await client . vector_stores . file_batches . upload_and_poll (
store . id ,
files = sample_files ,
)
O SDK também inclui auxiliares para processar fluxos e lidar com eventos recebidos.
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 )
Mais informações sobre auxiliares de streaming podem ser encontradas na documentação dedicada: helpers.md
Simplesmente importe AsyncOpenAI
em vez de OpenAI
e use await
com cada chamada de API:
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 ())
A funcionalidade entre os clientes síncronos e assíncronos é idêntica.
Fornecemos suporte para respostas de streaming usando 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 = "" )
O cliente assíncrono usa exatamente a mesma interface.
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 ())
Importante
É altamente recomendável instanciar instâncias de clientes em vez de confiar no cliente global.
Também expomos uma instância de cliente global que pode ser acessada de maneira semelhante às versões anteriores à v1.
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 )
A API é exatamente igual à API padrão baseada em instância do cliente.
Destina-se a ser usado em REPLs ou notebooks para iteração mais rápida, não no código do aplicativo.
Recomendamos que você sempre instancie um cliente (por exemplo, com client = OpenAI()
) no código da aplicação porque:
Os parâmetros de solicitação aninhados são TypedDicts. As respostas são modelos Pydantic que também fornecem métodos auxiliares para coisas como:
model.to_json()
model.to_dict()
Solicitações e respostas digitadas fornecem preenchimento automático e documentação em seu editor. Se você quiser ver erros de tipo no VS Code para ajudar a detectar bugs mais cedo, defina python.analysis.typeCheckingMode
como basic
.
Os métodos de lista na API OpenAI são paginados.
Esta biblioteca fornece iteradores de paginação automática com cada resposta da lista, para que você não precise solicitar páginas sucessivas manualmente:
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 )
Ou, de forma assíncrona:
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 ())
Alternativamente, você pode usar os métodos .has_next_page()
, .next_page_info()
ou .get_next_page()
para um controle mais granular ao trabalhar com páginas:
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.
Ou apenas trabalhe diretamente com os dados retornados:
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.
Parâmetros aninhados são dicionários digitados usando TypedDict
, por exemplo:
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" },
)
Os parâmetros de solicitação que correspondem aos uploads de arquivos podem ser passados como bytes
, uma instância PathLike
ou uma tupla de (filename, contents, media type)
.
from pathlib import Path
from openai import OpenAI
client = OpenAI ()
client . files . create (
file = Path ( "input.jsonl" ),
purpose = "fine-tune" ,
)
O cliente assíncrono usa exatamente a mesma interface. Se você passar uma instância PathLike
, o conteúdo do arquivo será lido de forma assíncrona e automática.
Quando a biblioteca não consegue se conectar à API (por exemplo, devido a problemas de conexão de rede ou tempo limite), uma subclasse de openai.APIConnectionError
é gerada.
Quando a API retorna um código de status de falha (ou seja, resposta 4xx ou 5xx), uma subclasse de openai.APIStatusError
é gerada, contendo status_code
e propriedades response
.
Todos os erros são herdados de 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 )
Os códigos de erro são os seguintes:
Código de status | Tipo de erro |
---|---|
400 | BadRequestError |
401 | AuthenticationError |
403 | PermissionDeniedError |
404 | NotFoundError |
422 | UnprocessableEntityError |
429 | RateLimitError |
>=500 | InternalServerError |
N / D | APIConnectionError |
Para obter mais informações sobre solicitações de depuração, consulte estes documentos
Todas as respostas de objeto no SDK fornecem uma propriedade _request_id
que é adicionada do cabeçalho de resposta x-request-id
para que você possa registrar rapidamente solicitações com falha e reportá-las ao OpenAI.
completion = await client . chat . completions . create (
messages = [{ "role" : "user" , "content" : "Say this is a test" }], model = "gpt-4"
)
print ( completion . _request_id ) # req_123
Observe que, diferentemente de outras propriedades que usam um prefixo _
, a propriedade _request_id
é pública. A menos que documentado de outra forma, todas as outras propriedades, métodos e módulos _
prefix são private .
Certos erros são repetidos automaticamente 2 vezes por padrão, com uma espera exponencial curta. Erros de conexão (por exemplo, devido a um problema de conectividade de rede), 408 Request Timeout, 409 Conflict, 429 Rate Limit e >=500 Erros internos são todos repetidos por padrão.
Você pode usar a opção max_retries
para definir ou desabilitar as configurações de nova tentativa:
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" ,
)
Por padrão, as solicitações expiram após 10 minutos. Você pode configurar isso com uma opção timeout
, que aceita um objeto float ou httpx.Timeout
:
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" ,
)
No tempo limite, um APITimeoutError
é lançado.
Observe que as solicitações que atingem o tempo limite são repetidas duas vezes por padrão.
Usamos o módulo logging
de biblioteca padrão.
Você pode ativar o log definindo a variável de ambiente OPENAI_LOG
como info
.
$ export OPENAI_LOG=info
Ou para debug
para obter registros mais detalhados.
None
significa null
ou ausente Em uma resposta da API, um campo pode ser explicitamente null
ou totalmente ausente; em ambos os casos, seu valor é None
nesta biblioteca. Você pode diferenciar os dois casos com .model_fields_set
:
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}.' )
O objeto Response "bruto" pode ser acessado prefixando .with_raw_response.
para qualquer chamada de método HTTP, por exemplo,
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 )
Esses métodos retornam um objeto LegacyAPIResponse
. Esta é uma classe legada, pois iremos alterá-la ligeiramente na próxima versão principal.
Para o cliente de sincronização, isso será basicamente o mesmo, com exceção do content
e text
será métodos em vez de propriedades. No cliente assíncrono, todos os métodos serão assíncronos.
Um script de migração será fornecido e a migração em geral deverá ser tranquila.
.with_streaming_response
A interface acima lê ansiosamente o corpo completo da resposta quando você faz a solicitação, o que pode nem sempre ser o que você deseja.
Para transmitir o corpo da resposta, use .with_streaming_response
, que requer um gerenciador de contexto e só lê o corpo da resposta depois de chamar .read()
, .text()
, .json()
, .iter_bytes()
, .iter_text()
, .iter_lines()
ou .parse()
. No cliente assíncrono, esses são métodos assíncronos.
Como tal, os métodos .with_streaming_response
retornam um objeto APIResponse
diferente e o cliente assíncrono retorna um objeto AsyncAPIResponse
.
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 )
O gerenciador de contexto é necessário para que a resposta seja fechada de forma confiável.
Esta biblioteca é digitada para acesso conveniente à API documentada.
Se você precisar acessar endpoints, parâmetros ou propriedades de resposta não documentados, a biblioteca ainda poderá ser usada.
Para fazer solicitações a endpoints não documentados, você pode fazer solicitações usando client.get
, client.post
e outros verbos http. As opções do cliente serão respeitadas (como novas tentativas) ao fazer esta solicitação.
import httpx
response = client . post (
"/foo" ,
cast_to = httpx . Response ,
body = { "my_param" : True },
)
print ( response . headers . get ( "x-foo" ))
Se quiser enviar explicitamente um parâmetro extra, você pode fazer isso com as opções de solicitação extra_query
, extra_body
e extra_headers
.
Para acessar propriedades de resposta não documentadas, você pode acessar campos extras como response.unknown_prop
. Você também pode obter todos os campos extras no modelo Pydantic como um ditado com response.model_extra
.
Você pode substituir diretamente o cliente httpx para personalizá-lo de acordo com seu caso de uso, incluindo:
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" ),
),
)
Você também pode personalizar o cliente por solicitação usando with_options()
:
client . with_options ( http_client = DefaultHttpxClient (...))
Por padrão, a biblioteca fecha conexões HTTP subjacentes sempre que o cliente é coletado como lixo. Você pode fechar manualmente o cliente usando o método .close()
se desejar, ou com um gerenciador de contexto que fecha ao sair.
Para utilizar esta biblioteca com Azure OpenAI, utilize a classe AzureOpenAI
em vez da classe OpenAI
.
Importante
A forma da API do Azure difere da forma da API principal, o que significa que os tipos estáticos para respostas/parâmetros nem sempre estarão corretos.
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 ())
Além das opções fornecidas no cliente OpenAI
base, são fornecidas as seguintes opções:
azure_endpoint
(ou a variável de ambiente AZURE_OPENAI_ENDPOINT
)azure_deployment
api_version
(ou a variável de ambiente OPENAI_API_VERSION
)azure_ad_token
(ou a variável de ambiente AZURE_OPENAI_AD_TOKEN
)azure_ad_token_provider
Um exemplo de uso do cliente com Microsoft Entra ID (anteriormente conhecido como Azure Active Directory) pode ser encontrado aqui.
Este pacote geralmente segue as convenções do SemVer, embora certas alterações incompatíveis com versões anteriores possam ser lançadas como versões secundárias:
Levamos a compatibilidade com versões anteriores a sério e trabalhamos duro para garantir que você possa contar com uma experiência de atualização tranquila.
Estamos ansiosos pelo seu feedback; abra um problema com perguntas, bugs ou sugestões.
Se você atualizou para a versão mais recente, mas não está vendo nenhum recurso novo que esperava, então seu ambiente python provavelmente ainda está usando uma versão mais antiga.
Você pode determinar a versão que está sendo usada em tempo de execução com:
import openai
print ( openai . __version__ )
Python 3.8 ou superior.
Veja a documentação de contribuição.