openai-python
openai-python copied to clipboard
Add Support for API Key Provider
Confirm this is a feature request for the Python library and not the underlying OpenAI API.
- [X] This is a feature request for the Python library
Describe the feature or improvement you're requesting
Similar to azure_ad_token_provider, support an openai_api_key_provider for OpenAI and AzureOpenAI instances. The application scenario is that OpenAI API keys are managed by some OAuth2 token servers, where a request is posted to the token servers and an API key with expiration is granted. In this case, for long running services, each time a request for OpenAI API is made, it is necessary to check and update the cached OpenAI API key. Therefore, I think it would be good to have an openai_api_key_provider to manage this situation.
Additional context
No response
We're also interested in this feature for basically the same reason - I'll try tagging @kwhinnery-openai (please feel free to reroute!) who I saw active on some other PRs in this repo recently. Happy to think through a proposal for the interface of a credential provider if it's something y'all are open to.
As a followup (not required initially, can file a followup issue for this), we'd also be interested in making this pluggable so users in our organization don't have to pass the openai_api_key_provider every time, but instead could install a plugin package that automatically provides auth.
Thinking aloud, I imagine the precedence order for resolving auth in the client when doing something like
client = OpenAI(
api_key=...,
base_url="...,
http_client=...,
openai_api_key_provider=...,
)
could then look like:
- [current behavior] Any authorization headers set in the
http_clientarg, if this arg is provided - [current behavior] The value of the
api_key, if provided - [current behavior] OpenAI environment variables (OPENAI_API_KEY etc)
- Auth explicitly specified in
openai_api_key_provider - Auth automatically provided by plugins, if
api_key,http_client,openai_api_key_providerare not passed
I'm able to create something like this by using the api_key parameter/property, since that actually sets a Bearer header behind the scenes.
import logging
import os
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv(override=True)
logging.basicConfig(level=logging.DEBUG)
credential = DefaultAzureCredential()
openai_token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default")
azure_openai_service = os.environ["AZURE_OPENAI_SERVICE"]
deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT"]
client = OpenAI(
base_url=f"https://{azure_openai_service}.openai.azure.com/openai/deployments/{deployment_name}",
api_key=openai_token_provider(),
default_query={"api-version": os.environ["AZURE_OPENAI_API_VERSION"]},
)
# We must set the api_key each time we issue a new request, to make sure our token is refreshed as needed
client.api_key = openai_token_provider()
result = client.chat.completions.create(
model=None, # this must be specified, but doesn't need a value
messages=[
{
"role": "system",
"content": "You are a helpful assistant.",
},
{
"role": "user",
"content": "What is the capital of the United States?",
},
])