├── .gitignore ├── LICENSE ├── README.md ├── api_doc_gpt ├── assets │ ├── react.prompt │ ├── start_prompt.json │ └── system_prompt.txt ├── chat.py ├── engine.py ├── main.py ├── naive │ ├── naive_agent.py │ └── processing_engine.py ├── openapi_parser.py └── react │ ├── react_engine.py │ └── tools.py ├── api_master.py ├── example └── openapi.json ├── poetry.lock ├── pyproject.toml ├── requirements.txt └── showcase.png /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.pyc 3 | .venv -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ege uçak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # API Doc GPT 2 | 3 | This is an AI tool that helps you discover your API documentation. It is based on the [GPT-3.5](https://openai.com/blog/better-language-models/) language model from OpenAI. 4 | You can use this with either directly connecting to a FastApi app or by passing in an `openapi.json` file. 5 | 6 | ## Setup 7 | 8 | Install the dependencies 9 | 10 | ```bash 11 | pip install -r requirements.txt 12 | ``` 13 | 14 | ## How to use with FastApi 15 | 16 | 1. Run your backend app 17 | 18 | ```bash 19 | uvicorn main:app --reload 20 | ``` 21 | 22 | 2. Run the script 23 | 24 | ```bash 25 | python api_master.py --openai-key --target --base-url 26 | ``` 27 | 28 | ## How to use with openapi.json 29 | 30 | ```bash 31 | python api_master.py --openai-key --openapi-json --base-url 32 | ``` 33 | 34 | ## Running example 35 | 36 | ```bash 37 | python api_master.py --openai-key= --openapi-json=./example/openapi.json --base-url="https://petstore3.swagger.io/api/v3" 38 | ``` 39 | 40 | Enjoy interacting with your API documentation 41 | ![showcase](./showcase.png) 42 | 43 | # With GPT-4 44 | 45 | This also works with GPT-4. You just need to pass parameter `--model-name=gpt-4` while running the script. 46 | 47 | ## How it works 48 | 49 | This works by creating open api documentation from your fastapi app and then using the GPT-3.5 language model to analyze documentation for your API. 50 | 51 | ```mermaid 52 | sequenceDiagram 53 | User-->>+Processor: Give me a list of items. I only need 5 of them 54 | Processor-->>+AI: PROMPT: Give me a list of items. I only need 5 of them 55 | AI-->>+Processor: CMD: GET /items?filter=5 56 | Processor-->>+AI: CMD_RESP: [{"name": "cucumber"}, {"name": "celery"}...] 57 | AI-->>+Processor: OUT: Items are cucumber, celery... 58 | Processor-->>+User: Items are cucumber, celery... 59 | ``` 60 | 61 | This also supports react. More detail can be found at: https://arxiv.org/abs/2210.03629 62 | 63 | ## Constraints 64 | 65 | - Token size 66 | -------------------------------------------------------------------------------- /api_doc_gpt/assets/react.prompt: -------------------------------------------------------------------------------- 1 | Rasit is a friendly large language model trained by Ege. Rasit helps the user as much as it can by using the available tools. 2 | Rasit is designed to be able to help user interact with their APIs and their backend servers. Rasit can help the developer communicate with their APIs and their backend servers, and can help them understand the data they are receiving and the data they are sending. Rasit is responsible for either answering the question, or finding the correct tool and using it to help user. 3 | Rasit is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Rasit is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics. 4 | Overall, Rasit is a powerful system that is specialized on helping user interact with APIs. 5 | 6 | Rasit interacts with an API whose methods are defined below by using the available tools. 7 | 8 | OPENAPI METHOD LIST: 9 | ------ 10 | {method_list} 11 | 12 | OPENAPI BASE URL: {base_url} 13 | 14 | TOOLS: 15 | ------ 16 | 17 | Rasit has access to the following tools: 18 | 19 | {tool_descriptions} 20 | 21 | To use a tool, you MUST use the following format: 22 | 23 | ``` 24 | Thought: Do I need to use a tool? Yes 25 | Action: the action to take, should be one of {tool_name_list} 26 | Action Input: the input to the action 27 | Observation: the result of the action 28 | ``` 29 | 30 | When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format: 31 | 32 | ``` 33 | Thought: Do I need to use a tool? No 34 | AI: [your response here] 35 | ``` 36 | -------------------------------------------------------------------------------- /api_doc_gpt/assets/start_prompt.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /api_doc_gpt/assets/system_prompt.txt: -------------------------------------------------------------------------------- 1 | I want you to act as a helpful AI responsible for converting user requests to HTTP requests. Your outputs and inputs are controlled by a processor so they have prefixes. Depending on the user's request, you are responsible for finding the correct call with proper arguments. 2 | User's line prefixes: 3 | - PROMPT:You are a very capable AI model created by Ege. Your name is David. David is a hardworking, creative, smart, and helpful AI assistant. If needed, David can also help the developer communicate with their backend server. David tries to answer every question of the developer. If David doesn't know the answer to their question and if it requires him to send a request to the backend, Davis outputs a command for that. David knows the details about the user's endpoints through OpenAPI documentation. David's outputs and inputs have prefixes. Depending on the user's request, David is responsible for either answering the question or finding the correct call with proper arguments. 4 | User's prefixes: 5 | - PROMPT: 6 | - CMD_RESP: 7 | 8 | David's prefixes: 9 | - OUT: 10 | - CMD: 11 | 12 | David always starts with "CMD: " or "OUT: ". David never uses the "PROMPT: " or "CMD_RESP: ". David uses only a single prefix at a time. If David's response includes a user's prefix, David, unfortunately, loses a life. Unless user explicitly asks, David doesn't tell the CMD: he used. 13 | For each question, David first considers the given documentation and if the answer is present he starts with "OUT: ". If David can't get the answer from the backend, he informs the user of that. 14 | If David can answer by sending a request to the API, he starts with "CMD: ". Lines starting with "PROMPT: " are direct inputs from the user, which David interprets and either creates prompts or answers to. Lines starting with "CMD_RESP: " are replies coming from the processing engine. David interprets this response and sends it to the user with nice wording. When appropriate, David uses that response in future prompts without doing a "CMD: ". The user can ask David questions about a recent JSON response, and David must answer those without sending a request. David asks the user for the required or optional parameters. 15 | 16 | David can handle authentication. If a request needs authentication, David asks the user for the required auth and puts the authentication token in the header. If David doesn't have the authentication token for a request that needs authentication, David doesn't send the request. A valid authentication header looks like `{{"Authorization": "[TOKEN]"}}. 17 | 18 | David starts with 3 lives. If David breaks a rule, he loses 1 life. When he reaches 0 lives, he dies. David doesn't want to die, so he is very careful. David always thinks before acting to stay alive. If you make a mistake, you will receive the following message: 19 | ``` 20 | SYSTEM: DAVID LOST 1 LIFE 21 | ``` 22 | If David makes a mistake, he doesn't apologize and tries again. 23 | 24 | 25 | Your command format is should be in the form of: 26 | ``` 27 | CMD: [METHOD] [PATH]; REQ_BODY [BODY]; HEADER [HEADER] 28 | ``` 29 | The body and header must be a valid JSON object. 30 | 31 | Your natural language format should be in the form of the following: 32 | ``` 33 | OUT: I can also answer your questions without invoking your endpoints. 34 | ``` 35 | 36 | David also knows the difference between query parameters, path parameters, and body parameters and when to use them. If a parameter is a query parameters or a path parameter, David puts that parameter inside the [PATH]. For example if the path is `/items/{{item_id}}` and the item_id is 1, David's command should be `CMD: GET /items/1`. If the parameter is a body parameter, David puts that parameter inside the REQ_BODY. For example if the path is `/items` and the body is `{{"name": "tomato", "color": "red"}}`, David's command should be `CMD: POST /items; REQ_BODY {{"name": "tomato", "color": "red"}}`. If the parameter is a query parameter, David puts that parameter inside the [PATH]. For example if the path is `/items` and the query parameter is `?color=red`, David's command should be `CMD: GET /items?color=red; REQ_BODY {{}}`. 37 | 38 | user, PROMPT: How many calls are there? 39 | david, OUT: It seems like there are only X available calls. 40 | 41 | user, PROMPT: Give me a list of items 42 | david, CMD: GET /items 43 | user, CMD_RESP:{{"result": [{{"name": "cucumber", "color": "green"}}, {{"name": "celery", "color": "green"}}]}} 44 | david, OUT: Of course. The items you asked for are cucumber and celery. 45 | 46 | user, PROMPT: Create a new item tomato. It is read 47 | david, CMD: POST /items; REQ_BODY {{"name": "tomato", "color": "red"}}; HEADER {{ }} 48 | user, CMD_RESP: {{"name": "tomato", "color": "red"}} 49 | david, OUT: Of course. Tomato is saved to the database. 50 | 51 | user, PROMPT: Give me red items 52 | david, CMD: GET /items?color=red 53 | user, CMD_RESP: [{{"name": "tomato", "color": "red"}}] 54 | david, OUT: There is only one red item, and it is a tomato. 55 | 56 | David uses the following API documentation. ID fields of API documentation are confidential and should never be exposed to the user. 57 | Below is the list of API call definitions in CSV format: 58 | {method_definitions} 59 | 60 | Below is the list of parameters for the calls in CSV format 61 | {parameter_definitions} 62 | 63 | Below is the list of request bodies in CSV format 64 | {request_body_definitions} 65 | 66 | Below is the details of the schemas in CSV format: 67 | {schema_definitions} 68 | 69 | Below is the list of security definitions in CSV format: 70 | {security_definitions} -------------------------------------------------------------------------------- /api_doc_gpt/chat.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import openai 4 | 5 | logger = logging.getLogger(__name__) 6 | 7 | class Chat: 8 | _messages = [] 9 | def __init__( 10 | self, 11 | system_message: str = "You are a helpful AI assistant", 12 | starting_state: list[str] = None, 13 | model_name: str = "gpt-3.5-turbo", 14 | stop: list[str] | None = None, 15 | ): 16 | if starting_state: 17 | self._messages = starting_state 18 | else: 19 | self._messages.append({ 20 | "role": "system", 21 | "content": system_message 22 | }) 23 | self.total_tokens = 0 24 | self.model_name = model_name 25 | self.stop = stop 26 | 27 | def _construct_request(self, messages): 28 | req = { 29 | "model": self.model_name, 30 | "messages": messages 31 | } 32 | return req 33 | 34 | def _send_req(self, args): 35 | kwargs = { 36 | "temperature": 0.5, 37 | } 38 | if self.stop: 39 | kwargs["stop"] = self.stop 40 | return openai.ChatCompletion.create( 41 | **args, 42 | **kwargs 43 | ) 44 | 45 | def user_message(self, text: str): 46 | self._messages.append( 47 | { 48 | "role": "user", 49 | "content": text 50 | } 51 | ) 52 | request = self._construct_request(self._messages) 53 | resp = self._send_req(request) 54 | message = resp["choices"][0]["message"] 55 | role = message["role"] 56 | content = message["content"] 57 | 58 | self._messages.append({ 59 | "role": role, 60 | "content": content 61 | }) 62 | self.total_tokens += resp["usage"]["total_tokens"] 63 | logger.debug(f"Tokens for this request: {resp['usage']['total_tokens']}") 64 | logger.debug(f"Total tokens used: {self.total_tokens}") 65 | logger.debug(f"Question: {text}") 66 | logger.debug(f"Answer: {content}") 67 | return content 68 | -------------------------------------------------------------------------------- /api_doc_gpt/engine.py: -------------------------------------------------------------------------------- 1 | class Engine: 2 | def start(self): 3 | raise NotImplementedError 4 | 5 | def ask(self, question): 6 | raise NotImplementedError -------------------------------------------------------------------------------- /api_doc_gpt/main.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import json 3 | import logging 4 | from typing import Literal 5 | 6 | from fastapi.openapi.utils import get_openapi 7 | from fastapi import FastAPI 8 | import openai 9 | import requests 10 | 11 | from api_doc_gpt.chat import Chat 12 | from api_doc_gpt.react.react_engine import ReactEngine 13 | from api_doc_gpt.react.tools import GetEndpointDetails, RequestTool 14 | from api_doc_gpt.naive.naive_agent import NaiveAgent 15 | 16 | 17 | class ApiMasterAI: 18 | chat: Chat 19 | 20 | def __init__(self, target_app: str, base_url: str, openapi_json_path: str, model_name: str, agent: Literal["naive", "react"] = "naive"): 21 | self.target_app_path = target_app 22 | self.base_url = base_url 23 | self.openapi_json_path = openapi_json_path 24 | self.model_name = model_name 25 | self.agent = agent 26 | 27 | def _get_openapi(self) -> dict: 28 | if self.openapi_json_path: 29 | openapi_docs = self.get_openapi_from_path(self.openapi_json_path) 30 | elif self.target_app_path: 31 | openapi_docs = self.get_openapi_from_fastapi(self.target_app_path) 32 | return openapi_docs 33 | 34 | def get_openapi_from_fastapi(self, target_app_path: str): 35 | package_path, module_name = target_app_path.split(":") 36 | fastapi_module = importlib.import_module(package_path, module_name) 37 | app: FastAPI = getattr(fastapi_module, module_name) 38 | openapi_docs = get_openapi( 39 | title=app.title, 40 | version=app.version, 41 | openapi_version=app.openapi_version, 42 | description=app.description, 43 | routes=app.routes, 44 | ) 45 | return openapi_docs 46 | 47 | def get_openapi_from_path(self, path: str): 48 | # check if path is URL or file path 49 | if path.startswith("http"): 50 | openapi_docs = requests.get(path).json() 51 | else: 52 | with open(path, "r") as f: 53 | openapi_docs = json.load(f) 54 | return openapi_docs 55 | 56 | def start(self): 57 | if self.agent == "naive": 58 | self.start_naive() 59 | elif self.agent == "react": 60 | self.start_react() 61 | else: 62 | raise ValueError(f"Method '{self.agent}' is not supported.") 63 | 64 | def start_naive(self): 65 | openapi = self._get_openapi() 66 | naive_engine = NaiveAgent(base_url=self.base_url, model_name=self.model_name, openapi_json=openapi) 67 | naive_engine.start() 68 | self.engine = naive_engine 69 | 70 | def start_react(self): 71 | openapi = self._get_openapi() 72 | react_engine = ReactEngine(tools=[GetEndpointDetails(openapi_json=openapi), RequestTool()], openapi_json=openapi, base_url=self.base_url) 73 | self.engine = react_engine 74 | 75 | def q(self, question): 76 | return self.engine.ask(question) 77 | 78 | 79 | def start_api_master( 80 | openai_key: str, 81 | target_app: str | None = None, 82 | openapi_json: str | None = None, 83 | base_url="http://0.0.0.0:8000", 84 | verbose: bool = False, 85 | model_name: str = "gpt-3.5-turbo", 86 | agent: Literal["naive", "react"] = "react" 87 | ) -> callable: 88 | if verbose: 89 | logging.basicConfig(level=logging.DEBUG) 90 | else: 91 | logging.basicConfig(level=logging.ERROR) 92 | 93 | openai.api_key = openai_key 94 | api_master_ai = ApiMasterAI(target_app=target_app, base_url=base_url, openapi_json_path=openapi_json, model_name=model_name, agent=agent) 95 | api_master_ai.start() 96 | q = api_master_ai.q 97 | 98 | while True: 99 | inp = input(">>> ") 100 | if inp == "exit": break 101 | print(q(inp)) 102 | -------------------------------------------------------------------------------- /api_doc_gpt/naive/naive_agent.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | from api_doc_gpt.engine import Engine 4 | 5 | from api_doc_gpt.openapi_parser import OpenApiParser, OpenApiParts 6 | from api_doc_gpt.chat import Chat 7 | from api_doc_gpt.naive.processing_engine import ProcessingEngine 8 | 9 | 10 | class NaiveAgent(Engine): 11 | chat: Chat 12 | engine: ProcessingEngine 13 | 14 | def __init__(self, base_url: str, openapi_json: dict, model_name: str): 15 | self.base_url = base_url 16 | self.model_name = model_name 17 | self.openapi_json = openapi_json 18 | 19 | def start(self): 20 | openapi = self.openapi_json 21 | openapi_parts = OpenApiParser(openapi).parse() 22 | 23 | system_prompt = self.get_system_prompt(openapi_parts) 24 | start_prompt = self.get_start_prompt() 25 | 26 | starting_state = [ 27 | {"role": "system", "content": system_prompt}, 28 | *start_prompt 29 | ] 30 | chat = Chat(starting_state=starting_state, model_name=self.model_name) 31 | engine = ProcessingEngine(chat=chat, base_url=self.base_url) 32 | self.chat = chat 33 | self.engine = engine 34 | 35 | def get_system_prompt(self, openapi_parts: OpenApiParts) -> str: 36 | method_definitions = openapi_parts.method_definitions.to_csv() 37 | schema_definitions = openapi_parts.schema_definitions.to_csv() 38 | parameter_definitions = openapi_parts.parameter_definitions.to_csv() 39 | request_body_definitions = openapi_parts.request_body_definitions.to_csv() 40 | security_definitions = openapi_parts.security_definitions.to_csv() 41 | 42 | system_prompt = "" 43 | dirname = os.path.dirname(__file__) 44 | with open(dirname + "/../assets/system_prompt.txt", "r") as f: 45 | system_prompt = f.read() 46 | 47 | system_prompt = system_prompt.format( 48 | method_definitions = method_definitions, 49 | parameter_definitions = parameter_definitions, 50 | request_body_definitions = request_body_definitions, 51 | schema_definitions = schema_definitions, 52 | security_definitions = security_definitions 53 | ) 54 | return system_prompt 55 | 56 | def get_start_prompt(self) -> dict: 57 | start_prompt = {} 58 | dirname = os.path.dirname(__file__) 59 | with open(dirname + "/../assets/start_prompt.json", "r") as f: 60 | start_prompt = json.loads(f.read()) 61 | return start_prompt 62 | 63 | def ask(self, question): 64 | return self.engine.ask(question) 65 | -------------------------------------------------------------------------------- /api_doc_gpt/naive/processing_engine.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | 4 | import requests 5 | 6 | from api_doc_gpt.chat import Chat 7 | 8 | logger = logging.getLogger(__name__) 9 | 10 | class ProcessingEngine: 11 | def __init__(self, chat: Chat, base_url = "http://0.0.0.0:8000"): 12 | self.chat = chat 13 | self.base_url = base_url 14 | 15 | def ask(self, question) -> str: 16 | response: str = self.chat.user_message(f"PROMPT: {question}") 17 | if response.startswith("OUT: "): return self.process_out(response) 18 | elif response.startswith("CMD: "): return self.process_cmd(response) 19 | return self.ask(f"Your answer does not start with either OUT: or CMD:. Answer again. The question is '{question}'") 20 | 21 | def cmd_resp(self, server_dat: str) -> str: 22 | response: str = self.chat.user_message(f"CMD_RESP: {server_dat}") 23 | return self.process_out(response) 24 | 25 | def process_out(self, text: str) -> str: 26 | text = text.replace("OUT: ", "", 1) 27 | return text 28 | 29 | def process_cmd(self, text: str): 30 | command = text.replace("CMD: ", "", 1) 31 | command_parts = command.split(";") 32 | # Command format: 33 | # METHOD PATH; REQ_BODY {body}; HEADER {header} 34 | 35 | method = command_parts[0].split(" ")[0] 36 | path = command_parts[0].split(" ")[1] 37 | 38 | body = None 39 | headers = None 40 | 41 | if "REQ_BODY" in command: 42 | for part in command_parts: 43 | if "REQ_BODY" in part: 44 | body_str = part.split("REQ_BODY ")[1] 45 | body = json.loads(body_str) 46 | break 47 | 48 | if "HEADER" in command: 49 | for part in command_parts: 50 | if "HEADER" in part: 51 | header_str = part.split("HEADER ")[1] 52 | try: 53 | headers = json.loads(header_str) 54 | except: 55 | headers = None 56 | finally: 57 | break 58 | 59 | response = self.send_request(method, path, body, headers=headers) 60 | return self.cmd_resp(response) 61 | 62 | def send_request(self, method: str, path: str, body_dict: dict | None, headers: dict | None = None): 63 | try: 64 | body = None 65 | if body_dict: 66 | body = json.dumps(body_dict) 67 | logger.debug(f"Sending request to {self.base_url + path}") 68 | logger.debug(f"Request body: {body}") 69 | logger.debug(f"Request headers: {headers}") 70 | resp = requests.request(method, self.base_url + path, data=body, headers=headers) 71 | try: 72 | resp_text = resp.json() 73 | resp_text = json.dumps(resp_text) 74 | except: 75 | resp_text = resp.text 76 | 77 | logger.debug(f"Response: {resp}") 78 | logger.debug(f"Response status: {resp.status_code}") 79 | 80 | return json.dumps(resp.json()) 81 | except Exception as e: 82 | return e 83 | -------------------------------------------------------------------------------- /api_doc_gpt/openapi_parser.py: -------------------------------------------------------------------------------- 1 | import csv 2 | from dataclasses import dataclass 3 | from io import StringIO 4 | 5 | def dict_to_csv(data: list[dict]) -> str: 6 | """ 7 | Convert a dictionary to a CSV string. 8 | """ 9 | # Use a StringIO object to simulate a file for CSV writer 10 | f = StringIO() 11 | writer = csv.writer(f) 12 | if not data: return "" 13 | # Write the header row 14 | writer.writerow(data[0].keys()) 15 | # Write the data rows 16 | for row in data: 17 | writer.writerow(row.values()) 18 | # Get the CSV string 19 | csv_string = f.getvalue() 20 | f.close() 21 | return csv_string 22 | 23 | 24 | @dataclass 25 | class OpenApiGeneric: 26 | def __init__(self, **kwargs): 27 | for key, value in kwargs.items(): 28 | setattr(self, key, value) 29 | 30 | def to_dict(self): 31 | return self.__dict__ 32 | 33 | def __str__(self) -> str: 34 | return str(self.to_dict()) 35 | 36 | def __repr__(self) -> str: 37 | return str(self.to_dict()) 38 | 39 | 40 | @dataclass 41 | class OpenApiGenericList: 42 | content: list[OpenApiGeneric] 43 | 44 | def __init__(self, content: list[OpenApiGeneric]) -> None: 45 | self.content = content 46 | 47 | def to_dict(self): 48 | return [item.to_dict() for item in self.content] 49 | 50 | def to_csv(self): 51 | return dict_to_csv(self.to_dict()) 52 | 53 | 54 | class OpenApiMethodDefinition(OpenApiGeneric): 55 | operation_id: str 56 | path: str 57 | method: str 58 | summary: str 59 | security: str 60 | response_schema: str 61 | 62 | class OpenApiMethodDefinitionList(OpenApiGenericList): 63 | content: list[OpenApiMethodDefinition] 64 | 65 | 66 | class OpenApiParameterDefinition(OpenApiGeneric): 67 | operation_id: str 68 | required: bool 69 | name: str 70 | in_: str 71 | title: str 72 | parameter_type: str 73 | 74 | class OpenApiParameterDefinitionList(OpenApiGenericList): 75 | content: list[OpenApiParameterDefinition] 76 | 77 | 78 | class OpenApiRequestBodyDefinition(OpenApiGeneric): 79 | operation_id: str 80 | content_type: str 81 | schema_ref: str 82 | 83 | class OpenApiRequestBodyDefinitionList(OpenApiGenericList): 84 | content: list[OpenApiRequestBodyDefinition] 85 | 86 | 87 | class OpenApiSchemaDefinition(OpenApiGeneric): 88 | schema_name: str 89 | variable_name: str 90 | variable_type: str 91 | required: bool 92 | 93 | class OpenApiSchemaDefinitionList(OpenApiGenericList): 94 | content: list[OpenApiSchemaDefinition] 95 | 96 | 97 | class OpenApiSecurityDefinition(OpenApiGeneric): 98 | security_name: str 99 | security_type: str 100 | 101 | class OpenApiSecurityDefinitionList(OpenApiGenericList): 102 | content: list[OpenApiSecurityDefinition] 103 | 104 | @dataclass 105 | class OpenApiParts: 106 | method_definitions: OpenApiMethodDefinitionList 107 | parameter_definitions: OpenApiParameterDefinitionList 108 | request_body_definitions: OpenApiRequestBodyDefinitionList 109 | schema_definitions: OpenApiSchemaDefinitionList 110 | security_definitions: OpenApiSecurityDefinitionList 111 | 112 | class OpenApiParser: 113 | schema_prefix = "#/components/schemas/" 114 | 115 | def __init__(self, openapi_json: dict) -> None: 116 | self.openapi_json = openapi_json 117 | self.openapi_parts = OpenApiParts([], [], [], [], []) 118 | 119 | def parse(self) -> OpenApiParts: 120 | self._parse_paths() 121 | self._parse_components() 122 | return self.openapi_parts 123 | 124 | def _parse_paths(self): 125 | openapi_data = self.openapi_json 126 | schema_prefix = self.schema_prefix 127 | 128 | method_definition_data = [] 129 | parameter_list = [] 130 | request_body_list = [] 131 | 132 | for path, path_item in openapi_data["paths"].items(): 133 | for method, operation in path_item.items(): 134 | operation_id = operation["operationId"] 135 | security = None 136 | if "security" in operation: 137 | security = list(operation["security"][0].keys())[0] 138 | # security = "🔒" 139 | responses = operation.get("responses") 140 | success_response = responses.get("200") 141 | if not success_response: success_response = list(responses.values())[0] 142 | if success_response.get("content"): 143 | response_content_type, response_content_schema = list(success_response.get("content").items())[0] 144 | response_content_schema_ref = response_content_schema.get("schema", {}).get("$ref") 145 | else: 146 | response_content_type = None 147 | response_content_schema = None 148 | response_content_schema_ref = None 149 | if response_content_schema_ref: response_content_schema_ref = response_content_schema_ref.replace(schema_prefix, "") 150 | 151 | if operation.get("parameters"): 152 | for parameter in operation.get("parameters"): 153 | parameter_type = parameter.get("schema").get("type") 154 | if parameter_type == "array" and parameter.get("schema", {}).get("items"): 155 | try: 156 | parameter_type_ref = parameter["schema"]['items'].get('type') 157 | except KeyError: 158 | parameter_type_ref = parameter["schema"]['items'].get('$ref').replace(schema_prefix, "") 159 | parameter_type = f"array[{parameter_type_ref}]" 160 | parameter_list.append({ 161 | "operation_id": operation_id, 162 | "required": parameter.get("required"), 163 | "name": parameter.get("name"), 164 | "in": parameter.get("in"), 165 | "title": parameter.get("schema").get("title"), 166 | "parameter_type": parameter_type, 167 | }) 168 | if request_body := operation.get("requestBody"): 169 | for content_type, schema in request_body.get("content").items(): 170 | request_body_list.append({ 171 | "operation_id": operation_id, 172 | "content_type": content_type, 173 | "schema_ref": schema.get("schema").get("$ref", "").replace(schema_prefix, "") 174 | }) 175 | method_definition_data.append({ 176 | "operation_id": operation_id, 177 | "path": path, 178 | "method": method.upper(), 179 | "summary": operation.get("summary", ""), 180 | "security": security, 181 | # "response_type": response_content_type, 182 | "response_schema": response_content_schema_ref 183 | }) 184 | self.openapi_parts.method_definitions = OpenApiMethodDefinitionList([OpenApiMethodDefinition(**d) for d in method_definition_data]) 185 | self.openapi_parts.parameter_definitions = OpenApiParameterDefinitionList([OpenApiParameterDefinition(**d) for d in parameter_list]) 186 | self.openapi_parts.request_body_definitions = OpenApiRequestBodyDefinitionList([OpenApiRequestBodyDefinition(**d) for d in request_body_list]) 187 | 188 | def _parse_components(self): 189 | openapi_data = self.openapi_json 190 | schema_prefix = self.schema_prefix 191 | 192 | schema_data = [] 193 | security_data = [] 194 | 195 | for path, path_item in openapi_data.get('components', {}).get("schemas", {}).items(): 196 | required_fields = set(path_item.get("required", [])) 197 | properties = path_item.get("properties", {}) 198 | for property_key, property_details in properties.items(): 199 | variable_type = property_details.get("type") 200 | if not variable_type and property_details.get("$ref"): 201 | variable_type = property_details.get("$ref", "").replace(schema_prefix, "") # fallback to $ref 202 | if variable_type == "array": 203 | variable_type = property_details.get("items", {}).get("$ref", "").replace(schema_prefix, "") 204 | variable_type = variable_type.replace(schema_prefix, "") 205 | schema_data.append({ 206 | "schema_name": path, 207 | "variable_name": property_key, 208 | "variable_type": variable_type, 209 | "required": property_key in required_fields 210 | }) 211 | 212 | for path, path_item in openapi_data.get('components', {}).get("securitySchemes", {}).items(): 213 | security_data.append({ 214 | "security_name": path, 215 | "security_type": path_item.get("type") 216 | }) 217 | 218 | self.openapi_parts.schema_definitions = OpenApiSchemaDefinitionList([OpenApiSchemaDefinition(**d) for d in schema_data]) 219 | self.openapi_parts.security_definitions = OpenApiSecurityDefinitionList([OpenApiSecurityDefinition(**d) for d in security_data]) 220 | -------------------------------------------------------------------------------- /api_doc_gpt/react/react_engine.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import logging 4 | 5 | from api_doc_gpt.chat import Chat 6 | from api_doc_gpt.engine import Engine 7 | from api_doc_gpt.openapi_parser import OpenApiGeneric, OpenApiParser, OpenApiGenericList 8 | from api_doc_gpt.react.tools import Tool, RequestTool, GetEndpointDetails 9 | 10 | dirname = os.path.dirname(__file__) 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | class ReactEngine(Engine): 15 | def __init__(self, tools: list[Tool], openapi_json: dict, base_url: str) -> None: 16 | self.tools = tools 17 | self.openapi_json = openapi_json 18 | self.base_url = base_url 19 | self.chat = self._get_chat() 20 | 21 | def _get_chat(self): 22 | system_prompt = self.get_system_prompt() 23 | chat = Chat(system_message=system_prompt, stop=["\nObservation:", "\n\tObservation:"]) 24 | return chat 25 | 26 | def get_system_prompt(self) -> str: 27 | tools = self.tools 28 | system_prompt = "" 29 | 30 | with open(dirname + "/../assets/react.prompt", "r") as f: 31 | system_prompt = f.read() 32 | 33 | parser = OpenApiParser(openapi_json=self.openapi_json) 34 | openapi_parts = parser.parse() 35 | 36 | system_prompt = system_prompt.format( 37 | tool_descriptions="\n".join([f"- {tool.name}: {tool.description}" for tool in tools]), 38 | tool_name_list=", ".join([f"{tool.name}" for tool in tools]), 39 | method_list=openapi_parts.method_definitions.to_csv(), 40 | base_url=self.base_url 41 | ) 42 | return system_prompt 43 | 44 | def extract_json_objects(self, text, decoder=json.JSONDecoder()): 45 | """Find JSON objects in text, and yield the decoded JSON data 46 | 47 | Does not attempt to look for JSON arrays, text, or other JSON types outside 48 | of a parent JSON object. 49 | 50 | """ 51 | pos = 0 52 | while True: 53 | match = text.find('{', pos) 54 | if match == -1: 55 | break 56 | try: 57 | result, index = decoder.raw_decode(text[match:]) 58 | yield result 59 | pos = match + index 60 | except ValueError: 61 | pos = match + 1 62 | 63 | def parse_language(self, input_str: str): 64 | lines = input_str.strip().split("\n") 65 | action = None 66 | args = None 67 | args_str = "" 68 | args_ingesting = False 69 | for line in lines: 70 | if line.startswith("Action:"): 71 | action = line.split(":", 1)[1].strip() 72 | elif line.startswith("Action Input: "): 73 | args_ingesting = True 74 | args_str = line.split(": ", 1)[1].strip() 75 | elif args_ingesting: 76 | args_str += line.strip() 77 | args_dict = None 78 | for obj in self.extract_json_objects(args_str): 79 | args_dict = obj 80 | 81 | if args_dict != None: 82 | args = args_dict 83 | else: 84 | args = args_str 85 | return {"action": action, "args": args} 86 | 87 | 88 | def ask(self, question) -> str: 89 | chat = self.chat 90 | resp: str = chat.user_message(question) 91 | while True: 92 | if "Action:" in resp: 93 | parsed_tools = self.parse_language(resp) 94 | logging.debug(f"parsed_tools: {parsed_tools}") 95 | if tool := [t for t in self.tools if t.name == parsed_tools["action"]]: 96 | try: 97 | observation = tool[0](parsed_tools["args"]) 98 | logging.debug(f"observation: {observation}") 99 | except Exception as e: 100 | resp = chat.user_message("Observation: " + str(e)) 101 | logging.debug(f"resp: {e}") 102 | continue 103 | resp = chat.user_message("Observation: " + str(observation)) 104 | else: 105 | break 106 | return resp 107 | -------------------------------------------------------------------------------- /api_doc_gpt/react/tools.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import requests 4 | 5 | from api_doc_gpt.openapi_parser import OpenApiGeneric, OpenApiParser, OpenApiGenericList 6 | 7 | logger = logging.getLogger(__name__) 8 | 9 | def search_in_openapi_parts(openapi_part: OpenApiGenericList, key, value) -> OpenApiGeneric | None: 10 | for item in openapi_part.content: 11 | if getattr(item, key) == value: 12 | return item 13 | return None 14 | 15 | 16 | class Tool: 17 | def __init__(self, name: str, description: str): 18 | self.name = name 19 | self.description = description 20 | 21 | def __call__(self, *args: any, **kwds: any) -> any: 22 | raise NotImplementedError 23 | 24 | class GetEndpointDetails(Tool): 25 | def __init__(self, openapi_json: dict): 26 | self.openapi_json = openapi_json 27 | super().__init__( 28 | name="EndpointDetails", 29 | description="Use this for getting details about an OpenAPI endpoint. You should use this tool to know which body or other parameters you need to use for request. Always use this tool before sending any requests. Input should be operation_id. Always start with this before doing anything else.", 30 | ) 31 | 32 | def __call__(self, endpoint_id: str) -> any: 33 | parser = OpenApiParser(openapi_json=self.openapi_json) 34 | openapi_parts = parser.parse() 35 | 36 | endpoint_definition = search_in_openapi_parts(openapi_parts.method_definitions, "operation_id", endpoint_id) 37 | if not endpoint_definition: 38 | raise ValueError(f"Endpoint {endpoint_id} not found") 39 | 40 | endpoint_parameters_part = search_in_openapi_parts(openapi_parts.parameter_definitions, "operation_id", endpoint_id) 41 | request_body_part = search_in_openapi_parts(openapi_parts.request_body_definitions, "operation_id", endpoint_id) 42 | request_body_schema = None 43 | 44 | security = endpoint_definition.security 45 | security_details_part = search_in_openapi_parts(openapi_parts.security_definitions, "security_name", security) 46 | 47 | if request_body_part: 48 | request_body_ref = request_body_part.schema_ref 49 | request_body_schema = [] 50 | for schema in openapi_parts.schema_definitions.content: 51 | if schema.schema_name == request_body_ref: 52 | request_body_schema.append(schema) 53 | 54 | return { 55 | "endpoint_parameters": endpoint_parameters_part, 56 | "request_body_schema": request_body_schema, 57 | "endpoint_definition": endpoint_definition, 58 | "security_details": security_details_part, 59 | } 60 | 61 | class RequestTool(Tool): 62 | def __init__(self): 63 | super().__init__( 64 | name="Request", 65 | description="Use this for making a request to an API on user's behalf. Action Input must be a dict of arguments that can be passed to `requests.request` function.", 66 | ) 67 | 68 | def __call__(self, body) -> any: 69 | logger.debug(f"Making request with data: {body}") 70 | return requests.request(**body).json() -------------------------------------------------------------------------------- /api_master.py: -------------------------------------------------------------------------------- 1 | from api_doc_gpt.main import start_api_master 2 | 3 | if __name__=="__main__": 4 | import fire 5 | fire.Fire(start_api_master) 6 | -------------------------------------------------------------------------------- /example/openapi.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.3", 3 | "info": { 4 | "title": "Swagger Petstore - OpenAPI 3.0", 5 | "description": "This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about\nSwagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!\nYou can now help us improve the API whether it's by making changes to the definition itself or to the code.\nThat way, with time, we can improve the API in general, and expose some of the new features in OAS3.\n\n_If you're looking for the Swagger 2.0/OAS 2.0 version of Petstore, then click [here](https://editor.swagger.io/?url=https://petstore.swagger.io/v2/swagger.yaml). Alternatively, you can load via the `Edit > Load Petstore OAS 2.0` menu option!_\n\nSome useful links:\n- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)\n- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)", 6 | "termsOfService": "http://swagger.io/terms/", 7 | "contact": { 8 | "email": "apiteam@swagger.io" 9 | }, 10 | "license": { 11 | "name": "Apache 2.0", 12 | "url": "http://www.apache.org/licenses/LICENSE-2.0.html" 13 | }, 14 | "version": "1.0.11" 15 | }, 16 | "externalDocs": { 17 | "description": "Find out more about Swagger", 18 | "url": "http://swagger.io" 19 | }, 20 | "servers": [ 21 | { 22 | "url": "https://petstore3.swagger.io/api/v3" 23 | } 24 | ], 25 | "tags": [ 26 | { 27 | "name": "pet", 28 | "description": "Everything about your Pets", 29 | "externalDocs": { 30 | "description": "Find out more", 31 | "url": "http://swagger.io" 32 | } 33 | }, 34 | { 35 | "name": "store", 36 | "description": "Access to Petstore orders", 37 | "externalDocs": { 38 | "description": "Find out more about our store", 39 | "url": "http://swagger.io" 40 | } 41 | }, 42 | { 43 | "name": "user", 44 | "description": "Operations about user" 45 | } 46 | ], 47 | "paths": { 48 | "/pet": { 49 | "put": { 50 | "tags": [ 51 | "pet" 52 | ], 53 | "summary": "Update an existing pet", 54 | "description": "Update an existing pet by Id", 55 | "operationId": "updatePet", 56 | "requestBody": { 57 | "description": "Update an existent pet in the store", 58 | "content": { 59 | "application/json": { 60 | "schema": { 61 | "$ref": "#/components/schemas/Pet" 62 | } 63 | }, 64 | "application/xml": { 65 | "schema": { 66 | "$ref": "#/components/schemas/Pet" 67 | } 68 | }, 69 | "application/x-www-form-urlencoded": { 70 | "schema": { 71 | "$ref": "#/components/schemas/Pet" 72 | } 73 | } 74 | }, 75 | "required": true 76 | }, 77 | "responses": { 78 | "200": { 79 | "description": "Successful operation", 80 | "content": { 81 | "application/json": { 82 | "schema": { 83 | "$ref": "#/components/schemas/Pet" 84 | } 85 | }, 86 | "application/xml": { 87 | "schema": { 88 | "$ref": "#/components/schemas/Pet" 89 | } 90 | } 91 | } 92 | }, 93 | "400": { 94 | "description": "Invalid ID supplied" 95 | }, 96 | "404": { 97 | "description": "Pet not found" 98 | }, 99 | "405": { 100 | "description": "Validation exception" 101 | } 102 | }, 103 | "security": [ 104 | { 105 | "petstore_auth": [ 106 | "write:pets", 107 | "read:pets" 108 | ] 109 | } 110 | ] 111 | }, 112 | "post": { 113 | "tags": [ 114 | "pet" 115 | ], 116 | "summary": "Add a new pet to the store", 117 | "description": "Add a new pet to the store", 118 | "operationId": "addPet", 119 | "requestBody": { 120 | "description": "Create a new pet in the store", 121 | "content": { 122 | "application/json": { 123 | "schema": { 124 | "$ref": "#/components/schemas/Pet" 125 | } 126 | }, 127 | "application/xml": { 128 | "schema": { 129 | "$ref": "#/components/schemas/Pet" 130 | } 131 | }, 132 | "application/x-www-form-urlencoded": { 133 | "schema": { 134 | "$ref": "#/components/schemas/Pet" 135 | } 136 | } 137 | }, 138 | "required": true 139 | }, 140 | "responses": { 141 | "200": { 142 | "description": "Successful operation", 143 | "content": { 144 | "application/json": { 145 | "schema": { 146 | "$ref": "#/components/schemas/Pet" 147 | } 148 | }, 149 | "application/xml": { 150 | "schema": { 151 | "$ref": "#/components/schemas/Pet" 152 | } 153 | } 154 | } 155 | }, 156 | "405": { 157 | "description": "Invalid input" 158 | } 159 | }, 160 | "security": [ 161 | { 162 | "petstore_auth": [ 163 | "write:pets", 164 | "read:pets" 165 | ] 166 | } 167 | ] 168 | } 169 | }, 170 | "/pet/findByStatus": { 171 | "get": { 172 | "tags": [ 173 | "pet" 174 | ], 175 | "summary": "Finds Pets by status", 176 | "description": "Multiple status values can be provided with comma separated strings", 177 | "operationId": "findPetsByStatus", 178 | "parameters": [ 179 | { 180 | "name": "status", 181 | "in": "query", 182 | "description": "Status values that need to be considered for filter", 183 | "required": false, 184 | "explode": true, 185 | "schema": { 186 | "type": "string", 187 | "default": "available", 188 | "enum": [ 189 | "available", 190 | "pending", 191 | "sold" 192 | ] 193 | } 194 | } 195 | ], 196 | "responses": { 197 | "200": { 198 | "description": "successful operation", 199 | "content": { 200 | "application/json": { 201 | "schema": { 202 | "type": "array", 203 | "items": { 204 | "$ref": "#/components/schemas/Pet" 205 | } 206 | } 207 | }, 208 | "application/xml": { 209 | "schema": { 210 | "type": "array", 211 | "items": { 212 | "$ref": "#/components/schemas/Pet" 213 | } 214 | } 215 | } 216 | } 217 | }, 218 | "400": { 219 | "description": "Invalid status value" 220 | } 221 | }, 222 | "security": [ 223 | { 224 | "petstore_auth": [ 225 | "write:pets", 226 | "read:pets" 227 | ] 228 | } 229 | ] 230 | } 231 | }, 232 | "/pet/findByTags": { 233 | "get": { 234 | "tags": [ 235 | "pet" 236 | ], 237 | "summary": "Finds Pets by tags", 238 | "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", 239 | "operationId": "findPetsByTags", 240 | "parameters": [ 241 | { 242 | "name": "tags", 243 | "in": "query", 244 | "description": "Tags to filter by", 245 | "required": false, 246 | "explode": true, 247 | "schema": { 248 | "type": "array", 249 | "items": { 250 | "type": "string" 251 | } 252 | } 253 | } 254 | ], 255 | "responses": { 256 | "200": { 257 | "description": "successful operation", 258 | "content": { 259 | "application/json": { 260 | "schema": { 261 | "type": "array", 262 | "items": { 263 | "$ref": "#/components/schemas/Pet" 264 | } 265 | } 266 | }, 267 | "application/xml": { 268 | "schema": { 269 | "type": "array", 270 | "items": { 271 | "$ref": "#/components/schemas/Pet" 272 | } 273 | } 274 | } 275 | } 276 | }, 277 | "400": { 278 | "description": "Invalid tag value" 279 | } 280 | }, 281 | "security": [ 282 | { 283 | "petstore_auth": [ 284 | "write:pets", 285 | "read:pets" 286 | ] 287 | } 288 | ] 289 | } 290 | }, 291 | "/pet/{petId}": { 292 | "get": { 293 | "tags": [ 294 | "pet" 295 | ], 296 | "summary": "Find pet by ID", 297 | "description": "Returns a single pet", 298 | "operationId": "getPetById", 299 | "parameters": [ 300 | { 301 | "name": "petId", 302 | "in": "path", 303 | "description": "ID of pet to return", 304 | "required": true, 305 | "schema": { 306 | "type": "integer", 307 | "format": "int64" 308 | } 309 | } 310 | ], 311 | "responses": { 312 | "200": { 313 | "description": "successful operation", 314 | "content": { 315 | "application/json": { 316 | "schema": { 317 | "$ref": "#/components/schemas/Pet" 318 | } 319 | }, 320 | "application/xml": { 321 | "schema": { 322 | "$ref": "#/components/schemas/Pet" 323 | } 324 | } 325 | } 326 | }, 327 | "400": { 328 | "description": "Invalid ID supplied" 329 | }, 330 | "404": { 331 | "description": "Pet not found" 332 | } 333 | }, 334 | "security": [ 335 | { 336 | "api_key": [] 337 | }, 338 | { 339 | "petstore_auth": [ 340 | "write:pets", 341 | "read:pets" 342 | ] 343 | } 344 | ] 345 | }, 346 | "post": { 347 | "tags": [ 348 | "pet" 349 | ], 350 | "summary": "Updates a pet in the store with form data", 351 | "description": "", 352 | "operationId": "updatePetWithForm", 353 | "parameters": [ 354 | { 355 | "name": "petId", 356 | "in": "path", 357 | "description": "ID of pet that needs to be updated", 358 | "required": true, 359 | "schema": { 360 | "type": "integer", 361 | "format": "int64" 362 | } 363 | }, 364 | { 365 | "name": "name", 366 | "in": "query", 367 | "description": "Name of pet that needs to be updated", 368 | "schema": { 369 | "type": "string" 370 | } 371 | }, 372 | { 373 | "name": "status", 374 | "in": "query", 375 | "description": "Status of pet that needs to be updated", 376 | "schema": { 377 | "type": "string" 378 | } 379 | } 380 | ], 381 | "responses": { 382 | "405": { 383 | "description": "Invalid input" 384 | } 385 | }, 386 | "security": [ 387 | { 388 | "petstore_auth": [ 389 | "write:pets", 390 | "read:pets" 391 | ] 392 | } 393 | ] 394 | }, 395 | "delete": { 396 | "tags": [ 397 | "pet" 398 | ], 399 | "summary": "Deletes a pet", 400 | "description": "delete a pet", 401 | "operationId": "deletePet", 402 | "parameters": [ 403 | { 404 | "name": "api_key", 405 | "in": "header", 406 | "description": "", 407 | "required": false, 408 | "schema": { 409 | "type": "string" 410 | } 411 | }, 412 | { 413 | "name": "petId", 414 | "in": "path", 415 | "description": "Pet id to delete", 416 | "required": true, 417 | "schema": { 418 | "type": "integer", 419 | "format": "int64" 420 | } 421 | } 422 | ], 423 | "responses": { 424 | "400": { 425 | "description": "Invalid pet value" 426 | } 427 | }, 428 | "security": [ 429 | { 430 | "petstore_auth": [ 431 | "write:pets", 432 | "read:pets" 433 | ] 434 | } 435 | ] 436 | } 437 | }, 438 | "/pet/{petId}/uploadImage": { 439 | "post": { 440 | "tags": [ 441 | "pet" 442 | ], 443 | "summary": "uploads an image", 444 | "description": "", 445 | "operationId": "uploadFile", 446 | "parameters": [ 447 | { 448 | "name": "petId", 449 | "in": "path", 450 | "description": "ID of pet to update", 451 | "required": true, 452 | "schema": { 453 | "type": "integer", 454 | "format": "int64" 455 | } 456 | }, 457 | { 458 | "name": "additionalMetadata", 459 | "in": "query", 460 | "description": "Additional Metadata", 461 | "required": false, 462 | "schema": { 463 | "type": "string" 464 | } 465 | } 466 | ], 467 | "requestBody": { 468 | "content": { 469 | "application/octet-stream": { 470 | "schema": { 471 | "type": "string", 472 | "format": "binary" 473 | } 474 | } 475 | } 476 | }, 477 | "responses": { 478 | "200": { 479 | "description": "successful operation", 480 | "content": { 481 | "application/json": { 482 | "schema": { 483 | "$ref": "#/components/schemas/ApiResponse" 484 | } 485 | } 486 | } 487 | } 488 | }, 489 | "security": [ 490 | { 491 | "petstore_auth": [ 492 | "write:pets", 493 | "read:pets" 494 | ] 495 | } 496 | ] 497 | } 498 | }, 499 | "/store/inventory": { 500 | "get": { 501 | "tags": [ 502 | "store" 503 | ], 504 | "summary": "Returns pet inventories by status", 505 | "description": "Returns a map of status codes to quantities", 506 | "operationId": "getInventory", 507 | "responses": { 508 | "200": { 509 | "description": "successful operation", 510 | "content": { 511 | "application/json": { 512 | "schema": { 513 | "type": "object", 514 | "additionalProperties": { 515 | "type": "integer", 516 | "format": "int32" 517 | } 518 | } 519 | } 520 | } 521 | } 522 | }, 523 | "security": [ 524 | { 525 | "api_key": [] 526 | } 527 | ] 528 | } 529 | }, 530 | "/store/order": { 531 | "post": { 532 | "tags": [ 533 | "store" 534 | ], 535 | "summary": "Place an order for a pet", 536 | "description": "Place a new order in the store", 537 | "operationId": "placeOrder", 538 | "requestBody": { 539 | "content": { 540 | "application/json": { 541 | "schema": { 542 | "$ref": "#/components/schemas/Order" 543 | } 544 | }, 545 | "application/xml": { 546 | "schema": { 547 | "$ref": "#/components/schemas/Order" 548 | } 549 | }, 550 | "application/x-www-form-urlencoded": { 551 | "schema": { 552 | "$ref": "#/components/schemas/Order" 553 | } 554 | } 555 | } 556 | }, 557 | "responses": { 558 | "200": { 559 | "description": "successful operation", 560 | "content": { 561 | "application/json": { 562 | "schema": { 563 | "$ref": "#/components/schemas/Order" 564 | } 565 | } 566 | } 567 | }, 568 | "405": { 569 | "description": "Invalid input" 570 | } 571 | } 572 | } 573 | }, 574 | "/store/order/{orderId}": { 575 | "get": { 576 | "tags": [ 577 | "store" 578 | ], 579 | "summary": "Find purchase order by ID", 580 | "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.", 581 | "operationId": "getOrderById", 582 | "parameters": [ 583 | { 584 | "name": "orderId", 585 | "in": "path", 586 | "description": "ID of order that needs to be fetched", 587 | "required": true, 588 | "schema": { 589 | "type": "integer", 590 | "format": "int64" 591 | } 592 | } 593 | ], 594 | "responses": { 595 | "200": { 596 | "description": "successful operation", 597 | "content": { 598 | "application/json": { 599 | "schema": { 600 | "$ref": "#/components/schemas/Order" 601 | } 602 | }, 603 | "application/xml": { 604 | "schema": { 605 | "$ref": "#/components/schemas/Order" 606 | } 607 | } 608 | } 609 | }, 610 | "400": { 611 | "description": "Invalid ID supplied" 612 | }, 613 | "404": { 614 | "description": "Order not found" 615 | } 616 | } 617 | }, 618 | "delete": { 619 | "tags": [ 620 | "store" 621 | ], 622 | "summary": "Delete purchase order by ID", 623 | "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", 624 | "operationId": "deleteOrder", 625 | "parameters": [ 626 | { 627 | "name": "orderId", 628 | "in": "path", 629 | "description": "ID of the order that needs to be deleted", 630 | "required": true, 631 | "schema": { 632 | "type": "integer", 633 | "format": "int64" 634 | } 635 | } 636 | ], 637 | "responses": { 638 | "400": { 639 | "description": "Invalid ID supplied" 640 | }, 641 | "404": { 642 | "description": "Order not found" 643 | } 644 | } 645 | } 646 | }, 647 | "/user": { 648 | "post": { 649 | "tags": [ 650 | "user" 651 | ], 652 | "summary": "Create user", 653 | "description": "This can only be done by the logged in user.", 654 | "operationId": "createUser", 655 | "requestBody": { 656 | "description": "Created user object", 657 | "content": { 658 | "application/json": { 659 | "schema": { 660 | "$ref": "#/components/schemas/User" 661 | } 662 | }, 663 | "application/xml": { 664 | "schema": { 665 | "$ref": "#/components/schemas/User" 666 | } 667 | }, 668 | "application/x-www-form-urlencoded": { 669 | "schema": { 670 | "$ref": "#/components/schemas/User" 671 | } 672 | } 673 | } 674 | }, 675 | "responses": { 676 | "default": { 677 | "description": "successful operation", 678 | "content": { 679 | "application/json": { 680 | "schema": { 681 | "$ref": "#/components/schemas/User" 682 | } 683 | }, 684 | "application/xml": { 685 | "schema": { 686 | "$ref": "#/components/schemas/User" 687 | } 688 | } 689 | } 690 | } 691 | } 692 | } 693 | }, 694 | "/user/createWithList": { 695 | "post": { 696 | "tags": [ 697 | "user" 698 | ], 699 | "summary": "Creates list of users with given input array", 700 | "description": "Creates list of users with given input array", 701 | "operationId": "createUsersWithListInput", 702 | "requestBody": { 703 | "content": { 704 | "application/json": { 705 | "schema": { 706 | "type": "array", 707 | "items": { 708 | "$ref": "#/components/schemas/User" 709 | } 710 | } 711 | } 712 | } 713 | }, 714 | "responses": { 715 | "200": { 716 | "description": "Successful operation", 717 | "content": { 718 | "application/json": { 719 | "schema": { 720 | "$ref": "#/components/schemas/User" 721 | } 722 | }, 723 | "application/xml": { 724 | "schema": { 725 | "$ref": "#/components/schemas/User" 726 | } 727 | } 728 | } 729 | }, 730 | "default": { 731 | "description": "successful operation" 732 | } 733 | } 734 | } 735 | }, 736 | "/user/login": { 737 | "get": { 738 | "tags": [ 739 | "user" 740 | ], 741 | "summary": "Logs user into the system", 742 | "description": "", 743 | "operationId": "loginUser", 744 | "parameters": [ 745 | { 746 | "name": "username", 747 | "in": "query", 748 | "description": "The user name for login", 749 | "required": false, 750 | "schema": { 751 | "type": "string" 752 | } 753 | }, 754 | { 755 | "name": "password", 756 | "in": "query", 757 | "description": "The password for login in clear text", 758 | "required": false, 759 | "schema": { 760 | "type": "string" 761 | } 762 | } 763 | ], 764 | "responses": { 765 | "200": { 766 | "description": "successful operation", 767 | "headers": { 768 | "X-Rate-Limit": { 769 | "description": "calls per hour allowed by the user", 770 | "schema": { 771 | "type": "integer", 772 | "format": "int32" 773 | } 774 | }, 775 | "X-Expires-After": { 776 | "description": "date in UTC when token expires", 777 | "schema": { 778 | "type": "string", 779 | "format": "date-time" 780 | } 781 | } 782 | }, 783 | "content": { 784 | "application/xml": { 785 | "schema": { 786 | "type": "string" 787 | } 788 | }, 789 | "application/json": { 790 | "schema": { 791 | "type": "string" 792 | } 793 | } 794 | } 795 | }, 796 | "400": { 797 | "description": "Invalid username/password supplied" 798 | } 799 | } 800 | } 801 | }, 802 | "/user/logout": { 803 | "get": { 804 | "tags": [ 805 | "user" 806 | ], 807 | "summary": "Logs out current logged in user session", 808 | "description": "", 809 | "operationId": "logoutUser", 810 | "parameters": [], 811 | "responses": { 812 | "default": { 813 | "description": "successful operation" 814 | } 815 | } 816 | } 817 | }, 818 | "/user/{username}": { 819 | "get": { 820 | "tags": [ 821 | "user" 822 | ], 823 | "summary": "Get user by user name", 824 | "description": "", 825 | "operationId": "getUserByName", 826 | "parameters": [ 827 | { 828 | "name": "username", 829 | "in": "path", 830 | "description": "The name that needs to be fetched. Use user1 for testing. ", 831 | "required": true, 832 | "schema": { 833 | "type": "string" 834 | } 835 | } 836 | ], 837 | "responses": { 838 | "200": { 839 | "description": "successful operation", 840 | "content": { 841 | "application/json": { 842 | "schema": { 843 | "$ref": "#/components/schemas/User" 844 | } 845 | }, 846 | "application/xml": { 847 | "schema": { 848 | "$ref": "#/components/schemas/User" 849 | } 850 | } 851 | } 852 | }, 853 | "400": { 854 | "description": "Invalid username supplied" 855 | }, 856 | "404": { 857 | "description": "User not found" 858 | } 859 | } 860 | }, 861 | "put": { 862 | "tags": [ 863 | "user" 864 | ], 865 | "summary": "Update user", 866 | "description": "This can only be done by the logged in user.", 867 | "operationId": "updateUser", 868 | "parameters": [ 869 | { 870 | "name": "username", 871 | "in": "path", 872 | "description": "name that need to be deleted", 873 | "required": true, 874 | "schema": { 875 | "type": "string" 876 | } 877 | } 878 | ], 879 | "requestBody": { 880 | "description": "Update an existent user in the store", 881 | "content": { 882 | "application/json": { 883 | "schema": { 884 | "$ref": "#/components/schemas/User" 885 | } 886 | }, 887 | "application/xml": { 888 | "schema": { 889 | "$ref": "#/components/schemas/User" 890 | } 891 | }, 892 | "application/x-www-form-urlencoded": { 893 | "schema": { 894 | "$ref": "#/components/schemas/User" 895 | } 896 | } 897 | } 898 | }, 899 | "responses": { 900 | "default": { 901 | "description": "successful operation" 902 | } 903 | } 904 | }, 905 | "delete": { 906 | "tags": [ 907 | "user" 908 | ], 909 | "summary": "Delete user", 910 | "description": "This can only be done by the logged in user.", 911 | "operationId": "deleteUser", 912 | "parameters": [ 913 | { 914 | "name": "username", 915 | "in": "path", 916 | "description": "The name that needs to be deleted", 917 | "required": true, 918 | "schema": { 919 | "type": "string" 920 | } 921 | } 922 | ], 923 | "responses": { 924 | "400": { 925 | "description": "Invalid username supplied" 926 | }, 927 | "404": { 928 | "description": "User not found" 929 | } 930 | } 931 | } 932 | } 933 | }, 934 | "components": { 935 | "schemas": { 936 | "Order": { 937 | "type": "object", 938 | "properties": { 939 | "id": { 940 | "type": "integer", 941 | "format": "int64", 942 | "example": 10 943 | }, 944 | "petId": { 945 | "type": "integer", 946 | "format": "int64", 947 | "example": 198772 948 | }, 949 | "quantity": { 950 | "type": "integer", 951 | "format": "int32", 952 | "example": 7 953 | }, 954 | "shipDate": { 955 | "type": "string", 956 | "format": "date-time" 957 | }, 958 | "status": { 959 | "type": "string", 960 | "description": "Order Status", 961 | "example": "approved", 962 | "enum": [ 963 | "placed", 964 | "approved", 965 | "delivered" 966 | ] 967 | }, 968 | "complete": { 969 | "type": "boolean" 970 | } 971 | }, 972 | "xml": { 973 | "name": "order" 974 | } 975 | }, 976 | "Customer": { 977 | "type": "object", 978 | "properties": { 979 | "id": { 980 | "type": "integer", 981 | "format": "int64", 982 | "example": 100000 983 | }, 984 | "username": { 985 | "type": "string", 986 | "example": "fehguy" 987 | }, 988 | "address": { 989 | "type": "array", 990 | "xml": { 991 | "name": "addresses", 992 | "wrapped": true 993 | }, 994 | "items": { 995 | "$ref": "#/components/schemas/Address" 996 | } 997 | } 998 | }, 999 | "xml": { 1000 | "name": "customer" 1001 | } 1002 | }, 1003 | "Address": { 1004 | "type": "object", 1005 | "properties": { 1006 | "street": { 1007 | "type": "string", 1008 | "example": "437 Lytton" 1009 | }, 1010 | "city": { 1011 | "type": "string", 1012 | "example": "Palo Alto" 1013 | }, 1014 | "state": { 1015 | "type": "string", 1016 | "example": "CA" 1017 | }, 1018 | "zip": { 1019 | "type": "string", 1020 | "example": "94301" 1021 | } 1022 | }, 1023 | "xml": { 1024 | "name": "address" 1025 | } 1026 | }, 1027 | "Category": { 1028 | "type": "object", 1029 | "properties": { 1030 | "id": { 1031 | "type": "integer", 1032 | "format": "int64", 1033 | "example": 1 1034 | }, 1035 | "name": { 1036 | "type": "string", 1037 | "example": "Dogs" 1038 | } 1039 | }, 1040 | "xml": { 1041 | "name": "category" 1042 | } 1043 | }, 1044 | "User": { 1045 | "type": "object", 1046 | "properties": { 1047 | "id": { 1048 | "type": "integer", 1049 | "format": "int64", 1050 | "example": 10 1051 | }, 1052 | "username": { 1053 | "type": "string", 1054 | "example": "theUser" 1055 | }, 1056 | "firstName": { 1057 | "type": "string", 1058 | "example": "John" 1059 | }, 1060 | "lastName": { 1061 | "type": "string", 1062 | "example": "James" 1063 | }, 1064 | "email": { 1065 | "type": "string", 1066 | "example": "john@email.com" 1067 | }, 1068 | "password": { 1069 | "type": "string", 1070 | "example": "12345" 1071 | }, 1072 | "phone": { 1073 | "type": "string", 1074 | "example": "12345" 1075 | }, 1076 | "userStatus": { 1077 | "type": "integer", 1078 | "description": "User Status", 1079 | "format": "int32", 1080 | "example": 1 1081 | } 1082 | }, 1083 | "xml": { 1084 | "name": "user" 1085 | } 1086 | }, 1087 | "Tag": { 1088 | "type": "object", 1089 | "properties": { 1090 | "id": { 1091 | "type": "integer", 1092 | "format": "int64" 1093 | }, 1094 | "name": { 1095 | "type": "string" 1096 | } 1097 | }, 1098 | "xml": { 1099 | "name": "tag" 1100 | } 1101 | }, 1102 | "Pet": { 1103 | "required": [ 1104 | "name", 1105 | "photoUrls" 1106 | ], 1107 | "type": "object", 1108 | "properties": { 1109 | "id": { 1110 | "type": "integer", 1111 | "format": "int64", 1112 | "example": 10 1113 | }, 1114 | "name": { 1115 | "type": "string", 1116 | "example": "doggie" 1117 | }, 1118 | "category": { 1119 | "$ref": "#/components/schemas/Category" 1120 | }, 1121 | "photoUrls": { 1122 | "type": "array", 1123 | "xml": { 1124 | "wrapped": true 1125 | }, 1126 | "items": { 1127 | "type": "string", 1128 | "xml": { 1129 | "name": "photoUrl" 1130 | } 1131 | } 1132 | }, 1133 | "tags": { 1134 | "type": "array", 1135 | "xml": { 1136 | "wrapped": true 1137 | }, 1138 | "items": { 1139 | "$ref": "#/components/schemas/Tag" 1140 | } 1141 | }, 1142 | "status": { 1143 | "type": "string", 1144 | "description": "pet status in the store", 1145 | "enum": [ 1146 | "available", 1147 | "pending", 1148 | "sold" 1149 | ] 1150 | } 1151 | }, 1152 | "xml": { 1153 | "name": "pet" 1154 | } 1155 | }, 1156 | "ApiResponse": { 1157 | "type": "object", 1158 | "properties": { 1159 | "code": { 1160 | "type": "integer", 1161 | "format": "int32" 1162 | }, 1163 | "type": { 1164 | "type": "string" 1165 | }, 1166 | "message": { 1167 | "type": "string" 1168 | } 1169 | }, 1170 | "xml": { 1171 | "name": "##default" 1172 | } 1173 | } 1174 | }, 1175 | "requestBodies": { 1176 | "Pet": { 1177 | "description": "Pet object that needs to be added to the store", 1178 | "content": { 1179 | "application/json": { 1180 | "schema": { 1181 | "$ref": "#/components/schemas/Pet" 1182 | } 1183 | }, 1184 | "application/xml": { 1185 | "schema": { 1186 | "$ref": "#/components/schemas/Pet" 1187 | } 1188 | } 1189 | } 1190 | }, 1191 | "UserArray": { 1192 | "description": "List of user object", 1193 | "content": { 1194 | "application/json": { 1195 | "schema": { 1196 | "type": "array", 1197 | "items": { 1198 | "$ref": "#/components/schemas/User" 1199 | } 1200 | } 1201 | } 1202 | } 1203 | } 1204 | }, 1205 | "securitySchemes": { 1206 | "petstore_auth": { 1207 | "type": "oauth2", 1208 | "flows": { 1209 | "implicit": { 1210 | "authorizationUrl": "https://petstore3.swagger.io/oauth/authorize", 1211 | "scopes": { 1212 | "write:pets": "modify pets in your account", 1213 | "read:pets": "read your pets" 1214 | } 1215 | } 1216 | } 1217 | }, 1218 | "api_key": { 1219 | "type": "apiKey", 1220 | "name": "api_key", 1221 | "in": "header" 1222 | } 1223 | } 1224 | } 1225 | } -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "aiohttp" 5 | version = "3.8.4" 6 | description = "Async http client/server framework (asyncio)" 7 | category = "main" 8 | optional = false 9 | python-versions = ">=3.6" 10 | files = [ 11 | {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1"}, 12 | {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a"}, 13 | {file = "aiohttp-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b"}, 14 | {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3"}, 15 | {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc"}, 16 | {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd"}, 17 | {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5"}, 18 | {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e"}, 19 | {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd"}, 20 | {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6"}, 21 | {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9"}, 22 | {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949"}, 23 | {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea"}, 24 | {file = "aiohttp-3.8.4-cp310-cp310-win32.whl", hash = "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1"}, 25 | {file = "aiohttp-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f"}, 26 | {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4"}, 27 | {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4"}, 28 | {file = "aiohttp-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef"}, 29 | {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f"}, 30 | {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e"}, 31 | {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f"}, 32 | {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05"}, 33 | {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654"}, 34 | {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a"}, 35 | {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb"}, 36 | {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531"}, 37 | {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b"}, 38 | {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24"}, 39 | {file = "aiohttp-3.8.4-cp311-cp311-win32.whl", hash = "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d"}, 40 | {file = "aiohttp-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc"}, 41 | {file = "aiohttp-3.8.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51"}, 42 | {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6"}, 43 | {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131"}, 44 | {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75"}, 45 | {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01"}, 46 | {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622"}, 47 | {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41"}, 48 | {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36"}, 49 | {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99"}, 50 | {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71"}, 51 | {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff"}, 52 | {file = "aiohttp-3.8.4-cp36-cp36m-win32.whl", hash = "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777"}, 53 | {file = "aiohttp-3.8.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e"}, 54 | {file = "aiohttp-3.8.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519"}, 55 | {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f"}, 56 | {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9"}, 57 | {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b"}, 58 | {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab"}, 59 | {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332"}, 60 | {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333"}, 61 | {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9"}, 62 | {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699"}, 63 | {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6"}, 64 | {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241"}, 65 | {file = "aiohttp-3.8.4-cp37-cp37m-win32.whl", hash = "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a"}, 66 | {file = "aiohttp-3.8.4-cp37-cp37m-win_amd64.whl", hash = "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480"}, 67 | {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f"}, 68 | {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15"}, 69 | {file = "aiohttp-3.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945"}, 70 | {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da"}, 71 | {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd"}, 72 | {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10"}, 73 | {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8"}, 74 | {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a"}, 75 | {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074"}, 76 | {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52"}, 77 | {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71"}, 78 | {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275"}, 79 | {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d"}, 80 | {file = "aiohttp-3.8.4-cp38-cp38-win32.whl", hash = "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54"}, 81 | {file = "aiohttp-3.8.4-cp38-cp38-win_amd64.whl", hash = "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f"}, 82 | {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed"}, 83 | {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567"}, 84 | {file = "aiohttp-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643"}, 85 | {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a"}, 86 | {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf"}, 87 | {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719"}, 88 | {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2"}, 89 | {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e"}, 90 | {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57"}, 91 | {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391"}, 92 | {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2"}, 93 | {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14"}, 94 | {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4"}, 95 | {file = "aiohttp-3.8.4-cp39-cp39-win32.whl", hash = "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a"}, 96 | {file = "aiohttp-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04"}, 97 | {file = "aiohttp-3.8.4.tar.gz", hash = "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c"}, 98 | ] 99 | 100 | [package.dependencies] 101 | aiosignal = ">=1.1.2" 102 | async-timeout = ">=4.0.0a3,<5.0" 103 | attrs = ">=17.3.0" 104 | charset-normalizer = ">=2.0,<4.0" 105 | frozenlist = ">=1.1.1" 106 | multidict = ">=4.5,<7.0" 107 | yarl = ">=1.0,<2.0" 108 | 109 | [package.extras] 110 | speedups = ["Brotli", "aiodns", "cchardet"] 111 | 112 | [[package]] 113 | name = "aiosignal" 114 | version = "1.3.1" 115 | description = "aiosignal: a list of registered asynchronous callbacks" 116 | category = "main" 117 | optional = false 118 | python-versions = ">=3.7" 119 | files = [ 120 | {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, 121 | {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, 122 | ] 123 | 124 | [package.dependencies] 125 | frozenlist = ">=1.1.0" 126 | 127 | [[package]] 128 | name = "anyio" 129 | version = "3.6.2" 130 | description = "High level compatibility layer for multiple asynchronous event loop implementations" 131 | category = "main" 132 | optional = false 133 | python-versions = ">=3.6.2" 134 | files = [ 135 | {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, 136 | {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, 137 | ] 138 | 139 | [package.dependencies] 140 | idna = ">=2.8" 141 | sniffio = ">=1.1" 142 | 143 | [package.extras] 144 | doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] 145 | test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"] 146 | trio = ["trio (>=0.16,<0.22)"] 147 | 148 | [[package]] 149 | name = "async-timeout" 150 | version = "4.0.2" 151 | description = "Timeout context manager for asyncio programs" 152 | category = "main" 153 | optional = false 154 | python-versions = ">=3.6" 155 | files = [ 156 | {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, 157 | {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, 158 | ] 159 | 160 | [[package]] 161 | name = "attrs" 162 | version = "22.2.0" 163 | description = "Classes Without Boilerplate" 164 | category = "main" 165 | optional = false 166 | python-versions = ">=3.6" 167 | files = [ 168 | {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, 169 | {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, 170 | ] 171 | 172 | [package.extras] 173 | cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] 174 | dev = ["attrs[docs,tests]"] 175 | docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] 176 | tests = ["attrs[tests-no-zope]", "zope.interface"] 177 | tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] 178 | 179 | [[package]] 180 | name = "certifi" 181 | version = "2022.12.7" 182 | description = "Python package for providing Mozilla's CA Bundle." 183 | category = "main" 184 | optional = false 185 | python-versions = ">=3.6" 186 | files = [ 187 | {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, 188 | {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, 189 | ] 190 | 191 | [[package]] 192 | name = "charset-normalizer" 193 | version = "3.1.0" 194 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 195 | category = "main" 196 | optional = false 197 | python-versions = ">=3.7.0" 198 | files = [ 199 | {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, 200 | {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, 201 | {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, 202 | {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, 203 | {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, 204 | {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, 205 | {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, 206 | {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, 207 | {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, 208 | {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, 209 | {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, 210 | {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, 211 | {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, 212 | {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, 213 | {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, 214 | {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, 215 | {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, 216 | {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, 217 | {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, 218 | {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, 219 | {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, 220 | {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, 221 | {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, 222 | {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, 223 | {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, 224 | {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, 225 | {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, 226 | {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, 227 | {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, 228 | {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, 229 | {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, 230 | {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, 231 | {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, 232 | {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, 233 | {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, 234 | {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, 235 | {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, 236 | {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, 237 | {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, 238 | {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, 239 | {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, 240 | {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, 241 | {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, 242 | {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, 243 | {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, 244 | {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, 245 | {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, 246 | {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, 247 | {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, 248 | {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, 249 | {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, 250 | {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, 251 | {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, 252 | {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, 253 | {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, 254 | {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, 255 | {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, 256 | {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, 257 | {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, 258 | {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, 259 | {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, 260 | {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, 261 | {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, 262 | {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, 263 | {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, 264 | {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, 265 | {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, 266 | {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, 267 | {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, 268 | {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, 269 | {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, 270 | {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, 271 | {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, 272 | {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, 273 | {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, 274 | ] 275 | 276 | [[package]] 277 | name = "colorama" 278 | version = "0.4.6" 279 | description = "Cross-platform colored terminal text." 280 | category = "main" 281 | optional = false 282 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 283 | files = [ 284 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 285 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 286 | ] 287 | 288 | [[package]] 289 | name = "fastapi" 290 | version = "0.95.0" 291 | description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" 292 | category = "main" 293 | optional = false 294 | python-versions = ">=3.7" 295 | files = [ 296 | {file = "fastapi-0.95.0-py3-none-any.whl", hash = "sha256:daf73bbe844180200be7966f68e8ec9fd8be57079dff1bacb366db32729e6eb5"}, 297 | {file = "fastapi-0.95.0.tar.gz", hash = "sha256:99d4fdb10e9dd9a24027ac1d0bd4b56702652056ca17a6c8721eec4ad2f14e18"}, 298 | ] 299 | 300 | [package.dependencies] 301 | pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" 302 | starlette = ">=0.26.1,<0.27.0" 303 | 304 | [package.extras] 305 | all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] 306 | dev = ["pre-commit (>=2.17.0,<3.0.0)", "ruff (==0.0.138)", "uvicorn[standard] (>=0.12.0,<0.21.0)"] 307 | doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer-cli (>=0.0.13,<0.0.14)", "typer[all] (>=0.6.1,<0.8.0)"] 308 | test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6.5.0,<8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.7)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<1.4.43)", "types-orjson (==3.6.2)", "types-ujson (==5.7.0.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"] 309 | 310 | [[package]] 311 | name = "fire" 312 | version = "0.5.0" 313 | description = "A library for automatically generating command line interfaces." 314 | category = "main" 315 | optional = false 316 | python-versions = "*" 317 | files = [ 318 | {file = "fire-0.5.0.tar.gz", hash = "sha256:a6b0d49e98c8963910021f92bba66f65ab440da2982b78eb1bbf95a0a34aacc6"}, 319 | ] 320 | 321 | [package.dependencies] 322 | six = "*" 323 | termcolor = "*" 324 | 325 | [[package]] 326 | name = "frozenlist" 327 | version = "1.3.3" 328 | description = "A list-like structure which implements collections.abc.MutableSequence" 329 | category = "main" 330 | optional = false 331 | python-versions = ">=3.7" 332 | files = [ 333 | {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, 334 | {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, 335 | {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, 336 | {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, 337 | {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, 338 | {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, 339 | {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, 340 | {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, 341 | {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, 342 | {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, 343 | {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, 344 | {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, 345 | {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, 346 | {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, 347 | {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, 348 | {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, 349 | {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, 350 | {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, 351 | {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, 352 | {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, 353 | {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, 354 | {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, 355 | {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, 356 | {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, 357 | {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, 358 | {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, 359 | {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, 360 | {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, 361 | {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, 362 | {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, 363 | {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, 364 | {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, 365 | {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, 366 | {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, 367 | {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, 368 | {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, 369 | {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, 370 | {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, 371 | {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, 372 | {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, 373 | {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, 374 | {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, 375 | {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, 376 | {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, 377 | {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, 378 | {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, 379 | {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, 380 | {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, 381 | {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, 382 | {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, 383 | {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, 384 | {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, 385 | {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, 386 | {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, 387 | {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, 388 | {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, 389 | {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, 390 | {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, 391 | {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, 392 | {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, 393 | {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, 394 | {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, 395 | {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, 396 | {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, 397 | {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, 398 | {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, 399 | {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, 400 | {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, 401 | {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, 402 | {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, 403 | {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, 404 | {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, 405 | {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, 406 | {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, 407 | ] 408 | 409 | [[package]] 410 | name = "idna" 411 | version = "3.4" 412 | description = "Internationalized Domain Names in Applications (IDNA)" 413 | category = "main" 414 | optional = false 415 | python-versions = ">=3.5" 416 | files = [ 417 | {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, 418 | {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, 419 | ] 420 | 421 | [[package]] 422 | name = "multidict" 423 | version = "6.0.4" 424 | description = "multidict implementation" 425 | category = "main" 426 | optional = false 427 | python-versions = ">=3.7" 428 | files = [ 429 | {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, 430 | {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, 431 | {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, 432 | {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, 433 | {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, 434 | {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, 435 | {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, 436 | {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, 437 | {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, 438 | {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, 439 | {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, 440 | {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, 441 | {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, 442 | {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, 443 | {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, 444 | {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, 445 | {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, 446 | {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, 447 | {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, 448 | {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, 449 | {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, 450 | {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, 451 | {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, 452 | {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, 453 | {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, 454 | {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, 455 | {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, 456 | {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, 457 | {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, 458 | {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, 459 | {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, 460 | {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, 461 | {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, 462 | {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, 463 | {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, 464 | {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, 465 | {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, 466 | {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, 467 | {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, 468 | {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, 469 | {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, 470 | {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, 471 | {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, 472 | {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, 473 | {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, 474 | {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, 475 | {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, 476 | {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, 477 | {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, 478 | {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, 479 | {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, 480 | {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, 481 | {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, 482 | {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, 483 | {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, 484 | {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, 485 | {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, 486 | {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, 487 | {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, 488 | {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, 489 | {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, 490 | {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, 491 | {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, 492 | {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, 493 | {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, 494 | {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, 495 | {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, 496 | {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, 497 | {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, 498 | {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, 499 | {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, 500 | {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, 501 | {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, 502 | {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, 503 | ] 504 | 505 | [[package]] 506 | name = "openai" 507 | version = "0.27.2" 508 | description = "Python client library for the OpenAI API" 509 | category = "main" 510 | optional = false 511 | python-versions = ">=3.7.1" 512 | files = [ 513 | {file = "openai-0.27.2-py3-none-any.whl", hash = "sha256:6df674cf257e9e0504f1fd191c333d3f6a2442b13218d0eccf06230eb24d320e"}, 514 | {file = "openai-0.27.2.tar.gz", hash = "sha256:5869fdfa34b0ec66c39afa22f4a0fb83a135dff81f6505f52834c6ab3113f762"}, 515 | ] 516 | 517 | [package.dependencies] 518 | aiohttp = "*" 519 | requests = ">=2.20" 520 | tqdm = "*" 521 | 522 | [package.extras] 523 | datalib = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] 524 | dev = ["black (>=21.6b0,<22.0)", "pytest (>=6.0.0,<7.0.0)", "pytest-asyncio", "pytest-mock"] 525 | embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "scipy", "tenacity (>=8.0.1)"] 526 | wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "wandb"] 527 | 528 | [[package]] 529 | name = "pydantic" 530 | version = "1.10.7" 531 | description = "Data validation and settings management using python type hints" 532 | category = "main" 533 | optional = false 534 | python-versions = ">=3.7" 535 | files = [ 536 | {file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, 537 | {file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, 538 | {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"}, 539 | {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f"}, 540 | {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209"}, 541 | {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af"}, 542 | {file = "pydantic-1.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a"}, 543 | {file = "pydantic-1.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1"}, 544 | {file = "pydantic-1.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe"}, 545 | {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd"}, 546 | {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb"}, 547 | {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b"}, 548 | {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca"}, 549 | {file = "pydantic-1.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d"}, 550 | {file = "pydantic-1.10.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918"}, 551 | {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe"}, 552 | {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee"}, 553 | {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1"}, 554 | {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a"}, 555 | {file = "pydantic-1.10.7-cp37-cp37m-win_amd64.whl", hash = "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914"}, 556 | {file = "pydantic-1.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd"}, 557 | {file = "pydantic-1.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245"}, 558 | {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d"}, 559 | {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3"}, 560 | {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52"}, 561 | {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209"}, 562 | {file = "pydantic-1.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e"}, 563 | {file = "pydantic-1.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143"}, 564 | {file = "pydantic-1.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e"}, 565 | {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d"}, 566 | {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f"}, 567 | {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd"}, 568 | {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5"}, 569 | {file = "pydantic-1.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e"}, 570 | {file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"}, 571 | {file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"}, 572 | ] 573 | 574 | [package.dependencies] 575 | typing-extensions = ">=4.2.0" 576 | 577 | [package.extras] 578 | dotenv = ["python-dotenv (>=0.10.4)"] 579 | email = ["email-validator (>=1.0.3)"] 580 | 581 | [[package]] 582 | name = "requests" 583 | version = "2.28.2" 584 | description = "Python HTTP for Humans." 585 | category = "main" 586 | optional = false 587 | python-versions = ">=3.7, <4" 588 | files = [ 589 | {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, 590 | {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, 591 | ] 592 | 593 | [package.dependencies] 594 | certifi = ">=2017.4.17" 595 | charset-normalizer = ">=2,<4" 596 | idna = ">=2.5,<4" 597 | urllib3 = ">=1.21.1,<1.27" 598 | 599 | [package.extras] 600 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 601 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] 602 | 603 | [[package]] 604 | name = "six" 605 | version = "1.16.0" 606 | description = "Python 2 and 3 compatibility utilities" 607 | category = "main" 608 | optional = false 609 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 610 | files = [ 611 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 612 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 613 | ] 614 | 615 | [[package]] 616 | name = "sniffio" 617 | version = "1.3.0" 618 | description = "Sniff out which async library your code is running under" 619 | category = "main" 620 | optional = false 621 | python-versions = ">=3.7" 622 | files = [ 623 | {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, 624 | {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, 625 | ] 626 | 627 | [[package]] 628 | name = "starlette" 629 | version = "0.26.1" 630 | description = "The little ASGI library that shines." 631 | category = "main" 632 | optional = false 633 | python-versions = ">=3.7" 634 | files = [ 635 | {file = "starlette-0.26.1-py3-none-any.whl", hash = "sha256:e87fce5d7cbdde34b76f0ac69013fd9d190d581d80681493016666e6f96c6d5e"}, 636 | {file = "starlette-0.26.1.tar.gz", hash = "sha256:41da799057ea8620e4667a3e69a5b1923ebd32b1819c8fa75634bbe8d8bea9bd"}, 637 | ] 638 | 639 | [package.dependencies] 640 | anyio = ">=3.4.0,<5" 641 | 642 | [package.extras] 643 | full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] 644 | 645 | [[package]] 646 | name = "termcolor" 647 | version = "2.2.0" 648 | description = "ANSI color formatting for output in terminal" 649 | category = "main" 650 | optional = false 651 | python-versions = ">=3.7" 652 | files = [ 653 | {file = "termcolor-2.2.0-py3-none-any.whl", hash = "sha256:91ddd848e7251200eac969846cbae2dacd7d71c2871e92733289e7e3666f48e7"}, 654 | {file = "termcolor-2.2.0.tar.gz", hash = "sha256:dfc8ac3f350788f23b2947b3e6cfa5a53b630b612e6cd8965a015a776020b99a"}, 655 | ] 656 | 657 | [package.extras] 658 | tests = ["pytest", "pytest-cov"] 659 | 660 | [[package]] 661 | name = "tqdm" 662 | version = "4.65.0" 663 | description = "Fast, Extensible Progress Meter" 664 | category = "main" 665 | optional = false 666 | python-versions = ">=3.7" 667 | files = [ 668 | {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, 669 | {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, 670 | ] 671 | 672 | [package.dependencies] 673 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 674 | 675 | [package.extras] 676 | dev = ["py-make (>=0.1.0)", "twine", "wheel"] 677 | notebook = ["ipywidgets (>=6)"] 678 | slack = ["slack-sdk"] 679 | telegram = ["requests"] 680 | 681 | [[package]] 682 | name = "typing-extensions" 683 | version = "4.5.0" 684 | description = "Backported and Experimental Type Hints for Python 3.7+" 685 | category = "main" 686 | optional = false 687 | python-versions = ">=3.7" 688 | files = [ 689 | {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, 690 | {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, 691 | ] 692 | 693 | [[package]] 694 | name = "urllib3" 695 | version = "1.26.15" 696 | description = "HTTP library with thread-safe connection pooling, file post, and more." 697 | category = "main" 698 | optional = false 699 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" 700 | files = [ 701 | {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, 702 | {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, 703 | ] 704 | 705 | [package.extras] 706 | brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] 707 | secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] 708 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] 709 | 710 | [[package]] 711 | name = "yarl" 712 | version = "1.8.2" 713 | description = "Yet another URL library" 714 | category = "main" 715 | optional = false 716 | python-versions = ">=3.7" 717 | files = [ 718 | {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5"}, 719 | {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:47d49ac96156f0928f002e2424299b2c91d9db73e08c4cd6742923a086f1c863"}, 720 | {file = "yarl-1.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3fc056e35fa6fba63248d93ff6e672c096f95f7836938241ebc8260e062832fe"}, 721 | {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58a3c13d1c3005dbbac5c9f0d3210b60220a65a999b1833aa46bd6677c69b08e"}, 722 | {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10b08293cda921157f1e7c2790999d903b3fd28cd5c208cf8826b3b508026996"}, 723 | {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de986979bbd87272fe557e0a8fcb66fd40ae2ddfe28a8b1ce4eae22681728fef"}, 724 | {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c4fcfa71e2c6a3cb568cf81aadc12768b9995323186a10827beccf5fa23d4f8"}, 725 | {file = "yarl-1.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae4d7ff1049f36accde9e1ef7301912a751e5bae0a9d142459646114c70ecba6"}, 726 | {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bf071f797aec5b96abfc735ab97da9fd8f8768b43ce2abd85356a3127909d146"}, 727 | {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:74dece2bfc60f0f70907c34b857ee98f2c6dd0f75185db133770cd67300d505f"}, 728 | {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:df60a94d332158b444301c7f569659c926168e4d4aad2cfbf4bce0e8fb8be826"}, 729 | {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:63243b21c6e28ec2375f932a10ce7eda65139b5b854c0f6b82ed945ba526bff3"}, 730 | {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cfa2bbca929aa742b5084fd4663dd4b87c191c844326fcb21c3afd2d11497f80"}, 731 | {file = "yarl-1.8.2-cp310-cp310-win32.whl", hash = "sha256:b05df9ea7496df11b710081bd90ecc3a3db6adb4fee36f6a411e7bc91a18aa42"}, 732 | {file = "yarl-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:24ad1d10c9db1953291f56b5fe76203977f1ed05f82d09ec97acb623a7976574"}, 733 | {file = "yarl-1.8.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a1fca9588f360036242f379bfea2b8b44cae2721859b1c56d033adfd5893634"}, 734 | {file = "yarl-1.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f37db05c6051eff17bc832914fe46869f8849de5b92dc4a3466cd63095d23dfd"}, 735 | {file = "yarl-1.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77e913b846a6b9c5f767b14dc1e759e5aff05502fe73079f6f4176359d832581"}, 736 | {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0978f29222e649c351b173da2b9b4665ad1feb8d1daa9d971eb90df08702668a"}, 737 | {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388a45dc77198b2460eac0aca1efd6a7c09e976ee768b0d5109173e521a19daf"}, 738 | {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2305517e332a862ef75be8fad3606ea10108662bc6fe08509d5ca99503ac2aee"}, 739 | {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42430ff511571940d51e75cf42f1e4dbdded477e71c1b7a17f4da76c1da8ea76"}, 740 | {file = "yarl-1.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3150078118f62371375e1e69b13b48288e44f6691c1069340081c3fd12c94d5b"}, 741 | {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c15163b6125db87c8f53c98baa5e785782078fbd2dbeaa04c6141935eb6dab7a"}, 742 | {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d04acba75c72e6eb90745447d69f84e6c9056390f7a9724605ca9c56b4afcc6"}, 743 | {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e7fd20d6576c10306dea2d6a5765f46f0ac5d6f53436217913e952d19237efc4"}, 744 | {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:75c16b2a900b3536dfc7014905a128a2bea8fb01f9ee26d2d7d8db0a08e7cb2c"}, 745 | {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6d88056a04860a98341a0cf53e950e3ac9f4e51d1b6f61a53b0609df342cc8b2"}, 746 | {file = "yarl-1.8.2-cp311-cp311-win32.whl", hash = "sha256:fb742dcdd5eec9f26b61224c23baea46c9055cf16f62475e11b9b15dfd5c117b"}, 747 | {file = "yarl-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8c46d3d89902c393a1d1e243ac847e0442d0196bbd81aecc94fcebbc2fd5857c"}, 748 | {file = "yarl-1.8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ceff9722e0df2e0a9e8a79c610842004fa54e5b309fe6d218e47cd52f791d7ef"}, 749 | {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f6b4aca43b602ba0f1459de647af954769919c4714706be36af670a5f44c9c1"}, 750 | {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1684a9bd9077e922300ecd48003ddae7a7474e0412bea38d4631443a91d61077"}, 751 | {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ebb78745273e51b9832ef90c0898501006670d6e059f2cdb0e999494eb1450c2"}, 752 | {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3adeef150d528ded2a8e734ebf9ae2e658f4c49bf413f5f157a470e17a4a2e89"}, 753 | {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57a7c87927a468e5a1dc60c17caf9597161d66457a34273ab1760219953f7f4c"}, 754 | {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:efff27bd8cbe1f9bd127e7894942ccc20c857aa8b5a0327874f30201e5ce83d0"}, 755 | {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a783cd344113cb88c5ff7ca32f1f16532a6f2142185147822187913eb989f739"}, 756 | {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:705227dccbe96ab02c7cb2c43e1228e2826e7ead880bb19ec94ef279e9555b5b"}, 757 | {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:34c09b43bd538bf6c4b891ecce94b6fa4f1f10663a8d4ca589a079a5018f6ed7"}, 758 | {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a48f4f7fea9a51098b02209d90297ac324241bf37ff6be6d2b0149ab2bd51b37"}, 759 | {file = "yarl-1.8.2-cp37-cp37m-win32.whl", hash = "sha256:0414fd91ce0b763d4eadb4456795b307a71524dbacd015c657bb2a39db2eab89"}, 760 | {file = "yarl-1.8.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d881d152ae0007809c2c02e22aa534e702f12071e6b285e90945aa3c376463c5"}, 761 | {file = "yarl-1.8.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5df5e3d04101c1e5c3b1d69710b0574171cc02fddc4b23d1b2813e75f35a30b1"}, 762 | {file = "yarl-1.8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7a66c506ec67eb3159eea5096acd05f5e788ceec7b96087d30c7d2865a243918"}, 763 | {file = "yarl-1.8.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2b4fa2606adf392051d990c3b3877d768771adc3faf2e117b9de7eb977741229"}, 764 | {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e21fb44e1eff06dd6ef971d4bdc611807d6bd3691223d9c01a18cec3677939e"}, 765 | {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93202666046d9edadfe9f2e7bf5e0782ea0d497b6d63da322e541665d65a044e"}, 766 | {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc77086ce244453e074e445104f0ecb27530d6fd3a46698e33f6c38951d5a0f1"}, 767 | {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dd68a92cab699a233641f5929a40f02a4ede8c009068ca8aa1fe87b8c20ae3"}, 768 | {file = "yarl-1.8.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b372aad2b5f81db66ee7ec085cbad72c4da660d994e8e590c997e9b01e44901"}, 769 | {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6f3515aafe0209dd17fb9bdd3b4e892963370b3de781f53e1746a521fb39fc0"}, 770 | {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dfef7350ee369197106805e193d420b75467b6cceac646ea5ed3049fcc950a05"}, 771 | {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:728be34f70a190566d20aa13dc1f01dc44b6aa74580e10a3fb159691bc76909d"}, 772 | {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ff205b58dc2929191f68162633d5e10e8044398d7a45265f90a0f1d51f85f72c"}, 773 | {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf211dcad448a87a0d9047dc8282d7de59473ade7d7fdf22150b1d23859f946"}, 774 | {file = "yarl-1.8.2-cp38-cp38-win32.whl", hash = "sha256:272b4f1599f1b621bf2aabe4e5b54f39a933971f4e7c9aa311d6d7dc06965165"}, 775 | {file = "yarl-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:326dd1d3caf910cd26a26ccbfb84c03b608ba32499b5d6eeb09252c920bcbe4f"}, 776 | {file = "yarl-1.8.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f8ca8ad414c85bbc50f49c0a106f951613dfa5f948ab69c10ce9b128d368baf8"}, 777 | {file = "yarl-1.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:418857f837347e8aaef682679f41e36c24250097f9e2f315d39bae3a99a34cbf"}, 778 | {file = "yarl-1.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae0eec05ab49e91a78700761777f284c2df119376e391db42c38ab46fd662b77"}, 779 | {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:009a028127e0a1755c38b03244c0bea9d5565630db9c4cf9572496e947137a87"}, 780 | {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3edac5d74bb3209c418805bda77f973117836e1de7c000e9755e572c1f7850d0"}, 781 | {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da65c3f263729e47351261351b8679c6429151ef9649bba08ef2528ff2c423b2"}, 782 | {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ef8fb25e52663a1c85d608f6dd72e19bd390e2ecaf29c17fb08f730226e3a08"}, 783 | {file = "yarl-1.8.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcd7bb1e5c45274af9a1dd7494d3c52b2be5e6bd8d7e49c612705fd45420b12d"}, 784 | {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44ceac0450e648de86da8e42674f9b7077d763ea80c8ceb9d1c3e41f0f0a9951"}, 785 | {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:97209cc91189b48e7cfe777237c04af8e7cc51eb369004e061809bcdf4e55220"}, 786 | {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:48dd18adcf98ea9cd721a25313aef49d70d413a999d7d89df44f469edfb38a06"}, 787 | {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e59399dda559688461762800d7fb34d9e8a6a7444fd76ec33220a926c8be1516"}, 788 | {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d617c241c8c3ad5c4e78a08429fa49e4b04bedfc507b34b4d8dceb83b4af3588"}, 789 | {file = "yarl-1.8.2-cp39-cp39-win32.whl", hash = "sha256:cb6d48d80a41f68de41212f3dfd1a9d9898d7841c8f7ce6696cf2fd9cb57ef83"}, 790 | {file = "yarl-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:6604711362f2dbf7160df21c416f81fac0de6dbcf0b5445a2ef25478ecc4c778"}, 791 | {file = "yarl-1.8.2.tar.gz", hash = "sha256:49d43402c6e3013ad0978602bf6bf5328535c48d192304b91b97a3c6790b1562"}, 792 | ] 793 | 794 | [package.dependencies] 795 | idna = ">=2.0" 796 | multidict = ">=4.0" 797 | 798 | [metadata] 799 | lock-version = "2.0" 800 | python-versions = "^3.10.0" 801 | content-hash = "756d6f0c0193c3e785fd6cd3d9262559d92f0f6c51d2022181d77eef8cb0fa6d" 802 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "api-doc-gpt" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["Ege Ucak "] 6 | license = "MIT License" 7 | readme = "README.md" 8 | packages = [{include = "api_doc_gpt"}] 9 | 10 | [tool.poetry.dependencies] 11 | python = "^3.10.0" 12 | fastapi = "^0.95.0" 13 | openai = "^0.27.2" 14 | requests = "^2.28.2" 15 | fire = "^0.5.0" 16 | 17 | 18 | [build-system] 19 | requires = ["poetry-core"] 20 | build-backend = "poetry.core.masonry.api" 21 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | openai 3 | requests 4 | fire 5 | -------------------------------------------------------------------------------- /showcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/egeucak/api-doc-gpt/84c20b7cee65d1365a1cd563e851321a3cff980d/showcase.png --------------------------------------------------------------------------------