Skip to content

Commit

Permalink
Change API to reflect new Open AI API version in order to avoid Janua…
Browse files Browse the repository at this point in the history
…ry 4th 2024 decommissioning of old APIs.
  • Loading branch information
paraskuk committed Dec 8, 2023
1 parent 421ca3c commit 9099897
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 119 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Make sure to set the `OPEN_AI_KEY` environment variable before running the appli
## License

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
This project is not licensed for commercial use due to having been partially generated by Chat GPT.
This project is not licensed for commercial use.

## Disclaimer

Expand Down
131 changes: 86 additions & 45 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

import openai
import os

from openai import OpenAI
from exceptions.GPTException import GPTException
from models.query_model import QueryModel
from typing import Optional
Expand All @@ -13,10 +12,12 @@
import logging

app = FastAPI()
client = OpenAI(api_key=os.getenv("OPEN_AI_KEY"))

# logging
log = logging.getLogger("uvicorn")
openai.api_key = os.getenv("OPEN_AI_KEY")



templates_directory = Path(__file__).parent / "templates"
templates = Jinja2Templates(directory=templates_directory)
Expand All @@ -36,61 +37,101 @@ async def index(request: Request):
log.exception("An HTTPException occurred: %s", exc.detail)
return http_exception_handler(exc)

# This was the route with old completions API
# @app.post("/ask_gpt4/")
# async def ask_gpt4(query_params: QueryModel, model: Optional[str] = "text-davinci-003") -> dict:
# """
# Post Route receive a query and return a response with OpenAIAPI for chat GPT
# :param query_params: User input in the form of questions to chat GPT
# :param model: type of model as per OpenAIAPI specifications.
# :return: Json in the form of a JSONResponse FastAPi instance
# """
# try:
# # Call the OpenAI API
# # The model used is not gpt4 to use gpt4 as a model a different API has to be used and
# # in specific the openai.ChatCompletion.create(.....)
# response = openai.Completion.create(
# engine=model,
# prompt=query_params.user_input,
# max_tokens=1000,
# n=1,
# stop=None,
# temperature=0.5,
# )
#
# if len(response.choices) > 0 and hasattr(response.choices[0], "text"):
# answer = response.choices[0].text.strip()
# return {"response": answer}
# else:
# error_msg = "ChatGPT response does not contain text attribute."
# log.error(error_msg)
# raise GPTException(error_msg)
#
# # return {"error": "ChatGPT response does not contain text attribute."}
# except GPTException as e:
# raise e
# except Exception as e:
# log.error(f"Exception occurred: {str(e)}")
# if not query_params.user_input: # Empty user_input case
# raise GPTException("Empty user_input", status_code=400)
# else:
# raise GPTException(str(e))
# # except Exception as e:
# # return {"error": str(e)}
#
# # Exception handling


@app.post("/ask_gpt4/")
async def ask_gpt4(query_params: QueryModel, model: Optional[str] = "text-davinci-003") -> dict:
async def ask_gpt4(query_params: QueryModel) -> JSONResponse:
"""
Post Route receive a query and return a response with OpenAIAPI for chat GPT
:param query_params: User input in the form of questions to chat GPT
:param model: type of model as per OpenAIAPI specifications.
:return: Json in the form of a JSONResponse FastAPi instance
Endpoint to receive a query and return a response using OpenAI's Chat Completions API
:param query_params: User input
:return: JSONResponse containing the response
"""
try:
# Call the OpenAI API
# The model used is not gpt4 to use gpt4 as a model a different API has to be used and
# in specific the openai.ChatCompletion.create(.....)
response = openai.Completion.create(
engine=model,
prompt=query_params.user_input,
max_tokens=1000,
n=1,
stop=None,
temperature=0.5,
# Using the Chat Completions API
response = client.chat.completions.create(
model=query_params.model,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": query_params.user_input}
]
)

if len(response.choices) > 0 and hasattr(response.choices[0], "text"):
answer = response.choices[0].text.strip()
return {"response": answer}
# Extracting the response
if response.choices and len(response.choices) > 0 and response.choices[0].message:
return JSONResponse(content={"response": response.choices[0].message.content})
else:
error_msg = "ChatGPT response does not contain text attribute."
log.error(error_msg)
raise GPTException(error_msg)

# return {"error": "ChatGPT response does not contain text attribute."}
except GPTException as e:
raise e
raise HTTPException(status_code=500, detail="No response from the model.")
except Exception as e:
log.error(f"Exception occurred: {str(e)}")
if not query_params.user_input: # Empty user_input case
raise GPTException("Empty user_input", status_code=400)
else:
raise GPTException(str(e))
# except Exception as e:
# return {"error": str(e)}

