Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions bin/openai
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#!/usr/bin/env python
import argparse
import json
import logging
import os
import sys

import openai
from openai.cli import display_error
from openai.cli import register as api_register
from openai.cli import api_register, tools_register

logger = logging.getLogger()
formatter = logging.Formatter("[%(asctime)s] %(message)s")
Expand Down Expand Up @@ -40,9 +38,11 @@ def main():
parser.set_defaults(func=help)

subparsers = parser.add_subparsers()
sub = subparsers.add_parser("api", help="Direct API calls")
sub_api = subparsers.add_parser("api", help="Direct API calls")
sub_tools = subparsers.add_parser("tools", help="Client side tools for convenience")

api_register(sub)
api_register(sub_api)
tools_register(sub_tools)

args = parser.parse_args()
if args.verbosity == 1:
Expand Down
2 changes: 1 addition & 1 deletion openai/api_resources/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def create(cls, *args, **kwargs):
of valid parameters.
"""
start = time.time()
timeout = kwargs.get("timeout", None)
timeout = kwargs.pop("timeout", None)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rachellim What's the reason for this change? This is preventing the timeout parameter to be passed on to super().create(...), meaning that API users have no way to specify a timeout.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @feroldi! In trying to avoid a backwards incompatible change, we added a new param called request_timeout so that users could set a timeout that didn't interfere with the existing timeout functionality. It's documented here: https://github.com/openai/openai-python#params

Does that help?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! That makes sense. Thanks.

if kwargs.get("model", None) is None and kwargs.get("engine", None) is None:
raise InvalidRequestError(
"Must provide an 'engine' or 'model' parameter to create a Completion.",
Expand Down
59 changes: 59 additions & 0 deletions openai/api_resources/file.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from __future__ import absolute_import, division, print_function

import json
import os

import openai
from openai import api_requestor, util
from openai.api_resources.abstract import (
Expand Down Expand Up @@ -29,3 +32,59 @@ def create(
return util.convert_to_openai_object(
response, api_key, api_version, organization
)

@classmethod
def download(
cls, id, api_key=None, api_base=None, api_version=None, organization=None
):
requestor = api_requestor.APIRequestor(
api_key,
api_base=api_base or openai.file_api_base or openai.api_base,
api_version=api_version,
organization=organization,
)
url = f"{cls.class_url()}/{id}/content"
rbody, rcode, rheaders, _, _ = requestor.request_raw("get", url)
if not 200 <= rcode < 300:
raise requestor.handle_error_response(
rbody, rcode, json.loads(rbody), rheaders, stream_error=False
)
return rbody

@classmethod
def find_matching_files(
cls,
api_key=None,
api_base=None,
api_version=None,
organization=None,
file=None,
purpose=None,
):
if file is None:
raise openai.error.InvalidRequestError(
"'file' is a required property", "file"
)
if purpose is None:
raise openai.error.InvalidRequestError(
"'purpose' is a required property", "purpose"
)
all_files = cls.list(
api_key=api_key,
api_base=api_base or openai.file_api_base or openai.api_base,
api_version=api_version,
organization=organization,
).get("data", [])
matching_files = []
for f in all_files:
if f["purpose"] != purpose:
continue
if not hasattr(file, "name") or f["filename"] != file.name:
continue
file.seek(0, os.SEEK_END)
if f["bytes"] != file.tell():
file.seek(0)
continue
file.seek(0)
matching_files.append(f)
return matching_files
Loading