Skip to content

Commit 4e38179

Browse files
authored
migrate to 0.6.0 (#7)
* Add support for modifying files and file_set support (#4) * Add support for modifying files and file_set support * Bump version * Updated file sets to use name everywhere * Bump to 0.4.0 * Added cli support for file and fileset (#5) * Added cli support for file and fileset * Back to .4.0 * Typo * Add some basic tests to confirm that array stuff works * Added a test for multiple prompts. * refactor retriever endpoint (#6) * Make higherlevel have class methods so you can call with openai.HigherLevel.answer (#7) * refactor retriever endpoint * Actually just make everything a classmethod so you can call it like openai.HigherLevel * Rename file_sets to collections everywhere (#8) * Rename file_sets to collections everywhere * Remove collections (#10) * Higherlevel endpoints now point to /v1 (#11) * Higherlevel endpoints now point to v1 * new line * Move answer and classification to top level attributes, rename higherlevel (#12) * Move answer and classification to top level attributes * New namespaces for answers and classifications * Meant to make the method create * Go up the class stack since we don't need all the things that engineapiresource gives us * Add file support to search (#13) * Add file support to search * Add support for max_rerank * Added return_metadata support * Fixed some cherry pick issues
1 parent ff751ab commit 4e38179

10 files changed

+165
-32
lines changed

openai/api_requestor.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ def _api_encode(data):
4545
elif isinstance(value, list) or isinstance(value, tuple):
4646
for i, sv in enumerate(value):
4747
if isinstance(sv, dict):
48-
subdict = _encode_nested_dict("%s[]" % (key,), sv)
48+
subdict = _encode_nested_dict("%s[%d]" % (key, i), sv)
4949
for k, v in _api_encode(subdict):
5050
yield (k, v)
5151
else:
52-
yield ("%s[]" % (key,), util.utf8(sv))
52+
yield ("%s[%d]" % (key, i), util.utf8(sv))
5353
elif isinstance(value, dict):
5454
subdict = _encode_nested_dict(key, value)
5555
for subkey, subvalue in _api_encode(subdict):

openai/api_resources/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from openai.api_resources.error_object import ErrorObject
55
from openai.api_resources.event import Event
66
from openai.api_resources.file import File
7-
from openai.api_resources.higherlevel import HigherLevel
7+
from openai.api_resources.answer import Answer
8+
from openai.api_resources.classification import Classification
89
from openai.api_resources.plan import Plan
910
from openai.api_resources.run import Run
1011
from openai.api_resources.snapshot import Snapshot

openai/api_resources/answer.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from openai.openai_object import OpenAIObject
2+
3+
4+
class Answer(OpenAIObject):
5+
api_prefix = "v1"
6+
7+
@classmethod
8+
def get_url(self, base):
9+
return "/%s/%s" % (self.api_prefix, base)
10+
11+
@classmethod
12+
def create(cls, **params):
13+
instance = cls()
14+
return instance.request("post", cls.get_url("answers"), params)
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from openai.openai_object import OpenAIObject
2+
3+
4+
class Classification(OpenAIObject):
5+
api_prefix = "v1"
6+
7+
@classmethod
8+
def get_url(self, base):
9+
return "/%s/%s" % (self.api_prefix, base)
10+
11+
@classmethod
12+
def create(cls, **params):
13+
instance = cls()
14+
return instance.request("post", cls.get_url("classifications"), params)

openai/api_resources/file.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,14 @@
77
import openai
88
from openai import api_requestor, util
99
from openai.api_resources.abstract import (
10-
APIResource,
11-
CreateableAPIResource,
1210
DeletableAPIResource,
1311
ListableAPIResource,
1412
UpdateableAPIResource,
1513
)
1614
from openai.util import log_info
1715

1816

19-
class File(ListableAPIResource):
17+
class File(ListableAPIResource, DeletableAPIResource):
2018
OBJECT_NAME = "file"
2119

2220
@classmethod

openai/api_resources/higherlevel.py

-17
This file was deleted.

openai/cli.py

+96-8
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def generate(cls, args):
7676
top_p=args.top_p,
7777
logprobs=args.logprobs,
7878
stop=args.stop,
79-
**kwargs
79+
**kwargs,
8080
)
8181
if not args.stream:
8282
resp = [resp]
@@ -94,17 +94,34 @@ def generate(cls, args):
9494
@classmethod
9595
def search(cls, args):
9696
# Will soon be deprecated and replaced by a Search.create
97-
resp = openai.Engine(id=args.id).search(
98-
documents=args.documents, query=args.query
99-
)
97+
params = {
98+
"query": args.query,
99+
"max_rerank": args.max_rerank,
100+
"return_metadata": args.return_metadata,
101+
}
102+
if args.documents:
103+
params["documents"] = args.documents
104+
if args.file:
105+
params["file"] = args.file
106+
107+
resp = openai.Engine(id=args.id).search(**params)
100108
scores = [
101109
(search_result["score"], search_result["document"])
102110
for search_result in resp["data"]
103111
]
104112
scores.sort(reverse=True)
113+
dataset = (
114+
args.documents if args.documents else [x["text"] for x in resp["data"]]
115+
)
105116
for score, document_idx in scores:
106117
print("=== score {:.3f} ===".format(score))
107-
print(args.documents[document_idx])
118+
print(dataset[document_idx])
119+
if (
120+
args.return_metadata
121+
and args.file
122+
and "metadata" in resp["data"][document_idx]
123+
):
124+
print(f"METADATA: {resp['data'][document_idx]['metadata']}")
108125

109126
@classmethod
110127
def list(cls, args):
@@ -195,6 +212,31 @@ def list(cls, args):
195212
print(tags)
196213

197214

215+
class File:
216+
@classmethod
217+
def create(cls, args):
218+
resp = openai.File.create(
219+
file=open(args.file),
220+
purpose=args.purpose,
221+
)
222+
print(resp)
223+
224+
@classmethod
225+
def get(cls, args):
226+
resp = openai.File.retrieve(id=args.id)
227+
print(resp)
228+
229+
@classmethod
230+
def delete(cls, args):
231+
file = openai.File(id=args.id).delete()
232+
print(file)
233+
234+
@classmethod
235+
def list(cls, args):
236+
file = openai.File.list()
237+
print(file)
238+
239+
198240
class FineTuneCLI:
199241
@classmethod
200242
def list(cls, args):
@@ -311,8 +353,26 @@ def help(args):
311353
"-d",
312354
"--documents",
313355
action="append",
314-
help="List of documents to search over",
315-
required=True,
356+
help="List of documents to search over. Only one of `documents` or `file` may be supplied.",
357+
required=False,
358+
)
359+
sub.add_argument(
360+
"-f",
361+
"--file",
362+
help="A file id to search over. Only one of `documents` or `file` may be supplied.",
363+
required=False,
364+
)
365+
sub.add_argument(
366+
"--max_rerank",
367+
help="The maximum number of documents to be re-ranked and returned by search. This flag only takes effect when `file` is set.",
368+
type=int,
369+
default=200,
370+
)
371+
sub.add_argument(
372+
"--return_metadata",
373+
help="A special boolean flag for showing metadata. If set `true`, each document entry in the returned json will contain a 'metadata' field. Default to be `false`. This flag only takes effect when `file` is set.",
374+
type=bool,
375+
default=False,
316376
)
317377
sub.add_argument("-q", "--query", required=True, help="Search query")
318378
sub.set_defaults(func=Engine.search)
@@ -424,7 +484,35 @@ def help(args):
424484
sub = subparsers.add_parser("tags.list")
425485
sub.set_defaults(func=Tag.list)
426486