# Exception handling


raise HTTPException(status_code=500, detail=str(e))

# @app.exception_handler(HTTPException)
# async def http_exception_handler(exc: HTTPException) -> dict:
# """
# Function for exception handling. for old gpt
# :param exc: the relevant exception raised
# :return: dictionary, key , value a pair of status code and error detail.
# """
#
# log.debug("Calling http_exception_handler")
# return {"detail": exc.detail, "status_code": exc.status_code}
@app.exception_handler(HTTPException)
async def http_exception_handler(exc: HTTPException) -> dict:
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
"""
Function for HTTP exception handling.
:param request: the request that caused the exception
:param exc: the relevant exception raised
:return: JSONResponse with error detail and status code.
"""
Function for exception handling.
:param exc: the relevant exception raised
:return: dictionary, key , value a pair of status code and error detail.
"""

log.debug("Calling http_exception_handler")
return {"detail": exc.detail, "status_code": exc.status_code}
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail}
)



@app.exception_handler(GPTException)
Expand Down
3 changes: 2 additions & 1 deletion models/query_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@


class QueryModel(BaseModel):
user_input: str = Field(min_length=1, max_length=1000)
user_input: str = Field(min_length=1, max_length=2000)
model: str = "gpt-4" # Default model
145 changes: 73 additions & 72 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,72 +1,73 @@
aiohttp
aiosignal
anyio
async-timeout
attrs
CacheControl
certifi
charset-normalizer
click
colorama
coverage
cyclonedx-python-lib
dataclasses-json
defusedxml
fastapi
filelock
flake8
frozenlist
greenlet
h11
html5lib
httpcore
httpx
idna
iniconfig
Jinja2
langchain
langchainplus-sdk
markdown-it-py
MarkupSafe
marshmallow
marshmallow-enum
mccabe
mdurl
msgpack
multidict
mypy-extensions
numexpr
numpy
openai
openapi-schema-pydantic
packageurl-python
packaging
pip-api
pip-requirements-parser
pip_audit
pluggy
py-serializable
pycodestyle
pydantic
pyflakes
Pygments
pyparsing
pytest
pytest-cov
PyYAML
requests
rich
six
sniffio
sortedcontainers
SQLAlchemy
starlette
tenacity
toml
tqdm
typing-inspect
typing_extensions
urllib3
uvicorn
webencodings
yarl
aiohttp==3.8.4
aiosignal==1.3.1
anyio==3.6.2
async-timeout==4.0.2
attrs==23.1.0
CacheControl==0.13.1
certifi==2022.12.7
charset-normalizer==3.1.0
click==8.1.3
colorama==0.4.6
coverage==7.2.7
cyclonedx-python-lib==4.0.1
dataclasses-json==0.5.9
defusedxml==0.7.1
distro==1.8.0
fastapi==0.95.1
filelock==3.12.2
flake8==6.0.0
frozenlist==1.3.3
greenlet==2.0.2
h11==0.14.0
html5lib==1.1
httpcore==0.17.3
httpx==0.24.1
idna==3.4
iniconfig==2.0.0
Jinja2==3.1.2
langchain==0.0.225
langchainplus-sdk==0.0.20
markdown-it-py==3.0.0
MarkupSafe==2.1.2
marshmallow==3.19.0
marshmallow-enum==1.5.1
mccabe==0.7.0
mdurl==0.1.2
msgpack==1.0.5
multidict==6.0.4
mypy-extensions==1.0.0
numexpr==2.8.4
numpy==1.25.0
openai==1.3.7
openapi-schema-pydantic==1.2.4
packageurl-python==0.11.1
packaging==23.1
pip-api==0.0.30
pip-requirements-parser==32.0.1
pip_audit==2.6.0
pluggy==1.2.0
py-serializable==0.11.1
pycodestyle==2.10.0
pydantic==1.10.7
pyflakes==3.0.1
Pygments==2.15.1
pyparsing==3.1.0
pytest==7.4.0
pytest-cov==4.1.0
PyYAML==6.0
requests==2.31.0
rich==13.4.2
six==1.16.0
sniffio==1.3.0
sortedcontainers==2.4.0
SQLAlchemy==2.0.18
starlette==0.26.1
tenacity==8.2.2
toml==0.10.2
tqdm==4.65.0
typing-inspect==0.9.0
typing_extensions==4.5.0
urllib3==1.26.15
uvicorn==0.21.1
webencodings==0.5.1
yarl==1.8.2

0 comments on commit 9099897

Please sign in to comment.