Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Supplying API keys per request #160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
numpde opened this issue Dec 22, 2022 · 5 comments · Fixed by #163
Closed

Supplying API keys per request #160

numpde opened this issue Dec 22, 2022 · 5 comments · Fixed by #163

Comments

@numpde
Copy link

numpde commented Dec 22, 2022

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()
@hallacy
Copy link
Collaborator

hallacy commented Dec 22, 2022

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?

@numpde
Copy link
Author

numpde commented Dec 22, 2022

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=....)

@hallacy
Copy link
Collaborator

hallacy commented Dec 23, 2022

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?

@numpde
Copy link
Author

numpde commented Dec 23, 2022

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).

@hallacy
Copy link
Collaborator

hallacy commented Dec 23, 2022

We probably won't be able to merge this in until after the holidays, but I think the patch above should fix your issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants