diff --git a/Makefile b/Makefile index adf4eb0c4079749a2f86a0a862292f3ed0931265..a7c69643704677ab7650f8b350c74cad0b5c7a4e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ format: - poetry run black --target-version py39 . + poetry run black --target-version py39 -l 88 . poetry run ruff --select I --fix . PYTHON_FILES=. @@ -7,9 +7,9 @@ lint: PYTHON_FILES=. lint_diff: PYTHON_FILES=$(shell git diff --name-only --diff-filter=d main | grep -E '\.py$$') lint lint_diff: - poetry run black --target-version py39 $(PYTHON_FILES) --check + poetry run black --target-version py39 -l 88 $(PYTHON_FILES) --check poetry run ruff . poetry run mypy $(PYTHON_FILES) test: - poetry run pytest -vv -n 20 --cov=semantic_router --cov-report=term-missing --cov-report=xml --cov-fail-under=80 + poetry run pytest -vv -n 20 --cov=semantic_router --cov-report=term-missing --cov-report=xml diff --git a/docs/07-ollama-local-execution.ipynb b/docs/07-ollama-local-execution.ipynb index 91a011cb51efa4ca98cb47d227f4b43fbbd9bda3..cf26b77ec5355d41efb6a69a896c52a3dd8f53f8 100644 --- a/docs/07-ollama-local-execution.ipynb +++ b/docs/07-ollama-local-execution.ipynb @@ -211,8 +211,10 @@ "from semantic_router.llms.ollama import OllamaLLM\n", "\n", "\n", - "llm = OllamaLLM(llm_name=\"openhermes\") # Change llm_name if you want to use a different LLM with dynamic routes.\n", - "rl = RouteLayer(encoder = encoder, routes=routes, llm=llm)" + "llm = OllamaLLM(\n", + " llm_name=\"openhermes\"\n", + ") # Change llm_name if you want to use a different LLM with dynamic routes.\n", + "rl = RouteLayer(encoder=encoder, routes=routes, llm=llm)" ] }, { @@ -303,15 +305,15 @@ "\n", "def get_time(timezone: str) -> str:\n", " \"\"\"\n", - "Finds the current time in a specific timezone.\n", + " Finds the current time in a specific timezone.\n", "\n", - ":param timezone: The timezone to find the current time in, should\n", - " be a valid timezone from the IANA Time Zone Database like\n", - " \"America/New_York\" or \"Europe/London\". Do NOT put the place\n", - " name itself like \"rome\", or \"new york\", you must provide\n", - " the IANA format.\n", - ":type timezone: str\n", - ":return: The current time in the specified timezone.\n", + " :param timezone: The timezone to find the current time in, should\n", + " be a valid timezone from the IANA Time Zone Database like\n", + " \"America/New_York\" or \"Europe/London\". Do NOT put the place\n", + " name itself like \"rome\", or \"new york\", you must provide\n", + " the IANA format.\n", + " :type timezone: str\n", + " :return: The current time in the specified timezone.\n", " \"\"\"\n", " now = datetime.now(ZoneInfo(timezone))\n", " return now.strftime(\"%H:%M\")" @@ -449,7 +451,6 @@ } ], "source": [ - "\n", "get_time(**out.function_call)" ] }, diff --git a/docs/examples/rolling-window-splitter.ipynb b/docs/examples/rolling-window-splitter.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..b94d3a5615ec9b2edda91da90a481be235829bef --- /dev/null +++ b/docs/examples/rolling-window-splitter.ipynb @@ -0,0 +1,193 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "text = \"\"\"\n", + "In a recent surge of social media discussions on Weibo, Chinese netizens have been engaging in conversations about the struggles and challenges of earning money. The online debate sparked a wave of opinions and perspectives on the relationship between hard work, high pay, and finding contentment. Among the tweets, several users pontificated that one should avoid earning \"too much hard-earned money.\"\n", + "The tweets and discussions revolve around the idea that working too hard for one's income can have a detrimental effect on one's life, both physically and mentally. Some users advocate for finding opportunities that align with one's strengths and passions, rather than simply focusing on high-paying jobs that may require excessive hours and intense labor.\n", + "One Weibo user pontificates, \"Don't earn that much hard-earned money,\" a sentiment echoed by others with tweets such as, \"Why is it that when earning money, that process always has to be so tough?\" This question is followed by a comparison between two types of people - those who are used to earning money the hard way and those who seem to effortlessly obtain wealth. While the former group is depicted as having been taught to suffer from a young age, the latter is shown as being able to focus solely on their natural talents and thriving in their niche advantageously.\n", + "Discussions on the platform draw attention to a variety of issues that those who earn money the hard way might face. For example, they are described as likely having to work overtime, forgo time off for illness or rest, and maintain an unyielding dedication to their occupation, which often results in a never-ending cycle of work without any perceived progression in their lives.\n", + "Another tweet that captures this sentiment reads, \"Drowning in more work and poverty despite trying harder and harder,\" pointing to a sense of despair and dissatisfaction that comes with work that is both disproportionately demanding and inadequately rewarding. Critics also note how the pursuit of hard-earned money could potentially create physical and mental health risks due to the unrelenting pressure and stress that these jobs might impose.\n", + "Conversely, those in favor of earning money with less difficulty contend that it's crucial to harness one's strengths and passions to create opportunities that yield financial success without the need for excessive labor. The debate revolves around the concept that people should seek out ways to work smarter, not harder, especially if it means a healthier and more fulfilling lifestyle.\n", + "In fact, the notion of a \"vicious cycle,\" often attributed to those chasing hard-earned money, is juxtaposed with an idealized image of someone operating in their zone of excellence. Confidently focused on their strengths, such individuals are depicted as enjoying a more relaxed and less stressful work environment, one in which they can thrive without the need for never-ending overtime or self-sacrifice.\n", + "Some tweets even extend this sentiment to the broader socio-economic context, observing how wealth is not merely derived from manual labor or high-paying positions requiring extraordinary work hours. The tweets emphasize the importance of cultivating an entrepreneurial spirit and a penchant for innovative thinking, especially in the modern digital age.\n", + "One user writes, \"Too hard-earned money isn't worth it. Learn how to make money using your brain, not your body,\" while another suggests, \"Love will flow towards those who are not lacking in love, and money will flow towards those who are not lacking in money!\"\n", + "While some of the discussions take a somewhat passive-aggressive view, others acknowledge that financial security and comfort might not always be possible for everyone. In a more realistic tone, a user remarks, \"If life were so easy that diligence led to wealth, then the world's richest person would be the best worker bee. But that's not the case.\" This acknowledgment underscores the complexities of the economy and the role that factors like luck, connections, and a rapidly evolving job market can play in financial success.\n", + "Some users are quick to criticize the notion that earning money the hard way should be avoided, with one tweet expressing, \"The person who advises you to avoid hard-earned money is likely a scammer who profits off providing emotional value in exchange for exploitation.\" Others argue that while it's essential to find enjoyment and fulfillment in one's work, it's crucial not to shun or belittle those who choose to work in physically demanding or high-paying industries.\n", + "Overall, the Weibo discussions offer a fascinating insight into the complexities of the modern Chinese labor market and the work-life balance that people strive to achieve. As in many countries, striking the right balance between work and play is an ongoing challenge for many Chinese citizens. However, the conversations on Weibo signal an increasing awareness of the importance of finding meaningful, fulfilling, and financially rewarding work that doesn't necessitate excessive sacrifice or sufferance.\n", + "In the end, as one user succinctly puts it, \"Make sure you're earning your money in a way that brings you joy and satisfaction. That's the only way to ensure that your life doesn't become a never-ending cycle of hard work without any tangible progress.\"\n", + "In this context, social media discussions focusing on the trials and tribulations of earning money serve not only as an outlet for venting frustrations but also as a means of promoting dialogue and shared understanding about the challenges faced by workers across all industries. These virtual conversations sparked by tweets and in-depth discussions likely resonate with a wide swath of Chinese citizens struggling to navigate the complexities of balancing a career that pays well with one that brings them joy, fulfillment, and a sense of purpose.\n", + "As the discussions on Weibo continue to evolve and unfold, it is evident that the discourse around work, money, and life satisfaction holds the potential to inspire meaningful change and shift societal attitudes towards a more holistic, balanced, and humane understanding of success and prosperity.\n", + "---\n", + "Note: The translated tweets and user quotes from Chinese to English were used as the foundation for the long-form news article. The author tried to maintain the integrity of the original content in the translation while adapting it to fit a journalistic format. No inaccuracies were introduced during translation, and the opinion-based nature of the original content was preserved while maintaining objectivity.\n", + "Heart count: 0/2\n", + "Note: The author did not include any Chinese characters in the final response.\n", + "Collapse\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jamesbriggs/opt/anaconda3/envs/decision-layer/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + } + ], + "source": [ + "import os\n", + "from getpass import getpass\n", + "from semantic_router.splitters import RollingWindowSplitter\n", + "from semantic_router.encoders import OpenAIEncoder\n", + "\n", + "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n", + " \"Enter your OpenAI API key: \"\n", + ")\n", + "\n", + "splitter = RollingWindowSplitter(\n", + " encoder=OpenAIEncoder(),\n", + " min_split_tokens=50,\n", + " max_split_tokens=300,\n", + " window_size=5, # sentences\n", + " plot_splits=True,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[33m2024-02-23 08:44:26 WARNING semantic_router.utils.logger Single document exceeds the maximum token limit of 300. Splitting to sentences before semantically splitting.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 0: Trying threshold: 0.8881277932028191\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 0: Median tokens per split: 24.0\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 0: Adjusting high to 0.8781277932028191\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 1: Trying threshold: 0.8687934834140205\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 1: Median tokens per split: 34.5\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 1: Adjusting high to 0.8587934834140205\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Final optimal threshold: 0.8687934834140205\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 218 tokens due to threshold 0.8687934834140205.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 262 tokens due to exceeding token limit of 300.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 137 tokens due to threshold 0.8687934834140205.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 249 tokens due to threshold 0.8687934834140205.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 117 tokens due to threshold 0.8687934834140205.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 171 tokens due to threshold 0.8687934834140205.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 72 tokens due to threshold 0.8687934834140205.\u001b[0m\n", + "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Final split added with 23 tokens due to remaining documents.\u001b[0m\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "<Figure size 1200x600 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "splits = splitter([text])" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Split 1, tokens 218, triggered by: 0.85\n", + "\u001b[31mIn a recent surge of social media discussions on Weibo, Chinese netizens have been engaging in conversations about the struggles and challenges of earning money. The online debate sparked a wave of opinions and perspectives on the relationship between hard work, high pay, and finding contentment. Among the tweets, several users pontificated that one should avoid earning \"too much hard-earned money.\" The tweets and discussions revolve around the idea that working too hard for one's income can have a detrimental effect on one's life, both physically and mentally. Some users advocate for finding opportunities that align with one's strengths and passions, rather than simply focusing on high-paying jobs that may require excessive hours and intense labor. One Weibo user pontificates, \"Don't earn that much hard-earned money,\" a sentiment echoed by others with tweets such as, \"Why is it that when earning money, that process always has to be so tough?\" This question is followed by a comparison between two types of people - those who are used to earning money the hard way and those who seem to effortlessly obtain wealth.\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n", + "Split 2, tokens 262, triggered by: token limit\n", + "\u001b[32mWhile the former group is depicted as having been taught to suffer from a young age, the latter is shown as being able to focus solely on their natural talents and thriving in their niche advantageously. Discussions on the platform draw attention to a variety of issues that those who earn money the hard way might face. For example, they are described as likely having to work overtime, forgo time off for illness or rest, and maintain an unyielding dedication to their occupation, which often results in a never-ending cycle of work without any perceived progression in their lives. Another tweet that captures this sentiment reads, \"Drowning in more work and poverty despite trying harder and harder,\" pointing to a sense of despair and dissatisfaction that comes with work that is both disproportionately demanding and inadequately rewarding. Critics also note how the pursuit of hard-earned money could potentially create physical and mental health risks due to the unrelenting pressure and stress that these jobs might impose. Conversely, those in favor of earning money with less difficulty contend that it's crucial to harness one's strengths and passions to create opportunities that yield financial success without the need for excessive labor. The debate revolves around the concept that people should seek out ways to work smarter, not harder, especially if it means a healthier and more fulfilling lifestyle.\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n", + "Split 3, tokens 137, triggered by: 0.85\n", + "\u001b[34mIn fact, the notion of a \"vicious cycle,\" often attributed to those chasing hard-earned money, is juxtaposed with an idealized image of someone operating in their zone of excellence. Confidently focused on their strengths, such individuals are depicted as enjoying a more relaxed and less stressful work environment, one in which they can thrive without the need for never-ending overtime or self-sacrifice. Some tweets even extend this sentiment to the broader socio-economic context, observing how wealth is not merely derived from manual labor or high-paying positions requiring extraordinary work hours. The tweets emphasize the importance of cultivating an entrepreneurial spirit and a penchant for innovative thinking, especially in the modern digital age.\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n", + "Split 4, tokens 249, triggered by: 0.86\n", + "\u001b[35mOne user writes, \"Too hard-earned money isn't worth it. Learn how to make money using your brain, not your body,\" while another suggests, \"Love will flow towards those who are not lacking in love, and money will flow towards those who are not lacking in money!\" While some of the discussions take a somewhat passive-aggressive view, others acknowledge that financial security and comfort might not always be possible for everyone. In a more realistic tone, a user remarks, \"If life were so easy that diligence led to wealth, then the world's richest person would be the best worker bee. But that's not the case.\" This acknowledgment underscores the complexities of the economy and the role that factors like luck, connections, and a rapidly evolving job market can play in financial success. Some users are quick to criticize the notion that earning money the hard way should be avoided, with one tweet expressing, \"The person who advises you to avoid hard-earned money is likely a scammer who profits off providing emotional value in exchange for exploitation.\" Others argue that while it's essential to find enjoyment and fulfillment in one's work, it's crucial not to shun or belittle those who choose to work in physically demanding or high-paying industries.\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n", + "Split 5, tokens 117, triggered by: 0.87\n", + "\u001b[31mOverall, the Weibo discussions offer a fascinating insight into the complexities of the modern Chinese labor market and the work-life balance that people strive to achieve. As in many countries, striking the right balance between work and play is an ongoing challenge for many Chinese citizens. However, the conversations on Weibo signal an increasing awareness of the importance of finding meaningful, fulfilling, and financially rewarding work that doesn't necessitate excessive sacrifice or sufferance. In the end, as one user succinctly puts it, \"Make sure you're earning your money in a way that brings you joy and satisfaction.\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n", + "Split 6, tokens 171, triggered by: 0.82\n", + "\u001b[32mThat's the only way to ensure that your life doesn't become a never-ending cycle of hard work without any tangible progress.\" In this context, social media discussions focusing on the trials and tribulations of earning money serve not only as an outlet for venting frustrations but also as a means of promoting dialogue and shared understanding about the challenges faced by workers across all industries. These virtual conversations sparked by tweets and in-depth discussions likely resonate with a wide swath of Chinese citizens struggling to navigate the complexities of balancing a career that pays well with one that brings them joy, fulfillment, and a sense of purpose. As the discussions on Weibo continue to evolve and unfold, it is evident that the discourse around work, money, and life satisfaction holds the potential to inspire meaningful change and shift societal attitudes towards a more holistic, balanced, and humane understanding of success and prosperity.\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n", + "Split 7, tokens 72, triggered by: 0.80\n", + "\u001b[34m--- Note: The translated tweets and user quotes from Chinese to English were used as the foundation for the long-form news article. The author tried to maintain the integrity of the original content in the translation while adapting it to fit a journalistic format. No inaccuracies were introduced during translation, and the opinion-based nature of the original content was preserved while maintaining objectivity.\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n", + "Split 8, tokens 23, triggered by: final split\n", + "\u001b[35mHeart count: 0/2 Note: The author did not include any Chinese characters in the final response. Collapse\u001b[0m\n", + "----------------------------------------------------------------------------------------\n", + "\n", + "\n" + ] + } + ], + "source": [ + "splitter.print(splits)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/poetry.lock b/poetry.lock index 1f68d5a7e70ac6c73db6fe986666a264df5417fe..fff4911a18d411f8d16f02740c7becdf57f58d02 100644 --- a/poetry.lock +++ b/poetry.lock @@ -123,13 +123,13 @@ files = [ [[package]] name = "anyio" -version = "4.2.0" +version = "4.3.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, - {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, + {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, + {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, ] [package.dependencies] @@ -449,13 +449,13 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "cohere" -version = "4.47" +version = "4.49" description = "Python SDK for the Cohere API" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "cohere-4.47-py3-none-any.whl", hash = "sha256:8b96a1ab57713eceffb4ffd58bf647055676fb741a4e5153c14296f9814c77fa"}, - {file = "cohere-4.47.tar.gz", hash = "sha256:d689212079c1a545bd497b143cff7aa5632831fa6cf41bf7acc93b4a6effb839"}, + {file = "cohere-4.49-py3-none-any.whl", hash = "sha256:145fdf55e44c50bc69d892d124cf47534686a30e3d83bd94c350513196d19def"}, + {file = "cohere-4.49.tar.gz", hash = "sha256:509e81c44f8e1b4eb31b27d8ea388e79e04c5bee8308ac1a337a6053dd3f5a87"}, ] [package.dependencies] @@ -528,65 +528,128 @@ traitlets = ">=4" [package.extras] test = ["pytest"] +[[package]] +name = "contourpy" +version = "1.2.0" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = true +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0274c1cb63625972c0c007ab14dd9ba9e199c36ae1a231ce45d725cbcbfd10a8"}, + {file = "contourpy-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab459a1cbbf18e8698399c595a01f6dcc5c138220ca3ea9e7e6126232d102bb4"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fdd887f17c2f4572ce548461e4f96396681212d858cae7bd52ba3310bc6f00f"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d16edfc3fc09968e09ddffada434b3bf989bf4911535e04eada58469873e28e"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c203f617abc0dde5792beb586f827021069fb6d403d7f4d5c2b543d87edceb9"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b69303ceb2e4d4f146bf82fda78891ef7bcd80c41bf16bfca3d0d7eb545448aa"}, + {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:884c3f9d42d7218304bc74a8a7693d172685c84bd7ab2bab1ee567b769696df9"}, + {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1b1208102be6e851f20066bf0e7a96b7d48a07c9b0cfe6d0d4545c2f6cadab"}, + {file = "contourpy-1.2.0-cp310-cp310-win32.whl", hash = "sha256:34b9071c040d6fe45d9826cbbe3727d20d83f1b6110d219b83eb0e2a01d79488"}, + {file = "contourpy-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:bd2f1ae63998da104f16a8b788f685e55d65760cd1929518fd94cd682bf03e41"}, + {file = "contourpy-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd10c26b4eadae44783c45ad6655220426f971c61d9b239e6f7b16d5cdaaa727"}, + {file = "contourpy-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5c6b28956b7b232ae801406e529ad7b350d3f09a4fde958dfdf3c0520cdde0dd"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebeac59e9e1eb4b84940d076d9f9a6cec0064e241818bcb6e32124cc5c3e377a"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139d8d2e1c1dd52d78682f505e980f592ba53c9f73bd6be102233e358b401063"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e9dc350fb4c58adc64df3e0703ab076f60aac06e67d48b3848c23647ae4310e"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18fc2b4ed8e4a8fe849d18dce4bd3c7ea637758c6343a1f2bae1e9bd4c9f4686"}, + {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:16a7380e943a6d52472096cb7ad5264ecee36ed60888e2a3d3814991a0107286"}, + {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d8faf05be5ec8e02a4d86f616fc2a0322ff4a4ce26c0f09d9f7fb5330a35c95"}, + {file = "contourpy-1.2.0-cp311-cp311-win32.whl", hash = "sha256:67b7f17679fa62ec82b7e3e611c43a016b887bd64fb933b3ae8638583006c6d6"}, + {file = "contourpy-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:99ad97258985328b4f207a5e777c1b44a83bfe7cf1f87b99f9c11d4ee477c4de"}, + {file = "contourpy-1.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:575bcaf957a25d1194903a10bc9f316c136c19f24e0985a2b9b5608bdf5dbfe0"}, + {file = "contourpy-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9e6c93b5b2dbcedad20a2f18ec22cae47da0d705d454308063421a3b290d9ea4"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:464b423bc2a009088f19bdf1f232299e8b6917963e2b7e1d277da5041f33a779"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68ce4788b7d93e47f84edd3f1f95acdcd142ae60bc0e5493bfd120683d2d4316"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7d1f8871998cdff5d2ff6a087e5e1780139abe2838e85b0b46b7ae6cc25399"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e739530c662a8d6d42c37c2ed52a6f0932c2d4a3e8c1f90692ad0ce1274abe0"}, + {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:247b9d16535acaa766d03037d8e8fb20866d054d3c7fbf6fd1f993f11fc60ca0"}, + {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:461e3ae84cd90b30f8d533f07d87c00379644205b1d33a5ea03381edc4b69431"}, + {file = "contourpy-1.2.0-cp312-cp312-win32.whl", hash = "sha256:1c2559d6cffc94890b0529ea7eeecc20d6fadc1539273aa27faf503eb4656d8f"}, + {file = "contourpy-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:491b1917afdd8638a05b611a56d46587d5a632cabead889a5440f7c638bc6ed9"}, + {file = "contourpy-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5fd1810973a375ca0e097dee059c407913ba35723b111df75671a1976efa04bc"}, + {file = "contourpy-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:999c71939aad2780f003979b25ac5b8f2df651dac7b38fb8ce6c46ba5abe6ae9"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7caf9b241464c404613512d5594a6e2ff0cc9cb5615c9475cc1d9b514218ae8"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:266270c6f6608340f6c9836a0fb9b367be61dde0c9a9a18d5ece97774105ff3e"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbd50d0a0539ae2e96e537553aff6d02c10ed165ef40c65b0e27e744a0f10af8"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11f8d2554e52f459918f7b8e6aa20ec2a3bce35ce95c1f0ef4ba36fbda306df5"}, + {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ce96dd400486e80ac7d195b2d800b03e3e6a787e2a522bfb83755938465a819e"}, + {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d3364b999c62f539cd403f8123ae426da946e142312a514162adb2addd8d808"}, + {file = "contourpy-1.2.0-cp39-cp39-win32.whl", hash = "sha256:1c88dfb9e0c77612febebb6ac69d44a8d81e3dc60f993215425b62c1161353f4"}, + {file = "contourpy-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:78e6ad33cf2e2e80c5dfaaa0beec3d61face0fb650557100ee36db808bfa6843"}, + {file = "contourpy-1.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be16975d94c320432657ad2402f6760990cb640c161ae6da1363051805fa8108"}, + {file = "contourpy-1.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b95a225d4948b26a28c08307a60ac00fb8671b14f2047fc5476613252a129776"}, + {file = "contourpy-1.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0d7e03c0f9a4f90dc18d4e77e9ef4ec7b7bbb437f7f675be8e530d65ae6ef956"}, + {file = "contourpy-1.2.0.tar.gz", hash = "sha256:171f311cb758de7da13fc53af221ae47a5877be5a0843a9fe150818c51ed276a"}, +] + +[package.dependencies] +numpy = ">=1.20,<2.0" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.6.1)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] + [[package]] name = "coverage" -version = "7.4.1" +version = "7.4.2" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"}, - {file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"}, - {file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"}, - {file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"}, - {file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"}, - {file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"}, - {file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"}, - {file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"}, - {file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"}, - {file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"}, - {file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"}, - {file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"}, - {file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"}, - {file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"}, - {file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"}, - {file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"}, - {file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"}, - {file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"}, - {file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"}, - {file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"}, - {file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"}, - {file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"}, + {file = "coverage-7.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf54c3e089179d9d23900e3efc86d46e4431188d9a657f345410eecdd0151f50"}, + {file = "coverage-7.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fe6e43c8b510719b48af7db9631b5fbac910ade4bd90e6378c85ac5ac706382c"}, + {file = "coverage-7.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b98c89db1b150d851a7840142d60d01d07677a18f0f46836e691c38134ed18b"}, + {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5f9683be6a5b19cd776ee4e2f2ffb411424819c69afab6b2db3a0a364ec6642"}, + {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78cdcbf7b9cb83fe047ee09298e25b1cd1636824067166dc97ad0543b079d22f"}, + {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2599972b21911111114100d362aea9e70a88b258400672626efa2b9e2179609c"}, + {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ef00d31b7569ed3cb2036f26565f1984b9fc08541731ce01012b02a4c238bf03"}, + {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:20a875bfd8c282985c4720c32aa05056f77a68e6d8bbc5fe8632c5860ee0b49b"}, + {file = "coverage-7.4.2-cp310-cp310-win32.whl", hash = "sha256:b3f2b1eb229f23c82898eedfc3296137cf1f16bb145ceab3edfd17cbde273fb7"}, + {file = "coverage-7.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7df95fdd1432a5d2675ce630fef5f239939e2b3610fe2f2b5bf21fa505256fa3"}, + {file = "coverage-7.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8ddbd158e069dded57738ea69b9744525181e99974c899b39f75b2b29a624e2"}, + {file = "coverage-7.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81a5fb41b0d24447a47543b749adc34d45a2cf77b48ca74e5bf3de60a7bd9edc"}, + {file = "coverage-7.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2412e98e70f16243be41d20836abd5f3f32edef07cbf8f407f1b6e1ceae783ac"}, + {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb79414c15c6f03f56cc68fa06994f047cf20207c31b5dad3f6bab54a0f66ef"}, + {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf89ab85027427d351f1de918aff4b43f4eb5f33aff6835ed30322a86ac29c9e"}, + {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a178b7b1ac0f1530bb28d2e51f88c0bab3e5949835851a60dda80bff6052510c"}, + {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:06fe398145a2e91edaf1ab4eee66149c6776c6b25b136f4a86fcbbb09512fd10"}, + {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:18cac867950943fe93d6cd56a67eb7dcd2d4a781a40f4c1e25d6f1ed98721a55"}, + {file = "coverage-7.4.2-cp311-cp311-win32.whl", hash = "sha256:f72cdd2586f9a769570d4b5714a3837b3a59a53b096bb954f1811f6a0afad305"}, + {file = "coverage-7.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:d779a48fac416387dd5673fc5b2d6bd903ed903faaa3247dc1865c65eaa5a93e"}, + {file = "coverage-7.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:adbdfcda2469d188d79771d5696dc54fab98a16d2ef7e0875013b5f56a251047"}, + {file = "coverage-7.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ac4bab32f396b03ebecfcf2971668da9275b3bb5f81b3b6ba96622f4ef3f6e17"}, + {file = "coverage-7.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:006d220ba2e1a45f1de083d5022d4955abb0aedd78904cd5a779b955b019ec73"}, + {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3733545eb294e5ad274abe131d1e7e7de4ba17a144505c12feca48803fea5f64"}, + {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42a9e754aa250fe61f0f99986399cec086d7e7a01dd82fd863a20af34cbce962"}, + {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2ed37e16cf35c8d6e0b430254574b8edd242a367a1b1531bd1adc99c6a5e00fe"}, + {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b953275d4edfab6cc0ed7139fa773dfb89e81fee1569a932f6020ce7c6da0e8f"}, + {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32b4ab7e6c924f945cbae5392832e93e4ceb81483fd6dc4aa8fb1a97b9d3e0e1"}, + {file = "coverage-7.4.2-cp312-cp312-win32.whl", hash = "sha256:f5df76c58977bc35a49515b2fbba84a1d952ff0ec784a4070334dfbec28a2def"}, + {file = "coverage-7.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:34423abbaad70fea9d0164add189eabaea679068ebdf693baa5c02d03e7db244"}, + {file = "coverage-7.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b11f9c6587668e495cc7365f85c93bed34c3a81f9f08b0920b87a89acc13469"}, + {file = "coverage-7.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:51593a1f05c39332f623d64d910445fdec3d2ac2d96b37ce7f331882d5678ddf"}, + {file = "coverage-7.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69f1665165ba2fe7614e2f0c1aed71e14d83510bf67e2ee13df467d1c08bf1e8"}, + {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3c8bbb95a699c80a167478478efe5e09ad31680931ec280bf2087905e3b95ec"}, + {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:175f56572f25e1e1201d2b3e07b71ca4d201bf0b9cb8fad3f1dfae6a4188de86"}, + {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8562ca91e8c40864942615b1d0b12289d3e745e6b2da901d133f52f2d510a1e3"}, + {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d9a1ef0f173e1a19738f154fb3644f90d0ada56fe6c9b422f992b04266c55d5a"}, + {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f40ac873045db4fd98a6f40387d242bde2708a3f8167bd967ccd43ad46394ba2"}, + {file = "coverage-7.4.2-cp38-cp38-win32.whl", hash = "sha256:d1b750a8409bec61caa7824bfd64a8074b6d2d420433f64c161a8335796c7c6b"}, + {file = "coverage-7.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b4ae777bebaed89e3a7e80c4a03fac434a98a8abb5251b2a957d38fe3fd30088"}, + {file = "coverage-7.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ff7f92ae5a456101ca8f48387fd3c56eb96353588e686286f50633a611afc95"}, + {file = "coverage-7.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:861d75402269ffda0b33af94694b8e0703563116b04c681b1832903fac8fd647"}, + {file = "coverage-7.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3507427d83fa961cbd73f11140f4a5ce84208d31756f7238d6257b2d3d868405"}, + {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf711d517e21fb5bc429f5c4308fbc430a8585ff2a43e88540264ae87871e36a"}, + {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c00e54f0bd258ab25e7f731ca1d5144b0bf7bec0051abccd2bdcff65fa3262c9"}, + {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f8e845d894e39fb53834da826078f6dc1a933b32b1478cf437007367efaf6f6a"}, + {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:840456cb1067dc350af9080298c7c2cfdddcedc1cb1e0b30dceecdaf7be1a2d3"}, + {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c11ca2df2206a4e3e4c4567f52594637392ed05d7c7fb73b4ea1c658ba560265"}, + {file = "coverage-7.4.2-cp39-cp39-win32.whl", hash = "sha256:3ff5bdb08d8938d336ce4088ca1a1e4b6c8cd3bef8bb3a4c0eb2f37406e49643"}, + {file = "coverage-7.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:ac9e95cefcf044c98d4e2c829cd0669918585755dd9a92e28a1a7012322d0a95"}, + {file = "coverage-7.4.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:f593a4a90118d99014517c2679e04a4ef5aee2d81aa05c26c734d271065efcb6"}, + {file = "coverage-7.4.2.tar.gz", hash = "sha256:1a5ee18e3a8d766075ce9314ed1cb695414bae67df6a4b0805f5137d93d6f1cb"}, ] [package.dependencies] @@ -595,6 +658,21 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = true +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "debugpy" version = "1.8.1" @@ -793,6 +871,71 @@ files = [ {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"}, ] +[[package]] +name = "fonttools" +version = "4.49.0" +description = "Tools to manipulate font files" +optional = true +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d970ecca0aac90d399e458f0b7a8a597e08f95de021f17785fb68e2dc0b99717"}, + {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac9a745b7609f489faa65e1dc842168c18530874a5f5b742ac3dd79e26bca8bc"}, + {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ba0e00620ca28d4ca11fc700806fd69144b463aa3275e1b36e56c7c09915559"}, + {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdee3ab220283057e7840d5fb768ad4c2ebe65bdba6f75d5d7bf47f4e0ed7d29"}, + {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ce7033cb61f2bb65d8849658d3786188afd80f53dad8366a7232654804529532"}, + {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:07bc5ea02bb7bc3aa40a1eb0481ce20e8d9b9642a9536cde0218290dd6085828"}, + {file = "fonttools-4.49.0-cp310-cp310-win32.whl", hash = "sha256:86eef6aab7fd7c6c8545f3ebd00fd1d6729ca1f63b0cb4d621bccb7d1d1c852b"}, + {file = "fonttools-4.49.0-cp310-cp310-win_amd64.whl", hash = "sha256:1fac1b7eebfce75ea663e860e7c5b4a8831b858c17acd68263bc156125201abf"}, + {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:edc0cce355984bb3c1d1e89d6a661934d39586bb32191ebff98c600f8957c63e"}, + {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:83a0d9336de2cba86d886507dd6e0153df333ac787377325a39a2797ec529814"}, + {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36c8865bdb5cfeec88f5028e7e592370a0657b676c6f1d84a2108e0564f90e22"}, + {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33037d9e56e2562c710c8954d0f20d25b8386b397250d65581e544edc9d6b942"}, + {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8fb022d799b96df3eaa27263e9eea306bd3d437cc9aa981820850281a02b6c9a"}, + {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33c584c0ef7dc54f5dd4f84082eabd8d09d1871a3d8ca2986b0c0c98165f8e86"}, + {file = "fonttools-4.49.0-cp311-cp311-win32.whl", hash = "sha256:cbe61b158deb09cffdd8540dc4a948d6e8f4d5b4f3bf5cd7db09bd6a61fee64e"}, + {file = "fonttools-4.49.0-cp311-cp311-win_amd64.whl", hash = "sha256:fc11e5114f3f978d0cea7e9853627935b30d451742eeb4239a81a677bdee6bf6"}, + {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d647a0e697e5daa98c87993726da8281c7233d9d4ffe410812a4896c7c57c075"}, + {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f3bbe672df03563d1f3a691ae531f2e31f84061724c319652039e5a70927167e"}, + {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bebd91041dda0d511b0d303180ed36e31f4f54b106b1259b69fade68413aa7ff"}, + {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4145f91531fd43c50f9eb893faa08399816bb0b13c425667c48475c9f3a2b9b5"}, + {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ea329dafb9670ffbdf4dbc3b0e5c264104abcd8441d56de77f06967f032943cb"}, + {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c076a9e548521ecc13d944b1d261ff3d7825048c338722a4bd126d22316087b7"}, + {file = "fonttools-4.49.0-cp312-cp312-win32.whl", hash = "sha256:b607ea1e96768d13be26d2b400d10d3ebd1456343eb5eaddd2f47d1c4bd00880"}, + {file = "fonttools-4.49.0-cp312-cp312-win_amd64.whl", hash = "sha256:a974c49a981e187381b9cc2c07c6b902d0079b88ff01aed34695ec5360767034"}, + {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b85ec0bdd7bdaa5c1946398cbb541e90a6dfc51df76dfa88e0aaa41b335940cb"}, + {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:af20acbe198a8a790618ee42db192eb128afcdcc4e96d99993aca0b60d1faeb4"}, + {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d418b1fee41a1d14931f7ab4b92dc0bc323b490e41d7a333eec82c9f1780c75"}, + {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b44a52b8e6244b6548851b03b2b377a9702b88ddc21dcaf56a15a0393d425cb9"}, + {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7c7125068e04a70739dad11857a4d47626f2b0bd54de39e8622e89701836eabd"}, + {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29e89d0e1a7f18bc30f197cfadcbef5a13d99806447c7e245f5667579a808036"}, + {file = "fonttools-4.49.0-cp38-cp38-win32.whl", hash = "sha256:9d95fa0d22bf4f12d2fb7b07a46070cdfc19ef5a7b1c98bc172bfab5bf0d6844"}, + {file = "fonttools-4.49.0-cp38-cp38-win_amd64.whl", hash = "sha256:768947008b4dc552d02772e5ebd49e71430a466e2373008ce905f953afea755a"}, + {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:08877e355d3dde1c11973bb58d4acad1981e6d1140711230a4bfb40b2b937ccc"}, + {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fdb54b076f25d6b0f0298dc706acee5052de20c83530fa165b60d1f2e9cbe3cb"}, + {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0af65c720520710cc01c293f9c70bd69684365c6015cc3671db2b7d807fe51f2"}, + {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f255ce8ed7556658f6d23f6afd22a6d9bbc3edb9b96c96682124dc487e1bf42"}, + {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d00af0884c0e65f60dfaf9340e26658836b935052fdd0439952ae42e44fdd2be"}, + {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:263832fae27481d48dfafcc43174644b6706639661e242902ceb30553557e16c"}, + {file = "fonttools-4.49.0-cp39-cp39-win32.whl", hash = "sha256:0404faea044577a01bb82d47a8fa4bc7a54067fa7e324785dd65d200d6dd1133"}, + {file = "fonttools-4.49.0-cp39-cp39-win_amd64.whl", hash = "sha256:b050d362df50fc6e38ae3954d8c29bf2da52be384649ee8245fdb5186b620836"}, + {file = "fonttools-4.49.0-py3-none-any.whl", hash = "sha256:af281525e5dd7fa0b39fb1667b8d5ca0e2a9079967e14c4bfe90fd1cd13e0f18"}, + {file = "fonttools-4.49.0.tar.gz", hash = "sha256:ebf46e7f01b7af7861310417d7c49591a85d99146fc23a5ba82fdb28af156321"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + [[package]] name = "frozenlist" version = "1.4.1" @@ -927,13 +1070,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.3" +version = "1.0.4" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.3-py3-none-any.whl", hash = "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2"}, - {file = "httpcore-1.0.3.tar.gz", hash = "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544"}, + {file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"}, + {file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"}, ] [package.dependencies] @@ -944,7 +1087,7 @@ h11 = ">=0.13,<0.15" asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.24.0)"] +trio = ["trio (>=0.22.0,<0.25.0)"] [[package]] name = "httpx" @@ -1047,6 +1190,24 @@ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.link 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.1.1" +description = "Read resources from Python packages" +optional = true +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, + {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, +] + +[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 (<7.2.5)", "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", "zipp (>=3.17)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -1218,14 +1379,127 @@ traitlets = ">=5.3" 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 = "kiwisolver" +version = "1.4.5" +description = "A fast implementation of the Cassowary constraint solver" +optional = true +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, +] + [[package]] name = "llama-cpp-python" -version = "0.2.44" +version = "0.2.48" description = "Python bindings for the llama.cpp library" optional = true python-versions = ">=3.8" files = [ - {file = "llama_cpp_python-0.2.44.tar.gz", hash = "sha256:afe0e93548d4ba75f20bc754039907594738a6381c9f4602922bcc8a418b2039"}, + {file = "llama_cpp_python-0.2.48.tar.gz", hash = "sha256:37294f14c3b8157334beb8c9b6d92087f2c9d82730d733e6fc4fc15034271dd8"}, ] [package.dependencies] @@ -1309,6 +1583,55 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "matplotlib" +version = "3.8.3" +description = "Python plotting package" +optional = true +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.8.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cf60138ccc8004f117ab2a2bad513cc4d122e55864b4fe7adf4db20ca68a078f"}, + {file = "matplotlib-3.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f557156f7116be3340cdeef7f128fa99b0d5d287d5f41a16e169819dcf22357"}, + {file = "matplotlib-3.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f386cf162b059809ecfac3bcc491a9ea17da69fa35c8ded8ad154cd4b933d5ec"}, + {file = "matplotlib-3.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3c5f96f57b0369c288bf6f9b5274ba45787f7e0589a34d24bdbaf6d3344632f"}, + {file = "matplotlib-3.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:83e0f72e2c116ca7e571c57aa29b0fe697d4c6425c4e87c6e994159e0c008635"}, + {file = "matplotlib-3.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:1c5c8290074ba31a41db1dc332dc2b62def469ff33766cbe325d32a3ee291aea"}, + {file = "matplotlib-3.8.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5184e07c7e1d6d1481862ee361905b7059f7fe065fc837f7c3dc11eeb3f2f900"}, + {file = "matplotlib-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d7e7e0993d0758933b1a241a432b42c2db22dfa37d4108342ab4afb9557cbe3e"}, + {file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04b36ad07eac9740fc76c2aa16edf94e50b297d6eb4c081e3add863de4bb19a7"}, + {file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c42dae72a62f14982f1474f7e5c9959fc4bc70c9de11cc5244c6e766200ba65"}, + {file = "matplotlib-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf5932eee0d428192c40b7eac1399d608f5d995f975cdb9d1e6b48539a5ad8d0"}, + {file = "matplotlib-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:40321634e3a05ed02abf7c7b47a50be50b53ef3eaa3a573847431a545585b407"}, + {file = "matplotlib-3.8.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:09074f8057917d17ab52c242fdf4916f30e99959c1908958b1fc6032e2d0f6d4"}, + {file = "matplotlib-3.8.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5745f6d0fb5acfabbb2790318db03809a253096e98c91b9a31969df28ee604aa"}, + {file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97653d869a71721b639714b42d87cda4cfee0ee74b47c569e4874c7590c55c5"}, + {file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:242489efdb75b690c9c2e70bb5c6550727058c8a614e4c7716f363c27e10bba1"}, + {file = "matplotlib-3.8.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:83c0653c64b73926730bd9ea14aa0f50f202ba187c307a881673bad4985967b7"}, + {file = "matplotlib-3.8.3-cp312-cp312-win_amd64.whl", hash = "sha256:ef6c1025a570354297d6c15f7d0f296d95f88bd3850066b7f1e7b4f2f4c13a39"}, + {file = "matplotlib-3.8.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c4af3f7317f8a1009bbb2d0bf23dfaba859eb7dd4ccbd604eba146dccaaaf0a4"}, + {file = "matplotlib-3.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c6e00a65d017d26009bac6808f637b75ceade3e1ff91a138576f6b3065eeeba"}, + {file = "matplotlib-3.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7b49ab49a3bea17802df6872f8d44f664ba8f9be0632a60c99b20b6db2165b7"}, + {file = "matplotlib-3.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6728dde0a3997396b053602dbd907a9bd64ec7d5cf99e728b404083698d3ca01"}, + {file = "matplotlib-3.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:813925d08fb86aba139f2d31864928d67511f64e5945ca909ad5bc09a96189bb"}, + {file = "matplotlib-3.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:cd3a0c2be76f4e7be03d34a14d49ded6acf22ef61f88da600a18a5cd8b3c5f3c"}, + {file = "matplotlib-3.8.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fa93695d5c08544f4a0dfd0965f378e7afc410d8672816aff1e81be1f45dbf2e"}, + {file = "matplotlib-3.8.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9764df0e8778f06414b9d281a75235c1e85071f64bb5d71564b97c1306a2afc"}, + {file = "matplotlib-3.8.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5e431a09e6fab4012b01fc155db0ce6dccacdbabe8198197f523a4ef4805eb26"}, + {file = "matplotlib-3.8.3.tar.gz", hash = "sha256:7b416239e9ae38be54b028abbf9048aff5054a9aba5416bef0bd17f9162ce161"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} +kiwisolver = ">=1.3.1" +numpy = ">=1.21,<2" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + [[package]] name = "matplotlib-inline" version = "0.1.6" @@ -2399,6 +2722,20 @@ files = [ plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pyparsing" +version = "3.1.1" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = true +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pyreadline3" version = "3.4.1" @@ -2693,7 +3030,7 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} name = "regex" version = "2023.12.25" description = "Alternative regular expression module, to replace re." -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, @@ -3025,6 +3362,58 @@ files = [ [package.dependencies] mpmath = ">=0.19" +[[package]] +name = "tiktoken" +version = "0.6.0" +description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tiktoken-0.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:277de84ccd8fa12730a6b4067456e5cf72fef6300bea61d506c09e45658d41ac"}, + {file = "tiktoken-0.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c44433f658064463650d61387623735641dcc4b6c999ca30bc0f8ba3fccaf5c"}, + {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afb9a2a866ae6eef1995ab656744287a5ac95acc7e0491c33fad54d053288ad3"}, + {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62c05b3109fefca26fedb2820452a050074ad8e5ad9803f4652977778177d9f"}, + {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ef917fad0bccda07bfbad835525bbed5f3ab97a8a3e66526e48cdc3e7beacf7"}, + {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e095131ab6092d0769a2fda85aa260c7c383072daec599ba9d8b149d2a3f4d8b"}, + {file = "tiktoken-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:05b344c61779f815038292a19a0c6eb7098b63c8f865ff205abb9ea1b656030e"}, + {file = "tiktoken-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cefb9870fb55dca9e450e54dbf61f904aab9180ff6fe568b61f4db9564e78871"}, + {file = "tiktoken-0.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:702950d33d8cabc039845674107d2e6dcabbbb0990ef350f640661368df481bb"}, + {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8d49d076058f23254f2aff9af603863c5c5f9ab095bc896bceed04f8f0b013a"}, + {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:430bc4e650a2d23a789dc2cdca3b9e5e7eb3cd3935168d97d43518cbb1f9a911"}, + {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:293cb8669757301a3019a12d6770bd55bec38a4d3ee9978ddbe599d68976aca7"}, + {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7bd1a288b7903aadc054b0e16ea78e3171f70b670e7372432298c686ebf9dd47"}, + {file = "tiktoken-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac76e000183e3b749634968a45c7169b351e99936ef46f0d2353cd0d46c3118d"}, + {file = "tiktoken-0.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17cc8a4a3245ab7d935c83a2db6bb71619099d7284b884f4b2aea4c74f2f83e3"}, + {file = "tiktoken-0.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:284aebcccffe1bba0d6571651317df6a5b376ff6cfed5aeb800c55df44c78177"}, + {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c1a3a5d33846f8cd9dd3b7897c1d45722f48625a587f8e6f3d3e85080559be8"}, + {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6318b2bb2337f38ee954fd5efa82632c6e5ced1d52a671370fa4b2eff1355e91"}, + {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f5f0f2ed67ba16373f9a6013b68da298096b27cd4e1cf276d2d3868b5c7efd1"}, + {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:75af4c0b16609c2ad02581f3cdcd1fb698c7565091370bf6c0cf8624ffaba6dc"}, + {file = "tiktoken-0.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:45577faf9a9d383b8fd683e313cf6df88b6076c034f0a16da243bb1c139340c3"}, + {file = "tiktoken-0.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c1492ab90c21ca4d11cef3a236ee31a3e279bb21b3fc5b0e2210588c4209e68"}, + {file = "tiktoken-0.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e2b380c5b7751272015400b26144a2bab4066ebb8daae9c3cd2a92c3b508fe5a"}, + {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f497598b9f58c99cbc0eb764b4a92272c14d5203fc713dd650b896a03a50ad"}, + {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e65e8bd6f3f279d80f1e1fbd5f588f036b9a5fa27690b7f0cc07021f1dfa0839"}, + {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5f1495450a54e564d236769d25bfefbf77727e232d7a8a378f97acddee08c1ae"}, + {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6c4e4857d99f6fb4670e928250835b21b68c59250520a1941618b5b4194e20c3"}, + {file = "tiktoken-0.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:168d718f07a39b013032741867e789971346df8e89983fe3c0ef3fbd5a0b1cb9"}, + {file = "tiktoken-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47fdcfe11bd55376785a6aea8ad1db967db7f66ea81aed5c43fad497521819a4"}, + {file = "tiktoken-0.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb7d2ccbf1a7784810aff6b80b4012fb42c6fc37eaa68cb3b553801a5cc2d1fc"}, + {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ccb7a111ee76af5d876a729a347f8747d5ad548e1487eeea90eaf58894b3138"}, + {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2048e1086b48e3c8c6e2ceeac866561374cd57a84622fa49a6b245ffecb7744"}, + {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07f229a5eb250b6403a61200199cecf0aac4aa23c3ecc1c11c1ca002cbb8f159"}, + {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:432aa3be8436177b0db5a2b3e7cc28fd6c693f783b2f8722539ba16a867d0c6a"}, + {file = "tiktoken-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:8bfe8a19c8b5c40d121ee7938cd9c6a278e5b97dc035fd61714b4f0399d2f7a1"}, + {file = "tiktoken-0.6.0.tar.gz", hash = "sha256:ace62a4ede83c75b0374a2ddfa4b76903cf483e9cb06247f566be3bf14e6beed"}, +] + +[package.dependencies] +regex = ">=2022.1.18" +requests = ">=2.26.0" + +[package.extras] +blobfile = ["blobfile (>=2)"] + [[package]] name = "tokenizers" version = "0.15.2" @@ -3311,13 +3700,13 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "transformers" -version = "4.37.2" +version = "4.38.1" description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" optional = true python-versions = ">=3.8.0" files = [ - {file = "transformers-4.37.2-py3-none-any.whl", hash = "sha256:595a8b12a1fcc4ad0ced49ce206c58e17be68c85d7aee3d7546d04a32c910d2e"}, - {file = "transformers-4.37.2.tar.gz", hash = "sha256:f307082ae5d528b8480611a4879a4a11651012d0e9aaea3f6cf17219ffd95542"}, + {file = "transformers-4.38.1-py3-none-any.whl", hash = "sha256:a7a9265fb060183e9d975cbbadc4d531b10281589c43f6d07563f86322728973"}, + {file = "transformers-4.38.1.tar.gz", hash = "sha256:86dc84ccbe36123647e84cbd50fc31618c109a41e6be92514b064ab55bf1304c"}, ] [package.dependencies] @@ -3334,16 +3723,16 @@ tqdm = ">=4.27" [package.extras] accelerate = ["accelerate (>=0.21.0)"] -agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.11,!=1.12.0)"] -all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision"] +agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch"] +all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"] audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] codecarbon = ["codecarbon (==1.2.0)"] deepspeed = ["accelerate (>=0.21.0)", "deepspeed (>=0.9.3)"] -deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] -dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"] -dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision"] +deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] +dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"] +dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"] docs-specific = ["hf-doc-builder"] flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"] flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] @@ -3360,20 +3749,20 @@ ray = ["ray[tune] (>=2.7.0)"] retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] sagemaker = ["sagemaker (>=2.31.0)"] sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"] -serving = ["fastapi", "pydantic (<2)", "starlette", "uvicorn"] +serving = ["fastapi", "pydantic", "starlette", "uvicorn"] sigopt = ["sigopt"] sklearn = ["scikit-learn"] speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"] +testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"] tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] timm = ["timm"] tokenizers = ["tokenizers (>=0.14,<0.19)"] -torch = ["accelerate (>=0.21.0)", "torch (>=1.11,!=1.12.0)"] +torch = ["accelerate (>=0.21.0)", "torch"] torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] torch-vision = ["Pillow (>=10.0.1,<=15.0)", "torchvision"] -torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "tqdm (>=4.27)"] +torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch", "tqdm (>=4.27)"] video = ["av (==9.2.0)", "decord (==0.6.0)"] vision = ["Pillow (>=10.0.1,<=15.0)"] @@ -3599,9 +3988,10 @@ fastembed = ["fastembed"] hybrid = ["pinecone-text"] local = ["llama-cpp-python", "torch", "transformers"] pinecone = ["pinecone-client"] +processing = ["matplotlib"] vision = ["pillow", "torch", "torchvision", "transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "26f85562a59d475cc411ed0aa003cc84cd8ebc328cfafed1c74e77d0aaa544d3" +content-hash = "067185d9d8b058fbcf9bd00e3c9a0b5b3ada33cbfa7f77e81d164692d98ae22b" diff --git a/pyproject.toml b/pyproject.toml index 294ef44e7175b3563d58b7e4bc64b6170978057d..1db92298c89558bdea75590d9b3679c71fbcb149 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,8 +31,11 @@ llama-cpp-python = {version = "^0.2.28", optional = true} black = "^23.12.1" colorama = "^0.4.6" pinecone-client = {version="^3.0.0", optional = true} +regex = "^2023.12.25" torchvision = { version = "^0.16.2", optional = true} pillow = { version= "^10.2.0", optional = true} +tiktoken = "^0.6.0" +matplotlib = { version="^3.8.3", optional = true} [tool.poetry.extras] hybrid = ["pinecone-text"] @@ -40,6 +43,7 @@ fastembed = ["fastembed"] local = ["torch", "transformers", "llama-cpp-python"] pinecone = ["pinecone-client"] vision = ["torch", "torchvision", "transformers", "pillow"] +processing = ["matplotlib"] [tool.poetry.group.dev.dependencies] ipykernel = "^6.25.0" diff --git a/semantic_router/index/base.py b/semantic_router/index/base.py index 351692df71316a8d779de43de96014dff88e6a12..5271b897298af0d99efb5e6f23f87c94da4e7b12 100644 --- a/semantic_router/index/base.py +++ b/semantic_router/index/base.py @@ -37,7 +37,8 @@ class BaseIndex(BaseModel): def describe(self) -> dict: """ - Returns a dictionary with index details such as type, dimensions, and total vector count. + Returns a dictionary with index details such as type, dimensions, and total + vector count. This method should be implemented by subclasses. """ raise NotImplementedError("This method should be implemented by subclasses.") diff --git a/semantic_router/index/local.py b/semantic_router/index/local.py index e462463171bdd75d722588d9a99d2d5b338fb9f2..81da71d1d6114cb58849ec364a0fa175254020c6 100644 --- a/semantic_router/index/local.py +++ b/semantic_router/index/local.py @@ -16,7 +16,8 @@ class LocalIndex(BaseIndex): super().__init__(index=index, routes=routes, utterances=utterances) self.type = "local" - class Config: # Stop pydantic from complaining about Optional[np.ndarray] type hints. + class Config: + # Stop pydantic from complaining about Optional[np.ndarray]type hints. arbitrary_types_allowed = True def add( @@ -83,7 +84,8 @@ class LocalIndex(BaseIndex): self.utterances = np.delete(self.utterances, delete_idx, axis=0) else: raise ValueError( - "Attempted to delete route records but either index, routes or utterances is None." + "Attempted to delete route records but either index, routes or " + "utterances is None." ) def delete_index(self): diff --git a/semantic_router/index/pinecone.py b/semantic_router/index/pinecone.py index 35f7f879f1f615065fdc77c6816c67c953c6960c..886cd8065ca7b9f2e8eb19cda3658b0a4c21d9e3 100644 --- a/semantic_router/index/pinecone.py +++ b/semantic_router/index/pinecone.py @@ -23,9 +23,9 @@ class PineconeRecord(BaseModel): def __init__(self, **data): super().__init__(**data) - # generate ID based on route name and utterances to prevent duplicates clean_route = clean_route_name(self.route) - utterance_id = hashlib.md5(self.utterance.encode()).hexdigest() + # Use SHA-256 for a more secure hash + utterance_id = hashlib.sha256(self.utterance.encode()).hexdigest() self.id = f"{clean_route}#{utterance_id}" def to_dict(self): @@ -51,13 +51,8 @@ class PineconeIndex(BaseIndex): def __init__(self, **data): super().__init__(**data) self._initialize_client() - self.type = "pinecone" self.client = self._initialize_client() - if not self.index_name.startswith(self.index_prefix): - self.index_name = f"{self.index_prefix}{self.index_name}" - # Create or connect to an existing Pinecone index - self.index = self._init_index() def _initialize_client(self, api_key: Optional[str] = None): try: diff --git a/semantic_router/layer.py b/semantic_router/layer.py index 0635c1ea9beef2afb4437b2406dc421ca831fbfd..3ef16206d638a96cf9274112c61388fec0e31a03 100644 --- a/semantic_router/layer.py +++ b/semantic_router/layer.py @@ -19,7 +19,8 @@ from semantic_router.utils.logger import logger def is_valid(layer_config: str) -> bool: - """Make sure the given string is json format and contains the 3 keys: ["encoder_name", "encoder_type", "routes"]""" + """Make sure the given string is json format and contains the 3 keys: + ["encoder_name", "encoder_type", "routes"]""" try: output_json = json.loads(layer_config) required_keys = ["encoder_name", "encoder_type", "routes"] @@ -209,7 +210,8 @@ class RouteLayer: matching_routes = [route for route in self.routes if route.name == top_class] if not matching_routes: logger.error( - f"No route found with name {top_class}. Check to see if any Routes have been defined." + f"No route found with name {top_class}. Check to see if any Routes " + "have been defined." ) return None return matching_routes[0] diff --git a/semantic_router/llms/ollama.py b/semantic_router/llms/ollama.py index 1c5dfed58857310ed5fff5e55c09988d2a38b4dd..df35ac06a97748ece6a2da86fad58bb7e4a0a52f 100644 --- a/semantic_router/llms/ollama.py +++ b/semantic_router/llms/ollama.py @@ -1,4 +1,5 @@ from typing import List, Optional + import requests from semantic_router.llms import BaseLLM diff --git a/semantic_router/schema.py b/semantic_router/schema.py index 8bb5a65f6f3c0d5e315ac433cc68b55cdc25989a..8841902161f6b72b1c5ee3245b3b08e1994609eb 100644 --- a/semantic_router/schema.py +++ b/semantic_router/schema.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Any, List, Optional +from typing import List, Optional from pydantic.v1 import BaseModel from pydantic.v1.dataclasses import dataclass @@ -77,6 +77,12 @@ class Message(BaseModel): class DocumentSplit(BaseModel): - docs: List[Any] + docs: List[str] is_triggered: bool = False triggered_score: Optional[float] = None + token_count: Optional[int] = None + metadata: Optional[dict] = None + + @property + def content(self) -> str: + return " ".join(self.docs) diff --git a/semantic_router/splitters/__init__.py b/semantic_router/splitters/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..44acb9e39ef60f0db98b2b07ddafee69cffeb756 100644 --- a/semantic_router/splitters/__init__.py +++ b/semantic_router/splitters/__init__.py @@ -0,0 +1,11 @@ +from semantic_router.splitters.base import BaseSplitter +from semantic_router.splitters.consecutive_sim import ConsecutiveSimSplitter +from semantic_router.splitters.cumulative_sim import CumulativeSimSplitter +from semantic_router.splitters.rolling_window import RollingWindowSplitter + +__all__ = [ + "BaseSplitter", + "ConsecutiveSimSplitter", + "CumulativeSimSplitter", + "RollingWindowSplitter", +] diff --git a/semantic_router/splitters/base.py b/semantic_router/splitters/base.py index 7f66c8bceff2292f1193161c57d87178d07a60aa..0514e014e34e50b03a1285395591d71f67775b17 100644 --- a/semantic_router/splitters/base.py +++ b/semantic_router/splitters/base.py @@ -1,14 +1,38 @@ -from typing import Any, List +from typing import List -from pydantic.v1 import BaseModel +from colorama import Fore, Style +from pydantic.v1 import BaseModel, Extra from semantic_router.encoders import BaseEncoder +from semantic_router.schema import DocumentSplit class BaseSplitter(BaseModel): name: str encoder: BaseEncoder - score_threshold: float - def __call__(self, docs: List[Any]) -> List[List[float]]: + class Config: + extra = Extra.allow + + def __call__(self, docs: List[str]) -> List[DocumentSplit]: raise NotImplementedError("Subclasses must implement this method") + + def print(self, document_splits: List[DocumentSplit]) -> None: + colors = [Fore.RED, Fore.GREEN, Fore.BLUE, Fore.MAGENTA] + for i, split in enumerate(document_splits): + color = colors[i % len(colors)] + colored_content = f"{color}{split.content}{Style.RESET_ALL}" + if split.is_triggered: + triggered = f"{split.triggered_score:.2f}" + elif i == len(document_splits) - 1: + triggered = "final split" + else: + triggered = "token limit" + print( + f"Split {i + 1}, " + f"tokens {split.token_count}, " + f"triggered by: {triggered}" + ) + print(colored_content) + print("-" * 88) + print("\n") diff --git a/semantic_router/splitters/consecutive_sim.py b/semantic_router/splitters/consecutive_sim.py index f30bbc755061640300f861e04fc7febba57fe947..4a2e110645ae90932871c36c5eb30f537943ad6f 100644 --- a/semantic_router/splitters/consecutive_sim.py +++ b/semantic_router/splitters/consecutive_sim.py @@ -19,8 +19,9 @@ class ConsecutiveSimSplitter(BaseSplitter): name: str = "consecutive_similarity_splitter", score_threshold: float = 0.45, ): - super().__init__(name=name, score_threshold=score_threshold, encoder=encoder) + super().__init__(name=name, encoder=encoder) encoder.score_threshold = score_threshold + self.score_threshold = score_threshold def __call__(self, docs: List[Any]): # Check if there's only a single document diff --git a/semantic_router/splitters/cumulative_sim.py b/semantic_router/splitters/cumulative_sim.py index f7a6475ad809a8b1eb877f592cf9ca0799941ba2..e9dd8deb2b1f24f519fab47c8fb61cc7e8f0f221 100644 --- a/semantic_router/splitters/cumulative_sim.py +++ b/semantic_router/splitters/cumulative_sim.py @@ -8,9 +8,9 @@ from semantic_router.splitters.base import BaseSplitter class CumulativeSimSplitter(BaseSplitter): - """ - Called "cumulative sim" because we check the similarities of the embeddings of cumulative concatenated documents with the next document. + Called "cumulative sim" because we check the similarities of the + embeddings of cumulative concatenated documents with the next document. """ def __init__( @@ -19,15 +19,17 @@ class CumulativeSimSplitter(BaseSplitter): name: str = "cumulative_similarity_splitter", score_threshold: float = 0.45, ): - super().__init__(name=name, score_threshold=score_threshold, encoder=encoder) + super().__init__(name=name, encoder=encoder) encoder.score_threshold = score_threshold + self.score_threshold = score_threshold def __call__(self, docs: List[str]): total_docs = len(docs) # Check if there's only a single document if total_docs == 1: raise ValueError( - "There is only one document provided; at least two are required to determine topics based on similarity." + "There is only one document provided; at least two are required " + "to determine topics based on similarity." ) splits = [] curr_split_start_idx = 0 @@ -35,10 +37,12 @@ class CumulativeSimSplitter(BaseSplitter): for idx in range(0, total_docs): if idx + 1 < total_docs: # Ensure there is a next document to compare with. if idx == 0: - # On the first iteration, compare the first document directly to the second. + # On the first iteration, compare the + # first document directly to the second. curr_split_docs = docs[idx] else: - # For subsequent iterations, compare cumulative documents up to the current one with the next. + # For subsequent iterations, compare cumulative + # documents up to the current one with the next. curr_split_docs = "\n".join(docs[curr_split_start_idx : idx + 1]) next_doc = docs[idx + 1] diff --git a/semantic_router/splitters/rolling_window.py b/semantic_router/splitters/rolling_window.py new file mode 100644 index 0000000000000000000000000000000000000000..ca9eed95ff1105c7e69591034d66692f40ae4193 --- /dev/null +++ b/semantic_router/splitters/rolling_window.py @@ -0,0 +1,329 @@ +from typing import List + +import numpy as np + +from semantic_router.encoders.base import BaseEncoder +from semantic_router.schema import DocumentSplit +from semantic_router.splitters.base import BaseSplitter +from semantic_router.splitters.utils import split_to_sentences, tiktoken_length +from semantic_router.utils.logger import logger + + +class RollingWindowSplitter(BaseSplitter): + def __init__( + self, + encoder: BaseEncoder, + threshold_adjustment=0.01, + window_size=5, + min_split_tokens=100, + max_split_tokens=300, + split_tokens_tolerance=10, + plot_splits=False, + name="rolling_window_splitter", + ): + super().__init__(name=name, encoder=encoder) + self.calculated_threshold: float + self.encoder = encoder + self.threshold_adjustment = threshold_adjustment + self.window_size = window_size + self.plot_splits = plot_splits + self.min_split_tokens = min_split_tokens + self.max_split_tokens = max_split_tokens + self.split_tokens_tolerance = split_tokens_tolerance + + def encode_documents(self, docs: List[str]) -> np.ndarray: + try: + embeddings = self.encoder(docs) + return np.array(embeddings) + except Exception as e: + logger.error(f"Error encoding documents {docs}: {e}") + raise + + def calculate_similarity_scores(self, encoded_docs: np.ndarray) -> List[float]: + raw_similarities = [] + for idx in range(1, len(encoded_docs)): + window_start = max(0, idx - self.window_size) + cumulative_context = np.mean(encoded_docs[window_start:idx], axis=0) + curr_sim_score = np.dot(cumulative_context, encoded_docs[idx]) / ( + np.linalg.norm(cumulative_context) * np.linalg.norm(encoded_docs[idx]) + + 1e-10 + ) + raw_similarities.append(curr_sim_score) + return raw_similarities + + def find_split_indices(self, similarities: List[float]) -> List[int]: + split_indices = [] + for idx in range(1, len(similarities)): + if similarities[idx] < self.calculated_threshold: + split_indices.append(idx + 1) + return split_indices + + def find_optimal_threshold(self, docs: List[str], encoded_docs: np.ndarray): + token_counts = [tiktoken_length(doc) for doc in docs] + cumulative_token_counts = np.cumsum([0] + token_counts) + similarity_scores = self.calculate_similarity_scores(encoded_docs) + + # Analyze the distribution of similarity scores to set initial bounds + median_score = np.median(similarity_scores) + std_dev = np.std(similarity_scores) + + # Set initial bounds based on median and standard deviation + low = max(0.0, float(median_score - std_dev)) + high = min(1.0, float(median_score + std_dev)) + + iteration = 0 + while low <= high: + self.calculated_threshold = (low + high) / 2 + logger.info( + f"Iteration {iteration}: Trying threshold: {self.calculated_threshold}" + ) + split_indices = self.find_split_indices(similarity_scores) + + # Calculate the token counts for each split using the cumulative sums + split_token_counts = [ + cumulative_token_counts[end] - cumulative_token_counts[start] + for start, end in zip( + [0] + split_indices, split_indices + [len(token_counts)] + ) + ] + + # Calculate the median token count for the splits + median_tokens = np.median(split_token_counts) + logger.info( + f"Iteration {iteration}: Median tokens per split: {median_tokens}" + ) + if ( + self.min_split_tokens - self.split_tokens_tolerance + <= median_tokens + <= self.max_split_tokens + self.split_tokens_tolerance + ): + logger.info( + f"Iteration {iteration}: " + f"Optimal threshold {self.calculated_threshold} found " + f"with median tokens ({median_tokens}) in target range " + f" {self.min_split_tokens}-{self.max_split_tokens}." + ) + break + elif median_tokens < self.min_split_tokens: + high = self.calculated_threshold - self.threshold_adjustment + logger.info(f"Iteration {iteration}: Adjusting high to {high}") + else: + low = self.calculated_threshold + self.threshold_adjustment + logger.info(f"Iteration {iteration}: Adjusting low to {low}") + iteration += 1 + + logger.info(f"Final optimal threshold: {self.calculated_threshold}") + return self.calculated_threshold + + def split_documents( + self, docs: List[str], split_indices: List[int], similarities: List[float] + ) -> List[DocumentSplit]: + """ + This method iterates through each document, appending it to the current split + until it either reaches a split point (determined by split_indices) or exceeds + the maximum token limit for a split (self.max_split_tokens). + When a document causes the current token count to exceed this limit, + or when a split point is reached and the minimum token requirement is met, + the current split is finalized and added to the List of splits. + """ + token_counts = [tiktoken_length(doc) for doc in docs] + splits, current_split = [], [] + current_tokens_count = 0 + + for doc_idx, doc in enumerate(docs): + doc_token_count = token_counts[doc_idx] + + # Check if current index is a split point based on similarity + if doc_idx + 1 in split_indices: + if current_tokens_count + doc_token_count >= self.min_split_tokens: + # Include the current document before splitting + # if it doesn't exceed the max limit + current_split.append(doc) + current_tokens_count += doc_token_count + + triggered_score = ( + similarities[doc_idx] if doc_idx < len(similarities) else None + ) + splits.append( + DocumentSplit( + docs=current_split.copy(), + is_triggered=True, + triggered_score=triggered_score, + token_count=current_tokens_count, + ) + ) + logger.info( + f"Split finalized with {current_tokens_count} tokens due to " + f"threshold {self.calculated_threshold}." + ) + current_split, current_tokens_count = [], 0 + continue # Move to the next document after splitting + + # Check if adding the current document exceeds the max token limit + if current_tokens_count + doc_token_count > self.max_split_tokens: + if current_tokens_count >= self.min_split_tokens: + splits.append( + DocumentSplit( + docs=current_split.copy(), + is_triggered=False, + triggered_score=None, + token_count=current_tokens_count, + ) + ) + logger.info( + f"Split finalized with {current_tokens_count} tokens due to " + f"exceeding token limit of {self.max_split_tokens}." + ) + current_split, current_tokens_count = [], 0 + + current_split.append(doc) + current_tokens_count += doc_token_count + + # Handle the last split + if current_split: + splits.append( + DocumentSplit( + docs=current_split.copy(), + is_triggered=False, + triggered_score=None, + token_count=current_tokens_count, + ) + ) + logger.info( + f"Final split added with {current_tokens_count} " + "tokens due to remaining documents." + ) + + # Validation to ensure no tokens are lost during the split + original_token_count = sum(token_counts) + split_token_count = sum( + [tiktoken_length(doc) for split in splits for doc in split.docs] + ) + if original_token_count != split_token_count: + logger.error( + f"Token count mismatch: {original_token_count} != {split_token_count}" + ) + raise ValueError( + f"Token count mismatch: {original_token_count} != {split_token_count}" + ) + + return splits + + def plot_similarity_scores( + self, similarities: List[float], split_indices: List[int] + ): + try: + from matplotlib import pyplot as plt + except ImportError: + logger.warning( + "Plotting is disabled. Please `pip install " + "semantic-router[processing]`." + ) + return + + if not self.plot_splits: + return + plt.figure(figsize=(12, 6)) + plt.plot(similarities, label="Similarity Scores", marker="o") + for split_index in split_indices: + plt.axvline( + x=split_index - 1, + color="r", + linestyle="--", + label="Split" if split_index == split_indices[0] else "", + ) + plt.axhline( + y=self.calculated_threshold, + color="g", + linestyle="-.", + label="Threshold Similarity Score", + ) + + # Annotating each similarity score + for i, score in enumerate(similarities): + plt.annotate( + f"{score:.2f}", # Formatting to two decimal places + (i, score), + textcoords="offset points", + xytext=(0, 10), # Positioning the text above the point + ha="center", + ) # Center-align the text + + plt.xlabel("Document Segment Index") + plt.ylabel("Similarity Score") + plt.title( + f"Threshold: {self.calculated_threshold} |" + f" Window Size: {self.window_size}", + loc="right", + fontsize=10, + ) + plt.suptitle("Document Similarity Scores", fontsize=14) + plt.legend() + plt.show() + + def plot_sentence_similarity_scores( + self, docs: List[str], threshold: float, window_size: int + ): + try: + from matplotlib import pyplot as plt + except ImportError: + logger.warning("Plotting is disabled. Please `pip install matplotlib`.") + return + """ + Computes similarity scores between the average of the last + 'window_size' sentences and the next one, + plots a graph of these similarity scores, and prints the first + sentence after a similarity score below + a specified threshold. + """ + sentences = [sentence for doc in docs for sentence in split_to_sentences(doc)] + encoded_sentences = self.encode_documents(sentences) + similarity_scores = [] + + for i in range(window_size, len(encoded_sentences)): + window_avg_encoding = np.mean( + encoded_sentences[i - window_size : i], axis=0 + ) + sim_score = np.dot(window_avg_encoding, encoded_sentences[i]) / ( + np.linalg.norm(window_avg_encoding) + * np.linalg.norm(encoded_sentences[i]) + + 1e-10 + ) + similarity_scores.append(sim_score) + + plt.figure(figsize=(10, 8)) + plt.plot(similarity_scores, marker="o", linestyle="-", color="b") + plt.title("Sliding Window Sentence Similarity Scores") + plt.xlabel("Sentence Index") + plt.ylabel("Similarity Score") + plt.grid(True) + plt.axhline(y=threshold, color="r", linestyle="--", label="Threshold") + plt.show() + + for i, score in enumerate(similarity_scores): + if score < threshold: + print( + f"First sentence after similarity score " + f"below {threshold}: {sentences[i + window_size]}" + ) + + def __call__(self, docs: List[str]) -> List[DocumentSplit]: + if not docs: + raise ValueError("At least one document is required for splitting.") + + if len(docs) == 1: + token_count = tiktoken_length(docs[0]) + if token_count > self.max_split_tokens: + logger.warning( + f"Single document exceeds the maximum token limit " + f"of {self.max_split_tokens}. " + "Splitting to sentences before semantically splitting." + ) + docs = split_to_sentences(docs[0]) + encoded_docs = self.encode_documents(docs) + self.find_optimal_threshold(docs, encoded_docs) + similarities = self.calculate_similarity_scores(encoded_docs) + split_indices = self.find_split_indices(similarities=similarities) + splits = self.split_documents(docs, split_indices, similarities) + self.plot_similarity_scores(similarities, split_indices) + return splits diff --git a/semantic_router/splitters/utils.py b/semantic_router/splitters/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..349c3eaac76017c53dd5425abfe65e7e2952a679 --- /dev/null +++ b/semantic_router/splitters/utils.py @@ -0,0 +1,63 @@ +import regex +import tiktoken + + +def split_to_sentences(text: str) -> list[str]: + """ + Enhanced regex pattern to split a given text into sentences more accurately. + + The enhanced regex pattern includes handling for: + - Direct speech and quotations. + - Abbreviations, initials, and acronyms. + - Decimal numbers and dates. + - Ellipses and other punctuation marks used in informal text. + - Removing control characters and format characters. + + Args: + text (str): The text to split into sentences. + + Returns: + list: A list of sentences extracted from the text. + """ + regex_pattern = r""" + # Negative lookbehind for word boundary, word char, dot, word char + (?<!\b\w\.\w.) + # Negative lookbehind for single uppercase initials like "A." + (?<!\b[A-Z][a-z]\.) + # Negative lookbehind for abbreviations like "U.S." + (?<!\b[A-Z]\.) + # Negative lookbehind for abbreviations with uppercase letters and dots + (?<!\b\p{Lu}\.\p{Lu}.) + # Negative lookbehind for numbers, to avoid splitting decimals + (?<!\b\p{N}\.) + # Positive lookbehind for punctuation followed by whitespace + (?<=\.|\?|!|:|\.\.\.)\s+ + # Positive lookahead for uppercase letter or opening quote at word boundary + (?="?(?=[A-Z])|"\b) + # OR + | + # Splits after punctuation that follows closing punctuation, followed by + # whitespace + (?<=[\"\'\]\)\}][\.!?])\s+(?=[\"\'\(A-Z]) + # OR + | + # Splits after punctuation if not preceded by a period + (?<=[^\.][\.!?])\s+(?=[A-Z]) + # OR + | + # Handles splitting after ellipses + (?<=\.\.\.)\s+(?=[A-Z]) + # OR + | + # Matches and removes control characters and format characters + [\p{Cc}\p{Cf}]+ + """ + sentences = regex.split(regex_pattern, text, flags=regex.VERBOSE) + sentences = [sentence.strip() for sentence in sentences if sentence.strip()] + return sentences + + +def tiktoken_length(text: str) -> int: + tokenizer = tiktoken.get_encoding("cl100k_base") + tokens = tokenizer.encode(text, disallowed_special=()) + return len(tokens) diff --git a/tests/unit/llms/test_llm_ollama.py b/tests/unit/llms/test_llm_ollama.py index 299989821d2dc2885f4e4cbe89dd0308d24fffda..369e5f4444789c3bb70988455bb49c7df4792445 100644 --- a/tests/unit/llms/test_llm_ollama.py +++ b/tests/unit/llms/test_llm_ollama.py @@ -1,4 +1,5 @@ import pytest + from semantic_router.llms.ollama import OllamaLLM from semantic_router.schema import Message diff --git a/tests/unit/test_layer.py b/tests/unit/test_layer.py index 3f2c413f45f279656bada2ffdc7ee47b96ef1a6c..415150a597ee396d593c88b651658bd28410fc80 100644 --- a/tests/unit/test_layer.py +++ b/tests/unit/test_layer.py @@ -399,10 +399,11 @@ class TestRouteLayer: # Load the LayerConfig from the temporary file layer_config = LayerConfig.from_file(str(config_path)) - # Using BaseLLM because trying to create a useable Mock LLM is a nightmare. + # Using BaseLLM because trying to create a usable Mock LLM is a nightmare. assert isinstance( layer_config.routes[0].llm, BaseLLM - ), "LLM should be instantiated and associated with the route based on the config" + ), "LLM should be instantiated and associated with the route based on the " + "config" assert ( layer_config.routes[0].llm.name == "fake-model-v1" ), "LLM instance should have the 'name' attribute set correctly"