Supplying API keys per request
I'd like to supply the API key for each request separatly (for different users of the same app), instead of openai.api_key = ....
I find this strange behaviour, as documented in the following code, see in particular the _UNEXPECTED_BEHAVIOR tests.
Edit: the following tests all pass with openai==0.25.0.
import os
import openai
import unittest
from openai.error import AuthenticationError, RateLimitError
# No API key is provided implicitly, to avoid leakage
assert os.environ.get('OPENAI_API_KEY') is None
# This is my API key
MINE = os.environ['MY_OPENAI_API_KEY']
prompt = "Give me three anagrams of 'Randompile':"
class NoKeyError(Exception):
pass
def inspector(f):
def _(*a, **kw):
try:
result = f(*a, **kw)
except RateLimitError:
raise RuntimeError("This test assumes the API key is still valid.")
except AuthenticationError as ex:
if "No API key provided" in ex.user_message:
raise NoKeyError
else:
raise
else:
return result
return _
@inspector
def completion(*, key_constr=None, key_member=None):
worker = openai.Completion(api_key=key_constr)
return worker.create(api_key=key_member, model='text-davinci-003', prompt=prompt)
@inspector
def dalleimage(*, key_constr=None, key_member=None):
worker = openai.Image(api_key=key_constr)
return worker.create(api_key=key_member, prompt=prompt)
class ObservedBehavior(unittest.TestCase):
def test_completion_00(self):
with self.assertRaises(NoKeyError):
completion(key_constr=None, key_member=None)
def test_completion_10_UNEXPECTED_BEHAVIOUR(self):
with self.assertRaises(NoKeyError):
completion(key_constr=MINE, key_member=None)
def test_completion_01(self):
result = completion(key_constr=None, key_member=MINE)
# print(f"{prompt}", result['choices'][0]['text'].strip(), sep='\n')
def test_completion_11(self):
result = completion(key_constr=MINE, key_member=MINE)
# print(f"{prompt}", result['choices'][0]['text'].strip(), sep='\n')
def test_dalleimage_00(self):
with self.assertRaises(NoKeyError):
dalleimage(key_constr=None, key_member=None)
def test_dalleimage_10_UNEXPECTED_BEHAVIOUR(self):
with self.assertRaises(NoKeyError):
dalleimage(key_constr=MINE, key_member=None)
def test_dalleimage_01_UNEXPECTED_BEHAVIOUR(self):
with self.assertRaises(NoKeyError):
dalleimage(key_constr=None, key_member=MINE)
def test_dalleimage_11_UNEXPECTED_BEHAVIOUR(self):
with self.assertRaises(NoKeyError):
dalleimage(key_constr=MINE, key_member=MINE)
if __name__ == '__main__':
unittest.main()
Thanks @numpde !
I'm a little confused by this issue. Can you elaborate a bit more on what you'd expect to see in the different test cases?
Basically, I'd expect
openai.Image(api_key=api_key).create(...)
or
openai.Image.create(api_key=api_key, ...)
to work, but they don't.
What I did to work-around was:
def create(**kw):
worker = openai.Image()
assert api_key
worker.refresh_from({}, api_key=api_key) # hammer it in
return worker.request("post", worker._get_url("generations"), kw)
create(prompt=....)
That makes sense. I've been able to recreate this behavior on Image.create but not on other API calls. Are there any other places you're seeing this issue?
That makes sense. I've been able to recreate this behavior on Image.create but not on other API calls. Are there any other places you're seeing this issue?
I haven't tried (but seeing the code, I don't expect it).
We probably won't be able to merge this in until after the holidays, but I think the patch above should fix your issue?