From 79fc663bbdd017acbef52ec71001cd22f09b62a8 Mon Sep 17 00:00:00 2001 From: Shruti Patel Date: Wed, 8 Nov 2023 01:09:38 -0500 Subject: [PATCH] Add agents (#25) * Add error handling for generating embeddings * Change file name of test file * Add toml config * Move api key setting into init function * Analyze & explain commands now stream responses from chatgpt. * Add vscode lens extraction function * Update repo to use tree-sitter sql parser * Remove sqlglot * Add refactor_code function for vscode ext * Using queries to find functions instead of manually searching * Remove code from vscode output * Ignore parsing hidden directories * Don't try parsing files that we don't have parsers for * Ignore filepaths with extensions we can't pass * Fixed the error where all the changes were getting resaved. * Ensure that running setup without an existing file still works * Fix typo * Add expt with agents * Add expt with agents * Add poetry.toml * Add agents * Stop warnings in jupyter notebook * Fix typo * Add agents * Temp move pygraphviz to dev dependencies so it doesn't need to be installed in github --- .gitignore | 1 + README.md | 28 +- expt/autogen-agents.ipynb | 757 +++++ expt/autogen-tools.ipynb | 445 +++ expt/call_functions_with_chat_models.ipynb | 284 ++ poetry.lock | 2859 +++++++++++------ poetry.toml | 5 + pyproject.toml | 34 +- src/repo_gpt/agents/__init__.py | 0 src/repo_gpt/agents/autogen/__init__.py | 0 src/repo_gpt/agents/autogen/repo_qna.py | 356 ++ .../autogen/user_proxy_function_call_agent.py | 73 + src/repo_gpt/agents/base_agent.py | 117 + src/repo_gpt/agents/central_intelligence.py | 109 + src/repo_gpt/agents/code_writer.py | 145 + src/repo_gpt/agents/repo_comprehender.py | 270 ++ src/repo_gpt/agents/simple_memory_store.py | 122 + src/repo_gpt/cli.py | 97 +- .../code_manager/abstract_extractor.py | 59 + .../code_manager/code_dir_extractor.py | 156 + src/repo_gpt/code_manager/code_extractor.py | 148 - src/repo_gpt/code_manager/code_manager.py | 122 +- src/repo_gpt/code_manager/code_processor.py | 60 +- .../code_vscode_file_extractor.py | 17 + src/repo_gpt/codebase_analyzer/__init__.py | 0 .../codebase_analyzer/class_analyzer.py | 65 + .../codebase_analyzer/dependency_analyzer.py | 50 + .../function_call_analyzer.py | 92 + .../codebase_analyzer/graph_analyzer.py | 175 + src/repo_gpt/console.py | 16 + src/repo_gpt/file_handler/abstract_handler.py | 31 +- .../file_handler/generic_code_file_handler.py | 273 +- .../file_handler/generic_sql_file_handler.py | 100 + src/repo_gpt/file_handler/sql_file_handler.py | 37 - src/repo_gpt/logging_config.py | 26 + src/repo_gpt/openai_service.py | 76 +- src/repo_gpt/prompt_service.py | 66 + src/repo_gpt/search_service.py | 177 +- src/repo_gpt/test_generator.py | 8 +- src/repo_gpt/utils.py | 28 +- src/repo_gpt/vscode_prompt_service.py | 67 + test/code_manager/code_extractor.py | 109 + test/file_handler/test_php_extract_code.py | 21 +- .../test_php_extract_vscode_ext_codelens.py | 77 + test/file_handler/test_python_extract_code.py | 41 +- ...test_python_extract_vscode_ext_codelens.py | 78 + .../test_sql_extract_vscode_ext_codelens.py | 195 ++ .../test_sql_file_handler_extract_code.py | 55 +- .../test_typescript_extract_code.py | 24 +- ..._typescript_extract_vscode_ext_codelens.py | 83 + 50 files changed, 6839 insertions(+), 1395 deletions(-) create mode 100644 expt/autogen-agents.ipynb create mode 100644 expt/autogen-tools.ipynb create mode 100644 expt/call_functions_with_chat_models.ipynb create mode 100644 poetry.toml create mode 100644 src/repo_gpt/agents/__init__.py create mode 100644 src/repo_gpt/agents/autogen/__init__.py create mode 100644 src/repo_gpt/agents/autogen/repo_qna.py create mode 100644 src/repo_gpt/agents/autogen/user_proxy_function_call_agent.py create mode 100644 src/repo_gpt/agents/base_agent.py create mode 100644 src/repo_gpt/agents/central_intelligence.py create mode 100644 src/repo_gpt/agents/code_writer.py create mode 100644 src/repo_gpt/agents/repo_comprehender.py create mode 100644 src/repo_gpt/agents/simple_memory_store.py create mode 100644 src/repo_gpt/code_manager/abstract_extractor.py create mode 100644 src/repo_gpt/code_manager/code_dir_extractor.py delete mode 100644 src/repo_gpt/code_manager/code_extractor.py create mode 100644 src/repo_gpt/code_manager/code_vscode_file_extractor.py create mode 100644 src/repo_gpt/codebase_analyzer/__init__.py create mode 100644 src/repo_gpt/codebase_analyzer/class_analyzer.py create mode 100644 src/repo_gpt/codebase_analyzer/dependency_analyzer.py create mode 100644 src/repo_gpt/codebase_analyzer/function_call_analyzer.py create mode 100644 src/repo_gpt/codebase_analyzer/graph_analyzer.py create mode 100644 src/repo_gpt/file_handler/generic_sql_file_handler.py delete mode 100644 src/repo_gpt/file_handler/sql_file_handler.py create mode 100644 src/repo_gpt/logging_config.py create mode 100644 src/repo_gpt/prompt_service.py create mode 100644 src/repo_gpt/vscode_prompt_service.py create mode 100644 test/code_manager/code_extractor.py create mode 100644 test/file_handler/test_php_extract_vscode_ext_codelens.py create mode 100644 test/file_handler/test_python_extract_vscode_ext_codelens.py create mode 100644 test/file_handler/test_sql_extract_vscode_ext_codelens.py create mode 100644 test/file_handler/test_typescript_extract_vscode_ext_codelens.py diff --git a/.gitignore b/.gitignore index 7fe0853..e5db574 100644 --- a/.gitignore +++ b/.gitignore @@ -232,3 +232,4 @@ fabric.properties # Can't be having folks committing the crime of sharing their creds .env +expt/* diff --git a/README.md b/README.md index d804998..212a6f3 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Repo-GPT is a Python CLI tool designed to utilize the power of OpenAI's GPT-3 mo Repo-GPT can be installed via [pip](https://pip.pypa.io/en/stable/): ```bash +brew install graphviz pip install repo-gpt ``` @@ -93,6 +94,16 @@ repo-gpt add-test function_name --test_save_file_path $PWD/test.py --testing_pac We welcome your contributions! Before starting, please make sure to install Python `3.11` and the latest version of [poetry](https://python-poetry.org/docs/#installing-with-pipx). [Pyenv](https://github.com/pyenv/pyenv) is a convenient tool to manage multiple Python versions on your computer. Here are the steps to set up your development environment: +0. Install global dependencies: + + ```shell + nvm use --lts + + brew install graphviz + export CFLAGS="-I $(brew --prefix graphviz)/include" + export LDFLAGS="-L $(brew --prefix graphviz)/lib" + pip install poetry + ``` 1. Export your OpenAI key to your environment variables: @@ -104,6 +115,7 @@ Here are the steps to set up your development environment: ```shell poetry install --no-root + jupyter lab build ``` 3. Install pre-commit hooks: @@ -129,9 +141,20 @@ Here are the steps to set up your development environment: You can view the output of the `code_embeddings.pkl` using the following command: ```shell +poetry shell +python +import pandas as pd pd.read_pickle('./.repo_gpt/code_embeddings.pkl', compression='infer') ``` +#### Interpreter +```shell +poetry shell +ipython +%load_ext autoreload +%autoreload 2 +``` + ## Roadmap Here are the improvements we are currently considering: @@ -144,4 +167,7 @@ Here are the improvements we are currently considering: - [ ] Save # of tokens each code snippet has so we can ensure we don't pass too many tokens to GPT - [X] Add SQL file handler - [ ] Add DBT file handler -- this may be a break in pattern as we'd want to use the manifest.json file -- [ ] Create VSCode extension +- [X] Create VSCode extension +- [ ] Ensure files can be added & deleted and the indexing picks up on the changes. +- [ ] Add .repogptignore file to config & use it in the indexing command +- [ ] Use pygments library for prettier code formatting diff --git a/expt/autogen-agents.ipynb b/expt/autogen-agents.ipynb new file mode 100644 index 0000000..0704e80 --- /dev/null +++ b/expt/autogen-agents.ipynb @@ -0,0 +1,757 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Auto Generated Agent Chat: Performs Research with Multi-Agent Group Chat\n", + "\n", + "AutoGen offers conversable agents powered by LLM, tool or human, which can be used to perform tasks collectively via automated chat. This framwork allows tool use and human participance through multi-agent conversation.\n", + "Please find documentation about this feature [here](https://microsoft.github.io/autogen/docs/Use-Cases/agent_chat).\n", + "\n", + "[More useful research paper](https://arxiv.org/pdf/2308.08155.pdf)\n", + "\n", + "## Requirements\n", + "\n", + "AutoGen requires `Python>=3.8`. To run this notebook example, please install:\n", + "```bash\n", + "pip install pyautogen\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%%capture --no-stderr\n", + "# %pip install pyautogen~=0.1.0" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Encode the config list as a JSON string\n", + "OPENAI_API_KEY = ''" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set your API Endpoint\n", + "\n", + "The [`config_list_from_json`](https://microsoft.github.io/autogen/docs/reference/oai/openai_utils#config_list_from_json) function loads a list of configurations from an environment variable or a json file." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from repo_gpt.file_handler.generic_code_file_handler import PythonFileHandler\n", + "from repo_gpt.search_service import SearchService, convert_search_df_to_json\n", + "from pathlib import Path\n", + "from repo_gpt.openai_service import OpenAIService\n", + "\n", + "pythonfilehandler = PythonFileHandler()\n", + "root_path = Path(\"/Users/shrutipatel/projects/work/repo-gpt/\")\n", + "embedding_path = root_path / \".repo_gpt/code_embeddings.pkl\"\n", + "openai_service = OpenAIService(OPENAI_API_KEY)\n", + "search_service = SearchService(openai_service, embedding_path)\n", + " \n", + "\n", + "def completed_all_code_updates(code_changes):\n", + " return code_changes\n", + "\n", + "def create_file(file_path, content):\n", + " \"\"\"\n", + " Create a new file with the provided content.\n", + "\n", + " Args:\n", + " - file_path (str): Path to the new file to be created.\n", + " - content (str): Content to write in the new file.\n", + "\n", + " Returns:\n", + " - str: Success or error message.\n", + " \"\"\"\n", + " full_path = root_path / Path(file_path)\n", + "\n", + " # Check if file already exists\n", + " if full_path.exists():\n", + " return (\n", + " f\"File {file_path} already exists. To update it, use append_to_file().\"\n", + " )\n", + "\n", + " with open(full_path, \"w\") as f:\n", + " f.write(content)\n", + "\n", + " return f\"File {file_path} has been created successfully.\"\n", + "\n", + "def append_to_file(file_path, content):\n", + " \"\"\"\n", + " Append content to an existing file.\n", + "\n", + " Args:\n", + " - file_path (str): Path to the file to be updated.\n", + " - content (str): Content to append in the file.\n", + "\n", + " Returns:\n", + " - str: Success or error message.\n", + " \"\"\"\n", + " full_path = root_path / Path(file_path)\n", + "\n", + " # Check if file exists\n", + " if not full_path.exists():\n", + " return f\"File {file_path} does not exist. To create it, use create_file().\"\n", + "\n", + " with open(full_path, \"a\") as f:\n", + " f.write(content)\n", + "\n", + " return f\"Content has been appended to {file_path} successfully.\"\n", + "\n", + "def view_function_code(function_name):\n", + " logger.info(f\"Reading the code for: {function_name}\")\n", + " functions_df, classes_df = search_service.find_function_match(\n", + " function_name\n", + " )\n", + "\n", + " if (classes_df is None or classes_df.empty) and (\n", + " functions_df is None or functions_df.empty\n", + " ):\n", + " return \"\"\n", + " elif functions_df is None or functions_df.empty:\n", + " return convert_search_df_to_json(classes_df)\n", + " elif classes_df is None or classes_df.empty:\n", + " return convert_search_df_to_json(functions_df)\n", + " else:\n", + " return convert_search_df_to_json(functions_df)\n", + "\n", + "def semantic_search(query):\n", + " logger.info(f\"Searching the codebase for: {query}\")\n", + " return convert_search_df_to_json(\n", + " search_service.semantic_search_similar_code(query)\n", + " )\n", + "\n", + "def view_file_functions_and_classes(file_paths):\n", + " logger.info(f\"Skimming the code in: {file_paths}\")\n", + " results = []\n", + " for file_path in file_paths:\n", + " full_path = root_path / Path(file_path)\n", + "\n", + " if not full_path.exists():\n", + " results.append(f\"File not found: {file_path}\")\n", + " continue # Skip to the next iteration\n", + " elif full_path.is_dir():\n", + " results.append(\n", + " f\"This is not a file, but a directory, pass a filepath instead: {file_path}\"\n", + " )\n", + " continue # Skip to the next iteration\n", + "\n", + " # TODO select the correct filehandler and then summarize file\n", + " results.append(pythonfilehandler.summarize_file(full_path))\n", + "\n", + " return \"\\n\".join(results)\n", + "\n", + "def create_plan_to_complete_user_task(plan):\n", + " return plan" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from repo_gpt.file_handler.generic_code_file_handler import PythonFileHandler\n", + "from repo_gpt.search_service import SearchService, convert_search_df_to_json\n", + "from pathlib import Path\n", + "from repo_gpt.openai_service import OpenAIService\n", + "\n", + "pythonfilehandler = PythonFileHandler()\n", + "root_path = Path(\"/Users/shrutipatel/projects/work/repo-gpt/\")\n", + "embedding_path = root_path / \".repo_gpt/code_embeddings.pkl\"\n", + "openai_service = OpenAIService(OPENAI_API_KEY)\n", + "search_service = SearchService(openai_service, embedding_path)\n", + " \n", + "\n", + "def completed_all_code_updates(code_changes):\n", + " return code_changes\n", + "\n", + "def create_file(file_path, content):\n", + " \"\"\"\n", + " Create a new file with the provided content.\n", + "\n", + " Args:\n", + " - file_path (str): Path to the new file to be created.\n", + " - content (str): Content to write in the new file.\n", + "\n", + " Returns:\n", + " - str: Success or error message.\n", + " \"\"\"\n", + " full_path = root_path / Path(file_path)\n", + "\n", + " # Check if file already exists\n", + " if full_path.exists():\n", + " return (\n", + " f\"File {file_path} already exists. To update it, use append_to_file().\"\n", + " )\n", + "\n", + " with open(full_path, \"w\") as f:\n", + " f.write(content)\n", + "\n", + " return f\"File {file_path} has been created successfully.\"\n", + "\n", + "def append_to_file(file_path, content):\n", + " \"\"\"\n", + " Append content to an existing file.\n", + "\n", + " Args:\n", + " - file_path (str): Path to the file to be updated.\n", + " - content (str): Content to append in the file.\n", + "\n", + " Returns:\n", + " - str: Success or error message.\n", + " \"\"\"\n", + " full_path = root_path / Path(file_path)\n", + "\n", + " # Check if file exists\n", + " if not full_path.exists():\n", + " return f\"File {file_path} does not exist. To create it, use create_file().\"\n", + "\n", + " with open(full_path, \"a\") as f:\n", + " f.write(content)\n", + "\n", + " return f\"Content has been appended to {file_path} successfully.\"\n", + "\n", + "def view_function_code(function_name):\n", + " logger.info(f\"Reading the code for: {function_name}\")\n", + " functions_df, classes_df = search_service.find_function_match(\n", + " function_name\n", + " )\n", + "\n", + " if (classes_df is None or classes_df.empty) and (\n", + " functions_df is None or functions_df.empty\n", + " ):\n", + " return \"\"\n", + " elif functions_df is None or functions_df.empty:\n", + " return convert_search_df_to_json(classes_df)\n", + " elif classes_df is None or classes_df.empty:\n", + " return convert_search_df_to_json(functions_df)\n", + " else:\n", + " return convert_search_df_to_json(functions_df)\n", + "\n", + "def semantic_search(query):\n", + " logger.info(f\"Searching the codebase for: {query}\")\n", + " return convert_search_df_to_json(\n", + " search_service.semantic_search_similar_code(query)\n", + " )\n", + "\n", + "def view_file_functions_and_classes(file_paths):\n", + " logger.info(f\"Skimming the code in: {file_paths}\")\n", + " results = []\n", + " for file_path in file_paths:\n", + " full_path = root_path / Path(file_path)\n", + "\n", + " if not full_path.exists():\n", + " results.append(f\"File not found: {file_path}\")\n", + " continue # Skip to the next iteration\n", + " elif full_path.is_dir():\n", + " results.append(\n", + " f\"This is not a file, but a directory, pass a filepath instead: {file_path}\"\n", + " )\n", + " continue # Skip to the next iteration\n", + "\n", + " # TODO select the correct filehandler and then summarize file\n", + " results.append(pythonfilehandler.summarize_file(full_path))\n", + "\n", + " return \"\\n\".join(results)\n", + "\n", + "def create_plan_to_complete_user_task(plan):\n", + " return plan" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import autogen\n", + "import os\n", + "import json\n", + "\n", + "import tempfile\n", + "from dotenv import find_dotenv, load_dotenv\n", + "load_dotenv(find_dotenv())\n", + "\n", + "env_var = [\n", + "{\n", + " 'model': 'gpt-3.5-turbo',\n", + " 'api_key': OPENAI_API_KEY,\n", + " },\n", + " {\n", + " 'model': 'gpt-3.5-turbo-16k',\n", + " 'api_key': OPENAI_API_KEY,\n", + " },\n", + " {\n", + " 'model': 'gpt-4-32k',\n", + " 'api_key': OPENAI_API_KEY,\n", + " },\n", + "]\n", + "\n", + "# Create a temporary file\n", + "# Write the JSON structure to a temporary file and pass it to config_list_from_json\n", + "with tempfile.NamedTemporaryFile(mode='w+', delete=True) as temp:\n", + " env_var = json.dumps(env_var)\n", + " temp.write(env_var)\n", + " temp.flush()\n", + "\n", + "# OAI_CONFIG_LIST = json.dumps([\n", + "# {\n", + "# 'model': 'gpt-3.5-turbo',\n", + "# 'api_key': OPENAI_API_KEY,\n", + "# },\n", + "# {\n", + "# 'model': 'gpt-3.5-turbo-16k',\n", + "# 'api_key': OPENAI_API_KEY,\n", + "# },\n", + "# {\n", + "# 'model': 'gpt-4-32k',\n", + "# 'api_key': OPENAI_API_KEY,\n", + "# },\n", + "# ])\n", + "\n", + "# Set it as an environment variable\n", + "# os.environ['OAI_CONFIG'] = OAI_CONFIG_LIST\n", + "\n", + " config_list_gpt4 = autogen.config_list_from_json(\n", + " temp.name,\n", + " filter_dict={\n", + " \"model\": [\"gpt-3.5-turbo\", \"gpt-3.5-turbo-16k\"],\n", + " },\n", + " )\n", + "\n", + "source_code_librarian_config = {\n", + " \"functions\": [\n", + " {\n", + " \"name\": \"semantic_search\",\n", + " \"description\": \"Use this function to search the entire codebase semantically. The input should be the search query string.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"query\": {\n", + " \"type\": \"string\",\n", + " \"description\": f\"\"\"\n", + " The semantic search query to use to search the code base.\n", + " \"\"\",\n", + " }\n", + " },\n", + " \"required\": [\"query\"],\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"view_function_code\",\n", + " \"description\": \"Use this function to search for and view a function's code in the user's codebase. Input should be the name of the function you want to search for. An empty response means the given files don't exist.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"function_name\": {\n", + " \"type\": \"string\",\n", + " \"description\": f\"\"\"\n", + " The name of the function or its description.\n", + " \"\"\",\n", + " }\n", + " },\n", + " \"required\": [\"function_name\"],\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"view_file_functions_and_classes\",\n", + " \"description\": \"Use this function to retrieve a list of the functions and classes in a file from the user's codebase. An empty response means the given files don't exist.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"file_paths\": {\n", + " \"type\": \"array\",\n", + " \"items\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"An array of one or more file paths of a file you want to retrieve functions and classes from. If a file doesn't exist, the function will return a string saying so.\",\n", + " },\n", + " \"description\": f\"\"\"\n", + " The file paths of the files you want to retrieve functions and classes for to better understand the user's task. Below are the files within the user's repository:\n", + " {get_relative_path_directory_structure(\"/Users/shrutipatel/projects/work/repo-gpt\")}\n", + " \"\"\",\n", + " }\n", + " },\n", + " \"required\": [\"file_paths\"],\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"create_plan_to_complete_user_task\",\n", + " \"description\": \"Use this function when you understand the user's task and have a detailed plan ready for completing the user's task. The input should be a step-by-step plan on how to complete the user's task. It can include things like 'Create a new file with a given file path', 'Add the given code to the file', etc.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"plan\": {\n", + " \"type\": \"string\",\n", + " \"description\": f\"\"\"\n", + " A step-by-step plan on how to complete the user's task. It can include things like \"Create a new file with a given file path\", \"Add the given code to the file\", etc.\n", + " \"\"\",\n", + " }\n", + " },\n", + " \"required\": [\"plan\"],\n", + " },\n", + " },\n", + " ],\n", + " \"config_list\": config_list_gpt4,\n", + " \"request_timeout\": 120,\n", + "}\n", + "\n", + "\n", + "engineer_config = {\n", + " \"functions\": [\n", + " {\n", + " \"name\": \"create_file\",\n", + " \"description\": \"Create a new file with the provided content.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"file_path\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"Path to the new file to be created.\",\n", + " },\n", + " \"content\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"Content to write in the new file.\",\n", + " },\n", + " },\n", + " \"required\": [\"file_path\", \"content\"],\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"append_to_file\",\n", + " \"description\": \"Append content to an existing file.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"file_path\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"Path to the file to be updated.\",\n", + " },\n", + " \"content\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"Content to append to the file.\",\n", + " },\n", + " },\n", + " \"required\": [\"file_path\", \"content\"],\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"completed_all_code_updates\",\n", + " \"description\": \"Call this function when all the code updates are completed.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"code_changes\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"Enumeration of all the changes that were made to the code.\",\n", + " }\n", + " },\n", + " \"required\": [\"code_changes\"],\n", + " },\n", + " },\n", + " ],\n", + " \"config_list\": config_list_gpt4,\n", + " \"request_timeout\": 120,\n", + "}\n", + "\n", + " " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It first looks for environment variable \"OAI_CONFIG_LIST\" which needs to be a valid json string. If that variable is not found, it then looks for a json file named \"OAI_CONFIG_LIST\". It filters the configs by models (you can filter by other keys as well).\n", + "\n", + "The config list looks like the following:\n", + "```python\n", + "config_list = [\n", + " {\n", + " 'model': 'gpt-4-32k',\n", + " 'api_key': '',\n", + " },\n", + " {\n", + " 'model': 'gpt-4-32k',\n", + " 'api_key': '',\n", + " 'api_base': '',\n", + " 'api_type': 'azure',\n", + " 'api_version': '2023-06-01-preview',\n", + " },\n", + " {\n", + " 'model': 'gpt-4-32k-0314',\n", + " 'api_key': '',\n", + " 'api_base': '',\n", + " 'api_type': 'azure',\n", + " 'api_version': '2023-06-01-preview',\n", + " },\n", + "]\n", + "```\n", + "\n", + "If you open this notebook in colab, you can upload your files by clicking the file icon on the left panel and then choose \"upload file\" icon.\n", + "\n", + "You can set the value of config_list in other ways you prefer, e.g., loading from a YAML file." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plan\n", + "1. Create a UseProxyAgent + Assistant for searching the codebase\n", + "2. If code updates are necessary, generate a detailed plan of next steps\n", + "3. Engineer + UserProxyAgent writes the code\n", + "4. Have a Critic + UserProxyAgent that reviews the code (add functions for reading git diffs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create simple agent structure\n", + "[Example Notebook](https://github.com/microsoft/autogen/blob/main/notebook/agentchat_two_users.ipynb)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Construct Agents" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "gpt4_config = {\n", + " \"seed\": 42, # change the seed for different trials\n", + " \"temperature\": 0,\n", + " \"config_list\": config_list_gpt4,\n", + " \"request_timeout\": 120,\n", + "}\n", + "user_proxy = autogen.UserProxyAgent(\n", + " name=\"Admin\",\n", + " system_message=\"A human admin. Interact with the planner to discuss the plan. Plan execution needs to be approved by this admin.\",\n", + " code_execution_config=False,\n", + ")\n", + "engineer = autogen.UserProxyAgent(\n", + " name=\"Engineer\",\n", + " llm_config=engineer_config,\n", + " human_input_mode=\"NEVER\",\n", + " system_message='''Engineer. You follow an approved plan. You write python/shell code to solve tasks. Wrap the code in a code block that specifies the script type. The user can't modify your code. So do not suggest incomplete code which requires others to modify. Don't use a code block if it's not intended to be executed by the executor.\n", + "Don't include multiple code blocks in one response. Do not ask others to copy and paste the result. Check the execution result returned by the executor.\n", + "If the result indicates there is an error, fix the error and output the code again. Suggest the full code instead of partial code or code changes. If the error can't be fixed or if the task is not solved even after the code is executed successfully, analyze the problem, revisit your assumption, collect additional info you need, and think of a different approach to try.\n", + "''',\n", + ")\n", + "engineer.register_function(\n", + " function_map={\n", + " \"create_file\": create_file,\n", + " \"append_to_file\": append_to_file,\n", + " \"completed_all_code_updates\": completed_all_code_updates,\n", + " })\n", + "\n", + "#\"Repository Manager\" or \"Source Code Librarian\"\n", + "source_code_librarian = autogen.UserProxyAgent(\n", + " name=\"Architect\",\n", + " llm_config=source_code_librarian_config,\n", + " human_input_mode=\"NEVER\",\n", + " system_message=\"\"\"Architect. You browse the codebase to understand the larger structure, dependencies, metadata, and code logic. \n", + "Based on your browsing, you answer questions about the code base and create code architecture plans that fit the codebase's existing patterns.\n", + "You don't write code. You tell the Engineer what to code.\n", + " \"\"\"\n", + ")\n", + "source_code_librarian.register_function(\n", + " function_map={\n", + " \"semantic_search\": semantic_search,\n", + " \"view_function_code\": view_function_code,\n", + " \"view_file_functions_and_classes\": view_file_functions_and_classes,\n", + " \"create_plan_to_complete_user_task\": create_plan_to_complete_user_task,\n", + " })\n", + "planner = autogen.AssistantAgent(\n", + " name=\"Coordinator\",\n", + " system_message='''Coordinator. First, ask for the architect's input and then suggest a plan. \n", + "The plan may involve an engineer who can write code and an architect who searches the existing codebase.\n", + "Explain the plan first. Be clear about which step is performed by an engineer, and which is performed by an architect.\n", + "Revise the plan based on findings from the architect and engineer if necessary.\n", + "''',\n", + " llm_config=gpt4_config,\n", + ")\n", + "\n", + "# TODO replace with test writer\n", + "executor = autogen.UserProxyAgent(\n", + " name=\"Executor\",\n", + " system_message=\"Executor. Execute the code written by the engineer and report the result.\",\n", + " human_input_mode=\"NEVER\",\n", + " code_execution_config={\"work_dir\": \"coding\"},\n", + ")\n", + "critic = autogen.AssistantAgent(\n", + " name=\"Critic\",\n", + " system_message=\"Critic. Double check plan, claims, code from other agents and provide feedback. Check whether the plan includes adding verifiable info such as source URL.\",\n", + " llm_config=gpt4_config,\n", + ")\n", + "# groupchat = autogen.GroupChat(agents=[user_proxy, engineer, source_code_librarian, planner, executor, critic], messages=[], max_round=50)\n", + "groupchat = autogen.GroupChat(agents=[user_proxy, engineer, source_code_librarian, executor, critic], messages=[], max_round=50)\n", + "manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=gpt4_config)\n", + "\n", + "manager.register_function(\n", + " function_map={\n", + " \"semantic_search\": semantic_search,\n", + " \"view_function_code\": view_function_code,\n", + " \"view_file_functions_and_classes\": view_file_functions_and_classes,\n", + " \"create_plan_to_complete_user_task\": create_plan_to_complete_user_task,\n", + " \"create_file\": create_file,\n", + " \"append_to_file\": append_to_file,\n", + " \"completed_all_code_updates\": completed_all_code_updates,\n", + " })" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Start Chat" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mAdmin\u001b[0m (to chat_manager):\n", + "\n", + "\n", + "Add a code file handler for Elixir.\n", + "\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mEngineer\u001b[0m (to chat_manager):\n", + "\n", + "\u001b[32m***** Suggested function Call: append_to_file *****\u001b[0m\n", + "Arguments: \n", + "{\n", + " \"file_path\": \"handlers.json\",\n", + " \"content\": \",\\n \\\"elixir\\\": \\\"elixir_handler.py\\\"\"\n", + "}\n", + "\u001b[32m***************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mArchitect\u001b[0m (to chat_manager):\n", + "\n", + "\u001b[32m***** Response from calling function \"append_to_file\" *****\u001b[0m\n", + "Error: Function append_to_file not found.\n", + "\u001b[32m***********************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mArchitect\u001b[0m (to chat_manager):\n", + "\n", + "\u001b[32m***** Suggested function Call: view_function_code *****\u001b[0m\n", + "Arguments: \n", + "{\n", + " \"function_name\": \"append_to_file\"\n", + "}\n", + "\u001b[32m*******************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mEngineer\u001b[0m (to chat_manager):\n", + "\n", + "\u001b[32m***** Response from calling function \"view_function_code\" *****\u001b[0m\n", + "Error: Function view_function_code not found.\n", + "\u001b[32m***************************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "user_proxy.initiate_chat(\n", + " manager,\n", + " message=\"\"\"\n", + "Add a code file handler for Elixir.\n", + "\"\"\",\n", + ")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create Group Chat without Critic for Comparison" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "groupchat_nocritic = autogen.GroupChat(agents=[user_proxy, engineer, scientist, planner, executor], messages=[], max_round=50)\n", + "for agent in groupchat.agents:\n", + " agent.reset()\n", + "manager_nocritic = autogen.GroupChatManager(groupchat=groupchat_nocritic, llm_config=gpt4_config)\n", + "user_proxy.initiate_chat(\n", + " manager_nocritic,\n", + " message=\"\"\"\n", + "find papers on LLM applications from arxiv in the last week, create a markdown table of different domains.\n", + "\"\"\",\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/expt/autogen-tools.ipynb b/expt/autogen-tools.ipynb new file mode 100644 index 0000000..4fd2dfd --- /dev/null +++ b/expt/autogen-tools.ipynb @@ -0,0 +1,445 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "ae1f50ec", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "9a71fa36", + "metadata": {}, + "source": [ + "# Auto Generated Agent Chat: Task Solving with Provided Tools as Functions\n", + "\n", + "AutoGen offers conversable agents powered by LLM, tool or human, which can be used to perform tasks collectively via automated chat. This framwork allows tool use and human participance through multi-agent conversation. Please find documentation about this feature [here](https://microsoft.github.io/autogen/docs/Use-Cases/agent_chat).\n", + "\n", + "In this notebook, we demonstrate how to use `AssistantAgent` and `UserProxyAgent` to make function calls with the new feature of OpenAI models (in model version 0613). A specified prompt and function configs need to be passed to `AssistantAgent` to initialize the agent. The corresponding functions need to be passed to `UserProxyAgent`, which will be responsible for executing any function calls made by `AssistantAgent`. Besides this requirement of matching descriptions with functions, we recommend checking the system message in the `AssistantAgent` to make sure the instructions align with the function call descriptions.\n", + "\n", + "## Requirements\n", + "\n", + "AutoGen requires `Python>=3.8`. To run this notebook example, please install the [mathchat] option since we will import functions from `MathUserProxyAgent`:\n", + "```bash\n", + "pip install \"pyautogen[mathchat]\"\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2b803c17", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install \"pyautogen[mathchat]~=0.1.0\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "5ebd2397", + "metadata": {}, + "source": [ + "## Set your API Endpoint\n", + "\n", + "The [`config_list_from_models`](https://microsoft.github.io/autogen/docs/reference/oai/openai_utils#config_list_from_models) function tries to create a list of configurations using Azure OpenAI endpoints and OpenAI endpoints for the provided list of models. It assumes the api keys and api bases are stored in the corresponding environment variables or local txt files:\n", + "\n", + "- OpenAI API key: os.environ[\"OPENAI_API_KEY\"] or `openai_api_key_file=\"key_openai.txt\"`.\n", + "- Azure OpenAI API key: os.environ[\"AZURE_OPENAI_API_KEY\"] or `aoai_api_key_file=\"key_aoai.txt\"`. Multiple keys can be stored, one per line.\n", + "- Azure OpenAI API base: os.environ[\"AZURE_OPENAI_API_BASE\"] or `aoai_api_base_file=\"base_aoai.txt\"`. Multiple bases can be stored, one per line.\n", + "\n", + "It's OK to have only the OpenAI API key, or only the Azure OpenAI API key + base.\n", + "If you open this notebook in google colab, you can upload your files by click the file icon on the left panel and then choose \"upload file\" icon.\n", + "\n", + "The following code excludes Azure OpenAI endpoints from the config list because some endpoints don't support functions yet. Remove the `exclude` argument if they do." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "dca301a4", + "metadata": {}, + "outputs": [], + "source": [ + "import autogen\n", + "\n", + "config_list = autogen.config_list_from_models(model_list=[\"gpt-4\", \"gpt-3.5-turbo\", \"gpt-3.5-turbo-16k\"], exclude=\"aoai\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "92fde41f", + "metadata": {}, + "source": [ + "The config list looks like the following:\n", + "```python\n", + "config_list = [\n", + " {\n", + " 'model': 'gpt-4',\n", + " 'api_key': '',\n", + " }, # OpenAI API endpoint for gpt-4\n", + " {\n", + " 'model': 'gpt-3.5-turbo',\n", + " 'api_key': '',\n", + " }, # OpenAI API endpoint for gpt-3.5-turbo\n", + " {\n", + " 'model': 'gpt-3.5-turbo-16k',\n", + " 'api_key': '',\n", + " }, # OpenAI API endpoint for gpt-3.5-turbo-16k\n", + "]\n", + "```\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "2b9526e7", + "metadata": {}, + "source": [ + "## Making Function Calls\n", + "\n", + "In this example, we demonstrate function call execution with `AssistantAgent` and `UserProxyAgent`. With the default system prompt of `AssistantAgent`, we allow the LLM assistant to perform tasks with code, and the `UserProxyAgent` would extract code blocks from the LLM response and execute them. With the new \"function_call\" feature, we define functions and specify the description of the function in the OpenAI config for the `AssistantAgent`. Then we register the functions in `UserProxyAgent`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "9fb85afb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33muser_proxy\u001b[0m (to chatbot):\n", + "\n", + "Draw two agents chatting with each other with an example dialog. Don't add plt.show().\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mchatbot\u001b[0m (to user_proxy):\n", + "\n", + "\u001b[32m***** Suggested function Call: python *****\u001b[0m\n", + "Arguments: \n", + "{\n", + " \"cell\": \"\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib.patches as mpatches\n", + "\n", + "# Define basic parameters\n", + "face_color = '#FFDDC1'\n", + "plt.figure(figsize=(10, 2))\n", + "\n", + "# Agent 1\n", + "agent1 = mpatches.FancyBboxPatch((0.02, 0.4), 0.2, 0.6, boxstyle=mpatches.BoxStyle(\\\"Round\\\", pad=0.02))\n", + "plt.gca().add_artist(agent1)\n", + "plt.gca().text(0.12, 0.7, 'Agent 1', ha='center', va='center', fontsize=12, color='blue')\n", + "\n", + "# Agent 2\n", + "agent2 = mpatches.FancyBboxPatch((0.45, 0.4), 0.2, 0.6, boxstyle=mpatches.BoxStyle(\\\"Round\\\", pad=0.02))\n", + "plt.gca().add_artist(agent2)\n", + "plt.gca().text(0.55, 0.7, 'Agent 2', ha='center', va='center', fontsize=12, color='red')\n", + "\n", + "# Dialog\n", + "plt.gca().text(0.12, 0.35, '\\\"Hello, how are you?\\\"', ha='center', va='center', fontsize=10)\n", + "plt.gca().text(0.55, 0.15, '\\\"I\\'m fine, thank you!\\\"', ha='center', va='center', fontsize=10)\n", + "\n", + "# Descriptions\n", + "plt.gca().text(0.12, 0.15, 'Greeting', ha='center', va='center', fontsize=10)\n", + "plt.gca().text(0.55, 0.35, 'Response', ha='center', va='center', fontsize=10)\n", + "\n", + "plt.axis('off')\n", + "\"\n", + "}\n", + "\u001b[32m*******************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33muser_proxy\u001b[0m (to chatbot):\n", + "\n", + "\u001b[32m***** Response from calling function \"python\" *****\u001b[0m\n", + "Error: Invalid \\escape: line 1 column 785 (char 784)\n", + " You argument should follow json format.\n", + "\u001b[32m***************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mchatbot\u001b[0m (to user_proxy):\n", + "\n", + "\u001b[32m***** Suggested function Call: python *****\u001b[0m\n", + "Arguments: \n", + "{\n", + " \"cell\": \"import matplotlib.pyplot as plt\\nimport matplotlib.patches as mpatches\\n\\n# Define basic parameters\\nface_color = '#FFDDC1'\\nplt.figure(figsize=(10, 2))\\n\\n# Agent 1\\nagent1 = mpatches.FancyBboxPatch((0.02, 0.4), 0.2, 0.6, boxstyle=mpatches.BoxStyle('Round', pad=0.02))\\nplt.gca().add_artist(agent1)\\nplt.gca().text(0.12, 0.7, 'Agent 1', ha='center', va='center', fontsize=12, color='blue')\\n\\n# Agent 2\\nagent2 = mpatches.FancyBboxPatch((0.45, 0.4), 0.2, 0.6, boxstyle=mpatches.BoxStyle('Round', pad=0.02))\\nplt.gca().add_artist(agent2)\\nplt.gca().text(0.55, 0.7, 'Agent 2', ha='center', va='center', fontsize=12, color='red')\\n\\n# Dialog\\nplt.gca().text(0.12, 0.35, '\\\"Hello, how are you?\\\"', ha='center', va='center', fontsize=10)\\nplt.gca().text(0.55, 0.15, '\\\"I\\\\'m fine, thank you!\\\"', ha='center', va='center', fontsize=10)\\n\\n# Descriptions\\nplt.gca().text(0.12, 0.15, 'Greeting', ha='center', va='center', fontsize=10)\\nplt.gca().text(0.55, 0.35, 'Response', ha='center', va='center', fontsize=10)\\n\\nplt.axis('off')\"\n", + "}\n", + "\u001b[32m*******************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[35m\n", + ">>>>>>>> EXECUTING FUNCTION python...\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "(0.0, 1.0, 0.0, 1.0)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxoAAACuCAYAAACx83usAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAsEElEQVR4nO3deXxM5/4H8M/MZJ3JTppEEomIRGyxRIu0xBLUmlZV0Sa20lJFUbR+DaVq6Y3lVl3u1UiprS6lTdTSK2goGklEVksESQiRbbJn5vn9kZoasQyOxvJ5v155vZwzz3nO9wyek8+c85yRCSEEiIiIiIiIJCSv6wKIiIiIiOjZw6BBRERERESSY9AgIiIiIiLJMWgQEREREZHkGDSIiIiIiEhyDBpERERERCQ5Bg0iIiIiIpIcgwYREREREUmOQYOIiIiIiCRnZGhDpeeLeOGN0MdZC1Gdyt02Fz2aOWLXrl11XQo95cLCwjDjk/+D8+StdV0K0WNTdHw7Ko5vRYm6uK5LIaInlOFXNGSyx1gG0ROA/8ZJSvznRM88/iMnonvjrVNERERERCQ5Bg0iIiIiIpIcgwYREREREUmOQYOIiIiIiCTHoEFERERERJJj0CAiIiIiIskxaBARERERkeQYNIiIiIiISHIMGkREREREJDkGDSIiIiIikhyDBhERERERSY5Bg4iIiIiIJMegQUREREREkmPQICIiIiIiyTFoEBERERGR5Bg0iIiIiIhIcgwaREREREQkOQYNIiIiIiKSHIMGERERERFJjkGDiIiIiIgkx6BBRERERESSY9AgIiIiIiLJMWgQEREREZHkGDSIiIiIiEhyDBpERERERCQ5Bg0iIiIiIpIcgwYREREREUmOQYOIiIiIiCTHoEFERERERJJj0CAiIiIiIskxaBARERERkeQYNIiIiIiISHIMGkREREREJDkGDSIiIiIikhyDBhERERERSY5Bg4iIiIiIJGdU1wU8TYpPuuHGvhYwccqHU/CRui6nluKTbpAZa2DR8rJB7UtSnFB21gEVOTaozlfB1DUPjsN+f8xVEtHz4u2TkZi/bxXinbwQFBxW1+XU8vbJSJQbm2Jbyx73bWtTVoQ3T+1D97PH4Zl3CcZaDc7ZuWBt+4H42afz31AtEdHTh1c0HkBJcgMorEtRmWOLqnxlXZdTS3GcG9SJLg/UvvSsAxSWZZCbVT7GyojoeRSUHI1L1g5onZMOt/zsui6nlnfiIvFG4n6D2rbNSsW0Q+tRaG6JrzsNwZLO76DM2BRf71qMKYe/f8yVEhE9nRg0DFRVYI6KLDvYdUuGXFmBkiTnui7pkdXvFw/XyXvgOPQYFBYVdV0OET1DXAquwC8rBfO7jcZ1pTWCkqLruqRHkl6/IbqOXYOxr89GuN9ArG/bD8Pe+gIxbq3w3rFtMK8sr+sSiYieOLx1ykAlyc6Qm1XCvHEulN5XUJLcADYvn6nVTlNmjPxfm6H0jAMgA5RNrsKq/XnkhHdGvT4Jerc1VeWpUHDIG+UX60FbpYCJfTGsO52Bskmuro060QV5Ub5wGH4EpWmOKElyhqhWwMz9Our1ToRCWXMl4vKqrtAU1VxlyVzUFwDueyuUkRVPjET0eAQlR6PAzAL/a9weu739MTA5GstfHlarnU1ZET779d8IPPM7hEyOfU1ewn/aB2F3+IeY1mey3m1NjfMuYeqh9eh08RTMqyqQZu+GFZ2GYn+Tl3Rt3kjcj6+ilmHQ8MV4NS0GryUdgHl1BQ67t8Gs3hNxQ2kNAPht1Si4FNWMtRcW9QMA/O7aAm8NW3jH47ls41h7pUyGvU06wj/zFBoWXkGavfvDvl1ERM8kXtEwUEmSM5ReVyBTCKh8slCdb4GKHGu9NkIA17a1R0lyA1i0yIJt5zRo1Ka4Hulbq7/KaxbIWe+PqjwLWHU4B7tuKZAZa3Btux9K0x1qtc/f3xxV16xg7X8Glq0vouzsC7ixr7nudbvuyVBYlsHITo16/eJRr188rDuelf6NICIyQFBSNH7x6oQqhTF2+XSGR342WuWk67WRCS3WbvscA5IP4r8tumNJ53dgr87HPyKX1uqvybVM7Fg/DZ55l7GqwxuY3200yozNsGb7fPRKrz1nbu7+1fC5loHl/kOxoXUfdD97HJ/v+5fu9c+7v4tsy/o4a+eCyf2mYnK/qfi645AHPk77knwAwA1zqwfelojoWccrGgaouGKF6hsWUAaeBgCYuuRDYVmGkiRnmDoV6tqVpTuiItsWtt2TYOV3AQBg0SYTuVteQtVtfeb/2hxGVmVwCo6BzEira3v1+47Ij24KpddVvfZys0q8MOQ4ZLKaZSGA4lh3aCuMIDethtLrKgoOe0NuXgmL5lmP5X0gIjJEiytn4XnjMkID3wMAnHBpjmzL+ghKisYpJy9du57pv6Nddirmdn8X4X4DAQAb2vTBhi2za/UZ+usaZFnZY2DwUlQaGQMA1rfpi23ff4wZ0euwx6uTXvt8M0u8M2Qebg6acqHFiNifYFlRgmJTFfZ6dcTUw+uRb26FH5t3fajjtC4rxpCEvTjm0hzXLOweqg8iomcZr2gYoCTJGXJVOcwa5gGoOW+pmuagJNUJQvtXu7IMe0CuhYXvRd06mQywbJOp15+mzBjlmfWgbJoDbaUCmlJjaEqNoS0zhlmja6jOt0B1saneNhatL+pCBgCYud4AhBzVhebSHzAR0SMISjqAayobHG3YsmaFTIafm76C/qmHINdqdO26ZMSiUm6ETb69dOuETI7v2vTT68+6rBidMk8hsunLUFWWwra0sOanrAiHGrWFR342HIqv622zqXVv3DponnBtDiOhhXNhLqQgE1os/+krWFWoMSdwnCR9EhE9a3hF4z6EFihNbQCzhnmoLvzrSVMmDfKhPeGB8sz6MG9Uc4KrLjSHwqIccmOtXh9GtiV6y9X5SgAyFB72RuFh7zvuV1tqClj+NUH79vkUcrOaayTacuOHPjYiIqnJtRr0Tz2Mow1bwbXwryuz8Q28MfbEDvhnJuBwo7YAAJfCXORa2KLc2Eyvj0xbJ71l9/xsyCEw7fAGTDu84Y77rV9aiKuW9XXL2Vb2eq8XmlkAAKzL1Q9/cLeYu281AjJiMaXvR0h5wUOSPomInjUMGvdRnlkfGrUZSlOcUZpS+0lTJcnOuqBhMFHzKZvVi+dg1ujaHZsY2eiHE8jEg+2DiKgOdMo8BQf1DQxIOYQBKYdqvR6UHK0LGoaSi5rxb/WLr+PQXba9YKMfTjSyO1+wl+HRx9JJv21EcFwkFnYZgR0tuj1yf0REzyoGjfsoSW4AubICdn/Oz7hVabojStMdoO0ph9xYCyPrsj+fICXXu6pRna/S287IprTmD3IBc/c8CatlGCGiuhWUHI1rSht89uf8jFv1Tj+KnulHYdqzAhXGprhs/QI6XEyEWVW53lUNt/wcve0u/vnEp2q5AjHurSWrVUB2/0a3eefkz5gSsxFr/QbiXx3ekKwWIqJnEedo3IO2So7SdEeYN86FqumVWj+WbTMhKo1RdrbmKVFmja4BWjnUCQ11fQhR88V4t1KoKmHaMA/q+IaoVuvPxQAATanJQ9UrM9ZAW8HsSER1w7SqAr3Sj9Q80rbpy7V+Itr2g2VlGQLPHgMAHGrUFibaagxN2KPrQya0CI77Wa/fvD/newyL/wX26hu19mtXWlhrnSHKjM1gVVFy/4Z/6pdyCHP2r8GOZgGY123MQ+2TiOh5wt9K76HsrANEpTGUTa7e8XVT5/yaL+9LdobKJwfKJldg4pSP/P/5oDpfBeN6apSecYCm7OY8ir+uONgFnsbV7zsi59vOsPC9CCPrUmhKTVGZZYvqYjM0GHX4ges1cSyEOs4NBUc8YWxTArmqEuZud79iUn7JDuWXap6Uoik1gbZKgYIjngBqJpubudY+oRMR3U3g2WOwrCzT+16LW8U5e+O60hoDk6Pxs09n7G3SAfFOXvj0f2vhlp+Dc/VcEHjmGGzKauZR3HrF4f8C38e27z/Gnm8/wGbfnrho7Yj6pQVom5UKp+LreHXU1w9cb6KjJ96Oi8IHRzYj08YJ11U2OOpW+3HkAOCbnYZ/RIYh39wSR9x8EZQcrfd6rLMPLt3puzaIiJ5jDBr3UJLsDJmRBmbud55HIZMB5h65KEl2hqbMGArzKrzwxgnc+LU51Ked//zCviuw9j+Dq9930j3GFgBM6qvhGPIbCmO8UJLoAk2ZCRTKCpg4FMHav/YXARrCxv8MNEXmKDrmAVFpDFPXvHsHjcx6KIzx0lunm5zun86gQUQPZGByNMqNTHD4Lrc3CZkcBzzaY2ByNGzKilBgboWRb4Qi9Nc1GHT6VwiZHHuadMQy/2HY/v10VBj99bCLs/Ubon/IMkyO2Yg3En+FTVkx8pTWSHLwwHL/oQ9V7wr/t+BclItxx/4Ly8oy/O7a4q5Bo0neJZhqqmFaWoglu5fXen1an8kMGkREt5EJIQy6sV/Z5CW8MOizx13PM6k03QHXdvjBYfgRmLnk13U5dBe5//0cPXwcsGvXrrouhZ5yYWFhmPHp/8F50ta6LuWp1DP9KNbs+AKDhi9GrEuzui6H7qLo+A5UHN+CEnVxXZdCRE8oztGQmLZK/y0VWqD4pDtkJlUwcXi4+4iJiJ5VplUVestyrQYhJ39CkYkSpx0a11FVREQkBd46JbH8/c2hrVbAtEE+oKmZTF6RZQebzqm1vl+DiOh5N3f/aphVV+Bkg6Yw0VShd/pR+GWlYHHnYFQY135YBhERPT0YNCRm5paHouMeKDv7AoRGDmObUtj2OA2rdpn335iI6DlzxK0V3j2+A93OnoCpphKZNg3wWY9x+K5d/7oujYiIHhGDhsRUzbKhapZd12UQET0VdjULwK5mAXVdBhERPQaco0FERERERJJj0CAiIiIiIskxaBARERERkeQYNIiIiIiISHIMGkREREREJDkGDSIiIiIikhyDBhERERERSY5Bg4iIiIiIJMegQUREREREkmPQICIiIiIiyTFoEBERERGR5Bg0iIiIiIhIcgwaREREREQkOQYNIiIiIiKSHIMGERERERFJjkGDiIiIiIgkx6BBRERERESSY9AgIiIiIiLJMWgQEREREZHkGDSIiIiIiEhyDBpERERERCQ5Bg0iIiIiIpIcgwYREREREUmOQYOIiIiIiCTHoEFERERERJJj0CAiIiIiIskxaBARERERkeQYNIiIiIiISHIMGkREREREJDkGDSIiIiIikhyDBhERERERSY5Bg4iIiIiIJMegQUREREREkmPQICIiIiIiyTFoEBERERGR5Bg0iIiIiIhIcgYHDVF8DdqK0sdZC1Gd0VaUQhRfg1KprOtS6BmgVCqhqapAVcGVui6F6LEQQouqvEsw55hJRPdgcNDQFuTg6rfjURwXhcprFyC0msdZ1yNTJ+7HxWVDdMsFv32P7PCJj3Uf9HQRWg0qr11AcVwUrn47HtqCHAQHB9d1WfQM6Nu3LxxecMDVbycg/9B6VGSlQFtVXtdlET0SIQSqC6+iJPU3XNswDepTezHh/ffquiwieoIZGdowLTUFk6dMwc4fvwEAKExMYfqCB2Q2DSA3s6j1IzMygUyuAGRyyGRyQCbT9VUQswkKCztY+vbClfVTUf+1T2FkYYdq9Q1c3/EF6vX9CMZ2znr7z9v7DYxtG8CqfZBB9VYV5ABaDSqy0wAA1cV5EFUVumUp3L4PenRCUwV1wl6UX0yAprQIRlb1Ydm2P0wbeAMAihP2QKO+ARv/ocjdPh/Wnd6CqaPnLR0ICKEFhBZCq4GoroS2XF3rRxRkoyL3PDSVFQCAgUFBWLZ0Kdzd3evgqOlZ4+rqijPpaZg/fz6WLl2GoqNbIJPJYfZCQ8jsGkJhblV7zDQ2qxkz5TfHzKfvztaCmE0oP/9HzYJMDoXSBmZurWDRujdkCuO6LY7uTAgIIQChAbRaCE0VtBUltcfN4muozj2PypJCAEDLVr5YufkQXnnllTo+ACJ6ksmEEOJBNigqKkJcXBxiY2MRGxuLM+fO48aNGygoKEBRQQGqqiofV61ED83Y2ARWNjawsbGBnZ0dmjT2QLt27dCuXTu0adMGVlZWdV0iPaMqKipw+vRp3ZiZlJyC63l5KCgoRFFhPspKeUsqPXnkCgUsraxhY2MLO1tbuDg76cbMdu3awcnJqa5LJKKnwAMHjXsRQqC8vBz5+fkoLy9HdXU1NBoNqqur9drNnj0bDRo0wPjx49GqVSvs3r0bzs7OyMrKwquvvoqtW7eiadOmetuMGjUK3t7emDFjBgCgsrISK1aswC+//IKioiJ4enpiypQpaN++PQBg586dWLx4MWJiYgAA33zzDQ4cOIAffvgBAKDVarFmzRps27YN+fn58PDwwKRJk/Dyyy8bfLw393Hz58qVK2jTpg3mzZsHe3t7g/bz0UcfoX79+vjkk08AAIsWLcL333+PnTt3olGjRqiqqoK/vz9WrFiBDh061KqhoKAACxYswMmTJ1FUVAQXFxeMGTMGffr00XvvPD09oVAoEBkZiSZNmmDt2rU4c+YMwsLCcPLkSZibm6NTp06YPn06bG1ta+2ntLQU3bt3x9y5c9GzZ0/d+v/973+YOXMmDhw4AJVKhfT0dCxatAinTp2CmZkZevTogenTp+vmPtz+9wgAkyZNgqWlJebPn19rv8nJyXjrrbewd+9eODo64ptvvkF2djbmz5+P3r17Y968ebq/85uMjIygUChgZGQEMzMz2Nrawtzc3OC/V6K/U2VlJQoKCqBWq6HRaHRjpoRD899m9uzZKC4uxvLly3XrpkyZgqysLGzduhVarRbffvsttm3bhry8PLi5uWHs2LG6MaWoqAgLFizA0aNHUVpaCgcHB4wZMwZBQUG688OiRYuwceNGpKSkwNXVFZ9++in8/Px0+/vjjz8QFhaGtLQ0WFtbY8CAAfjggw9gZFRzAX/UqFHw8vKCiYkJtm/fDmNjYwwePBjjx48HUHMeW7VqFX788Ufk5eXBxsYGgYGBmDlzJoD7n3ueRgqFQjdmGhsbw8bGBpaWlpDdcicCEdFDEXUgJCREhIaGij9DjsjIyBBCCJGRkSEAiLi4uFrbdOnSRUyaNEm3PGbMGNGpUydx6NAhcfbsWbFkyRJhamoq0tPThRBChIeHC2tra1370NBQ4evrq1sOCwsTVlZWYtOmTSI1NVV8/PHHwtjYWLe9IcLDw4WxsbHo0aOHOHHihIiNjRU+Pj5i2LBhBu9nxYoVonnz5rr2rVu3FvXr1xerVq0SQgjx22+/CWNjY1FSUnLHGi5fviyWLFki4uLixLlz58SKFSuEQqEQx44d03vvLCwsxPTp00VqaqpITU0V+fn5wt7eXsyaNUukpKSIkydPisDAQNG1a9e7Hu+7774r+vTpo7duwIABIjg4WAghhFqtFk5OTuL1118XiYmJ4tdffxWNGjUSISEherXc+vcohBADBw7Ua3NTeXm56NmzpwgMDNStCw0N1bV1c3MTBw4cuGu9RPT3CgkJEQMHDtQtJyYmCkdHR/HSSy8JIYSYP3++aNq0qfjll1/EuXPnRHh4uDA1NRXR0dFCCCEmTJggWrduLU6cOCEyMjLEvn37xK5du4QQf50fXFxcxLZt20RycrIYM2aMsLS0FNevXxdC1IyHSqVSjB8/XqSkpIgdO3aI+vXr6843QtSMQVZWVmLOnDkiPT1dRERECJlMJvbu3SuEEOKHH34QVlZWIioqSmRmZopjx46JNWvW6La/37mHiIj+UidB425unkjMzc2FSqXS+5HL5bpfUDMzM4VCoRBZWVl623fv3l3MmjVLCHH/oNGgQQPxxRdf6G3fvn17MX78eIPrDQ8PFwDE2bNndetWrlwpHBwcDN7PqVOnhEwmE7m5ueLGjRvCxMREzJs3TwwZMkQIUXNi7tSpk8E1CSFE3759xdSpU3XLXbp0EW3atNFrM2/ePNGzZ0+9dZcuXRIARFpa2h37PXbsmFAoFCI7O1sIIcTVq1eFkZGR7peENWvWCFtbW6FWq3XbREZGCrlcLq5cuaKrxZCgUVVVJXr27Ck6deokCgsLDT94IqozISEhQqFQCJVKJUxNTQUAIZfLxbZt20R5eblQKpXiyJEjetuMHj1aDB06VAghRP/+/cXIkSPv2PfN88PChQt166qqqoSLi4tYtGiREEKITz75RHh7ewutVqtrs3LlSmFhYSE0Go0QomYMevnll/X6bt++vZgxY4YQQoh//OMfwsvLS1RWVtaqwZBzDxER/cXgyeB/py1btsDHx0dv3fDhw3V/TkxMhEajgZeXl16biooK1KtX7779FxUVITs7G/7+/nrr/f39kZCQ8EC1KpVKNG7cWLfs5OSE3Nxcg/fTokUL2NnZ4eDBgzAxMUGbNm3Qr18/rFy5EgBw8OBBBAQE3HX/Go0GCxYswNatW5GVlYXKykpUVFTUekxru3bt9JYTEhJw4MABWFhY1Orz3Llztd5bAHjxxRfRvHlzREREYObMmdiwYQPc3NzQuXNnAEBKSgp8fX2hUqn0jlWr1SItLQ0ODg53PY7b7dixA7/99hsuX77M+RNET5GuXbti1apVKCkpwdKlS2FkZIRBgwYhKSkJpaWlCAwM1GtfWVmJNm3aAADef/99DBo0CCdPnkTPnj0RFBSETp066bXv2LGj7s9GRkbw8/NDSkoKgJoxqGPHjnq3/Pj7+0OtVuPy5cto2LAhAKBVq1Z6fd46bg8ePBjLli2Dh4cHevfujT59+qB///4wMjJ65HMPEdHz5okMGq6urvD09NRbd+s99mq1GgqFArGxsVAoFHrt7vSL8+NkbKz/JBWZTPZA91bLZDJ07twZ0dHRMDU1RUBAAFq1aqWbQHrkyBFMmzbtrtsvWbIEy5cvx7Jly9CyZUuoVCpMnjwZlZX6k/Jv/eUfqHkP+/fvj0WLFtXq816T/MaMGYOVK1di5syZCA8Px8iRIx/oPl65XF7r/amqqqrVLjs7G/b29necL0JETy6VSqUbv7/99lv4+vpi7dq1aNGiBQAgMjISzs76TxU0NTUFALz66qvIzMxEVFQU9u3bh+7du2PChAn46quvJK3xTuO2VqsFUHP+SUtLw/79+7Fv3z6MHz8eS5YswcGDB5+ocw8R0dPg6Xt+IoA2bdpAo9EgNzcXnp6eej+Ojo733d7KygoNGjTQTRS/KSYmBs2aNZOsTkP306VLF0RHRyM6OhoBAQGQy+Xo3LkzlixZgoqKilpXRG7va+DAgXj77bfh6+sLDw8PpKen37e2tm3bIikpCe7u7rXew9tDya3efvttZGZmYsWKFUhOTkZISIjuNR8fHyQkJKCkpESvPrlcDm/vmsfT2tvbIycnR/e6RqPB6dOna+1n6NCh+Omnn+57HET05JLL5fjkk08we/ZsNGvWDKamprh48WKtMcfV1VW3jb29PUJCQrBhwwYsW7YMa9as0evz999/1/25uroasbGxuivgPj4+OHr0qN6HGTExMbC0tISLi4vBdZubm6N///5YsWIFoqOjcfToUSQmJj7yuYeI6HnzVAYNLy8vDB8+HMHBwdi+fTsyMjJw/PhxfPnll4iMjDSoj+nTp2PRokXYsmUL0tLSMHPmTMTHx2PSpEmS1mrIfgICApCcnIykpCTd06gCAgLw/fffw8/P756/+Ddp0gT79u3DkSNHkJKSgnHjxuHq1av3rWvChAm4ceMGhg4dihMnTuDcuXPYs2cPRo4cCY3m7l/GaGtri9dffx3Tp09Hz5499U7ew4cPh5mZGUJCQnD69GkcOHAAEydOxDvvvKO7bapbt26IjIxEZGQkUlNT8f7776OgoKDWfrZu3YrJkyff9ziI6Mk2ePBgKBQKrF69GtOmTcOUKVMQERGBc+fO4eTJk/jnP/+JiIgIAMBnn32GnTt34uzZs0hKSsLPP/9c6zbalStXYseOHUhNTcWECROQn5+PUaNGAQDGjx+PS5cuYeLEiUhNTcXOnTsRGhqKjz76CHK5Yae7devWYe3atTh9+jTOnz+PDRs2wNzcHG5ubpKce4iInidP5K1ThggPD8f8+fMxdepUZGVloX79+ujQoQP69etn0PYffvghCgsLMXXqVOTm5qJZs2bYtWsXmjRpomsTEBAAd3d3rFu37qHrNGQ/LVu2hI2NDby8vHSX3wMCAqDRaO45PwOoeZzk+fPn0atXLyiVSowdOxZBQUEoLCy853Y3r7TMmDEDPXv2REVFBdzc3NC7d+/7npBHjx6NjRs36k7uNymVSuzZsweTJk1C+/btoVQqMWjQIISFhenajBo1CgkJCQgODoaRkRGmTJmCrl271trH9evXce7cuXvWQURPPiMjI3zwwQdYvHgxMjIyYG9vjy+//BLnz5+HjY0N2rZtq3u8t4mJCWbNmoULFy7A3Nwcr7zyCjZv3qzX38KFC7Fw4ULEx8fD09MTu3btQv369QEAzs7OiIqKwvTp0+Hr6ws7OzuMHj0as2fPNrheGxsbLFy4EB999BE0Gg1atmyJn376STcH41HPPUREzxNJv0fjWePm5oa5c+dixIgRdV3KE2X9+vWYMmUKsrOzYWJiUtflENFz4MKFC2jUqBHi4uLQunXrui6HiIgM8NRe0XjckpKSYG1tjeDg4Lou5YlRWlqKnJwcLFy4EOPGjWPIICIiIqK7eirnaPwdmjdvjlOnThl8X+/zYPHixWjatCkcHR0xa9asui6HiIiIiJ5gvHWKiIiIiIgkx4/riYiIiIhIcgwaREREREQkOQYNIiIiIiKSHIMGERERERFJjkGDiIiIiIgkx6BBRERERESSY9AgIiIiIiLJMWgQEREREZHkGDSIiIiIiEhyDBpERERERCQ5Bg0iIiIiIpIcgwYREREREUmOQYOIiIiIiCTHoEFERERERJJj0CAiIiIiIskxaBARERERkeQYNJ4BMpkMP/74Y12XQUTPuDVr1sDV1RVyuRzLli3DnDlz0Lp167ouCwBw4cIFyGQyxMfHP/Z9ccwlIjIMg8YDunLlCiZNmgRPT0+YmZnBwcEB/v7+WLVqFUpLSx/rvu92Us/JycGrr776WPdNRHVrxIgRmDNnDoCaX3QvXLgAoPYv2DeXpVZUVIQPPvgAM2bMQFZWFsaOHYtp06bh119/lXxf9zNixAgEBQX97ft9GtwegqKjo+Hu7g5A/98QEdHfwaiuC3ianD9/Hv7+/rCxscGCBQvQsmVLmJqaIjExEWvWrIGzszMGDBhQa7uqqioYGxs/trocHR0fW99ERABw8eJFVFVVoW/fvnByctKtt7CwqMOqiIjoScYrGg9g/PjxMDIywh9//IE333wTPj4+8PDwwMCBAxEZGYn+/fsDqPlEadWqVRgwYABUKhW++OILAMDOnTvRtm1bmJmZwcPDA3PnzkV1dbWu/4KCAowZMwb29vawsrJCt27dkJCQAABYt24d5s6di4SEBMhkMshkMqxbt063v5ufYN38NHP79u3o2rUrlEolfH19cfToUb1j+fe//w1XV1colUq89tprCAsLg42NzeN9A4nob7du3TrY2Njg559/hre3N5RKJd544w2UlpYiIiIC7u7usLW1xYcffgiNRnPXPlq2bAkA8PDw0F1Ruf0q680rDV999RWcnJxQr149TJgwAVVVVbo2FRUVmDZtGpydnaFSqfDSSy8hOjra4OOZM2cOIiIisHPnTt1YeOv258+fv+vYl5eXh6FDh8LZ2RlKpRItW7bEpk2b9PoPCAjAhx9+iI8//hh2dnZwdHS871WA0NBQODk54dSpU7Veu3DhAuRyOf744w+99cuWLYObmxu0Wi0A4ODBg3jxxRdhamoKJycnzJw5U+/84O7ujmXLlun10bp1a16hIKInGoOGgfLy8rB3715MmDABKpXqjm1uvV1hzpw5eO2115CYmIhRo0bh8OHDCA4OxqRJk5CcnIzVq1dj3bp1uhACAIMHD0Zubi52796N2NhYtG3bFt27d8eNGzcwZMgQTJ06Fc2bN0dOTg5ycnIwZMiQu9b76aefYtq0aYiPj4eXlxeGDh2qO2nFxMTgvffew6RJkxAfH4/AwEC9Oojo2VJaWooVK1Zg8+bN+OWXXxAdHY3XXnsNUVFRiIqKwvr167F69Wps27btjtsPGTIE+/fvBwAcP34cOTk5cHV1vWPbAwcO4Ny5czhw4AAiIiKwbt063YciAPDBBx/g6NGj2Lx5M06dOoXBgwejd+/eOHPmjEHHMm3aNLz55pvo3bu3bizs1KmT7vV7jX3l5eVo164dIiMjcfr0aYwdOxbvvPMOjh8/rrePiIgIqFQqHDt2DIsXL8bnn3+Offv21apFCIGJEyfiu+++w+HDh9GqVatabdzd3dGjRw+Eh4frrQ8PD8eIESMgl8uRlZWFPn36oH379khISMCqVauwdu1azJ8/36D3hIjoiSXIIL///rsAILZv3663vl69ekKlUgmVSiU+/vhjIYQQAMTkyZP12nXv3l0sWLBAb9369euFk5OTEEKIw4cPCysrK1FeXq7XpnHjxmL16tVCCCFCQ0OFr69vrdoAiB07dgghhMjIyBAAxH/+8x/d60lJSQKASElJEUIIMWTIENG3b1+9PoYPHy6sra0NeCeI6Ely8/98XFzcHV8PDw8XAMTZs2d168aNGyeUSqUoLi7WrevVq5cYN27cXfcTFxcnAIiMjAzdutvHpJCQEOHm5iaqq6t16wYPHiyGDBkihBAiMzNTKBQKkZWVpdd39+7dxaxZsww5XN1+Bg4cqLfOkLHvTvr27SumTp2qW+7SpYt4+eWX9dq0b99ezJgxQ7cMQPzwww9i2LBhwsfHR1y+fPme9W7ZskXY2trqxvfY2Fghk8l07+Unn3wivL29hVar1W2zcuVKYWFhITQajRBCCDc3N7F06VK9fn19fUVoaKjeulvPB0REdY1XNB7R8ePHER8fj+bNm6OiokK33s/PT69dQkICPv/8c1hYWOh+3n33XeTk5KC0tBQJCQlQq9WoV6+eXpuMjAycO3fugeu69ZO1m/dT5+bmAgDS0tLw4osv6rW/fZmInh1KpRKNGzfWLTs4OMDd3V1vfoWDg4NujHgUzZs3h0Kh0C07OTnp+k1MTIRGo4GXl5feOHfw4MGHGufu5F5jn0ajwbx589CyZUvY2dnBwsICe/bswcWLF+/ax+3HcNOUKVNw7NgxHDp0CM7OzvesKSgoCAqFAjt27ABQcyta165ddZO0U1JS0LFjR72r4v7+/lCr1bh8+fIDHD0R0ZOFk8EN5OnpCZlMhrS0NL31Hh4eAABzc3O99bffXqVWqzF37ly8/vrrtfo2MzODWq2Gk5PTHe9Vfpi5E7dOPr958rp5LzARPV9ufxiFTCa74zopxoh79atWq6FQKBAbG6sXRgDpJpXfa+xbsmQJli9fjmXLlqFly5ZQqVSYPHkyKisrDT6GmwIDA7Fp0ybs2bMHw4cPv2dNJiYmCA4ORnh4OF5//XVs3LgRy5cvf6DjksvlEELorbt17gsR0ZOIQcNA9erVQ2BgIL7++mtMnDjxrvM07qZt27ZIS0uDp6fnXV+/cuUKjIyMdJ9y3c7ExOSukzUfhLe3N06cOKG37vZlIiKptWnTBhqNBrm5uXjllVceup+HHQtjYmIwcOBAvP322wBqAkh6ejqaNWv2wH0NGDAA/fv3x7Bhw6BQKPDWW2/ds/2YMWPQokULfPPNN6iurtb70MnHxwf//e9/IYTQhaOYmBhYWlrCxcUFAGBvb4+cnBzdNkVFRcjIyKi1n9vDCBFRXeKtUw/g5gnCz88PW7ZsQUpKCtLS0rBhwwakpqbW+oTuVp999hm+++47zJ07F0lJSUhJScHmzZsxe/ZsAECPHj3QsWNHBAUFYe/evbhw4QKOHDmCTz/9VPe0End3d2RkZCA+Ph7Xr1/Xu1XrQUycOBFRUVEICwvDmTNnsHr1auzevfuxPHufiOgmLy8vDB8+HMHBwdi+fTsyMjJw/PhxfPnll4iMjDS4H3d3d5w6dQppaWm4fv26wZ/sN2nSBPv27cORI0eQkpKCcePG4erVqw97OHjttdewfv16jBw58q4T6W/y8fFBhw4dMGPGDAwdOlTvKvj48eNx6dIlTJw4Eampqdi5cydCQ0Px0UcfQS6vOU1369YN69evx+HDh5GYmIiQkJBa55ysrCw0bdq0Tr7bhIjoThg0HkDjxo0RFxeHHj16YNasWfD19YWfnx/++c9/Ytq0aZg3b95dt+3Vqxd+/vln7N27F+3bt0eHDh2wdOlSuLm5Aai5NB8VFYXOnTtj5MiR8PLywltvvYXMzEw4ODgAAAYNGoTevXuja9eusLe3r/VYRkP5+/vjX//6F8LCwuDr64tffvkFU6ZMgZmZ2UP1R0RkqPDwcAQHB2Pq1Knw9vZGUFAQTpw4gYYNG+ra3Pr47jt599134e3tDT8/P9jb2yMmJsagfc+ePRtt27ZFr169EBAQAEdHx0f+4r833ngDEREReOedd7B9+/Z7th09ejQqKysxatQovfXOzs6IiorC8ePH4evri/feew+jR4/WfRAFALNmzUKXLl3Qr18/9O3bF0FBQXrzboCaW6nS0tJQXFz8SMdERCQVmeB1VkLNiTs1NRWHDx+u61KI6DmWkZEBLy8vJCcno0mTJnVdjqTmzZuHH3744Y7ft0FE9CziHI3n1FdffYXAwECoVCrs3r0bERER+Oabb+q6LCJ6zkVFRWHs2LHPVMhQq9W4cOECvv76a343BhE9V3hF4zn15ptvIjo6GsXFxfDw8MDEiRPx3nvv1XVZRETPnBEjRmDTpk0ICgrCxo0b7zmfj4joWcKgQUREREREkuNkcCIiIiIikhyDBhERERERSY5Bg4iIiIiIJMegQUREREREkmPQICIiIiIiyTFoEBERERGR5Bg0iIiIiIhIcgwaREREREQkOQYNIiIiIiKSHIMGERERERFJjkGDiIiIiIgkx6BBRERERESSY9AgIiIiIiLJMWgQEREREZHkGDSIiIiIiEhyDBpERERERCQ5Bg0iIiIiIpIcgwYREREREUmOQYOIiIiIiCTHoEFERERERJJj0CAiIiIiIskxaBARERERkeQYNIiIiIiISHIMGkREREREJDkGDSIiIiIiktz/A0/x9tng3v+UAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33muser_proxy\u001b[0m (to chatbot):\n", + "\n", + "\u001b[32m***** Response from calling function \"python\" *****\u001b[0m\n", + "(0.0, 1.0, 0.0, 1.0)\n", + "\u001b[32m***************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mchatbot\u001b[0m (to user_proxy):\n", + "\n", + "TERMINATE\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "llm_config = {\n", + " \"functions\": [\n", + " {\n", + " \"name\": \"python\",\n", + " \"description\": \"run cell in ipython and return the execution result.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"cell\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"Valid Python cell to execute.\",\n", + " }\n", + " },\n", + " \"required\": [\"cell\"],\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"sh\",\n", + " \"description\": \"run a shell script and return the execution result.\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"script\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"Valid shell script to execute.\",\n", + " }\n", + " },\n", + " \"required\": [\"script\"],\n", + " },\n", + " },\n", + " ],\n", + " \"config_list\": config_list,\n", + " \"request_timeout\": 120,\n", + "}\n", + "chatbot = autogen.AssistantAgent(\n", + " name=\"chatbot\",\n", + " system_message=\"For coding tasks, only use the functions you have been provided with. Reply TERMINATE when the task is done.\",\n", + " llm_config=llm_config,\n", + ")\n", + "\n", + "# create a UserProxyAgent instance named \"user_proxy\"\n", + "user_proxy = autogen.UserProxyAgent(\n", + " name=\"user_proxy\",\n", + " is_termination_msg=lambda x: x.get(\"content\", \"\") and x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n", + " human_input_mode=\"NEVER\",\n", + " max_consecutive_auto_reply=10,\n", + " code_execution_config={\"work_dir\": \"coding\"},\n", + ")\n", + "\n", + "# define functions according to the function desription\n", + "from IPython import get_ipython\n", + "\n", + "def exec_python(cell):\n", + " ipython = get_ipython()\n", + " result = ipython.run_cell(cell)\n", + " log = str(result.result)\n", + " if result.error_before_exec is not None:\n", + " log += f\"\\n{result.error_before_exec}\"\n", + " if result.error_in_exec is not None:\n", + " log += f\"\\n{result.error_in_exec}\"\n", + " return log\n", + "\n", + "def exec_sh(script):\n", + " return user_proxy.execute_code_blocks([(\"sh\", script)])\n", + "\n", + "# register the functions\n", + "user_proxy.register_function(\n", + " function_map={\n", + " \"python\": exec_python,\n", + " \"sh\": exec_sh,\n", + " }\n", + ")\n", + "\n", + "# start the conversation\n", + "user_proxy.initiate_chat(\n", + " chatbot,\n", + " message=\"Draw two agents chatting with each other with an example dialog. Don't add plt.show().\",\n", + ")\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "e9531d55", + "metadata": {}, + "source": [ + "## Another example with Wolfram Alpha API\n", + "\n", + "We give another example of querying Wolfram Alpha API to solve math problem. We use the predefined function `MathUserProxyAgent().execute_one_wolfram_query` as the function to be called." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4a917492", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33muser_proxy\u001b[0m (to chatbot):\n", + "\n", + "Problem: Find all $x$ that satisfy the inequality $(2x+10)(x+3)<(3x+9)(x+8)$. Express your answer in interval notation.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mchatbot\u001b[0m (to user_proxy):\n", + "\n", + "\u001b[32m***** Suggested function Call: query_wolfram *****\u001b[0m\n", + "Arguments: \n", + "{\n", + " \"query\": \"solve (2x+10)(x+3)<(3x+9)(x+8) for x\"\n", + "}\n", + "\u001b[32m**************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[35m\n", + ">>>>>>>> EXECUTING FUNCTION query_wolfram...\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33muser_proxy\u001b[0m (to chatbot):\n", + "\n", + "\u001b[32m***** Response from calling function \"query_wolfram\" *****\u001b[0m\n", + "('Assumption: solve (2 x + 10) (x + 3)<(3 x + 9) (x + 8) for x \\nAnswer: ans 0: x<-14\\nans 1: x>-3\\n', True)\n", + "\u001b[32m**********************************************************\u001b[0m\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mchatbot\u001b[0m (to user_proxy):\n", + "\n", + "The solution to the inequality $(2x+10)(x+3)<(3x+9)(x+8)$ is $x \\in (-\\infty, -14) \\cup (-3, +\\infty)$. TERMINATE\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33muser_proxy\u001b[0m (to chatbot):\n", + "\n", + "\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mchatbot\u001b[0m (to user_proxy):\n", + "\n", + "TERMINATE\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "import os\n", + "from autogen.agentchat.contrib.math_user_proxy_agent import MathUserProxyAgent\n", + "\n", + "# you need to provide a wolfram alpha appid to run this example\n", + "if not os.environ.get(\"WOLFRAM_ALPHA_APPID\"):\n", + " os.environ[\"WOLFRAM_ALPHA_APPID\"] = open(\"wolfram.txt\").read().strip()\n", + "\n", + "llm_config = {\n", + " \"model\": \"gpt-4-0613\",\n", + " \"functions\": [\n", + " {\n", + " \"name\": \"query_wolfram\",\n", + " \"description\": \"Return the API query result from the Wolfram Alpha. the ruturn is a tuple of (result, is_success).\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"query\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"The Wolfram Alpha code to be executed.\",\n", + " }\n", + " },\n", + " \"required\": [\"query\"],\n", + " },\n", + " }\n", + " ],\n", + " \"config_list\": config_list,\n", + "}\n", + "chatbot = autogen.AssistantAgent(\n", + " name=\"chatbot\",\n", + " system_message=\"Only use the functions you have been provided with. Do not ask user to perform other actions than executing the functions. Reply TERMINATE when the task is done.\",\n", + " llm_config=llm_config,\n", + ")\n", + "\n", + "# the key in `function_map` should match the function name in \"functions\" above\n", + "# we register a class instance method directly\n", + "user_proxy = autogen.UserProxyAgent(\n", + " \"user_proxy\",\n", + " max_consecutive_auto_reply=2,\n", + " human_input_mode=\"NEVER\",\n", + " function_map={\"query_wolfram\": MathUserProxyAgent().execute_one_wolfram_query},\n", + ")\n", + "\n", + "# start the conversation\n", + "user_proxy.initiate_chat(\n", + " chatbot,\n", + " message=\"Problem: Find all $x$ that satisfy the inequality $(2x+10)(x+3)<(3x+9)(x+8)$. Express your answer in interval notation.\",\n", + ")\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/expt/call_functions_with_chat_models.ipynb b/expt/call_functions_with_chat_models.ipynb new file mode 100644 index 0000000..c5b436f --- /dev/null +++ b/expt/call_functions_with_chat_models.ipynb @@ -0,0 +1,284 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "64c85e26", + "metadata": {}, + "source": [ + "## How to generate function arguments" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "80e71f33", + "metadata": { + "pycharm": { + "is_executing": true + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: scipy in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (1.11.1)\n", + "Requirement already satisfied: numpy<1.28.0,>=1.21.6 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from scipy) (1.26.0)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Requirement already satisfied: tenacity in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (8.2.3)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Requirement already satisfied: tiktoken in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (0.4.0)\n", + "Requirement already satisfied: regex>=2022.1.18 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from tiktoken) (2023.8.8)\n", + "Requirement already satisfied: requests>=2.26.0 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from tiktoken) (2.31.0)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.26.0->tiktoken) (3.2.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.26.0->tiktoken) (3.4)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.26.0->tiktoken) (2.0.4)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.26.0->tiktoken) (2023.7.22)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Requirement already satisfied: termcolor in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (2.3.0)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Requirement already satisfied: openai in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (0.27.10)\n", + "Requirement already satisfied: requests>=2.20 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from openai) (2.31.0)\n", + "Requirement already satisfied: tqdm in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from openai) (4.66.1)\n", + "Requirement already satisfied: aiohttp in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from openai) (3.8.5)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.20->openai) (3.2.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.20->openai) (3.4)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.20->openai) (2.0.4)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests>=2.20->openai) (2023.7.22)\n", + "Requirement already satisfied: attrs>=17.3.0 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from aiohttp->openai) (23.1.0)\n", + "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from aiohttp->openai) (6.0.4)\n", + "Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from aiohttp->openai) (4.0.3)\n", + "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from aiohttp->openai) (1.9.2)\n", + "Requirement already satisfied: frozenlist>=1.1.1 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from aiohttp->openai) (1.4.0)\n", + "Requirement already satisfied: aiosignal>=1.1.2 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from aiohttp->openai) (1.3.1)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Requirement already satisfied: requests in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (2.31.0)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests) (3.2.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests) (3.4)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests) (2.0.4)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /Users/shrutipatel/projects/work/repo-gpt/.venv/lib/python3.11/site-packages (from requests) (2023.7.22)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" + ] + } + ], + "source": [ + "!pip install scipy\n", + "!pip install tenacity\n", + "!pip install tiktoken\n", + "!pip install termcolor \n", + "!pip install openai\n", + "!pip install requests" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "dab872c5", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import openai\n", + "import requests\n", + "from tenacity import retry, wait_random_exponential, stop_after_attempt\n", + "from termcolor import colored\n", + "\n", + "GPT_MODEL = \"gpt-3.5-turbo-0613\"\n", + "openai_key = \"\"\n", + "openai.api_key = openai_key" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d567ddf6-98b8-4270-b602-d2ca86faffbd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The autoreload extension is already loaded. To reload it, use:\n", + " %reload_ext autoreload\n" + ] + } + ], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "8f75fcf7-ba08-4c4b-8602-6042122b302a", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "error_code=context_length_exceeded error_message=\"This model's maximum context length is 4097 tokens. However, your messages resulted in 20735 tokens (108 in the messages, 20627 in the functions). Please reduce the length of the messages or functions.\" error_param=messages error_type=invalid_request_error message='OpenAI API error received' stream_error=False\n", + "Unable to generate ChatCompletion response\n", + "Exception: This model's maximum context length is 4097 tokens. However, your messages resulted in 20735 tokens (108 in the messages, 20627 in the functions). Please reduce the length of the messages or functions.\n" + ] + }, + { + "ename": "InvalidRequestError", + "evalue": "This model's maximum context length is 4097 tokens. However, your messages resulted in 20735 tokens (108 in the messages, 20627 in the functions). Please reduce the length of the messages or functions.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mInvalidRequestError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[7], line 21\u001b[0m\n\u001b[1;32m 16\u001b[0m root_path \u001b[38;5;241m=\u001b[39m Path(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/Users/shrutipatel/projects/work/repo-gpt/\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 17\u001b[0m repo_agent \u001b[38;5;241m=\u001b[39m RepoUnderstandingAgent(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhere should I add tests for the new file handler I\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mm writing? Do I need to create a new test file? If so, where?\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 18\u001b[0m root_path,\n\u001b[1;32m 19\u001b[0m openai_key \u001b[38;5;241m=\u001b[39m openai_key,\n\u001b[1;32m 20\u001b[0m debug\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m---> 21\u001b[0m plan \u001b[38;5;241m=\u001b[39m \u001b[43mrepo_agent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprocess_messages\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 22\u001b[0m plan\n", + "File \u001b[0;32m~/projects/work/repo-gpt/src/repo_gpt/agents/base_agent.py:101\u001b[0m, in \u001b[0;36mBaseAgent.process_messages\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 95\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 97\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m (\n\u001b[1;32m 98\u001b[0m iter_count \u001b[38;5;241m<\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mthreshold\n\u001b[1;32m 99\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m function_call_name \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mterminating_function_call_name\n\u001b[1;32m 100\u001b[0m ):\n\u001b[0;32m--> 101\u001b[0m chat_response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mchat_completion_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 102\u001b[0m assistant_message \u001b[38;5;241m=\u001b[39m chat_response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mchoices\u001b[39m\u001b[38;5;124m\"\u001b[39m][\u001b[38;5;241m0\u001b[39m][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessage\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 103\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_append_message(assistant_message\u001b[38;5;241m.\u001b[39mto_dict_recursive())\n", + "File \u001b[0;32m~/projects/work/repo-gpt/src/repo_gpt/agents/base_agent.py:73\u001b[0m, in \u001b[0;36mBaseAgent.chat_completion_request\u001b[0;34m(self, function_call, model)\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mchat_completion_request\u001b[39m(\u001b[38;5;28mself\u001b[39m, function_call\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mauto\u001b[39m\u001b[38;5;124m\"\u001b[39m, model\u001b[38;5;241m=\u001b[39mGPT_MODEL):\n\u001b[1;32m 72\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 73\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mopenai\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mChatCompletion\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 74\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 75\u001b[0m \u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmemory_store\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 76\u001b[0m \u001b[43m \u001b[49m\u001b[43mfunctions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunctions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 77\u001b[0m \u001b[43m \u001b[49m\u001b[43mfunction_call\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfunction_call\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 78\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 79\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n\u001b[1;32m 80\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[0;32m~/projects/work/repo-gpt/.venv/lib/python3.11/site-packages/openai/api_resources/chat_completion.py:25\u001b[0m, in \u001b[0;36mChatCompletion.create\u001b[0;34m(cls, *args, **kwargs)\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 25\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m TryAgain \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m time\u001b[38;5;241m.\u001b[39mtime() \u001b[38;5;241m>\u001b[39m start \u001b[38;5;241m+\u001b[39m timeout:\n", + "File \u001b[0;32m~/projects/work/repo-gpt/.venv/lib/python3.11/site-packages/openai/api_resources/abstract/engine_api_resource.py:153\u001b[0m, in \u001b[0;36mEngineAPIResource.create\u001b[0;34m(cls, api_key, api_base, api_type, request_id, api_version, organization, **params)\u001b[0m\n\u001b[1;32m 127\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[1;32m 128\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcreate\u001b[39m(\n\u001b[1;32m 129\u001b[0m \u001b[38;5;28mcls\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 136\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparams,\n\u001b[1;32m 137\u001b[0m ):\n\u001b[1;32m 138\u001b[0m (\n\u001b[1;32m 139\u001b[0m deployment_id,\n\u001b[1;32m 140\u001b[0m engine,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 150\u001b[0m api_key, api_base, api_type, api_version, organization, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparams\n\u001b[1;32m 151\u001b[0m )\n\u001b[0;32m--> 153\u001b[0m response, _, api_key \u001b[38;5;241m=\u001b[39m \u001b[43mrequestor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 154\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mpost\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 155\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 156\u001b[0m \u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 157\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 158\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 159\u001b[0m \u001b[43m \u001b[49m\u001b[43mrequest_id\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 160\u001b[0m \u001b[43m \u001b[49m\u001b[43mrequest_timeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 161\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 163\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m stream:\n\u001b[1;32m 164\u001b[0m \u001b[38;5;66;03m# must be an iterator\u001b[39;00m\n\u001b[1;32m 165\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(response, OpenAIResponse)\n", + "File \u001b[0;32m~/projects/work/repo-gpt/.venv/lib/python3.11/site-packages/openai/api_requestor.py:298\u001b[0m, in \u001b[0;36mAPIRequestor.request\u001b[0;34m(self, method, url, params, headers, files, stream, request_id, request_timeout)\u001b[0m\n\u001b[1;32m 277\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrequest\u001b[39m(\n\u001b[1;32m 278\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 279\u001b[0m method,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 286\u001b[0m request_timeout: Optional[Union[\u001b[38;5;28mfloat\u001b[39m, Tuple[\u001b[38;5;28mfloat\u001b[39m, \u001b[38;5;28mfloat\u001b[39m]]] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 287\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tuple[Union[OpenAIResponse, Iterator[OpenAIResponse]], \u001b[38;5;28mbool\u001b[39m, \u001b[38;5;28mstr\u001b[39m]:\n\u001b[1;32m 288\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrequest_raw(\n\u001b[1;32m 289\u001b[0m method\u001b[38;5;241m.\u001b[39mlower(),\n\u001b[1;32m 290\u001b[0m url,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 296\u001b[0m request_timeout\u001b[38;5;241m=\u001b[39mrequest_timeout,\n\u001b[1;32m 297\u001b[0m )\n\u001b[0;32m--> 298\u001b[0m resp, got_stream \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_interpret_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 299\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m resp, got_stream, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mapi_key\n", + "File \u001b[0;32m~/projects/work/repo-gpt/.venv/lib/python3.11/site-packages/openai/api_requestor.py:700\u001b[0m, in \u001b[0;36mAPIRequestor._interpret_response\u001b[0;34m(self, result, stream)\u001b[0m\n\u001b[1;32m 692\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m (\n\u001b[1;32m 693\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_interpret_response_line(\n\u001b[1;32m 694\u001b[0m line, result\u001b[38;5;241m.\u001b[39mstatus_code, result\u001b[38;5;241m.\u001b[39mheaders, stream\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 695\u001b[0m )\n\u001b[1;32m 696\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m line \u001b[38;5;129;01min\u001b[39;00m parse_stream(result\u001b[38;5;241m.\u001b[39miter_lines())\n\u001b[1;32m 697\u001b[0m ), \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 698\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 699\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m (\n\u001b[0;32m--> 700\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_interpret_response_line\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 701\u001b[0m \u001b[43m \u001b[49m\u001b[43mresult\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcontent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdecode\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mutf-8\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 702\u001b[0m \u001b[43m \u001b[49m\u001b[43mresult\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstatus_code\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 703\u001b[0m \u001b[43m \u001b[49m\u001b[43mresult\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 704\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 705\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m 706\u001b[0m \u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[1;32m 707\u001b[0m )\n", + "File \u001b[0;32m~/projects/work/repo-gpt/.venv/lib/python3.11/site-packages/openai/api_requestor.py:765\u001b[0m, in \u001b[0;36mAPIRequestor._interpret_response_line\u001b[0;34m(self, rbody, rcode, rheaders, stream)\u001b[0m\n\u001b[1;32m 763\u001b[0m stream_error \u001b[38;5;241m=\u001b[39m stream \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124merror\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mdata\n\u001b[1;32m 764\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m stream_error \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;241m200\u001b[39m \u001b[38;5;241m<\u001b[39m\u001b[38;5;241m=\u001b[39m rcode \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m300\u001b[39m:\n\u001b[0;32m--> 765\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandle_error_response(\n\u001b[1;32m 766\u001b[0m rbody, rcode, resp\u001b[38;5;241m.\u001b[39mdata, rheaders, stream_error\u001b[38;5;241m=\u001b[39mstream_error\n\u001b[1;32m 767\u001b[0m )\n\u001b[1;32m 768\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", + "\u001b[0;31mInvalidRequestError\u001b[0m: This model's maximum context length is 4097 tokens. However, your messages resulted in 20735 tokens (108 in the messages, 20627 in the functions). Please reduce the length of the messages or functions." + ] + } + ], + "source": [ + "from repo_gpt.agents.repo_comprehender import RepoUnderstandingAgent\n", + "from repo_gpt.agents.base_agent import BaseAgent\n", + "from repo_gpt.agents.simple_memory_store import MemoryStore\n", + "from repo_gpt.logging_config import configure_logging\n", + "import logging\n", + "import warnings\n", + "from pathlib import Path\n", + "\n", + "\n", + "from urllib3.exceptions import InsecureRequestWarning\n", + "\n", + "# Suppress only the single warning from urllib3\n", + "warnings.filterwarnings(\"ignore\", category=InsecureRequestWarning)\n", + "\n", + "configure_logging(logging.INFO)\n", + "root_path = Path(\"/Users/shrutipatel/projects/work/repo-gpt/\")\n", + "repo_agent = RepoUnderstandingAgent(\"Where should I add tests for the new file handler I'm writing? Do I need to create a new test file? If so, where?\",\n", + " root_path,\n", + " openai_key = openai_key,\n", + " debug=True)\n", + "plan = repo_agent.process_messages()\n", + "plan" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "418c4e61-0fa5-4268-a422-1ff624b97994", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef0b9161-405a-4235-911e-9179791e8cdc", + "metadata": {}, + "outputs": [], + "source": [ + "from repo_gpt.agents.code_writer import CodeWritingAgent\n", + "from repo_gpt.agents.central_intelligence import CentralIntelligenceAgent\n", + "\n", + "root_path = Path(\"/Users/shrutipatel/projects/work/repo-gpt/\")\n", + "embedding_file_path = root_path / \".repo_gpt/code_embeddings.pkl\"\n", + "writer_agent = CodeWritingAgent(plan, \n", + " root_path,\n", + " embedding_file_path,\n", + " openai_key = openai_key,\n", + " debug=True)\n", + "result = writer_agent.process_messages()\n", + "result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "803418c6-df34-4819-bae3-c3a1d03471a4", + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from repo_gpt.agents.central_intelligence import CentralIntelligenceAgent\n", + "\n", + "root_path = Path(\"/Users/shrutipatel/projects/work/repo-gpt/\")\n", + "embedding_file_path = root_path / \".repo_gpt/code_embeddings.pkl\"\n", + "\n", + "ci_agent = CentralIntelligenceAgent(\"Where should I add tests for the new file handler I'm writing? Do I need to create a new test file? If so, where?\",\n", + " root_path,\n", + " embedding_file_path,\n", + " openai_key = openai_key,\n", + " debug=True)\n", + "output = ci_agent.process_messages()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "549cdd7a-c762-48ae-b425-a5d15402ea6a", + "metadata": {}, + "outputs": [], + "source": [ + "%debug" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6be1f70a-3419-4432-be55-56dbe035baab", + "metadata": {}, + "outputs": [], + "source": [ + "# ## TODO\n", + "# - Update initial user query so we include results from semantic search\n", + "# - Update system prompt and or the function json to include the output schema of the returned code_embedding csv rows\n", + "# - Update sep for CSV output to a more uncommon character since commas are frequently used in code? (This may not be necessary because converting to csv usually ex\n", + "# - Add a function where the writeragent can ask the repounderstandingagent\n", + "# - Update function so you search for files -- this will decrease the token size because we won't send the all the files every time and this will handle larger codebases with greater ease\n", + "# - Use COD to ensure messages are being compressed while retaining all relevant info\n", + "# - How can I incorporate reflexion?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/poetry.lock b/poetry.lock index 2d731a3..f3e7762 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,99 +1,99 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiohttp" -version = "3.8.5" +version = "3.8.6" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.6" files = [ - {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a94159871304770da4dd371f4291b20cac04e8c94f11bdea1c3478e557fbe0d8"}, - {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:13bf85afc99ce6f9ee3567b04501f18f9f8dbbb2ea11ed1a2e079670403a7c84"}, - {file = "aiohttp-3.8.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ce2ac5708501afc4847221a521f7e4b245abf5178cf5ddae9d5b3856ddb2f3a"}, - {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96943e5dcc37a6529d18766597c491798b7eb7a61d48878611298afc1fca946c"}, - {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ad5c3c4590bb3cc28b4382f031f3783f25ec223557124c68754a2231d989e2b"}, - {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c413c633d0512df4dc7fd2373ec06cc6a815b7b6d6c2f208ada7e9e93a5061d"}, - {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df72ac063b97837a80d80dec8d54c241af059cc9bb42c4de68bd5b61ceb37caa"}, - {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c48c5c0271149cfe467c0ff8eb941279fd6e3f65c9a388c984e0e6cf57538e14"}, - {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:368a42363c4d70ab52c2c6420a57f190ed3dfaca6a1b19afda8165ee16416a82"}, - {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7607ec3ce4993464368505888af5beb446845a014bc676d349efec0e05085905"}, - {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0d21c684808288a98914e5aaf2a7c6a3179d4df11d249799c32d1808e79503b5"}, - {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:312fcfbacc7880a8da0ae8b6abc6cc7d752e9caa0051a53d217a650b25e9a691"}, - {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad093e823df03bb3fd37e7dec9d4670c34f9e24aeace76808fc20a507cace825"}, - {file = "aiohttp-3.8.5-cp310-cp310-win32.whl", hash = "sha256:33279701c04351a2914e1100b62b2a7fdb9a25995c4a104259f9a5ead7ed4802"}, - {file = "aiohttp-3.8.5-cp310-cp310-win_amd64.whl", hash = "sha256:6e4a280e4b975a2e7745573e3fc9c9ba0d1194a3738ce1cbaa80626cc9b4f4df"}, - {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae871a964e1987a943d83d6709d20ec6103ca1eaf52f7e0d36ee1b5bebb8b9b9"}, - {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:461908b2578955045efde733719d62f2b649c404189a09a632d245b445c9c975"}, - {file = "aiohttp-3.8.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72a860c215e26192379f57cae5ab12b168b75db8271f111019509a1196dfc780"}, - {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc14be025665dba6202b6a71cfcdb53210cc498e50068bc088076624471f8bb9"}, - {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8af740fc2711ad85f1a5c034a435782fbd5b5f8314c9a3ef071424a8158d7f6b"}, - {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:841cd8233cbd2111a0ef0a522ce016357c5e3aff8a8ce92bcfa14cef890d698f"}, - {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed1c46fb119f1b59304b5ec89f834f07124cd23ae5b74288e364477641060ff"}, - {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84f8ae3e09a34f35c18fa57f015cc394bd1389bce02503fb30c394d04ee6b938"}, - {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62360cb771707cb70a6fd114b9871d20d7dd2163a0feafe43fd115cfe4fe845e"}, - {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:23fb25a9f0a1ca1f24c0a371523546366bb642397c94ab45ad3aedf2941cec6a"}, - {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0ba0d15164eae3d878260d4c4df859bbdc6466e9e6689c344a13334f988bb53"}, - {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5d20003b635fc6ae3f96d7260281dfaf1894fc3aa24d1888a9b2628e97c241e5"}, - {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0175d745d9e85c40dcc51c8f88c74bfbaef9e7afeeeb9d03c37977270303064c"}, - {file = "aiohttp-3.8.5-cp311-cp311-win32.whl", hash = "sha256:2e1b1e51b0774408f091d268648e3d57f7260c1682e7d3a63cb00d22d71bb945"}, - {file = "aiohttp-3.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:043d2299f6dfdc92f0ac5e995dfc56668e1587cea7f9aa9d8a78a1b6554e5755"}, - {file = "aiohttp-3.8.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cae533195e8122584ec87531d6df000ad07737eaa3c81209e85c928854d2195c"}, - {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f21e83f355643c345177a5d1d8079f9f28b5133bcd154193b799d380331d5d3"}, - {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a75ef35f2df54ad55dbf4b73fe1da96f370e51b10c91f08b19603c64004acc"}, - {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e2e9839e14dd5308ee773c97115f1e0a1cb1d75cbeeee9f33824fa5144c7634"}, - {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44e65da1de4403d0576473e2344828ef9c4c6244d65cf4b75549bb46d40b8dd"}, - {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d847e4cde6ecc19125ccbc9bfac4a7ab37c234dd88fbb3c5c524e8e14da543"}, - {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:c7a815258e5895d8900aec4454f38dca9aed71085f227537208057853f9d13f2"}, - {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:8b929b9bd7cd7c3939f8bcfffa92fae7480bd1aa425279d51a89327d600c704d"}, - {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:5db3a5b833764280ed7618393832e0853e40f3d3e9aa128ac0ba0f8278d08649"}, - {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:a0215ce6041d501f3155dc219712bc41252d0ab76474615b9700d63d4d9292af"}, - {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:fd1ed388ea7fbed22c4968dd64bab0198de60750a25fe8c0c9d4bef5abe13824"}, - {file = "aiohttp-3.8.5-cp36-cp36m-win32.whl", hash = "sha256:6e6783bcc45f397fdebc118d772103d751b54cddf5b60fbcc958382d7dd64f3e"}, - {file = "aiohttp-3.8.5-cp36-cp36m-win_amd64.whl", hash = "sha256:b5411d82cddd212644cf9360879eb5080f0d5f7d809d03262c50dad02f01421a"}, - {file = "aiohttp-3.8.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:01d4c0c874aa4ddfb8098e85d10b5e875a70adc63db91f1ae65a4b04d3344cda"}, - {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5980a746d547a6ba173fd5ee85ce9077e72d118758db05d229044b469d9029a"}, - {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a482e6da906d5e6e653be079b29bc173a48e381600161c9932d89dfae5942ef"}, - {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80bd372b8d0715c66c974cf57fe363621a02f359f1ec81cba97366948c7fc873"}, - {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1161b345c0a444ebcf46bf0a740ba5dcf50612fd3d0528883fdc0eff578006a"}, - {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd56db019015b6acfaaf92e1ac40eb8434847d9bf88b4be4efe5bfd260aee692"}, - {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:153c2549f6c004d2754cc60603d4668899c9895b8a89397444a9c4efa282aaf4"}, - {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4a01951fabc4ce26ab791da5f3f24dca6d9a6f24121746eb19756416ff2d881b"}, - {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bfb9162dcf01f615462b995a516ba03e769de0789de1cadc0f916265c257e5d8"}, - {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7dde0009408969a43b04c16cbbe252c4f5ef4574ac226bc8815cd7342d2028b6"}, - {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4149d34c32f9638f38f544b3977a4c24052042affa895352d3636fa8bffd030a"}, - {file = "aiohttp-3.8.5-cp37-cp37m-win32.whl", hash = "sha256:68c5a82c8779bdfc6367c967a4a1b2aa52cd3595388bf5961a62158ee8a59e22"}, - {file = "aiohttp-3.8.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2cf57fb50be5f52bda004b8893e63b48530ed9f0d6c96c84620dc92fe3cd9b9d"}, - {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eca4bf3734c541dc4f374ad6010a68ff6c6748f00451707f39857f429ca36ced"}, - {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1274477e4c71ce8cfe6c1ec2f806d57c015ebf84d83373676036e256bc55d690"}, - {file = "aiohttp-3.8.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c543e54710d6158fc6f439296c7865b29e0b616629767e685a7185fab4a6b9"}, - {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:910bec0c49637d213f5d9877105d26e0c4a4de2f8b1b29405ff37e9fc0ad52b8"}, - {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5443910d662db951b2e58eb70b0fbe6b6e2ae613477129a5805d0b66c54b6cb7"}, - {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e460be6978fc24e3df83193dc0cc4de46c9909ed92dd47d349a452ef49325b7"}, - {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb1558def481d84f03b45888473fc5a1f35747b5f334ef4e7a571bc0dfcb11f8"}, - {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34dd0c107799dcbbf7d48b53be761a013c0adf5571bf50c4ecad5643fe9cfcd0"}, - {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aa1990247f02a54185dc0dff92a6904521172a22664c863a03ff64c42f9b5410"}, - {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0e584a10f204a617d71d359fe383406305a4b595b333721fa50b867b4a0a1548"}, - {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a3cf433f127efa43fee6b90ea4c6edf6c4a17109d1d037d1a52abec84d8f2e42"}, - {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c11f5b099adafb18e65c2c997d57108b5bbeaa9eeee64a84302c0978b1ec948b"}, - {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:84de26ddf621d7ac4c975dbea4c945860e08cccde492269db4e1538a6a6f3c35"}, - {file = "aiohttp-3.8.5-cp38-cp38-win32.whl", hash = "sha256:ab88bafedc57dd0aab55fa728ea10c1911f7e4d8b43e1d838a1739f33712921c"}, - {file = "aiohttp-3.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:5798a9aad1879f626589f3df0f8b79b3608a92e9beab10e5fda02c8a2c60db2e"}, - {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a6ce61195c6a19c785df04e71a4537e29eaa2c50fe745b732aa937c0c77169f3"}, - {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:773dd01706d4db536335fcfae6ea2440a70ceb03dd3e7378f3e815b03c97ab51"}, - {file = "aiohttp-3.8.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f83a552443a526ea38d064588613aca983d0ee0038801bc93c0c916428310c28"}, - {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f7372f7341fcc16f57b2caded43e81ddd18df53320b6f9f042acad41f8e049a"}, - {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea353162f249c8097ea63c2169dd1aa55de1e8fecbe63412a9bc50816e87b761"}, - {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d47ae48db0b2dcf70bc8a3bc72b3de86e2a590fc299fdbbb15af320d2659de"}, - {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d827176898a2b0b09694fbd1088c7a31836d1a505c243811c87ae53a3f6273c1"}, - {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3562b06567c06439d8b447037bb655ef69786c590b1de86c7ab81efe1c9c15d8"}, - {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4e874cbf8caf8959d2adf572a78bba17cb0e9d7e51bb83d86a3697b686a0ab4d"}, - {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6809a00deaf3810e38c628e9a33271892f815b853605a936e2e9e5129762356c"}, - {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:33776e945d89b29251b33a7e7d006ce86447b2cfd66db5e5ded4e5cd0340585c"}, - {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eaeed7abfb5d64c539e2db173f63631455f1196c37d9d8d873fc316470dfbacd"}, - {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e91d635961bec2d8f19dfeb41a539eb94bd073f075ca6dae6c8dc0ee89ad6f91"}, - {file = "aiohttp-3.8.5-cp39-cp39-win32.whl", hash = "sha256:00ad4b6f185ec67f3e6562e8a1d2b69660be43070bd0ef6fcec5211154c7df67"}, - {file = "aiohttp-3.8.5-cp39-cp39-win_amd64.whl", hash = "sha256:c0a9034379a37ae42dea7ac1e048352d96286626251862e448933c0f59cbd79c"}, - {file = "aiohttp-3.8.5.tar.gz", hash = "sha256:b9552ec52cc147dbf1944ac7ac98af7602e51ea2dcd076ed194ca3c0d1c7d0bc"}, + {file = "aiohttp-3.8.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:41d55fc043954cddbbd82503d9cc3f4814a40bcef30b3569bc7b5e34130718c1"}, + {file = "aiohttp-3.8.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1d84166673694841d8953f0a8d0c90e1087739d24632fe86b1a08819168b4566"}, + {file = "aiohttp-3.8.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:253bf92b744b3170eb4c4ca2fa58f9c4b87aeb1df42f71d4e78815e6e8b73c9e"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fd194939b1f764d6bb05490987bfe104287bbf51b8d862261ccf66f48fb4096"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c5f938d199a6fdbdc10bbb9447496561c3a9a565b43be564648d81e1102ac22"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2817b2f66ca82ee699acd90e05c95e79bbf1dc986abb62b61ec8aaf851e81c93"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fa375b3d34e71ccccf172cab401cd94a72de7a8cc01847a7b3386204093bb47"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9de50a199b7710fa2904be5a4a9b51af587ab24c8e540a7243ab737b45844543"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e1d8cb0b56b3587c5c01de3bf2f600f186da7e7b5f7353d1bf26a8ddca57f965"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8e31e9db1bee8b4f407b77fd2507337a0a80665ad7b6c749d08df595d88f1cf5"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7bc88fc494b1f0311d67f29fee6fd636606f4697e8cc793a2d912ac5b19aa38d"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ec00c3305788e04bf6d29d42e504560e159ccaf0be30c09203b468a6c1ccd3b2"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad1407db8f2f49329729564f71685557157bfa42b48f4b93e53721a16eb813ed"}, + {file = "aiohttp-3.8.6-cp310-cp310-win32.whl", hash = "sha256:ccc360e87341ad47c777f5723f68adbb52b37ab450c8bc3ca9ca1f3e849e5fe2"}, + {file = "aiohttp-3.8.6-cp310-cp310-win_amd64.whl", hash = "sha256:93c15c8e48e5e7b89d5cb4613479d144fda8344e2d886cf694fd36db4cc86865"}, + {file = "aiohttp-3.8.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e2f9cc8e5328f829f6e1fb74a0a3a939b14e67e80832975e01929e320386b34"}, + {file = "aiohttp-3.8.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e6a00ffcc173e765e200ceefb06399ba09c06db97f401f920513a10c803604ca"}, + {file = "aiohttp-3.8.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:41bdc2ba359032e36c0e9de5a3bd00d6fb7ea558a6ce6b70acedf0da86458321"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14cd52ccf40006c7a6cd34a0f8663734e5363fd981807173faf3a017e202fec9"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2d5b785c792802e7b275c420d84f3397668e9d49ab1cb52bd916b3b3ffcf09ad"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1bed815f3dc3d915c5c1e556c397c8667826fbc1b935d95b0ad680787896a358"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96603a562b546632441926cd1293cfcb5b69f0b4159e6077f7c7dbdfb686af4d"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d76e8b13161a202d14c9584590c4df4d068c9567c99506497bdd67eaedf36403"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e3f1e3f1a1751bb62b4a1b7f4e435afcdade6c17a4fd9b9d43607cebd242924a"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:76b36b3124f0223903609944a3c8bf28a599b2cc0ce0be60b45211c8e9be97f8"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a2ece4af1f3c967a4390c284797ab595a9f1bc1130ef8b01828915a05a6ae684"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:16d330b3b9db87c3883e565340d292638a878236418b23cc8b9b11a054aaa887"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:42c89579f82e49db436b69c938ab3e1559e5a4409eb8639eb4143989bc390f2f"}, + {file = "aiohttp-3.8.6-cp311-cp311-win32.whl", hash = "sha256:efd2fcf7e7b9d7ab16e6b7d54205beded0a9c8566cb30f09c1abe42b4e22bdcb"}, + {file = "aiohttp-3.8.6-cp311-cp311-win_amd64.whl", hash = "sha256:3b2ab182fc28e7a81f6c70bfbd829045d9480063f5ab06f6e601a3eddbbd49a0"}, + {file = "aiohttp-3.8.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fdee8405931b0615220e5ddf8cd7edd8592c606a8e4ca2a00704883c396e4479"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d25036d161c4fe2225d1abff2bd52c34ed0b1099f02c208cd34d8c05729882f0"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d791245a894be071d5ab04bbb4850534261a7d4fd363b094a7b9963e8cdbd31"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0cccd1de239afa866e4ce5c789b3032442f19c261c7d8a01183fd956b1935349"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f13f60d78224f0dace220d8ab4ef1dbc37115eeeab8c06804fec11bec2bbd07"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a9b5a0606faca4f6cc0d338359d6fa137104c337f489cd135bb7fbdbccb1e39"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:13da35c9ceb847732bf5c6c5781dcf4780e14392e5d3b3c689f6d22f8e15ae31"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:4d4cbe4ffa9d05f46a28252efc5941e0462792930caa370a6efaf491f412bc66"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:229852e147f44da0241954fc6cb910ba074e597f06789c867cb7fb0621e0ba7a"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:713103a8bdde61d13490adf47171a1039fd880113981e55401a0f7b42c37d071"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:45ad816b2c8e3b60b510f30dbd37fe74fd4a772248a52bb021f6fd65dff809b6"}, + {file = "aiohttp-3.8.6-cp36-cp36m-win32.whl", hash = "sha256:2b8d4e166e600dcfbff51919c7a3789ff6ca8b3ecce16e1d9c96d95dd569eb4c"}, + {file = "aiohttp-3.8.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0912ed87fee967940aacc5306d3aa8ba3a459fcd12add0b407081fbefc931e53"}, + {file = "aiohttp-3.8.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e2a988a0c673c2e12084f5e6ba3392d76c75ddb8ebc6c7e9ead68248101cd446"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebf3fd9f141700b510d4b190094db0ce37ac6361a6806c153c161dc6c041ccda"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3161ce82ab85acd267c8f4b14aa226047a6bee1e4e6adb74b798bd42c6ae1f80"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d95fc1bf33a9a81469aa760617b5971331cdd74370d1214f0b3109272c0e1e3c"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c43ecfef7deaf0617cee936836518e7424ee12cb709883f2c9a1adda63cc460"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca80e1b90a05a4f476547f904992ae81eda5c2c85c66ee4195bb8f9c5fb47f28"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:90c72ebb7cb3a08a7f40061079817133f502a160561d0675b0a6adf231382c92"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bb54c54510e47a8c7c8e63454a6acc817519337b2b78606c4e840871a3e15349"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:de6a1c9f6803b90e20869e6b99c2c18cef5cc691363954c93cb9adeb26d9f3ae"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:a3628b6c7b880b181a3ae0a0683698513874df63783fd89de99b7b7539e3e8a8"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fc37e9aef10a696a5a4474802930079ccfc14d9f9c10b4662169671ff034b7df"}, + {file = "aiohttp-3.8.6-cp37-cp37m-win32.whl", hash = "sha256:f8ef51e459eb2ad8e7a66c1d6440c808485840ad55ecc3cafefadea47d1b1ba2"}, + {file = "aiohttp-3.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:b2fe42e523be344124c6c8ef32a011444e869dc5f883c591ed87f84339de5976"}, + {file = "aiohttp-3.8.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9e2ee0ac5a1f5c7dd3197de309adfb99ac4617ff02b0603fd1e65b07dc772e4b"}, + {file = "aiohttp-3.8.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01770d8c04bd8db568abb636c1fdd4f7140b284b8b3e0b4584f070180c1e5c62"}, + {file = "aiohttp-3.8.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3c68330a59506254b556b99a91857428cab98b2f84061260a67865f7f52899f5"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89341b2c19fb5eac30c341133ae2cc3544d40d9b1892749cdd25892bbc6ac951"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71783b0b6455ac8f34b5ec99d83e686892c50498d5d00b8e56d47f41b38fbe04"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f628dbf3c91e12f4d6c8b3f092069567d8eb17814aebba3d7d60c149391aee3a"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04691bc6601ef47c88f0255043df6f570ada1a9ebef99c34bd0b72866c217ae"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ee912f7e78287516df155f69da575a0ba33b02dd7c1d6614dbc9463f43066e3"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9c19b26acdd08dd239e0d3669a3dddafd600902e37881f13fbd8a53943079dbc"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:99c5ac4ad492b4a19fc132306cd57075c28446ec2ed970973bbf036bcda1bcc6"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f0f03211fd14a6a0aed2997d4b1c013d49fb7b50eeb9ffdf5e51f23cfe2c77fa"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:8d399dade330c53b4106160f75f55407e9ae7505263ea86f2ccca6bfcbdb4921"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ec4fd86658c6a8964d75426517dc01cbf840bbf32d055ce64a9e63a40fd7b771"}, + {file = "aiohttp-3.8.6-cp38-cp38-win32.whl", hash = "sha256:33164093be11fcef3ce2571a0dccd9041c9a93fa3bde86569d7b03120d276c6f"}, + {file = "aiohttp-3.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:bdf70bfe5a1414ba9afb9d49f0c912dc524cf60141102f3a11143ba3d291870f"}, + {file = "aiohttp-3.8.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d52d5dc7c6682b720280f9d9db41d36ebe4791622c842e258c9206232251ab2b"}, + {file = "aiohttp-3.8.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ac39027011414dbd3d87f7edb31680e1f430834c8cef029f11c66dad0670aa5"}, + {file = "aiohttp-3.8.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3f5c7ce535a1d2429a634310e308fb7d718905487257060e5d4598e29dc17f0b"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b30e963f9e0d52c28f284d554a9469af073030030cef8693106d918b2ca92f54"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:918810ef188f84152af6b938254911055a72e0f935b5fbc4c1a4ed0b0584aed1"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:002f23e6ea8d3dd8d149e569fd580c999232b5fbc601c48d55398fbc2e582e8c"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fcf3eabd3fd1a5e6092d1242295fa37d0354b2eb2077e6eb670accad78e40e1"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:255ba9d6d5ff1a382bb9a578cd563605aa69bec845680e21c44afc2670607a95"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d67f8baed00870aa390ea2590798766256f31dc5ed3ecc737debb6e97e2ede78"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:86f20cee0f0a317c76573b627b954c412ea766d6ada1a9fcf1b805763ae7feeb"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:39a312d0e991690ccc1a61f1e9e42daa519dcc34ad03eb6f826d94c1190190dd"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e827d48cf802de06d9c935088c2924e3c7e7533377d66b6f31ed175c1620e05e"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd111d7fc5591ddf377a408ed9067045259ff2770f37e2d94e6478d0f3fc0c17"}, + {file = "aiohttp-3.8.6-cp39-cp39-win32.whl", hash = "sha256:caf486ac1e689dda3502567eb89ffe02876546599bbf915ec94b1fa424eeffd4"}, + {file = "aiohttp-3.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:3f0e27e5b733803333bb2371249f41cf42bae8884863e8e8965ec69bebe53132"}, + {file = "aiohttp-3.8.6.tar.gz", hash = "sha256:b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c"}, ] [package.dependencies] @@ -122,26 +122,51 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "aiostream" +version = "0.5.2" +description = "Generator-based operators for asynchronous iteration" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiostream-0.5.2-py3-none-any.whl", hash = "sha256:054660370be9d37f6fe3ece3851009240416bd082e469fd90cc8673d3818cf71"}, + {file = "aiostream-0.5.2.tar.gz", hash = "sha256:b71b519a2d66c38f0872403ab86417955b77352f08d9ad02ad46fc3926b389f4"}, +] + +[package.dependencies] +typing-extensions = "*" + +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + [[package]] name = "anyio" -version = "3.7.1" +version = "4.0.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, + {file = "anyio-4.0.0-py3-none-any.whl", hash = "sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f"}, + {file = "anyio-4.0.0.tar.gz", hash = "sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a"}, ] [package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" [package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.22)"] [[package]] name = "appnope" @@ -156,22 +181,23 @@ files = [ [[package]] name = "argon2-cffi" -version = "21.3.0" -description = "The secure Argon2 password hashing algorithm." +version = "23.1.0" +description = "Argon2 for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "argon2-cffi-21.3.0.tar.gz", hash = "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b"}, - {file = "argon2_cffi-21.3.0-py3-none-any.whl", hash = "sha256:8c976986f2c5c0e5000919e6de187906cfd81fb1c72bf9d88c01177e77da7f80"}, + {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, + {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, ] [package.dependencies] argon2-cffi-bindings = "*" [package.extras] -dev = ["cogapp", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "pre-commit", "pytest", "sphinx", "sphinx-notfound-page", "tomli"] -docs = ["furo", "sphinx", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] +dev = ["argon2-cffi[tests,typing]", "tox (>4)"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"] +tests = ["hypothesis", "pytest"] +typing = ["mypy"] [[package]] name = "argon2-cffi-bindings" @@ -212,34 +238,71 @@ tests = ["pytest"] [[package]] name = "arrow" -version = "1.2.3" +version = "1.3.0" description = "Better dates & times for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"}, - {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, ] [package.dependencies] python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + +[[package]] +name = "asgiref" +version = "3.7.2" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.7" +files = [ + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "astroid" +version = "3.0.1" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "astroid-3.0.1-py3-none-any.whl", hash = "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca"}, + {file = "astroid-3.0.1.tar.gz", hash = "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "asttokens" -version = "2.2.1" +version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false python-versions = "*" files = [ - {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, - {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, ] [package.dependencies] -six = "*" +six = ">=1.12.0" [package.extras] -test = ["astroid", "pytest"] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "async-lru" @@ -286,28 +349,17 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte [[package]] name = "babel" -version = "2.12.1" +version = "2.13.1" description = "Internationalization utilities" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, - {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, + {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, + {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -optional = false -python-versions = "*" -files = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "beautifulsoup4" @@ -329,13 +381,13 @@ lxml = ["lxml"] [[package]] name = "bleach" -version = "6.0.0" +version = "6.1.0" description = "An easy safelist-based HTML-sanitizing tool." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, - {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, ] [package.dependencies] @@ -343,7 +395,7 @@ six = ">=1.9.0" webencodings = "*" [package.extras] -css = ["tinycss2 (>=1.1.0,<1.2)"] +css = ["tinycss2 (>=1.1.0,<1.3)"] [[package]] name = "bump2version" @@ -369,75 +421,63 @@ files = [ [[package]] name = "cffi" -version = "1.15.1" +version = "1.16.0" description = "Foreign Function Interface for Python calling C code." optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, ] [package.dependencies] @@ -445,97 +485,158 @@ pycparser = "*" [[package]] name = "cfgv" -version = "3.3.1" +version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.8" files = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "cloudpickle" +version = "2.0.0" +description = "Extended pickling support for Python objects" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cloudpickle-2.0.0-py3-none-any.whl", hash = "sha256:6b2df9741d06f43839a3275c4e6632f7df6487a1f181f5f46a052d3c917c3d11"}, + {file = "cloudpickle-2.0.0.tar.gz", hash = "sha256:5cd02f3b417a783ba84a4ec3e290ff7929009fe51f6405423cfccfadd43ba4a4"}, +] + +[[package]] +name = "cloudpickle" +version = "2.2.1" +description = "Extended pickling support for Python objects" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, + {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, +] + +[[package]] +name = "code2flow" +version = "2.5.1" +description = "Visualize your source code as DOT flowcharts" +optional = false +python-versions = ">=3.6" +files = [ + {file = "code2flow-2.5.1.tar.gz", hash = "sha256:ad98717920da6598dac38a1951f38b84891f4aa4bd2f36c119b0dbac729f4785"}, ] [[package]] @@ -549,50 +650,74 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "colored" +version = "2.2.3" +description = "Simple python library for color and formatting to terminal" +optional = false +python-versions = ">=3.9" +files = [ + {file = "colored-2.2.3-py3-none-any.whl", hash = "sha256:1318b2fb8e0313d39724b8ab0707af79d1e2c0e60710b608a00e70fe0f84ff5d"}, + {file = "colored-2.2.3.tar.gz", hash = "sha256:1905ae45fa2b7fd63a8b4776586e63aeaba4df8db225b72b78fd167408558983"}, +] + [[package]] name = "comm" -version = "0.1.4" +version = "0.2.0" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "comm-0.1.4-py3-none-any.whl", hash = "sha256:6d52794cba11b36ed9860999cd10fd02d6b2eac177068fdd585e1e2f8a96e67a"}, - {file = "comm-0.1.4.tar.gz", hash = "sha256:354e40a59c9dd6db50c5cc6b4acc887d82e9603787f83b68c01a80a923984d15"}, + {file = "comm-0.2.0-py3-none-any.whl", hash = "sha256:2da8d9ebb8dd7bfc247adaff99f24dce705638a8042b85cb995066793e391001"}, + {file = "comm-0.2.0.tar.gz", hash = "sha256:a517ea2ca28931c7007a7a99c562a0fa5883cfb48963140cf642c41c948498be"}, ] [package.dependencies] traitlets = ">=4" [package.extras] -lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"] test = ["pytest"] -typing = ["mypy (>=0.990)"] + +[[package]] +name = "configargparse" +version = "1.7" +description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." +optional = false +python-versions = ">=3.5" +files = [ + {file = "ConfigArgParse-1.7-py3-none-any.whl", hash = "sha256:d249da6591465c6c26df64a9f73d2536e743be2f244eb3ebe61114af2f94f86b"}, + {file = "ConfigArgParse-1.7.tar.gz", hash = "sha256:e7067471884de5478c58a511e529f0f9bd1c66bfef1dea90935438d6c23306d1"}, +] + +[package.extras] +test = ["PyYAML", "mock", "pytest"] +yaml = ["PyYAML"] [[package]] name = "debugpy" -version = "1.6.7.post1" +version = "1.8.0" description = "An implementation of the Debug Adapter Protocol for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "debugpy-1.6.7.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:903bd61d5eb433b6c25b48eae5e23821d4c1a19e25c9610205f5aeaccae64e32"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16882030860081e7dd5aa619f30dec3c2f9a421e69861125f83cc372c94e57d"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win32.whl", hash = "sha256:eea8d8cfb9965ac41b99a61f8e755a8f50e9a20330938ad8271530210f54e09c"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win_amd64.whl", hash = "sha256:85969d864c45f70c3996067cfa76a319bae749b04171f2cdeceebe4add316155"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:890f7ab9a683886a0f185786ffbda3b46495c4b929dab083b8c79d6825832a52"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4ac7a4dba28801d184b7fc0e024da2635ca87d8b0a825c6087bb5168e3c0d28"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win32.whl", hash = "sha256:3370ef1b9951d15799ef7af41f8174194f3482ee689988379763ef61a5456426"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:65b28435a17cba4c09e739621173ff90c515f7b9e8ea469b92e3c28ef8e5cdfb"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:92b6dae8bfbd497c90596bbb69089acf7954164aea3228a99d7e43e5267f5b36"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72f5d2ecead8125cf669e62784ef1e6300f4067b0f14d9f95ee00ae06fc7c4f7"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win32.whl", hash = "sha256:f0851403030f3975d6e2eaa4abf73232ab90b98f041e3c09ba33be2beda43fcf"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win_amd64.whl", hash = "sha256:3de5d0f97c425dc49bce4293df6a04494309eedadd2b52c22e58d95107e178d9"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:38651c3639a4e8bbf0ca7e52d799f6abd07d622a193c406be375da4d510d968d"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038c51268367c9c935905a90b1c2d2dbfe304037c27ba9d19fe7409f8cdc710c"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win32.whl", hash = "sha256:4b9eba71c290852f959d2cf8a03af28afd3ca639ad374d393d53d367f7f685b2"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win_amd64.whl", hash = "sha256:973a97ed3b434eab0f792719a484566c35328196540676685c975651266fccf9"}, - {file = "debugpy-1.6.7.post1-py2.py3-none-any.whl", hash = "sha256:1093a5c541af079c13ac8c70ab8b24d1d35c8cacb676306cf11e57f699c02926"}, - {file = "debugpy-1.6.7.post1.zip", hash = "sha256:fe87ec0182ef624855d05e6ed7e0b7cb1359d2ffa2a925f8ec2d22e98b75d0ca"}, + {file = "debugpy-1.8.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb"}, + {file = "debugpy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada"}, + {file = "debugpy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f"}, + {file = "debugpy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637"}, + {file = "debugpy-1.8.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e"}, + {file = "debugpy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6"}, + {file = "debugpy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b"}, + {file = "debugpy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153"}, + {file = "debugpy-1.8.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd"}, + {file = "debugpy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f"}, + {file = "debugpy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa"}, + {file = "debugpy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595"}, + {file = "debugpy-1.8.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8"}, + {file = "debugpy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332"}, + {file = "debugpy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6"}, + {file = "debugpy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926"}, + {file = "debugpy-1.8.0-py2.py3-none-any.whl", hash = "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4"}, + {file = "debugpy-1.8.0.zip", hash = "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0"}, ] [[package]] @@ -617,6 +742,31 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "dill" +version = "0.3.7" +description = "serialize all of Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, + {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] + +[[package]] +name = "diskcache" +version = "5.6.3" +description = "Disk Cache -- Disk and file backed persistent cache." +optional = false +python-versions = ">=3" +files = [ + {file = "diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19"}, + {file = "diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc"}, +] + [[package]] name = "distlib" version = "0.3.7" @@ -630,13 +780,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.1.2" +version = "1.1.3" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, - {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, ] [package.extras] @@ -644,27 +794,46 @@ test = ["pytest (>=6)"] [[package]] name = "executing" -version = "1.2.0" +version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, ] [package.extras] -tests = ["asttokens", "littleutils", "pytest", "rich"] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "fastapi" +version = "0.103.0" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = false +python-versions = ">=3.7" +files = [ + {file = "fastapi-0.103.0-py3-none-any.whl", hash = "sha256:61ab72c6c281205dd0cbaccf503e829a37e0be108d965ac223779a8479243665"}, + {file = "fastapi-0.103.0.tar.gz", hash = "sha256:4166732f5ddf61c33e9fa4664f73780872511e0598d4d5434b1816dc1e6d9421"}, +] + +[package.dependencies] +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +starlette = ">=0.27.0,<0.28.0" +typing-extensions = ">=4.5.0" + +[package.extras] +all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "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)"] [[package]] name = "fastjsonschema" -version = "2.18.0" +version = "2.18.1" description = "Fastest Python implementation of JSON schema" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"}, - {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"}, + {file = "fastjsonschema-2.18.1-py3-none-any.whl", hash = "sha256:aec6a19e9f66e9810ab371cc913ad5f4e9e479b63a7072a2cd060a9369e329a8"}, + {file = "fastjsonschema-2.18.1.tar.gz", hash = "sha256:06dc8680d937628e993fa0cd278f196d20449a1adc087640710846b324d422ea"}, ] [package.extras] @@ -672,18 +841,56 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "filelock" -version = "3.12.2" +version = "3.13.1" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "flaml" +version = "2.1.1" +description = "A fast library for automated machine learning and tuning" +optional = false +python-versions = ">=3.6" +files = [ + {file = "FLAML-2.1.1-py3-none-any.whl", hash = "sha256:ba34f1a06f3cbc6bb23a2ea4830a264375f6bba497f402122a73e42647a15535"}, + {file = "FLAML-2.1.1.tar.gz", hash = "sha256:53e94aacc996da80fe779bc6833d3b25c80c77fe11667d0912798e49293282eb"}, +] + +[package.dependencies] +NumPy = ">=1.17.0rc1" + +[package.extras] +autogen = ["diskcache", "openai (==0.27.8)", "termcolor"] +automl = ["lightgbm (>=2.3.1)", "pandas (>=1.1.4)", "scikit-learn (>=0.24)", "scipy (>=1.4.1)", "xgboost (>=0.90)"] +autozero = ["packaging", "pandas", "scikit-learn"] +azureml = ["azureml-mlflow"] +benchmark = ["catboost (>=0.26)", "pandas (==1.1.4)", "psutil (==5.8.0)", "xgboost (==1.3.3)"] +blendsearch = ["optuna (==2.8.0)", "packaging"] +catboost = ["catboost (>=0.26)"] +forecast = ["hcrystalball (==0.1.10)", "holidays (<0.14)", "prophet (>=1.0.1)", "pytorch-forecasting (>=0.9.0)", "pytorch-lightning (==1.9.0)", "statsmodels (>=0.12.2)", "tensorboardX (==2.6)"] +hf = ["datasets", "nltk", "rouge-score", "seqeval", "transformers[torch] (==4.26)"] +mathchat = ["diskcache", "openai (==0.27.8)", "pydantic (==1.10.9)", "sympy", "termcolor", "wolframalpha"] +nlp = ["datasets", "nltk", "rouge-score", "seqeval", "transformers[torch] (==4.26)"] +nni = ["nni"] +notebook = ["jupyter"] +openai = ["diskcache", "openai (==0.27.8)"] +ray = ["ray[tune] (>=1.13,<2.0)"] +retrievechat = ["chromadb", "diskcache", "openai (==0.27.8)", "sentence-transformers", "termcolor", "tiktoken"] +spark = ["joblib (<1.3.0)", "joblibspark (>=0.5.0)", "pyspark (>=3.2.0)"] +synapse = ["joblib (<1.3.0)", "joblibspark (>=0.5.0)", "optuna (==2.8.0)", "pyspark (>=3.2.0)"] +test = ["catboost (>=0.26,<1.2)", "coverage (>=5.3)", "dataclasses", "datasets", "hcrystalball (==0.1.10)", "ipykernel", "joblib (<1.3.0)", "joblibspark (>=0.5.0)", "lightgbm (>=2.3.1)", "mlflow", "nbconvert", "nbformat", "nltk", "openml", "optuna (==2.8.0)", "packaging", "pandas (>=1.1.4)", "pre-commit", "psutil (==5.8.0)", "pydantic (==1.10.9)", "pyspark (>=3.2.0)", "pytest (>=6.1.1)", "pytorch-forecasting (>=0.9.0,<=0.10.1)", "pytorch-lightning (<1.9.1)", "requests (<2.29.0)", "rgf-python", "rouge-score", "scikit-learn (>=0.24)", "scipy (>=1.4.1)", "seqeval", "statsmodels (>=0.12.2)", "sympy", "tensorboardX (==2.6)", "thop", "torch", "torchvision", "transformers[torch] (==4.26)", "wolframalpha", "xgboost (>=0.90)"] +ts-forecast = ["hcrystalball (==0.1.10)", "holidays (<0.14)", "prophet (>=1.0.1)", "statsmodels (>=0.12.2)"] +vw = ["scikit-learn", "vowpalwabbit (>=8.10.0,<9.0.0)"] [[package]] name = "fqdn" @@ -767,35 +974,82 @@ files = [ ] [[package]] -name = "halo" -version = "0.0.31" -description = "Beautiful terminal spinners in Python" +name = "fuzzywuzzy" +version = "0.18.0" +description = "Fuzzy string matching in python" +optional = false +python-versions = "*" +files = [ + {file = "fuzzywuzzy-0.18.0-py2.py3-none-any.whl", hash = "sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993"}, + {file = "fuzzywuzzy-0.18.0.tar.gz", hash = "sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8"}, +] + +[package.extras] +speedup = ["python-levenshtein (>=0.12)"] + +[[package]] +name = "grpclib" +version = "0.4.3" +description = "Pure-Python gRPC implementation for asyncio" optional = false -python-versions = ">=3.4" +python-versions = ">=3.7" files = [ - {file = "halo-0.0.31-py2-none-any.whl", hash = "sha256:5350488fb7d2aa7c31a1344120cee67a872901ce8858f60da7946cef96c208ab"}, - {file = "halo-0.0.31.tar.gz", hash = "sha256:7b67a3521ee91d53b7152d4ee3452811e1d2a6321975137762eb3d70063cc9d6"}, + {file = "grpclib-0.4.3.tar.gz", hash = "sha256:eadf2002fc5a25158b707c0338a6c0b96dd7fbdc6df66f7e515e7f041d56a940"}, ] [package.dependencies] -colorama = ">=0.3.9" -log-symbols = ">=0.0.14" -six = ">=1.12.0" -spinners = ">=0.0.24" -termcolor = ">=1.1.0" +h2 = ">=3.1.0,<5" +multidict = "*" [package.extras] -ipython = ["IPython (==5.7.0)", "ipywidgets (==7.1.0)"] +protobuf = ["protobuf (>=3.15.0)"] + +[[package]] +name = "h2" +version = "4.1.0" +description = "HTTP/2 State-Machine based protocol implementation" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, + {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, +] + +[package.dependencies] +hpack = ">=4.0,<5" +hyperframe = ">=6.0,<7" + +[[package]] +name = "hpack" +version = "4.0.0" +description = "Pure-Python HPACK header compression" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, + {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, +] + +[[package]] +name = "hyperframe" +version = "6.0.1" +description = "HTTP/2 framing layer for Python" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, + {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, +] [[package]] name = "identify" -version = "2.5.26" +version = "2.5.31" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.26-py2.py3-none-any.whl", hash = "sha256:c22a8ead0d4ca11f1edd6c9418c3220669b3b7533ada0a0ffa6cc0ef85cf9b54"}, - {file = "identify-2.5.26.tar.gz", hash = "sha256:7243800bce2f58404ed41b7c002e53d4d22bcf3ae1b7900c2d7aefd95394bf7f"}, + {file = "identify-2.5.31-py2.py3-none-any.whl", hash = "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d"}, + {file = "identify-2.5.31.tar.gz", hash = "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75"}, ] [package.extras] @@ -831,24 +1085,6 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] -[[package]] -name = "importlib-resources" -version = "6.0.1" -description = "Read resources from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"}, - {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -862,13 +1098,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.25.1" +version = "6.26.0" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.25.1-py3-none-any.whl", hash = "sha256:c8a2430b357073b37c76c21c52184db42f6b4b0e438e1eb7df3c4440d120497c"}, - {file = "ipykernel-6.25.1.tar.gz", hash = "sha256:050391364c0977e768e354bdb60cbbfbee7cbb943b1af1618382021136ffd42f"}, + {file = "ipykernel-6.26.0-py3-none-any.whl", hash = "sha256:3ba3dc97424b87b31bb46586b5167b3161b32d7820b9201a9e698c71e271602c"}, + {file = "ipykernel-6.26.0.tar.gz", hash = "sha256:553856658eb8430bbe9653ea041a41bff63e9606fc4628873fc92a6cf3abd404"}, ] [package.dependencies] @@ -895,24 +1131,23 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.12.2" +version = "8.17.2" description = "IPython: Productive Interactive Computing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"}, - {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"}, + {file = "ipython-8.17.2-py3-none-any.whl", hash = "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444"}, + {file = "ipython-8.17.2.tar.gz", hash = "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb"}, ] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" pygments = ">=2.4.0" stack-data = "*" @@ -920,17 +1155,17 @@ traitlets = ">=5" typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "isoduration" @@ -946,15 +1181,32 @@ files = [ [package.dependencies] arrow = ">=0.15.0" +[[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + [[package]] name = "jedi" -version = "0.19.0" +version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" files = [ - {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, - {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, ] [package.dependencies] @@ -963,7 +1215,7 @@ parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" @@ -1008,24 +1260,22 @@ files = [ [[package]] name = "jsonschema" -version = "4.19.0" +version = "4.19.2" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, - {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, + {file = "jsonschema-4.19.2-py3-none-any.whl", hash = "sha256:eee9e502c788e89cb166d4d37f43084e3b64ab405c795c03d343a4dbc2c810fc"}, + {file = "jsonschema-4.19.2.tar.gz", hash = "sha256:c9ff4d7447eed9592c23a12ccee508baf0dd0d59650615e847feb6cdca74f392"}, ] [package.dependencies] attrs = ">=22.2.0" fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} jsonschema-specifications = ">=2023.03.6" -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} referencing = ">=0.28.4" rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} @@ -1049,18 +1299,17 @@ files = [ ] [package.dependencies] -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} referencing = ">=0.28.0" [[package]] name = "jupyter-client" -version = "8.3.0" +version = "8.6.0" description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.3.0-py3-none-any.whl", hash = "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158"}, - {file = "jupyter_client-8.3.0.tar.gz", hash = "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f"}, + {file = "jupyter_client-8.6.0-py3-none-any.whl", hash = "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99"}, + {file = "jupyter_client-8.6.0.tar.gz", hash = "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7"}, ] [package.dependencies] @@ -1077,13 +1326,13 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.3.1" +version = "5.5.0" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.3.1-py3-none-any.whl", hash = "sha256:ae9036db959a71ec1cac33081eeb040a79e681f08ab68b0883e9a676c7a90dce"}, - {file = "jupyter_core-5.3.1.tar.gz", hash = "sha256:5ba5c7938a7f97a6b0481463f7ff0dbac7c15ba48cf46fa4035ca6e838aa1aba"}, + {file = "jupyter_core-5.5.0-py3-none-any.whl", hash = "sha256:e11e02cd8ae0a9de5c6c44abf5727df9f2581055afe00b22183f621ba3585805"}, + {file = "jupyter_core-5.5.0.tar.gz", hash = "sha256:880b86053bf298a8724994f95e99b99130659022a4f7f45f563084b6223861d3"}, ] [package.dependencies] @@ -1092,18 +1341,18 @@ pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_ traitlets = ">=5.3" [package.extras] -docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] [[package]] name = "jupyter-events" -version = "0.7.0" +version = "0.9.0" description = "Jupyter Event System library" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_events-0.7.0-py3-none-any.whl", hash = "sha256:4753da434c13a37c3f3c89b500afa0c0a6241633441421f6adafe2fb2e2b924e"}, - {file = "jupyter_events-0.7.0.tar.gz", hash = "sha256:7be27f54b8388c03eefea123a4f79247c5b9381c49fb1cd48615ee191eb12615"}, + {file = "jupyter_events-0.9.0-py3-none-any.whl", hash = "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf"}, + {file = "jupyter_events-0.9.0.tar.gz", hash = "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399"}, ] [package.dependencies] @@ -1137,13 +1386,13 @@ jupyter-server = ">=1.1.2" [[package]] name = "jupyter-server" -version = "2.7.0" +version = "2.10.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_server-2.7.0-py3-none-any.whl", hash = "sha256:6a77912aff643e53fa14bdb2634884b52b784a4be77ce8e93f7283faed0f0849"}, - {file = "jupyter_server-2.7.0.tar.gz", hash = "sha256:36da0a266d31a41ac335a366c88933c17dfa5bb817a48f5c02c16d303bc9477f"}, + {file = "jupyter_server-2.10.0-py3-none-any.whl", hash = "sha256:dde56c9bc3cb52d7b72cc0f696d15d7163603526f1a758eb4a27405b73eab2a5"}, + {file = "jupyter_server-2.10.0.tar.gz", hash = "sha256:47b8f5e63440125cb1bb8957bf12b18453ee5ed9efe42d2f7b2ca66a7019a278"}, ] [package.dependencies] @@ -1161,7 +1410,7 @@ packaging = "*" prometheus-client = "*" pywinpty = {version = "*", markers = "os_name == \"nt\""} pyzmq = ">=24" -send2trash = "*" +send2trash = ">=1.8.2" terminado = ">=0.8.3" tornado = ">=6.2.0" traitlets = ">=5.6.0" @@ -1192,19 +1441,18 @@ test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", [[package]] name = "jupyterlab" -version = "4.0.4" +version = "4.0.8" description = "JupyterLab computational environment" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.0.4-py3-none-any.whl", hash = "sha256:23eef35d22be8f2ad9b873ec41ceb2e8c3b0dc8ae740c0f973e2de09e587530f"}, - {file = "jupyterlab-4.0.4.tar.gz", hash = "sha256:049449a56d93202ed204e0e86f96f5a3447a08cfc09fb012fd239e178651cb34"}, + {file = "jupyterlab-4.0.8-py3-none-any.whl", hash = "sha256:2ff5aa2a51eb21df241d6011c236e88bd1ff9a5dbb75bebc54472f9c18bfffa4"}, + {file = "jupyterlab-4.0.8.tar.gz", hash = "sha256:c4fe93f977bcc987bd395d7fae5ab02e0c042bf4e0f7c95196f3e2e578c2fb3a"}, ] [package.dependencies] async-lru = ">=1.0.0" importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -importlib-resources = {version = ">=1.4", markers = "python_version < \"3.9\""} ipykernel = "*" jinja2 = ">=3.0.3" jupyter-core = "*" @@ -1218,8 +1466,8 @@ tornado = ">=6.2.0" traitlets = "*" [package.extras] -dev = ["black[jupyter] (==23.3.0)", "build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.0.271)"] -docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-tornasync", "sphinx (>=1.8)", "sphinx-copybutton"] +dev = ["black[jupyter] (==23.10.1)", "build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.0.292)"] +docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-tornasync", "sphinx (>=1.8,<7.2.0)", "sphinx-copybutton"] docs-screenshots = ["altair (==5.0.1)", "ipython (==8.14.0)", "ipywidgets (==8.0.6)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post0)", "matplotlib (==3.7.1)", "nbconvert (>=7.0.0)", "pandas (==2.0.2)", "scipy (==1.10.1)", "vega-datasets (==0.9.0)"] test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] @@ -1236,13 +1484,13 @@ files = [ [[package]] name = "jupyterlab-server" -version = "2.24.0" +version = "2.25.0" description = "A set of server components for JupyterLab and JupyterLab like applications." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "jupyterlab_server-2.24.0-py3-none-any.whl", hash = "sha256:5f077e142bb8dc9b843d960f940c513581bceca3793a0d80f9c67d9522c4e876"}, - {file = "jupyterlab_server-2.24.0.tar.gz", hash = "sha256:4e6f99e0a5579bbbc32e449c4dbb039561d4f1a7827d5733273ed56738f21f07"}, + {file = "jupyterlab_server-2.25.0-py3-none-any.whl", hash = "sha256:c9f67a98b295c5dee87f41551b0558374e45d449f3edca153dd722140630dcb2"}, + {file = "jupyterlab_server-2.25.0.tar.gz", hash = "sha256:77c2f1f282d610f95e496e20d5bf1d2a7706826dfb7b18f3378ae2870d272fb7"}, ] [package.dependencies] @@ -1250,29 +1498,135 @@ babel = ">=2.10" importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} jinja2 = ">=3.0.3" json5 = ">=0.9.0" -jsonschema = ">=4.17.3" +jsonschema = ">=4.18.0" jupyter-server = ">=1.21,<3" packaging = ">=21.3" -requests = ">=2.28" +requests = ">=2.31" [package.extras] docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] -openapi = ["openapi-core (>=0.16.1,<0.17.0)", "ruamel-yaml"] -test = ["hatch", "ipykernel", "jupyterlab-server[openapi]", "openapi-spec-validator (>=0.5.1,<0.7.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] +openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] +test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.7.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] [[package]] -name = "log-symbols" -version = "0.0.14" -description = "Colored symbols for various log levels for Python" +name = "levenshtein" +version = "0.23.0" +description = "Python extension for computing string edit distances and similarities." optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "log_symbols-0.0.14-py3-none-any.whl", hash = "sha256:4952106ff8b605ab7d5081dd2c7e6ca7374584eff7086f499c06edd1ce56dcca"}, - {file = "log_symbols-0.0.14.tar.gz", hash = "sha256:cf0bbc6fe1a8e53f0d174a716bc625c4f87043cc21eb55dd8a740cfe22680556"}, + {file = "Levenshtein-0.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2d3f2b8e67915268c49f0faa29a29a8c26811a4b46bd96dd043bc8557428065d"}, + {file = "Levenshtein-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10b980dcc865f8fe04723e448fac4e9a32cbd21fb41ab548725a2d30d9a22429"}, + {file = "Levenshtein-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8c8c48217b2733ae5bd8ef14e0ad730a30d113c84dc2cfc441435ef900732b"}, + {file = "Levenshtein-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:854a0962d6f5852b891b6b5789467d1e72b69722df1bc0dd85cbf70efeddc83f"}, + {file = "Levenshtein-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5abc4ee22340625ec401d6f11136afa387d377b7aa5dad475618ffce1f0d2e2f"}, + {file = "Levenshtein-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20f79946481052bbbee5284c755aa0a5feb10a344d530e014a50cb9544745dd3"}, + {file = "Levenshtein-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6084fc909a218843bb55723fde64a8a58bac7e9086854c37134269b3f946aeb"}, + {file = "Levenshtein-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0acaae1c20c8ed37915b0cde14b5c77d5a3ba08e05f9ce4f55e16843de9c7bb8"}, + {file = "Levenshtein-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54a51036b02222912a029a6efa2ce1ee2be49c88e0bb32995e0999feba183913"}, + {file = "Levenshtein-0.23.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:68ec2ef442621027f290cb5cef80962889d86fff3e405e5d21c7f9634d096bbf"}, + {file = "Levenshtein-0.23.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d8ba18720bafa4a65f07baba8c3228e98a6f8da7455de4ec58ae06de4ecdaea0"}, + {file = "Levenshtein-0.23.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:af1b70cac87c5627cd2227823318fa39c64fbfed686c8c3c2f713f72bc25813b"}, + {file = "Levenshtein-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fe2810c42cc5bca15eeb4a2eb192b1f74ceef6005876b1a166ecbde1defbd22d"}, + {file = "Levenshtein-0.23.0-cp310-cp310-win32.whl", hash = "sha256:89a0829637221ff0fd6ce63dfbe59e22b25eeba914d50e191519b9d9b8ccf3e9"}, + {file = "Levenshtein-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:b8bc81d59205558326ac75c97e236fd72b8bcdf63fcdbfb7387bd63da242b209"}, + {file = "Levenshtein-0.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:151046d1c70bdf01ede01f46467c11151ceb9c86fefaf400978b990110d0a55e"}, + {file = "Levenshtein-0.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7e992de09832ee11b35910c05c1581e8a9ab8ea9737c2f582c7eb540e2cdde69"}, + {file = "Levenshtein-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5e3461d29b3188518464bd3121fc64635ff884ae544147b5d326ce13c50d36"}, + {file = "Levenshtein-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1772c4491f6ef6504e591c0dd60e1e418b2015074c3d56ee93af6b1a019906ee"}, + {file = "Levenshtein-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e125c92cd0ac3b53c4c80fcf2890d89a1d19ff4979dc804031773bc90223859f"}, + {file = "Levenshtein-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d2f608c5ce7b9a0a0af3c910f43ea7eb060296655aa127b10e4af7be5559303"}, + {file = "Levenshtein-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe5c3b7d96a838d9d86bb4ec57495749965e598a3ea2c5b877a61aa09478bab7"}, + {file = "Levenshtein-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249eaa351b5355b3e3ca7e3a8e2a0bca7bff4491c89a0b0fa3b9d0614cf3efeb"}, + {file = "Levenshtein-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0033a243510e829ead1ae62720389c9f17d422a98c0525da593d239a9ff434e5"}, + {file = "Levenshtein-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f956ad16cab9267c0e7d382a37b4baca6bf3bf1637a76fa95fdbf9dd3ea774d7"}, + {file = "Levenshtein-0.23.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3789e4aeaeb830d944e1f502f9aa9024e9cd36b68d6eba6892df7972b884abd7"}, + {file = "Levenshtein-0.23.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:f91335f056b9a548070cb87b3e6cf017a18b27d34a83f222bdf46a5360615f11"}, + {file = "Levenshtein-0.23.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3497eda857e70863a090673a82442877914c57b5f04673c782642e69caf25c0c"}, + {file = "Levenshtein-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5e17ea59115179c269c6daea52415faaf54c6340d4ad91d9012750845a445a13"}, + {file = "Levenshtein-0.23.0-cp311-cp311-win32.whl", hash = "sha256:da2063cee1fbecc09e1692e7c4de7624fd4c47a54ee7588b7ea20540f8f8d779"}, + {file = "Levenshtein-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:4d3b9c9e2852eca20de6bd8ca7f47d817a056993fd4927a4d50728b62315376b"}, + {file = "Levenshtein-0.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:ef2e3e93ae612ac87c3a28f08e8544b707d67e99f9624e420762a7c275bb13c5"}, + {file = "Levenshtein-0.23.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:85220b27a47df4a5106ef13d43b6181d73da77d3f78646ec7251a0c5eb08ac40"}, + {file = "Levenshtein-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bb77b3ade7f256ca5882450aaf129be79b11e074505b56c5997af5058a8f834"}, + {file = "Levenshtein-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99b487f08c32530ee608e8aab0c4075048262a7f5a6e113bac495b05154ae427"}, + {file = "Levenshtein-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f91d0a5d3696e373cae08c80ec99a4ff041e562e55648ebe582725cba555190"}, + {file = "Levenshtein-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fddda71ae372cd835ffd64990f0d0b160409e881bf8722b6c5dc15dc4239d7db"}, + {file = "Levenshtein-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7664bcf9a12e62c672a926c4579f74689507beaa24378ad7664f0603b0dafd20"}, + {file = "Levenshtein-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6d07539502610ee8d6437a77840feedefa47044ab0f35cd3bc37adfc63753bd"}, + {file = "Levenshtein-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:830a74b6a045a13e1b1d28af62af9878aeae8e7386f14888c84084d577b92771"}, + {file = "Levenshtein-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f29cbd0c172a8fc1d51eaacd163bdc11596aded5a90db617e6b778c2258c7006"}, + {file = "Levenshtein-0.23.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:df0704fd6a30a7c27c03655ae6dc77345c1655634fe59654e74bb06a3c7c1357"}, + {file = "Levenshtein-0.23.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:0ab52358f54ee48ad7656a773a0c72ef89bb9ba5acc6b380cfffd619fb223a23"}, + {file = "Levenshtein-0.23.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:f0a86394c9440e23a29f48f2bbc460de7b19950f46ec2bea3be8c2090839bb29"}, + {file = "Levenshtein-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a689e6e0514f48a434e7ee44cc1eb29c34b21c51c57accb304eac97fba87bf48"}, + {file = "Levenshtein-0.23.0-cp312-cp312-win32.whl", hash = "sha256:2d3229c1336498c2b72842dd4c850dff1040588a5468abe5104444a372c1a573"}, + {file = "Levenshtein-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:5b9b6a8509415bc214d33f5828d7c700c80292ea25f9d9e8cba95ad5a74b3cdf"}, + {file = "Levenshtein-0.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:5a61606bad3afb9fcec0a2a21871319c3f7da933658d2e0e6e55ab4a34814f48"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:078bb87ea32a28825900f5d29ba2946dc9cf73094dfed4ba5d70f042f2435609"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26b468455f29fb255b62c22522026985cb3181a02e570c8b37659fedb1bc0170"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc62b2f74e4050f0a1261a34e11fd9e7c6d80a45679c0e02ac452b16fda7b34"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8b65b0b4e8b88e8326cdbfd3ec119953a0b10b514947f4bd03a4ed0fc58f6471"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bccaf7f16b9da5edb608705edc3c38401e83ea0ff04c6375f25c6fc15e88f9b3"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b35f752d04c0828fb1877d9bee5d1786b2574ec3b1cba0533008aa1ff203712"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2c32f86bb54b9744c95c27b5398f108158cc6a87c5dbb3ad5a344634bf9b07d3"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fa8b65f483cdd3114d41736e0e9c3841e7ee6ac5861bae3d26e21e19faa229ff"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:9fdf67c10a5403b1668d1b6ade7744d20790367b10866d27394e64716992c3e4"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:eb6dfba3264b38a3e95cac8e64f318ad4c27e2232f6c566a69b3b113115c06ef"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8541f1b7516290f6ccc3faac9aea681183c5d0b1f8078b957ae41dfbd5b93b58"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-win32.whl", hash = "sha256:f35b138bb698b29467627318af9258ec677e021e0816ae0da9b84f9164ed7518"}, + {file = "Levenshtein-0.23.0-cp37-cp37m-win_amd64.whl", hash = "sha256:936320113eadd3d71d9ce371d9027b1c56299001b48ed197a0db4140e1d13bbd"}, + {file = "Levenshtein-0.23.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:da64e19e1ec0c1e8a1cd77c4802a0d656f8a6e0ab7a1479d435a9d2575e473f8"}, + {file = "Levenshtein-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e729781b6134a6e3b380a2d8eae0843a230fc3716bdc8bba4cde2b0ce260982b"}, + {file = "Levenshtein-0.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:97d0841a2682a3c302f70537e8316077e56795062c6f629714f5d0771f7a5838"}, + {file = "Levenshtein-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:727a679d19b18a0b4532abf87f9788070bcd94b78ff07135abe41c716bccbb7d"}, + {file = "Levenshtein-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48c8388a321e55c1feeef543b49fc969be6a5cf6bcf4dcb5dced82f5fea6793c"}, + {file = "Levenshtein-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58f8b8f5d4348e470e8c0d4e9f7c23a8f7cfc3cbd8024cc5a1fc68cc81f7d6cb"}, + {file = "Levenshtein-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:549170257f052289df93a13526877cb397d351b0c8a3e4c9ae3936aeafd8ad17"}, + {file = "Levenshtein-0.23.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5d32f3b28065e430d54781e1f3b31198b6bfc21e6d565f0c06218e7618884551"}, + {file = "Levenshtein-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecc8c12e710212c4d959fda3a52377ae6a30fa204822f2e63fd430e018be3d6f"}, + {file = "Levenshtein-0.23.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:88b47fbabbd9cee8be5d6c26ac4d599dd66146628b9ca23d9f4f209c4e3e143e"}, + {file = "Levenshtein-0.23.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:5106bce4e94bc1ae137b50d1e5f49b726997be879baf66eafc6ee365adec3db5"}, + {file = "Levenshtein-0.23.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:d36634491e06234672492715bc6ff7be61aeaf44822cb366dbbe9d924f2614cc"}, + {file = "Levenshtein-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a591c94f7047d105c29630e7606a2b007f96cf98651fb93e9f820272b0361e02"}, + {file = "Levenshtein-0.23.0-cp38-cp38-win32.whl", hash = "sha256:9fce199af18d459c8f19747501d1e852d86550162e7ccdc2c193b44e55d9bbfb"}, + {file = "Levenshtein-0.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:b4303024ffea56fd164a68f80f23df9e9158620593b7515c73c885285ec6a558"}, + {file = "Levenshtein-0.23.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:73aed4856e672ab12769472cf7aece04b4a6813eb917390d22e58002576136e0"}, + {file = "Levenshtein-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e93dbfdf08360b4261a2385340d26ac491a1bf9bd17bf22a59636705d2d6479"}, + {file = "Levenshtein-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b847f716fc314cf83d128fedc2c16ffdff5431a439db412465c4b0ac1762478e"}, + {file = "Levenshtein-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0d567beb47cd403394bf241df8cfc14499279d0f3a6675f89b667249841aab1"}, + {file = "Levenshtein-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e13857d870048ff58ce95c8eb32e10285918ee74e1c9bf1825af08dd49b0bc6"}, + {file = "Levenshtein-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c4250f507bb1b7501f7187af8345e200cbc1a58ceb3730bf4e3fdc371fe732c0"}, + {file = "Levenshtein-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fb90de8a279ce83797bcafbbfe6d641362c3c96148c17d8c8612dddb02744c5"}, + {file = "Levenshtein-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:039dc7323fd28de44d6c13a334a34ab1ddee598762cb2dae3223ca1f083577f9"}, + {file = "Levenshtein-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d5739f513cb02039f970054eabeccc62696ed2a1afff6e17f75d5492a3ed8d74"}, + {file = "Levenshtein-0.23.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2a3801a0463791440b4350b734e4ec0dbc140b675a3ce9ef936feed06b23c58d"}, + {file = "Levenshtein-0.23.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:606ba30bbdf06fc51b0a763760e113dea9085011a2399cf4b1f72316836e4d03"}, + {file = "Levenshtein-0.23.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:14c5f90859e512004cc25b50b79c7ae6f068ebe69a7213a9018c83bd88c1305b"}, + {file = "Levenshtein-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c8a75233798e334fd53305656ffcf0601f60e9ff461af759677006c07c060939"}, + {file = "Levenshtein-0.23.0-cp39-cp39-win32.whl", hash = "sha256:9a271d50643cf927bfc002d397b4f715abdbc6ca46a5a93d1d66a033eabaa5f3"}, + {file = "Levenshtein-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:684118d9e070e00df91bc4bd276e0559df7bb2319659699dafda16b5a0229553"}, + {file = "Levenshtein-0.23.0-cp39-cp39-win_arm64.whl", hash = "sha256:98412a7bdc49c7fbb493be3c3e7fd2f874eff29ed636b8c0eca325a1e3e74264"}, + {file = "Levenshtein-0.23.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:760c964ff0be8dea5f7eda20314cf66238fdd0fec63f1ce9c474736bb2904924"}, + {file = "Levenshtein-0.23.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de42400ea86e3e8be3dc7f9b3b9ed51da7fd06dc2f3a426d7effd7fbf35de848"}, + {file = "Levenshtein-0.23.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2080ee52aeac03854a0c6e73d4214d5be2120bdd5f16def4394f9fbc5666e04"}, + {file = "Levenshtein-0.23.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb00ecae116e62801613788d8dc3938df26f582efce5a3d3320e9692575e7c4d"}, + {file = "Levenshtein-0.23.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:f351694f65d4df48ee2578d977d37a0560bd3e8535e85dfe59df6abeed12bd6e"}, + {file = "Levenshtein-0.23.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:34859c5ff7261f25daea810b5439ad80624cbb9021381df2c390c20eb75b79c6"}, + {file = "Levenshtein-0.23.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ece1d077d9006cff329bb95eb9704f407933ff4484e5d008a384d268b993439"}, + {file = "Levenshtein-0.23.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35ce82403730dd2a3b397abb2535786af06835fcf3dc40dc8ea67ed589bbd010"}, + {file = "Levenshtein-0.23.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a88aa3b5f49aeca08080b6c3fa7e1095d939eafb13f42dbe8f1b27ff405fd43"}, + {file = "Levenshtein-0.23.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:748fbba6d9c04fc39b956b44ccde8eb14f34e21ab68a0f9965aae3fa5c8fdb5e"}, + {file = "Levenshtein-0.23.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:60440d583986e344119a15cea9e12099f3a07bdddc1c98ec2dda69e96429fb25"}, + {file = "Levenshtein-0.23.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b048a83b07fc869648460f2af1255e265326d75965157a165dde2d9ba64fa73"}, + {file = "Levenshtein-0.23.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4be0e5e742f6a299acf7aa8d2e5cfca946bcff224383fd451d894e79499f0a46"}, + {file = "Levenshtein-0.23.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7a626637c1d967e3e504ced353f89c2a9f6c8b4b4dbf348fdd3e1daa947a23c"}, + {file = "Levenshtein-0.23.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:88d8a13cf310cfc893e3734f8e7e42ef20c52780506e9bdb96e76a8b75e3ba20"}, + {file = "Levenshtein-0.23.0.tar.gz", hash = "sha256:de7ccc31a471ea5bfafabe804c12a63e18b4511afc1014f23c3cc7be8c70d3bd"}, ] [package.dependencies] -colorama = ">=0.3.9" +rapidfuzz = ">=3.1.0,<4.0.0" [[package]] name = "markdown-it-py" @@ -1371,6 +1725,17 @@ files = [ [package.dependencies] traitlets = "*" +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -1384,15 +1749,49 @@ files = [ [[package]] name = "mistune" -version = "3.0.1" +version = "3.0.2" description = "A sane and fast Markdown parser with useful plugins and renderers" optional = false python-versions = ">=3.7" files = [ - {file = "mistune-3.0.1-py3-none-any.whl", hash = "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6"}, - {file = "mistune-3.0.1.tar.gz", hash = "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c"}, + {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, + {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, +] + +[[package]] +name = "modal" +version = "0.55.4073" +description = "Python client library for Modal" +optional = false +python-versions = ">=3.7" +files = [ + {file = "modal-0.55.4073-py3-none-any.whl", hash = "sha256:e3ed66aa64538b606d69b76cef527670f1c3d1163cc01a4630aa07889f96dc92"}, ] +[package.dependencies] +aiohttp = "*" +aiostream = "*" +asgiref = "*" +certifi = "*" +click = ">=8.1.0" +cloudpickle = [ + {version = ">=2.0.0,<2.1.0", markers = "python_version < \"3.11\""}, + {version = ">=2.2.0,<2.3.0", markers = "python_version >= \"3.11\""}, +] +fastapi = "*" +grpclib = "0.4.3" +importlib-metadata = ">=3.6.0" +protobuf = ">=3.19,<4.24.0 || >4.24.0,<5.0" +rich = ">=12.0.0" +synchronicity = ">=0.5.3,<0.6.0" +tblib = ">=1.7.0" +toml = "*" +typer = ">=0.9.0,<0.10.0" +types-certifi = "*" +types-toml = "*" +typing-extensions = ">=4.6,<5.0" +watchfiles = "*" + [[package]] name = "multidict" version = "6.0.4" @@ -1478,13 +1877,13 @@ files = [ [[package]] name = "nbclient" -version = "0.8.0" +version = "0.9.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." optional = false python-versions = ">=3.8.0" files = [ - {file = "nbclient-0.8.0-py3-none-any.whl", hash = "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548"}, - {file = "nbclient-0.8.0.tar.gz", hash = "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55"}, + {file = "nbclient-0.9.0-py3-none-any.whl", hash = "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15"}, + {file = "nbclient-0.9.0.tar.gz", hash = "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e"}, ] [package.dependencies] @@ -1500,13 +1899,13 @@ test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>= [[package]] name = "nbconvert" -version = "7.7.3" +version = "7.11.0" description = "Converting Jupyter Notebooks" optional = false python-versions = ">=3.8" files = [ - {file = "nbconvert-7.7.3-py3-none-any.whl", hash = "sha256:3022adadff3f86578a47fab7c2228bb3ca9c56a24345642a22f917f6168b48fc"}, - {file = "nbconvert-7.7.3.tar.gz", hash = "sha256:4a5996bf5f3cd16aa0431897ba1aa4c64842c2079f434b3dc6b8c4b252ef3355"}, + {file = "nbconvert-7.11.0-py3-none-any.whl", hash = "sha256:d1d417b7f34a4e38887f8da5bdfd12372adf3b80f995d57556cb0972c68909fe"}, + {file = "nbconvert-7.11.0.tar.gz", hash = "sha256:abedc01cf543177ffde0bfc2a69726d5a478f6af10a332fc1bf29fcb4f0cf000"}, ] [package.dependencies] @@ -1533,7 +1932,7 @@ docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sp qtpdf = ["nbconvert[qtpng]"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] +test = ["flaky", "ipykernel", "ipywidgets (>=7)", "pytest"] webpdf = ["playwright"] [[package]] @@ -1559,15 +1958,33 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] [[package]] name = "nest-asyncio" -version = "1.5.7" +version = "1.5.8" description = "Patch asyncio to allow nested event loops" optional = false python-versions = ">=3.5" files = [ - {file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"}, - {file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"}, + {file = "nest_asyncio-1.5.8-py3-none-any.whl", hash = "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d"}, + {file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"}, ] +[[package]] +name = "networkx" +version = "3.2.1" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.9" +files = [ + {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, + {file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"}, +] + +[package.extras] +default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + [[package]] name = "nodeenv" version = "1.8.0" @@ -1601,50 +2018,54 @@ test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync" [[package]] name = "numpy" -version = "1.24.4" +version = "1.26.1" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.8" -files = [ - {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, - {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, - {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, - {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, - {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, - {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, - {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, - {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, - {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, - {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, - {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +python-versions = "<3.13,>=3.9" +files = [ + {file = "numpy-1.26.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82e871307a6331b5f09efda3c22e03c095d957f04bf6bc1804f30048d0e5e7af"}, + {file = "numpy-1.26.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdd9ec98f0063d93baeb01aad472a1a0840dee302842a2746a7a8e92968f9575"}, + {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d78f269e0c4fd365fc2992c00353e4530d274ba68f15e968d8bc3c69ce5f5244"}, + {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ab9163ca8aeb7fd32fe93866490654d2f7dda4e61bc6297bf72ce07fdc02f67"}, + {file = "numpy-1.26.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:78ca54b2f9daffa5f323f34cdf21e1d9779a54073f0018a3094ab907938331a2"}, + {file = "numpy-1.26.1-cp310-cp310-win32.whl", hash = "sha256:d1cfc92db6af1fd37a7bb58e55c8383b4aa1ba23d012bdbba26b4bcca45ac297"}, + {file = "numpy-1.26.1-cp310-cp310-win_amd64.whl", hash = "sha256:d2984cb6caaf05294b8466966627e80bf6c7afd273279077679cb010acb0e5ab"}, + {file = "numpy-1.26.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cd7837b2b734ca72959a1caf3309457a318c934abef7a43a14bb984e574bbb9a"}, + {file = "numpy-1.26.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c59c046c31a43310ad0199d6299e59f57a289e22f0f36951ced1c9eac3665b9"}, + {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d58e8c51a7cf43090d124d5073bc29ab2755822181fcad978b12e144e5e5a4b3"}, + {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6081aed64714a18c72b168a9276095ef9155dd7888b9e74b5987808f0dd0a974"}, + {file = "numpy-1.26.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:97e5d6a9f0702c2863aaabf19f0d1b6c2628fbe476438ce0b5ce06e83085064c"}, + {file = "numpy-1.26.1-cp311-cp311-win32.whl", hash = "sha256:b9d45d1dbb9de84894cc50efece5b09939752a2d75aab3a8b0cef6f3a35ecd6b"}, + {file = "numpy-1.26.1-cp311-cp311-win_amd64.whl", hash = "sha256:3649d566e2fc067597125428db15d60eb42a4e0897fc48d28cb75dc2e0454e53"}, + {file = "numpy-1.26.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d1bd82d539607951cac963388534da3b7ea0e18b149a53cf883d8f699178c0f"}, + {file = "numpy-1.26.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:afd5ced4e5a96dac6725daeb5242a35494243f2239244fad10a90ce58b071d24"}, + {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03fb25610ef560a6201ff06df4f8105292ba56e7cdd196ea350d123fc32e24e"}, + {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcfaf015b79d1f9f9c9fd0731a907407dc3e45769262d657d754c3a028586124"}, + {file = "numpy-1.26.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e509cbc488c735b43b5ffea175235cec24bbc57b227ef1acc691725beb230d1c"}, + {file = "numpy-1.26.1-cp312-cp312-win32.whl", hash = "sha256:af22f3d8e228d84d1c0c44c1fbdeb80f97a15a0abe4f080960393a00db733b66"}, + {file = "numpy-1.26.1-cp312-cp312-win_amd64.whl", hash = "sha256:9f42284ebf91bdf32fafac29d29d4c07e5e9d1af862ea73686581773ef9e73a7"}, + {file = "numpy-1.26.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb894accfd16b867d8643fc2ba6c8617c78ba2828051e9a69511644ce86ce83e"}, + {file = "numpy-1.26.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e44ccb93f30c75dfc0c3aa3ce38f33486a75ec9abadabd4e59f114994a9c4617"}, + {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9696aa2e35cc41e398a6d42d147cf326f8f9d81befcb399bc1ed7ffea339b64e"}, + {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5b411040beead47a228bde3b2241100454a6abde9df139ed087bd73fc0a4908"}, + {file = "numpy-1.26.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1e11668d6f756ca5ef534b5be8653d16c5352cbb210a5c2a79ff288e937010d5"}, + {file = "numpy-1.26.1-cp39-cp39-win32.whl", hash = "sha256:d1d2c6b7dd618c41e202c59c1413ef9b2c8e8a15f5039e344af64195459e3104"}, + {file = "numpy-1.26.1-cp39-cp39-win_amd64.whl", hash = "sha256:59227c981d43425ca5e5c01094d59eb14e8772ce6975d4b2fc1e106a833d5ae2"}, + {file = "numpy-1.26.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:06934e1a22c54636a059215d6da99e23286424f316fddd979f5071093b648668"}, + {file = "numpy-1.26.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76ff661a867d9272cd2a99eed002470f46dbe0943a5ffd140f49be84f68ffc42"}, + {file = "numpy-1.26.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6965888d65d2848e8768824ca8288db0a81263c1efccec881cb35a0d805fcd2f"}, + {file = "numpy-1.26.1.tar.gz", hash = "sha256:c8c6c72d4a9f831f328efb1312642a1cafafaa88981d9ab76368d50d07d93cbe"}, ] [[package]] name = "openai" -version = "0.27.8" +version = "0.27.10" description = "Python client library for the OpenAI API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-0.27.8-py3-none-any.whl", hash = "sha256:e0a7c2f7da26bdbe5354b03c6d4b82a2f34bd4458c7a17ae1a7092c3e397e03c"}, - {file = "openai-0.27.8.tar.gz", hash = "sha256:2483095c7db1eee274cebac79e315a986c4e55207bb4fa7b82d185b3a2ed9536"}, + {file = "openai-0.27.10-py3-none-any.whl", hash = "sha256:beabd1757e3286fa166dde3b70ebb5ad8081af046876b47c14c41e203ed22a14"}, + {file = "openai-0.27.10.tar.gz", hash = "sha256:60e09edf7100080283688748c6803b7b3b52d5a55d21890f3815292a0552d83b"}, ] [package.dependencies] @@ -1671,81 +2092,81 @@ files = [ [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] name = "pandas" -version = "2.0.3" +version = "2.1.2" description = "Powerful data structures for data analysis, time series, and statistics" optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8"}, - {file = "pandas-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0"}, - {file = "pandas-2.0.3-cp310-cp310-win32.whl", hash = "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210"}, - {file = "pandas-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df"}, - {file = "pandas-2.0.3-cp311-cp311-win32.whl", hash = "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd"}, - {file = "pandas-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0"}, - {file = "pandas-2.0.3-cp38-cp38-win32.whl", hash = "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02"}, - {file = "pandas-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641"}, - {file = "pandas-2.0.3-cp39-cp39-win32.whl", hash = "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682"}, - {file = "pandas-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc"}, - {file = "pandas-2.0.3.tar.gz", hash = "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c"}, +python-versions = ">=3.9" +files = [ + {file = "pandas-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24057459f19db9ebb02984c6fdd164a970b31a95f38e4a49cf7615b36a1b532c"}, + {file = "pandas-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6cf8fcc8a63d333970b950a7331a30544cf59b1a97baf0a7409e09eafc1ac38"}, + {file = "pandas-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ae6ffbd9d614c20d028c7117ee911fc4e266b4dca2065d5c5909e401f8ff683"}, + {file = "pandas-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eff794eeb7883c5aefb1ed572e7ff533ae779f6c6277849eab9e77986e352688"}, + {file = "pandas-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:02954e285e8e2f4006b6f22be6f0df1f1c3c97adbb7ed211c6b483426f20d5c8"}, + {file = "pandas-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:5b40c9f494e1f27588c369b9e4a6ca19cd924b3a0e1ef9ef1a8e30a07a438f43"}, + {file = "pandas-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:08d287b68fd28906a94564f15118a7ca8c242e50ae7f8bd91130c362b2108a81"}, + {file = "pandas-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bbd98dcdcd32f408947afdb3f7434fade6edd408c3077bbce7bd840d654d92c6"}, + {file = "pandas-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e90c95abb3285d06f6e4feedafc134306a8eced93cb78e08cf50e224d5ce22e2"}, + {file = "pandas-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52867d69a54e71666cd184b04e839cff7dfc8ed0cd6b936995117fdae8790b69"}, + {file = "pandas-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d0382645ede2fde352da2a885aac28ec37d38587864c0689b4b2361d17b1d4c"}, + {file = "pandas-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:65177d1c519b55e5b7f094c660ed357bb7d86e799686bb71653b8a4803d8ff0d"}, + {file = "pandas-2.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5aa6b86802e8cf7716bf4b4b5a3c99b12d34e9c6a9d06dad254447a620437931"}, + {file = "pandas-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d594e2ce51b8e0b4074e6644758865dc2bb13fd654450c1eae51201260a539f1"}, + {file = "pandas-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3223f997b6d2ebf9c010260cf3d889848a93f5d22bb4d14cd32638b3d8bba7ad"}, + {file = "pandas-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4944dc004ca6cc701dfa19afb8bdb26ad36b9bed5bcec617d2a11e9cae6902"}, + {file = "pandas-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3f76280ce8ec216dde336e55b2b82e883401cf466da0fe3be317c03fb8ee7c7d"}, + {file = "pandas-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:7ad20d24acf3a0042512b7e8d8fdc2e827126ed519d6bd1ed8e6c14ec8a2c813"}, + {file = "pandas-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:021f09c15e1381e202d95d4a21ece8e7f2bf1388b6d7e9cae09dfe27bd2043d1"}, + {file = "pandas-2.1.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7f12b2de0060b0b858cfec0016e7d980ae5bae455a1746bfcc70929100ee633"}, + {file = "pandas-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c166b9bb27c1715bed94495d9598a7f02950b4749dba9349c1dd2cbf10729d"}, + {file = "pandas-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25c9976c17311388fcd953cb3d0697999b2205333f4e11e669d90ff8d830d429"}, + {file = "pandas-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:851b5afbb0d62f6129ae891b533aa508cc357d5892c240c91933d945fff15731"}, + {file = "pandas-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:e78507adcc730533619de07bfdd1c62b2918a68cd4419ea386e28abf7f6a1e5c"}, + {file = "pandas-2.1.2.tar.gz", hash = "sha256:52897edc2774d2779fbeb6880d2cfb305daa0b1a29c16b91f531a18918a6e0f3"}, ] [package.dependencies] numpy = [ - {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, - {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, + {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" tzdata = ">=2022.1" [package.extras] -all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"] -aws = ["s3fs (>=2021.08.0)"] -clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"] -compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"] -computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"] +all = ["PyQt5 (>=5.15.6)", "SQLAlchemy (>=1.4.36)", "beautifulsoup4 (>=4.11.1)", "bottleneck (>=1.3.4)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=0.8.1)", "fsspec (>=2022.05.0)", "gcsfs (>=2022.05.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.8.0)", "matplotlib (>=3.6.1)", "numba (>=0.55.2)", "numexpr (>=2.8.0)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pandas-gbq (>=0.17.5)", "psycopg2 (>=2.9.3)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.5)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "pyxlsb (>=1.0.9)", "qtpy (>=2.2.0)", "s3fs (>=2022.05.0)", "scipy (>=1.8.1)", "tables (>=3.7.0)", "tabulate (>=0.8.10)", "xarray (>=2022.03.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)", "zstandard (>=0.17.0)"] +aws = ["s3fs (>=2022.05.0)"] +clipboard = ["PyQt5 (>=5.15.6)", "qtpy (>=2.2.0)"] +compression = ["zstandard (>=0.17.0)"] +computation = ["scipy (>=1.8.1)", "xarray (>=2022.03.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pyxlsb (>=1.0.9)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)"] feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2021.07.0)"] -gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"] -hdf5 = ["tables (>=3.6.1)"] -html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"] -mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"] +fss = ["fsspec (>=2022.05.0)"] +gcp = ["gcsfs (>=2022.05.0)", "pandas-gbq (>=0.17.5)"] +hdf5 = ["tables (>=3.7.0)"] +html = ["beautifulsoup4 (>=4.11.1)", "html5lib (>=1.1)", "lxml (>=4.8.0)"] +mysql = ["SQLAlchemy (>=1.4.36)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.8.10)"] parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"] +performance = ["bottleneck (>=1.3.4)", "numba (>=0.55.2)", "numexpr (>=2.8.0)"] plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"] -spss = ["pyreadstat (>=1.1.2)"] -sql-other = ["SQLAlchemy (>=1.4.16)"] -test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.6.3)"] +postgresql = ["SQLAlchemy (>=1.4.36)", "psycopg2 (>=2.9.3)"] +spss = ["pyreadstat (>=1.1.5)"] +sql-other = ["SQLAlchemy (>=1.4.36)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.8.0)"] [[package]] name = "pandocfilters" @@ -1798,37 +2219,15 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -optional = false -python-versions = "*" -files = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] - -[[package]] -name = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, -] - [[package]] name = "platformdirs" -version = "3.10.0" +version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, + {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, ] [package.extras] @@ -1837,13 +2236,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pluggy" -version = "1.2.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] [package.extras] @@ -1852,13 +2251,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.3.3" +version = "3.5.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.8" files = [ - {file = "pre_commit-3.3.3-py2.py3-none-any.whl", hash = "sha256:10badb65d6a38caff29703362271d7dca483d01da88f9d7e05d0b97171c136cb"}, - {file = "pre_commit-3.3.3.tar.gz", hash = "sha256:a2256f489cd913d575c145132ae196fe335da32d91a8294b7afe6622335dd023"}, + {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, + {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, ] [package.dependencies] @@ -1870,13 +2269,13 @@ virtualenv = ">=20.10.0" [[package]] name = "prometheus-client" -version = "0.17.1" +version = "0.18.0" description = "Python client for the Prometheus monitoring system." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "prometheus_client-0.17.1-py3-none-any.whl", hash = "sha256:e537f37160f6807b8202a6fc4764cdd19bac5480ddd3e0d463c3002b34462101"}, - {file = "prometheus_client-0.17.1.tar.gz", hash = "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091"}, + {file = "prometheus_client-0.18.0-py3-none-any.whl", hash = "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184"}, + {file = "prometheus_client-0.18.0.tar.gz", hash = "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17"}, ] [package.extras] @@ -1896,27 +2295,49 @@ files = [ [package.dependencies] wcwidth = "*" +[[package]] +name = "protobuf" +version = "4.25.0" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-4.25.0-cp310-abi3-win32.whl", hash = "sha256:5c1203ac9f50e4853b0a0bfffd32c67118ef552a33942982eeab543f5c634395"}, + {file = "protobuf-4.25.0-cp310-abi3-win_amd64.whl", hash = "sha256:c40ff8f00aa737938c5378d461637d15c442a12275a81019cc2fef06d81c9419"}, + {file = "protobuf-4.25.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:cf21faba64cd2c9a3ed92b7a67f226296b10159dbb8fbc5e854fc90657d908e4"}, + {file = "protobuf-4.25.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:32ac2100b0e23412413d948c03060184d34a7c50b3e5d7524ee96ac2b10acf51"}, + {file = "protobuf-4.25.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:683dc44c61f2620b32ce4927de2108f3ebe8ccf2fd716e1e684e5a50da154054"}, + {file = "protobuf-4.25.0-cp38-cp38-win32.whl", hash = "sha256:1a3ba712877e6d37013cdc3476040ea1e313a6c2e1580836a94f76b3c176d575"}, + {file = "protobuf-4.25.0-cp38-cp38-win_amd64.whl", hash = "sha256:b2cf8b5d381f9378afe84618288b239e75665fe58d0f3fd5db400959274296e9"}, + {file = "protobuf-4.25.0-cp39-cp39-win32.whl", hash = "sha256:63714e79b761a37048c9701a37438aa29945cd2417a97076048232c1df07b701"}, + {file = "protobuf-4.25.0-cp39-cp39-win_amd64.whl", hash = "sha256:d94a33db8b7ddbd0af7c467475fb9fde0c705fb315a8433c0e2020942b863a1f"}, + {file = "protobuf-4.25.0-py3-none-any.whl", hash = "sha256:1a53d6f64b00eecf53b65ff4a8c23dc95df1fa1e97bb06b8122e5a64f49fc90a"}, + {file = "protobuf-4.25.0.tar.gz", hash = "sha256:68f7caf0d4f012fd194a301420cf6aa258366144d814f358c5b32558228afa7c"}, +] + [[package]] name = "psutil" -version = "5.9.5" +version = "5.9.6" description = "Cross-platform lib for process and system monitoring in Python." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, - {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, - {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, - {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, - {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, - {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, - {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, - {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "psutil-5.9.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d"}, + {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c"}, + {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28"}, + {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017"}, + {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c"}, + {file = "psutil-5.9.6-cp27-none-win32.whl", hash = "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9"}, + {file = "psutil-5.9.6-cp27-none-win_amd64.whl", hash = "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac"}, + {file = "psutil-5.9.6-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a"}, + {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c"}, + {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4"}, + {file = "psutil-5.9.6-cp36-cp36m-win32.whl", hash = "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602"}, + {file = "psutil-5.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa"}, + {file = "psutil-5.9.6-cp37-abi3-win32.whl", hash = "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c"}, + {file = "psutil-5.9.6-cp37-abi3-win_amd64.whl", hash = "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a"}, + {file = "psutil-5.9.6-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57"}, + {file = "psutil-5.9.6.tar.gz", hash = "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a"}, ] [package.extras] @@ -1947,6 +2368,31 @@ files = [ [package.extras] tests = ["pytest"] +[[package]] +name = "pyautogen" +version = "0.1.14" +description = "Enabling Next-Gen LLM Applications via Multi-Agent Conversation Framework" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyautogen-0.1.14-py3-none-any.whl", hash = "sha256:4f12b248af5350958a6073952123a802334b3d3dcd700353cdf25a8aacac4298"}, + {file = "pyautogen-0.1.14.tar.gz", hash = "sha256:1e9334cc7a69e73907154ff7c9c323f13aab7b70bdc8cce836be7ea92a127fff"}, +] + +[package.dependencies] +diskcache = "*" +flaml = "*" +openai = "<1" +python-dotenv = "*" +termcolor = "*" + +[package.extras] +blendsearch = ["flaml[blendsearch]"] +mathchat = ["pydantic (==1.10.9)", "sympy", "wolframalpha"] +retrievechat = ["chromadb", "ipython", "pypdf", "sentence-transformers", "tiktoken"] +teachable = ["chromadb"] +test = ["chromadb", "coverage (>=5.3)", "datasets", "ipykernel", "lancedb", "nbconvert", "nbformat", "pre-commit", "pydantic (==1.10.9)", "pytest (>=6.1.1)", "pytest-asyncio", "qdrant-client[fastembed]", "sympy", "tiktoken", "wolframalpha"] + [[package]] name = "pycparser" version = "2.21" @@ -1958,6 +2404,157 @@ files = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] +[[package]] +name = "pydantic" +version = "2.4.2" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-2.4.2-py3-none-any.whl", hash = "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1"}, + {file = "pydantic-2.4.2.tar.gz", hash = "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.10.1" +typing-extensions = ">=4.6.1" + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.10.1" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic_core-2.10.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63"}, + {file = "pydantic_core-2.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6"}, + {file = "pydantic_core-2.10.1-cp310-none-win32.whl", hash = "sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b"}, + {file = "pydantic_core-2.10.1-cp310-none-win_amd64.whl", hash = "sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0"}, + {file = "pydantic_core-2.10.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea"}, + {file = "pydantic_core-2.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4"}, + {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607"}, + {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f"}, + {file = "pydantic_core-2.10.1-cp311-none-win32.whl", hash = "sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6"}, + {file = "pydantic_core-2.10.1-cp311-none-win_amd64.whl", hash = "sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27"}, + {file = "pydantic_core-2.10.1-cp311-none-win_arm64.whl", hash = "sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325"}, + {file = "pydantic_core-2.10.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921"}, + {file = "pydantic_core-2.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d"}, + {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f"}, + {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c"}, + {file = "pydantic_core-2.10.1-cp312-none-win32.whl", hash = "sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f"}, + {file = "pydantic_core-2.10.1-cp312-none-win_amd64.whl", hash = "sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430"}, + {file = "pydantic_core-2.10.1-cp312-none-win_arm64.whl", hash = "sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f"}, + {file = "pydantic_core-2.10.1-cp37-none-win32.whl", hash = "sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c"}, + {file = "pydantic_core-2.10.1-cp37-none-win_amd64.whl", hash = "sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e"}, + {file = "pydantic_core-2.10.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc"}, + {file = "pydantic_core-2.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e"}, + {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561"}, + {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de"}, + {file = "pydantic_core-2.10.1-cp38-none-win32.whl", hash = "sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee"}, + {file = "pydantic_core-2.10.1-cp38-none-win_amd64.whl", hash = "sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e"}, + {file = "pydantic_core-2.10.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970"}, + {file = "pydantic_core-2.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429"}, + {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7"}, + {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595"}, + {file = "pydantic_core-2.10.1-cp39-none-win32.whl", hash = "sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a"}, + {file = "pydantic_core-2.10.1-cp39-none-win_amd64.whl", hash = "sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776"}, + {file = "pydantic_core-2.10.1.tar.gz", hash = "sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pydeps" +version = "1.12.17" +description = "Display module dependencies" +optional = false +python-versions = "*" +files = [ + {file = "pydeps-1.12.17-py3-none-any.whl", hash = "sha256:4fb2e86071c78c1b85a1c63745a267d100e91daf6bab2f14331b3c77433b58b4"}, + {file = "pydeps-1.12.17.tar.gz", hash = "sha256:c308e8355a1e77ff0af899d6f9f1665d4eb07019692dba9fb1dc1cab05df36a4"}, +] + +[package.dependencies] +stdlib-list = "*" + [[package]] name = "pygments" version = "2.16.1" @@ -1972,15 +2569,54 @@ files = [ [package.extras] plugins = ["importlib-metadata"] +[[package]] +name = "pygraphviz" +version = "1.11" +description = "Python interface to Graphviz" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygraphviz-1.11.zip", hash = "sha256:a97eb5ced266f45053ebb1f2c6c6d29091690503e3a5c14be7f908b37b06f2d4"}, +] + +[[package]] +name = "pylint" +version = "3.0.2" +description = "python code static checker" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "pylint-3.0.2-py3-none-any.whl", hash = "sha256:60ed5f3a9ff8b61839ff0348b3624ceeb9e6c2a92c514d81c9cc273da3b6bcda"}, + {file = "pylint-3.0.2.tar.gz", hash = "sha256:0d4c286ef6d2f66c8bfb527a7f8a629009e42c99707dec821a03e1b51a4c1496"}, +] + +[package.dependencies] +astroid = ">=3.0.1,<=3.1.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, +] +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + [[package]] name = "pytest" -version = "7.4.0" +version = "7.4.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, - {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] @@ -2008,6 +2644,20 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "python-json-logger" version = "2.0.7" @@ -2019,15 +2669,29 @@ files = [ {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, ] +[[package]] +name = "python-levenshtein" +version = "0.23.0" +description = "Python extension for computing string edit distances and similarities." +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-Levenshtein-0.23.0.tar.gz", hash = "sha256:156a0198cdcc659c90c8d3863d0ed3f4f0cf020608da71da52ac0f0746ef901a"}, + {file = "python_Levenshtein-0.23.0-py3-none-any.whl", hash = "sha256:486a47b189e3955463107aa36b57fb1e2b3b40243b9cc2994cde9810c78195c0"}, +] + +[package.dependencies] +Levenshtein = "0.23.0" + [[package]] name = "pytz" -version = "2023.3" +version = "2023.3.post1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, - {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, + {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, + {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, ] [[package]] @@ -2055,16 +2719,17 @@ files = [ [[package]] name = "pywinpty" -version = "2.0.11" +version = "2.0.12" description = "Pseudo terminal support for Windows from Python." optional = false python-versions = ">=3.8" files = [ - {file = "pywinpty-2.0.11-cp310-none-win_amd64.whl", hash = "sha256:452f10ac9ff8ab9151aa8cea9e491a9612a12250b1899278c6a56bc184afb47f"}, - {file = "pywinpty-2.0.11-cp311-none-win_amd64.whl", hash = "sha256:6701867d42aec1239bc0fedf49a336570eb60eb886e81763db77ea2b6c533cc3"}, - {file = "pywinpty-2.0.11-cp38-none-win_amd64.whl", hash = "sha256:0ffd287751ad871141dc9724de70ea21f7fc2ff1af50861e0d232cf70739d8c4"}, - {file = "pywinpty-2.0.11-cp39-none-win_amd64.whl", hash = "sha256:e4e7f023c28ca7aa8e1313e53ba80a4d10171fe27857b7e02f99882dfe3e8638"}, - {file = "pywinpty-2.0.11.tar.gz", hash = "sha256:e244cffe29a894876e2cd251306efd0d8d64abd5ada0a46150a4a71c0b9ad5c5"}, + {file = "pywinpty-2.0.12-cp310-none-win_amd64.whl", hash = "sha256:21319cd1d7c8844fb2c970fb3a55a3db5543f112ff9cfcd623746b9c47501575"}, + {file = "pywinpty-2.0.12-cp311-none-win_amd64.whl", hash = "sha256:853985a8f48f4731a716653170cd735da36ffbdc79dcb4c7b7140bce11d8c722"}, + {file = "pywinpty-2.0.12-cp312-none-win_amd64.whl", hash = "sha256:1617b729999eb6713590e17665052b1a6ae0ad76ee31e60b444147c5b6a35dca"}, + {file = "pywinpty-2.0.12-cp38-none-win_amd64.whl", hash = "sha256:189380469ca143d06e19e19ff3fba0fcefe8b4a8cc942140a6b863aed7eebb2d"}, + {file = "pywinpty-2.0.12-cp39-none-win_amd64.whl", hash = "sha256:7520575b6546db23e693cbd865db2764097bd6d4ef5dc18c92555904cd62c3d4"}, + {file = "pywinpty-2.0.12.tar.gz", hash = "sha256:8197de460ae8ebb7f5d1701dfa1b5df45b157bb832e92acba316305e18ca00dd"}, ] [[package]] @@ -2221,6 +2886,108 @@ files = [ [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "rapidfuzz" +version = "3.5.2" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rapidfuzz-3.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1a047d6e58833919d742bbc0dfa66d1de4f79e8562ee195007d3eae96635df39"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:22877c027c492b7dc7e3387a576a33ed5aad891104aa90da2e0844c83c5493ef"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e0f448b0eacbcc416feb634e1232a48d1cbde5e60f269c84e4fb0912f7bbb001"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05146497672f869baf41147d5ec1222788c70e5b8b0cfcd6e95597c75b5b96b"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f2df3968738a38d2a0058b5e721753f5d3d602346a1027b0dde31b0476418f3"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5afc1fcf1830f9bb87d3b490ba03691081b9948a794ea851befd2643069a30c1"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84be69ea65f64fa01e5c4976be9826a5aa949f037508887add42da07420d65d6"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8658c1045766e87e0038323aa38b4a9f49b7f366563271f973c8890a98aa24b5"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:852b3f93c15fce58b8dc668bd54123713bfdbbb0796ba905ea5df99cfd083132"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:12424a06ad9bd0cbf5f7cea1015e78d924a0034a0e75a5a7b39c0703dcd94095"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b4e9ded8e80530bd7205a7a2b01802f934a4695ca9e9fbe1ce9644f5e0697864"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:affb8fe36157c2dc8a7bc45b6a1875eb03e2c49167a1d52789144bdcb7ab3b8c"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1d33a622572d384f4c90b5f7a139328246ab5600141e90032b521c2127bd605"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-win32.whl", hash = "sha256:2cf9f2ed4a97b388cffd48d534452a564c2491f68f4fd5bc140306f774ceb63a"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:6541ffb70097885f7302cd73e2efd77be99841103023c2f9408551f27f45f7a5"}, + {file = "rapidfuzz-3.5.2-cp310-cp310-win_arm64.whl", hash = "sha256:1dd2542e5103fb8ca46500a979ae14d1609dcba11d2f9fe01e99eec03420e193"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bff7d3127ebc5cd908f3a72f6517f31f5247b84666137556a8fcc5177c560939"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fdfdb3685b631d8efbb6d6d3d86eb631be2b408d9adafcadc11e63e3f9c96dec"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:97b043fe8185ec53bb3ff0e59deb89425c0fc6ece6e118939963aab473505801"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a4a7832737f87583f3863dc62e6f56dd4a9fefc5f04a7bdcb4c433a0f36bb1b"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d876dba9a11fcf60dcf1562c5a84ef559db14c2ceb41e1ad2d93cd1dc085889"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa4c0612893716bbb6595066ca9ecb517c982355abe39ba9d1f4ab834ace91ad"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:120316824333e376b88b284724cfd394c6ccfcb9818519eab5d58a502e5533f0"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cdbe8e80cc186d55f748a34393533a052d855357d5398a1ccb71a5021b58e8d"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1062425c8358a547ae5ebad148f2e0f02417716a571b803b0c68e4d552e99d32"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:66be181965aff13301dd5f9b94b646ce39d99c7fe2fd5de1656f4ca7fafcb38c"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:53df7aea3cf301633cfa2b4b2c2d2441a87dfc878ef810e5b4eddcd3e68723ad"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:76639dca5eb0afc6424ac5f42d43d3bd342ac710e06f38a8c877d5b96de09589"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:27689361c747b5f7b8a26056bc60979875323f1c3dcaaa9e2fec88f03b20a365"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-win32.whl", hash = "sha256:99c9fc5265566fb94731dc6826f43c5109e797078264e6389a36d47814473692"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:666928ee735562a909d81bd2f63207b3214afd4ca41f790ab3025d066975c814"}, + {file = "rapidfuzz-3.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:d55de67c48f06b7772541e8d4c062a2679205799ce904236e2836cb04c106442"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:04e1e02b182283c43c866e215317735e91d22f5d34e65400121c04d5ed7ed859"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:365e544aba3ac13acf1a62cb2e5909ad2ba078d0bfc7d69b1f801dfd673b9782"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b61f77d834f94b0099fa9ed35c189b7829759d4e9c2743697a130dd7ba62259f"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43fb368998b9703fa8c63db292a8ab9e988bf6da0c8a635754be8e69da1e7c1d"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25510b5d142c47786dbd27cfd9da7cae5bdea28d458379377a3644d8460a3404"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf3093443751e5a419834162af358d1e31dec75f84747a91dbbc47b2c04fc085"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2fbaf546f15a924613f89d609ff66b85b4f4c2307ac14d93b80fe1025b713138"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32d580df0e130ed85400ff77e1c32d965e9bc7be29ac4072ab637f57e26d29fb"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:358a0fbc49343de20fee8ebdb33c7fa8f55a9ff93ff42d1ffe097d2caa248f1b"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fb379ac0ddfc86c5542a225d194f76ed468b071b6f79ff57c4b72e635605ad7d"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7fb21e182dc6d83617e88dea002963d5cf99cf5eabbdbf04094f503d8fe8d723"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:c04f9f1310ce414ab00bdcbf26d0906755094bfc59402cb66a7722c6f06d70b2"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f6da61cc38c1a95efc5edcedf258759e6dbab73191651a28c5719587f32a56ad"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-win32.whl", hash = "sha256:f823fd1977071486739f484e27092765d693da6beedaceece54edce1dfeec9b2"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:a8162d81486de85ab1606e48e076431b66d44cf431b2b678e9cae458832e7147"}, + {file = "rapidfuzz-3.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:dfc63fabb7d8da8483ca836bae7e55766fe39c63253571e103c034ba8ea80950"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:df8fae2515a1e4936affccac3e7d506dd904de5ff82bc0b1433b4574a51b9bfb"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dd6384780c2a16097d47588844cd677316a90e0f41ef96ff485b62d58de79dcf"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:467a4d730ae3bade87dba6bd769e837ab97e176968ce20591fe8f7bf819115b1"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54576669c1502b751b534bd76a4aeaaf838ed88b30af5d5c1b7d0a3ca5d4f7b5"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abafeb82f85a651a9d6d642a33dc021606bc459c33e250925b25d6b9e7105a2e"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73e14617a520c0f1bc15eb78c215383477e5ca70922ecaff1d29c63c060e04ca"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7cdf92116e9dfe40da17f921cdbfa0039dde9eb158914fa5f01b1e67a20b19cb"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1962d5ccf8602589dbf8e85246a0ee2b4050d82fade1568fb76f8a4419257704"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:db45028eae2fda7a24759c69ebeb2a7fbcc1a326606556448ed43ee480237a3c"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b685abb8b6d97989f6c69556d7934e0e533aa8822f50b9517ff2da06a1d29f23"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:40139552961018216b8cd88f6df4ecbbe984f907a62a5c823ccd907132c29a14"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:0fef4705459842ef8f79746d6f6a0b5d2b6a61a145d7d8bbe10b2e756ea337c8"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6b2ad5516f7068c7d9cbcda8ac5906c589e99bc427df2e1050282ee2d8bc2d58"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-win32.whl", hash = "sha256:2da3a24c2f7dfca7f26ba04966b848e3bbeb93e54d899908ff88dfe3e1def9dc"}, + {file = "rapidfuzz-3.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:e3f2be79d4114d01f383096dbee51b57df141cb8b209c19d0cf65f23a24e75ba"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:089a7e96e5032821af5964d8457fcb38877cc321cdd06ad7c5d6e3d852264cb9"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75d8a52bf8d1aa2ac968ae4b21b83b94fc7e5ea3dfbab34811fc60f32df505b2"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2bacce6bbc0362f0789253424269cc742b1f45e982430387db3abe1d0496e371"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5fd627e604ddc02db2ddb9ddc4a91dd92b7a6d6378fcf30bb37b49229072b89"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2e8b369f23f00678f6e673572209a5d3b0832f4991888e3df97af7b8b9decf3"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c29958265e4c2b937269e804b8a160c027ee1c2627d6152655008a8b8083630e"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00be97f9219355945c46f37ac9fa447046e6f7930f7c901e5d881120d1695458"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada0d8d57e0f556ef38c24fee71bfe8d0db29c678bff2acd1819fc1b74f331c2"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:de89585268ed8ee44e80126814cae63ff6b00d08416481f31b784570ef07ec59"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:908ff2de9c442b379143d1da3c886c63119d4eba22986806e2533cee603fe64b"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:54f0061028723c026020f5bb20649c22bc8a0d9f5363c283bdc5901d4d3bff01"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b581107ec0c610cdea48b25f52030770be390db4a9a73ca58b8d70fa8a5ec32e"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1d5a686ea258931aaa38019204bdc670bbe14b389a230b1363d84d6cf4b9dc38"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-win32.whl", hash = "sha256:97f811ca7709c6ee8c0b55830f63b3d87086f4abbcbb189b4067e1cd7014db7b"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:58ee34350f8c292dd24a050186c0e18301d80da904ef572cf5fda7be6a954929"}, + {file = "rapidfuzz-3.5.2-cp39-cp39-win_arm64.whl", hash = "sha256:c5075ce7b9286624cafcf36720ef1cfb2946d75430b87cb4d1f006e82cd71244"}, + {file = "rapidfuzz-3.5.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:af5221e4f7800db3e84c46b79dba4112e3b3cc2678f808bdff4fcd2487073846"}, + {file = "rapidfuzz-3.5.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8501d7875b176930e6ed9dbc1bc35adb37ef312f6106bd6bb5c204adb90160ac"}, + {file = "rapidfuzz-3.5.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e414e1ca40386deda4291aa2d45062fea0fbaa14f95015738f8bb75c4d27f862"}, + {file = "rapidfuzz-3.5.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2059cd73b7ea779a9307d7a78ed743f0e3d33b88ccdcd84569abd2953cd859f"}, + {file = "rapidfuzz-3.5.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:58e3e21f6f13a7cca265cce492bc797425bd4cb2025fdd161a9e86a824ad65ce"}, + {file = "rapidfuzz-3.5.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b847a49377e64e92e11ef3d0a793de75451526c83af015bdafdd5d04de8a058a"}, + {file = "rapidfuzz-3.5.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a42c7a8c62b29c4810e39da22b42524295fcb793f41c395c2cb07c126b729e83"}, + {file = "rapidfuzz-3.5.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51b5166be86e09e011e92d9862b1fe64c4c7b9385f443fb535024e646d890460"}, + {file = "rapidfuzz-3.5.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f808dcb0088a7a496cc9895e66a7b8de55ffea0eb9b547c75dfb216dd5f76ed"}, + {file = "rapidfuzz-3.5.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d4b05a8f4ab7e7344459394094587b033fe259eea3a8720035e8ba30e79ab39b"}, + {file = "rapidfuzz-3.5.2.tar.gz", hash = "sha256:9e9b395743e12c36a3167a3a9fd1b4e11d92fb0aa21ec98017ee6df639ed385e"}, +] + +[package.extras] +full = ["numpy"] + [[package]] name = "referencing" version = "0.30.2" @@ -2238,99 +3005,99 @@ rpds-py = ">=0.7.0" [[package]] name = "regex" -version = "2023.8.8" +version = "2023.10.3" description = "Alternative regular expression module, to replace re." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"}, - {file = "regex-2023.8.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7"}, - {file = "regex-2023.8.8-cp310-cp310-win32.whl", hash = "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb"}, - {file = "regex-2023.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd"}, - {file = "regex-2023.8.8-cp311-cp311-win32.whl", hash = "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8"}, - {file = "regex-2023.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb"}, - {file = "regex-2023.8.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b"}, - {file = "regex-2023.8.8-cp36-cp36m-win32.whl", hash = "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7"}, - {file = "regex-2023.8.8-cp36-cp36m-win_amd64.whl", hash = "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236"}, - {file = "regex-2023.8.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7"}, - {file = "regex-2023.8.8-cp37-cp37m-win32.whl", hash = "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3"}, - {file = "regex-2023.8.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882"}, - {file = "regex-2023.8.8-cp38-cp38-win32.whl", hash = "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7"}, - {file = "regex-2023.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6"}, - {file = "regex-2023.8.8-cp39-cp39-win32.whl", hash = "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e"}, - {file = "regex-2023.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb"}, - {file = "regex-2023.8.8.tar.gz", hash = "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e"}, + {file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"}, + {file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"}, + {file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"}, + {file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"}, + {file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"}, + {file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"}, + {file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"}, + {file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"}, + {file = "regex-2023.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb"}, + {file = "regex-2023.10.3-cp37-cp37m-win32.whl", hash = "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a"}, + {file = "regex-2023.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4"}, + {file = "regex-2023.10.3-cp38-cp38-win32.whl", hash = "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d"}, + {file = "regex-2023.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"}, + {file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"}, + {file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"}, + {file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"}, ] [[package]] @@ -2381,127 +3148,128 @@ files = [ [[package]] name = "rich" -version = "13.5.2" +version = "13.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"}, - {file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"}, + {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, + {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, ] [package.dependencies] markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.9.2" +version = "0.12.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"}, - {file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6"}, - {file = "rpds_py-0.9.2-cp310-none-win32.whl", hash = "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764"}, - {file = "rpds_py-0.9.2-cp310-none-win_amd64.whl", hash = "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e"}, - {file = "rpds_py-0.9.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3"}, - {file = "rpds_py-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de"}, - {file = "rpds_py-0.9.2-cp311-none-win32.whl", hash = "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab"}, - {file = "rpds_py-0.9.2-cp311-none-win_amd64.whl", hash = "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298"}, - {file = "rpds_py-0.9.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386"}, - {file = "rpds_py-0.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d"}, - {file = "rpds_py-0.9.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d"}, - {file = "rpds_py-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e"}, - {file = "rpds_py-0.9.2-cp38-none-win32.whl", hash = "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920"}, - {file = "rpds_py-0.9.2-cp38-none-win_amd64.whl", hash = "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044"}, - {file = "rpds_py-0.9.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260"}, - {file = "rpds_py-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26"}, - {file = "rpds_py-0.9.2-cp39-none-win32.whl", hash = "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0"}, - {file = "rpds_py-0.9.2-cp39-none-win_amd64.whl", hash = "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"}, - {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"}, + {file = "rpds_py-0.12.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:c694bee70ece3b232df4678448fdda245fd3b1bb4ba481fb6cd20e13bb784c46"}, + {file = "rpds_py-0.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:30e5ce9f501fb1f970e4a59098028cf20676dee64fc496d55c33e04bbbee097d"}, + {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d72a4315514e5a0b9837a086cb433b004eea630afb0cc129de76d77654a9606f"}, + {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eebaf8c76c39604d52852366249ab807fe6f7a3ffb0dd5484b9944917244cdbe"}, + {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a239303acb0315091d54c7ff36712dba24554993b9a93941cf301391d8a997ee"}, + {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ced40cdbb6dd47a032725a038896cceae9ce267d340f59508b23537f05455431"}, + {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c8c0226c71bd0ce9892eaf6afa77ae8f43a3d9313124a03df0b389c01f832de"}, + {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8e11715178f3608874508f08e990d3771e0b8c66c73eb4e183038d600a9b274"}, + {file = "rpds_py-0.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5210a0018c7e09c75fa788648617ebba861ae242944111d3079034e14498223f"}, + {file = "rpds_py-0.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:171d9a159f1b2f42a42a64a985e4ba46fc7268c78299272ceba970743a67ee50"}, + {file = "rpds_py-0.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:57ec6baec231bb19bb5fd5fc7bae21231860a1605174b11585660236627e390e"}, + {file = "rpds_py-0.12.0-cp310-none-win32.whl", hash = "sha256:7188ddc1a8887194f984fa4110d5a3d5b9b5cd35f6bafdff1b649049cbc0ce29"}, + {file = "rpds_py-0.12.0-cp310-none-win_amd64.whl", hash = "sha256:1e04581c6117ad9479b6cfae313e212fe0dfa226ac727755f0d539cd54792963"}, + {file = "rpds_py-0.12.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:0a38612d07a36138507d69646c470aedbfe2b75b43a4643f7bd8e51e52779624"}, + {file = "rpds_py-0.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f12d69d568f5647ec503b64932874dade5a20255736c89936bf690951a5e79f5"}, + {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8a1d990dc198a6c68ec3d9a637ba1ce489b38cbfb65440a27901afbc5df575"}, + {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c567c664fc2f44130a20edac73e0a867f8e012bf7370276f15c6adc3586c37c"}, + {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e9e976e0dbed4f51c56db10831c9623d0fd67aac02853fe5476262e5a22acb7"}, + {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:efddca2d02254a52078c35cadad34762adbae3ff01c6b0c7787b59d038b63e0d"}, + {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9e7f29c00577aff6b318681e730a519b235af292732a149337f6aaa4d1c5e31"}, + {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:389c0e38358fdc4e38e9995e7291269a3aead7acfcf8942010ee7bc5baee091c"}, + {file = "rpds_py-0.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33ab498f9ac30598b6406e2be1b45fd231195b83d948ebd4bd77f337cb6a2bff"}, + {file = "rpds_py-0.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d56b1cd606ba4cedd64bb43479d56580e147c6ef3f5d1c5e64203a1adab784a2"}, + {file = "rpds_py-0.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fa73ed22c40a1bec98d7c93b5659cd35abcfa5a0a95ce876b91adbda170537c"}, + {file = "rpds_py-0.12.0-cp311-none-win32.whl", hash = "sha256:dbc25baa6abb205766fb8606f8263b02c3503a55957fcb4576a6bb0a59d37d10"}, + {file = "rpds_py-0.12.0-cp311-none-win_amd64.whl", hash = "sha256:c6b52b7028b547866c2413f614ee306c2d4eafdd444b1ff656bf3295bf1484aa"}, + {file = "rpds_py-0.12.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:9620650c364c01ed5b497dcae7c3d4b948daeae6e1883ae185fef1c927b6b534"}, + {file = "rpds_py-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2124f9e645a94ab7c853bc0a3644e0ca8ffbe5bb2d72db49aef8f9ec1c285733"}, + {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281c8b219d4f4b3581b918b816764098d04964915b2f272d1476654143801aa2"}, + {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:27ccc93c7457ef890b0dd31564d2a05e1aca330623c942b7e818e9e7c2669ee4"}, + {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1c562a9bb72244fa767d1c1ab55ca1d92dd5f7c4d77878fee5483a22ffac808"}, + {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e57919c32ee295a2fca458bb73e4b20b05c115627f96f95a10f9f5acbd61172d"}, + {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa35ad36440aaf1ac8332b4a4a433d4acd28f1613f0d480995f5cfd3580e90b7"}, + {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e6aea5c0eb5b0faf52c7b5c4a47c8bb64437173be97227c819ffa31801fa4e34"}, + {file = "rpds_py-0.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:81cf9d306c04df1b45971c13167dc3bad625808aa01281d55f3cf852dde0e206"}, + {file = "rpds_py-0.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:08e6e7ff286254016b945e1ab632ee843e43d45e40683b66dd12b73791366dd1"}, + {file = "rpds_py-0.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4d0a675a7acbbc16179188d8c6d0afb8628604fc1241faf41007255957335a0b"}, + {file = "rpds_py-0.12.0-cp312-none-win32.whl", hash = "sha256:b2287c09482949e0ca0c0eb68b2aca6cf57f8af8c6dfd29dcd3bc45f17b57978"}, + {file = "rpds_py-0.12.0-cp312-none-win_amd64.whl", hash = "sha256:8015835494b21aa7abd3b43fdea0614ee35ef6b03db7ecba9beb58eadf01c24f"}, + {file = "rpds_py-0.12.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6174d6ad6b58a6bcf67afbbf1723420a53d06c4b89f4c50763d6fa0a6ac9afd2"}, + {file = "rpds_py-0.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a689e1ded7137552bea36305a7a16ad2b40be511740b80748d3140614993db98"}, + {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45321224144c25a62052035ce96cbcf264667bcb0d81823b1bbc22c4addd194"}, + {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa32205358a76bf578854bf31698a86dc8b2cb591fd1d79a833283f4a403f04b"}, + {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91bd2b7cf0f4d252eec8b7046fa6a43cee17e8acdfc00eaa8b3dbf2f9a59d061"}, + {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3acadbab8b59f63b87b518e09c4c64b142e7286b9ca7a208107d6f9f4c393c5c"}, + {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:429349a510da82c85431f0f3e66212d83efe9fd2850f50f339341b6532c62fe4"}, + {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05942656cb2cb4989cd50ced52df16be94d344eae5097e8583966a1d27da73a5"}, + {file = "rpds_py-0.12.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0c5441b7626c29dbd54a3f6f3713ec8e956b009f419ffdaaa3c80eaf98ddb523"}, + {file = "rpds_py-0.12.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:b6b0e17d39d21698185097652c611f9cf30f7c56ccec189789920e3e7f1cee56"}, + {file = "rpds_py-0.12.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3b7a64d43e2a1fa2dd46b678e00cabd9a49ebb123b339ce799204c44a593ae1c"}, + {file = "rpds_py-0.12.0-cp38-none-win32.whl", hash = "sha256:e5bbe011a2cea9060fef1bb3d668a2fd8432b8888e6d92e74c9c794d3c101595"}, + {file = "rpds_py-0.12.0-cp38-none-win_amd64.whl", hash = "sha256:bec29b801b4adbf388314c0d050e851d53762ab424af22657021ce4b6eb41543"}, + {file = "rpds_py-0.12.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:1096ca0bf2d3426cbe79d4ccc91dc5aaa73629b08ea2d8467375fad8447ce11a"}, + {file = "rpds_py-0.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48aa98987d54a46e13e6954880056c204700c65616af4395d1f0639eba11764b"}, + {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7979d90ee2190d000129598c2b0c82f13053dba432b94e45e68253b09bb1f0f6"}, + {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:88857060b690a57d2ea8569bca58758143c8faa4639fb17d745ce60ff84c867e"}, + {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4eb74d44776b0fb0782560ea84d986dffec8ddd94947f383eba2284b0f32e35e"}, + {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f62581d7e884dd01ee1707b7c21148f61f2febb7de092ae2f108743fcbef5985"}, + {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f5dcb658d597410bb7c967c1d24eaf9377b0d621358cbe9d2ff804e5dd12e81"}, + {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bf9acce44e967a5103fcd820fc7580c7b0ab8583eec4e2051aec560f7b31a63"}, + {file = "rpds_py-0.12.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:240687b5be0f91fbde4936a329c9b7589d9259742766f74de575e1b2046575e4"}, + {file = "rpds_py-0.12.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:25740fb56e8bd37692ed380e15ec734be44d7c71974d8993f452b4527814601e"}, + {file = "rpds_py-0.12.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a54917b7e9cd3a67e429a630e237a90b096e0ba18897bfb99ee8bd1068a5fea0"}, + {file = "rpds_py-0.12.0-cp39-none-win32.whl", hash = "sha256:b92aafcfab3d41580d54aca35a8057341f1cfc7c9af9e8bdfc652f83a20ced31"}, + {file = "rpds_py-0.12.0-cp39-none-win_amd64.whl", hash = "sha256:cd316dbcc74c76266ba94eb021b0cc090b97cca122f50bd7a845f587ff4bf03f"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0853da3d5e9bc6a07b2486054a410b7b03f34046c123c6561b535bb48cc509e1"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:cb41ad20064e18a900dd427d7cf41cfaec83bcd1184001f3d91a1f76b3fcea4e"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b710bf7e7ae61957d5c4026b486be593ed3ec3dca3e5be15e0f6d8cf5d0a4990"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a952ae3eb460c6712388ac2ec706d24b0e651b9396d90c9a9e0a69eb27737fdc"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0bedd91ae1dd142a4dc15970ed2c729ff6c73f33a40fa84ed0cdbf55de87c777"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:761531076df51309075133a6bc1db02d98ec7f66e22b064b1d513bc909f29743"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2baa6be130e8a00b6cbb9f18a33611ec150b4537f8563bddadb54c1b74b8193"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f05450fa1cd7c525c0b9d1a7916e595d3041ac0afbed2ff6926e5afb6a781b7f"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:81c4d1a3a564775c44732b94135d06e33417e829ff25226c164664f4a1046213"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e888be685fa42d8b8a3d3911d5604d14db87538aa7d0b29b1a7ea80d354c732d"}, + {file = "rpds_py-0.12.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6f8d7fe73d1816eeb5378409adc658f9525ecbfaf9e1ede1e2d67a338b0c7348"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0831d3ecdea22e4559cc1793f22e77067c9d8c451d55ae6a75bf1d116a8e7f42"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:513ccbf7420c30e283c25c82d5a8f439d625a838d3ba69e79a110c260c46813f"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:301bd744a1adaa2f6a5e06c98f1ac2b6f8dc31a5c23b838f862d65e32fca0d4b"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8832a4f83d4782a8f5a7b831c47e8ffe164e43c2c148c8160ed9a6d630bc02a"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b2416ed743ec5debcf61e1242e012652a4348de14ecc7df3512da072b074440"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35585a8cb5917161f42c2104567bb83a1d96194095fc54a543113ed5df9fa436"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d389ff1e95b6e46ebedccf7fd1fadd10559add595ac6a7c2ea730268325f832c"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9b007c2444705a2dc4a525964fd4dd28c3320b19b3410da6517cab28716f27d3"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:188912b22b6c8225f4c4ffa020a2baa6ad8fabb3c141a12dbe6edbb34e7f1425"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b4cf9ab9a0ae0cb122685209806d3f1dcb63b9fccdf1424fb42a129dc8c2faa"}, + {file = "rpds_py-0.12.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2d34a5450a402b00d20aeb7632489ffa2556ca7b26f4a63c35f6fccae1977427"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:466030a42724780794dea71eb32db83cc51214d66ab3fb3156edd88b9c8f0d78"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:68172622a5a57deb079a2c78511c40f91193548e8ab342c31e8cb0764d362459"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54cdfcda59251b9c2f87a05d038c2ae02121219a04d4a1e6fc345794295bdc07"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6b75b912a0baa033350367a8a07a8b2d44fd5b90c890bfbd063a8a5f945f644b"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47aeceb4363851d17f63069318ba5721ae695d9da55d599b4d6fb31508595278"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0525847f83f506aa1e28eb2057b696fe38217e12931c8b1b02198cfe6975e142"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efbe0b5e0fd078ed7b005faa0170da4f72666360f66f0bb2d7f73526ecfd99f9"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0fadfdda275c838cba5102c7f90a20f2abd7727bf8f4a2b654a5b617529c5c18"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:56dd500411d03c5e9927a1eb55621e906837a83b02350a9dc401247d0353717c"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:6915fc9fa6b3ec3569566832e1bb03bd801c12cea030200e68663b9a87974e76"}, + {file = "rpds_py-0.12.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5f1519b080d8ce0a814f17ad9fb49fb3a1d4d7ce5891f5c85fc38631ca3a8dc4"}, + {file = "rpds_py-0.12.0.tar.gz", hash = "sha256:7036316cc26b93e401cedd781a579be606dad174829e6ad9e9c5a0da6e036f80"}, ] [[package]] @@ -2522,19 +3290,37 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "68.0.0" +version = "68.2.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, + {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "sigtools" +version = "4.0.1" +description = "Utilities for working with inspect.Signature objects." +optional = false +python-versions = ">=3.6" files = [ - {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, - {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, + {file = "sigtools-4.0.1-py2.py3-none-any.whl", hash = "sha256:d216b4cf920bbab0fce636ddc429ed8463a5b533d9e1492acb45a2a1bc36ac6c"}, + {file = "sigtools-4.0.1.tar.gz", hash = "sha256:4b8e135a9cd4d2ea00da670c093372d74e672ba3abb87f4c98d8e73dea54445c"}, ] +[package.dependencies] +attrs = "*" + [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +test = ["coverage", "mock", "repeated-test (>=2.2.1)", "sphinx"] +tests = ["coverage", "mock", "repeated-test (>=2.2.1)", "sphinx"] [[package]] name = "six" @@ -2560,68 +3346,103 @@ files = [ [[package]] name = "soupsieve" -version = "2.4.1" +version = "2.5" description = "A modern CSS selector implementation for Beautiful Soup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, - {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] [[package]] -name = "spinners" -version = "0.0.24" -description = "Spinners for terminals" +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" files = [ - {file = "spinners-0.0.24-py3-none-any.whl", hash = "sha256:2fa30d0b72c9650ad12bbe031c9943b8d441e41b4f5602b0ec977a19f3290e98"}, - {file = "spinners-0.0.24.tar.gz", hash = "sha256:1eb6aeb4781d72ab42ed8a01dcf20f3002bf50740d7154d12fb8c9769bf9e27f"}, + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, ] +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + [[package]] -name = "sqlglot" -version = "16.8.1" -description = "An easily customizable SQL parser and transpiler" +name = "starlette" +version = "0.27.0" +description = "The little ASGI library that shines." optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "sqlglot-16.8.1-py3-none-any.whl", hash = "sha256:14dcc4478f220839262172849f0174c6b80f4a8c77f2fb6295c16f2d121f09fa"}, - {file = "sqlglot-16.8.1.tar.gz", hash = "sha256:2a7451f0ed2feac6e7a832bafee852a25e743c35a637e5020f3235c1feb9b700"}, + {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"}, + {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"}, ] +[package.dependencies] +anyio = ">=3.4.0,<5" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + [package.extras] -dev = ["autoflake", "black", "duckdb (>=0.6)", "isort", "mypy (>=0.990)", "pandas", "pdoc", "pre-commit", "pyspark", "python-dateutil"] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] [[package]] -name = "stack-data" -version = "0.6.2" -description = "Extract data from python stack frames and tracebacks for informative displays" +name = "stdlib-list" +version = "0.9.0" +description = "A list of Python Standard Libraries (2.7 through 3.9)." optional = false -python-versions = "*" +python-versions = ">=3.7" +files = [ + {file = "stdlib_list-0.9.0-py3-none-any.whl", hash = "sha256:f79957d59e41930d44afcd81e465f740b9a7a9828707a40e24ab1092b12bd423"}, + {file = "stdlib_list-0.9.0.tar.gz", hash = "sha256:98eb66135976c96b4ee3f4c0ef0552ebb5a9977ce3028433db79f4738b02af26"}, +] + +[package.extras] +dev = ["build", "stdlib-list[doc,lint,test]"] +doc = ["furo", "sphinx"] +lint = ["black", "mypy", "ruff"] +support = ["sphobjinv"] +test = ["coverage[toml]", "pytest", "pytest-cov"] + +[[package]] +name = "synchronicity" +version = "0.5.3" +description = "Export blocking and async library versions from a single async implementation" +optional = false +python-versions = ">=3.7.9" files = [ - {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, - {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, + {file = "synchronicity-0.5.3-py3-none-any.whl", hash = "sha256:d7ff3ec96d3002a4f1c21b99ad4f556557fda0ca1b0014071831e217affa2300"}, ] [package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" +sigtools = "4.0.1" -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[[package]] +name = "tblib" +version = "3.0.0" +description = "Traceback serialization library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tblib-3.0.0-py3-none-any.whl", hash = "sha256:80a6c77e59b55e83911e1e607c649836a69c103963c5f28a46cbeef44acf8129"}, + {file = "tblib-3.0.0.tar.gz", hash = "sha256:93622790a0a29e04f0346458face1e144dc4d32f493714c6c3dff82a4adb77e6"}, +] [[package]] name = "tenacity" -version = "8.2.2" +version = "8.2.3" description = "Retry code until it succeeds" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "tenacity-8.2.2-py3-none-any.whl", hash = "sha256:2f277afb21b851637e8f52e6a613ff08734c347dc19ade928e519d7d2d8569b0"}, - {file = "tenacity-8.2.2.tar.gz", hash = "sha256:43af037822bd0029025877f3b2d97cc4d7bb0c2991000a3d59d71517c5c969e0"}, + {file = "tenacity-8.2.3-py3-none-any.whl", hash = "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"}, + {file = "tenacity-8.2.3.tar.gz", hash = "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a"}, ] [package.extras] @@ -2724,6 +3545,17 @@ webencodings = ">=0.4" doc = ["sphinx", "sphinx_rtd_theme"] test = ["flake8", "isort", "pytest"] +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -2735,24 +3567,35 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "tomlkit" +version = "0.12.2" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.2-py3-none-any.whl", hash = "sha256:eeea7ac7563faeab0a1ed8fe12c2e5a51c61f933f2502f7e9db0241a65163ad0"}, + {file = "tomlkit-0.12.2.tar.gz", hash = "sha256:df32fab589a81f0d7dc525a4267b6d7a64ee99619cbd1eeb0fae32c1dd426977"}, +] + [[package]] name = "tornado" -version = "6.3.2" +version = "6.3.3" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">= 3.8" files = [ - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, - {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, - {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, - {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, + {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, + {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, + {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, ] [[package]] @@ -2777,97 +3620,220 @@ telegram = ["requests"] [[package]] name = "traitlets" -version = "5.9.0" +version = "5.13.0" description = "Traitlets Python configuration system" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, - {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, + {file = "traitlets-5.13.0-py3-none-any.whl", hash = "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619"}, + {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.6.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "tree-sitter" -version = "0.20.1" -description = "Python bindings to the Tree-sitter parsing library" +version = "0.20.2" +description = "Python bindings for the Tree-Sitter parsing library" optional = false python-versions = ">=3.3" files = [ - {file = "tree_sitter-0.20.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:6f11a1fd909dcf569e7b1d98861a837436799e757bbbc5cd5280989050929e12"}, - {file = "tree_sitter-0.20.1.tar.gz", hash = "sha256:e93f082c545d6649bcfb5d681ed255eb004a6ce22988971a128f40692feec60d"}, + {file = "tree_sitter-0.20.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1a151ccf9233b0b84850422654247f68a4d78f548425c76520402ea6fb6cdb24"}, + {file = "tree_sitter-0.20.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52ca2738c3c4c660c83054ac3e44a49cbecb9f89dc26bb8e154d6ca288aa06b0"}, + {file = "tree_sitter-0.20.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8d51478ea078da7cc6f626e9e36f131bbc5fac036cf38ea4b5b81632cbac37d"}, + {file = "tree_sitter-0.20.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0b2b59e1633efbf19cd2ed1ceb8d51b2c44a278153b1113998c70bc1570b750"}, + {file = "tree_sitter-0.20.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7f691c57d2a65d6e53e2f3574153c9cd0c157ff938b8d6f252edd5e619811403"}, + {file = "tree_sitter-0.20.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba72a363387eebaff9a0b788f864fe47da425136cbd4cac6cd125051f043c296"}, + {file = "tree_sitter-0.20.2-cp310-cp310-win32.whl", hash = "sha256:55e33eb206446d5046d3b5fe36ab300840f5a8a844246adb0ccc68c55c30b722"}, + {file = "tree_sitter-0.20.2-cp310-cp310-win_amd64.whl", hash = "sha256:24ce9d14daba0a71a778417d9d61dd4038ca96981ddec19e1e8990881469321c"}, + {file = "tree_sitter-0.20.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:942dbfb8bc380f09b0e323d3884de07d19022930516f33b7503a6eb5f6e18979"}, + {file = "tree_sitter-0.20.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ee5651c11924d426f8d6858a40fd5090ae31574f81ef180bef2055282f43bf62"}, + {file = "tree_sitter-0.20.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fb6982b480031628dad7f229c4c8d90b17d4c281ba97848d3b100666d7fa45f"}, + {file = "tree_sitter-0.20.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:067609c6c7cb6e5a6c4be50076a380fe52b6e8f0641ee9d0da33b24a5b972e82"}, + {file = "tree_sitter-0.20.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:849d7e6b66fe7ded08a633943b30e0ed807eee76104288e6c6841433f4a9651b"}, + {file = "tree_sitter-0.20.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e85689573797e49f86e2d7cf48b9dd23bc044c477df074a78546e666d6990a29"}, + {file = "tree_sitter-0.20.2-cp311-cp311-win32.whl", hash = "sha256:098906148e44ea391a91b019d584dd8d0ea1437af62a9744e280e93163fd35ca"}, + {file = "tree_sitter-0.20.2-cp311-cp311-win_amd64.whl", hash = "sha256:2753a87094b72fe7f02276b3948155618f53aa14e1ca20588f0eeed510f68512"}, + {file = "tree_sitter-0.20.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:5de192cb9e7b1c882d45418decb7899f1547f7056df756bcae186bbf4966d96e"}, + {file = "tree_sitter-0.20.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3a77e663293a73a97edbf2a2e05001de08933eb5d311a16bdc25b9b2fac54f3"}, + {file = "tree_sitter-0.20.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:415da4a70c56a003758537517fe9e60b8b0c5f70becde54cc8b8f3ba810adc70"}, + {file = "tree_sitter-0.20.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:707fb4d7a6123b8f9f2b005d61194077c3168c0372556e7418802280eddd4892"}, + {file = "tree_sitter-0.20.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:75fcbfb0a61ad64e7f787eb3f8fbf29b8e2b858dc011897ad039d838a06cee02"}, + {file = "tree_sitter-0.20.2-cp36-cp36m-win32.whl", hash = "sha256:622926530895d939fa6e1e2487e71a311c71d3b09f4c4f19301695ea866304a4"}, + {file = "tree_sitter-0.20.2-cp36-cp36m-win_amd64.whl", hash = "sha256:5c0712f031271d9bc462f1db7623d23703ed9fbcbaa6dc19ba535f58d6110774"}, + {file = "tree_sitter-0.20.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2dfdf680ecf5619447243c4c20e4040a7b5e7afca4e1569f03c814e86bfda248"}, + {file = "tree_sitter-0.20.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79650ee23a15559b69542c71ed9eb3297dce21932a7c5c148be384dd0f2cd49d"}, + {file = "tree_sitter-0.20.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63059746b4b2f2f87dd19c208141c69452694aae32459b7a4ebca8539d13bf4"}, + {file = "tree_sitter-0.20.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9398d1e214d4915032cf68a678de7eb803f64d25ef04724d70b88db7bb7746e9"}, + {file = "tree_sitter-0.20.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b506fb2e2bd7a5a1603c644bbb90401fe488f86bbca39706addaa8d2bfc80815"}, + {file = "tree_sitter-0.20.2-cp37-cp37m-win32.whl", hash = "sha256:405e83804ba60ca1c3dbd258adbe0d7b0f1bdce948e5eec5587a2ebedcf930ba"}, + {file = "tree_sitter-0.20.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a1e66d211c04144484e223922ac094a2367476e6f57000f986c5560dc5a83c6e"}, + {file = "tree_sitter-0.20.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f8adc325c74c042204ed47d095e0ec86f83de3c7ec4979645f86b58514f60297"}, + {file = "tree_sitter-0.20.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb49c861e1d111e0df119ecbfaa409e6413b8d91e8f56bcdb15f07fbc35594e"}, + {file = "tree_sitter-0.20.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e17ee83409b01fdd09021997b0c747be2f773bb2bb140ba6fb48b7e12fdd039a"}, + {file = "tree_sitter-0.20.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:475ab841647a0d1bc1266c8978279f8e4f7b9520b9a7336d532e5dfc8910214d"}, + {file = "tree_sitter-0.20.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:222350189675d9814966a5c88c6c1378a2ee2f3041c439a6f1d1ff2006f403aa"}, + {file = "tree_sitter-0.20.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:31ea52f0deee70f2cb00aff01e40aae325a34ebe1661de274c9107322fb95f54"}, + {file = "tree_sitter-0.20.2-cp38-cp38-win32.whl", hash = "sha256:cceaf7287137cbca707006624a4a8d4b5ccbfec025793fde84d90524c2bb0946"}, + {file = "tree_sitter-0.20.2-cp38-cp38-win_amd64.whl", hash = "sha256:25b9669911f21ec2b3727bb2f4dfeff6ddb6f81898c3e968d378a660e0d7f90e"}, + {file = "tree_sitter-0.20.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ce30a17f46a6b39a04a599dea88c127a19e3e1f43a2ad0ced71b5c032d585077"}, + {file = "tree_sitter-0.20.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9576e8b2e663639527e01ab251b87f0bd370bfdd40515588689ebc424aec786"}, + {file = "tree_sitter-0.20.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d03731a498f624ce3536c821ef23b03d1ad569b3845b326a5b7149ef189d732c"}, + {file = "tree_sitter-0.20.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef0116ecb163573ebaa0fc04cc99c90bd94c0be5cc4d0a1ebeb102de9cc9a054"}, + {file = "tree_sitter-0.20.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0943b00d3700f253c3ee6a53a71b9a6ca46defd9c0a33edb07a9388e70dc3a9e"}, + {file = "tree_sitter-0.20.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8cb566b6f0b5457148cb8310a1ca3d764edf28e47fcccfe0b167861ecaa50c12"}, + {file = "tree_sitter-0.20.2-cp39-cp39-win32.whl", hash = "sha256:4544204a24c2b4d25d1731b0df83f7c819ce87c4f2538a19724b8753815ef388"}, + {file = "tree_sitter-0.20.2-cp39-cp39-win_amd64.whl", hash = "sha256:9517b204e471d6aa59ee2232f6220f315ed5336079034d5c861a24660d6511d6"}, + {file = "tree_sitter-0.20.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:84343678f58cb354d22ed14b627056ffb33c540cf16c35a83db4eeee8827b935"}, + {file = "tree_sitter-0.20.2-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:611a80171d8fa6833dd0c8b022714d2ea789de15a955ec42ec4fd5fcc1032edb"}, + {file = "tree_sitter-0.20.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bacecfb61694c95ccee462742b3fcea50ba1baf115c42e60adf52b549ef642ce"}, + {file = "tree_sitter-0.20.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:f344ae94a268479456f19712736cc7398de5822dc74cca7d39538c28085721d0"}, + {file = "tree_sitter-0.20.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:221784d7f326fe81ce7174ac5972800f58b9a7c5c48a03719cad9830c22e5a76"}, + {file = "tree_sitter-0.20.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64210ed8d2a1b7e2951f6576aa0cb7be31ad06d87da26c52961318fc54c7fe77"}, + {file = "tree_sitter-0.20.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2634ac73b39ceacfa431d6d95692eae7465977fa0b9e9f7ae6cb445991e829a5"}, + {file = "tree_sitter-0.20.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:71663a0e8230dae99d9c55e6895bd2c9e42534ec861b255775f704ae2db70c1d"}, + {file = "tree_sitter-0.20.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:32c3e0f30b45a58d36bf6a0ec982ca3eaa23c7f924628da499b7ad22a8abad71"}, + {file = "tree_sitter-0.20.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b02e4ab2158c25f6f520c93318d562da58fa4ba53e1dbd434be008f48104980"}, + {file = "tree_sitter-0.20.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10e567eb6961a1e86aebbe26a9ca07d324f8529bca90937a924f8aa0ea4dc127"}, + {file = "tree_sitter-0.20.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:63f8e8e69f5f25c2b565449e1b8a2aa7b6338b4f37c8658c5fbdec04858c30be"}, + {file = "tree_sitter-0.20.2.tar.gz", hash = "sha256:0a6c06abaa55de174241a476b536173bba28241d2ea85d198d33aa8bf009f028"}, ] [[package]] name = "tree-sitter-languages" -version = "1.7.0" +version = "1.8.0" description = "Binary Python wheels for all tree sitter languages." optional = false python-versions = "*" files = [ - {file = "tree_sitter_languages-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fd8b856c224a74c395ed9495761c3ef8ba86014dbf6037d73634436ae683c808"}, - {file = "tree_sitter_languages-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:277d1bec6e101a26a4445cd7cb1eb8f8cf5a9bbad1ca80692bfae1af63568272"}, - {file = "tree_sitter_languages-1.7.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0473bd896799ccc87f428766813ddedd3506cad8430dbe863b663c81d7387680"}, - {file = "tree_sitter_languages-1.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb6799419bc7e3029112f2a3f8b77b6c299f94f03bb70e5c31a437b3180486be"}, - {file = "tree_sitter_languages-1.7.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e5b705c8ce6ef47fc461484878956ecd42a67cbeb0a17e323b86a4439a8fdc3d"}, - {file = "tree_sitter_languages-1.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:28a732be6fced2f70184c1b34f64961e3b6259fe6d5f7540c91028c2a43a7109"}, - {file = "tree_sitter_languages-1.7.0-cp310-cp310-win32.whl", hash = "sha256:f5cdb1ec88f0b8c617330c953555a20cc7e96ca6b1f5c68ab6db347e869cfeeb"}, - {file = "tree_sitter_languages-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:26cb344a75798fce1a73b690504d8e7789f6ba25a178efcd203444d7868caf38"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:433b56cb3dca02b30f21c596f431a2cff90905326be1f8913c3515acb984b21e"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96686390e1a01af44aedef7b33d6be82de3cf674a98a5c7b417e540e6afa62cc"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25a4b6d559fbd76c6ec1b73cf03d09f53aaa5a1b61078a3f518b162866d9d97e"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e504f199c7a4c8b1b1efb05a063450aa23234feea6fa6c06f4077f7248ea9c98"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6b29856e9314b5f68f05dfa45e6674f47535229dda32294ba6d129077a97759c"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:786fdaf3d2120eef9384b0f22d7e2e42a561073ba753c7b438e90a1e7b351650"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-win32.whl", hash = "sha256:a55a7007056d0927b78481b437d79ea0487cc991c7f9c19d67adcceac3d47f53"}, - {file = "tree_sitter_languages-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:4b01d3bdf7ce2aeee4d0df62071a0ca91e618a29845686a5bd714d93c5ef3b36"}, - {file = "tree_sitter_languages-1.7.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9b603f1ad01bfb9d178f965125e2528cb7da9666d180f4a9a1acfaedbf5862ea"}, - {file = "tree_sitter_languages-1.7.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70610aa26dd985d2fb9eb07ea8eacc3ceb0cc9c2e91416f51305120cfd919e28"}, - {file = "tree_sitter_languages-1.7.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0444ebc8bdb7dc0d66a816050cfd52376c4e62a94a9c54fde90b29acf3e4bab1"}, - {file = "tree_sitter_languages-1.7.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7eeb5a3307ff1c0994ffff5ea37ec656a716a728b8c9359374104da521a76ded"}, - {file = "tree_sitter_languages-1.7.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:6c319cef16f2df667f1c165fe4eee160f2b51a0c4b61db1e70de2ab86420ca9a"}, - {file = "tree_sitter_languages-1.7.0-cp36-cp36m-win32.whl", hash = "sha256:b216650126d95d494f927393903e836a7ef5f0c4db0834f3a0b576f97c13abaf"}, - {file = "tree_sitter_languages-1.7.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6c96e5785d164a205962a10256808b3d12dccee9827ec88a46899063a2a2d28"}, - {file = "tree_sitter_languages-1.7.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:adafeabbd8d47b80122fad18bb61c25ed3da04f5347b7d774b53826accb27b7a"}, - {file = "tree_sitter_languages-1.7.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50e2bc5d2da770ecd5af94f9d716faa4764f890fd61bc0a488e9269653d9fb71"}, - {file = "tree_sitter_languages-1.7.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac773097cff7de6cf265c5be9990b4c6690161452da1d9fc41021d4bf7e8c73a"}, - {file = "tree_sitter_languages-1.7.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b233bfc48cf0f16436200afc7d7643cd87101c321de25b919b61f21f1693aa52"}, - {file = "tree_sitter_languages-1.7.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:eab3caedf50467045ed5cab776a57b494332616376d387c6600fd7ea4f5483cf"}, - {file = "tree_sitter_languages-1.7.0-cp37-cp37m-win32.whl", hash = "sha256:d533f743a22f5696494d3a5a60adb4cfbef63d58b8b5622993d93d6d0a602444"}, - {file = "tree_sitter_languages-1.7.0-cp37-cp37m-win_amd64.whl", hash = "sha256:aab96f64be30c9f73d6dc958ec22bb1a9fe70e90b2d2a3d233d537b347cea729"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1bf89d771621e28847036b377f865f947e555a6654356d21beab738bb2531a69"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b2f171089ec3c4f1de275edc8f0722e1e3dc7a54e83107098315ea2f0952cfcd"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a091577d3a8454c40f813ee2834314c73cc504522f70f9e33d7c2268d33973f9"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8287efa87d080b340b583a6e81266cc3d8266deb61b8f3312649a9d1562e665a"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9c5080c06a2df7a59c69d2422a6ae83a5e37e92d57c4bd5e572d0eb5226ab3b0"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ca8f629cfb406a2f9b9f8a3a5c804d4d1ba4cdca41cccba63f51fc1bab13e5de"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-win32.whl", hash = "sha256:fd3561b37a99c9d501719819a8736529ae3a6d597128c15be432d1855f3cb0d9"}, - {file = "tree_sitter_languages-1.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:377ad60f7a7bf27315676c4fa84cc766aa0019c1e556083763136ed951e934c0"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1dc71b68e48f58cd5b6a9ab7a541714201815629a6554a969cfc579a6ee6e53"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb1521367b14c275bef70997ea90526e7049f840ba1bbd3ef56c72f5b15596e9"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f73651f7e78371dc3d455e8aba510cc6fb9e1ac1d648c3334157950781eb295"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:049b0dd63be721fe3f9642a2b5a044bea2852de2b35818467996242ae4b7f01f"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c428a8e1f5ecc4eb5c79abff3eb2881123446cde16fd1d8866d527470a6fdd2f"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:40fb3fc11ff90caf65b4713feeb6c4852e5d2a04ef8ae6a2ac734a702a6a6c7e"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-win32.whl", hash = "sha256:f28e9904833b7a909f8227c4560401049bd3310cebe3e0a884d9461f783b9af2"}, - {file = "tree_sitter_languages-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ea47ee390ec2e1c9bf96d7b418775263766021a834910c9f2d578f95a3e27d0f"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a20045f0c7a8394ac0c085c3a7da88438f9e62c6a8b661ebf63c3edb8c3f2bf6"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ef80d5896b420d434f7322abbc2c5a5548a37b3821c5486ed0612d2bd760d5a"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e7c7100c7b4a364035417e811ab8d43c8ee4e38d0c6ab9cad9c4d8133c0abd"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9618bfb5874c43fcb4da43cd71bc24f01f4f94cd55bb9923c4210c7f9e977eb5"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7b0b606be0c61155bde8e913528b7dc038e8476891f5b198996f780c678ecc0"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:306b49d60afb8c08f95a55e38744687521aa9350a97e9d6d1512db47ea401c51"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b561b979d1dc15a0b2bc35586fe4ccf95049812944042ea5760d8450b63c3fe0"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c46c82a5649c41fd4ce7483534fe548a98af6ef6490b5c9f066e2df43e40aa9"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-win32.whl", hash = "sha256:4d84b2bf63f8dc51188f83a6dfc7d70365e1c720310c1222f44d0cd2ec76e4d0"}, + {file = "tree_sitter_languages-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:c59b81123fa73e7d66d3a8bc0e64af2f2a8fcbbce1b08676d9188ec5edb4fb49"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a5816a1e394d717a86b9f5cbb0af08ad92a9badbb4b95678d75052e6bd7402"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:912a12a56361077715b231f1931cf7d472f7d6cfdc76abb806e6b1bdf11d3835"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33838baa8583b2c9f9df4d672237158dcc9d845782413569b51cc8dfed2fb4de"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b6f148e459e8af180be68e9f9c8f8c4db0db170850482b083fd078fba3f4076"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96dbdaff9d317d193451bc5b566098717096381d67674f9e65fb8f0ebe98c847"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c719535ebdd39f94c26f2182b0d16c45a2996b03b5ad7b78a863178eca1546d"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d5c4cb2f4231135d038155787c96f4ecdf44f63eeee8d9e36b100b96a80a7764"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:524bfa0bcbf0fe8cbb93712336d1de0a3073f08c004bb920270d69c0c3eaaf14"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-win32.whl", hash = "sha256:26a0b923c47eeed551e4c307b7badb337564523cca36f9c40e188a308f471c72"}, + {file = "tree_sitter_languages-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3f0ed6297878f9f335f652843e9ab48c561f9a5b312a41a868b5fc127567447b"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0f18d0d98b92bfa40ec15fc4cc5eb5e1f39b9f2f8986cf4cb3e1f8a8e31b06cf"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c742b0733be6d057d323252c56b8419fa2e120510baf601f710363971ae99ae7"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4417710db978edf6bad1e1e59efba04693919ed45c4115bae7da359354d9d8af"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a051e1cceddd1126ce0fa0d3faa12873e5b52cafae0893cc82d22b21348fc83c"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2665768f7ef6d00ab3847c5a3a5fdd54fbc62a9abf80475bff26dcc7a4e8544f"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:76be6fd0d1e514e496eb3430b05ce0efd2f7d09fc3dfe47cc99afc653313c36a"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:510c5ba5dd3ce502f2963c46cc56ad4a0acd1b776be9b119da03f392bda9f8bf"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-win32.whl", hash = "sha256:f852ff7b77df5c7a3f8b825c31673aee59456a93347b58cfa43fdda81fe1cb63"}, + {file = "tree_sitter_languages-1.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:53934c8b09650e576ad5724b84c6891d84b69508ad71a78bb2d4dc88b63543fc"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:400ba190fd08cec9412d70efa09e2f1791a0db82a3e9b31f677e145ad2e48a9a"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:937b0e8cc07fb6574b475fcaded8dd16fa445c66f40bf449b4e50684fd8c380b"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c165c5d13ee335c74a2b6dc6edfcf85045839fa2f7254d2aae3ae9f76020e87d"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:124117c6184653cdd381c70a16e5d6a45a41c3f6470d9d756452ea50aa6bb472"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4c12232c93d4c5c8b3b6324850085971fa93c2226842778f07fe3fba9a7683c1"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b9baf99c00366fe2c8e61bf7489d86eaab4c884f669abdb30ba2450cfabb77f7"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f97baf3d574fc44872c1de8c941888c940a0376c8f80a15ec6931d19b4fe2091"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-win32.whl", hash = "sha256:c40267904f734d8a7e9a05ce60f04ea95db59cad183207c4af34e6bc1f5bbd1f"}, + {file = "tree_sitter_languages-1.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:06b8d11ea550d3c4f0ce0774d6b521c44f2e83d1a77d50f85bea3ed150e66c28"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9a151d4f2637309f1780b9a0422cdeea3c0a8a6209800f587fe4374ebe13e6a1"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1a3afb35a316495ff1b848aadeb4f9f7ef6522e9b730a7a35cfe28361398404e"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22eb91d745b96936c13fc1c100d78e6dcbaa14e9fbe54e180cdc6ca1b262c0f"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54a3a83474d3abb44a178aa1f0a5ef73002c014e7e489977fd39624c1ac0a476"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5a13aa1e6f0fc76268e8fed282fb433ca4b8f6644bb75476a10d28cc19d6cf3"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:68872fcea16f7ddbfeec52120b7070e18a820407d16f6b513ec95ede4110df82"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:43928c43d8a25204297c43bbaab0c4b567a7e85901a19ef9317a3964ad8eb76e"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cca84cacd5530f23ae5d05e4904c2d42f7479fd80541eda34c27cadbf9611d6b"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-win32.whl", hash = "sha256:9d043fdbaf260d0f36f8843acf43096765bed913be71ad705265dccb8e381e1c"}, + {file = "tree_sitter_languages-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f5bbccf1250dc07e74fd86f08a9ed614efd64986a48c142846cd21e84267d46b"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10046058a4213304e3ba78a52ab88d8d5a2703f5d193e7e976d0a53c2fa12f4b"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2fc84bb37ca0bb1f45f808a38733f6bb9c2e8fc8a02712fe8658fe3d31ed74e7"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36b13199282d71d2a841f404f58ccf914b3917b27a99917b0a79b80c93f8a24e"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a94f5f5ac57591004823385bd7f4cc1b62c7b0b08efc1c39a5e33fb2f8c201bf"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a796a359bd6fb4f2b67e29f86c9130bd6ae840d75d31d356594f92d5505f43d"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:45a6edf0106ff653940fe52fb8a47f8c03d0c5981312ac036888d44102840452"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f077fe6099bb310a247514b68d7103c6dbafef552856fcd225d0867f78b620b7"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3842ef8d05e3368c227fd5a57f08f636374b4b870070916d08c4aafb99d04cd1"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-win32.whl", hash = "sha256:3e9eafc7079114783b5385a769fd190c93525bcae3cf6791fd819c617067394e"}, + {file = "tree_sitter_languages-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:9d30b7f48f18a60eea9a0f9494e0f0ea6f560d861770a84c3faab8d7a446fc55"}, ] [package.dependencies] tree-sitter = "*" +[[package]] +name = "typer" +version = "0.9.0" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.6" +files = [ + {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"}, + {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"}, +] + +[package.dependencies] +click = ">=7.1.1,<9.0.0" +typing-extensions = ">=3.7.4.3" + +[package.extras] +all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] +doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] +test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] + +[[package]] +name = "types-certifi" +version = "2021.10.8.3" +description = "Typing stubs for certifi" +optional = false +python-versions = "*" +files = [ + {file = "types-certifi-2021.10.8.3.tar.gz", hash = "sha256:72cf7798d165bc0b76e1c10dd1ea3097c7063c42c21d664523b928e88b554a4f"}, + {file = "types_certifi-2021.10.8.3-py3-none-any.whl", hash = "sha256:b2d1e325e69f71f7c78e5943d410e650b4707bb0ef32e4ddf3da37f54176e88a"}, +] + +[[package]] +name = "types-python-dateutil" +version = "2.8.19.14" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = "*" +files = [ + {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"}, + {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"}, +] + +[[package]] +name = "types-toml" +version = "0.10.8.7" +description = "Typing stubs for toml" +optional = false +python-versions = "*" +files = [ + {file = "types-toml-0.10.8.7.tar.gz", hash = "sha256:58b0781c681e671ff0b5c0319309910689f4ab40e8a2431e205d70c94bb6efb1"}, + {file = "types_toml-0.10.8.7-py3-none-any.whl", hash = "sha256:61951da6ad410794c97bec035d59376ce1cbf4453dc9b6f90477e81e4442d631"}, +] + [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] [[package]] @@ -2897,13 +3863,13 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake [[package]] name = "urllib3" -version = "2.0.4" +version = "2.0.7" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, - {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, ] [package.extras] @@ -2914,13 +3880,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.24.2" +version = "20.24.6" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.2-py3-none-any.whl", hash = "sha256:43a3052be36080548bdee0b42919c88072037d50d56c28bd3f853cbe92b953ff"}, - {file = "virtualenv-20.24.2.tar.gz", hash = "sha256:fd8a78f46f6b99a67b7ec5cf73f92357891a7b3a40fd97637c27f854aae3b9e0"}, + {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"}, + {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"}, ] [package.dependencies] @@ -2929,18 +3895,105 @@ filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<4" [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] +[[package]] +name = "watchfiles" +version = "0.21.0" +description = "Simple, modern and high performance file watching and code reload in python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"}, + {file = "watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"}, + {file = "watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"}, + {file = "watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"}, + {file = "watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"}, + {file = "watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"}, + {file = "watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"}, + {file = "watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"}, + {file = "watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"}, + {file = "watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"}, + {file = "watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"}, + {file = "watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"}, + {file = "watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"}, + {file = "watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"}, + {file = "watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"}, +] + +[package.dependencies] +anyio = ">=3.0.0" + [[package]] name = "wcwidth" -version = "0.2.6" +version = "0.2.9" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, + {file = "wcwidth-0.2.9-py2.py3-none-any.whl", hash = "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223"}, + {file = "wcwidth-0.2.9.tar.gz", hash = "sha256:a675d1a4a2d24ef67096a04b85b02deeecd8e226f57b5e3a72dbb9ed99d27da8"}, ] [[package]] @@ -2971,17 +4024,17 @@ files = [ [[package]] name = "websocket-client" -version = "1.6.1" +version = "1.6.4" description = "WebSocket client for Python with low level API options" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "websocket-client-1.6.1.tar.gz", hash = "sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd"}, - {file = "websocket_client-1.6.1-py3-none-any.whl", hash = "sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d"}, + {file = "websocket-client-1.6.4.tar.gz", hash = "sha256:b3324019b3c28572086c4a319f91d1dcd44e6e11cd340232978c684a7650d0df"}, + {file = "websocket_client-1.6.4-py3-none-any.whl", hash = "sha256:084072e0a7f5f347ef2ac3d8698a5e0b4ffbfcab607628cadabc650fc9a83a24"}, ] [package.extras] -docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] +docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] @@ -3074,20 +4127,20 @@ multidict = ">=4.0" [[package]] name = "zipp" -version = "3.16.2" +version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, - {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [metadata] lock-version = "2.0" -python-versions = ">=3.8,<3.12" -content-hash = "003e97a3a488b2cdffd88ebbb716c2a122e5a24840e4e1611c28147195018c34" +python-versions = ">=3.9,<3.12" +content-hash = "3fe63f4aec951565b5754f620497680b82f5b60492bbfaef852689d40180347a" diff --git a/poetry.toml b/poetry.toml new file mode 100644 index 0000000..c2e18e3 --- /dev/null +++ b/poetry.toml @@ -0,0 +1,5 @@ +[virtualenvs] +in-project = true + +[installer] +moddern-installation = false diff --git a/pyproject.toml b/pyproject.toml index e2dd173..be4b9d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "repo-gpt" -version = "0.1.5" +version = "0.1.6" description = "Search your code repository using GPT3.5 or GPT4." authors = ["Shruti Patel "] license = "Apache License 2.0" @@ -21,26 +21,45 @@ classifiers = [ ] [tool.poetry.dependencies] -python = ">=3.8,<3.12" +python = ">=3.9,<3.12" pandas = "^2.0.2" numpy = "^1.24.3" -halo = "^0.0.31" tqdm = "^4.65.0" pathspec = "^0.11.1" openai = "^0.27.8" rich = "^13.4.1" tenacity = "^8.2.2" -sqlglot = "^16.4.0" tree-sitter-languages = "^1.7.0" -pygments = "^2.16.1" tiktoken = "^0.4.0" +configargparse = "^1.7" +toml = "^0.10.2" +pyautogen = "^0.1.14" +code2flow = "^2.5.1" +networkx = "^3.1" +pydeps = "^1.12.17" +pylint = "^3.0.1" +python-levenshtein = "^0.23.0" +colored = "^2.2.3" +fuzzywuzzy = "^0.18.0" [tool.poetry.group.dev.dependencies] pytest = "^7.3.2" pre-commit = "^3.3.2" exceptiongroup = { version="^1.1.1", markers="python_version <= '3.10'" } -jupyterlab = "^4.0.4" +jupyterlab = "^4.0.8" bump2version = "^1.0.1" +ipython = "^8.14.0" +pygraphviz = "^1.11" # Moved here temporarily because so pygraphviz doesn't need to be install on ci/cd. + +#[tool.poetry.dependencies.pygraphviz] +## This marker ensures that the build options are only applied on macOS +#markers = "sys_platform == 'darwin'" +#build-options = [ +# "--global-option=build_ext", +# "--global-option=-I/usr/local/opt/graphviz/include/", +# "--global-option=-L/usr/local/opt/graphviz/lib/" +#] +modal = "^0.55.4043" [tool.poetry.scripts] repo-gpt = "repo_gpt.cli:main" @@ -51,3 +70,6 @@ build-backend = "poetry.core.masonry.api" [tool.pytest.ini_options] python_paths = ["src"] + +[tool.repo_gpt] +code_root_path = "./src/repo_gpt" diff --git a/src/repo_gpt/agents/__init__.py b/src/repo_gpt/agents/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/repo_gpt/agents/autogen/__init__.py b/src/repo_gpt/agents/autogen/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/repo_gpt/agents/autogen/repo_qna.py b/src/repo_gpt/agents/autogen/repo_qna.py new file mode 100644 index 0000000..a732421 --- /dev/null +++ b/src/repo_gpt/agents/autogen/repo_qna.py @@ -0,0 +1,356 @@ +import logging +import os +import re +from pathlib import Path + +import autogen +import pytest + +from repo_gpt.agents.autogen.user_proxy_function_call_agent import ( + UserProxyFunctionCallAgent, +) +from repo_gpt.agents.repo_comprehender import get_relative_path_directory_structure +from repo_gpt.code_manager.abstract_extractor import AbstractCodeExtractor +from repo_gpt.file_handler.generic_code_file_handler import PythonFileHandler +from repo_gpt.openai_service import OpenAIService +from repo_gpt.search_service import SearchService, convert_search_df_to_json + +logger = logging.getLogger(__name__) +from repo_gpt.logging_config import VERBOSE_INFO, configure_logging + + +class RepoQnA: + def __init__(self, question, root_path, embedding_path=None, openai_api_key=None): + self.question = question + self.question_answer = None + self.is_valid_answer = None + self.validator_explanation = None + self.openai_api_key = openai_api_key + self.root_path = Path(root_path) + self.embedding_path = ( + Path(embedding_path) + if embedding_path is not None + else self.root_path / ".repo_gpt/code_embeddings.pkl" + ) + self.openai_service = OpenAIService(openai_api_key) + self.search_service = SearchService(self.openai_service, self.embedding_path) + self.openai_api_key = ( + openai_api_key if openai_api_key else os.environ["OPENAI_API_KEY"] + ) + + config_list = [ + { + "model": "gpt-3.5-turbo-1106", + "api_key": self.openai_api_key, + }, # OpenAI API endpoint for gpt-3.5-turbo + ] + self.config = self.create_function_augmented_config(config_list) + + def create_code_librarian(self): + return autogen.AssistantAgent( + name="CodeRepo Librarian", + system_message="""You are a detail-oriented world-class software engineer. You specialize in answering questions about the user's codebase. You use the functions to search and understand the codebase.""", + llm_config=self.config, + ) + + def is_answer_to_question(self, msg): + is_termination_msg = msg.get("content", "") and msg.get( + "content", "" + ).rstrip().startswith("ANSWER:") + + if is_termination_msg: + self.question_answer = msg.get("content", "").replace("ANSWER:", "").strip() + + return is_termination_msg + + def is_answer_to_question(self, msg): + content = msg.get("content", "") + if not content: + return False + + # Check if the content contains the "ANSWER:" marker + if "ANSWER:" in content: + # Find the position where "ANSWER:" ends + answer_start_index = content.find("ANSWER:") + len("ANSWER:") + + # Extract the content after "ANSWER:" + self.question_answer = content[answer_start_index:].strip() + + # Return True since the content contains an answer + return True + + # Return False if the content does not contain "ANSWER:" + return False + + def is_answer_correct(self, msg): + content = msg.get("content", "") + if not content: + return False + + # Check for "ANSWER:" and capture the value after it + answer_pattern = r"^ANSWER:\s*(True|False|Unsure)" + answer_match = re.search(answer_pattern, content, re.IGNORECASE) + + # If "ANSWER:" is found, extract the value and check for "EXPLANATION:" + if answer_match: + self.is_valid_answer = answer_match.group(1) + + # Check for "EXPLANATION:" and capture the value after it + explanation_pattern = r"EXPLANATION:\s*(.*)" + explanation_match = re.search(explanation_pattern, content) + if explanation_match: + self.validator_explanation = explanation_match.group(1).strip() + + return True + return False + + def create_code_answer_validator(self): + return autogen.AssistantAgent( + name="CodeRepo Answer Validator", + system_message="""You are a detail-oriented world-class software engineer. You specialize in criticing answers to code repository questions. You do this by searching and understanding the codebase to check if the provided answer is correct. You use the functions to search and understand the codebase.""", + llm_config=self.config, + ) + + def create_function_augmented_config(self, config): + return { + "functions": [ + { + "name": "semantic_search", + "description": "Use this function to search the entire codebase semantically. The input should be the search query string.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": f"""The semantic search query to use to search the code base.""", + } + }, + "required": ["query"], + }, + }, + { + "name": "view_function_code", + "description": "Use this function to search for and view a function's code in the user's codebase. Input should be the name of the function you want to search for.", + "parameters": { + "type": "object", + "properties": { + "function_name": { + "type": "string", + "description": f"""The name of the function or its description.""", + } + }, + "required": ["function_name"], + }, + }, + # { + # "name": "view_file_functions_and_classes", + # "description": "Use this function to retrieve a list of the functions and classes in a file from the user's codebase.", + # "parameters": { + # "type": "object", + # "properties": { + # "file_paths": { + # "type": "array", + # "items": { + # "type": "string", + # "description": "An array of one or more file paths of a file you want to retrieve functions and classes from. If a file doesn't exist, the function will return a string saying so.", + # }, + # "description": f"""The file paths of the files you want to retrieve functions and classes to understand the user's task better. Below are the files within the user's repository: + # {get_relative_path_directory_structure("/Users/shrutipatel/projects/work/repo-gpt")} + # """, + # } + # }, + # "required": ["file_paths"], + # }, + # }, + { + "name": "view_raw_file_contents", + "description": "Use this function to retrieve the raw contents of a file from the user's codebase.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": f"""The file path of the file you want to retrieve the raw contents of. Below are the files within the user's repository: +{get_relative_path_directory_structure("/Users/shrutipatel/projects/work/repo-gpt")} +""", + } + }, + "required": ["file_path"], + }, + }, + ], + "config_list": config, + "request_timeout": 120, + } + + def create_user_proxy(self, is_termination_msg): + return self.UserProxyAgent( + self.root_path, + self.embedding_path, + self.openai_api_key, + is_termination_msg, + ) + + def initiate_chat(self, validate_answer=False): + code_librarian = self.create_code_librarian() + user_proxy = self.create_user_proxy(self.is_answer_to_question) + user_proxy.initiate_chat( + code_librarian, + message=f"""{self.question} +Use the functions to read and understand the codebase. Then, once you have an answer, backed up by searching in the code, reply with: +``` +ANSWER: +``` +If you cannot answer the user's question, reply with: +``` +ANSWER: I cannot answer this question. +``` +""", + clear_history=True, + ) + + # print(self.question_answer) + if self.question_answer is not None and validate_answer: + # Validate answer + code_answer_validator = self.create_code_answer_validator() + validator_user_proxy = self.create_user_proxy(self.is_answer_correct) + + validator_user_proxy.initiate_chat( + code_answer_validator, + message=f"""Verify the following question & answer are correct: +Q:{self.question} +A:{self.question_answer} +------------------ +Use the functions to read and understand the codebase. Then, once you have an answer, backed up by searching in the code, reply with: +``` +ANSWER: +EXPLANATION: +``` +""", + clear_history=True, + ) + + # print(self.is_valid_answer) + + # TODO add reflection + + if not self.is_valid_answer: + user_proxy.initiate_chat( + code_librarian, + message=f"""{self.question} +This is the last answer, incorrect answer: +{self.question_answer} +Here is an explanation of why the answer is incorrect: +{self.validator_explanation} +-------- +Use the functions to read and understand the codebase. Then, once you have an answer, backed up by searching in the code, reply with: +``` +ANSWER: +``` +If you cannot answer the user's question, reply with: +``` +ANSWER: I cannot answer this question. +``` +""", + clear_history=True, + ) + return self.question_answer + + class UserProxyAgent(UserProxyFunctionCallAgent): + def __init__( + self, root_path, embedding_path, openai_api_key, is_termination_msg_func + ): + self.openai_service = OpenAIService(openai_api_key) + self.root_path = root_path + self.embedding_path = embedding_path + self.search_service = SearchService( + self.openai_service, self.embedding_path + ) + + super().__init__( + name="You", + is_termination_msg=is_termination_msg_func, + human_input_mode="NEVER", + max_consecutive_auto_reply=3, + code_execution_config=False, + function_map={ + # "view_file_functions_and_classes": self.view_file_functions_and_classes, + "view_raw_file_contents": self.view_raw_file_contents, + "view_function_code": self.view_function_code, + "semantic_search": self.semantic_search, + }, + ) + + def view_function_code(self, function_name): + # logger.info(f"Reading the code for: {function_name}") + df = self.search_service.find_function_match(function_name) + + if df is None or df.empty: + return "Not found." + else: + return convert_search_df_to_json(df, ["code"]) + + def semantic_search(self, query): + # logger.info(f"Searching the codebase for: {query}") + return convert_search_df_to_json( + self.search_service.semantic_search_similar_code(query) + ) + + # def view_file_functions_and_classes(self, file_paths): + # # logger.info(f"Skimming the code in: {file_paths}") + # results = [] + # for file_path in file_paths: + # full_path = self.root_path / Path(file_path) + # + # if not full_path.exists(): + # results.append(f"File not found: {file_path}") + # continue # Skip to the next iteration + # elif full_path.is_dir(): + # results.append( + # f"This is not a file, but a directory, pass a filepath instead: {file_path}" + # ) + # continue # Skip to the next iteration + # + # parsable_extensions = AbstractCodeExtractor.get_file_extensions_with_handlers() + # if full_path.suffix not in parsable_extensions: + # return f"Cannot parse file." # TODO just pass the full text instead + # file_handler = AbstractCodeExtractor.get_handler(file_path)() + # file_contents = file_handler.summarize_file(full_path) + # + # if "" == file_contents: + # results.append(f"File is empty: {file_path}") + # continue + # + # results.append(file_contents) + # + # return "\n".join(results) + + def view_raw_file_contents(self, file_path): + partial_path = Path(file_path) + full_path = self.root_path / Path(file_path) + print(full_path) + + path_to_read = None + + if not full_path.exists() and not partial_path.exists(): + return f"File not found: {file_path}" + elif full_path.exists() and not full_path.is_dir(): + path_to_read = full_path + elif partial_path.exists() and not partial_path.is_dir(): + path_to_read = partial_path + else: + return f"This is not a file, but a directory, pass a filepath instead: {file_path}" + + with open(path_to_read, "r") as f: + return f.read() + + +def test(): + # REPO_QUESTION = "How do I add a handler for a new language to the codebase?" + # REPO_QUESTION = "Where should I add new tests for a new Java file handler I'm writing?" + # REPO_QUESTION = "What is the framework used for writing tests?" + REPO_QUESTION = "How do I replace pandas with polars code?" + root_path = "/Users/shrutipatel/projects/work/repo-gpt/" + repo_qna = RepoQnA(REPO_QUESTION, root_path) + print(repo_qna.initiate_chat()) + assert False diff --git a/src/repo_gpt/agents/autogen/user_proxy_function_call_agent.py b/src/repo_gpt/agents/autogen/user_proxy_function_call_agent.py new file mode 100644 index 0000000..7354819 --- /dev/null +++ b/src/repo_gpt/agents/autogen/user_proxy_function_call_agent.py @@ -0,0 +1,73 @@ +import json +import logging + +import autogen + +try: + from termcolor import colored +except ImportError: + + def colored(x, *args, **kwargs): + return x + + +logger = logging.getLogger(__name__) + + +class UserProxyFunctionCallAgent(autogen.UserProxyAgent): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def execute_function(self, func_call): + """Execute a function call and return the result. + + Override this function to modify the way to execute a function call. + + Args: + func_call: a dictionary extracted from openai message at key "function_call" with keys "name" and "arguments". + + Returns: + A tuple of (is_exec_success, result_dict). + is_exec_success (boolean): whether the execution is successful. + result_dict: a dictionary with keys "name", "role", and "content". Value of "role" is "function". + """ + func_name = func_call.get("name", "") + + func = self._function_map.get(func_name, None) + + if hasattr(func, "__self__"): + func = getattr(self, func_name, None) + + is_exec_success = False + if func is not None: + # Extract arguments from a json-like string and put it into a dict. + input_string = self._format_json_str(func_call.get("arguments", "{}")) + try: + arguments = json.loads(input_string) + except json.JSONDecodeError as e: + arguments = None + content = f"Error: {e}\n You argument should follow json format." + + # Try to execute the function + if arguments is not None: + print( + colored(f"\n>>>>>>>> EXECUTING FUNCTION {func_name}...", "magenta"), + flush=True, + ) + try: + content = func(**arguments) + is_exec_success = True + except Exception as e: + content = f"Error: {e}" + print(e) + raise e + # print(f"Finished executing, here is the content: {content}") + # print(f"is_exec_success: {is_exec_success}") + else: + content = f"Error: Function {func_name} not found." + + return is_exec_success, { + "name": func_name, + "role": "function", + "content": str(content), + } diff --git a/src/repo_gpt/agents/base_agent.py b/src/repo_gpt/agents/base_agent.py new file mode 100644 index 0000000..2085c16 --- /dev/null +++ b/src/repo_gpt/agents/base_agent.py @@ -0,0 +1,117 @@ +import inspect +import json +import logging +from abc import ABC, abstractmethod + +import openai +import tiktoken +from tenacity import ( # for exponential backoff + retry, + stop_after_attempt, + wait_random_exponential, +) + +from repo_gpt.agents.simple_memory_store import MemoryStore + +logger = logging.getLogger(__name__) + + +class BaseAgent(ABC): + GPT_MODEL = "gpt-3.5-turbo-0613" # gpt-4-0613 + + def __init__( + self, + user_task, + terminating_function_call_name, + system_prompt, + threshold=10, + debug=False, + ): + self.terminating_function_call_name = terminating_function_call_name + self.functions = self._initialize_functions() + self.memory_store = MemoryStore(system_prompt, user_task, self.functions) + self.user_task = user_task + self.system_prompt = system_prompt + self.threshold = threshold + self.debug = debug + + @abstractmethod + def _initialize_functions(self): + """ + Must be implemented by subclasses to initialize function-related attributes. + """ + pass + + def _parse_arguments(self, function_call): + return json.loads(function_call["arguments"]) + + def _append_message(self, message): + self.memory_store.add_message(message) + + def compress_messages(self): + self.memory_store.compress_messages() + + def execute_function_call(self, message): + function_name = message["function_call"]["name"] + args = self._parse_arguments(message["function_call"]) + + func = getattr(self, function_name, None) + if not func: + return f"Error: function {function_name} does not exist" + + # Filter out args to only pass those that the function accepts + accepted_args = inspect.signature(func).parameters.keys() + filtered_args = { + key: value for key, value in args.items() if key in accepted_args + } + + return func(**filtered_args) + + # @retry(wait=wait_random_exponential(multiplier=1, max=40), stop=stop_after_attempt(3)) + def chat_completion_request(self, function_call="auto", model=GPT_MODEL): + try: + response = openai.ChatCompletion.create( + model=model, + messages=self.memory_store.messages, + functions=self.functions, + function_call=function_call, + ) + return response + except Exception as e: + logger.error("Unable to generate ChatCompletion response") + logger.error(f"Exception: {e}") + raise + + def append_function_result_message(self, function_call_name, results): + self._append_message( + {"role": "function", "content": results, "name": function_call_name} + ) + + def process_messages(self): + # TODO: make ending function name settable OR move this into the childclass + iter_count = 0 + function_call_name = "" + + results = "" + + while ( + iter_count < self.threshold + and function_call_name != self.terminating_function_call_name + ): + chat_response = self.chat_completion_request() + assistant_message = chat_response["choices"][0]["message"] + self._append_message(assistant_message.to_dict_recursive()) + logger.debug(assistant_message) + if "function_call" in assistant_message: + results = self.execute_function_call(assistant_message) + function_call_name = assistant_message["function_call"]["name"] + self.append_function_result_message(function_call_name, results) + else: + self._append_message({"role": "user", "content": "Continue"}) + iter_count += 1 + + if function_call_name == self.terminating_function_call_name: + return results + raise Exception( + "I had to stop the search loop before plan for formulated because I reached the end of my allotted function calls" + ) diff --git a/src/repo_gpt/agents/central_intelligence.py b/src/repo_gpt/agents/central_intelligence.py new file mode 100644 index 0000000..c754aca --- /dev/null +++ b/src/repo_gpt/agents/central_intelligence.py @@ -0,0 +1,109 @@ +import logging + +from repo_gpt.agents.base_agent import BaseAgent +from repo_gpt.agents.code_writer import CodeWritingAgent +from repo_gpt.agents.repo_comprehender import RepoUnderstandingAgent +from repo_gpt.file_handler.generic_code_file_handler import PythonFileHandler +from repo_gpt.openai_service import OpenAIService +from repo_gpt.search_service import SearchService + +logger = logging.getLogger(__name__) + + +class CentralIntelligenceAgent(BaseAgent): + system_prompt = """You are an expert software engineer. You have a few helper agents that help you understand and write good software. You can call these agents by using the following functions: + - understand_the_codebase_and_formulate_plan(query): Use this function to call an LLM agent to understand the codebase and formulate a plan of what files need to be updated and how they need to be updated. Also use this function to answer general questions about the codebase. The input should be a query about the codebase. + - update_code(plan): Use this function to call an LLM agent to update the code in the repository. The input should be a plan of what files need to be updated and how they need to be updated. +Use the two llm agents to complete the user task. Always understand the codebase first and follow the existing coding practices +**DO NOT** respond to the user directly. Use the functions instead. +""" + + def __init__( + self, + user_task, + root_path, + embedding_file_path, + threshold=10 * 2, + debug=False, + openai_key=None, + ): + system_prompt = "You are an expert software engineer writing code in a repository. The user gives you a plan detailing how the code needs to be updated. You implement the code changes using functions. Ask clarifying questions." + super().__init__( + user_task, "completed_all_code_updates", system_prompt, threshold, debug + ) # Call ParentAgent constructor + self.root_path = root_path + self.embedding_path = embedding_file_path + self.openai_key = openai_key + self.openai_service = ( + OpenAIService() if not openai_key else OpenAIService(openai_key) + ) + self.functions = self._initialize_functions() + + def _initialize_functions(self): + return [ + { + "name": "understand_the_codebase_and_formulate_plan", + "description": "Use this function to call an LLM agent to understand the codebase and formulate a plan of what files need to be updated and how they need to be updated. Also use this function to answer general questions about the codebase. The input should be a query about the codebase.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The task that needs to be accomplished or a general repository question that must be answered.", + }, + }, + "required": ["query"], + }, + }, + { + "name": "update_code", + "description": "Use this function to call an LLM agent to update the code in the repository. The input should be a plan of what files need to be updated and how they need to be updated.", + "parameters": { + "type": "object", + "properties": { + "plan": { + "type": "string", + "description": "A detailed plan of what files need to be updated and how they need to be updated.", + } + }, + "required": ["plan"], + }, + }, + { + "name": "users_task_is_completed", + "description": "Call this function when the user's task is completed. ", + "parameters": { + "type": "object", + "properties": { + "summary_of_actions_taken": { + "type": "string", + "description": "Enumeration of all the changes that were made to the code.", + } + }, + "required": ["summary_of_actions_taken"], + }, + }, + ] + + def understand_the_codebase_and_formulate_plan(self, query): + repo_agent = RepoUnderstandingAgent( + query, + self.root_path, + self.embedding_path, + openai_key=self.openai_key, + debug=True, + ) + return repo_agent.process_messages() + + def update_code(self, plan): + writer_agent = CodeWritingAgent( + plan, + self.root_path, + self.embedding_path, + openai_key=self.openai_key, + debug=True, + ) + return writer_agent.process_messages() + + def users_task_is_completed(self, summary_of_actions_taken): + return summary_of_actions_taken diff --git a/src/repo_gpt/agents/code_writer.py b/src/repo_gpt/agents/code_writer.py new file mode 100644 index 0000000..9bbe0f3 --- /dev/null +++ b/src/repo_gpt/agents/code_writer.py @@ -0,0 +1,145 @@ +import logging +from pathlib import Path + +from repo_gpt.agents.base_agent import BaseAgent +from repo_gpt.file_handler.generic_code_file_handler import PythonFileHandler +from repo_gpt.openai_service import OpenAIService +from repo_gpt.search_service import SearchService + +logger = logging.getLogger(__name__) + + +class CodeWritingAgent(BaseAgent): + system_prompt = """You are an expert software engineer writing code in a repository. The user gives you a plan detailing how the code needs to be updated. You implement the code changes using functions. Ask clarifying questions. + **DO NOT** respond to the user directly. Use the functions instead. + """ + + def __init__( + self, + user_task, + root_path, + embedding_path, + system_prompt=system_prompt, + threshold=10, + debug=False, + openai_key=None, + ): + self.system_prompt = system_prompt if system_prompt else self.system_prompt + super().__init__( + user_task, "completed_all_code_updates", system_prompt, threshold, debug + ) # Call ParentAgent constructor + self.root_path = root_path + self.embedding_path = embedding_path + self.openai_service = ( + OpenAIService() if not openai_key else OpenAIService(openai_key) + ) + self.search_service = SearchService(self.openai_service, self.embedding_path) + self.codefilehandler = ( + PythonFileHandler() + ) # TODO: update to handle more than python files (all except sql) + + self.functions = self._initialize_functions() + + def _initialize_functions(self): + return [ + { + "name": "create_file", + "description": "Create a new file with the provided content.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to the new file to be created.", + }, + "content": { + "type": "string", + "description": "Content to write in the new file.", + }, + }, + "required": ["file_path", "content"], + }, + }, + { + "name": "append_to_file", + "description": "Append content to an existing file.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to the file to be updated.", + }, + "content": { + "type": "string", + "description": "Content to append to the file.", + }, + }, + "required": ["file_path", "content"], + }, + }, + { + "name": "completed_all_code_updates", + "description": "Call this function when all the code updates are completed.", + "parameters": { + "type": "object", + "properties": { + "code_changes": { + "type": "string", + "description": "Enumeration of all the changes that were made to the code.", + } + }, + "required": ["code_changes"], + }, + }, + ] + + def completed_all_code_updates(self, code_changes): + self.append_function_result_message("completed_all_code_updates", code_changes) + return code_changes + + def create_file(self, file_path, content): + """ + Create a new file with the provided content. + + Args: + - file_path (str): Path to the new file to be created. + - content (str): Content to write in the new file. + + Returns: + - str: Success or error message. + """ + full_path = self.root_path / Path(file_path) + + # Check if file already exists + if full_path.exists(): + return ( + f"File {file_path} already exists. To update it, use append_to_file()." + ) + + with open(full_path, "w") as f: + f.write(content) + + return f"File {file_path} has been created successfully." + + def append_to_file(self, file_path, content): + """ + Append content to an existing file. + + Args: + - file_path (str): Path to the file to be updated. + - content (str): Content to append in the file. + + Returns: + - str: Success or error message. + """ + full_path = self.root_path / Path(file_path) + + # Check if file exists + if not full_path.exists(): + return f"File {file_path} does not exist. To create it, use create_file()." + + with open(full_path, "a") as f: + f.write(content) + + return f"Content has been appended to {file_path} successfully." diff --git a/src/repo_gpt/agents/repo_comprehender.py b/src/repo_gpt/agents/repo_comprehender.py new file mode 100644 index 0000000..4d320d5 --- /dev/null +++ b/src/repo_gpt/agents/repo_comprehender.py @@ -0,0 +1,270 @@ +# Refactored RepoUnderstandingAgent using the ParentAgent +import logging +import os +from pathlib import Path + +from pathspec import PathSpec +from pathspec.patterns import GitWildMatchPattern +from tqdm import tqdm + +from repo_gpt.agents.base_agent import BaseAgent +from repo_gpt.file_handler.generic_code_file_handler import PythonFileHandler +from repo_gpt.openai_service import OpenAIService +from repo_gpt.search_service import SearchService, convert_search_df_to_json + +# Initialize the tqdm integration with pandas + + +logger = logging.getLogger(__name__) + + +def get_gitignore_spec(root_directory): + gitignore_file = os.path.join(root_directory, ".gitignore") + if not os.path.exists(gitignore_file): + return None + with open(gitignore_file, "r") as f: + spec = PathSpec.from_lines(GitWildMatchPattern, f) + return spec + + +def is_hidden(path): + # Check if a file or directory is hidden by checking if its name starts with a dot + return os.path.basename(path).startswith(".") + + +def get_indented_directory_structure(root_directory): + structured_output = [] + gitignore_spec = get_gitignore_spec(root_directory) + + for current_path, directories, files in os.walk(root_directory): + # Filter out hidden directories and those in gitignore + directories[:] = [ + d + for d in directories + if not is_hidden(d) + and ( + not gitignore_spec + or not gitignore_spec.match_file(os.path.join(current_path, d)) + ) + ] + + # Skip hidden directories in the main loop + if is_hidden(current_path): + continue + + depth = current_path.replace(root_directory, "").count(os.sep) + indent = " " * depth + structured_output.append(f"{indent}/{os.path.basename(current_path)}") + sub_indent = " " * (depth + 1) + + for file in sorted(files): + # Skip hidden files or those in gitignore + if not is_hidden(file) and ( + not gitignore_spec + or not gitignore_spec.match_file(os.path.join(current_path, file)) + ): + structured_output.append(f"{sub_indent}{file}") + + return "\n".join(structured_output) + + +def get_relative_path_directory_structure(root_directory): + structured_output = [] + gitignore_spec = get_gitignore_spec(root_directory) + + for current_path, directories, files in os.walk(root_directory): + # Filter out hidden directories and those in gitignore + directories[:] = [ + d + for d in directories + if not is_hidden(d) + and ( + not gitignore_spec + or not gitignore_spec.match_file(os.path.join(current_path, d)) + ) + ] + + # Skip hidden directories in the main loop + if is_hidden(current_path): + continue + + # # Convert the current directory path to a relative path from the root directory + rel_dir = os.path.relpath(current_path, root_directory) + + # # Append the relative directory path to structured_output + # structured_output.append(rel_dir if rel_dir != "." else "") + + for file in sorted(files): + # Skip hidden files or those in gitignore + if not is_hidden(file) and ( + not gitignore_spec + or not gitignore_spec.match_file(os.path.join(current_path, file)) + ): + # Combine the relative directory path with the file name to get the relative file path + rel_file_path = os.path.join(rel_dir, file) + structured_output.append(rel_file_path) + + return structured_output + + +def get_relative_path_directory_structure_string(root_directory): + return "\n".join(get_relative_path_directory_structure(root_directory)) + + +# print(get_relative_path_directory_structure_string("/Users/shrutipatel/projects/work/repo-gpt")) + + +class RepoUnderstandingAgent(BaseAgent): + system_prompt = """You are an expert software engineer on a specific code repository. Users ask you how they can implement something in their codebase. You first use your tools to search and understand the codebase and then figure out how to implement the users' task in the repository. + **DO NOT** communicate with the user directly. Use the functions instead. + """ + + def __init__( + self, + user_task, + root_path, + system_prompt=system_prompt, + threshold=10, + debug=False, + openai_key=None, + ): + self.system_prompt = system_prompt + super().__init__( + user_task, + "create_plan_to_complete_user_task", + system_prompt, + threshold, + debug, + ) # Call ParentAgent constructor + self.root_path = root_path + self.embedding_path = self.root_path / ".repo_gpt/code_embeddings.pkl" + self.openai_service = ( + OpenAIService() if not openai_key else OpenAIService(openai_key) + ) + self.search_service = SearchService(self.openai_service, self.embedding_path) + self.pythonfilehandler = ( + PythonFileHandler() + ) # TODO: update to handle more than python files (all except SQL) + + self.functions = self._initialize_functions() + + def _initialize_functions(self): + # Define function details + return [ + { + "name": "semantic_search", + "description": "Use this function to search the entire codebase semantically. The input should be the search query string.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": f""" + The semantic search query to use to search the code base. + """, + } + }, + "required": ["query"], + }, + }, + { + "name": "view_function_code", + "description": "Use this function to search for and view a function's code in the user's codebase. Input should be the name of the function you want to search for. An empty response means the given files don't exist.", + "parameters": { + "type": "object", + "properties": { + "function_name": { + "type": "string", + "description": f""" + The name of the function or its description. + """, + } + }, + "required": ["function_name"], + }, + }, + { + "name": "view_file_functions_and_classes", + "description": "Use this function to retrieve a list of the functions and classes in a file from the user's codebase. An empty response means the given files don't exist.", + "parameters": { + "type": "object", + "properties": { + "file_paths": { + "type": "array", + "items": { + "type": "string", + "description": "An array of one or more file paths of a file you want to retrieve functions and classes from. If a file doesn't exist, the function will return a string saying so.", + }, + "description": f""" + The file paths of the files you want to retrieve functions and classes for to better understand the user's task. Below are the files within the user's repository: + {get_relative_path_directory_structure("/Users/shrutipatel/projects/work/repo-gpt")} + """, + } + }, + "required": ["file_paths"], + }, + }, + { + "name": "create_plan_to_complete_user_task", + "description": "Use this function when you understand the user's task and have a detailed plan ready for completing the user's task. The input should be a step-by-step plan on how to complete the user's task. It can include things like 'Create a new file with a given file path', 'Add the given code to the file', etc.", + "parameters": { + "type": "object", + "properties": { + "plan": { + "type": "string", + "description": f""" + A step-by-step plan on how to complete the user's task. It can include things like "Create a new file with a given file path", "Add the given code to the file", etc. + """, + } + }, + "required": ["plan"], + }, + }, + ] + + def view_function_code(self, function_name): + logger.info(f"Reading the code for: {function_name}") + functions_df, classes_df = self.search_service.find_function_match( + function_name + ) + + if (classes_df is None or classes_df.empty) and ( + functions_df is None or functions_df.empty + ): + return "" + elif functions_df is None or functions_df.empty: + return convert_search_df_to_json(classes_df) + elif classes_df is None or classes_df.empty: + return convert_search_df_to_json(functions_df) + else: + return convert_search_df_to_json(functions_df) + + def semantic_search(self, query): + logger.info(f"Searching the codebase for: {query}") + return convert_search_df_to_json( + self.search_service.semantic_search_similar_code(query) + ) + + def view_file_functions_and_classes(self, file_paths): + logger.info(f"Skimming the code in: {file_paths}") + results = [] + for file_path in file_paths: + full_path = self.root_path / Path(file_path) + + if not full_path.exists(): + results.append(f"File not found: {file_path}") + continue # Skip to the next iteration + elif full_path.is_dir(): + results.append( + f"This is not a file, but a directory, pass a filepath instead: {file_path}" + ) + continue # Skip to the next iteration + + # TODO select the correct filehandler and then summarize file + results.append(self.pythonfilehandler.summarize_file(full_path)) + + return "\n".join(results) + + def create_plan_to_complete_user_task(self, plan): + self.append_function_result_message("create_plan_to_complete_user_task", plan) + return plan diff --git a/src/repo_gpt/agents/simple_memory_store.py b/src/repo_gpt/agents/simple_memory_store.py new file mode 100644 index 0000000..a1b49db --- /dev/null +++ b/src/repo_gpt/agents/simple_memory_store.py @@ -0,0 +1,122 @@ +import json +import logging + +import openai +import tiktoken +from tenacity import ( # for exponential backoff + retry, + stop_after_attempt, + wait_random_exponential, +) + +from repo_gpt.openai_service import num_tokens_from_messages, num_tokens_from_string + + +class MemoryStore: + summary_prompt = """*Briefly* summarize this partial conversation about programming. + Include less detail about older parts and more detail about the most recent messages. + Start a new paragraph every time the topic changes! + + This is only part of a longer conversation so *DO NOT* conclude the summary with language like "Finally, ...". Because the conversation continues after the summary. + The summary *MUST* include the function names, libraries, packages that are being discussed. + The summary *MUST* include the filenames that are being referenced! + The summaries *MUST NOT* include ```...``` fenced code blocks! + + Phrase the summary with the USER in first person, telling the ASSISTANT about the conversation. + Write *as* the user. + The user should refer to the assistant as *you*. + Start the summary with "I asked you...". + """ + + SUMMARY_MODEL = "gpt-3.5-turbo-16k-0613" + + def __init__( + self, + system_prompt, + user_task, + functions=[], + threshold=4000, + summary_model=SUMMARY_MODEL, + ): + self.messages = [] + self.threshold = threshold + self.summary_model = summary_model + self.system_prompt = system_prompt + self.user_task = user_task + self._initialize_messages() + self.functions = functions + + def _initialize_messages(self): + initial_messages = [ + {"role": "system", "content": self.system_prompt}, + {"role": "user", "content": self.user_task}, + ] + self.messages = initial_messages + + def add_message(self, message): + self.messages.append(message) + if self._count_messages_tokens() >= self.threshold: + self.compress_messages() + + def get_messages(self): + return self.messages + + def _count_messages_tokens(self): + return num_tokens_from_messages( + self.messages, "gpt-4" + ) + num_tokens_from_string(json.dumps(self.functions), "gpt-4") + + # @retry(wait=wait_random_exponential(multiplier=1, max=40), stop=stop_after_attempt(3)) + + def get_formatted_messages(self): + # output = StringIO() + # pprint.pprint(self.messages, stream=output) + # formatted_messages = output.getvalue() + + # formatted_messages = json.dumps(self.messages) + formatted_messages = [] + for message in self.messages: + if "function_call" in message: + # Message to call a function + formatted_messages.append( + f"calling function {message['function_call']['name']}({str(message['function_call']['arguments'])})" + ) + elif "name" in message: + # Message with function results + formatted_messages.append( + f"function {message['name']} returned: {message['content']}" + ) + else: + formatted_messages.append(f"{message['role']}: {message['content']}") + + return "\n".join(formatted_messages) + # return "test" + + def compress_messages(self): + # TODO: use something intelligent like semantic search possibly to select relevant messages + + summary_messages = [ + { + "role": "system", + "content": f"You are an expert technical writer.", + }, + { + "role": "user", + "content": f"{self.summary_prompt}\n{self.get_formatted_messages()}", + }, + ] + try: + response = openai.ChatCompletion.create( + model=self.SUMMARY_MODEL, messages=summary_messages + ) + logging.debug(response) + assistant_message = response["choices"][0]["message"] + logging.debug(assistant_message) + self._initialize_messages() + assistant_message.role = "user" + self.messages.append(assistant_message) + return response + except Exception as e: + logging.error("Unable to generate ChatCompletion response") + logging.error(f"Exception: {e}") + raise diff --git a/src/repo_gpt/cli.py b/src/repo_gpt/cli.py index 907dc03..d6ac87f 100755 --- a/src/repo_gpt/cli.py +++ b/src/repo_gpt/cli.py @@ -1,9 +1,13 @@ #!./venv/bin/python - -import argparse import os from pathlib import Path +import configargparse + +from repo_gpt import utils +from repo_gpt.agents.autogen.repo_qna import RepoQnA +from repo_gpt.logging_config import VERBOSE_INFO, configure_logging + from .code_manager.code_manager import CodeManager from .openai_service import OpenAIService from .search_service import SearchService @@ -13,59 +17,63 @@ def main(): - parser = argparse.ArgumentParser(description="Code extractor and searcher") + parser = configargparse.ArgParser( + default_config_files=["pyproject.toml", ".repo_gpt/config.toml"], + description="Code extractor and searcher", + config_file_parser_class=configargparse.TomlConfigParser(["tool.repo_gpt"]), + ) + parser.add_argument( + "--pickle_path", + type=str, + help="Path of the pickled DataFrame to search in", + default=CODE_EMBEDDING_FILE_PATH, + ) + parser.add_argument( + "--code_root_path", + type=str, + help="Root path of the code", + default=str(Path.cwd()), + ) + parser.add_argument( + "--testing_package", + type=str, + help="Package/library GPT should use to write tests (e.g. pytest, unittest, etc.)", + ) + + # For some reason no -v returns 2, -v returns 1, -vv returns 3, -vvv returns 5 + parser.add_argument( + "--verbose", + "-v", + action="count", + default=0, + help="Increase verbosity level (e.g., -v, -vv, -vvv)", + ) + subparsers = parser.add_subparsers(dest="command") - def print_help(*args): + def print_help(): parser.print_help() # Sub-command to run code extraction and processing parser_run = subparsers.add_parser( "setup", help="Run code extraction and processing" ) - parser_run.add_argument( - "--root_path", type=str, help="Root path of the code", default=str(Path.cwd()) - ) - parser_run.add_argument( - "--output_path", - type=str, - help="Output path for the pickled DataFrame", - default=CODE_EMBEDDING_FILE_PATH, - ) # Sub-command to search in the pickled DataFrame parser_search = subparsers.add_parser( "search", help="Search in the pickled DataFrame" ) parser_search.add_argument("query", type=str, help="Query string to search for") - parser_search.add_argument( - "--pickle_path", - type=str, - help="Path of the pickled DataFrame to search in", - default=CODE_EMBEDDING_FILE_PATH, - ) # Sub-command to ask a question to the model parser_query = subparsers.add_parser( "query", help="Ask a question about the code to the model" ) parser_query.add_argument("question", type=str, help="Question to ask") - parser_query.add_argument( - "--pickle_path", - type=str, - help="Path of the pickled DataFrame to search in", - default=CODE_EMBEDDING_FILE_PATH, - ) # Sub-command to analyze a file analyze_file = subparsers.add_parser("analyze", help="Analyze a file") analyze_file.add_argument("file_path", type=str, help="File to analyze") - analyze_file.add_argument( - "--pickle_path", - type=str, - help="Path of the pickled DataFrame to search in", - default=CODE_EMBEDDING_FILE_PATH, - ) # Sub-command to explain a file explain_code = subparsers.add_parser("explain", help="Explain a code snippet") @@ -94,18 +102,6 @@ def print_help(*args): help="Filepath to save the generated tests to", ) - add_test.add_argument( - "--testing_package", - type=str, - help="Package/library GPT should use to write tests (e.g. pytest, unittest, etc.)", - ) - add_test.add_argument( - "--pickle_path", - type=str, - help="Path of the pickled DataFrame to search in", - default=CODE_EMBEDDING_FILE_PATH, - ) - parser_help = subparsers.add_parser("help", help="Show this help message") parser_help.set_defaults(func=print_help) @@ -119,17 +115,20 @@ def print_help(*args): if args.command not in ["setup", "explain"] else None ) + if int(args.verbose) >= 1: + configure_logging(VERBOSE_INFO) if args.command == "setup": - root_path = Path(args.root_path) - output_path = Path(args.output_path) - manager = CodeManager(output_path, root_path) + code_root_path = Path(args.code_root_path) + pickle_path = Path(args.pickle_path) + manager = CodeManager(pickle_path, code_root_path) manager.setup() elif args.command == "search": # search_service.simple_search(args.query) # simple search search_service.semantic_search(args.query) # semantic search elif args.command == "query": - search_service.question_answer(args.question) + repo_qna = RepoQnA(args.question, args.code_root_path) + repo_qna.initiate_chat() elif args.command == "analyze": search_service.analyze_file(args.file_path) elif args.command == "explain": @@ -212,6 +211,4 @@ def add_tests( if __name__ == "__main__": - result = main() - if result != None: - print(result) + main() diff --git a/src/repo_gpt/code_manager/abstract_extractor.py b/src/repo_gpt/code_manager/abstract_extractor.py new file mode 100644 index 0000000..b772092 --- /dev/null +++ b/src/repo_gpt/code_manager/abstract_extractor.py @@ -0,0 +1,59 @@ +import os +from abc import ABC +from enum import Enum +from typing import Set, Type + +from pathspec import PathSpec +from pathspec.patterns import GitWildMatchPattern +from pygments.lexers import get_lexer_for_filename +from pygments.util import ClassNotFound + +from repo_gpt.file_handler.abstract_handler import FileHandler +from repo_gpt.file_handler.generic_code_file_handler import ( + PHPFileHandler, + PythonFileHandler, + TypeScriptFileHandler, +) +from repo_gpt.file_handler.generic_sql_file_handler import GenericSQLFileHandler + + +class LanguageHandler(Enum): + PYTHON = PythonFileHandler + SQL = GenericSQLFileHandler + PHP = PHPFileHandler + TYPESCRIPT = TypeScriptFileHandler + + +class AbstractCodeExtractor(ABC): + HANDLER_MAPPING = { + ".py": PythonFileHandler, + ".sql": GenericSQLFileHandler, + ".php": PHPFileHandler, + ".ts": TypeScriptFileHandler, + } + + @staticmethod + def get_file_extensions_with_handlers() -> Set[str]: + return AbstractCodeExtractor.HANDLER_MAPPING.keys() + + @staticmethod + def detect_language(file_path): + """Detect the coding language based on the file's extension using Pygments.""" + try: + lexer = get_lexer_for_filename(file_path) + return lexer.name + except ClassNotFound: + # This exception is raised if Pygments can't find a lexer based on the file's extension. + return ( + f"Unknown language for file extension: {os.path.splitext(file_path)[1]}" + ) + + @staticmethod + def get_handler(filepath: str) -> Type[FileHandler]: + _, file_extension = os.path.splitext(filepath) + handler_class = AbstractCodeExtractor.HANDLER_MAPPING.get(file_extension) + if handler_class is None: + print( + f"No handler for files with extension {file_extension}. Skipping file {filepath}" + ) + return handler_class diff --git a/src/repo_gpt/code_manager/code_dir_extractor.py b/src/repo_gpt/code_manager/code_dir_extractor.py new file mode 100644 index 0000000..905293b --- /dev/null +++ b/src/repo_gpt/code_manager/code_dir_extractor.py @@ -0,0 +1,156 @@ +import hashlib +import logging +import os +from pathlib import Path +from typing import Dict, List, Set + +import pandas as pd +from pathspec import PathSpec +from pathspec.patterns import GitWildMatchPattern +from tqdm import tqdm + +from ..console import verbose_print +from ..file_handler.abstract_handler import ParsedCode +from .abstract_extractor import AbstractCodeExtractor + +logger = logging.getLogger(__name__) + + +class CodeDirectoryExtractor(AbstractCodeExtractor): + def __init__( + self, + root_directory_path: Path, + output_filepath: Path, + code_df: pd.DataFrame | None = None, + ): + self.root_directory_path = root_directory_path + self.output_filepath = output_filepath + self.all_code_files = self._find_all_code_files() + self.code_df = code_df + + def generate_md5_checksum(self, file_path: str, chunk_size: int = 4096) -> str: + file_hash = hashlib.md5() + with open(file_path, "rb") as file: + chunk = file.read(chunk_size) + while chunk: + file_hash.update(chunk) + chunk = file.read(chunk_size) + return file_hash.hexdigest() + + def _find_all_code_files(self) -> List[str]: + all_code_files = [] + for current_root, directories, files in tqdm( + os.walk(self.root_directory_path), desc="Scanning directories" + ): + relative_path = Path(current_root).relative_to(self.root_directory_path) + + # Ignore directories listed in .gitignore + directories[:] = [ + dir + for dir in directories + if self.is_dir_parsable(os.path.join(relative_path, dir)) + ] + + for file in files: + full_file_path = relative_path / file + all_code_files.append(self.root_directory_path / full_file_path) + return all_code_files + + def _map_checksum_to_filepath(self) -> Dict[str, str]: # checksum : filepath + return ( + self.code_df.drop_duplicates(subset=["file_checksum"])[ + ["filepath", "file_checksum"] + ] + .set_index("file_checksum") + .to_dict()["filepath"] + ) + + def _map_filepath_to_checksum(self) -> Dict[str, str]: # filepath : checksum + if self.code_df is None or self.code_df.empty: + return {} + return ( + self.code_df.drop_duplicates(subset=["file_checksum"])[ + ["filepath", "file_checksum"] + ] + .set_index("filepath") + .to_dict()["file_checksum"] + ) + + def is_dir_parsable(self, dirpath: str) -> bool: + # Check if the directory is hidden + dirname = Path(dirpath).name + if dirname.startswith("."): + return False + + gitignore = self.get_gitignore() + spec = PathSpec.from_lines(GitWildMatchPattern, gitignore) + + if spec.match_file(dirpath): + return False + + return True + + def get_gitignore(self) -> List[str]: + gitignore_path = self.root_directory_path / ".gitignore" + if gitignore_path.is_file(): + with open(gitignore_path, "r") as file: + return file.read().splitlines() + else: + return [] + + def extract_code_blocks_from_files(self) -> (List[ParsedCode], Set[str]): + code_file_paths = self.all_code_files + filepath_to_checksum = self._map_filepath_to_checksum() + + parsable_extensions = AbstractCodeExtractor.get_file_extensions_with_handlers() + + extracted_blocks = [] + outdated_checksums = set() + for code_file_path in code_file_paths: + # print(f"🟢 Processing {code_file_path}") + current_file_checksum = self.generate_md5_checksum(code_file_path) + existing_filepath_checksum = filepath_to_checksum.get(code_file_path, None) + if existing_filepath_checksum == current_file_checksum: + logger.verbose_info(f"🟡 Skipping -- file unmodified {code_file_path}") + continue + + if code_file_path.suffix not in parsable_extensions: + logger.verbose_info( + f"🟡 Skipping -- no file parser for {code_file_path}" + ) + continue + + try: + if existing_filepath_checksum: + outdated_checksums.add(existing_filepath_checksum) + extracted_file_blocks = self._extract_code_blocks_from_single_file( + code_file_path, current_file_checksum + ) + except Exception as e: + logger.verbose_info( + f"🔴 Skipping -- error extracting code {code_file_path}: {str(e)}" + ) + continue + if not extracted_file_blocks: + logger.verbose_info( + f"🟡 Skipping -- no functions or classes found {code_file_path}" + ) + else: + logger.verbose_info( + f"🟢 Extracted {len(extracted_file_blocks)} functions from {code_file_path}" + ) + extracted_blocks.extend(extracted_file_blocks) + return extracted_blocks, outdated_checksums + + def _extract_code_blocks_from_single_file( + self, file_path: str, file_checksum: str + ) -> List[ParsedCode]: + handler_for_file = AbstractCodeExtractor.get_handler(file_path) + extracted_blocks_for_file = [] + if handler_for_file: + extracted_blocks_for_file = handler_for_file().extract_code(file_path) + for block in extracted_blocks_for_file: + block.filepath = file_path + block.file_checksum = file_checksum + + return extracted_blocks_for_file diff --git a/src/repo_gpt/code_manager/code_extractor.py b/src/repo_gpt/code_manager/code_extractor.py deleted file mode 100644 index e33ee5e..0000000 --- a/src/repo_gpt/code_manager/code_extractor.py +++ /dev/null @@ -1,148 +0,0 @@ -import hashlib -import os -from enum import Enum -from pathlib import Path -from typing import List, Type - -from pathspec import PathSpec -from pathspec.patterns import GitWildMatchPattern -from pygments.lexers import ClassNotFound, get_lexer_for_filename -from tqdm import tqdm - -from ..file_handler.abstract_handler import FileHandler, ParsedCode -from ..file_handler.generic_code_file_handler import PHPFileHandler, PythonFileHandler -from ..file_handler.sql_file_handler import SqlFileHandler -from ..utils import logger - - -class LanguageHandler(Enum): - PYTHON = PythonFileHandler - SQL = SqlFileHandler - PHP = PHPFileHandler - - -class CodeExtractor: - HANDLER_MAPPING = { - ".py": PythonFileHandler, - ".sql": SqlFileHandler, - ".php": PHPFileHandler, - } - - def __init__(self, code_root_path: Path, output_path: Path): - self.code_root_path = code_root_path - self.output_path = output_path - - def _detect_language(self, file_path): - """Detect the coding language based on the file's extension using Pygments.""" - try: - lexer = get_lexer_for_filename(file_path) - return lexer.name - except ClassNotFound: - # This exception is raised if Pygments can't find a lexer based on the file's extension. - return ( - f"Unknown language for file extension: {os.path.splitext(file_path)[1]}" - ) - - def get_handler(self, filepath: str) -> Type[FileHandler]: - _, file_extension = os.path.splitext(filepath) - handler_class = self.HANDLER_MAPPING.get(file_extension) - if handler_class is None: - print( - f"No handler for files with extension {file_extension}. Skipping file {filepath}" - ) - return handler_class - - def is_file_parsable(self, filepath: str) -> bool: - gitignore = self.get_gitignore() - spec = PathSpec.from_lines(GitWildMatchPattern, gitignore) - handler_class = self.get_handler(filepath) - if handler_class is None or spec.match_file(filepath): - return False - return True - - def is_dir_parsable(self, dirpath: str) -> bool: - gitignore = self.get_gitignore() - spec = PathSpec.from_lines(GitWildMatchPattern, gitignore) - if spec.match_file(dirpath): - return False - return True - - def generate_md5(self, filepath: str, chunk_size: int = 4096) -> str: - hash = hashlib.md5() - with open(filepath, "rb") as f: - chunk = f.read(chunk_size) - while chunk: - hash.update(chunk) - chunk = f.read(chunk_size) - return hash.hexdigest() - - def extract_code_files(self) -> List[str]: - code_files = [] - for root, dirs, files in tqdm( - os.walk(self.code_root_path), desc="Scanning directories" - ): - root_path = Path(root).relative_to(self.code_root_path) - - # Skip directories listed in .gitignore - dirs[:] = [ - d for d in dirs if self.is_dir_parsable(os.path.join(root_path, d)) - ] - - for file in files: - file_path = root_path / file - code_files.append(self.code_root_path / file_path) - return code_files - - def get_gitignore(self) -> List[str]: - gitignore_path = self.code_root_path / ".gitignore" - if gitignore_path.is_file(): - with open(gitignore_path, "r") as file: - return file.read().splitlines() - else: - return [] - - def extract_functions( - self, embedding_code_file_checksums: dict - ) -> List[ParsedCode]: - code_files = ( - self.extract_code_files() - if embedding_code_file_checksums is None - else embedding_code_file_checksums.values() - ) - code_blocks = [] - for code_filepath in code_files: - print(f"🟢 Processing {code_filepath}") - file_checksum = self.generate_md5(code_filepath) - if ( - embedding_code_file_checksums is not None - and file_checksum in embedding_code_file_checksums - ): - print(f"🟡 Skipping -- file unmodified {code_filepath}") - continue - file_code_blocks = self.extract_functions_from_file( - code_filepath, file_checksum - ) - if len(file_code_blocks) == 0: - print(f"🟡 Skipping -- no functions or classes found {code_filepath}") - else: - print( - f"🟢 Extracted {len(file_code_blocks)} functions from {code_filepath}" - ) - code_blocks.extend(file_code_blocks) - return code_blocks - - def extract_functions_from_file( - self, filepath: str, file_checksum: str - ) -> List[ParsedCode]: - handler = self.get_handler(filepath) - code_blocks = [] - if handler: - try: - code_blocks = handler().extract_code(filepath) - for code in code_blocks: - code.filepath = filepath - code.file_checksum = file_checksum - except Exception as e: - logger.error(f"Error extracting code from {filepath}: {e}") - - return code_blocks diff --git a/src/repo_gpt/code_manager/code_manager.py b/src/repo_gpt/code_manager/code_manager.py index 576c076..a3e3b70 100644 --- a/src/repo_gpt/code_manager/code_manager.py +++ b/src/repo_gpt/code_manager/code_manager.py @@ -1,82 +1,84 @@ +import logging import os import pickle from pathlib import Path -from typing import Dict import pandas as pd from tqdm import tqdm -from .code_extractor import CodeExtractor +from ..console import verbose_print +from ..openai_service import OpenAIService +from .code_dir_extractor import CodeDirectoryExtractor from .code_processor import CodeProcessor -tqdm.pandas() +logger = logging.getLogger(__name__) class CodeManager: - def __init__(self, output_path: Path, code_root: Path = None): - self.code_root = code_root - self.output_path = output_path - self.extractor = CodeExtractor(self.code_root, self.output_path) - self.processor = CodeProcessor(self.code_root) - - self.current_df = self.load_data() - - def list_file_structure(self): - output = [] - for current_path, dirs, files in os.walk(self.code_root): - level = current_path.replace(self.code_root, "").count(os.sep) - indent = " " * (level) - output.append(f"{indent}/{os.path.basename(current_path)}") - subindent = " " * (level + 1) - for f in sorted(files): - output.append(f"{subindent}{f}") - - return "\n".join(output) - - def load_data(self): - df = None - if os.path.exists(self.output_path): - with open(self.output_path, "rb") as f: - data = pickle.load(f) - df = pd.DataFrame(data) - return df + def __init__( + self, + output_filepath: Path, + root_directory: Path = None, + openai_service: OpenAIService = None, + ): + self.root_directory = root_directory + self.output_filepath = output_filepath + self.openai_service = ( + openai_service if openai_service is not None else OpenAIService() + ) + self.code_processor = CodeProcessor(self.root_directory, openai_service) - def setup(self): - # create a dictionary of filepaths and their corresponding checksums - embedding_code_file_checksums = ( - self.get_checksum_filepath_dict(self.current_df) - if self.current_df is not None - else None + self.code_df = self.load_code_dataframe() + self.directory_extractor = CodeDirectoryExtractor( + self.root_directory, self.output_filepath, self.code_df ) - self.parse_code_and_save_embeddings(embedding_code_file_checksums) - print("All done! ✨ 🦄 ✨") + def display_directory_structure(self): + structured_output = [] + for current_path, directories, files in os.walk(self.root_directory): + depth = current_path.replace(self.root_directory, "").count(os.sep) + indent = " " * (depth) + structured_output.append(f"{indent}/{os.path.basename(current_path)}") + sub_indent = " " * (depth + 1) + for file in sorted(files): + structured_output.append(f"{sub_indent}{file}") + + return "\n".join(structured_output) + + def load_code_dataframe(self): + dataframe = None + if os.path.exists(self.output_filepath): + with open(self.output_filepath, "rb") as file: + loaded_data = pickle.load(file) + dataframe = pd.DataFrame(loaded_data) + return dataframe - def get_checksum_filepath_dict(self, df): - return ( - df.drop_duplicates(subset=["file_checksum"])[["filepath", "file_checksum"]] - .set_index("file_checksum") - .to_dict()["filepath"] - ) + def setup(self): + self._extract_process_and_save_code() - def _update_or_create_post(self, df): - df = df._append(self.current_df, ignore_index=True) - path = Path(self.output_path) - directory = path.parent + logger.verbose_info("All done! ✨ 🦄 ✨") - if not directory.exists(): - directory.mkdir(parents=True) - print(f"Directory created: {directory}") + def _store_code_dataframe(self, dataframe): + output_directory = Path(self.output_filepath).parent + + if not output_directory.exists(): + output_directory.mkdir(parents=True) + print(f"Directory created: {output_directory}") # Save DataFrame as a pickle file - with open(self.output_path, "wb") as f: - pickle.dump(df, f) + with open(self.output_filepath, "wb") as file: + pickle.dump(dataframe, file) + + def _extract_process_and_save_code(self): + ( + extracted_code_blocks, + outdated_checksums, + ) = self.directory_extractor.extract_code_blocks_from_files() + processed_dataframe = self.code_processor.process(extracted_code_blocks) + + updated_df = pd.concat([self.code_df, processed_dataframe], ignore_index=True) - def parse_code_and_save_embeddings( - self, embedding_code_file_checksums: Dict[str, str] - ): # file_checksum : filepath - code_blocks = self.extractor.extract_functions(embedding_code_file_checksums) - df = self.processor.process(code_blocks) + # Remove checksums of updated code + updated_df = updated_df[~updated_df["file_checksum"].isin(outdated_checksums)] - if df is not None: - self._update_or_create_post(df) + self._store_code_dataframe(updated_df) diff --git a/src/repo_gpt/code_manager/code_processor.py b/src/repo_gpt/code_manager/code_processor.py index 51d6e3c..ffb14d8 100644 --- a/src/repo_gpt/code_manager/code_processor.py +++ b/src/repo_gpt/code_manager/code_processor.py @@ -1,29 +1,71 @@ +import logging +from itertools import islice from typing import List +import numpy as np import pandas as pd +import tiktoken from tqdm import tqdm +from ..console import verbose_print from ..file_handler.abstract_handler import ParsedCode -from ..openai_service import OpenAIService +from ..openai_service import OpenAIService, tokens_from_string -tqdm.pandas() +logger = logging.getLogger(__name__) class CodeProcessor: - def __init__(self, code_root): + def __init__(self, code_root, openai_service: OpenAIService = None): # Todo: add code root self.code_root = code_root - self.openai_service = OpenAIService() + self.openai_service = openai_service if openai_service else OpenAIService() def process(self, code_blocks: List[ParsedCode]): if len(code_blocks) == 0: - print("No code blocks to process") + logger.verbose_info("No code blocks to process") return None df = pd.DataFrame(code_blocks) - print( + logger.verbose_info( f"Generating openai embeddings for {len(df)} code blocks. This may take a while because of rate limiting..." ) - df["code_embedding"] = df["code"].progress_apply( - self.openai_service.get_embedding - ) + + def len_safe_get_embedding(text): + max_tokens = 8191 + encoding_name = "cl100k_base" + + chunk_embeddings = [] + chunk_lens = [] + for chunk in CodeProcessor._chunked_tokens( + text, encoding_name=encoding_name, chunk_length=max_tokens + ): + chunk_embeddings.append(self.openai_service.get_embedding(chunk)) + chunk_lens.append(len(chunk)) + + chunk_embedding = np.average(chunk_embeddings, axis=0, weights=chunk_lens) + return chunk_embedding / np.linalg.norm( + chunk_embedding + ) # normalizes length to 1 + + if logger.getEffectiveLevel() < logging.INFO: + tqdm.pandas() + df["code_embedding"] = df["code"].progress_apply(len_safe_get_embedding) + else: + df["code_embedding"] = df["code"].apply(len_safe_get_embedding) return df + + @staticmethod + def _batched(iterable, n): + """Batch data into tuples of length n. The last batch may be shorter.""" + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + raise ValueError("n must be at least one") + it = iter(iterable) + while batch := tuple(islice(it, n)): + yield batch + + @staticmethod + def _chunked_tokens(text, encoding_name, chunk_length): + encoding = tiktoken.get_encoding(encoding_name) + tokens = encoding.encode(text) + chunks_iterator = CodeProcessor._batched(tokens, chunk_length) + yield from chunks_iterator diff --git a/src/repo_gpt/code_manager/code_vscode_file_extractor.py b/src/repo_gpt/code_manager/code_vscode_file_extractor.py new file mode 100644 index 0000000..77f01ab --- /dev/null +++ b/src/repo_gpt/code_manager/code_vscode_file_extractor.py @@ -0,0 +1,17 @@ +from pathlib import Path +from typing import List + +from ..file_handler.abstract_handler import VSCodeExtCodeLensCode +from .abstract_extractor import AbstractCodeExtractor + + +class CodeVscodeFileExtractor(AbstractCodeExtractor): + def __init__(self, file_path: str): + self.file_path = Path(file_path) + + def extract_functions_from_file(self) -> List[VSCodeExtCodeLensCode]: + handler = AbstractCodeExtractor.get_handler(self.file_path) + code_blocks = [] + if handler: + code_blocks = handler().extract_vscode_ext_codelens(self.file_path) + return code_blocks diff --git a/src/repo_gpt/codebase_analyzer/__init__.py b/src/repo_gpt/codebase_analyzer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/repo_gpt/codebase_analyzer/class_analyzer.py b/src/repo_gpt/codebase_analyzer/class_analyzer.py new file mode 100644 index 0000000..88f8ca4 --- /dev/null +++ b/src/repo_gpt/codebase_analyzer/class_analyzer.py @@ -0,0 +1,65 @@ +import os +import subprocess + +import networkx as nx +import pygraphviz as pgv + +from repo_gpt.codebase_analyzer.graph_analyzer import GraphAnalyzer + + +class ClassAnalyzer(GraphAnalyzer): + def __init__( + self, directory_path: str, output_file_path: str = "class_diagram.dot" + ): + super().__init__(directory_path, output_file_path) + + def _generate_and_load_graph(self, output_file_path): + # Ensure pylint is installed + if not self._is_tool_installed("pyreverse"): + raise EnvironmentError( + "pyreverse (from pylint) must be installed to use this class." + ) + + # Generate dot file + try: + subprocess.run( + ["pyreverse", "-o", "dot", "-p", "ProjectName", self.directory_path], + check=True, + ) + + # Rename the generated dot file to the desired name + os.rename("classes_ProjectName.dot", output_file_path) + print(f"Dot file generated: {output_file_path}") + except subprocess.CalledProcessError: + raise RuntimeError("Error occurred while running pyreverse.") + + # Load the graph from the dot file + try: + with open(output_file_path, "r") as file: + file_content = file.read() + + agraph = pgv.AGraph(string=file_content) + self.graph = nx.DiGraph(agraph) + except Exception as e: + print(f"An error occurred while loading the graph: {e}") + + @staticmethod + def _is_tool_installed(tool: str) -> bool: + """Check if a tool is installed and accessible from the command line.""" + try: + subprocess.run( + [tool, "--version"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=True, + ) + return True + except subprocess.CalledProcessError: + return False + except FileNotFoundError: + return False + + +# Example Usage: +# analyzer = ClassGraphAnalyzer("/path/to/your/project") +# graph = analyzer.graph diff --git a/src/repo_gpt/codebase_analyzer/dependency_analyzer.py b/src/repo_gpt/codebase_analyzer/dependency_analyzer.py new file mode 100644 index 0000000..97835d9 --- /dev/null +++ b/src/repo_gpt/codebase_analyzer/dependency_analyzer.py @@ -0,0 +1,50 @@ +import os +import subprocess + +import networkx as nx +import pygraphviz as pgv + +from repo_gpt.codebase_analyzer.graph_analyzer import GraphAnalyzer + + +class DependencyAnalyzer(GraphAnalyzer): + def __init__(self, directory_path: str, output_file_path: str = "pydeps_graph.dot"): + super().__init__(directory_path, output_file_path) + + def _generate_and_load_graph(self, output_file_path): + # Generate dot file using pydeps + cmd = [ + "pydeps", + "--noshow", + "--max-bacon=1", + "-T", + "dot", + "-o", + output_file_path, + self.directory_path, + ] + + result = subprocess.run(cmd, capture_output=True, text=True) + + if result.returncode != 0: + print("Error occurred while running pydeps:") + print(result.stderr) + else: + print("Command executed successfully!") + print(result.stdout) + + # Load the graph from the dot file + try: + with open(output_file_path, "r") as file: + file_content = file.read() + + agraph = pgv.AGraph(string=file_content) + self.graph = nx.DiGraph(agraph) + print(f"Dependency DOT file saved to {os.path.abspath(output_file_path)}") + except Exception as e: + print(f"An error occurred while loading the graph: {e}") + + +# Example Usage: +# analyzer = DependencyAnalyzer("/path/to/your/source") +# graph = analyzer.graph diff --git a/src/repo_gpt/codebase_analyzer/function_call_analyzer.py b/src/repo_gpt/codebase_analyzer/function_call_analyzer.py new file mode 100644 index 0000000..ec641bf --- /dev/null +++ b/src/repo_gpt/codebase_analyzer/function_call_analyzer.py @@ -0,0 +1,92 @@ +import os + +import code2flow +import networkx as nx +import pygraphviz as pgv + +from repo_gpt.codebase_analyzer.graph_analyzer import GraphAnalyzer + + +class FunctionCallAnalyzer(GraphAnalyzer): + def __init__(self, directory_path, output_file_path="function_call_graph.dot"): + super().__init__(directory_path, output_file_path) + + def _generate_and_load_graph(self, output_file_path): + # Generate the code graph using pydeps + python_files = [] + + # Walk through directory and its subdirectories + for dirpath, dirnames, filenames in os.walk(self.directory_path): + for file in filenames: + if file.endswith(".py"): + python_files.append(os.path.join(dirpath, file)) + + # Generate the code graph + code2flow.code2flow(python_files, output_file_path) + + # Load the graph from the dot file + try: + with open(output_file_path, "r") as file: + file_content = file.read() + + agraph = pgv.AGraph(string=file_content) + self.graph = nx.DiGraph(agraph) + + root_nodes = [ + node for node, degree in self.graph.in_degree() if degree == 0 + ] + if root_nodes: + self.graph.remove_node(root_nodes[0]) + + label_mapping = { + node: self._clean_name(self.graph.nodes[node]["label"]) + for node in self.graph.nodes() + } + self.graph = nx.relabel_nodes(self.graph, label_mapping) + + for node in self.graph.nodes(): + node_data = self.graph.nodes[node] + for attribute in ["shape", "style", "fillcolor"]: + node_data.pop(attribute, None) + self._extract_attributes_from_name(node_data) + + except FileNotFoundError: + raise ValueError(f"File '{output_file_path}' not found.") + except Exception as e: + raise ValueError(f"Error loading graph from '{output_file_path}': {str(e)}") + + def _clean_name(self, name): + parts = name.split(":") + if len(parts) > 1: + final_parts = parts[1].split("()") + return final_parts[0].strip() if len(final_parts) > 1 else parts[1].strip() + return name.strip() + + def _extract_attributes_from_name(self, node_data): + name_parts = node_data["name"].split("::") + file_name = name_parts[0] + if len(name_parts) > 1: + class_and_function = name_parts[1].rsplit(".", 1) + class_name = class_and_function[0] if len(class_and_function) > 1 else None + function_name = class_and_function[-1] + else: + class_name = None + function_name = file_name + file_name = None + node_data["file_name"] = file_name + if class_name: + node_data["class_name"] = class_name + node_data["function_name"] = function_name + + # Not really used + def generate_class_graph(self): + return self._generate_graph_by_attribute("class_name") + + # Not really used + def generate_file_graph(self): + return self._generate_graph_by_attribute("file_name") + + +# Example Usage: +# analyzer = FunctionCallGraphAnalyzer("/path/to/your/directory") +# graph = analyzer.graph diff --git a/src/repo_gpt/codebase_analyzer/graph_analyzer.py b/src/repo_gpt/codebase_analyzer/graph_analyzer.py new file mode 100644 index 0000000..68f33c0 --- /dev/null +++ b/src/repo_gpt/codebase_analyzer/graph_analyzer.py @@ -0,0 +1,175 @@ +from abc import ABC, abstractmethod + +import Levenshtein +import networkx as nx + + +class GraphAnalyzer(ABC): + def __init__(self, directory_path, output_file_path): + self.directory_path = directory_path + self.graph = None + self._generate_and_load_graph(output_file_path) + + # Abstract methods + @abstractmethod + def _generate_and_load_graph(self, output_filename): + pass + + # Private helper methods + def _check_node_exists(self, node_name): + if node_name not in self.graph: + raise ValueError(f"Node with name '{node_name}' not found in the graph.") + + def _generate_hierarchical_structure(self, node, graph, visited=None): + if visited is None: + visited = set() + if node in visited: + return {node: "CYCLE"} + visited.add(node) + structure = {} + for successor in graph.successors(node): + structure[successor] = self._generate_hierarchical_structure( + successor, graph, visited.copy() + ) + return structure + + # Graph manipulation methods + def set_graph(self, graph): + self.graph = graph + + # Node relationship methods + def get_children(self, node_name): + self._check_node_exists(node_name) + return list(self.graph.successors(node_name)) + + def get_parents(self, node_name): + self._check_node_exists(node_name) + return list(self.graph.predecessors(node_name)) + + def get_children_by_depth(self, node_name, depth): + if depth < 1: + return [] + children = self.get_children(node_name) + for child in list(children): + children.extend(self.get_children_by_depth(child, depth - 1)) + return list(set(children)) + + def get_parents_by_depth(self, node_name, depth): + if depth < 1: + return [] + parents = self.get_parents(node_name) + for parent in list(parents): + parents.extend(self.get_parents_by_depth(parent, depth - 1)) + return list(set(parents)) + + # Node search and representation methods + def search_by_node_name(self, node_name): + if node_name in self.graph: + return {"name": node_name, "attributes": self.graph.nodes[node_name]} + return None + + def fuzzy_search_by_node_name(self, search_term): + """ + Fuzzy search for nodes by name or attributes using Levenshtein distance. + + Parameters: + - search_term (str): The term to search for. + + Returns: + - List of tuples where each tuple contains a node name and its distance to the search term. + Returns the top 3 nodes with the smallest distances. + """ + distances = [] + + for node, attributes in self.graph.nodes(data=True): + # Check distance with node name + node_distance = Levenshtein.distance(node, search_term) + distances.append((node, node_distance)) + + # Check distance with node attributes + for attribute, value in attributes.items(): + if isinstance(value, str): + attr_distance = Levenshtein.distance(value, search_term) + distances.append((node, attr_distance)) + + # Sort by distance and pick the top 3 nodes + distances.sort(key=lambda x: x[1]) + return distances[:3] + + def represent_node_hierarchy( + self, node, child_levels=None, parent_levels=None, visited=None + ): + if visited is None: + visited = set() + if node in visited: + return {node: "CYCLE"} + visited.add(node) + + structure = {} + + if parent_levels is not None: + structure["parents"] = self._get_parents_structure( + node, parent_levels, visited.copy() + ) + + if child_levels is not None: + structure["children"] = self._get_children_structure( + node, child_levels, visited.copy() + ) + + # Filter out empty keys for clarity + return {node: {k: v for k, v in structure.items() if v}} + + def _get_parents_structure(self, node, levels, visited): + if levels == 0: + return {} + + parents_structure = {} + for parent in self.graph.predecessors(node): + parents_structure[parent] = self.represent_node_hierarchy( + parent, + child_levels=None, + parent_levels=(levels - 1), + visited=visited.copy(), + ) + + return parents_structure + + def _get_children_structure(self, node, levels, visited): + if levels == 0: + return {} + + children_structure = {} + for child in self.graph.successors(node): + children_structure[child] = self.represent_node_hierarchy( + child, + child_levels=(levels - 1), + parent_levels=None, + visited=visited.copy(), + ) + + return children_structure + + def generate_text_representation(self, graph): + hierarchical_representations = {} + for node in graph.nodes(): + if not list(graph.predecessors(node)): + hierarchical_representations[ + node + ] = self._generate_hierarchical_structure(node, graph) + return hierarchical_representations + + # Graph generation methods + def _generate_graph_by_attribute(self, attribute): + new_graph = nx.DiGraph() + for node, attributes in self.graph.nodes(data=True): + current_attr = attributes.get(attribute) + if not current_attr: + continue + if current_attr not in new_graph: + new_graph.add_node(current_attr) + for child in self.graph.successors(node): + child_attr = self.graph.nodes[child].get(attribute) + if child_attr and child_attr != current_attr: + new_graph.add_edge(current_attr, child_attr) + return new_graph diff --git a/src/repo_gpt/console.py b/src/repo_gpt/console.py index 7eb37ea..a0e6d1c 100644 --- a/src/repo_gpt/console.py +++ b/src/repo_gpt/console.py @@ -1,8 +1,24 @@ from rich.console import Console from rich.syntax import Syntax +from tqdm import tqdm as _tqdm console = Console() +VERBOSE = False + + +def verbose_print(*args, **kwargs): + if VERBOSE: + print(*args, **kwargs) + + +def tqdm(*args, **kwargs): + if VERBOSE: + _tqdm.pandas() + return _tqdm(*args, **kwargs) + else: + return _tqdm(*args, **kwargs, disable=True) + def print_ai_assistant_chat_message(response: str): """Print the response from the OpenAI API. diff --git a/src/repo_gpt/file_handler/abstract_handler.py b/src/repo_gpt/file_handler/abstract_handler.py index 5e84b38..f649d2c 100644 --- a/src/repo_gpt/file_handler/abstract_handler.py +++ b/src/repo_gpt/file_handler/abstract_handler.py @@ -1,26 +1,33 @@ from abc import ABC, abstractmethod from dataclasses import dataclass from enum import Enum +from pathlib import Path from typing import List, Tuple, TypeVar, Union FileHandler = TypeVar("FileHandler", bound="AbstractHandler") -class CodeType(Enum): +class CodeType(str, Enum): FUNCTION = "function" CLASS = "class" METHOD = "method" GLOBAL = "global" + SELECT = "select" + INSERT = "insert" + UPDATE = "update" + DELETE = "delete" + @dataclass class ParsedCode: - name: Union[str, None] + function_name: Union[str, None] + class_name: Union[str, None] code_type: CodeType code: str summary: Union[str, None] inputs: Union[Tuple[str, ...], None] - outputs: Union[Tuple[str, ...], str] + outputs: Union[Tuple[str, ...], str, None] filepath: str = None file_checksum: str = None @@ -28,11 +35,27 @@ def __lt__(self, other: "ParsedCode"): return self.code < other.code +@dataclass(frozen=True) +class VSCodeExtCodeLensCode: + name: str + start_line: int + end_line: int + + def __lt__(self, other: "VSCodeExtCodeLensCode"): + return self.start_line < other.start_line + + class AbstractHandler(ABC): @abstractmethod - def extract_code(self, filepath) -> List[ParsedCode]: + def extract_code(self, filepath: Path) -> List[ParsedCode]: pass @abstractmethod def is_valid_code(self, code: str) -> bool: pass + + @abstractmethod + def extract_vscode_ext_codelens( + self, filepath: Path + ) -> List[VSCodeExtCodeLensCode]: + pass diff --git a/src/repo_gpt/file_handler/generic_code_file_handler.py b/src/repo_gpt/file_handler/generic_code_file_handler.py index 31bc4fc..10fee5c 100644 --- a/src/repo_gpt/file_handler/generic_code_file_handler.py +++ b/src/repo_gpt/file_handler/generic_code_file_handler.py @@ -1,10 +1,15 @@ from collections import deque from pathlib import Path -from typing import List, Tuple +from typing import Any, List, Optional, Tuple from tree_sitter_languages import get_language, get_parser -from .abstract_handler import AbstractHandler, CodeType, ParsedCode +from .abstract_handler import ( + AbstractHandler, + CodeType, + ParsedCode, + VSCodeExtCodeLensCode, +) class GenericCodeFileHandler(AbstractHandler): @@ -22,6 +27,10 @@ def __init__( method_name_node_type: str, function_output_node_type: str = "output", function_parameters_node_type: str = "parameters", + root_node_type: str = "source_file", + function_query: Optional[str] = None, + class_query: Optional[str] = None, + method_query: Optional[str] = None, ): self.function_name_node_type = function_name_node_type self.class_name_node_type = class_name_node_type @@ -34,11 +43,197 @@ def __init__( self.function_parameters_node_type = function_parameters_node_type self.parent_class_name_node_type = parent_class_name_node_type self.method_name_node_type = method_name_node_type + self.root_node_type = root_node_type self.language = get_language(lang) self.parser = get_parser(lang) self.parser.set_language(self.language) + self.function_query = ( + function_query + if function_query + else f""" + ({self.function_node_type}) @function + """ + ) + self.class_query = ( + class_query + if class_query + else f""" + ({class_node_type}) @class + """ + ) + self.method_query = ( + method_query + if method_query + else f""" + ({self.method_node_type}) @method + """ + ) + + def summarize_file(self, filepath: Path) -> str: + # Use the `extract_code` method to parse the given file and get all code structures. + parsed_codes = self.extract_code(filepath) + + summaries = [] + + for parsed_code in parsed_codes: + if parsed_code.code_type == CodeType.CLASS: + class_summary = f"Class: {parsed_code.class_name}" + if parsed_code.inputs: + class_summary += ( + f"\n\tParent Classes: {', '.join(parsed_code.inputs)}" + ) + summaries.append(class_summary) + + # Including the methods and their IO signatures within the class + for line in parsed_code.summary.split("\n"): + if line.strip().startswith("method:"): + summaries.append("\t" + line.strip()) + + elif parsed_code.code_type == CodeType.FUNCTION: + function_summary = f"Function: {parsed_code.function_name}" + if parsed_code.inputs: + function_summary += ( + f"\n\tInput Parameters: {', '.join(parsed_code.inputs)}" + ) + if parsed_code.outputs: + function_summary += ( + f"\n\tOutput Parameters: {', '.join(parsed_code.outputs)}" + ) + summaries.append(function_summary) + + elif parsed_code.code_type == CodeType.METHOD: + # This section might not be necessary as methods are captured under the class summary. + method_summary = f"Method (within class): {parsed_code.function_name}" + if parsed_code.inputs: + method_summary += ( + f"\n\tInput Parameters: {', '.join(parsed_code.inputs)}" + ) + if parsed_code.outputs: + method_summary += ( + f"\n\tOutput Parameters: {', '.join(parsed_code.outputs)}" + ) + summaries.append(method_summary) + + return "\n".join(summaries) + + """ VSCode Extension CodeLens """ + + def extract_vscode_ext_codelens( + self, filepath: Path + ) -> List[VSCodeExtCodeLensCode]: + with open(filepath, "r", encoding="utf-8") as source_code: + code = source_code.read() + tree = self.parser.parse(bytes(code, "utf8")) + return self.parse_vscode_ext_codelens(tree) + + def _query(self, query: str, root_node) -> List[Tuple[str, int, int]]: + query = self.language.query(query) + return query.captures(root_node) + + def parse_vscode_ext_codelens(self, tree) -> List[VSCodeExtCodeLensCode]: + return self.parse_code( + tree, + self.get_vscode_class_code, + self.get_vscode_function_code, + self.get_vscode_function_code, + ) + + def parse_code( + self, + tree, + class_parsing_func, + function_parsing_func, + method_parsing_func, + global_parsing_func=None, + ) -> List[Any]: + parsed_nodes = [] + root_node = tree.root_node + + # Get all classes + class_matches = self._get_all_classes(root_node) + for match in class_matches: + parsed_nodes.append(class_parsing_func(match[0])) + + # Get all functions + function_matches = self._get_all_functions(root_node) + for match in function_matches: + parsed_nodes.append(function_parsing_func(match[0])) + + # Get all methods + method_matches = [] + if self.method_node_type != self.function_node_type: + method_matches = self._get_all_methods(root_node) + for match in method_matches: + parsed_nodes.append(method_parsing_func(match[0])) + + if global_parsing_func != None: + parsed_node = self._get_all_global_code( + root_node, class_matches + function_matches + method_matches + ) + if parsed_node != None: + parsed_nodes.append(parsed_node) + + return parsed_nodes + + def _get_all_classes(self, node): + return self._query(self.class_query, node) + + def _get_all_functions(self, node): + return self._query(self.function_query, node) + + def _get_all_methods(self, node): + return self._query(self.method_query, node) + + def _get_all_global_code(self, node, nodes_to_remove=None): + source_code = node.text.decode("utf8") + # Convert source code to a list of lines + lines = source_code.split("\n") + + # Mark lines that belong to functions for removal + for node, _ in nodes_to_remove: + for line_num in range(node.start_point[0] - 1, node.end_point[0]): + lines[line_num] = None + + # Remove the marked lines + remaining_lines = [ + line for line in lines if line is not None and line.strip() != "" + ] + if len(remaining_lines) == 0: + return None + modified_source_code = "\n".join(line for line in lines if line is not None) + + return ParsedCode( + function_name=None, + class_name=None, + code_type=CodeType.GLOBAL, + code=modified_source_code, + summary=None, + inputs=None, + outputs=None, + ) + + def get_vscode_function_code(self, function_node) -> VSCodeExtCodeLensCode: + name = self.get_function_name(function_node) + return VSCodeExtCodeLensCode( + name=name, + start_line=function_node.start_point[0], + end_line=function_node.end_point[0], + # code=function_node.text.decode("utf8"), + ) + + def get_vscode_class_code(self, class_node) -> List[VSCodeExtCodeLensCode]: + class_name = self.get_class_name(class_node) + return VSCodeExtCodeLensCode( + name=class_name, + start_line=class_node.start_point[0], + # code=class_node.text.decode("utf8"), + end_line=class_node.end_point[0], + ) + + """ General Repo GPT """ + def get_function_name(self, function_node): for node in function_node.named_children: if ( @@ -59,36 +254,23 @@ def extract_code(self, filepath: Path) -> List[ParsedCode]: return self.parse_tree(tree) def parse_tree(self, tree) -> List[ParsedCode]: - parsed_nodes = [] - root_node = tree.root_node - global_nodes = [] - for node in root_node.children: - if node.type == self.function_node_type: - parsed_nodes.append(self.get_function_parsed_code(node)) - elif node.type == self.class_node_type: - parsed_nodes.extend(self.get_class_and_method_parsed_code(node)) - else: - global_nodes.append(node) - if len(global_nodes) > 0: - parsed_nodes.append(self.get_global_code(global_nodes)) - return parsed_nodes - - def get_global_code(self, global_nodes: []) -> ParsedCode: - code = "\n".join([node.text.decode("utf8") for node in global_nodes]) - return ParsedCode( - name=None, - code_type=CodeType.GLOBAL, - code=code, - summary=None, - inputs=None, - outputs=None, + parsed_codes = self.parse_code( + tree, + self.get_class_parsed_code, + self.get_function_parsed_code, + self.get_function_parsed_code, + self._get_all_global_code, ) + return parsed_codes - def get_function_parsed_code(self, function_node, is_method=False) -> ParsedCode: + def get_function_parsed_code( + self, function_node, class_name=None, is_method=False + ) -> ParsedCode: name = self.get_function_name(function_node) input_params, output_params = self.get_function_parameters(function_node) return ParsedCode( - name=name, + function_name=name, + class_name=class_name, code_type=CodeType.METHOD if is_method else CodeType.FUNCTION, code=function_node.text.decode("utf8"), summary=None, @@ -96,38 +278,34 @@ def get_function_parsed_code(self, function_node, is_method=False) -> ParsedCode outputs=output_params, ) - def get_class_and_method_parsed_code(self, class_node) -> List[ParsedCode]: - parsed_codes = [] + def get_class_parsed_code(self, class_node) -> ParsedCode: class_name = self.get_class_name(class_node) parent_classes = self.get_parent_classes(class_node) class_summary = [f"class: {class_name}\n parent classes: {parent_classes}\n"] for node in class_node.named_children: if node.type == self.class_internal_node_type: + # TODO get method nodes by query instea for n in node.named_children: if n.type == self.method_node_type: # function - parsed_code = self.get_function_parsed_code(n, is_method=True) - # TODO figure out how to get docstring - parsed_codes.append(parsed_code) + parsed_code = self.get_function_parsed_code( + n, class_name=class_name, is_method=True + ) input_params, output_params = self.get_function_parameters(n) class_summary.append( - f" method: {parsed_code.name}\n input parameters: {input_params}\n output parameters: {output_params}\n code: ...\n" + f" method: {parsed_code.function_name}\n input parameters: {input_params}\n output parameters: {output_params}\n code: ...\n" ) - name = self.get_class_name(class_node) - parsed_codes.append( - ParsedCode( - name=name, - code_type=CodeType.CLASS, - code=class_node.text.decode("utf8"), - summary="\n".join(class_summary), - inputs=parent_classes, - outputs=None, - ) + return ParsedCode( + function_name=None, + class_name=class_name, + code_type=CodeType.CLASS, + code=class_node.text.decode("utf8"), + summary="\n".join(class_summary), + inputs=parent_classes, + outputs=None, ) - return parsed_codes - def get_parent_classes(self, class_node) -> Tuple[str, ...]: for child in class_node.children: # If we found the base_classes node @@ -230,4 +408,9 @@ def __init__(self): function_output_node_type="type_annotation", function_parameters_node_type="formal_parameters", method_name_node_type="property_identifier", + root_node_type="program", ) + + +class GenericCodeFileHandler: + pass diff --git a/src/repo_gpt/file_handler/generic_sql_file_handler.py b/src/repo_gpt/file_handler/generic_sql_file_handler.py new file mode 100644 index 0000000..de47fe2 --- /dev/null +++ b/src/repo_gpt/file_handler/generic_sql_file_handler.py @@ -0,0 +1,100 @@ +from pathlib import Path +from typing import List + +from tree_sitter_languages import get_language, get_parser + +from .abstract_handler import ( + AbstractHandler, + CodeType, + ParsedCode, + VSCodeExtCodeLensCode, +) + + +class GenericSQLFileHandler(AbstractHandler): + def __init__(self): + lang = "sql" + self.language = get_language(lang) + self.parser = get_parser(lang) + + self.select_node_type = "select_statement" + self.update_node_type = "update_statement" + self.delete_node_type = "delete_statement" + self.insert_node_type = "insert_statement" + self.function_definition_node_type = "create_function_statement" + # There isn't a node type for CTEs + + """VSCode Extension CodeLens""" + + def extract_vscode_ext_codelens( + self, filepath: Path + ) -> List[VSCodeExtCodeLensCode]: + with open(filepath, "r", encoding="utf-8") as source_code: + code = source_code.read() + tree = self.parser.parse(bytes(code, "utf8")) + return self._parse_vscode_ext_codelens(tree) + + def _parse_vscode_ext_codelens(self, tree) -> List[VSCodeExtCodeLensCode]: + parsed_nodes = [] + root_node = tree.root_node + for node in root_node.children: + code_type = self._get_node_code_type(node) + if code_type is not None: + parsed_nodes.append( + VSCodeExtCodeLensCode( + name=code_type.value, + start_line=node.start_point[0], + end_line=node.end_point[0], + ) + ) + return parsed_nodes + + def _get_node_code_type(self, node): + code_type = None + if node.type == self.select_node_type: + code_type = CodeType.SELECT + elif node.type == self.update_node_type: + code_type = CodeType.UPDATE + elif node.type == self.delete_node_type: + code_type = CodeType.DELETE + elif node.type == self.insert_node_type: + code_type = CodeType.INSERT + elif node.type == self.function_definition_node_type: + code_type = CodeType.FUNCTION + return code_type + + """Repo GPT""" + + def extract_code(self, filepath: Path) -> List[ParsedCode]: + with open(filepath, "r", encoding="utf-8") as source_code: + code = source_code.read() + tree = self.parser.parse(bytes(code, "utf8")) + return self._parse_tree(tree) + + def _parse_tree(self, tree) -> List[ParsedCode]: + parsed_nodes = [] + root_node = tree.root_node + for node in root_node.children: + code_type = self._get_node_code_type(node) + if code_type is not None: + parsed_nodes.append( + ParsedCode( + function_name=None, + class_name=None, + code_type=code_type, + code=node.text.decode("utf8"), + inputs=None, + summary=None, + outputs=None, + ) + ) + return parsed_nodes + + def is_valid_code(self, code: str) -> bool: + tree = self.parser.parse(bytes(code, "utf8")) + errors = ( + tree.root_node.children[-1].type == "ERROR" + if tree.root_node.children + else False + ) + return not errors diff --git a/src/repo_gpt/file_handler/sql_file_handler.py b/src/repo_gpt/file_handler/sql_file_handler.py deleted file mode 100644 index 6713295..0000000 --- a/src/repo_gpt/file_handler/sql_file_handler.py +++ /dev/null @@ -1,37 +0,0 @@ -from typing import List - -import sqlglot -from sqlglot.expressions import CTE, Delete, Func, Insert, Select, Update - -from .abstract_handler import ParsedCode - - -class SqlFileHandler: - def extract_code(self, filepath) -> List[ParsedCode]: - with open(filepath, "r") as file: - sql = file.read() - - parsed = sqlglot.parse(sql) - - parsed_statements = [] - for i, statement in enumerate(parsed, start=1): - if isinstance(statement, (Select, Update, Delete, Insert, CTE, Func)): - parsed_statements.append( - ParsedCode( - name=str(i), - code_type=type(statement).__name__, - code=str(statement), - summary=None, - inputs=None, # TODO: should this include ctes? - outputs=None, - ) - ) - - return parsed_statements - - def is_valid_code(self, code: str) -> bool: - try: - sqlglot.parse(code) - return True - except: - return False diff --git a/src/repo_gpt/logging_config.py b/src/repo_gpt/logging_config.py new file mode 100644 index 0000000..24b6def --- /dev/null +++ b/src/repo_gpt/logging_config.py @@ -0,0 +1,26 @@ +import logging +import warnings + +from urllib3.exceptions import InsecureRequestWarning + +# Suppress only the single warning from urllib3 +warnings.filterwarnings("ignore", category=InsecureRequestWarning) + + +import logging + +VERBOSE_INFO = 15 + +logging.addLevelName(VERBOSE_INFO, "VERBOSE_INFO") + + +def verbose_info(self, message, *args, **kws): + if self.isEnabledFor(VERBOSE_INFO): + self._log(VERBOSE_INFO, message, args, **kws) + + +logging.Logger.verbose_info = verbose_info + + +def configure_logging(log_level=None): + logging.basicConfig(format="%(message)s", level=log_level or logging.INFO) diff --git a/src/repo_gpt/openai_service.py b/src/repo_gpt/openai_service.py index b80c8dd..4680c5b 100644 --- a/src/repo_gpt/openai_service.py +++ b/src/repo_gpt/openai_service.py @@ -1,4 +1,6 @@ # Set your OpenAI API key as an environment variable +import json +import logging import os import numpy as np @@ -10,7 +12,7 @@ wait_random_exponential, ) -openai.api_key = os.environ["OPENAI_API_KEY"] +from repo_gpt.utils import Singleton MAX_RETRIES = 3 GPT_MODEL = "gpt-3.5-turbo" # "gpt-3.5-turbo-16k" @@ -19,13 +21,15 @@ 0.4 # temperature = 0 can sometimes get stuck in repetitive loops, so we use 0.4 ) +logger = logging.getLogger(__name__) + def num_tokens_from_messages(messages, model="gpt-3.5-turbo"): """Return the number of tokens used by a list of messages.""" try: encoding = tiktoken.encoding_for_model(model) except KeyError: - print("Warning: model not found. Using cl100k_base encoding.") + logger.warn("Warning: model not found. Using cl100k_base encoding.") encoding = tiktoken.get_encoding("cl100k_base") if model in { "gpt-3.5-turbo-0613", @@ -43,12 +47,12 @@ def num_tokens_from_messages(messages, model="gpt-3.5-turbo"): ) tokens_per_name = -1 # if there's a name, the role is omitted elif "gpt-3.5-turbo" in model: - print( + logger.warn( "Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613." ) return num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613") elif "gpt-4" in model: - print( + logger.warn( "Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613." ) return num_tokens_from_messages(messages, model="gpt-4-0613") @@ -60,17 +64,49 @@ def num_tokens_from_messages(messages, model="gpt-3.5-turbo"): for message in messages: num_tokens += tokens_per_message for key, value in message.items(): - num_tokens += len(encoding.encode(value)) + num_tokens += len(encoding.encode(json.dumps(value))) if key == "name": num_tokens += tokens_per_name num_tokens += 3 # every reply is primed with <|start|>assistant<|message|> return num_tokens -class OpenAIService: - GENERAL_SYSTEM_PROMPT = "You are a world-class software engineer and technical writer specializing in understanding code + architecture + tradeoffs and explaining them clearly and in detail. You are helpful and answer questions the user asks. You organize your explanations in markdown-formatted, bulleted lists." +def tokens_from_string(string, model="gpt-3.5-turbo"): + """Return the number of tokens used by a string.""" + try: + encoding = tiktoken.encoding_for_model(model) + except KeyError: + logger.warn("Warning: model not found. Using cl100k_base encoding.") + encoding = tiktoken.get_encoding("cl100k_base") + + tokens = encoding.encode(string) + + return tokens + + +def num_tokens_from_string(prompt, model="gpt-3.5-turbo"): + """Return the number of tokens used by a string.""" + return len(tokens_from_string(prompt, model=model)) + + +def handle_after_retry(retry_state): + if retry_state.attempt_number < 6: + print(f"Attempt {retry_state.attempt_number} failed. Retrying...") + pass + else: + # Log or print if final attempt also fails + print(f"Final attempt failed after {retry_state.attempt_number} retries.") + + +class OpenAIService(metaclass=Singleton): + GENERAL_SYSTEM_PROMPT = "You are a world-class software engineer and technical writer specializing in understanding code + architecture + tradeoffs and explaining them clearly and in detail. You are helpful and answer questions the user asks. You organize your explanations in easy to read markdown." ANALYSIS_SYSTEM_PROMPT = "You are a world-class developer with an eagle eye for unintended bugs and edge cases. You carefully explain code with great detail and accuracy. You organize your explanations in markdown-formatted, bulleted lists." + def __init__(self, openai_api_key: str | None = None): + openai.api_key = ( + openai_api_key if openai_api_key else os.environ["OPENAI_API_KEY"] + ) + @retry(wait=wait_random_exponential(min=0.2, max=60), stop=stop_after_attempt(6)) def get_answer( self, query: str, code: str, system_prompt: str = GENERAL_SYSTEM_PROMPT @@ -94,9 +130,13 @@ def get_answer( ) return response.choices[0]["message"]["content"] - @retry(wait=wait_random_exponential(min=0.2, max=60), stop=stop_after_attempt(6)) - def query(self, query: str, system_prompt: str = GENERAL_SYSTEM_PROMPT): - response = openai.ChatCompletion.create( + @retry( + wait=wait_random_exponential(min=0.2, max=60), + stop=stop_after_attempt(6), + after=lambda retry_state: handle_after_retry(retry_state), + ) + def query_stream(self, query: str, system_prompt: str = GENERAL_SYSTEM_PROMPT): + api_response = openai.ChatCompletion.create( messages=[ { "role": "system", @@ -106,12 +146,24 @@ def query(self, query: str, system_prompt: str = GENERAL_SYSTEM_PROMPT): ], model=GPT_MODEL, temperature=TEMPERATURE, + stream=True, ) - return response.choices[0]["message"]["content"] + + for chunk in api_response: + delta = chunk["choices"][0]["delta"] + if "content" in delta: + content = delta["content"] + print(content, end="") @retry(wait=wait_random_exponential(min=0.2, max=60), stop=stop_after_attempt(6)) def get_embedding(self, text: str): - response = openai.Embedding.create(input=[text], model=EMBEDDING_MODEL) + try: + response = openai.Embedding.create(input=[text], model=EMBEDDING_MODEL) + except openai.error.OpenAIError as e: + # print(f"OpenAIError: {e}") + # print(f"Input: {text}") + # print(f"Response: {response}") + raise e if ( "data" not in response diff --git a/src/repo_gpt/prompt_service.py b/src/repo_gpt/prompt_service.py new file mode 100644 index 0000000..4d85ab0 --- /dev/null +++ b/src/repo_gpt/prompt_service.py @@ -0,0 +1,66 @@ +from repo_gpt.openai_service import OpenAIService +from repo_gpt.utils import Singleton + + +class PromptService(metaclass=Singleton): + def __init__(self, openai_service: OpenAIService, language: str): + self.language = language + self.openai_service = openai_service + + def analyze_file(self, file_path: str, output_html: bool = False): + with open(file_path, "r") as f: + code = f.read() + + self.explain(code, output_html=output_html) + + def explain(self, code: str, output_html: bool = False): + format = "html" if output_html else "markdown" + try: + explanation = self.openai_service.query_stream( + f"""Please explain the following {self.language} function. + +```{self.language} +{code} +```""", + system_prompt=f"""You are a world-class {self.language} developer and you are explaining the following code to a junior developer. Be concise. Organize your explanation in {format}.""", + ) + return explanation + except Exception as e: + return e.message + + def refactor_code(self, code: str, additional_instructions: str): + addition_instruction_query = ( + f" Additional instructions: {additional_instructions}" + if additional_instructions + else "" + ) + self.openai_service.query_stream( + f"""Please refactor the following {self.language} function.{addition_instruction_query} + +```{self.language} +{code} +```""", + system_prompt=f"""You are a world-class {self.language} developer and you are refactoring code. You always use best practices when coding. +When you edit or add code, you respect and use existing conventions, libraries, etc. Only output all refactored code in the following format: +```{self.language} + +```""", + ) + + def query_code(self, question: str, code: str = ""): + self.openai_service.query_stream( + f"""Use the code below to answer the subsequent question. If the answer cannot be found, write "I don't know." +``` +{code} +``` +Question: {question} +Output the answer in well organized markdown.""" + ) + + def _extract_code(self, response: str): + split = response.split("```{self.language}") + if len(split) < 2: + raise Exception("No code found in response") + code = split[1].split("```")[0] + + return code diff --git a/src/repo_gpt/search_service.py b/src/repo_gpt/search_service.py index 88a122e..b30a7c6 100644 --- a/src/repo_gpt/search_service.py +++ b/src/repo_gpt/search_service.py @@ -1,18 +1,50 @@ +import json +import logging import pickle -from pathlib import Path -from typing import Tuple +from enum import Enum +from pathlib import Path, PosixPath +import numpy as np import pandas as pd +import tqdm +from Levenshtein import distance as levenshtein_distance from rich.markdown import Markdown -from tqdm import tqdm -from .console import console, pretty_print_code +from .console import console, pretty_print_code, verbose_print +from .file_handler.abstract_handler import ParsedCode from .openai_service import OpenAIService - -tqdm.pandas() - - -class SearchService: +from .utils import Singleton + +logger = logging.getLogger(__name__) + + +class CustomCodeEmbeddingDFEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, Enum): + return obj.value + if isinstance(obj, PosixPath): + return str(obj) + return super(CustomCodeEmbeddingDFEncoder, self).default(obj) + + +def convert_search_df_to_json( + df: pd.DataFrame, + selected_columns: list = [ + "class_name", + "function_name", + "code", + "code_type", + "summary", + "inputs", + "outputs", + "filepath", + ], +): + df_dict = df[selected_columns].to_dict(orient="records") + return json.dumps(df_dict, cls=CustomCodeEmbeddingDFEncoder) + + +class SearchService(metaclass=Singleton): def __init__( self, openai_service: OpenAIService, @@ -39,47 +71,100 @@ def simple_search(self, query: str): print(matches) def semantic_search(self, code_query: str): - similar_code_df = self._semantic_search_similar_code(code_query) + similar_code_df = self.semantic_search_similar_code(code_query) pretty_print_code(similar_code_df, self.language) return similar_code_df def find_function_match( - self, function_name: str, class_name: str = None - ) -> Tuple[pd.DataFrame, pd.DataFrame]: + self, function_name: str, class_name: str = None, matches_to_return: int = 3 + ) -> pd.DataFrame: print(f"Loaded dataframe with {len(self.df)} code blocks") print(f"Searching for function {function_name}...") - # If class_name is provided, look for class matches - class_matches = ( - self.df[ - (self.df["name"] == class_name) - & (self.df["code_type"] == "CodeType.CLASS") - ] - if class_name - else None - ) + # Handle None values for class_name and function_name + class_name = class_name or "" + function_name = function_name or "" - # Look for function matches - function_matches = self.df[ - (self.df["name"] == function_name) - # & ((self.df["code_type"] == "CodeType.FUNCTION") | (self.df["code_type"] == "CodeType.METHOD")) # TODO not sure why this doesn't work. I just need to switch to polars - ] + # Concatenate class_name and function_name for comparison + search_name = f"{class_name}{function_name}" - return function_matches, class_matches + # Calculate the Levenshtein distance for the concatenated names without modifying self.df + name_distances = self.df.apply( + lambda row: levenshtein_distance( + search_name, f"{row['class_name'] or ''}{row['function_name'] or ''}" + ), + axis=1, + ) - def _semantic_search_similar_code(self, query: str, matches_to_return: int = 3): + # Get the indices of the smallest distances + closest_indices = np.argsort(name_distances)[:matches_to_return] + + # Return the top matches using the indices to index into the original DataFrame + return self.df.iloc[closest_indices] + + # def find_function_match( + # self, function_name: str, class_name: str = None, matches_to_return: int = 3 + # ) -> pd.DataFrame: + # print(f"Loaded dataframe with {len(self.df)} code blocks") + # print(f"Searching for function {function_name}...") + # + # # Handle None values for class_name and function_name + # class_name = class_name or '' + # function_name = function_name or '' + # + # # Concatenate class_name and function_name in the dataframe + # self.df['full_name'] = self.df['class_name'].fillna('') + self.df['function_name'].fillna('') + # + # # Calculate the Levenshtein distance for the concatenated names + # search_name = f"{class_name}{function_name}" + # self.df['name_distance'] = self.df['full_name'].apply( + # lambda x: levenshtein_distance(search_name, x) + # ) + # + # # Sort the DataFrame by the distance and get the top matches_to_return + # return self.df.sort_values(by='name_distance').head(matches_to_return) + + # def semantic_search_similar_code(self, query: str, matches_to_return: int = 3): + # embedding = self.openai_service.get_embedding(query) + # logger.verbose_info("Searching for similar code...") + # + # if logger.getEffectiveLevel() < logging.INFO: + # tqdm.pandas() + # self.df["similarities"] = self.df["code_embedding"].progress_apply( + # lambda x: x.dot(embedding) + # ) + # else: + # self.df["similarities"] = self.df["code_embedding"].apply( + # lambda x: x.dot(embedding) + # ) + # + # return self.df.sort_values("similarities", ascending=False).head( + # matches_to_return + # ) + + def semantic_search_similar_code(self, query: str, matches_to_return: int = 3): embedding = self.openai_service.get_embedding(query) - console.print("Searching for similar code...") - self.df["similarities"] = self.df["code_embedding"].progress_apply( - lambda x: x.dot(embedding) - ) + logger.verbose_info("Searching for similar code...") + + # Calculate similarities as a separate series instead of a DataFrame column + if logger.getEffectiveLevel() < logging.INFO: + tqdm.pandas() + similarities = self.df["code_embedding"].progress_apply( + lambda x: x.dot(embedding) + ) + else: + similarities = self.df["code_embedding"].apply(lambda x: x.dot(embedding)) - return self.df.sort_values("similarities", ascending=False).head( - matches_to_return + # Use the similarities series to sort the DataFrame index + sorted_indices = ( + similarities.sort_values(ascending=False).head(matches_to_return).index ) + # Return the top matches using the sorted indices to index into the original DataFrame + return self.df.loc[sorted_indices] + def question_answer(self, question: str): - similar_code_df = self._semantic_search_similar_code(question) + similar_code_df = self.semantic_search_similar_code(question) pretty_print_code(similar_code_df, self.language) # TODO: add code to only send X amount of tokens to OpenAI @@ -95,30 +180,22 @@ def question_answer(self, question: str): console.print("🤖 Answer from `GPT3.5` 🤖") console.print(ans_md) - def analyze_file(self, file_path: str): + def analyze_file(self, file_path: str, output_html: bool = False): with open(file_path, "r") as f: code = f.read() - console.print("Analyzing your code...") - ans = self.openai_service.get_answer( - "Please explain the following code. Review what each element of the " - "code is doing precisely and what the author's intentions may have " - "been. Organize your explanation as a markdown-formatted, bulleted list.", - code, - system_prompt=self.openai_service.ANALYSIS_SYSTEM_PROMPT, - ) - ans_md = Markdown(ans) - console.print("🤖 Answer from `GPT3.5` 🤖") - console.print(ans_md) - def explain(self, code: str): + self.explain(code, output_html=output_html) + + def explain(self, code: str, output_html: bool = False): + format = "html" if output_html else "markdown" try: - explanation = self.openai_service.query( + explanation = self.openai_service.query_stream( f"""Please explain the following {self.language} function. ```{self.language} {code} ```""", - system_prompt=f"""You are a world-class {self.language} developer and you are explaining the following code to a junior developer. Organize your explanation as a markdown-format.""", + system_prompt=f"""You are a world-class {self.language} developer and you are explaining the following code to a junior developer. Be concise. Organize your explanation in {format}.""", ) return explanation except Exception as e: diff --git a/src/repo_gpt/test_generator.py b/src/repo_gpt/test_generator.py index c38b06f..c4dd0a9 100644 --- a/src/repo_gpt/test_generator.py +++ b/src/repo_gpt/test_generator.py @@ -2,11 +2,9 @@ import openai as openai -from .code_manager.code_extractor import LanguageHandler +from .code_manager.abstract_extractor import LanguageHandler from .openai_service import GPT_3_MODELS, GPT_4_MODELS, num_tokens_from_messages -openai.api_key = os.environ["OPENAI_API_KEY"] - class TestGenerator: TEMPERATURE = 0.4 # temperature = 0 can sometimes get stuck in repetitive loops, so we use 0.4 @@ -20,7 +18,11 @@ def __init__( approx_min_cases_to_cover: int = 7, reruns_if_fail: int = 1, use_gpt_4: bool = False, + openai_api_key: str = None, ): + openai.api_key = ( + openai_api_key if openai_api_key else os.environ["OPENAI_API_KEY"] + ) self.messages = [] self.language = language self.unit_test_package = unit_test_package diff --git a/src/repo_gpt/utils.py b/src/repo_gpt/utils.py index 4638f78..f76c8b4 100644 --- a/src/repo_gpt/utils.py +++ b/src/repo_gpt/utils.py @@ -1,24 +1,8 @@ -import logging -import warnings +class Singleton(type): + _instances = {} -from urllib3.exceptions import InsecureRequestWarning + def __call__(cls, *args, **kwargs): + if cls not in cls._instances: + cls._instances[cls] = super().__call__(*args, **kwargs) -# Suppress only the single warning from urllib3 -warnings.filterwarnings("ignore", category=InsecureRequestWarning) - -# Create a logger -logger = logging.getLogger("repo_gpt") -logger.setLevel(logging.INFO) - -# Create a console handler -handler = logging.StreamHandler() -handler.setLevel(logging.INFO) - -# Create a formatter -formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") - -# Attach the formatter to the handler -handler.setFormatter(formatter) - -# Attach the handler to the logger -logger.addHandler(handler) + return cls._instances[cls] diff --git a/src/repo_gpt/vscode_prompt_service.py b/src/repo_gpt/vscode_prompt_service.py new file mode 100644 index 0000000..96d280f --- /dev/null +++ b/src/repo_gpt/vscode_prompt_service.py @@ -0,0 +1,67 @@ +import json +from dataclasses import asdict, dataclass +from enum import Enum +from typing import Union + +from repo_gpt.openai_service import OpenAIService +from repo_gpt.prompt_service import PromptService +from repo_gpt.search_service import SearchService + + +class Status(Enum): + SUCCESS = "SUCCESS" + ERROR = "ERROR" + + +@dataclass() +class VscodeMessage: + # Note this will be read using Typescript in Vscode + status: str + code: Union[str, None] + message: Union[str, None] + error: Union[str, None] + + def __init__( + self, + status: Status = Status.ERROR, + code: Union[str, None] = None, + message: Union[str, None] = None, + error: Union[Exception, str, None] = None, + ): + self.status = status.value + self.code = code + self.message = message + self.error = str(error) if isinstance(error, Exception) else error + + def __str__(self): + """ + This ensures printed strings are valid JSON, which is necessary for the Vscode extension to read the output. + :return: + """ + + return json.dumps(asdict(self)) + + +class VscodePromptService(PromptService): + def __init__( + self, + openai_service: OpenAIService, + language: str, + search_service: SearchService = None, + ): + super().__init__(openai_service, language) + self.search_service = search_service + + def refactor_code( + self, input_code_file_path: str, additional_instructions: str = "" + ): + # try: + with open(input_code_file_path, "r") as f: + code = f.read() + super().refactor_code(code, additional_instructions) + + def query_code(self, question: str): + similar_code_df = self.search_service.semantic_search_similar_code(question) + code = "\n".join(similar_code_df["code"].tolist()) + + super().query_code(question, code) diff --git a/test/code_manager/code_extractor.py b/test/code_manager/code_extractor.py new file mode 100644 index 0000000..d08224b --- /dev/null +++ b/test/code_manager/code_extractor.py @@ -0,0 +1,109 @@ +# imports +import pytest + +from repo_gpt.code_manager.code_dir_extractor import CodeDirExtractor +from repo_gpt.file_handler.abstract_handler import ParsedCode + + +# unit tests +@pytest.mark.parametrize( + "code_files, embedding_code_file_checksums, expected_output, expected_prints", + [ + # Scenario 1: code_files is an empty list + ([], {}, [], []), + # Scenario 2: code_files contains multiple file paths + ( + ["/path/to/file1.py", "/path/to/file2.py", "/path/to/file3.py"], + {}, + [ParsedCode(), ParsedCode(), ParsedCode()], + [ + "🟢 Extracted 3 functions from /path/to/file1.py", + "🟢 Extracted 3 functions from /path/to/file2.py", + "🟢 Extracted 3 functions from /path/to/file3.py", + ], + ), + # Scenario 3: embedding_code_file_checksums is an empty dictionary + ( + ["/path/to/file1.py", "/path/to/file2.py"], + {}, + [ParsedCode(), ParsedCode()], + [ + "🟢 Extracted 3 functions from /path/to/file1.py", + "🟢 Extracted 3 functions from /path/to/file2.py", + ], + ), + # Scenario 4: embedding_code_file_checksums contains checksums for some files + ( + ["/path/to/file1.py", "/path/to/file2.py"], + {"/path/to/file1.py": "checksum1"}, + [ParsedCode()], + [ + "🟡 Skipping -- file unmodified /path/to/file1.py", + "🟢 Extracted 3 functions from /path/to/file2.py", + ], + ), + # Scenario 5: No functions or classes found in a code file + ( + ["/path/to/file1.py"], + {}, + [], + ["🟡 Skipping -- no functions or classes found /path/to/file1.py"], + ), + # Scenario 6: Multiple functions or classes found in a code file + ( + ["/path/to/file1.py"], + {}, + [ParsedCode(), ParsedCode()], + ["🟢 Extracted 2 functions from /path/to/file1.py"], + ), + # Scenario 7: The extract_functions_from_file method raises an exception + ( + ["/path/to/file1.py"], + {}, + [], + ["🟡 Skipping -- no functions or classes found /path/to/file1.py"], + ), + # Scenario 8: The extract_code_files method raises an exception + ([], {}, [], []), + # Scenario 9: The generate_md5 method raises an exception + ( + ["/path/to/file1.py"], + {}, + [], + ["🟡 Skipping -- no functions or classes found /path/to/file1.py"], + ), + # Scenario 10: The print statements are disabled + (["/path/to/file1.py"], {}, [ParsedCode()], []), + ], +) +def test_extract_functions( + code_files, embedding_code_file_checksums, expected_output, expected_prints +): + # Mock the necessary methods and objects + my_class = CodeDirExtractor() + my_class.extract_code_files = lambda: code_files + my_class.generate_md5 = ( + lambda file_path: "checksum1" + if file_path == "/path/to/file1.py" + else "checksum2" + ) + my_class.extract_functions_from_file = ( + lambda file_path, checksum: [ParsedCode()] + if file_path == "/path/to/file1.py" + else [] + ) + + # Capture the prints during the test execution + captured_prints = [] + + def mock_print(*args): + captured_prints.append(" ".join(args)) + + my_class.print = mock_print + + # Call the function under test + output = my_class.extract_functions(embedding_code_file_checksums) + + # Assert the output and prints + assert output == expected_output + assert captured_prints == expected_prints diff --git a/test/file_handler/test_php_extract_code.py b/test/file_handler/test_php_extract_code.py index eb70051..baa4902 100644 --- a/test/file_handler/test_php_extract_code.py +++ b/test/file_handler/test_php_extract_code.py @@ -29,7 +29,8 @@ class TestClass extends BaseClass { # Define expected parsed code for PHP EXPECTED_PHP_FUNCTION_PARSED_CODE = [ ParsedCode( - name="helloWorld", + function_name="helloWorld", + class_name=None, code_type=CodeType.FUNCTION, code='function helloWorld(): string {\n return "Hello, world!";\n}', inputs=None, @@ -37,9 +38,10 @@ class TestClass extends BaseClass { outputs=("string",), ), ParsedCode( - name=None, + function_name=None, + class_name=None, code_type=CodeType.GLOBAL, - code="", + code="\n", inputs=None, summary=None, outputs=None, @@ -48,7 +50,8 @@ class TestClass extends BaseClass { EXPECTED_PHP_CLASS_PARSED_CODE = [ ParsedCode( - name="TestClass", + class_name="TestClass", + function_name=None, code_type=CodeType.CLASS, summary="""class: TestClass\n parent classes: ('BaseClass',)\n\n method: testMethod\n input parameters: None\n output parameters: None\n code: ...\n""", inputs=("BaseClass",), @@ -56,17 +59,19 @@ class TestClass extends BaseClass { outputs=None, ), ParsedCode( - name="testMethod", - code_type=CodeType.METHOD, + function_name="testMethod", + class_name=None, + code_type=CodeType.FUNCTION, code="public function testMethod() {\n /* This is a test method. */\n return;\n }", inputs=None, summary=None, outputs=None, ), ParsedCode( - name=None, + function_name=None, + class_name=None, code_type=CodeType.GLOBAL, - code="", + code="\n", inputs=None, summary=None, outputs=None, diff --git a/test/file_handler/test_php_extract_vscode_ext_codelens.py b/test/file_handler/test_php_extract_vscode_ext_codelens.py new file mode 100644 index 0000000..f3f8a2a --- /dev/null +++ b/test/file_handler/test_php_extract_vscode_ext_codelens.py @@ -0,0 +1,77 @@ +import pytest + +from src.repo_gpt.file_handler.abstract_handler import VSCodeExtCodeLensCode +from src.repo_gpt.file_handler.generic_code_file_handler import ( # Assuming you have this handler + PHPFileHandler, +) + +handler = PHPFileHandler() + +# Define some sample PHP inputs +SAMPLE_INPUT_TEXT_FUNCTION = """ + +""" + +SAMPLE_INPUT_TEXT_CLASS = """ + +""" + +# Define expected output for PHP +EXPECTED_OUTPUT_FUNCTION = [ + VSCodeExtCodeLensCode( + name="helloWorld", + start_line=2, + end_line=4, + # code='function helloWorld() {\n echo "Hello, world!";\n}', + ) +] + +EXPECTED_OUTPUT_CLASS = [ + VSCodeExtCodeLensCode( + name="SampleClass", + start_line=2, + end_line=6, + # code="class SampleClass {\n public function methodOne() {\n // Do something\n }\n}", + ), + VSCodeExtCodeLensCode( + name="methodOne", + start_line=3, + end_line=5, + # code="public function methodOne() {\n // Do something\n }", + ), +] + + +@pytest.mark.parametrize( + "input_text, expected_output", + [ + (SAMPLE_INPUT_TEXT_FUNCTION, EXPECTED_OUTPUT_FUNCTION), + (SAMPLE_INPUT_TEXT_CLASS, EXPECTED_OUTPUT_CLASS), + ], +) +def test_extract_vscode_ext_codelens(tmp_path, input_text, expected_output): + # Create a temporary file with the sample input + p = tmp_path / "sample.php" + p.write_text(input_text) + + # Call the function + parsed_vs_codelens = handler.extract_vscode_ext_codelens(p) + + # Check the output + assert isinstance(parsed_vs_codelens, list) + assert parsed_vs_codelens == expected_output + assert all(isinstance(code, VSCodeExtCodeLensCode) for code in parsed_vs_codelens) + parsed_vs_codelens.sort() + expected_output.sort() + assert len(parsed_vs_codelens) == len(expected_output) + assert parsed_vs_codelens == expected_output diff --git a/test/file_handler/test_python_extract_code.py b/test/file_handler/test_python_extract_code.py index 155a842..f00097a 100644 --- a/test/file_handler/test_python_extract_code.py +++ b/test/file_handler/test_python_extract_code.py @@ -9,10 +9,15 @@ SAMPLE_FUNCTION_INPUT_TEXT = """ foo = "bar" +def hello_world() -> str: + return "Hello, world!" + +@decorator def hello_world() -> str: return "Hello, world!" """ SAMPLE_CLASS_INPUT_TEXT = """ +@decorator class TestClass(BaseClass): \"""This is a test class. \""" def test_method(self): @@ -22,7 +27,8 @@ def test_method(self): # Define expected parsed code EXPECTED_FUNCTION_PARSED_CODE = [ ParsedCode( - name="hello_world", + function_name="hello_world", + class_name=None, code_type=CodeType.FUNCTION, code='def hello_world() -> str:\n return "Hello, world!"', inputs=None, @@ -30,9 +36,19 @@ def test_method(self): outputs=("str",), ), ParsedCode( - name=None, + function_name="hello_world", + class_name=None, + code_type=CodeType.FUNCTION, + code='def hello_world() -> str:\n return "Hello, world!"', + inputs=None, + summary=None, + outputs=("str",), + ), + ParsedCode( + function_name=None, + class_name=None, code_type=CodeType.GLOBAL, - code='foo = "bar"', + code='foo = "bar"\n\n\n@decorator\n', inputs=None, summary=None, outputs=None, @@ -41,7 +57,8 @@ def test_method(self): EXPECTED_CLASS_PARSED_CODE = [ ParsedCode( - name="TestClass", + class_name="TestClass", + function_name=None, code_type=CodeType.CLASS, summary="""class: TestClass\n parent classes: ('BaseClass',)\n\n method: test_method\n input parameters: ('self',)\n output parameters: None\n code: ...\n""", inputs=("BaseClass",), @@ -49,13 +66,23 @@ def test_method(self): outputs=None, ), ParsedCode( - name="test_method", - code_type=CodeType.METHOD, + function_name="test_method", + class_name=None, + code_type=CodeType.FUNCTION, code="""def test_method(self):\n \"""This is a test method. \"""\n pass""", inputs=("self",), summary=None, outputs=None, ), + ParsedCode( + function_name=None, + class_name=None, + code_type=CodeType.GLOBAL, + code="@decorator\n", + inputs=None, + summary=None, + outputs=None, + ), ] @@ -92,7 +119,7 @@ def test_no_function_in_file(tmp_path): assert isinstance(parsed_code, list) assert len(parsed_code) == 1 assert parsed_code[0].code_type == CodeType.GLOBAL - assert parsed_code[0].code == code.strip() + assert code.strip() in parsed_code[0].code def test_edge_cases(tmp_path): diff --git a/test/file_handler/test_python_extract_vscode_ext_codelens.py b/test/file_handler/test_python_extract_vscode_ext_codelens.py new file mode 100644 index 0000000..719bc82 --- /dev/null +++ b/test/file_handler/test_python_extract_vscode_ext_codelens.py @@ -0,0 +1,78 @@ +import pytest + +from src.repo_gpt.file_handler.abstract_handler import VSCodeExtCodeLensCode +from src.repo_gpt.file_handler.generic_code_file_handler import PythonFileHandler + +handler = PythonFileHandler() + +# Define some sample inputs +SAMPLE_INPUT_TEXT_FUNCTION = """ +def hello_world(): + print("Hello, world!") + +@decorator +def hello_world(): + print("Hello, world!") +""" + +SAMPLE_INPUT_TEXT_CLASS = """ +class SampleClass: + def method_one(self): + pass +""" + +# Define expected output +EXPECTED_OUTPUT_FUNCTION = [ + VSCodeExtCodeLensCode( + name="hello_world", + start_line=1, + end_line=2, + # code='def hello_world():\n print("Hello, world!")', + ), + VSCodeExtCodeLensCode( + name="hello_world", + start_line=5, + end_line=6, + # code='def hello_world():\n print("Hello, world!")', + ), +] + +EXPECTED_OUTPUT_CLASS = [ + VSCodeExtCodeLensCode( + name="SampleClass", + start_line=1, + end_line=3, + # code="class SampleClass:\n def method_one(self):\n pass", + ), + VSCodeExtCodeLensCode( + name="method_one", + start_line=2, + end_line=3, + # code="def method_one(self):\n pass", + ), +] + + +@pytest.mark.parametrize( + "input_text, expected_output", + [ + (SAMPLE_INPUT_TEXT_FUNCTION, EXPECTED_OUTPUT_FUNCTION), + (SAMPLE_INPUT_TEXT_CLASS, EXPECTED_OUTPUT_CLASS), + ], +) +def test_extract_vscode_ext_codelens(tmp_path, input_text, expected_output): + # Create a temporary file with the sample input + p = tmp_path / "sample.py" + p.write_text(input_text) + + # Call the function + parsed_vs_codelens = handler.extract_vscode_ext_codelens(p) + + # Check the output + assert isinstance(parsed_vs_codelens, list) + assert parsed_vs_codelens == expected_output + assert all(isinstance(code, VSCodeExtCodeLensCode) for code in parsed_vs_codelens) + parsed_vs_codelens.sort() + expected_output.sort() + assert len(parsed_vs_codelens) == len(expected_output) + assert parsed_vs_codelens == expected_output diff --git a/test/file_handler/test_sql_extract_vscode_ext_codelens.py b/test/file_handler/test_sql_extract_vscode_ext_codelens.py new file mode 100644 index 0000000..acc377a --- /dev/null +++ b/test/file_handler/test_sql_extract_vscode_ext_codelens.py @@ -0,0 +1,195 @@ +import pytest + +from repo_gpt.file_handler.abstract_handler import VSCodeExtCodeLensCode +from repo_gpt.file_handler.generic_sql_file_handler import GenericSQLFileHandler + +handler = GenericSQLFileHandler() + + +def test_single_sql_statement(tmp_path): + # Create a file with a single SQL statement + d = tmp_path / "single" + d.mkdir() + p = d / "single.sql" + p.write_text("SELECT * FROM table;") + + # Test the function + result = handler.extract_vscode_ext_codelens(p) + + assert len(result) == 1 + assert result[0] == VSCodeExtCodeLensCode( + name="select", + # code="SELECT * FROM table", + start_line=0, + end_line=0, + ) + + +@pytest.fixture +def sql_file(tmp_path): + # Setup: Create a file with multiple SQL statements with varied formatting + d = tmp_path / "multiple" + d.mkdir() + p = d / "multiple.sql" + p.write_text( + """ +-- CTE (Common Table Expression) +WITH CTE_Sales AS ( + SELECT + product_id + FROM + sales + GROUP BY + product_id +) + +-- SELECT statement using the CTE +SELECT + p.product_name +FROM + products p +WHERE + c.total_sales > 1000; + +-- UPDATE statement +UPDATE products +SET product_price = product_price * 0.9 +WHERE product_id IN (SELECT product_id FROM CTE_Sales WHERE total_sales < 500); + +-- DELETE statement +DELETE FROM sales +WHERE sale_date < '2022-01-01'; + +-- INSERT statement +INSERT INTO products (product_name, product_price) +VALUES ('New Product', 19.99); + +-- Function +CREATE OR REPLACE FUNCTION get_total_sales(product_id INT) RETURNS FLOAT AS $$ +BEGIN + RETURN ( + SELECT SUM(sale_amount) + FROM sales + WHERE sales.product_id = get_total_sales.product_id + ); +END; +$$ LANGUAGE plpgsql; + +-- Call the function +SELECT get_total_sales(5); + """ + ) + return p + + +def test_cte_extraction(sql_file): + result = handler.extract_vscode_ext_codelens(sql_file) + assert result[0].name == "select" + # assert "WITH CTE_Sales AS" in result[0].code + assert result[0].start_line == 2 + assert result[0].end_line == 17 + + +def test_update_extraction(sql_file): + result = handler.extract_vscode_ext_codelens(sql_file) + assert result[1].name == "update" + # assert "UPDATE products" in result[1].code + assert result[1].start_line == 20 + assert result[1].end_line == 22 + + +def test_delete_extraction(sql_file): + result = handler.extract_vscode_ext_codelens(sql_file) + assert result[2].name == "delete" + # assert "DELETE FROM sales" in result[2].code + assert result[2].start_line == 25 + assert result[2].end_line == 26 + + +def test_insert_extraction(sql_file): + result = handler.extract_vscode_ext_codelens(sql_file) + assert result[3].name == "insert" + # assert "INSERT INTO products" in result[3].code + assert result[3].start_line == 29 + assert result[3].end_line == 30 + + +def test_function_extraction(sql_file): + result = handler.extract_vscode_ext_codelens(sql_file) + assert result[4].name == "function" + # assert "CREATE OR REPLACE FUNCTION get_total_sales" in result[4].code + assert result[4].start_line == 33 + assert result[4].end_line == 41 + + +def test_function_call_extraction(sql_file): + result = handler.extract_vscode_ext_codelens(sql_file) + assert result[5].name == "select" + # assert "SELECT get_total_sales(5)" in result[5].code + assert result[5].start_line == 44 + assert result[5].end_line == 44 + + +def test_nested_sql_statements(tmp_path): + # Create a file with nested SQL statements + d = tmp_path / "nested" + d.mkdir() + p = d / "nested.sql" + p.write_text("SELECT * FROM (SELECT id FROM table);") + + # Test the function + result = handler.extract_vscode_ext_codelens(p) + + assert len(result) == 1 + assert result[0] == VSCodeExtCodeLensCode( + name="select", + # code="SELECT * FROM (SELECT id FROM table)", + start_line=0, + end_line=0, + ) + + +def test_comments_in_sql_file(tmp_path): + # Create a file with SQL statements and comments + d = tmp_path / "comments" + d.mkdir() + p = d / "comments.sql" + p.write_text( + "SELECT * FROM table; -- This is a comment\nINSERT INTO table VALUES (1, 2, 3);" + ) + + # Test the function + result = handler.extract_vscode_ext_codelens(p) + + assert len(result) == 2 + assert result[0] == VSCodeExtCodeLensCode( + name="select", + # code="SELECT * FROM table", + start_line=0, + end_line=0, + ) + assert result[1] == VSCodeExtCodeLensCode( + name="insert", + # code="INSERT INTO table VALUES (1, 2, 3)", + start_line=1, + end_line=1, + ) + + +def test_incorrect_sql_syntax(tmp_path): + # Create a file with incorrect SQL syntax + d = tmp_path / "incorrect" + d.mkdir() + p = d / "incorrect.py" + p.write_text("SELECT FROM table;") + + # Test the function + result = handler.extract_vscode_ext_codelens(p) + + assert len(result) == 1 + assert result[0] == VSCodeExtCodeLensCode( + name="select", + # code="SELECT FROM table", + start_line=0, + end_line=0, + ) diff --git a/test/file_handler/test_sql_file_handler_extract_code.py b/test/file_handler/test_sql_file_handler_extract_code.py index 5fe1105..8795f4e 100644 --- a/test/file_handler/test_sql_file_handler_extract_code.py +++ b/test/file_handler/test_sql_file_handler_extract_code.py @@ -1,13 +1,9 @@ import pytest -# Create a handler that we can use in our tests -from repo_gpt.file_handler.abstract_handler import ParsedCode -from repo_gpt.file_handler.sql_file_handler import SqlFileHandler +from repo_gpt.file_handler.abstract_handler import CodeType, ParsedCode +from repo_gpt.file_handler.generic_sql_file_handler import GenericSQLFileHandler -# Assume that sqlglot raises a SQLGlotError for incorrect syntax - - -handler = SqlFileHandler() +handler = GenericSQLFileHandler() def test_single_sql_statement(tmp_path): @@ -20,8 +16,9 @@ def test_single_sql_statement(tmp_path): result = handler.extract_code(p) assert len(result) == 1 assert result[0] == ParsedCode( - name="1", - code_type="Select", + function_name=None, + class_name=None, + code_type=CodeType.SELECT, code="SELECT * FROM table", inputs=None, summary=None, @@ -39,19 +36,21 @@ def test_multiple_sql_statements(tmp_path): result = handler.extract_code(p) assert len(result) == 2 assert result[0] == ParsedCode( - name="1", - code_type="Select", + function_name=None, + class_name=None, + code_type=CodeType.SELECT, code="SELECT * FROM table", inputs=None, summary=None, outputs=None, ) # Bug with sqlglot: the second statement is not parsed correctly - # assert result[1] == ParsedCode(name="2", code_type="Insert", code="INSERT INTO table VALUES (1, 2, 3)") + # assert result[1] == ParsedCode(name=None, code_type=CodeType.INSERT, code="INSERT INTO table VALUES (1, 2, 3)") assert result[1] == ParsedCode( - name="2", - code_type="Insert", - code="INSERT INTO VALUES (1, 2, 3)", + function_name=None, + class_name=None, + code_type=CodeType.INSERT, + code="INSERT INTO table VALUES (1, 2, 3)", inputs=None, summary=None, outputs=None, @@ -68,8 +67,9 @@ def test_nested_sql_statements(tmp_path): result = handler.extract_code(p) assert len(result) == 1 assert result[0] == ParsedCode( - name="1", - code_type="Select", + function_name=None, + class_name=None, + code_type=CodeType.SELECT, code="SELECT * FROM (SELECT id FROM table)", inputs=None, summary=None, @@ -89,19 +89,21 @@ def test_comments_in_sql_file(tmp_path): result = handler.extract_code(p) assert len(result) == 2 assert result[0] == ParsedCode( - name="1", - code_type="Select", + function_name=None, + class_name=None, + code_type=CodeType.SELECT, code="SELECT * FROM table", inputs=None, summary=None, outputs=None, ) # Bug with sqlglot: the second statement is not parsed correctly - # assert result[1] == ParsedCode(name="2", code_type="Insert", code="INSERT INTO table VALUES (1, 2, 3)") + # assert result[1] == ParsedCode(name=None, code_type=CodeType.INSERT, code="INSERT INTO table VALUES (1, 2, 3)") assert result[1] == ParsedCode( - name="2", - code_type="Insert", - code="INSERT INTO VALUES (1, 2, 3)", + function_name=None, + class_name=None, + code_type=CodeType.INSERT, + code="INSERT INTO table VALUES (1, 2, 3)", inputs=None, summary=None, outputs=None, @@ -112,14 +114,15 @@ def test_incorrect_sql_syntax(tmp_path): # Create a file with incorrect SQL syntax d = tmp_path / "incorrect" d.mkdir() - p = d / "incorrect.sql" + p = d / "incorrect.py" p.write_text("SELECT FROM table;") # Test the function, expect a SQLGlotError to be raised result = handler.extract_code(p) assert len(result) == 1 assert result[0] == ParsedCode( - name="1", - code_type="Select", + function_name=None, + class_name=None, + code_type=CodeType.SELECT, code="SELECT FROM table", inputs=None, summary=None, diff --git a/test/file_handler/test_typescript_extract_code.py b/test/file_handler/test_typescript_extract_code.py index 2fc405e..5b111de 100644 --- a/test/file_handler/test_typescript_extract_code.py +++ b/test/file_handler/test_typescript_extract_code.py @@ -10,6 +10,10 @@ function helloWorld(): string { return "Hello, world!"; } + +export async function helloWorld(): string { + return "Hello, world!"; +} """ SAMPLE_TS_CLASS_INPUT_TEXT = """ @@ -25,18 +29,29 @@ class TestClass extends BaseClass { # Define expected parsed code for TypeScript EXPECTED_TS_FUNCTION_PARSED_CODE = [ ParsedCode( - name="helloWorld", + function_name="helloWorld", + class_name=None, code_type=CodeType.FUNCTION, code='function helloWorld(): string {\n return "Hello, world!";\n}', inputs=None, summary=None, outputs=("string",), ), + ParsedCode( + function_name="helloWorld", + class_name=None, + code_type=CodeType.FUNCTION, + code='async function helloWorld(): string {\n return "Hello, world!";\n}', + inputs=None, + summary=None, + outputs=("string",), + ), ] EXPECTED_TS_CLASS_PARSED_CODE = [ ParsedCode( - name="TestClass", + class_name="TestClass", + function_name=None, code_type=CodeType.CLASS, summary="""class: TestClass\n parent classes: ('BaseClass',)\n\n method: testMethod\n input parameters: None\n output parameters: ('void',)\n code: ...\n""", inputs=("BaseClass",), @@ -44,8 +59,9 @@ class TestClass extends BaseClass { outputs=None, ), ParsedCode( - name="testMethod", - code_type=CodeType.METHOD, + function_name="testMethod", + class_name=None, + code_type=CodeType.FUNCTION, code="testMethod(): void {\n // This is a test method.\n return;\n }", inputs=None, summary=None, diff --git a/test/file_handler/test_typescript_extract_vscode_ext_codelens.py b/test/file_handler/test_typescript_extract_vscode_ext_codelens.py new file mode 100644 index 0000000..3c13c84 --- /dev/null +++ b/test/file_handler/test_typescript_extract_vscode_ext_codelens.py @@ -0,0 +1,83 @@ +import pytest + +from src.repo_gpt.file_handler.abstract_handler import VSCodeExtCodeLensCode +from src.repo_gpt.file_handler.generic_code_file_handler import ( # Assuming you have this handler + TypeScriptFileHandler, +) + +handler = TypeScriptFileHandler() + +# Define some sample TypeScript inputs +SAMPLE_INPUT_TEXT_FUNCTION = """ +function helloWorld(): string { + return "Hello, world!"; +} + +export async function helloWorld(): string { + return "Hello, world!"; +} +""" + +SAMPLE_INPUT_TEXT_CLASS = """ +class SampleClass { + methodOne(): void { + // Do something + } +} +""" + +# Define expected output for TypeScript +EXPECTED_OUTPUT_FUNCTION = [ + VSCodeExtCodeLensCode( + name="helloWorld", + start_line=1, + end_line=3, + # # code='function helloWorld(): string {\n return "Hello, world!";\n}', + ), + VSCodeExtCodeLensCode( + name="helloWorld", + start_line=5, + end_line=7, + # code='async function helloWorld(): string {\n return "Hello, world!";\n}', + ), +] + +EXPECTED_OUTPUT_CLASS = [ + VSCodeExtCodeLensCode( + name="SampleClass", + start_line=1, + end_line=5, + # code="class SampleClass {\n methodOne(): void {\n // Do something\n }\n}", + ), + VSCodeExtCodeLensCode( + name="methodOne", + start_line=2, + end_line=4, + # code="methodOne(): void {\n // Do something\n }", + ), +] + + +@pytest.mark.parametrize( + "input_text, expected_output", + [ + (SAMPLE_INPUT_TEXT_FUNCTION, EXPECTED_OUTPUT_FUNCTION), + (SAMPLE_INPUT_TEXT_CLASS, EXPECTED_OUTPUT_CLASS), + ], +) +def test_extract_vscode_ext_codelens(tmp_path, input_text, expected_output): + # Create a temporary file with the sample input + p = tmp_path / "sample.ts" + p.write_text(input_text) + + # Call the function + parsed_vs_codelens = handler.extract_vscode_ext_codelens(p) + + # Check the output + assert isinstance(parsed_vs_codelens, list) + assert parsed_vs_codelens == expected_output + assert all(isinstance(code, VSCodeExtCodeLensCode) for code in parsed_vs_codelens) + parsed_vs_codelens.sort() + expected_output.sort() + assert len(parsed_vs_codelens) == len(expected_output) + assert parsed_vs_codelens == expected_output