OpenAI API simulator on localhost
Table of Contents
- Preface
- Prerequisites
- Description
- Create Assistant with GPT-3.5-turbo
- FastAPI Application for Simulating OpenAI Responses
- Updated FastAPI Application to Return Request Data
- Updated Unit Test to Verify Request Data Response
- The Third Attempt
- FastAPI Application for Simulating OpenAI Responses
- Unit Test for Testing create_assistant API Endpoint
Preface
OpenAI
opens new horizons in software development. It is now possible
to write programs in a declarative style by simply describing the
desired outcome. This approach allows developers to focus on what they
want to achieve, rather than detailing the step-by-step instructions
to get there. As a result, the development process becomes more
intuitive and efficient, fostering innovation and reducing the
complexity of coding.
Prerequisites
Key
export OPENAI_API_MOCK_KEY='sk-the-mock-key-for-openai-simulation-on-localhost' echo $OPENAI_API_MOCK_KEY
sk-the-mock-key-for-openai-simulation-on-localhost
Venv
pip list
Package Version ----------------- -------- annotated-types 0.7.0 anyio 4.4.0 certifi 2024.7.4 click 8.1.7 dnspython 2.6.1 email_validator 2.2.0 fastapi 0.111.1 fastapi-cli 0.0.4 greenlet 3.0.3 h11 0.14.0 httpcore 1.0.5 httptools 0.6.1 httpx 0.27.0 idna 3.7 iniconfig 2.0.0 Jinja2 3.1.4 markdown-it-py 3.0.0 MarkupSafe 2.1.5 mdurl 0.1.2 packaging 24.1 pip 23.0.1 pluggy 1.5.0 pydantic 2.8.2 pydantic_core 2.20.1 pydantic-settings 2.3.4 Pygments 2.18.0 pytest 8.3.2 python-dotenv 1.0.1 python-multipart 0.0.9 PyYAML 6.0.1 rich 13.7.1 setuptools 66.1.1 shellingham 1.5.4 sniffio 1.3.1 SQLAlchemy 2.0.31 starlette 0.37.2 typer 0.12.3 typing_extensions 4.12.2 uvicorn 0.30.1 uvloop 0.19.0 watchfiles 0.22.0 websockets 12.0 wheel 0.38.4
Description
I want to build a FastAPI application for simulating responces from OpenAI server.
Create Assistant with GPT-3.5-turbo
I want to build a FastAPI application for simulating responses from
OpenAI server. For very beginning write the function
create_assistant
which on request:
```
curl "https://api.openai.com/v1/assistants" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_MOCK_KEY" \
-H "OpenAI-Beta: assistants=v2" \
-d '{
"instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.",
"name": "Math Tutor",
"tools": [{"type": "code_interpreter"}],
"model": "gpt-4-turbo"
}'
```
returns the mock
response:
```
{
"id": "asst_abc123",
"object": "assistant",
"created_at": 1698984975,
"name": "Math Tutor",
"description": null,
"model": "gpt-4-turbo",
"instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.",
"tools": [
{
"type": "code_interpreter"
}
],
"metadata": {},
"top_p": 1.0,
"temperature": 1.0,
"response_format": "auto"
}
```
In addition write the unittest
for testing create_assistant
with
```unittest.main(exit=False)``` at the bottom.
To create a FastAPI application that simulates responses from the OpenAI server, we can start by implementing a function called `create_assistant` that mimics the behavior of creating an assistant on the OpenAI server. This function will simulate the response data as if an assistant has been created successfully.
### FastAPI Application for Simulating Responses from OpenAI Server
FastAPI Application for Simulating OpenAI Responses
import unittest from fastapi import FastAPI from fastapi.testclient import TestClient app = FastAPI() def create_assistant(): return { "id": "asst_abc123", "object": "assistant", "created_at": 1698984975, "name": "Math Tutor", "description": None, "model": "gpt-4-turbo", "instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.", "tools": [{"type": "code_interpreter"}], "metadata": {}, "top_p": 1.0, "temperature": 1.0, "response_format": "auto" } @app.get("/create_assistant") def get_create_assistant(): return create_assistant() client = TestClient(app) class TestCreateAssistant(unittest.TestCase): def test_create_assistant(self): response = client.get("/create_assistant") expected_response = { "id": "asst_abc123", "object": "assistant", "created_at": 1698984975, "name": "Math Tutor", "description": None, "model": "gpt-4-turbo", "instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.", "tools": [{"type": "code_interpreter"}], "metadata": {}, "top_p": 1.0, "temperature": 1.0, "response_format": "auto" } self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), expected_response) unittest.main(exit=False)
. ---------------------------------------------------------------------- Ran 1 test in 0.018s OK
Question rectification
This code snippet
import unittest from fastapi import FastAPI from fastapi.testclient import TestClient app = FastAPI() def create_assistant(): return { "id": "asst_abc123", "object": "assistant", "created_at": 1698984975, "name": "Math Tutor", "description": None, "model": "gpt-4-turbo", "instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.", "tools": [{"type": "code_interpreter"}], "metadata": {}, "top_p": 1.0, "temperature": 1.0, "response_format": "auto" } @app.get("/create_assistant") def get_create_assistant(): return create_assistant() client = TestClient(app) class TestCreateAssistant(unittest.TestCase): def test_create_assistant(self): response = client.get("/create_assistant") expected_response = { "id": "asst_abc123", "object": "assistant", "created_at": 1698984975, "name": "Math Tutor", "description": None, "model": "gpt-4-turbo", "instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.", "tools": [{"type": "code_interpreter"}], "metadata": {}, "top_p": 1.0, "temperature": 1.0, "response_format": "auto" } self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), expected_response) unittest.main(exit=False)
works fine, thank you. FastAPI app just returns the mock data
explicitly defined in its code. Can you rewrite this code snippet and
change it to return the data from the incoming request
? Rewrite
TestCreateAssistant
suite as well.
#+begin_src markdown To modify the FastAPI application to return the data from the incoming request rather than a predefined mock response, along with updating the corresponding unit test to reflect the change, you can adjust the endpoint to receive data from the request and return it back. Here is how you can achieve this:
### Updated FastAPI Application to Return Request Data
```org
Updated FastAPI Application to Return Request Data
import unittest from fastapi import FastAPI, Request, HTTPException from fastapi.testclient import TestClient app = FastAPI() @app.get("/create_assistant") def get_create_assistant(request: Request): data = request.query_params # Extract query parameters from the request if not data: raise HTTPException(status_code=400, detail="No data provided") return data
```
### Explanation of the Updated Application
- Request Parameter:
- The endpoint `/create_assistant` now takes a `Request` parameter to access the incoming request data.
- It extracts the query parameters from the request and returns them in the response.
- If no data is provided, it raises a `HTTPException` with a status code 400 (Bad Request).
### Updated Unit Test to Verify Request Data Response
```org
Updated Unit Test to Verify Request Data Response
import unittest from fastapi.testclient import TestClient from main import app client = TestClient(app) class TestCreateAssistant(unittest.TestCase): def test_create_assistant_with_data(self): response = client.get("/create_assistant?name=MathTutor&model=gpt-4-turbo") expected_response = {"name": "MathTutor", "model": "gpt-4-turbo"} self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), expected_response) def test_create_assistant_without_data(self): response = client.get("/create_assistant") self.assertEqual(response.status_code, 400) unittest.main(exit=False)
```
### Explanation of the Updated Test Suite
- Test with Data:
- `test_create_assistant_with_data`: Verifies that the endpoint returns the query parameters in the request.
- The test provides query parameters in the request URL and checks if the response matches the expected data.
- Test without Data:
- `test_create_assistant_without_data`: Verifies that the endpoint returns a 400 status code when no data is provided.
### Running the Updated Application and Tests
You can execute the updated code blocks in your Python environment to run the FastAPI application that now returns the request data. The unit tests validate that the endpoint functions correctly by returning the query parameters in the response and handling scenarios where no data is provided. #+end_src
The Third Attempt
I want to build a FastAPI application for simulating responses from
OpenAI server. For very beginning write the function
create_assistant
which on request:
``` curl "https://api.openai.com/v1/assistants" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_MOCK_KEY" \ -H "OpenAI-Beta: assistants=v2" \ -d '{ "instructions": "You are a personal math tutor.", "name": "Math Tutor", "description": "The description of the assistant", "tools": [{"type": "code_interpreter"}], "model": "gpt-4-turbo", "temperature": 0.8, "top_p": 1.0 }' ``` returns the response:
``` { "id": "asst_abc123", "object": "assistant", "created_at": 1698984975, "name": "Math Tutor", "description": "The description of the assistant.", "model": "gpt-4-turbo", "instructions": "You are a personal math tutor.", "tools": [ { "type": "code_interpreter" } ], "metadata": {}, "top_p": 1.0, "temperature": 0.8, "response_format": "auto" } ```
Where id
, object
, created_at
, metadata
, response_format
are
mock values, but name
, description
, model
, instructions
,
tools
, top_p
, temperature
are values from request data
.
In addition write the unittest
for testing create_assistant
API endpoint with
```unittest.main(exit=False)```
at the bottom.
#+begin_src markdown To build a FastAPI application that simulates responses from the OpenAI server based on the incoming request data, you can create an endpoint `create_assistant` that parses the request body, generates a response, and returns it. Additionally, you can write unit tests to verify the functionality of this endpoint. Below is an example setup to achieve this:
### FastAPI Application for Simulating OpenAI responses
```org
FastAPI Application for Simulating OpenAI Responses
import pydantic from fastapi import FastAPI, HTTPException from fastapi.testclient import TestClient from pydantic import BaseModel app = FastAPI() class AssistantDetails(BaseModel): instructions: str name: str description: str tools: list model: str temperature: float top_p: float def create_assistant(data: AssistantDetails): mock_response = { "id": "asst_abc123", "object": "assistant", "created_at": 1698984975, "name": data.name, "description": data.description, "model": data.model, "instructions": data.instructions, "tools": data.tools, "metadata": {}, "top_p": data.top_p, "temperature": data.temperature, "response_format": "auto" } return mock_response @app.post("/create_assistant") def create_new_assistant(data: AssistantDetails): return create_assistant(data) client = TestClient(app) class TestCreateAssistant(unittest.TestCase): def test_create_assistant(self): request_data = { "instructions": "You are a personal math tutor.", "name": "Math Tutor", "description": "The description of the assistant.", "tools": [{"type": "code_interpreter"}], "model": "gpt-4-turbo", "temperature": 0.8, "top_p": 1.0 } response = client.post("/create_assistant", json=request_data) expected_response = { "object": "assistant", "name": "Math Tutor", "description": "The description of the assistant.", "model": "gpt-4-turbo", "instructions": "You are a personal math tutor.", "tools": [ {"type": "code_interpreter"} ], "top_p": 1.0, "temperature": 0.8 } self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), expected_response) unittest.main(exit=False)
F ====================================================================== FAIL: test_create_assistant (__main__.TestCreateAssistant.test_create_assistant) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/babel-C8lSuP/python-hZpYKx", line 69, in test_create_assistant self.assertDictEqual(response.json(), expected_response) AssertionError: {'id': 'asst_abc123', 'object': 'assistant'[288 chars]uto'} != {'object': 'assistant', 'name': 'Math Tutor[198 chars] 0.8} - {'created_at': 1698984975, - 'description': 'The description of the assistant.', ? ^ + {'description': 'The description of the assistant.', ? ^ - 'id': 'asst_abc123', 'instructions': 'You are a personal math tutor.', - 'metadata': {}, 'model': 'gpt-4-turbo', 'name': 'Math Tutor', 'object': 'assistant', - 'response_format': 'auto', 'temperature': 0.8, 'tools': [{'type': 'code_interpreter'}], 'top_p': 1.0} ---------------------------------------------------------------------- Ran 1 test in 0.005s FAILED (failures=1)
```
### Explanation of the FastAPI Application
- AssistantDetails Model:
- Defines a Pydantic `BaseModel` to represent the structure of the data expected in the POST request body.
- create_assistant Function:
- Takes the incoming data, creates a mock response using the provided data, and returns it.
- POST Endpoint:
- The `/create_assistant` endpoint receives POST requests with data of type `AssistantDetails` and returns the mock response based on the received data.
### Unit Test for the create_assistant API Endpoint
```org
Unit Test for Testing create_assistant API Endpoint
import unittest from fastapi.testclient import TestClient from main import app from models import AssistantDetails client = TestClient(app) class TestCreateAssistant(unittest.TestCase): def test_create_assistant(self): request_data = { "instructions": "You are a personal math tutor.", "name": "Math Tutor", "description": "The description of the assistant.", "tools": [{"type": "code_interpreter"}], "model": "gpt-4-turbo", "temperature": 0.8, "top_p": 1.0 } response = client.post("/create_assistant", json=request_data) expected_response = { "name": "Math Tutor", "description": "The description of the assistant.", "model": "gpt-4-turbo", "instructions": "You are a personal math tutor.", "tools": [ {"type": "code_interpreter"} ], "top_p": 1.0, "temperature": 0.8 } self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), expected_response) unittest.main(exit=False)
```
### Explanation of the Unit Test
- test_create_assistant: Sends a POST request to the `/create_assistant` endpoint with sample request data, verifies the response against the expected response, and tests the functionality of the API endpoint.
### Running the Application and Unit Tests
You can execute the above code blocks in your Python environment to run the FastAPI application that simulates responses from the OpenAI server based on the incoming request data. The provided unit test validates that the `create_assistant` endpoint functions correctly and generates responses accurately in accordance with the request data. #+end_src