427-
# /fine-tunes API
487+
# Files
488+
sub = subparsers.add_parser("files.create")
489+
490+
sub.add_argument(
491+
"-f",
492+
"--file",
493+
required=True,
494+
help="File to upload",
495+
)
496+
sub.add_argument(
497+
"-p",
498+
"--purpose",
499+
help="Why are you uploading this file? (see https://beta.openai.com/docs/api-reference/ for purposes)",
500+
required=True,
501+
)
502+
sub.set_defaults(func=File.create)
503+
504+
sub = subparsers.add_parser("files.get")
505+
sub.add_argument("-i", "--id", required=True, help="The files ID")
506+
sub.set_defaults(func=File.get)
507+
508+
sub = subparsers.add_parser("files.delete")
509+
sub.add_argument("-i", "--id", required=True, help="The files ID")
510+
sub.set_defaults(func=File.delete)
511+
512+
sub = subparsers.add_parser("files.list")
513+
sub.set_defaults(func=File.list)
514+
515+
# Finetune
428516
sub = subparsers.add_parser("fine_tunes.list")
429517
sub.set_defaults(func=FineTuneCLI.list)
430518

openai/multipart_data_generator.py

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io
55

66
import openai
7+
import re
78

89

910
class MultipartDataGenerator(object):
@@ -13,11 +14,19 @@ def __init__(self, chunk_size=1028):
1314
self.boundary = self._initialize_boundary()
1415
self.chunk_size = chunk_size
1516

17+
def _remove_array_element(self, input_string):
18+
match = re.match(r"^(.*)\[.*\]$", input_string)
19+
return match[1] if match else input_string
20+
1621
def add_params(self, params):
1722
# Flatten parameters first
1823
params = dict(openai.api_requestor._api_encode(params))
1924

2025
for key, value in openai.six.iteritems(params):
26+
27+
# strip array elements if present from key
28+
key = self._remove_array_element(key)
29+
2130
if value is None:
2231
continue
2332

openai/tests/test_endpoints.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import openai
2+
import io
3+
import json
4+
import uuid
5+
6+
### FILE TESTS
7+
def test_file_upload():
8+
result = openai.File.create(
9+
file=io.StringIO(json.dumps({"text": "test file data"})),
10+
purpose="search",
11+
)
12+
assert result.purpose == "search"
13+
assert "id" in result
14+
15+
16+
### COMPLETION TESTS
17+
def test_completions():
18+
result = openai.Completion.create(prompt="This was a test", n=5, engine="davinci")
19+
assert len(result.choices) == 5
20+
21+
22+
def test_completions_multiple_prompts():
23+
result = openai.Completion.create(
24+
prompt=["This was a test", "This was another test"], n=5, engine="davinci"
25+
)
26+
assert len(result.choices) == 10

openai/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = "0.4.0"
1+
VERSION = "0.6.0"

0 commit comments

Comments
 (0)