From 5dbd1aaeba59f6cf0704285822f42b223cde5464 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 16 Nov 2023 16:13:26 -0500 Subject: [PATCH 1/4] x --- poetry.lock | 522 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 13 +- 2 files changed, 527 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7cc06f82..dc6e11ce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,19 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +[[package]] +name = "accessible-pygments" +version = "0.0.4" +description = "A collection of accessible pygments styles" +optional = false +python-versions = "*" +files = [ + {file = "accessible-pygments-0.0.4.tar.gz", hash = "sha256:e7b57a9b15958e9601c7e9eb07a440c813283545a20973f2574a5f453d0e953e"}, + {file = "accessible_pygments-0.0.4-py2.py3-none-any.whl", hash = "sha256:416c6d8c1ea1c5ad8701903a20fcedf953c6e720d64f33dc47bfb2d3f2fa4e8d"}, +] + +[package.dependencies] +pygments = ">=1.5" + [[package]] name = "aiofiles" version = "22.1.0" @@ -148,6 +162,17 @@ files = [ dev = ["aiounittest (==1.4.1)", "attribution (==1.6.2)", "black (==23.3.0)", "coverage[toml] (==7.2.3)", "flake8 (==5.0.4)", "flake8-bugbear (==23.3.12)", "flit (==3.7.1)", "mypy (==1.2.0)", "ufmt (==2.1.0)", "usort (==1.0.6)"] docs = ["sphinx (==6.1.3)", "sphinx-mdinclude (==0.5.3)"] +[[package]] +name = "alabaster" +version = "0.7.13" +description = "A configurable sidebar-enabled Sphinx theme" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, +] + [[package]] name = "annotated-types" version = "0.6.0" @@ -556,6 +581,20 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -715,6 +754,25 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "dnspython" +version = "2.4.2" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "dnspython-2.4.2-py3-none-any.whl", hash = "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8"}, + {file = "dnspython-2.4.2.tar.gz", hash = "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984"}, +] + +[package.extras] +dnssec = ["cryptography (>=2.6,<42.0)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=0.17.3)", "httpx (>=0.24.1)"] +doq = ["aioquic (>=0.9.20)"] +idna = ["idna (>=2.1,<4.0)"] +trio = ["trio (>=0.14,<0.23)"] +wmi = ["wmi (>=1.5.1,<2.0.0)"] + [[package]] name = "docopt" version = "0.6.2" @@ -725,6 +783,17 @@ files = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] +[[package]] +name = "docutils" +version = "0.17.1" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, +] + [[package]] name = "entrypoints" version = "0.4" @@ -940,6 +1009,17 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + [[package]] name = "importlib-metadata" version = "6.8.0" @@ -1206,6 +1286,33 @@ files = [ importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} referencing = ">=0.31.0" +[[package]] +name = "jupyter-cache" +version = "0.6.1" +description = "A defined interface for working with a cache of jupyter notebooks." +optional = false +python-versions = "~=3.8" +files = [ + {file = "jupyter-cache-0.6.1.tar.gz", hash = "sha256:26f83901143edf4af2f3ff5a91e2d2ad298e46e2cee03c8071d37a23a63ccbfc"}, + {file = "jupyter_cache-0.6.1-py3-none-any.whl", hash = "sha256:2fce7d4975805c77f75bdfc1bc2e82bc538b8e5b1af27f2f5e06d55b9f996a82"}, +] + +[package.dependencies] +attrs = "*" +click = "*" +importlib-metadata = "*" +nbclient = ">=0.2,<0.8" +nbformat = "*" +pyyaml = "*" +sqlalchemy = ">=1.3.12,<3" +tabulate = "*" + +[package.extras] +cli = ["click-log"] +code-style = ["pre-commit (>=2.12,<4.0)"] +rtd = ["ipykernel", "jupytext", "myst-nb", "nbdime", "sphinx-book-theme", "sphinx-copybutton"] +testing = ["coverage", "ipykernel", "jupytext", "matplotlib", "nbdime", "nbformat (>=5.1)", "numpy", "pandas", "pytest (>=6,<8)", "pytest-cov", "pytest-regressions", "sympy"] + [[package]] name = "jupyter-client" version = "7.4.9" @@ -1507,6 +1614,61 @@ files = [ pydantic = ">=1,<3" requests = ">=2,<3" +[[package]] +name = "linkchecker" +version = "10.3.0" +description = "check links in web documents or full websites" +optional = false +python-versions = ">=3.8" +files = [ + {file = "LinkChecker-10.3.0-py3-none-any.whl", hash = "sha256:624f63be599b1d91c3be60d6c5e38412ddbc0f4417c49f0d1936b33c1ce62b09"}, + {file = "LinkChecker-10.3.0.tar.gz", hash = "sha256:1741b9506d3f2b5d1243cc2918f5e5813134fcb77a93dbd38b23e0d088940046"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.8.1" +dnspython = ">=2.0" +requests = ">=2.20" + +[[package]] +name = "livereload" +version = "2.6.3" +description = "Python LiveReload is an awesome tool for web developers" +optional = false +python-versions = "*" +files = [ + {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"}, + {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, +] + +[package.dependencies] +six = "*" +tornado = {version = "*", markers = "python_version > \"2.7\""} + +[[package]] +name = "markdown-it-py" +version = "2.2.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.7" +files = [ + {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, + {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "2.1.3" @@ -1610,6 +1772,36 @@ files = [ [package.dependencies] traitlets = "*" +[[package]] +name = "mdit-py-plugins" +version = "0.3.5" +description = "Collection of plugins for markdown-it-py" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, + {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, +] + +[package.dependencies] +markdown-it-py = ">=1.0.0,<3.0.0" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "mistune" version = "3.0.2" @@ -1762,6 +1954,60 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "myst-nb" +version = "0.17.2" +description = "A Jupyter Notebook Sphinx reader built on top of the MyST markdown parser." +optional = false +python-versions = ">=3.7" +files = [ + {file = "myst-nb-0.17.2.tar.gz", hash = "sha256:0f61386515fab07c73646adca97fff2f69f41e90d313a260217c5bbe419d858b"}, + {file = "myst_nb-0.17.2-py3-none-any.whl", hash = "sha256:132ca4d0f5c308fdd4b6fdaba077712e28e119ccdafd04d6e41b51aac5483494"}, +] + +[package.dependencies] +importlib_metadata = "*" +ipykernel = "*" +ipython = "*" +jupyter-cache = ">=0.5,<0.7" +myst-parser = ">=0.18.0,<0.19.0" +nbclient = "*" +nbformat = ">=5.0,<6.0" +pyyaml = "*" +sphinx = ">=4,<6" +typing-extensions = "*" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["alabaster", "altair", "bokeh", "coconut (>=1.4.3,<2.3.0)", "ipykernel (>=5.5,<6.0)", "ipywidgets", "jupytext (>=1.11.2,<1.12.0)", "matplotlib", "numpy", "pandas", "plotly", "sphinx-book-theme (>=0.3.0,<0.4.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0,<0.5.0)", "sphinxcontrib-bibtex", "sympy"] +testing = ["beautifulsoup4", "coverage (>=6.4,<8.0)", "ipykernel (>=5.5,<6.0)", "ipython (!=8.1.0,<8.5)", "ipywidgets (>=8)", "jupytext (>=1.11.2,<1.12.0)", "matplotlib (>=3.5.3,<3.6)", "nbdime", "numpy", "pandas", "pytest (>=7.1,<8.0)", "pytest-cov (>=3,<5)", "pytest-param-files (>=0.3.3,<0.4.0)", "pytest-regressions", "sympy (>=1.10.1)"] + +[[package]] +name = "myst-parser" +version = "0.18.1" +description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." +optional = false +python-versions = ">=3.7" +files = [ + {file = "myst-parser-0.18.1.tar.gz", hash = "sha256:79317f4bb2c13053dd6e64f9da1ba1da6cd9c40c8a430c447a7b146a594c246d"}, + {file = "myst_parser-0.18.1-py3-none-any.whl", hash = "sha256:61b275b85d9f58aa327f370913ae1bec26ebad372cc99f3ab85c8ec3ee8d9fb8"}, +] + +[package.dependencies] +docutils = ">=0.15,<0.20" +jinja2 = "*" +markdown-it-py = ">=1.0.0,<3.0.0" +mdit-py-plugins = ">=0.3.1,<0.4.0" +pyyaml = "*" +sphinx = ">=4,<6" +typing-extensions = "*" + +[package.extras] +code-style = ["pre-commit (>=2.12,<3.0)"] +linkify = ["linkify-it-py (>=1.0,<2.0)"] +rtd = ["ipython", "sphinx-book-theme", "sphinx-design", "sphinxcontrib.mermaid (>=0.7.1,<0.8.0)", "sphinxext-opengraph (>=0.6.3,<0.7.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] +testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx (<5.2)", "sphinx-pytest"] + [[package]] name = "nbclassic" version = "1.0.0" @@ -1799,25 +2045,25 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p [[package]] name = "nbclient" -version = "0.9.0" +version = "0.7.4" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." optional = false -python-versions = ">=3.8.0" +python-versions = ">=3.7.0" files = [ - {file = "nbclient-0.9.0-py3-none-any.whl", hash = "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15"}, - {file = "nbclient-0.9.0.tar.gz", hash = "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e"}, + {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, + {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, ] [package.dependencies] jupyter-client = ">=6.1.12" jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" nbformat = ">=5.1" -traitlets = ">=5.4" +traitlets = ">=5.3" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" @@ -1878,6 +2124,25 @@ traitlets = ">=5.1" docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] test = ["pep440", "pre-commit", "pytest", "testpath"] +[[package]] +name = "nbsphinx" +version = "0.8.12" +description = "Jupyter Notebook Tools for Sphinx" +optional = false +python-versions = ">=3.6" +files = [ + {file = "nbsphinx-0.8.12-py3-none-any.whl", hash = "sha256:c15b681c7fce287000856f91fe1edac50d29f7b0c15bbc746fbe55c8eb84750b"}, + {file = "nbsphinx-0.8.12.tar.gz", hash = "sha256:76570416cdecbeb21dbf5c3d6aa204ced6c1dd7ebef4077b5c21b8c6ece9533f"}, +] + +[package.dependencies] +docutils = "*" +jinja2 = "*" +nbconvert = "!=5.4" +nbformat = "*" +sphinx = ">=1.8" +traitlets = ">=5" + [[package]] name = "nest-asyncio" version = "1.5.8" @@ -2330,6 +2595,32 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydata-sphinx-theme" +version = "0.13.3" +description = "Bootstrap-based Sphinx theme from the PyData community" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydata_sphinx_theme-0.13.3-py3-none-any.whl", hash = "sha256:bf41ca6c1c6216e929e28834e404bfc90e080b51915bbe7563b5e6fda70354f0"}, + {file = "pydata_sphinx_theme-0.13.3.tar.gz", hash = "sha256:827f16b065c4fd97e847c11c108bf632b7f2ff53a3bca3272f63f3f3ff782ecc"}, +] + +[package.dependencies] +accessible-pygments = "*" +Babel = "*" +beautifulsoup4 = "*" +docutils = "!=0.17.0" +packaging = "*" +pygments = ">=2.7" +sphinx = ">=4.2" +typing-extensions = "*" + +[package.extras] +dev = ["nox", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml"] +doc = ["ablog (>=0.11.0rc2)", "colorama", "ipyleaflet", "jupyter_sphinx", "linkify-it-py", "matplotlib", "myst-nb", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube", "sphinxext-rediraffe", "xarray"] +test = ["codecov", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "pygments" version = "2.16.1" @@ -2932,6 +3223,17 @@ files = [ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + [[package]] name = "soupsieve" version = "2.5" @@ -2943,6 +3245,187 @@ files = [ {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] +[[package]] +name = "sphinx" +version = "4.5.0" +description = "Python documentation generator" +optional = false +python-versions = ">=3.6" +files = [ + {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, + {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, +] + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.18" +imagesize = "*" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] + +[[package]] +name = "sphinx-autobuild" +version = "2021.3.14" +description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." +optional = false +python-versions = ">=3.6" +files = [ + {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, + {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, +] + +[package.dependencies] +colorama = "*" +livereload = "*" +sphinx = "*" + +[package.extras] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "sphinx-book-theme" +version = "1.0.1" +description = "A clean book theme for scientific explanations and documentation with Sphinx" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx_book_theme-1.0.1-py3-none-any.whl", hash = "sha256:d15f8248b3718a9a6be0ba617a32d1591f9fa39c614469bface777ba06a73b75"}, + {file = "sphinx_book_theme-1.0.1.tar.gz", hash = "sha256:927b399a6906be067e49c11ef1a87472f1b1964075c9eea30fb82c64b20aedee"}, +] + +[package.dependencies] +pydata-sphinx-theme = ">=0.13.3" +sphinx = ">=4,<7" + +[package.extras] +code-style = ["pre-commit"] +doc = ["ablog", "docutils (==0.17.1)", "folium", "ipywidgets", "matplotlib", "myst-nb", "nbclient", "numpy", "numpydoc", "pandas", "plotly", "sphinx-copybutton", "sphinx-design", "sphinx-examples", "sphinx-tabs (<=3.4.0)", "sphinx-thebe", "sphinx-togglebutton", "sphinxcontrib-bibtex", "sphinxcontrib-youtube", "sphinxext-opengraph"] +test = ["beautifulsoup4", "coverage", "myst-nb", "pytest", "pytest-cov", "pytest-regressions", "sphinx_thebe"] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +description = "Add a copy button to each of your code cells." +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, + {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, +] + +[package.dependencies] +sphinx = ">=1.8" + +[package.extras] +code-style = ["pre-commit (==2.12.1)"] +rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.4" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, + {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.1" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, + {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + [[package]] name = "sqlalchemy" version = "2.0.23" @@ -3049,6 +3532,20 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + +[package.extras] +widechars = ["wcwidth"] + [[package]] name = "tenacity" version = "8.2.3" @@ -3102,6 +3599,17 @@ webencodings = ">=0.4" doc = ["sphinx", "sphinx_rtd_theme"] test = ["flake8", "isort", "pytest"] +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -3534,4 +4042,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "cce4d8c816ccfa58210fedc8a161a960cd4554777ed30a5da9e236be5c7c87db" +content-hash = "49a8a2e8cdeeff91c9e4ea8300353e32f745cca1635e97ed75aab7292b8cb60e" diff --git a/pyproject.toml b/pyproject.toml index 174f0463..a054ef96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langchain-benchmarks" -version = "0.1.0" +version = "0.0.1" description = "Flex them feathers! 🦜💪" authors = ["LangChain AI"] license = "MIT" @@ -21,6 +21,17 @@ mypy = "^1.7.0" [tool.poetry.group.lint.dependencies] ruff = "^0.1.5" +[tool.poetry.group.docs.dependencies] +nbsphinx = "^0.8.9" +sphinx = "^4.5.0" +sphinx-autobuild = "^2021.3.14" +sphinx_book_theme = "^1.0.0" +myst-nb = "^0.17.1" +linkchecker = "^10.2.1" +toml = "^0.10.2" +sphinx-copybutton = "^0.5.1" + + [tool.poetry.group.test.dependencies] pytest = "^7.2.1" pytest-cov = "^4.0.0" From b0e139ac9058463f4b0d88373fb47e57b9b324f0 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 16 Nov 2023 16:13:31 -0500 Subject: [PATCH 2/4] x --- docs/Makefile | 20 + docs/make.bat | 35 + docs/source/_static/parrot.png | Bin 0 -> 18941 bytes docs/source/conf.py | 105 +++ docs/source/examples/image_manipulation.ipynb | 680 ++++++++++++++++++ docs/source/index.md | 8 + 6 files changed, 848 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/_static/parrot.png create mode 100644 docs/source/conf.py create mode 100644 docs/source/examples/image_manipulation.ipynb create mode 100644 docs/source/index.md diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..747ffb7b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/_static/parrot.png b/docs/source/_static/parrot.png new file mode 100644 index 0000000000000000000000000000000000000000..48f0e294b430fc9116aca6085926568a6acaa3cc GIT binary patch literal 18941 zcmV)0K+eC3P)001trdQ@0+Qek%> zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3>vk{&sdWdHjq`Us94I1W~kxxpNNo*FzzW@c4& zkIWP+8NqMy1u#=nwZ)(PzyH^H{_DT~%emt76H}?V<^1x$*kbdYU+R1R*X(ciM*G|T z7r(do_g`Lre!by&DeyDgf0q7zzVmwe{e_=%xbfH5pZdMy>vtgc>%jKEpfl_D_2)(M zy1%cx?@FGw?=QL4^5>N-J@q;QbCRy!Lm!R}l1H z2%VpizkO(Y&e`uVq=z3V{9FkO@|WBD`T4$oF3?{V`RBLi@2mgox4$jE@89d;Z)=&q zHR6|l`G!k>dp-O*jsNq+;nx-UzrN9`pZ~a>@4s_aJ!jv$>oK#U`LifnZ1-~*J~&wN zU|-ApDg2lCz1W||pZfN9vgPZY@8HjL&3Sg^JTAKBx;t*$&*>(Y82$EzpWaU&?6n$- zZ+?cmPyBJmm(aormHnH3KWu0W{@1lQJ8!e|O;^KE;N(^X*%*1^)T-ZU6g+{a~u>V6tVd++cslJ;X@vw`~R6 z=fLL@Kd%e9r>yS)ED`5UT#O6sz?)r2F1xpQUz}qdD;w0gav!1}?0`$jFD}x@5VC)Y zuU_ZoJH^>&ee&7sWw1$J6mlr+O$(jPiZNk7C01;xr;uVwDW{U^lUnLI=xnzM{ zFQLSeN-m|;(n_zP#+qubrPkVNZ@vXEFtyxDtF5)({nI&7=UAQ3cU~EOgb_y?d6ZE{ z8+~FvGtM;gEVIrw`|>L+U}EJ}R$XoN?Vb%%?6}j;yX?B#?gv{t;lz_pKIPQYPXD!Q z->&}S&;P})xo_9J?UX)Oe(f5sKBfE|!U;~2_KY3#(Xr!2JAgrZ?b%yhj9xpZJ$su_ zE_p68X>Xq8v}0^x+|H-te(l}wo%t`%YP0$CEk{?d7lk$Dhyd7fzVRwK5aF4n)Q{_DttEU(QHe(U|ib){E=S zd#!Och__kA-6BrA!RRxJn<>2bo5pR zcaW!k?|iW2y-(jIjB#Q=SoU#agmb{lqQ?vm9SQ0PjoU^P-ZV<5{3D9KcD~Z1Igh;+XuT- zqMY4m{;o2xGm9nWE+4zgdNP}k=F$eN*Vd!*ogHoQPv($rR~)o7Gl_qG>bW2LPX}0Q z4z@kXk#w_rOy{u@EHU0)t}X9p^WNDB>$8ha9osI2{ju|wbrxHM?VS8#UD~ke@XCW7 zmWA!%uUkg^M0gKx?7b>G-%9OsCPj9fJ9SKVj1pJgzO5bdI4L+S*kaGx&(#EHw-(JH zIbC1xU~k#Om&*wF)d*pY(5BfE@KU;~Wj59~WbSqWkQl4$Bj*Qe)_Mn=fyh^|SjX4f z9FUX3HDeR8^nxoaEl-5C2HdAzL#?dKNxbZzSXQf>uXZgYNSVVauGu0Ev*(q&zzR3% zpw^qPZs%JHJvmGhKdqSJdPdp!1h>#f>yS~d0ytscZ1MM41;{>~<-^s$FqVu{)#9|m zk(;Ul#u!-ae8GaN=q+yG6_!g3;(gfBk?)>Z0nGjW9Gbll2Ry&l*Uj@B-pSqU7fhSG zv)bHXS9Ay|2S0bU59>Spbn`nLH+EJ6GPFZyJyWhoxB#2AkDrYXsD!@3X$Usp%Y`$r zvJ1#?jZ|3>x7TLrvcrxRTau)cy4D3heS4V8v(Zy$B1q0YF?_Z;U^uBhl+-_eK0m)S*G4{>e{pyx@CTEw6GURk&_#Hl zD>s9<^?`rRfCmV?9s=*-Mmsm6FR_K}t=_4u>V!;B7Uy6%MNYw0hUJ0s8uAQWrVxK& zA&c$T5wu^69bgae-~hr`kd|m%4oARwQb&T#N!*xk+n)8R;2KbRHrLL{A3;MgjGIe4 zTgs3~8=yZCD%;Jyb;;oEcFg3jRi?BfEA7S1^27BK2Sx)yT0~h6URQLvd1$h6WhWI zP;Xgf1+$_*T*nk=Fsx>YIN)>`xnD*siY`K7SIGKo3oUOJb`z;_a|n|~M=yuCF{5(t ztHI!q1D;ngJW;mAy=VvG>gkETPq-iU=EJI6RffgHcS>TxBI}vNd%ivfH zAw;{TdhF+Fd0;~O^>X`HdshSY6Ik*G&NQ;HntxpUtauEP;mCJc|5d=%He2V$JemPa zep?R&869ZKm$WCWk>?OVe!@r3I{&%1pkFe`v7qR+j}*lT7MdrC zMCjK`z5876f5KDyIT~I%X2hv6qGR25lJaVjLzVu4cu5?{2}P@3eR zAW!uQmmC>9+CDq11TMs}#7G9Hc2}kvW^9T07+y&07+aSlZNX=seAR||yADSrEL!L+ zOyS1?N~XgE88y@VHc5tPF9gb_VvVO8@P4e;C`^LAZe7pufdt~-Do z3p_{dBdyF9K+sdRR<6n!E~^vzocKzLR!CdE9LTr|H))3guJns|;xeoI&EklCaG0(* z;bVt!wx@^D_6yH(SdH0I{O~ClK0%Q|0TwpPIXR*vk$BGVll#>{ixBp?M8Tq-VxI8u zuyea`danz;EAgB7VGXf$m@j5BjDa=awLj2wk$VgfK*)#`MOEoX*ID~tLQvL-Jn#-K zE{VIRqEk>LN|4kVp1XUJp-EtipV|7vyB_`q=A0mcm=?lj`I)1ePQDRmYq}cP*CVa7CgKxD>pI;0Ycj?QE0x zl!mG3VtbE@9S?d)h77b`pOUgz9&94WG)XMDKsIh79A&KlHHb3wKyjEYF~$0h$3sAf z-2}RV>X^j^sc$|tMd{=p+x;@bSnA6%K@OWR%t6<{5*!tT{KK;$%|rT-g_aR^{B|r0 zV(sTp9@^&((St0MQwd_&{_;S6EL22pRwnD<4ex>txw#yKd&ufhp^NkEC}2YLg@j7? ze4W$qjs-}3Qj#IDnq0R@>-7G|pZLEnD~cYOVZ!wT1_|bEf2}zmRYQ)G)d(I@xB!1K zJ_lMSLM+%m1zvmlOzIBsakXike=ypE^ph7DTx=B>A zgV36ql7|Wrm)TZSYGzyAcA1S{g#P0|=VtspM+=!!BTJNLNMmzqgeNePcvD)XBv3+oGeOO9wf?KR^TB?Pc#$9o*`GT_cIoz69w7YoNZ}h-K;vxtQ#h@a~FeKrBX1&06=dya5`58o9mM*8p z+PquB_?n*>-mnBuF^bOWc0wZrPkBM(WJP;vS_3>nP9VjjG|O3HL+sgrOezVD&Mf#D zs-Ymzr??{_P}hPhvIYEW#_Y?BBz`=`NSH!n;pr7X5WFV@6h{?*FR%yQ83-weMQxjj zV%%W6`IMN8+m8jksXa8gI>Fgteh0QGqd1AL7;!b(CK0y=;XYez(9H`cbd8S)2pj{EFcjPVB-TEon1NF5A4gCy4L@_ zJMX>pa7jZla%dZHvp&i<;6=W)2PtB&!Jac>m6e6Y3>BKQUTCxGoVMO&ue2gas_wP#r zTgh!f*q1kD-w4}Spv)d6per(#w}y6&bJo|cBwtyIjY}dam7Ntg0!|6b3%spFqj3ax zJ~Nn{gg2gle$iG7EN!Z435I1wuzj{L;9?jex737do5ez;5Hw4CFbBU1Fpm`}oqA;3 ztX~2ts)Bx(#S}z>g4)|Im*g;4XTJBtdq9ti?lhjMya#9Z(83Wa-&1-YXi{XEhCSnw z=n-M$SlF)NCn>Zp(UMLTy{L8;q(rcExmY2lYDo^HCuf{f`bU8o*dr|EVKR?vKaV%* zGNlH~Eer^H!@9bn#@;baj2`x_15Gh!=;DT93BqygWsCpt56IF`J_JI{)##wyn~1m& z48zhk`y2oAmw8tTcuMu|WZRE|97^aS=K91svMfPJPzZbTYDyq4c7pv|ltfa5Az%eq zA)CB*C+J2ty*$bUhGMxH%p2sNSGrqvb-}iBY%lyN5XyimShLcB(3zRJ-Y9%iZYRt8 z0i<~>;-OWgF2j)g0Dr>F;y%GLqg_jk(|IBrsHg%8XfIL8g~mrpGQ`cwxRMK_RYyD|!geN4 z%PfhK&%4b<1>`HiN^VNQbFy6UKD!O&hVdF?@je zDA`R6@!02aI3@~6Tn?eR*`TPxRep5Cmq@HDw$|dFR`V*wvO8Vn+z1*N>#ma>bUogx zj-<4*WU7!ofIJjei<7?;Hvl;5T1xLiyLyuS5NL*}tE=LsP-!dD;3G=3_4sgFPt1hJ zv=YJv$JYG6W$a1e?-mf!pXP;LO9j+|>0m4Ff`yowUo2{sjhuBiUWFT_HpI*t9Abx0 zPrdj*^w@o${o5zC{boP=_lMKBk7^#$eFB^W9lV9O{t*6Dv#tgs=yz^if{MU}D@P@2 zK`Om0#qCr;0;ajmJgve|P~2>LLDR0Lbghw(R&Q#~=ttPPv@OX9Q)Ef82b`1*P`Ea~ zR36`agf&*}s42}1Y-pY0&F@*370f}dwWd5O@}Wt)I_)*rzb{27m_$b}_VJ+64qH)D zc?(!f2vpMrWT_*|a|;=&WgK_TFY)mre_8Bl*6l+zA12c3rf?Rh2FD|Y7Df7Or4zna z^601$D3tRth#Lc3H~R;Os3f{onq&J}8aV1{x3F7`9I)CbDR`c<^x;iE>xw=FKCV-< zL=Y1t)x718M*Jd)I8yjY+g}l-CHe>%} z|GHvmz#kEbTP)X>LzqeI*J2eIVb79gSL3fNa&6r9ij7OIr1R#j3qSytqO+-+Bp12d zcc-STl?sQ=&+S!cv9ihx|6f53_ z2`kMN;6+cUh6osU_2xC7QMB$SuME3i*iummPP?Xli6dIUaRp|5a5NdqM!gZWg~YZ&eP0bw~piU^1j7{CdUaR-htz5SIX*3HnRTz3a5}C zkI}|IxF4Y2O#pX16VK!RhB8P&Oe`uxid&}yRI&W6eDJpCqg??JbK_zPqSpZT zveHWL3`13*=4Nx%MDfm|c%4;7V{5=8RU|CV9A)5zKhFMVulM=b{Oq6 zw&e+mrIE4p6~iN<2=++@LIt8ISWW>O;0_dmhFFYMm(bFxVt8%AP@>H$VjR#e?18+8 z5|w4##*>yQ>%S(Bm5S%)mmLLvfKAzE%y6$um+_!}7AM8Kv@dI6U0OVouZk^hT+ zp6Ig_N&!(hlhr(wmhaFS`Q-WFLLd%tn@Rz67T{+4SI}X?`I-nu%d+M75=~W- zfLhhH$GEZ6GFux)F+i^J2mP+SC~xwL*+Rs*uV!)XOV5v6shL;P!zJdAsNY)hZorNF zAhO+>Kii`|9~YJE4e5xem?3lnI1EwJAsi-?PMARi9D0HB=|WYQf6C#jPAa!EzRcMTXkgA(F*4aT*=k)f z8o$05X$lNjbp%j-opUq4w|G^{t@v0}a&t<;R%{rLyeZb?U?IsmEP!UGbc3tFe|)Rz zvg4!ovVCE(E~;bza;SlVKhp1crl%|yl4f05-!njj%BVX3XiQ2C=sht0T z&(H4{l>f{ng`@P)S@X7@p}{zV8lqGrj#pI88};&0w?qWQ>v-e_suvt1sI?&cjJ#ke zO>nT>m({|h+)Wj#7s9D}07DGP0z)i-zgi($stB9D>TbP6`?zoahKLfc5p_gRm=Nb8 zswp4&AiQC?Q(@i!dW&0NhGScKDKFh1?6Q4)N2y}9XbzWHR#-e_E0(+---Blt;UnWa zJHNV+tqLRMQqEUaMW}aWMg>KX9PGnvReslD{s0>*pn5|P0cTN5?omg)Pg;t&%CfNSbVJke@JAFof914?mVkaq+NhRC4{t8rU~RM68DV|4DT;KU(sk^9y@ewVo+T9%WqR?Ajf(E#)C#Bd|d zGQ%xD`H=PyoaLWNh$wq&xxF9}h=S##xuN)@%GKTqxK=G<6RUF3M;TXaMLBxNs1bCv zZrq+6BA3guK}XRumg$tsS^XbuP|=}UNZz1stz;w9x3=sljNT=W}ML7i1; z=p!nOjrsMk)C42d_yFz+exnseMXNz;5LO>S_9=iHW*t4Q(_(A`0DH@&+2Y7I{SWO}#y15f;L;Z=5icQ1JH zmru6j#RRVtKWfwlW5-W9{_91$C-j$s<`8eIUi;@e;PMpsJeEsV&6WQ&i(oF2Ocu9a z=diSsYCKT7bIa4`mZyI;q&_Zv=aL}J?zW-3pWa{VGPInKhB8DvZzI*J>$~CG<$)cw z;8oBcL{B6`FWm*ZalX|5dPVW~>(^v|Un?;5IPvYj?Z91<_AlQt2)<1i5n}jjNuF;_ z>;jWhv*N8Ss-~o(l4X$X-LXw0PE{t<_9LEpy|GsXNTtzlgKGohZ@5hF*E=Fcjq1_h z!8JM zTsAQs{vxIkei4eE6`kNoUd`-fh09~}F24RZV*swTU|q}m0c&Rd%Rs8gjx%{ez|1ev0WcDg)v}Ap3nva2MCAEK6behF)7^u}EZUBH8 z;X*8}rCt6I-O8;?FbHoSfxQSWKr6voQ5|Kp5b>Xpl};L~gTxq?%3$M)PeIx322fuD z2URotKWsLNh)ZPaP$p_v?BB04&{|q2r3tgGR-29 z;f$>lZPZ?6Ta&)3w-ILudn`iGq6q*NYeeLMkqp4N)_@!hUqgbH^2^oAQNj^b8EW+u z?|FU`9}gQ-{-Y}ewZ5V)>!763(x`7*&KC*Az)bS$2Nf_`cJ;z5UxpMP zDZs*W#7SbG6_|l<2i2nRpT`nMK_xUznt4H_)h-XD54O@JhVMLtI_u`w*Jj?KR7u}n zePwPumllDR$27EMj&UlrrRV!i{lFoUcI}%O;pnJ^ z+Y6n)rrh0b(}#g)yG@5mJgKp(sb$A{q}P6~T=-4U0CYGgfQ!|+3g3if0oJcFOQ51Q z`wdpsBtqs3J}lgTjEc$!$)2Ge2$d)le9u593IUw7DtF*CS&)?sRPMZ$WZ6u0B5mab z9vfssF*>|j3Lq-+-F#3EM9dX5DF1PwPJE&cWR`mOYrK`=o6VMB%F01}Dc50rtlK6c zeoDaDH{e)rH7>j=9gaJ%GvXcu!B>-zShe;U;}PtCBWA%`aMY^XV})@lO6;spSZ3ws zk9r@DJGOj>+5#+1V5u8R?r9Q2DRC}UZt9krmzC@9D0hwe8LPdS;3a82H5KP?Qc%p- zALRspW+f~qIBr{z^3AHwLhd@ggNS+v?Sz8lQz0g3(#WgdMLowb9rZW{W%Yn&p$6U; zeL-U;XPpi&K(3ajn_*XYII7NPCGBqkt9)f&Rjs#LguS;cFrVhQN_0Vg^&w67a{CBB zx@bg22D_;^-c#| z<@1EF-V#-3ux_hX?4FCV0ugf7oo4b*N#7NvFZFxE3~;BLxkQU2*YBjvGMzAOgPU@D zd)a`K@VcW)>m-0i@$*-+o=xGurreZc7RB_B+^DK&2SCKeg6bMv+ps$RQDX(j$<@i| zxALds_8z+|wMi&f3lz8i3}uJ(rZz=D-IS~%L=@>Lwj!#DT$-4BQz=E0t+$H&D|;yy zdl0a*XwWW~uOU|Bn`(Pd&)yhm?*$iEGrKyChWfa@#LNs#@Ban1M|3J4l9-V zDjOMYJ3qHM<o%Jl8*EI+W}mD-aaxDw6`1AG z+!J7je9{oWE`QC;YVyd7TSb0FYpbTwq!BH}K(zXmNqGL5S}5huZdetdY??YHVioaS zO(@aq^Nv_qo)ra&k<=HCFB zRpV^3&=`=dnV6r-P!F*h{(&ffraDzRZItAz9QQj+5-fB+`*#k0CKf8np0anhG+qRG z#QzC>%qoY+#UJ4WTxh#wnxltj8hE~$qT?cAc0TIr1%w;97hAGJRtARCC}Cg-e_ zs7lkx=Iw~%?Q9ZReyTEvzRtT zdfVVsApIHcZ&m?aw|a4&>A!MnQ}53Bim6r&zTJW)L=oDQ-PU z&wv<84{JZwhRu#?igN)Ye4TKT0Ek&j-DBqTGY+RlpY;YM{J6s-&$+9Z-CF_*~E?^u!uRupq8kwnV6|tTZ3?=_LT{ zsKKRiHFFxZ{zp7g0z>*P-@?Klc;q!e-`qv+rsf&}R8sT7v+sbJtasY@|LVo0M`@bt z*MljZ2wz>%XydwwfWqt~6j7Fapm$aSh^+L1J0kxzzV%XjPrS#M+`le-aRM zs**z@H+S@`S;h44gGx9?#*Amz$cuOCs%V(m>T9m>K3mPSV{@fY^9nwz6%55btU12hB0~@hZ1Q^kSX4NQY+z8-lmOlpI9Eb{hOvIkPA0 zF}xLkOD+IRH9Y(BtII#1ughNnQciv&xb@z2HCP${3BgAA+)^I5i*LJ^3+u@h@C=M3 z-t3o!1QxNWr=z$Nt9+Zl1{bHJ+JG_u>YdeV9I;u2X(bcXW!tRd_Unt#lQ4pN?hKxq zL(cb<4{LQex;rjPlP=k23Dvl8-Fx2RxIIQhH)Q2;vD&G6XiBg(QF>qsi zB(<8|Uv$cl|Eo#j_60uwvN6z^mj`*dJ*xu9N#d+j3Zdt|k_2*DcdiPN>`h>U%`Vj5XG zmUot>zr9dDgDEOhAWiHUCff=b8l|-!I#Wy!xcBE{9k6~4MPPMNO+CeA=&*)cXCo&t z-A^U4HPg})Q$6=jBtRx5HI4?o5WDJs+!`Frd=`Xpda!{FB19N?ndVv`lu?&kQ$>S~ z$Df~v$0#dmy&|^IzaERj4HF{WP!XpMrQU?)?1zxl8YQhKMFrortP46@x8k;}mxax5 zrHe*h+k|O&m`lUfp-_@?afR>_GDYOuZO`kqUfjubi4MfE=I+#P zQ-q>w@!Oh=DBd-Vm#v?EJZMt3?3`dESw(lKx9fIJjiP+^hT>24de5)h2+NbVX~HI| zpc*wvf-F%#G#_z#;sCd;=WnQM5~Zg6(O8Cc<{6;KL?@!Ea2Q)PdToOZsAm); zdJ%*0TaTt%(rY>C2@=~XQDRiRe8kuukhE06@>fQT_C4Au`SMhaEQ6`jTG%xaBO$A4 zd1cou!C}Sqj9u%QUMgoEMSZnE_hyhV?Z8$_edEd`rs`zYeEOsgb?pSO4;`dS_lFzM5!8NV!rU$)qEp-<6XMhzXoKp?nyzR{P=mWgs~8LC`uIQ!9{Qc3n)k&!-?SN+`UKHB1T0BJdukYYWP zDUtTW>SqOs+ik1<4i5GIqWrp7tU82uw*x53Y+c5J*ALXKF+*FZJO$*-R}q*a1hf zUh4aZ6&tTx)n>i!h~&Ea`gI3k;7?Qa0;Q%09N}Zu((nxeG-Y+w{&5FMRBG-Tu*iCj z5R^D|t0L||7)TFW2p`6C)iXcT-J_&-u$D<-zp@&_Pjy*N~q3f`|=jf<=9xTMvKvvG5g4PNW|TR|E2&y^?Zzmgi{r z*Tz4!_T!Nyvij4;l%|?2)QhJFfE2sGo4Ai^#}sD%3dpzAlH<>TH3_ACp&L{;pm=WvGeLu?=s7bwbA?YD#ZR5SWI+pXtArb~S{FNP5)l*ASL8xVV0GgK?R^d%+HB zVfs79%&Pb2Dx9B!So&kQ0P&<}4}^q}N>Ss5>?hU+5lN}sZ@~R_>zd(vi2FonHIV%< zL)~W+a@q49G#?@&rH8pG%%uL*1euO6TwSwGI7ErF%W^?CsxL3017r`>V?K zM}^%1bWof1xU4C5a0L8v#p!vLdQO>!kJNmpaT7fg$k~%OT(kACVuflN;^y6E+wvoZ z{`+AokjM(nv4r!nCQm&JLWBQ)G(9KgcI(wR?!zPH338vZo>s2cD0^>@0Fe`}_oqR+ zEzV!Z*Vp#vn{qa%P{m(;wW=9t8r}M%?V(yI zCZz<|=dOBc;IhZ`nXg?F-e2BLMdRCwZE0Y+BXg8YbK=t=_x})b$R_kPcZ`Y^)y3X5=I{N114bzXZ zpm(&RRey8D)^b@=Qo%fVr{_7O^0k)4pU#rUT1jHjcvIRoXeHjQ;~9Dn_CsSUlGIz`Vm7&Vx~SPiYa)GuY36TdKc$e-sk=ty-MC>fKMQvWx8Pz zZxBy!S~}-_;s`5A3h_B{%%BSrKXP4m`HgeYVL#7|7@71uafDbXcCg&RtYoOfQ^Zk4 z)hOSeby?xO#aXS?SnHnrh2gxmvdndw!$@KgOAsMIMh#_DU?EPcMv93v?I%3^Lyli0 zmrSlQ7&#VDg$l{>ga5(rZq35vgqsvj09`M({V@u3?*h%bZGRuzcJl-XJOfu++h1(} zGoPf_+gkJp=-UP^uG^Zt2VCv|gHO6-NRAYs=`R$3_cQvY958ST^sKqPwf1rP0A#4E z)D3WO2#gged)?#Rq0Zj^J=5y%2Xk$5r+Obju>b%724YJ`L;(K){{a7>y{D4^000Sa zNLh0L01FcU01FcV0GgZ_00007bV*G`2j>JG5-m1hR1k0g02w_=L_t(&-i=y$d>qx0 zu6o@)Gd=fcMx*<-EX%ee+wzIAF}5MtV2)tGb~uc)B-m_{1vdFXAPXcAZ(`UG*svii z5WJ8Cf|EcXfRDuZz?Xd6vhMrVNHZhNJ>6aVN6(CAbUFR=&l*juU)OuD>Z`B5S18Le z0003100IyILi|DmqWI_dJ%X`o+^_J@-5R@#fCPZ?k^hOY#v6cR6TqpS9XG#;-~W^5 z;$-8*h6#m3aVwDHI6>fJ_TkvyC(Uo{6HBpYl8XRn!cD}~QIag1ek(BP0|FodBH+N_ zfXQew8cimn$!IWs_~9QB0094Q_im2kIF4}~&vATzf1mm;92+XJ15+*?()h)jIK!#u zjuRbVY_;@U~g|Pn`1$X_TBS+RKT7cI?=`U_tfP ztq&wG%~d84e?3lS?s%7o&-N;V{q^I&hQeVrygZ}z`&-^;h*fFBie9e>nprweyW99~ zi;)B385HQHB~F(bCP*L%OEVptR7*B)yldhFrgBr&6KQ(uQU*y4Ds?A9;n0ZJ`)^O) z+uD0n&yn54ufEYXYRQkttlH71E|WWG9u8}o{aV%i?OLhY(Hr+-8X1xQ^nq(Aq`l%7 zYJPi0uNP64mB~C|Qpcr~8)F_aZsAiVpS*!ruGCgkRQ>XIwh>LPQK7OlpBlAlhynr! z@~*b>m1h4UTMr=sA*4hb0Rl%#y*KTXp|t(qKJfk@{*XF>3Cl)T!J?_q2VZ>gMbGds zVakI=S+3&D&;AlEuC(|H^dpqCS6yN8jMvs3);*ltf&hq^Kv|0EQcu7!9+NJunzn8V1@}E60%ZNt(9SS?JGa+0_aM-Qo25hvMf)J9@D3&oKGqdwEZHw=*MS+)MdX zyr0Bey81LQ8i}|)?t9j0=T)Q;aH>hcP}n;fB0vNLBA+K59R*nizXw>D6GQAjmKGoa zBLE;44^jo<$rqr1C^9@0CDoT@#XaN_G=j}$OL76cdLEd-UM87IdwWMoNy+}-m8`rj zGY$t-bGCo^hUUaNJered;)PH|k`=0~wB$K;n20%|)SMrKo|eu)Z)aF0LIOpSPI|lx zzqkFFpFE%J^QsF?2clQ?tiy+o^mf&u|&^1xMr&SrRJe7k&Nf z%a$$6&CMHgA-W1Oj=PJgY!JUZc(AAW#it%E$jmTCB{|@iySwEVeP>Zb(hPPm6d(vSY>g(o(O^9+@*oVUu!t@>5Gyi zGlq;~MKc#>=?N7;EV=;4`HWiS#OH+oz%kV`l=ojU zbk@!N*4FjNkmvc#oZ{lrd7ZtUcYgmDAi7jrfA-=P0DA9(k9|Ra5szQMl`|&X%yw0$Bx`8|FFBy#Cz0 zdGpj2FXG49%JHNCV^(^972I?aQN2bQ0)#)v>tF8qCtyTvB zc{!O2t7c!RZ|re#YWEH~;{UQ8tS`{zT~ViQtvP8j&TN!%rHll(ZAc?xX^rij&8V9ow|&8l_BFUQv|4eQ_vOTme+fnYCy^<@38i^ zFJ8Jh2uMI%?!Im2j3T2^-_+LpvzMPTX^U^Vam8)xS3R70*UsmD*3l3-b;g!^w}Obt zHD%S^n@iW;_|a`^h6bdRk}}S$#wZrXtXBbnD5=^fNM*R7crJzp4u=3h(CDm=+%#t{ z6Gi~&2j72m!0l;hscGq|u~{uToyc=MLoCQPq*)DSv$40o!RJ4@NotzDwp)m@EIALZP>I&6>4q)~Mg`adYF@k0>=^sZl{mc_5`gqu9hL z5|#EIxx^a_3rpv2x_O`UkQ_b!JoAHIF)+Br!M(8af^}yUa2^y`Cmy>0&2xe27K`dQ=%ge)V!8Pn@ z>*zdr{xqj3!^qqkexTmt?WQ=8&{SlMPckl<9KBNv8*P9r~94b0qqu1^`di3O( z+Ev#qU4PT(?3WOUg?`lgR)8K3_nq6$F7dn@n5p+gNkvY;Ar0@e`+% zhy)=SlW=1ia?BDU*#uw13E(r9rjy4THk!NAjDU!YEnQT7lYt?zHirS|Fip7uUx9Fd-;EV)4Q~G^rYX4lR5|{oSC0i zjhkfSq-gZ~h4TijFwotphC=}tT&QS0PCEb$xCSp>sWosiky^T73Vy_KS^XeO3Zx2V z{$SwJmAbx`)~cYdpjd2b_od3I2}nu|1l%*vJTpzvHDTW<5DdtG7nQxXad(y z-M5r&5j9bNK>gmfl()_ucK+@2-|Rg&XZ@D@Hg8b}8SLw5Zm21qx$x_^-;`Ut7yw@0 z^`l3>_t4_y8_u4q1%Rl(WoWSHLd|}o*)eC{wM(lPEUBJ-%jzmH#(@#V^)z#Y?21B)+|}IzK>iW8`j9=%*4cal0JItb0RH;t z-x9^M4j>_f!v6M_T8A^&V6+%~A+r*(*foHRh|zS4tvUgmL=c~%fXCL>)+0v_@7l2` z+vyC4LjVxnuiz5ktjL+6V!0ggU8w&wdbza@fNTX$(PnfFbcVwLM3$bB2SAnF3e448}(m&wa!LG3z>dv9Fa)@08pUgv{du6s7hy*M1ChI_{leYjh*h@Ul0P} z7%g;s^EQ1+ZguHyWHKQ5o`BabbOdgC;DzU3h;#dihjj4I3tRCC6y+udMbPC{+Iv{k zi)FA#D+LJqWln=Q?;a3zN;IS-4!2^I5J_uu$f0m_)ThogF%&a7c+tq880d4!XS$-H zlOUCsMog9##dP0&_m!8IPZ0ytNLmyt;Nx5`&dihJtkZk6@bw}7pgT25db0)sj1!LLe6#NNF)%ld7>F|9$77BAo=G% z-*xAmcTNQ`6Sxqiq>k}KZ`^qv0q~qTI~@RIf8?&c&EH#GzI4@+!qUn^J8ND0>Qs)N zP}(s0yb{NAGsci1eEay7Z5!7vuPRW1Jm?EdZh5@s;wPRz(qw>z2n=v!&^>B0n(UU; zV;Up?EX?3I4hTF$eGQUazVQ~eaYOP8Pd4|-1lN@2d~msMLAqu}hOO?a&jh`-r25)$ zFj#;7XkN)20n7gsY04(_;PwKgidJNpGu zr_*ay+arOHMyEl>&}tMori+9XSNA|5P`K;{ooI-Sr6`d|$ieg>;`zcHi(+=9izbT^ zhp(~fWNTh_&>t{+@{Bo|2AiF6Ol7|ze^4uGud3OyF$bSIjU797ta{Pn>#OIK%*dBR zk*34vC|(n^9=Q+>MPiG=v4ZXsv)#ihSKlFu#>C^{aHz5VTxFJdW?tU^_L?`A*k@S9 zdcW>q=GUBMi+bAXdfMw2EW0V-8##UG<7gzR#$H=ZT_hAq5=ka#A`@hlt7y^)V6d6B zReD)gPW|JwnnbIXS7>ya7)&un6bpQHf|t)73HV140XRWclngPlBYRlO01#&B1I1!M z&naF-iMV>ZUw`R%ThHh1y)WE-qi8k)K=G2OoiXxJl$R<=_Furku z63m(7I8Fg7m{p+uiB>PF!V5zH1k`F|seAay{y=sXah%1LZZxMwrRb2Wr?gP*?+8MrLMGgTMqBoqE}6Yz_zr z_|_-?SXniDMs5ZoW@M))9|Edz%#d+udcw}pkN>N0^*z@7S!J^q17gVQ@g3dgue&5x zEw|Y-hKC1y-eF0KmXuaRqY>8Mt8YK*Tz zJf9ebdb<6!r!z)R0wCAGhDUv!f+P?0@UH$&g_y?;t_D+v77&Pt0FGa3>KpR(c)E5x zq&agoGTG|VnDjgzMkjF6U?{X{^QO07%bqpU&}YQj`lemKKl$stECe7z0CL(a03gZA zs6SAeA#fg4MnRjWF*jdigVzMjX~D*e;hNpnLLCr>Jg0o;4oOw3jiUpG{@VUiTFYRE zmG2ibG_gbp@blmO4FQ%e(k`fW_V)F~bLS+T18P|FS0fMv0Ht~6`7VpvmX8Fg?|HpVejbnm)>do#iDeJM$Ng_Vq@Uq+r1wJO!=a?cRGh{gFKiZkWP;JtU59aav3dV?Yu7Cie* zDWuR$no57;r@^4T`}S_z_Duk=nK-B2ye17UbZeh%v?zc-D(o_96m`2a_um&T%y)7(xj~WE?RY>-WWta2^#^h?1)T;F=(SG!_R5V< z-@SnduGZN}Q*xn!fx#U+c9?S8zVXwH_nz#dcu{VaN45kzHs4}<>4Nk39}ixB-@R%pMUmOhyH+AR>mQ_B(oLdqLhIE;*+&JTc;Ku5%aZK#`A?oa`G0SGcTuIm zlw%B%COHOeR!v!n@yH3UxxHf{Z=7FNqIL}!UL1+58Z@MGVw{np>lgAq(s7Fu(L_!NO%Gixq$tEMCL$Tua?oTQ=SC(Vn-e<`!d$ zsDM*9{;SRrTxJEFCTyO5qoCk{=I*{dG%sTdb$7J`!)A(lWUNldynD4 zXYm*l*KHpxD!ucrhXw{+XU<*_!~#T=23vQ<{h zx>Q^5_xlS9^N=x76rGN=z^ISU&1D(^LV9L#FlQ!)OkA3Sx7d1mdI5kjHfQcES&>A$ zy=>_Uz1>M_(;#BXF~H;zJWeh_1c0{FCFu?`0zQ9M@JO+ARuJ;(+lRjMRR5Bl^Ye?0 zTLv228ytN*??2qw)LPfjvU$@TsjabyiF1CU4R>sP z?wRi|m^XLT+B<`xFam72<%Xx9`0fXLKG}T#cN9scF(GlRCQM{l#|7ytkO literal 0 HcmV?d00001 diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..14666083 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,105 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- +import pathlib +import sys +from typing import List + +import toml + +ROOT_FOLDER = str(pathlib.Path(__file__).parent.parent.parent) + +# Add the project root to the path +sys.path.insert(0, ROOT_FOLDER) + +with open("../../pyproject.toml") as f: + data = toml.load(f) + +project = "LangChain Benchmarks" +copyright = "2023, Langchain AI" +author = "Langchain AI" + +version = data["tool"]["poetry"]["version"] +release = version + +html_title = project + " " + version + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autodoc.typehints", + "sphinx.ext.autosummary", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "myst_nb", + "sphinx_copybutton", + "IPython.sphinxext.ipython_console_highlighting", +] +source_suffix = [".ipynb", ".html", ".md", ".rst"] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns: List[str] = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_book_theme" + +html_theme_options = { + "path_to_docs": "docs", + "repository_url": "https://github.com/langchain-ai/langchain-benchmarks", + "home_page_in_toc": True, + "show_navbar_depth": 2, + "use_sidenotes": True, + "use_repository_button": True, +} + +html_context = { + "display_github": True, # Integrate GitHub + "github_user": "langchain-ai", # Username + "github_repo": "langchain-benchmarks", # Repo name + "github_version": "main", # Version + "conf_py_path": "/docs/", # Path in the checkout to the docs root +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# These paths are either relative to html_static_path +# or fully qualified paths (eg. https://...) +html_css_files = [ + "css/custom.css", +] + +nb_execution_mode = "off" +autosummary_generate = True diff --git a/docs/source/examples/image_manipulation.ipynb b/docs/source/examples/image_manipulation.ipynb new file mode 100644 index 00000000..6bde5c8d --- /dev/null +++ b/docs/source/examples/image_manipulation.ipynb @@ -0,0 +1,680 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5b3b1d10", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Image Manipulation\n", + "\n", + "Let's built a simple image manipulation API using Pillow and an LLM!\n", + "\n", + "The type of supported operations are limited to the list of functions created.\n", + "\n", + "The list of functions was generated using chat gpt (including type annotations and doc-strings).\n", + "\n", + "`Kork` doesn't know how to use kwargs yet, so the doc-strings that takes kwargs were modified with an explanation of what default value to use." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "85b99fbe", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [ + "remove_cell" + ] + }, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "import sys\n", + "\n", + "sys.path.insert(0, \"../\")" + ] + }, + { + "cell_type": "markdown", + "id": "fb23bdde", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "Let's install Pillow" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "fff547dd", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.1.2\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython3.10 -m pip install --upgrade pip\u001b[0m\n" + ] + } + ], + "source": [ + "!pip install Pillow > /dev/null" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "f5d6533a", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from PIL import Image, ImageOps, ImageFilter" + ] + }, + { + "cell_type": "markdown", + "id": "50c116c4", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "Let's create a functions manually" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "b406a2b6", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def resize(img: Image.Image, width: int, height: int) -> Image:\n", + " \"\"\"Use to resize an image to the given width and height\"\"\"\n", + " return img.resize((width, height))\n", + "\n", + "\n", + "def upscale(img: Image.Image, scale: float) -> Image.Image:\n", + " \"\"\"Upscale the image by the given scale\"\"\"\n", + " height = int(img.height * scale)\n", + " width = int(img.width * scale)\n", + " return img.resize((width, height))\n", + "\n", + "\n", + "def downscale(img: Image.Image, scale: float) -> Image.Image:\n", + " \"\"\"Downscale the image by the given scale\"\"\"\n", + " return upscale(img, 1 / scale)\n", + "\n", + "\n", + "def apply_sepia_filter(img: Image.Image) -> Image:\n", + " \"\"\"Apply a sepia filter.\"\"\"\n", + " # Convert the image to grayscale\n", + " grayscale_image = img.convert(\"L\")\n", + " # Apply sepia filter\n", + " sepia_image = ImageOps.colorize(grayscale_image, \"#704214\", \"#C0C090\")\n", + " return sepia_image" + ] + }, + { + "cell_type": "markdown", + "id": "4b9edeec", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "Below is a list of functions that was created (mostly) by chat gpt, so we don't have to write a lot of boiler plate by hand." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "fd65000b", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "def apply_blur(img: Image.Image, radius: int = 2) -> Image.Image:\n", + " \"\"\"Apply a blur filter to the image. Use default radius of 2, if not specified.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + " radius (int): The blur radius. Default is 2.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.GaussianBlur(radius=radius))\n", + "\n", + "\n", + "def apply_contour(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply a contour filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.CONTOUR())\n", + "\n", + "\n", + "def apply_detail(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply a detail filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + " detail (int): The level of detail enhancement. Default is 2.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.DETAIL())\n", + "\n", + "\n", + "def apply_edge_enhance(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply an edge enhance filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.EDGE_ENHANCE())\n", + "\n", + "\n", + "def apply_edge_enhance_more(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply a stronger edge enhance filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.EDGE_ENHANCE_MORE())\n", + "\n", + "\n", + "def apply_emboss(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply an emboss filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.EMBOSS())\n", + "\n", + "\n", + "def apply_find_edges(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply a find edges filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.FIND_EDGES())\n", + "\n", + "\n", + "def apply_sharpen(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply a sharpen filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.SHARPEN)\n", + "\n", + "\n", + "def apply_smooth(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply a smooth filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.SMOOTH())\n", + "\n", + "\n", + "def apply_smooth_more(img: Image.Image) -> Image.Image:\n", + " \"\"\"Apply a stronger smooth filter to the image.\n", + "\n", + " Args:\n", + " img (Image.Image): The input image.\n", + "\n", + " Returns:\n", + " Image.Image: The filtered image.\n", + " \"\"\"\n", + " return img.filter(ImageFilter.SMOOTH_MORE())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "01fbafa4", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from typing import List, Any, Optional\n", + "\n", + "import langchain\n", + "from langchain.llms import OpenAI\n", + "\n", + "from kork.parser import parse\n", + "from kork import InterpreterResult, Environment, run_interpreter, CodeChain" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "2127ca65", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "llm = OpenAI(temperature=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a14ceef0", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "examples = [\n", + " (\"resize the image to (20, 10)\", \"var result = resize(img, 20, 10)\"),\n", + " (\"apply sepia filter to the image\", \"var result = apply_sepia_filter(img)\"),\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f50f0575", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "examples_in_ast = [(query, parse(code)) for query, code in examples]" + ] + }, + { + "cell_type": "markdown", + "id": "7176d256", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "Let's get a test image from wikipedia." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "efe98c5d", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from io import BytesIO\n", + "import requests\n", + "\n", + "\n", + "def get_image(url: str) -> Image.Image:\n", + " \"\"\"Get an image from the given URL.\"\"\"\n", + " headers = {\n", + " \"User-Agent\": \"User-Agent: KorkDemo/0.0 (https://github.com/eyurtsev/kork/tree/main/kork;)\"\n", + " }\n", + " response = requests.get(url, headers=headers)\n", + "\n", + " # Create a PIL image from the downloaded image data\n", + " img = Image.open(BytesIO(response.content))\n", + " return img\n", + "\n", + "\n", + "url = \"https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Orange_tabby_cat_sitting_on_fallen_leaves-Hisashi-01A.jpg/1024px-Orange_tabby_cat_sitting_on_fallen_leaves-Hisashi-01A.jpg\"\n", + "\n", + "img = get_image(url)\n", + "resize(img, 100, 120)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "cbd4bf04", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "funcs = [\n", + " apply_blur,\n", + " apply_contour,\n", + " apply_detail,\n", + " apply_edge_enhance,\n", + " apply_edge_enhance_more,\n", + " apply_emboss,\n", + " apply_find_edges,\n", + " apply_sharpen,\n", + " apply_smooth,\n", + " apply_smooth_more,\n", + " resize,\n", + " apply_sepia_filter,\n", + " get_image,\n", + " downscale,\n", + " upscale,\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f25b0f5d", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "chain = CodeChain.from_defaults(\n", + " llm=llm,\n", + " examples=examples_in_ast,\n", + " interpreter=run_interpreter,\n", + " context=funcs,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "27d7d6f8-34f3-4018-8bf2-ce926ba42494", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from kork.display import as_html_dict, display_html_results" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "dcec8718-788a-47e5-8f68-e6ddae1a9b9a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "queries = [\n", + " \"resize the image to 100,100 and smooth it a lot\",\n", + " \"resize the image to 100,100 and sharpen\",\n", + " \"resize the image to 100, 100 and blur and apply sepia\",\n", + " \"resize the image to 100, 80, and then downscale it by another factor of 2x.\",\n", + " \"resize the image to 100, 90, and detect edges\",\n", + " \"resize the image to 100, 80, detect edges and finally apply sepia.\",\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "b647147e-a560-493d-a4ff-15fc981a7934", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "code_results = []\n", + "for query in queries:\n", + " code_results.append(chain(inputs={\"query\": query, \"variables\": {\"img\": img}}))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "91acb21f-8002-41a7-9e67-96f3f306fe5d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "html_results = [\n", + " as_html_dict(code_result, result_key=\"result\") for code_result in code_results\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "85f80108-94da-4bf8-979b-173c6f1d01f5", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 querycoderesult
0resize the image to 100,100 and smooth
it a lot
var result = apply_smooth_more(
resize(
img,
100,
100
)
)
1resize the image to 100,100 and sharpen
var result = apply_sharpen(
resize(
img,
100,
100
)
)
2resize the image to 100, 100 and blur
and apply sepia
var result = apply_sepia_filter(
apply_blur(
resize(
img,
100,
100
)
)
)
3resize the image to 100, 80, and then
downscale it by another factor of 2x.
var result = downscale(
resize(
img,
100,
80
),
2
)
4resize the image to 100, 90, and detect
edges
var result = apply_find_edges(
resize(
img,
100,
90
)
)
5resize the image to 100, 80, detect
edges and finally apply sepia.
var result = apply_sepia_filter(
apply_find_edges(
resize(
img,
100,
80
)
)
)
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display_html_results(html_results, columns=[\"query\", \"code\", \"result\"])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/index.md b/docs/source/index.md new file mode 100644 index 00000000..0fd3f31b --- /dev/null +++ b/docs/source/index.md @@ -0,0 +1,8 @@ +# Introduction + + +```{toctree} +:maxdepth: 2 +:caption: Contents + +``` \ No newline at end of file From c748b6ab35739a3acfa94b523abf543fbd667c79 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 16 Nov 2023 16:15:02 -0500 Subject: [PATCH 3/4] x --- poetry.lock | 522 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 515 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 854bfc70..038d1543 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,19 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +[[package]] +name = "accessible-pygments" +version = "0.0.4" +description = "A collection of accessible pygments styles" +optional = false +python-versions = "*" +files = [ + {file = "accessible-pygments-0.0.4.tar.gz", hash = "sha256:e7b57a9b15958e9601c7e9eb07a440c813283545a20973f2574a5f453d0e953e"}, + {file = "accessible_pygments-0.0.4-py2.py3-none-any.whl", hash = "sha256:416c6d8c1ea1c5ad8701903a20fcedf953c6e720d64f33dc47bfb2d3f2fa4e8d"}, +] + +[package.dependencies] +pygments = ">=1.5" + [[package]] name = "aiofiles" version = "22.1.0" @@ -148,6 +162,17 @@ files = [ dev = ["aiounittest (==1.4.1)", "attribution (==1.6.2)", "black (==23.3.0)", "coverage[toml] (==7.2.3)", "flake8 (==5.0.4)", "flake8-bugbear (==23.3.12)", "flit (==3.7.1)", "mypy (==1.2.0)", "ufmt (==2.1.0)", "usort (==1.0.6)"] docs = ["sphinx (==6.1.3)", "sphinx-mdinclude (==0.5.3)"] +[[package]] +name = "alabaster" +version = "0.7.13" +description = "A configurable sidebar-enabled Sphinx theme" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, +] + [[package]] name = "annotated-types" version = "0.6.0" @@ -556,6 +581,20 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -715,6 +754,25 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "dnspython" +version = "2.4.2" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "dnspython-2.4.2-py3-none-any.whl", hash = "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8"}, + {file = "dnspython-2.4.2.tar.gz", hash = "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984"}, +] + +[package.extras] +dnssec = ["cryptography (>=2.6,<42.0)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=0.17.3)", "httpx (>=0.24.1)"] +doq = ["aioquic (>=0.9.20)"] +idna = ["idna (>=2.1,<4.0)"] +trio = ["trio (>=0.14,<0.23)"] +wmi = ["wmi (>=1.5.1,<2.0.0)"] + [[package]] name = "docopt" version = "0.6.2" @@ -725,6 +783,17 @@ files = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] +[[package]] +name = "docutils" +version = "0.17.1" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, +] + [[package]] name = "entrypoints" version = "0.4" @@ -940,6 +1009,17 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + [[package]] name = "importlib-metadata" version = "6.8.0" @@ -1227,6 +1307,33 @@ files = [ importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} referencing = ">=0.31.0" +[[package]] +name = "jupyter-cache" +version = "0.6.1" +description = "A defined interface for working with a cache of jupyter notebooks." +optional = false +python-versions = "~=3.8" +files = [ + {file = "jupyter-cache-0.6.1.tar.gz", hash = "sha256:26f83901143edf4af2f3ff5a91e2d2ad298e46e2cee03c8071d37a23a63ccbfc"}, + {file = "jupyter_cache-0.6.1-py3-none-any.whl", hash = "sha256:2fce7d4975805c77f75bdfc1bc2e82bc538b8e5b1af27f2f5e06d55b9f996a82"}, +] + +[package.dependencies] +attrs = "*" +click = "*" +importlib-metadata = "*" +nbclient = ">=0.2,<0.8" +nbformat = "*" +pyyaml = "*" +sqlalchemy = ">=1.3.12,<3" +tabulate = "*" + +[package.extras] +cli = ["click-log"] +code-style = ["pre-commit (>=2.12,<4.0)"] +rtd = ["ipykernel", "jupytext", "myst-nb", "nbdime", "sphinx-book-theme", "sphinx-copybutton"] +testing = ["coverage", "ipykernel", "jupytext", "matplotlib", "nbdime", "nbformat (>=5.1)", "numpy", "pandas", "pytest (>=6,<8)", "pytest-cov", "pytest-regressions", "sympy"] + [[package]] name = "jupyter-client" version = "7.4.9" @@ -1539,6 +1646,61 @@ files = [ pydantic = ">=1,<3" requests = ">=2,<3" +[[package]] +name = "linkchecker" +version = "10.3.0" +description = "check links in web documents or full websites" +optional = false +python-versions = ">=3.8" +files = [ + {file = "LinkChecker-10.3.0-py3-none-any.whl", hash = "sha256:624f63be599b1d91c3be60d6c5e38412ddbc0f4417c49f0d1936b33c1ce62b09"}, + {file = "LinkChecker-10.3.0.tar.gz", hash = "sha256:1741b9506d3f2b5d1243cc2918f5e5813134fcb77a93dbd38b23e0d088940046"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.8.1" +dnspython = ">=2.0" +requests = ">=2.20" + +[[package]] +name = "livereload" +version = "2.6.3" +description = "Python LiveReload is an awesome tool for web developers" +optional = false +python-versions = "*" +files = [ + {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"}, + {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, +] + +[package.dependencies] +six = "*" +tornado = {version = "*", markers = "python_version > \"2.7\""} + +[[package]] +name = "markdown-it-py" +version = "2.2.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.7" +files = [ + {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, + {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "2.1.3" @@ -1642,6 +1804,36 @@ files = [ [package.dependencies] traitlets = "*" +[[package]] +name = "mdit-py-plugins" +version = "0.3.5" +description = "Collection of plugins for markdown-it-py" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, + {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, +] + +[package.dependencies] +markdown-it-py = ">=1.0.0,<3.0.0" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "mistune" version = "3.0.2" @@ -1794,6 +1986,60 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "myst-nb" +version = "0.17.2" +description = "A Jupyter Notebook Sphinx reader built on top of the MyST markdown parser." +optional = false +python-versions = ">=3.7" +files = [ + {file = "myst-nb-0.17.2.tar.gz", hash = "sha256:0f61386515fab07c73646adca97fff2f69f41e90d313a260217c5bbe419d858b"}, + {file = "myst_nb-0.17.2-py3-none-any.whl", hash = "sha256:132ca4d0f5c308fdd4b6fdaba077712e28e119ccdafd04d6e41b51aac5483494"}, +] + +[package.dependencies] +importlib_metadata = "*" +ipykernel = "*" +ipython = "*" +jupyter-cache = ">=0.5,<0.7" +myst-parser = ">=0.18.0,<0.19.0" +nbclient = "*" +nbformat = ">=5.0,<6.0" +pyyaml = "*" +sphinx = ">=4,<6" +typing-extensions = "*" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["alabaster", "altair", "bokeh", "coconut (>=1.4.3,<2.3.0)", "ipykernel (>=5.5,<6.0)", "ipywidgets", "jupytext (>=1.11.2,<1.12.0)", "matplotlib", "numpy", "pandas", "plotly", "sphinx-book-theme (>=0.3.0,<0.4.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0,<0.5.0)", "sphinxcontrib-bibtex", "sympy"] +testing = ["beautifulsoup4", "coverage (>=6.4,<8.0)", "ipykernel (>=5.5,<6.0)", "ipython (!=8.1.0,<8.5)", "ipywidgets (>=8)", "jupytext (>=1.11.2,<1.12.0)", "matplotlib (>=3.5.3,<3.6)", "nbdime", "numpy", "pandas", "pytest (>=7.1,<8.0)", "pytest-cov (>=3,<5)", "pytest-param-files (>=0.3.3,<0.4.0)", "pytest-regressions", "sympy (>=1.10.1)"] + +[[package]] +name = "myst-parser" +version = "0.18.1" +description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." +optional = false +python-versions = ">=3.7" +files = [ + {file = "myst-parser-0.18.1.tar.gz", hash = "sha256:79317f4bb2c13053dd6e64f9da1ba1da6cd9c40c8a430c447a7b146a594c246d"}, + {file = "myst_parser-0.18.1-py3-none-any.whl", hash = "sha256:61b275b85d9f58aa327f370913ae1bec26ebad372cc99f3ab85c8ec3ee8d9fb8"}, +] + +[package.dependencies] +docutils = ">=0.15,<0.20" +jinja2 = "*" +markdown-it-py = ">=1.0.0,<3.0.0" +mdit-py-plugins = ">=0.3.1,<0.4.0" +pyyaml = "*" +sphinx = ">=4,<6" +typing-extensions = "*" + +[package.extras] +code-style = ["pre-commit (>=2.12,<3.0)"] +linkify = ["linkify-it-py (>=1.0,<2.0)"] +rtd = ["ipython", "sphinx-book-theme", "sphinx-design", "sphinxcontrib.mermaid (>=0.7.1,<0.8.0)", "sphinxext-opengraph (>=0.6.3,<0.7.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] +testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx (<5.2)", "sphinx-pytest"] + [[package]] name = "nbclassic" version = "1.0.0" @@ -1831,25 +2077,25 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p [[package]] name = "nbclient" -version = "0.9.0" +version = "0.7.4" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." optional = false -python-versions = ">=3.8.0" +python-versions = ">=3.7.0" files = [ - {file = "nbclient-0.9.0-py3-none-any.whl", hash = "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15"}, - {file = "nbclient-0.9.0.tar.gz", hash = "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e"}, + {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, + {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, ] [package.dependencies] jupyter-client = ">=6.1.12" jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" nbformat = ">=5.1" -traitlets = ">=5.4" +traitlets = ">=5.3" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" @@ -1910,6 +2156,25 @@ traitlets = ">=5.1" docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] test = ["pep440", "pre-commit", "pytest", "testpath"] +[[package]] +name = "nbsphinx" +version = "0.8.12" +description = "Jupyter Notebook Tools for Sphinx" +optional = false +python-versions = ">=3.6" +files = [ + {file = "nbsphinx-0.8.12-py3-none-any.whl", hash = "sha256:c15b681c7fce287000856f91fe1edac50d29f7b0c15bbc746fbe55c8eb84750b"}, + {file = "nbsphinx-0.8.12.tar.gz", hash = "sha256:76570416cdecbeb21dbf5c3d6aa204ced6c1dd7ebef4077b5c21b8c6ece9533f"}, +] + +[package.dependencies] +docutils = "*" +jinja2 = "*" +nbconvert = "!=5.4" +nbformat = "*" +sphinx = ">=1.8" +traitlets = ">=5" + [[package]] name = "nest-asyncio" version = "1.5.8" @@ -2362,6 +2627,32 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydata-sphinx-theme" +version = "0.13.3" +description = "Bootstrap-based Sphinx theme from the PyData community" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydata_sphinx_theme-0.13.3-py3-none-any.whl", hash = "sha256:bf41ca6c1c6216e929e28834e404bfc90e080b51915bbe7563b5e6fda70354f0"}, + {file = "pydata_sphinx_theme-0.13.3.tar.gz", hash = "sha256:827f16b065c4fd97e847c11c108bf632b7f2ff53a3bca3272f63f3f3ff782ecc"}, +] + +[package.dependencies] +accessible-pygments = "*" +Babel = "*" +beautifulsoup4 = "*" +docutils = "!=0.17.0" +packaging = "*" +pygments = ">=2.7" +sphinx = ">=4.2" +typing-extensions = "*" + +[package.extras] +dev = ["nox", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml"] +doc = ["ablog (>=0.11.0rc2)", "colorama", "ipyleaflet", "jupyter_sphinx", "linkify-it-py", "matplotlib", "myst-nb", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube", "sphinxext-rediraffe", "xarray"] +test = ["codecov", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "pygments" version = "2.16.1" @@ -2964,6 +3255,17 @@ files = [ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + [[package]] name = "soupsieve" version = "2.5" @@ -2975,6 +3277,187 @@ files = [ {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] +[[package]] +name = "sphinx" +version = "4.5.0" +description = "Python documentation generator" +optional = false +python-versions = ">=3.6" +files = [ + {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, + {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, +] + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.18" +imagesize = "*" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] + +[[package]] +name = "sphinx-autobuild" +version = "2021.3.14" +description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." +optional = false +python-versions = ">=3.6" +files = [ + {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, + {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, +] + +[package.dependencies] +colorama = "*" +livereload = "*" +sphinx = "*" + +[package.extras] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "sphinx-book-theme" +version = "1.0.1" +description = "A clean book theme for scientific explanations and documentation with Sphinx" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx_book_theme-1.0.1-py3-none-any.whl", hash = "sha256:d15f8248b3718a9a6be0ba617a32d1591f9fa39c614469bface777ba06a73b75"}, + {file = "sphinx_book_theme-1.0.1.tar.gz", hash = "sha256:927b399a6906be067e49c11ef1a87472f1b1964075c9eea30fb82c64b20aedee"}, +] + +[package.dependencies] +pydata-sphinx-theme = ">=0.13.3" +sphinx = ">=4,<7" + +[package.extras] +code-style = ["pre-commit"] +doc = ["ablog", "docutils (==0.17.1)", "folium", "ipywidgets", "matplotlib", "myst-nb", "nbclient", "numpy", "numpydoc", "pandas", "plotly", "sphinx-copybutton", "sphinx-design", "sphinx-examples", "sphinx-tabs (<=3.4.0)", "sphinx-thebe", "sphinx-togglebutton", "sphinxcontrib-bibtex", "sphinxcontrib-youtube", "sphinxext-opengraph"] +test = ["beautifulsoup4", "coverage", "myst-nb", "pytest", "pytest-cov", "pytest-regressions", "sphinx_thebe"] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +description = "Add a copy button to each of your code cells." +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, + {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, +] + +[package.dependencies] +sphinx = ">=1.8" + +[package.extras] +code-style = ["pre-commit (==2.12.1)"] +rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.4" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, + {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.1" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, + {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + [[package]] name = "sqlalchemy" version = "2.0.23" @@ -3081,6 +3564,20 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + +[package.extras] +widechars = ["wcwidth"] + [[package]] name = "tenacity" version = "8.2.3" @@ -3134,6 +3631,17 @@ webencodings = ">=0.4" doc = ["sphinx", "sphinx_rtd_theme"] test = ["flake8", "isort", "pytest"] +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -3577,4 +4085,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "83e140fae605ab8da7d9259b93fb9648ecabd73a20f766647793b4dcc6287d37" +content-hash = "29519cf50a4c829da986b50f55055d3ad885bc4817119e0e69dddcfef7dfac84" From 04313573c2f031f0beda7082b7590c392a6229ba Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 16 Nov 2023 16:16:00 -0500 Subject: [PATCH 4/4] x --- docs/source/examples/image_manipulation.ipynb | 680 ------------------ 1 file changed, 680 deletions(-) delete mode 100644 docs/source/examples/image_manipulation.ipynb diff --git a/docs/source/examples/image_manipulation.ipynb b/docs/source/examples/image_manipulation.ipynb deleted file mode 100644 index 6bde5c8d..00000000 --- a/docs/source/examples/image_manipulation.ipynb +++ /dev/null @@ -1,680 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "5b3b1d10", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "# Image Manipulation\n", - "\n", - "Let's built a simple image manipulation API using Pillow and an LLM!\n", - "\n", - "The type of supported operations are limited to the list of functions created.\n", - "\n", - "The list of functions was generated using chat gpt (including type annotations and doc-strings).\n", - "\n", - "`Kork` doesn't know how to use kwargs yet, so the doc-strings that takes kwargs were modified with an explanation of what default value to use." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "85b99fbe", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove_cell" - ] - }, - "outputs": [], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "import sys\n", - "\n", - "sys.path.insert(0, \"../\")" - ] - }, - { - "cell_type": "markdown", - "id": "fb23bdde", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "Let's install Pillow" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "fff547dd", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.1.2\u001b[0m\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython3.10 -m pip install --upgrade pip\u001b[0m\n" - ] - } - ], - "source": [ - "!pip install Pillow > /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "f5d6533a", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "from PIL import Image, ImageOps, ImageFilter" - ] - }, - { - "cell_type": "markdown", - "id": "50c116c4", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "Let's create a functions manually" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b406a2b6", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "def resize(img: Image.Image, width: int, height: int) -> Image:\n", - " \"\"\"Use to resize an image to the given width and height\"\"\"\n", - " return img.resize((width, height))\n", - "\n", - "\n", - "def upscale(img: Image.Image, scale: float) -> Image.Image:\n", - " \"\"\"Upscale the image by the given scale\"\"\"\n", - " height = int(img.height * scale)\n", - " width = int(img.width * scale)\n", - " return img.resize((width, height))\n", - "\n", - "\n", - "def downscale(img: Image.Image, scale: float) -> Image.Image:\n", - " \"\"\"Downscale the image by the given scale\"\"\"\n", - " return upscale(img, 1 / scale)\n", - "\n", - "\n", - "def apply_sepia_filter(img: Image.Image) -> Image:\n", - " \"\"\"Apply a sepia filter.\"\"\"\n", - " # Convert the image to grayscale\n", - " grayscale_image = img.convert(\"L\")\n", - " # Apply sepia filter\n", - " sepia_image = ImageOps.colorize(grayscale_image, \"#704214\", \"#C0C090\")\n", - " return sepia_image" - ] - }, - { - "cell_type": "markdown", - "id": "4b9edeec", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "Below is a list of functions that was created (mostly) by chat gpt, so we don't have to write a lot of boiler plate by hand." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "fd65000b", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "def apply_blur(img: Image.Image, radius: int = 2) -> Image.Image:\n", - " \"\"\"Apply a blur filter to the image. Use default radius of 2, if not specified.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - " radius (int): The blur radius. Default is 2.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.GaussianBlur(radius=radius))\n", - "\n", - "\n", - "def apply_contour(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply a contour filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.CONTOUR())\n", - "\n", - "\n", - "def apply_detail(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply a detail filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - " detail (int): The level of detail enhancement. Default is 2.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.DETAIL())\n", - "\n", - "\n", - "def apply_edge_enhance(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply an edge enhance filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.EDGE_ENHANCE())\n", - "\n", - "\n", - "def apply_edge_enhance_more(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply a stronger edge enhance filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.EDGE_ENHANCE_MORE())\n", - "\n", - "\n", - "def apply_emboss(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply an emboss filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.EMBOSS())\n", - "\n", - "\n", - "def apply_find_edges(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply a find edges filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.FIND_EDGES())\n", - "\n", - "\n", - "def apply_sharpen(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply a sharpen filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.SHARPEN)\n", - "\n", - "\n", - "def apply_smooth(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply a smooth filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.SMOOTH())\n", - "\n", - "\n", - "def apply_smooth_more(img: Image.Image) -> Image.Image:\n", - " \"\"\"Apply a stronger smooth filter to the image.\n", - "\n", - " Args:\n", - " img (Image.Image): The input image.\n", - "\n", - " Returns:\n", - " Image.Image: The filtered image.\n", - " \"\"\"\n", - " return img.filter(ImageFilter.SMOOTH_MORE())" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "01fbafa4", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "from typing import List, Any, Optional\n", - "\n", - "import langchain\n", - "from langchain.llms import OpenAI\n", - "\n", - "from kork.parser import parse\n", - "from kork import InterpreterResult, Environment, run_interpreter, CodeChain" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "2127ca65", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "llm = OpenAI(temperature=0)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "a14ceef0", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "examples = [\n", - " (\"resize the image to (20, 10)\", \"var result = resize(img, 20, 10)\"),\n", - " (\"apply sepia filter to the image\", \"var result = apply_sepia_filter(img)\"),\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "f50f0575", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "examples_in_ast = [(query, parse(code)) for query, code in examples]" - ] - }, - { - "cell_type": "markdown", - "id": "7176d256", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "Let's get a test image from wikipedia." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "efe98c5d", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from io import BytesIO\n", - "import requests\n", - "\n", - "\n", - "def get_image(url: str) -> Image.Image:\n", - " \"\"\"Get an image from the given URL.\"\"\"\n", - " headers = {\n", - " \"User-Agent\": \"User-Agent: KorkDemo/0.0 (https://github.com/eyurtsev/kork/tree/main/kork;)\"\n", - " }\n", - " response = requests.get(url, headers=headers)\n", - "\n", - " # Create a PIL image from the downloaded image data\n", - " img = Image.open(BytesIO(response.content))\n", - " return img\n", - "\n", - "\n", - "url = \"https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Orange_tabby_cat_sitting_on_fallen_leaves-Hisashi-01A.jpg/1024px-Orange_tabby_cat_sitting_on_fallen_leaves-Hisashi-01A.jpg\"\n", - "\n", - "img = get_image(url)\n", - "resize(img, 100, 120)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "cbd4bf04", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "funcs = [\n", - " apply_blur,\n", - " apply_contour,\n", - " apply_detail,\n", - " apply_edge_enhance,\n", - " apply_edge_enhance_more,\n", - " apply_emboss,\n", - " apply_find_edges,\n", - " apply_sharpen,\n", - " apply_smooth,\n", - " apply_smooth_more,\n", - " resize,\n", - " apply_sepia_filter,\n", - " get_image,\n", - " downscale,\n", - " upscale,\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "f25b0f5d", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "pycharm": { - "name": "#%%\n" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "chain = CodeChain.from_defaults(\n", - " llm=llm,\n", - " examples=examples_in_ast,\n", - " interpreter=run_interpreter,\n", - " context=funcs,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "27d7d6f8-34f3-4018-8bf2-ce926ba42494", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from kork.display import as_html_dict, display_html_results" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "dcec8718-788a-47e5-8f68-e6ddae1a9b9a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "queries = [\n", - " \"resize the image to 100,100 and smooth it a lot\",\n", - " \"resize the image to 100,100 and sharpen\",\n", - " \"resize the image to 100, 100 and blur and apply sepia\",\n", - " \"resize the image to 100, 80, and then downscale it by another factor of 2x.\",\n", - " \"resize the image to 100, 90, and detect edges\",\n", - " \"resize the image to 100, 80, detect edges and finally apply sepia.\",\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "b647147e-a560-493d-a4ff-15fc981a7934", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "code_results = []\n", - "for query in queries:\n", - " code_results.append(chain(inputs={\"query\": query, \"variables\": {\"img\": img}}))" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "91acb21f-8002-41a7-9e67-96f3f306fe5d", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "html_results = [\n", - " as_html_dict(code_result, result_key=\"result\") for code_result in code_results\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "85f80108-94da-4bf8-979b-173c6f1d01f5", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
 querycoderesult
0resize the image to 100,100 and smooth
it a lot
var result = apply_smooth_more(
resize(
img,
100,
100
)
)
1resize the image to 100,100 and sharpen
var result = apply_sharpen(
resize(
img,
100,
100
)
)
2resize the image to 100, 100 and blur
and apply sepia
var result = apply_sepia_filter(
apply_blur(
resize(
img,
100,
100
)
)
)
3resize the image to 100, 80, and then
downscale it by another factor of 2x.
var result = downscale(
resize(
img,
100,
80
),
2
)
4resize the image to 100, 90, and detect
edges
var result = apply_find_edges(
resize(
img,
100,
90
)
)
5resize the image to 100, 80, detect
edges and finally apply sepia.
var result = apply_sepia_filter(
apply_find_edges(
resize(
img,
100,
80
)
)
)
\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "display_html_results(html_results, columns=[\"query\", \"code\", \"result\"])" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}