From 734b8bd47c12217b7017622462883dbd7548ec34 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Wed, 14 Sep 2022 17:18:57 +0200 Subject: [PATCH 01/61] 0.7.0-beta.0 release --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c82e2f0a..1b3121d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-bgp-models" -version = "0.6.0" +version = "0.7.0-beta.0" description = "Nautobot BGP Models Plugin" authors = ["Network to Code, LLC "] From 03292244d4791d2792038d5f703716b41b8721a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Sep 2022 00:44:41 +0000 Subject: [PATCH 02/61] Bump oauthlib from 3.2.0 to 3.2.1 Bumps [oauthlib](https://github.com/oauthlib/oauthlib) from 3.2.0 to 3.2.1. - [Release notes](https://github.com/oauthlib/oauthlib/releases) - [Changelog](https://github.com/oauthlib/oauthlib/blob/master/CHANGELOG.rst) - [Commits](https://github.com/oauthlib/oauthlib/compare/v3.2.0...v3.2.1) --- updated-dependencies: - dependency-name: oauthlib dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 723 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 620 insertions(+), 103 deletions(-) diff --git a/poetry.lock b/poetry.lock index 228b05ca..d1e16cd5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -29,7 +29,7 @@ python-versions = ">=3.7" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "astroid" @@ -41,6 +41,7 @@ python-versions = ">=3.6.2" [package.dependencies] lazy-object-proxy = ">=1.4.0" +setuptools = ">=20.0" typed-ast = {version = ">=1.4.0,<2.0", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} wrapt = ">=1.11,<2" @@ -65,10 +66,10 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] [[package]] name = "bandit" @@ -85,9 +86,9 @@ PyYAML = ">=5.3.1" stevedore = ">=1.20.0" [package.extras] -test = ["coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml", "beautifulsoup4 (>=4.8.0)", "pylint (==1.9.4)"] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"] toml = ["toml"] -yaml = ["pyyaml"] +yaml = ["PyYAML"] [[package]] name = "billiard" @@ -174,7 +175,7 @@ s3 = ["boto3 (>=1.9.125)"] slmq = ["softlayer-messaging (>=1.0.3)"] solar = ["ephem"] sqlalchemy = ["sqlalchemy"] -sqs = ["kombu"] +sqs = ["kombu[sqs]"] tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] @@ -245,7 +246,7 @@ python-versions = "*" click = ">=4.0" [package.extras] -dev = ["pytest (>=3.6)", "pytest-cov", "wheel", "coveralls"] +dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] [[package]] name = "click-repl" @@ -316,12 +317,12 @@ python-versions = ">=3.6" cffi = ">=1.12" [package.extras] -docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] -docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx_rtd_theme"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] sdist = ["setuptools_rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] [[package]] name = "defusedxml" @@ -343,7 +344,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"] +dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "dill" @@ -665,7 +666,7 @@ Django = "*" [package.extras] gunicorn = ["gunicorn"] pyuwsgi = ["pyuwsgi"] -test = ["pytest", "mock"] +test = ["mock", "pytest"] uvicorn = ["uvicorn (>0.6)"] waitress = ["waitress"] @@ -799,7 +800,7 @@ six = ">=1.10.0,<2" [package.extras] django = ["graphene-django"] sqlalchemy = ["graphene-sqlalchemy"] -test = ["pytest", "pytest-benchmark", "pytest-cov", "pytest-mock", "fastdiff (==0.2.0)", "snapshottest", "coveralls", "promise", "six", "mock", "pytz", "iso8601"] +test = ["coveralls", "fastdiff (==0.2.0)", "iso8601", "mock", "promise", "pytest", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytz", "six", "snapshottest"] [[package]] name = "graphene-django" @@ -819,9 +820,9 @@ six = ">=1.10.0" text-unidecode = "*" [package.extras] -dev = ["black (==19.10b0)", "flake8 (==3.7.9)", "flake8-black (==0.1.1)", "flake8-bugbear (==20.1.4)", "pytest (>=3.6.3)", "pytest-cov", "coveralls", "mock", "pytz", "pytest-django (>=3.3.2)", "djangorestframework (>=3.6.3)", "django-filter (<2)", "django-filter (>=2)"] +dev = ["black (==19.10b0)", "coveralls", "django-filter (<2)", "django-filter (>=2)", "djangorestframework (>=3.6.3)", "flake8 (==3.7.9)", "flake8-black (==0.1.1)", "flake8-bugbear (==20.1.4)", "mock", "pytest (>=3.6.3)", "pytest-cov", "pytest-django (>=3.3.2)", "pytz"] rest_framework = ["djangorestframework (>=3.6.3)"] -test = ["pytest (>=3.6.3)", "pytest-cov", "coveralls", "mock", "pytz", "pytest-django (>=3.3.2)", "djangorestframework (>=3.6.3)", "django-filter (<2)", "django-filter (>=2)"] +test = ["coveralls", "django-filter (<2)", "django-filter (>=2)", "djangorestframework (>=3.6.3)", "mock", "pytest (>=3.6.3)", "pytest-cov", "pytest-django (>=3.3.2)", "pytz"] [[package]] name = "graphene-django-optimizer" @@ -846,7 +847,7 @@ six = ">=1.10.0" [package.extras] gevent = ["gevent (>=1.1)"] -test = ["six (==1.14.0)", "pyannotate (==1.2.0)", "pytest (==4.6.10)", "pytest-django (==3.9.0)", "pytest-cov (==2.8.1)", "coveralls (==1.11.1)", "cython (==0.29.17)", "gevent (==1.5.0)", "pytest-benchmark (==3.2.3)", "pytest-mock (==2.0.0)"] +test = ["coveralls (==1.11.1)", "cython (==0.29.17)", "gevent (==1.5.0)", "pyannotate (==1.2.0)", "pytest (==4.6.10)", "pytest-benchmark (==3.2.3)", "pytest-cov (==2.8.1)", "pytest-django (==3.9.0)", "pytest-mock (==2.0.0)", "six (==1.14.0)"] [[package]] name = "graphql-relay" @@ -882,8 +883,8 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] [[package]] name = "importlib-resources" @@ -897,8 +898,8 @@ python-versions = ">=3.7" zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] +docs = ["jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [[package]] name = "inflection" @@ -925,10 +926,10 @@ optional = false python-versions = ">=3.6.1,<4.0" [package.extras] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] -requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] +requirements_deprecated_finder = ["pip-api", "pipreqs"] [[package]] name = "itypes" @@ -1099,12 +1100,12 @@ social-auth-app-django = ">=5.0.0,<5.1.0" svgwrite = ">=1.4.1,<1.5.0" [package.extras] -all = ["django-auth-ldap (>=4.0.0,<4.1.0)", "django-storages (>=1.12.3,<1.13.0)", "mysqlclient (>=2.1.0,<2.2.0)", "napalm (>=3.3.1,<3.4.0)", "social-auth-core[saml,openidconnect] (>=4.2.0,<4.3.0)"] +all = ["django-auth-ldap (>=4.0.0,<4.1.0)", "django-storages (>=1.12.3,<1.13.0)", "mysqlclient (>=2.1.0,<2.2.0)", "napalm (>=3.3.1,<3.4.0)", "social-auth-core[openidconnect,saml] (>=4.2.0,<4.3.0)"] ldap = ["django-auth-ldap (>=4.0.0,<4.1.0)"] -remote_storage = ["django-storages (>=1.12.3,<1.13.0)"] mysql = ["mysqlclient (>=2.1.0,<2.2.0)"] napalm = ["napalm (>=3.3.1,<3.4.0)"] -sso = ["social-auth-core[saml,openidconnect] (>=4.2.0,<4.3.0)"] +remote_storage = ["django-storages (>=1.12.3,<1.13.0)"] +sso = ["social-auth-core[openidconnect,saml] (>=4.2.0,<4.3.0)"] [[package]] name = "netaddr" @@ -1124,7 +1125,7 @@ python-versions = ">=3.6,<4.0" [[package]] name = "oauthlib" -version = "3.2.0" +version = "3.2.1" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" category = "main" optional = false @@ -1179,8 +1180,8 @@ optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] -test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] [[package]] name = "prometheus-client" @@ -1205,7 +1206,7 @@ python-versions = "*" six = "*" [package.extras] -test = ["pytest (>=2.7.3)", "pytest-cov", "coveralls", "futures", "pytest-benchmark", "mock"] +test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", "pytest-cov"] [[package]] name = "prompt-toolkit" @@ -1282,9 +1283,9 @@ python-versions = ">=3.6" [package.extras] crypto = ["cryptography (>=3.3.1)"] -dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.3.1)", "mypy", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pylint" @@ -1320,8 +1321,8 @@ pylint = ">=2.0,<3" pylint-plugin-utils = ">=0.7" [package.extras] -for_tests = ["django-tables2", "factory-boy", "coverage", "pytest", "wheel", "django-tastypie", "pylint (>=2.13)"] -with_django = ["django"] +for_tests = ["coverage", "django-tables2", "django-tastypie", "factory-boy", "pylint (>=2.13)", "pytest", "wheel"] +with_django = ["Django"] [[package]] name = "pylint-plugin-utils" @@ -1343,7 +1344,7 @@ optional = false python-versions = ">=3.6.8" [package.extras] -diagrams = ["railroad-diagrams", "jinja2"] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pyrsistent" @@ -1513,6 +1514,19 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "setuptools" +version = "65.3.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "singledispatch" version = "3.7.0" @@ -1525,8 +1539,8 @@ python-versions = ">=2.6" six = "*" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-flake8", "pytest-cov", "pytest-black (>=0.3.7)", "unittest2", "pytest-checkdocs (>=2.4)"] +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +testing = ["pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-flake8", "unittest2"] [[package]] name = "six" @@ -1581,11 +1595,11 @@ requests = ">=2.9.1" requests-oauthlib = ">=0.6.1" [package.extras] -all = ["python-jose (>=3.0.0)", "python3-saml (>=1.2.1)", "lxml (<4.7)", "cryptography (>=2.1.1)"] -allpy3 = ["python-jose (>=3.0.0)", "python3-saml (>=1.2.1)", "lxml (<4.7)", "cryptography (>=2.1.1)"] +all = ["cryptography (>=2.1.1)", "lxml (<4.7)", "python-jose (>=3.0.0)", "python3-saml (>=1.2.1)"] +allpy3 = ["cryptography (>=2.1.1)", "lxml (<4.7)", "python-jose (>=3.0.0)", "python3-saml (>=1.2.1)"] azuread = ["cryptography (>=2.1.1)"] openidconnect = ["python-jose (>=3.0.0)"] -saml = ["python3-saml (>=1.2.1)", "lxml (<4.7)"] +saml = ["lxml (<4.7)", "python3-saml (>=1.2.1)"] [[package]] name = "sqlparse" @@ -1677,8 +1691,8 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" [package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] @@ -1716,6 +1730,7 @@ python-versions = ">=3.6" [package.dependencies] pathspec = ">=0.5.3" pyyaml = "*" +setuptools = "*" [[package]] name = "zipp" @@ -1726,8 +1741,8 @@ optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] +docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] +testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" @@ -1747,9 +1762,18 @@ asgiref = [ {file = "asgiref-3.5.2-py3-none-any.whl", hash = "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4"}, {file = "asgiref-3.5.2.tar.gz", hash = "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"}, ] -astroid = [] -async-timeout = [] -attrs = [] +astroid = [ + {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, + {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, +] +async-timeout = [ + {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, + {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, +] +attrs = [ + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, +] bandit = [ {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, @@ -1758,7 +1782,31 @@ billiard = [ {file = "billiard-3.6.4.0-py3-none-any.whl", hash = "sha256:87103ea78fa6ab4d5c751c4909bcff74617d985de7fa8b672cf8618afd5a875b"}, {file = "billiard-3.6.4.0.tar.gz", hash = "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547"}, ] -black = [] +black = [ + {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"}, + {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"}, + {file = "black-22.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e"}, + {file = "black-22.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def"}, + {file = "black-22.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"}, + {file = "black-22.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d"}, + {file = "black-22.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256"}, + {file = "black-22.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78"}, + {file = "black-22.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849"}, + {file = "black-22.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c"}, + {file = "black-22.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90"}, + {file = "black-22.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f"}, + {file = "black-22.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e"}, + {file = "black-22.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6"}, + {file = "black-22.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad"}, + {file = "black-22.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf"}, + {file = "black-22.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c"}, + {file = "black-22.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2"}, + {file = "black-22.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee"}, + {file = "black-22.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b"}, + {file = "black-22.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4"}, + {file = "black-22.6.0-py3-none-any.whl", hash = "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c"}, + {file = "black-22.6.0.tar.gz", hash = "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9"}, +] cached-property = [ {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, @@ -1767,9 +1815,80 @@ celery = [ {file = "celery-5.2.7-py3-none-any.whl", hash = "sha256:138420c020cd58d6707e6257b6beda91fd39af7afde5d36c6334d175302c0e14"}, {file = "celery-5.2.7.tar.gz", hash = "sha256:fafbd82934d30f8a004f81e8f7a062e31413a23d444be8ee3326553915958c6d"}, ] -certifi = [] -cffi = [] -charset-normalizer = [] +certifi = [ + {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, + {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, +] +cffi = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, + {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, +] click = [ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, @@ -1852,7 +1971,30 @@ coverage = [ {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, ] -cryptography = [] +cryptography = [ + {file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884"}, + {file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6"}, + {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046"}, + {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5"}, + {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b"}, + {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8"}, + {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280"}, + {file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3"}, + {file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59"}, + {file = "cryptography-37.0.4-cp36-abi3-win32.whl", hash = "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157"}, + {file = "cryptography-37.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327"}, + {file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b"}, + {file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9"}, + {file = "cryptography-37.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67"}, + {file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d"}, + {file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282"}, + {file = "cryptography-37.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa"}, + {file = "cryptography-37.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441"}, + {file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596"}, + {file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a"}, + {file = "cryptography-37.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab"}, + {file = "cryptography-37.0.4.tar.gz", hash = "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82"}, +] defusedxml = [ {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, @@ -1865,13 +2007,22 @@ dill = [ {file = "dill-0.3.5.1-py2.py3-none-any.whl", hash = "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302"}, {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"}, ] -django = [] -django-ajax-tables = [] +django = [ + {file = "Django-3.2.14-py3-none-any.whl", hash = "sha256:a8681e098fa60f7c33a4b628d6fcd3fe983a0939ff1301ecacac21d0b38bad56"}, + {file = "Django-3.2.14.tar.gz", hash = "sha256:677182ba8b5b285a4e072f3ac17ceee6aff1b5ce77fd173cc5b6a2d3dc022fcf"}, +] +django-ajax-tables = [ + {file = "django_ajax_tables-1.1.1-py3-none-any.whl", hash = "sha256:62e0138949153c0a994eefbf469f5496b1ad98bc073e170bc021a1aada7a32d0"}, + {file = "django_ajax_tables-1.1.1.tar.gz", hash = "sha256:5a7e7bc7940aa6332a564916cde22010a858a3d29fc1090ce8061010ec76337c"}, +] django-appconf = [ {file = "django-appconf-1.0.5.tar.gz", hash = "sha256:be3db0be6c81fa84742000b89a81c016d70ae66a7ccb620cdef592b1f1a6aaa4"}, {file = "django_appconf-1.0.5-py3-none-any.whl", hash = "sha256:ae9f864ee1958c815a965ed63b3fba4874eec13de10236ba063a788f9a17389d"}, ] -django-cacheops = [] +django-cacheops = [ + {file = "django-cacheops-6.0.tar.gz", hash = "sha256:78e161ebd96a32e28e19ec7da31f2afed9e62a79726b8b5f0ed12dd16c2e5841"}, + {file = "django_cacheops-6.0-py2.py3-none-any.whl", hash = "sha256:ee38b969c9fc68f7c88e769b6c811e19563cca1ae08210d9f553ff758b6c3e17"}, +] django-celery-beat = [ {file = "django-celery-beat-2.2.1.tar.gz", hash = "sha256:97ae5eb309541551bdb07bf60cc57cadacf42a74287560ced2d2c06298620234"}, {file = "django_celery_beat-2.2.1-py2.py3-none-any.whl", hash = "sha256:ab43049634fd18dc037927d7c2c7d5f67f95283a20ebbda55f42f8606412e66c"}, @@ -1880,7 +2031,10 @@ django-constance = [ {file = "django-constance-2.8.0.tar.gz", hash = "sha256:0a492454acc78799ce7b9f7a28a00c53427d513f34f8bf6fdc90a46d8864b2af"}, {file = "django_constance-2.8.0-py3-none-any.whl", hash = "sha256:60fec73e397d5f4f7440f611b18d3e7ce5342647f316fedc47b62e1411c849e7"}, ] -django-cors-headers = [] +django-cors-headers = [ + {file = "django-cors-headers-3.10.1.tar.gz", hash = "sha256:b5a874b492bcad99f544bb76ef679472259eb41ee5644ca62d1a94ddb26b7f6e"}, + {file = "django_cors_headers-3.10.1-py3-none-any.whl", hash = "sha256:1390b5846e9835b0911e2574409788af87cd9154246aafbdc8ec546c93698fe6"}, +] django-cryptography = [ {file = "django-cryptography-1.0.tar.gz", hash = "sha256:13de5cf8f1250744c104b9e24774d03aa6d8488959dd40cdc016934043652445"}, {file = "django_cryptography-1.0-py3-none-any.whl", hash = "sha256:0a99980b1cee7cc5e52f9b20b322620fea7cc124d770273e7bd285b20fd9d222"}, @@ -1888,22 +2042,58 @@ django-cryptography = [ django-db-file-storage = [ {file = "django-db-file-storage-0.5.5.tar.gz", hash = "sha256:5d5da694b78ab202accab4508b958e0e37b3d146310e76f6f6125e1bdeaaad14"}, ] -django-debug-toolbar = [] +django-debug-toolbar = [ + {file = "django-debug-toolbar-3.5.0.tar.gz", hash = "sha256:97965f2630692de316ea0c1ca5bfa81660d7ba13146dbc6be2059cf55b35d0e5"}, + {file = "django_debug_toolbar-3.5.0-py3-none-any.whl", hash = "sha256:89a52128309eb4da12738801ff0c202d2ff8730d1c3225fac6acf630c303e661"}, +] django-extensions = [ {file = "django-extensions-3.1.5.tar.gz", hash = "sha256:28e1e1bf49f0e00307ba574d645b0af3564c981a6dfc87209d48cb98f77d0b1a"}, {file = "django_extensions-3.1.5-py3-none-any.whl", hash = "sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069"}, ] -django-filter = [] -django-health-check = [] -django-jinja = [] -django-js-asset = [] -django-mptt = [] -django-picklefield = [] -django-prometheus = [] -django-redis = [] -django-rq = [] -django-tables2 = [] -django-taggit = [] +django-filter = [ + {file = "django-filter-21.1.tar.gz", hash = "sha256:632a251fa8f1aadb4b8cceff932bb52fe2f826dd7dfe7f3eac40e5c463d6836e"}, + {file = "django_filter-21.1-py3-none-any.whl", hash = "sha256:f4a6737a30104c98d2e2a5fb93043f36dd7978e0c7ddc92f5998e85433ea5063"}, +] +django-health-check = [ + {file = "django-health-check-3.16.5.tar.gz", hash = "sha256:1edfd49293ccebbce29f9da609c407f307aee240ab799ab4201031341ae78c0f"}, + {file = "django_health_check-3.16.5-py2.py3-none-any.whl", hash = "sha256:8d66781a0ea82b1a8b44878187b38a27370e94f18287312e39be0593e72d8983"}, +] +django-jinja = [ + {file = "django-jinja-2.10.2.tar.gz", hash = "sha256:bfdfbb55c1f5a679d69ad575d550c4707d386634009152efe014089f3c4d1412"}, + {file = "django_jinja-2.10.2-py3-none-any.whl", hash = "sha256:dd003ec1c95c0989eb28a538831bced62b1b61da551cb44a5dfd708fcf75589f"}, +] +django-js-asset = [ + {file = "django_js_asset-2.0.0-py3-none-any.whl", hash = "sha256:86f9f300d682537ddaf0487dc2ab356581b8f50c069bdba91d334a46e449f923"}, + {file = "django_js_asset-2.0.0.tar.gz", hash = "sha256:adc1ee1efa853fad42054b540c02205344bb406c9bddf87c9e5377a41b7db90f"}, +] +django-mptt = [ + {file = "django-mptt-0.13.4.tar.gz", hash = "sha256:80c9fb34df7796a4e5af0cb6b8ade3697555b1aa438bd07a01f32b3ab5202b63"}, + {file = "django_mptt-0.13.4-py3-none-any.whl", hash = "sha256:75745b621ae31d97957ed924155a750dfa8cacd9543799ada2d713fd6bc3f5c7"}, +] +django-picklefield = [ + {file = "django-picklefield-3.1.tar.gz", hash = "sha256:c786cbeda78d6def2b43bff4840d19787809c8909f7ad683961703060398d356"}, + {file = "django_picklefield-3.1-py3-none-any.whl", hash = "sha256:d77c504df7311e8ec14e8b779f10ca6fec74de6c7f8e2c136e1ef60cf955125d"}, +] +django-prometheus = [ + {file = "django-prometheus-2.2.0.tar.gz", hash = "sha256:240378a1307c408bd5fc85614a3a57f1ce633d4a222c9e291e2bbf325173b801"}, + {file = "django_prometheus-2.2.0-py2.py3-none-any.whl", hash = "sha256:e6616770d8820b8834762764bf1b76ec08e1b98e72a6f359d488a2e15fe3537c"}, +] +django-redis = [ + {file = "django-redis-5.2.0.tar.gz", hash = "sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de"}, + {file = "django_redis-5.2.0-py3-none-any.whl", hash = "sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026"}, +] +django-rq = [ + {file = "django-rq-2.5.1.tar.gz", hash = "sha256:f08486602664d73a6e335872c868d79663e380247e6307496d01b8fa770fefd8"}, + {file = "django_rq-2.5.1-py2.py3-none-any.whl", hash = "sha256:7be1e10e7091555f9f36edf100b0dbb205ea2b98683d74443d2bdf3c6649a03f"}, +] +django-tables2 = [ + {file = "django-tables2-2.4.1.tar.gz", hash = "sha256:6c72dd208358539e789e4c0efd7d151e43283a4aa4093a35f44c43489e7ddeaa"}, + {file = "django_tables2-2.4.1-py2.py3-none-any.whl", hash = "sha256:50762bf3d7c61a4eb70e763c3e278650d7266bb78d0497fc8fafcf4e507c9a64"}, +] +django-taggit = [ + {file = "django-taggit-1.5.1.tar.gz", hash = "sha256:e5bb62891f458d55332e36a32e19c08d20142c43f74bc5656c803f8af25c084a"}, + {file = "django_taggit-1.5.1-py3-none-any.whl", hash = "sha256:dfe9e9c10b5929132041de0c00093ef0072c73c2a97d0f74a818ae50fa77149a"}, +] django-timezone-field = [ {file = "django-timezone-field-4.1.2.tar.gz", hash = "sha256:cffac62452d060e365938aa9c9f7b72d70d8b26b9c60243bce227b35abd1b9df"}, {file = "django_timezone_field-4.1.2-py3-none-any.whl", hash = "sha256:897c06e40b619cf5731a30d6c156886a7c64cba3a90364832148da7ef32ccf36"}, @@ -1912,15 +2102,30 @@ django-webserver = [ {file = "django-webserver-1.2.0.tar.gz", hash = "sha256:c976979d15b5ff9a212f7904d3b779e22219aebb4857860fcaf20e4e40f1da40"}, {file = "django_webserver-1.2.0-py2.py3-none-any.whl", hash = "sha256:09200631f266484b9e944e38e92681d6e9aa7d90d089a5c86d5fb08fddad84fe"}, ] -djangorestframework = [] -drf-spectacular = [] -drf-spectacular-sidecar = [] -drf-yasg = [] +djangorestframework = [ + {file = "djangorestframework-3.13.1-py3-none-any.whl", hash = "sha256:24c4bf58ed7e85d1fe4ba250ab2da926d263cd57d64b03e8dcef0ac683f8b1aa"}, + {file = "djangorestframework-3.13.1.tar.gz", hash = "sha256:0c33407ce23acc68eca2a6e46424b008c9c02eceb8cf18581921d0092bc1f2ee"}, +] +drf-spectacular = [ + {file = "drf-spectacular-0.22.1.tar.gz", hash = "sha256:866e16ddaae167a1234c76cd8c351161373551db994ce9665b347b32d5daf38b"}, + {file = "drf_spectacular-0.22.1-py3-none-any.whl", hash = "sha256:17ac5e31e5d6150dd5fa10843b429202f4f38069202acc44394cc5a771de63d9"}, +] +drf-spectacular-sidecar = [ + {file = "drf-spectacular-sidecar-2022.7.1.tar.gz", hash = "sha256:2dd95042a515e860993bbf945a49b78c454b824507a370bd8ba43f2b51b76399"}, + {file = "drf_spectacular_sidecar-2022.7.1-py3-none-any.whl", hash = "sha256:f0c304a6f56c3064f697d6ab815f632e4c3c9d385e79c6a9e69d6d5aa210ab09"}, +] +drf-yasg = [ + {file = "drf-yasg-1.20.3.tar.gz", hash = "sha256:1c66929fba56724c477951ab07266e69bbd0cb280e84b675957df19e3b567958"}, + {file = "drf_yasg-1.20.3-py2.py3-none-any.whl", hash = "sha256:915a16dae564143ebcbc1787e4aaad38062ccd95d1e6f97c2d33086575335bb8"}, +] flake8 = [ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] -funcy = [] +funcy = [ + {file = "funcy-1.17-py2.py3-none-any.whl", hash = "sha256:ba7af5e58bfc69321aaf860a1547f18d35e145706b95d1b3c966abc4f0b60309"}, + {file = "funcy-1.17.tar.gz", hash = "sha256:40b9b9a88141ae6a174df1a95861f2b82f2fdc17669080788b73a3ed9370e968"}, +] gitdb = [ {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, @@ -1956,7 +2161,10 @@ importlib-metadata = [ {file = "importlib_metadata-4.4.0-py3-none-any.whl", hash = "sha256:960d52ba7c21377c990412aca380bf3642d734c2eaab78a2c39319f67c6a5786"}, {file = "importlib_metadata-4.4.0.tar.gz", hash = "sha256:e592faad8de1bda9fe920cf41e15261e7131bcf266c30306eec00e8e225c1dd5"}, ] -importlib-resources = [] +importlib-resources = [ + {file = "importlib_resources-5.8.0-py3-none-any.whl", hash = "sha256:7952325ffd516c05a8ad0858c74dff2c3343f136fe66a6002b2623dd1d43f223"}, + {file = "importlib_resources-5.8.0.tar.gz", hash = "sha256:568c9f16cb204f9decc8d6d24a572eeea27dacbb4cee9e6b03a8025736769751"}, +] inflection = [ {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, @@ -1973,8 +2181,14 @@ itypes = [ {file = "itypes-1.2.0-py2.py3-none-any.whl", hash = "sha256:03da6872ca89d29aef62773672b2d408f490f80db48b23079a4b194c86dd04c6"}, {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, ] -jinja2 = [] -jsonschema = [] +jinja2 = [ + {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, + {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, +] +jsonschema = [ + {file = "jsonschema-4.4.0-py3-none-any.whl", hash = "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823"}, + {file = "jsonschema-4.4.0.tar.gz", hash = "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83"}, +] kombu = [ {file = "kombu-5.2.4-py3-none-any.whl", hash = "sha256:8b213b24293d3417bcf0d2f5537b7f756079e3ea232a8386dcc89a59fd2361a4"}, {file = "kombu-5.2.4.tar.gz", hash = "sha256:37cee3ee725f94ea8bb173eaab7c1760203ea53bbebae226328600f9d2799610"}, @@ -2022,7 +2236,48 @@ markdown = [ {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, ] -markupsafe = [] +markupsafe = [ + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, @@ -2031,14 +2286,26 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] -nautobot = [] +nautobot = [ + {file = "nautobot-1.3.8-py3-none-any.whl", hash = "sha256:aab13bd51070cca315bfd4e0c7e907a1b37f782e1ef2739d3a48d5d3595d7f69"}, + {file = "nautobot-1.3.8.tar.gz", hash = "sha256:39b6f266e3bc59bee14a7e44875354ee9ea7a540b4c781bf29247e3b95c81874"}, +] netaddr = [ {file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"}, {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, ] -netutils = [] -oauthlib = [] -packaging = [] +netutils = [ + {file = "netutils-1.1.0-py3-none-any.whl", hash = "sha256:bcb4367689c773cd30bf898b15bed38f22dc8bd69e64f2272bb9dd4726bf41d4"}, + {file = "netutils-1.1.0.tar.gz", hash = "sha256:90ab637c60ae18c515191224c52a7b0a1eb6fdde2f8dd40dfac638f2dd06ef2c"}, +] +oauthlib = [ + {file = "oauthlib-3.2.1-py3-none-any.whl", hash = "sha256:88e912ca1ad915e1dcc1c06fc9259d19de8deacd6fd17cc2df266decc2e49066"}, + {file = "oauthlib-3.2.1.tar.gz", hash = "sha256:1565237372795bf6ee3e5aba5e2a85bd5a65d0e2aa5c628b9a97b7d7a0da3721"}, +] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, @@ -2047,17 +2314,116 @@ pbr = [ {file = "pbr-5.9.0-py2.py3-none-any.whl", hash = "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a"}, {file = "pbr-5.9.0.tar.gz", hash = "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308"}, ] -pillow = [] +pillow = [ + {file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"}, + {file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"}, + {file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"}, + {file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"}, + {file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"}, + {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"}, + {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"}, + {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"}, + {file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"}, + {file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"}, + {file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"}, + {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"}, + {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"}, + {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"}, + {file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"}, + {file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"}, + {file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"}, + {file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"}, + {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"}, + {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"}, + {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"}, + {file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"}, + {file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"}, + {file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"}, + {file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"}, + {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"}, + {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"}, + {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"}, + {file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"}, + {file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"}, + {file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"}, + {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"}, + {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"}, + {file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"}, + {file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"}, +] platformdirs = [ {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, ] -prometheus-client = [] +prometheus-client = [ + {file = "prometheus_client-0.14.1-py3-none-any.whl", hash = "sha256:522fded625282822a89e2773452f42df14b5a8e84a86433e3f8a189c1d54dc01"}, + {file = "prometheus_client-0.14.1.tar.gz", hash = "sha256:5459c427624961076277fdc6dc50540e2bacb98eebde99886e59ec55ed92093a"}, +] promise = [ {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"}, ] -prompt-toolkit = [] -psycopg2-binary = [] +prompt-toolkit = [ + {file = "prompt_toolkit-3.0.30-py3-none-any.whl", hash = "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"}, + {file = "prompt_toolkit-3.0.30.tar.gz", hash = "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0"}, +] +psycopg2-binary = [ + {file = "psycopg2-binary-2.9.3.tar.gz", hash = "sha256:761df5313dc15da1502b21453642d7599d26be88bff659382f8f9747c7ebea4e"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:539b28661b71da7c0e428692438efbcd048ca21ea81af618d845e06ebfd29478"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e82d38390a03da28c7985b394ec3f56873174e2c88130e6966cb1c946508e65"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57804fc02ca3ce0dbfbef35c4b3a4a774da66d66ea20f4bda601294ad2ea6092"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:083a55275f09a62b8ca4902dd11f4b33075b743cf0d360419e2051a8a5d5ff76"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:0a29729145aaaf1ad8bafe663131890e2111f13416b60e460dae0a96af5905c9"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a79d622f5206d695d7824cbf609a4f5b88ea6d6dab5f7c147fc6d333a8787e4"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:090f3348c0ab2cceb6dfbe6bf721ef61262ddf518cd6cc6ecc7d334996d64efa"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a9e1f75f96ea388fbcef36c70640c4efbe4650658f3d6a2967b4cc70e907352e"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c3ae8e75eb7160851e59adc77b3a19a976e50622e44fd4fd47b8b18208189d42"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-win32.whl", hash = "sha256:7b1e9b80afca7b7a386ef087db614faebbf8839b7f4db5eb107d0f1a53225029"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:8b344adbb9a862de0c635f4f0425b7958bf5a4b927c8594e6e8d261775796d53"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:e847774f8ffd5b398a75bc1c18fbb56564cda3d629fe68fd81971fece2d3c67e"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68641a34023d306be959101b345732360fc2ea4938982309b786f7be1b43a4a1"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3303f8807f342641851578ee7ed1f3efc9802d00a6f83c101d21c608cb864460"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:e3699852e22aa68c10de06524a3721ade969abf382da95884e6a10ff798f9281"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:526ea0378246d9b080148f2d6681229f4b5964543c170dd10bf4faaab6e0d27f"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b1c8068513f5b158cf7e29c43a77eb34b407db29aca749d3eb9293ee0d3103ca"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:15803fa813ea05bef089fa78835118b5434204f3a17cb9f1e5dbfd0b9deea5af"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:152f09f57417b831418304c7f30d727dc83a12761627bb826951692cc6491e57"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:404224e5fef3b193f892abdbf8961ce20e0b6642886cfe1fe1923f41aaa75c9d"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-win32.whl", hash = "sha256:1f6b813106a3abdf7b03640d36e24669234120c72e91d5cbaeb87c5f7c36c65b"}, + {file = "psycopg2_binary-2.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:2d872e3c9d5d075a2e104540965a1cf898b52274a5923936e5bfddb58c59c7c2"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:10bb90fb4d523a2aa67773d4ff2b833ec00857f5912bafcfd5f5414e45280fb1"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a52ecab70af13e899f7847b3e074eeb16ebac5615665db33bce8a1009cf33"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a29b3ca4ec9defec6d42bf5feb36bb5817ba3c0230dd83b4edf4bf02684cd0ae"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:12b11322ea00ad8db8c46f18b7dfc47ae215e4df55b46c67a94b4effbaec7094"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:53293533fcbb94c202b7c800a12c873cfe24599656b341f56e71dd2b557be063"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c381bda330ddf2fccbafab789d83ebc6c53db126e4383e73794c74eedce855ef"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d29409b625a143649d03d0fd7b57e4b92e0ecad9726ba682244b73be91d2fdb"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:183a517a3a63503f70f808b58bfbf962f23d73b6dccddae5aa56152ef2bcb232"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:15c4e4cfa45f5a60599d9cec5f46cd7b1b29d86a6390ec23e8eebaae84e64554"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-win32.whl", hash = "sha256:adf20d9a67e0b6393eac162eb81fb10bc9130a80540f4df7e7355c2dd4af9fba"}, + {file = "psycopg2_binary-2.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2f9ffd643bc7349eeb664eba8864d9e01f057880f510e4681ba40a6532f93c71"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:def68d7c21984b0f8218e8a15d514f714d96904265164f75f8d3a70f9c295667"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dffc08ca91c9ac09008870c9eb77b00a46b3378719584059c034b8945e26b272"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:280b0bb5cbfe8039205c7981cceb006156a675362a00fe29b16fbc264e242834"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:af9813db73395fb1fc211bac696faea4ca9ef53f32dc0cfa27e4e7cf766dcf24"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:63638d875be8c2784cfc952c9ac34e2b50e43f9f0a0660b65e2a87d656b3116c"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ffb7a888a047696e7f8240d649b43fb3644f14f0ee229077e7f6b9f9081635bd"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0c9d5450c566c80c396b7402895c4369a410cab5a82707b11aee1e624da7d004"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:d1c1b569ecafe3a69380a94e6ae09a4789bbb23666f3d3a08d06bbd2451f5ef1"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8fc53f9af09426a61db9ba357865c77f26076d48669f2e1bb24d85a22fb52307"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-win32.whl", hash = "sha256:6472a178e291b59e7f16ab49ec8b4f3bdada0a879c68d3817ff0963e722a82ce"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:35168209c9d51b145e459e05c31a9eaeffa9a6b0fd61689b48e07464ffd1a83e"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:47133f3f872faf28c1e87d4357220e809dfd3fa7c64295a4a148bcd1e6e34ec9"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91920527dea30175cc02a1099f331aa8c1ba39bf8b7762b7b56cbf54bc5cce42"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887dd9aac71765ac0d0bac1d0d4b4f2c99d5f5c1382d8b770404f0f3d0ce8a39"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:1f14c8b0942714eb3c74e1e71700cbbcb415acbc311c730370e70c578a44a25c"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:7af0dd86ddb2f8af5da57a976d27cd2cd15510518d582b478fbb2292428710b4"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93cd1967a18aa0edd4b95b1dfd554cf15af657cb606280996d393dadc88c3c35"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bda845b664bb6c91446ca9609fc69f7db6c334ec5e4adc87571c34e4f47b7ddb"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:01310cf4cf26db9aea5158c217caa92d291f0500051a6469ac52166e1a16f5b7"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:99485cab9ba0fa9b84f1f9e1fef106f44a46ef6afdeec8885e0b88d0772b49e8"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-win32.whl", hash = "sha256:46f0e0a6b5fa5851bbd9ab1bc805eef362d3a230fbdfbc209f4a236d0a7a990d"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:accfe7e982411da3178ec690baaceaad3c278652998b2c45828aaac66cd8285f"}, +] pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, @@ -2066,7 +2432,38 @@ pycparser = [ {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] -pycryptodome = [] +pycryptodome = [ + {file = "pycryptodome-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e468724173df02f9d83f3fea830bf0d04aa291b5add22b4a78e01c97aab04873"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fb7a6f222072412f320b9e48d3ce981920efbfce37b06d028ec9bd94093b37f"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4f1b594d0cf35bd12ec4244df1155a7f565bf6e6245976ac36174c1564688c90"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9ea70f6c3f6566159e3798e4593a4a8016994a0080ac29a45200615b45091a1b"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f7aad304575d075faf2806977b726b67da7ba294adc97d878f92a062e357a56a"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:702446a012fd9337b9327d168bb0c7dc714eb93ad361f6f61af9ca8305a301f1"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-win32.whl", hash = "sha256:681ac47c538c64305d710eaed2bb49532f62b3f4c93aa7c423c520df981392e5"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7b3478a187d897f003b2aa1793bcc59463e8d57a42e2aafbcbbe9cd47ec46863"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:eec02d9199af4b1ccfe1f9c587691a07a1fa39d949d2c1dc69d079ab9af8212f"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9c8e0e6c5e982699801b20fa74f43c19aa080d2b53a39f3c132d35958e153bd4"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f5457e44d3f26d9946091e92b28f3e970a56538b96c87b4b155a84e32a40b7b5"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:88d6d54e83cf9bbd665ce1e7b9079983ee2d97a05f42e0569ff00a70f1dd8b1e"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:72de8c4d71e6b11d54528bb924447fa4fdabcbb3d76cc0e7f61d3b6075def6b3"}, + {file = "pycryptodome-3.13.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:008ef2c631f112cd5a58736e0b29f4a28b4bb853e68878689f8b476fd56e0691"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:51ebe9624ad0a0b4da1aaaa2d43aabadf8537737fd494cee0ffa37cd6326de02"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:deede160bdf87ddb71f0a1314ad5a267b1a960be314ea7dc6b7ad86da6da89a3"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:857c16bffd938254e3a834cd6b2a755ed24e1a953b1a86e33da136d3e4c16a6f"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:ca6db61335d07220de0b665bfee7b8e9615b2dfc67a54016db4826dac34c2dd2"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:073dedf0f9c490ae22ca081b86357646ac9b76f3e2bd89119d137fc697a9e3b6"}, + {file = "pycryptodome-3.13.0-cp35-abi3-win32.whl", hash = "sha256:e3affa03c49cce7b0a9501cc7f608d4f8e61fb2522b276d599ac049b5955576d"}, + {file = "pycryptodome-3.13.0-cp35-abi3-win_amd64.whl", hash = "sha256:e5d72be02b17e6bd7919555811264403468d1d052fa67c946e402257c3c29a27"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:0896d5d15ffe584d46cb9b69a75cf14a2bc8f6daf635b7bf16c1b041342a44b1"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:e420cdfca73f80fe15f79bb34756959945231a052440813e5fce531e6e96331a"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:720fafdf3e5c5de93039d8308f765cc60b8e9e7e852ad7135aa65dd89238191f"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-win32.whl", hash = "sha256:7a8b0e526ff239b4f4c61dd6898e2474d609843ffc437267f3a27ddff626e6f6"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d92a5eddffb0ad39f582f07c1de26e9daf6880e3e782a94bb7ebaf939567f8bf"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:cb9453c981554984c6f5c5ce7682d7286e65e2173d7416114c3593a977a01bf5"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:765b8b16bc1fd699e183dde642c7f2653b8f3c9c1a50051139908e9683f97732"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:b3af53dddf848afb38b3ac2bae7159ddad1feb9bac14aa3acec6ef1797b82f8d"}, + {file = "pycryptodome-3.13.0.tar.gz", hash = "sha256:95bacf9ff7d1b90bba537d3f5f6c834efe6bfbb1a0195cb3573f29e6716ef08d"}, +] pydocstyle = [ {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, @@ -2075,7 +2472,10 @@ pyflakes = [ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] -pyjwt = [] +pyjwt = [ + {file = "PyJWT-2.4.0-py3-none-any.whl", hash = "sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf"}, + {file = "PyJWT-2.4.0.tar.gz", hash = "sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba"}, +] pylint = [ {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, @@ -2088,8 +2488,33 @@ pylint-plugin-utils = [ {file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"}, {file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"}, ] -pyparsing = [] -pyrsistent = [] +pyparsing = [ + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, +] +pyrsistent = [ + {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, + {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, + {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, + {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, +] python-crontab = [ {file = "python-crontab-2.6.0.tar.gz", hash = "sha256:1e35ed7a3cdc3100545b43e196d34754e6551e7f95e4caebbe0e1c0ca41c2f1b"}, ] @@ -2105,7 +2530,44 @@ pytz = [ {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, ] -pyuwsgi = [] +pyuwsgi = [ + {file = "pyuwsgi-2.0.20-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd09a7328558728f6e38f77609f44d16f18d8b4dc5f8b8776f657c8892b70337"}, + {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:210ad768b8af02bbfd3c0345a51c6d2c56a2333ac268d9a97ecf2d4209f78ef8"}, + {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e33111308a79dbd202094963fd3a537dab30854e375d9be018f642fcd359e03d"}, + {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0306c3ca6f781ed7409774e44a2a90217824d3efb44e075a1f39a78a54ffe7d"}, + {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3eeea48fd965b68801618fc20eda2cb65dc2aeb4121955c9c422685f046311da"}, + {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dd048b85abb90c79a34afbf787995ab2933cb2a8b210a6e064e5fca0a9bdf2d8"}, + {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f612a72437c2934e39393fb575fab791e919efc102a0aa1a27b5d9a301d462e9"}, + {file = "pyuwsgi-2.0.20-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:78ac2d8b7d307232f8276cb8a45300211b0fae179c0494f2a3e3178c70693f81"}, + {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f84fc44bba77d05fa9d01189028501ff8e6a2d63db184ceea42085ce28196317"}, + {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:342c312949c2f494f5d9ac272965715483cb22ed0353c18abb1b4590769ef00f"}, + {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5740b84a016a246c69edef0df11912560df9a45c2adf6e47701329a974e37a71"}, + {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:82058f6b6656f12dbc66c963be2d7c0b977f481ddca5d4d3918e26def003b60d"}, + {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:dc99724df6d5613300d3357c4017cde840830ca132fe98f0a4feab9a6af48622"}, + {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:70096084ccfa18f058dfb3380aa10e80d48958ddfdb888b827f06aacb72f80b8"}, + {file = "pyuwsgi-2.0.20-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e7a8576452635612c82f660e5be99ba42cdcdff142948f5c263b5278f2c17b0"}, + {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2844205e0095a29d3a6e9e23bd37bcf18d65e4e5ab23a14a45f5159c03a3b890"}, + {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e2c0d5dafb9faacc8ed5b662f9eacb22e723fbc3cb7152b2ebf09a92b8bd6c0d"}, + {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087397457837c5fd653eda91c5d2c7948e06da589c786d26145bdcc397656bb2"}, + {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:da24ddb7e3522d36b4cdc2dbf131141d559084862f515d37f9a4b7b5c8b538b1"}, + {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:99b0c5a87aa95dcbaca2ccb599d783f37461600e098881d4ec9796ba68e3ff8f"}, + {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:df08a05dda4a92da46bd56af755dac091b145815c3cf6dda1855e01e40d12a99"}, + {file = "pyuwsgi-2.0.20-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c8ac4b2f411d15222f53a96627b8fa79056b39606925f429f59a51668bd95ab"}, + {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f1494d00df440865b1ee269a350187766c9c364ba5f124eddb064f366c4b6d8a"}, + {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5ee8782932dbacdb4dd98714c3575cbbb88ba87d7bcb3149c828725ba048897"}, + {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cdc4b32234b40fa2d515108a2f56a159896134ef16394f26dba764635142976"}, + {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:300417d6669171a454da19991fc7f910b3975232dac5b2dbc359e26f1038624b"}, + {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:015a8d310503eb8c0028ac8f98c7df3b49bc937c7db137aaf149ca7fae64c777"}, + {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9fc3d256270adf24b87f1dff893f3bc59bd5ee20c4ebb5add25e944c36359e1e"}, + {file = "pyuwsgi-2.0.20-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:052fe12d6a9ab9e9fc7814e40d2d28061aaea1a610069008d773e1d8a71feb11"}, + {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7d160c7bfa8f2974fc6b807a8fc080be0d130b1a4ad0b463c0320e707e6a6eb6"}, + {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7691ca470e541133c444b23f83c6f07ecca12f4771a49e0e3a04b05f4c80f2d3"}, + {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c87fb1d56dd2c6f18b87b08496be326afb6cf57c6a059261b01ce99046d9147"}, + {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8eb97cf51f58df05ec0dd74d83510172a2f5bcd8adc91382e24690a2abddc2f3"}, + {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a8fc4d52232f55df16e9cbf6faf4bf16910d15042229d5f8c717278fd4ea37a5"}, + {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1acedb1841aa0e60e1a7245ae483a5fcb30e39cf0cdfe3987e14de4746daf75b"}, + {file = "pyuwsgi-2.0.20.tar.gz", hash = "sha256:8b0936a964511fa0e2ac2847c2435e95130e7c98619f06fe1f67320527576043"}, +] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, @@ -2114,6 +2576,13 @@ pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, @@ -2141,30 +2610,54 @@ pyyaml = [ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] -redis = [] -requests = [] -requests-oauthlib = [] -rq = [] -"ruamel.yaml" = [] +redis = [ + {file = "redis-4.3.4-py3-none-any.whl", hash = "sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54"}, + {file = "redis-4.3.4.tar.gz", hash = "sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880"}, +] +requests = [ + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, +] +requests-oauthlib = [ + {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, + {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, +] +rq = [ + {file = "rq-1.10.1-py2.py3-none-any.whl", hash = "sha256:92f4cf38b2364c1697b541e77c0fe62b7e5242fa864324f262be126ee2a07e3a"}, + {file = "rq-1.10.1.tar.gz", hash = "sha256:62d06b44c3acfa5d1933c5a4ec3fbc2484144a8af60e318d0b8447c5236271e2"}, +] +"ruamel.yaml" = [ + {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, + {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, +] "ruamel.yaml.clib" = [ + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:066f886bc90cc2ce44df8b5f7acfc6a7e2b2e672713f027136464492b0c34d7c"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"}, {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"}, {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"}, {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d3c620a54748a3d4cf0bcfe623e388407c8e85a4b06b8188e126302bcab93ea8"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:210c8fcfeff90514b7133010bf14e3bad652c8efde6b20e00c43854bf94fa5a6"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:61bc5e5ca632d95925907c569daa559ea194a4d16084ba86084be98ab1cec1c6"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1b4139a6ffbca8ef60fdaf9b33dec05143ba746a6f0ae0f9d11d38239211d335"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"}, {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"}, @@ -2173,6 +2666,10 @@ rx = [ {file = "Rx-1.6.1-py2.py3-none-any.whl", hash = "sha256:7357592bc7e881a95e0c2013b73326f704953301ab551fbc8133a6fadab84105"}, {file = "Rx-1.6.1.tar.gz", hash = "sha256:13a1d8d9e252625c173dc795471e614eadfe1cf40ffc684e08b8fff0d9748c23"}, ] +setuptools = [ + {file = "setuptools-65.3.0-py3-none-any.whl", hash = "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82"}, + {file = "setuptools-65.3.0.tar.gz", hash = "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57"}, +] singledispatch = [ {file = "singledispatch-3.7.0-py2.py3-none-any.whl", hash = "sha256:bc77afa97c8a22596d6d4fc20f1b7bdd2b86edc2a65a4262bdd7cc3cc19aa989"}, {file = "singledispatch-3.7.0.tar.gz", hash = "sha256:c1a4d5c1da310c3fd8fccfb8d4e1cb7df076148fd5d858a819e37fffe44f3092"}, @@ -2189,8 +2686,14 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -social-auth-app-django = [] -social-auth-core = [] +social-auth-app-django = [ + {file = "social-auth-app-django-5.0.0.tar.gz", hash = "sha256:b6e3132ce087cdd6e1707aeb1b588be41d318408fcf6395435da0bc6fe9a9795"}, + {file = "social_auth_app_django-5.0.0-py3-none-any.whl", hash = "sha256:52241a25445a010ab1c108bafff21fc5522d5c8cd0d48a92c39c7371824b065d"}, +] +social-auth-core = [ + {file = "social-auth-core-4.3.0.tar.gz", hash = "sha256:4686f0e43cf12954216875a32e944847bb1dc69e7cd9573d16a9003bb05ca477"}, + {file = "social_auth_core-4.3.0-py3-none-any.whl", hash = "sha256:1e3440d104f743b02dfe258c9d4dba5b4065abf24b2f7eb362b47054d21797df"}, +] sqlparse = [ {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, @@ -2199,7 +2702,10 @@ stevedore = [ {file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"}, {file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"}, ] -svgwrite = [] +svgwrite = [ + {file = "svgwrite-1.4.3-py3-none-any.whl", hash = "sha256:bb6b2b5450f1edbfa597d924f9ac2dd099e625562e492021d7dd614f65f8a22d"}, + {file = "svgwrite-1.4.3.zip", hash = "sha256:a8fbdfd4443302a6619a7f76bc937fc683daf2628d9b737c891ec08b8ce524c3"}, +] swagger-spec-validator = [ {file = "swagger-spec-validator-2.7.4.tar.gz", hash = "sha256:2aee5e1fc0503be9f8299378b10c92169572781573c6de3315e831fd0559ba73"}, {file = "swagger_spec_validator-2.7.4-py2.py3-none-any.whl", hash = "sha256:4e373a4db5262e7257fde17d84c5c0178327b8057985ab1be63f580bfa009855"}, @@ -2238,12 +2744,18 @@ typed-ast = [ {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] -typing-extensions = [] +typing-extensions = [ + {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"}, + {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"}, +] uritemplate = [ {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] -urllib3 = [] +urllib3 = [ + {file = "urllib3-1.26.10-py2.py3-none-any.whl", hash = "sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec"}, + {file = "urllib3-1.26.10.tar.gz", hash = "sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6"}, +] vine = [ {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"}, {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, @@ -2318,5 +2830,10 @@ wrapt = [ {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] -yamllint = [] -zipp = [] +yamllint = [ + {file = "yamllint-1.27.1.tar.gz", hash = "sha256:e688324b58560ab68a1a3cff2c0a474e3fed371dfe8da5d1b9817b7df55039ce"}, +] +zipp = [ + {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"}, + {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"}, +] From 78e33480c54eee6970ca0e9d129d34eaeaa87973 Mon Sep 17 00:00:00 2001 From: Glenn Matthews Date: Mon, 19 Sep 2022 10:11:45 -0400 Subject: [PATCH 03/61] Make CI nautobot version match default invoke nautobot version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21783218..131afe88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,7 +80,7 @@ jobs: fail-fast: true matrix: python-version: ["3.7"] - nautobot-version: ["1.3.3"] + nautobot-version: ["1.3.8"] env: INVOKE_NAUTOBOT_BGP_MODELS_PYTHON_VER: "${{ matrix.python-version }}" INVOKE_NAUTOBOT_BGP_MODELS_NAUTOBOT_VER: "${{ matrix.nautobot-version }}" From 8feba5ee85ae35f41f133121113e973267c82e2f Mon Sep 17 00:00:00 2001 From: Glenn Matthews Date: Mon, 19 Sep 2022 10:21:57 -0400 Subject: [PATCH 04/61] Make CI nautobot version match default invoke nautobot version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 131afe88..0d944282 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -118,7 +118,7 @@ jobs: matrix: python-version: ["3.7", "3.8", "3.9", "3.10"] db-backend: ["postgresql"] - nautobot-version: ["1.3.3", "stable"] + nautobot-version: ["1.3.8", "stable"] runs-on: "ubuntu-20.04" env: INVOKE_NAUTOBOT_BGP_MODELS_PYTHON_VER: "${{ matrix.python-version }}" From 70bc304302b985fa341fbfec13020a3cf4f97fbc Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Mon, 19 Sep 2022 23:23:18 +0200 Subject: [PATCH 05/61] Fix signals for post_migrate_create_statuses --- nautobot_bgp_models/signals.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nautobot_bgp_models/signals.py b/nautobot_bgp_models/signals.py index d1e3e2f1..537d2509 100644 --- a/nautobot_bgp_models/signals.py +++ b/nautobot_bgp_models/signals.py @@ -1,13 +1,17 @@ """Nautobot signal handler functions for nautobot_bgp_models.""" +from django.apps import apps as global_apps from django.conf import settings PLUGIN_SETTINGS = settings.PLUGINS_CONFIG["nautobot_bgp_models"] -def post_migrate_create_statuses(sender, apps, **kwargs): +def post_migrate_create_statuses(sender, *, apps=global_apps, **kwargs): """Callback function for post_migrate() -- create default Statuses.""" # pylint: disable=invalid-name + if not apps: + return + Status = apps.get_model("extras", "Status") for model_name, default_statuses in PLUGIN_SETTINGS.get("default_statuses", {}).items(): From 490d4565a5874865bfe53aebd391193f191513e7 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Tue, 20 Sep 2022 15:09:28 +0200 Subject: [PATCH 06/61] 0.7.0-beta.1 release --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1b3121d8..63b6a68c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-bgp-models" -version = "0.7.0-beta.0" +version = "0.7.0-beta.1" description = "Nautobot BGP Models Plugin" authors = ["Network to Code, LLC "] From 9c66c67d64481da065c1bbd808e8d5c7f77e92f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Dec 2022 09:10:05 -0500 Subject: [PATCH 07/61] Bump certifi from 2022.6.15 to 2022.12.7 (#69) Bumps [certifi](https://github.com/certifi/python-certifi) from 2022.6.15 to 2022.12.7. - [Release notes](https://github.com/certifi/python-certifi/releases) - [Commits](https://github.com/certifi/python-certifi/compare/2022.06.15...2022.12.07) --- updated-dependencies: - dependency-name: certifi dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/poetry.lock b/poetry.lock index d1e16cd5..f9e9de72 100644 --- a/poetry.lock +++ b/poetry.lock @@ -69,7 +69,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] -tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] [[package]] name = "bandit" @@ -183,7 +183,7 @@ zstd = ["zstandard"] [[package]] name = "certifi" -version = "2022.6.15" +version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -209,7 +209,7 @@ optional = false python-versions = ">=3.6.0" [package.extras] -unicode_backport = ["unicodedata2"] +unicode-backport = ["unicodedata2"] [[package]] name = "click" @@ -650,7 +650,7 @@ django = ">=2.2" pytz = "*" [package.extras] -rest_framework = ["djangorestframework (>=3.0.0)"] +rest-framework = ["djangorestframework (>=3.0.0)"] [[package]] name = "django-webserver" @@ -821,7 +821,7 @@ text-unidecode = "*" [package.extras] dev = ["black (==19.10b0)", "coveralls", "django-filter (<2)", "django-filter (>=2)", "djangorestframework (>=3.6.3)", "flake8 (==3.7.9)", "flake8-black (==0.1.1)", "flake8-bugbear (==20.1.4)", "mock", "pytest (>=3.6.3)", "pytest-cov", "pytest-django (>=3.3.2)", "pytz"] -rest_framework = ["djangorestframework (>=3.6.3)"] +rest-framework = ["djangorestframework (>=3.6.3)"] test = ["coveralls", "django-filter (<2)", "django-filter (>=2)", "djangorestframework (>=3.6.3)", "mock", "pytest (>=3.6.3)", "pytest-cov", "pytest-django (>=3.3.2)", "pytz"] [[package]] @@ -927,9 +927,9 @@ python-versions = ">=3.6.1,<4.0" [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +pipfile-deprecated-finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] -requirements_deprecated_finder = ["pip-api", "pipreqs"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "itypes" @@ -970,7 +970,7 @@ typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format_nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "kombu" @@ -1104,7 +1104,7 @@ all = ["django-auth-ldap (>=4.0.0,<4.1.0)", "django-storages (>=1.12.3,<1.13.0)" ldap = ["django-auth-ldap (>=4.0.0,<4.1.0)"] mysql = ["mysqlclient (>=2.1.0,<2.2.0)"] napalm = ["napalm (>=3.3.1,<3.4.0)"] -remote_storage = ["django-storages (>=1.12.3,<1.13.0)"] +remote-storage = ["django-storages (>=1.12.3,<1.13.0)"] sso = ["social-auth-core[openidconnect,saml] (>=4.2.0,<4.3.0)"] [[package]] @@ -1321,8 +1321,8 @@ pylint = ">=2.0,<3" pylint-plugin-utils = ">=0.7" [package.extras] -for_tests = ["coverage", "django-tables2", "django-tastypie", "factory-boy", "pylint (>=2.13)", "pytest", "wheel"] -with_django = ["Django"] +for-tests = ["coverage", "django-tables2", "django-tastypie", "factory-boy", "pylint (>=2.13)", "pytest", "wheel"] +with-django = ["Django"] [[package]] name = "pylint-plugin-utils" @@ -1454,7 +1454,7 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-oauthlib" @@ -1816,8 +1816,8 @@ celery = [ {file = "celery-5.2.7.tar.gz", hash = "sha256:fafbd82934d30f8a004f81e8f7a062e31413a23d444be8ee3326553915958c6d"}, ] certifi = [ - {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, - {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, ] cffi = [ {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, @@ -2369,6 +2369,7 @@ prompt-toolkit = [ psycopg2-binary = [ {file = "psycopg2-binary-2.9.3.tar.gz", hash = "sha256:761df5313dc15da1502b21453642d7599d26be88bff659382f8f9747c7ebea4e"}, {file = "psycopg2_binary-2.9.3-cp310-cp310-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:539b28661b71da7c0e428692438efbcd048ca21ea81af618d845e06ebfd29478"}, + {file = "psycopg2_binary-2.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f2534ab7dc7e776a263b463a16e189eb30e85ec9bbe1bff9e78dae802608932"}, {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e82d38390a03da28c7985b394ec3f56873174e2c88130e6966cb1c946508e65"}, {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57804fc02ca3ce0dbfbef35c4b3a4a774da66d66ea20f4bda601294ad2ea6092"}, {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:083a55275f09a62b8ca4902dd11f4b33075b743cf0d360419e2051a8a5d5ff76"}, @@ -2402,6 +2403,7 @@ psycopg2-binary = [ {file = "psycopg2_binary-2.9.3-cp37-cp37m-win32.whl", hash = "sha256:adf20d9a67e0b6393eac162eb81fb10bc9130a80540f4df7e7355c2dd4af9fba"}, {file = "psycopg2_binary-2.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2f9ffd643bc7349eeb664eba8864d9e01f057880f510e4681ba40a6532f93c71"}, {file = "psycopg2_binary-2.9.3-cp38-cp38-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:def68d7c21984b0f8218e8a15d514f714d96904265164f75f8d3a70f9c295667"}, + {file = "psycopg2_binary-2.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e6aa71ae45f952a2205377773e76f4e3f27951df38e69a4c95440c779e013560"}, {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dffc08ca91c9ac09008870c9eb77b00a46b3378719584059c034b8945e26b272"}, {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:280b0bb5cbfe8039205c7981cceb006156a675362a00fe29b16fbc264e242834"}, {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:af9813db73395fb1fc211bac696faea4ca9ef53f32dc0cfa27e4e7cf766dcf24"}, @@ -2413,6 +2415,7 @@ psycopg2-binary = [ {file = "psycopg2_binary-2.9.3-cp38-cp38-win32.whl", hash = "sha256:6472a178e291b59e7f16ab49ec8b4f3bdada0a879c68d3817ff0963e722a82ce"}, {file = "psycopg2_binary-2.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:35168209c9d51b145e459e05c31a9eaeffa9a6b0fd61689b48e07464ffd1a83e"}, {file = "psycopg2_binary-2.9.3-cp39-cp39-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:47133f3f872faf28c1e87d4357220e809dfd3fa7c64295a4a148bcd1e6e34ec9"}, + {file = "psycopg2_binary-2.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b3a24a1982ae56461cc24f6680604fffa2c1b818e9dc55680da038792e004d18"}, {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91920527dea30175cc02a1099f331aa8c1ba39bf8b7762b7b56cbf54bc5cce42"}, {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887dd9aac71765ac0d0bac1d0d4b4f2c99d5f5c1382d8b770404f0f3d0ce8a39"}, {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:1f14c8b0942714eb3c74e1e71700cbbcb415acbc311c730370e70c578a44a25c"}, From 509cabb7c9825c4e6735a59645250c5e59aeebe1 Mon Sep 17 00:00:00 2001 From: Dan Bridson Date: Fri, 20 Jan 2023 16:50:02 +0000 Subject: [PATCH 08/61] Changed extends 'base.html' to extends 'generic/object_list.html' in the list templates --- .../templates/nautobot_bgp_models/peering_create.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html index 4f8e44fa..4541a0f7 100644 --- a/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html @@ -1,4 +1,4 @@ -{% extends 'base.html' %} +{% extends 'generic/object_list.html' %} {% load static %} {% load helpers %} {% load form_helpers %} From 7b7b1ec312aa8d07ea2b961729bb8efd3a79ecc2 Mon Sep 17 00:00:00 2001 From: Dan Bridson Date: Fri, 20 Jan 2023 17:59:36 +0000 Subject: [PATCH 09/61] Added .idea/ to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index c8dc4550..240931ef 100644 --- a/.gitignore +++ b/.gitignore @@ -192,6 +192,9 @@ $RECYCLE.BIN/ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +# Jetbrains IDE configs +.idea/ + # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml From dd9b2e49fbd40328c05a6d5759d2fe08fdc5fe6c Mon Sep 17 00:00:00 2001 From: Dan Bridson Date: Tue, 24 Jan 2023 17:54:35 +0000 Subject: [PATCH 10/61] Revert "Added .idea/ to .gitignore" This reverts commit 7b7b1ec312aa8d07ea2b961729bb8efd3a79ecc2. --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 240931ef..c8dc4550 100644 --- a/.gitignore +++ b/.gitignore @@ -192,9 +192,6 @@ $RECYCLE.BIN/ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 -# Jetbrains IDE configs -.idea/ - # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml From bc978952a10eb37f676f5c0919e524c28b6fdc77 Mon Sep 17 00:00:00 2001 From: Dan Bridson Date: Tue, 24 Jan 2023 17:54:41 +0000 Subject: [PATCH 11/61] Revert "Changed extends 'base.html' to extends 'generic/object_list.html' in the list templates" This reverts commit 509cabb7c9825c4e6735a59645250c5e59aeebe1. --- .../templates/nautobot_bgp_models/peering_create.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html index 4541a0f7..4f8e44fa 100644 --- a/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html @@ -1,4 +1,4 @@ -{% extends 'generic/object_list.html' %} +{% extends 'base.html' %} {% load static %} {% load helpers %} {% load form_helpers %} From 5109e9ffd03554b71c8a83833ce39f6d4ed2f983 Mon Sep 17 00:00:00 2001 From: mzb Date: Mon, 13 Feb 2023 22:43:28 +0100 Subject: [PATCH 12/61] CODEOWNERS update (#85) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index da54d15e..519d0cc1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,2 @@ # Default owner(s) of all files in this repository -* @glennmatthews @carbonarok +* @glennmatthews @mzbroch From cb1cc1cfe50473df1d88ef19de72f478dcce9808 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 16 Mar 2023 14:30:11 +0100 Subject: [PATCH 13/61] Development updates --- .dockerignore | 20 +- .flake8 | 9 +- .github/workflows/ci.yml | 45 +- .github/workflows/upstream_testing.yml | 13 + .gitignore | 6 + .readthedocs.yaml | 22 + development/Dockerfile | 82 +- development/creds.example.env | 31 +- development/dev.env | 17 - development/development.env | 40 + development/development_mysql.env | 3 + development/docker-compose.base.yml | 21 +- development/docker-compose.dev.yml | 22 +- development/docker-compose.local.yml | 8 - development/docker-compose.mysql.yml | 34 + development/docker-compose.postgres.yml | 23 + development/docker-compose.redis.yml | 12 + development/docker-compose.requirements.yml | 21 - development/nautobot_config.py | 375 +-- invoke.example.yml | 12 + invoke.mysql.yml | 12 + poetry.lock | 2798 ++++++++++--------- pyproject.toml | 6 +- tasks.py | 120 +- 24 files changed, 2047 insertions(+), 1705 deletions(-) create mode 100644 .github/workflows/upstream_testing.yml create mode 100644 .readthedocs.yaml delete mode 100644 development/dev.env create mode 100644 development/development.env create mode 100644 development/development_mysql.env delete mode 100644 development/docker-compose.local.yml create mode 100644 development/docker-compose.mysql.yml create mode 100644 development/docker-compose.postgres.yml create mode 100644 development/docker-compose.redis.yml delete mode 100644 development/docker-compose.requirements.yml create mode 100644 invoke.example.yml create mode 100644 invoke.mysql.yml diff --git a/.dockerignore b/.dockerignore index 555cad19..2270f496 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,16 +2,26 @@ development/Dockerfile development/docker-compose*.yml development/*.env +*.env +environments/ + +# Python +**/*.pyc +**/*.pyo +**/__pycache__/ +**/.pytest_cache/ +**/.venv/ -# Linting, etc. -.yamllint -.flake8 -.bandit.yml -.pydocstyle.ini # Other +docs/_build FAQ.md +.git/ .gitignore .github tasks.py LICENSE +**/*.log +**/.vscode/ +invoke*.yml +tasks.py diff --git a/.flake8 b/.flake8 index 07bc180d..5ac86eba 100644 --- a/.flake8 +++ b/.flake8 @@ -1,5 +1,10 @@ [flake8] # E501: Line length is enforced by Black, so flake8 doesn't need to check it -# F405: Star Imports for Nested Serializers (brief fields issue) # W503: Black disagrees with this rule, as does PEP 8; Black wins -ignore = E501, F405, W503 +ignore = E501, W503 +exclude = + migrations, + __pycache__, + manage.py, + settings.py, + .venv diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d944282..85971992 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,8 @@ --- name: "CI" +concurrency: # Cancel any existing runs of this workflow for this same PR + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true on: # yamllint disable-line rule:truthy rule:comments push: branches: @@ -21,7 +24,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v2" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v4" - name: "Linting: black" run: "poetry run invoke black" bandit: @@ -32,7 +35,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v2" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v4" - name: "Linting: bandit" run: "poetry run invoke bandit" pydocstyle: @@ -43,7 +46,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v2" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v4" - name: "Linting: pydocstyle" run: "poetry run invoke pydocstyle" flake8: @@ -54,7 +57,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v2" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v4" - name: "Linting: flake8" run: "poetry run invoke flake8" yamllint: @@ -65,7 +68,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v2" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v4" - name: "Linting: yamllint" run: "poetry run invoke yamllint" pylint: @@ -79,8 +82,8 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.7"] - nautobot-version: ["1.3.8"] + python-version: ["3.8"] + nautobot-version: ["1.5.4"] env: INVOKE_NAUTOBOT_BGP_MODELS_PYTHON_VER: "${{ matrix.python-version }}" INVOKE_NAUTOBOT_BGP_MODELS_NAUTOBOT_VER: "${{ matrix.nautobot-version }}" @@ -88,7 +91,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v2" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v4" - name: "Set up Docker Buildx" id: "buildx" uses: "docker/setup-buildx-action@v1" @@ -116,9 +119,19 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10"] db-backend: ["postgresql"] - nautobot-version: ["1.3.8", "stable"] + nautobot-version: ["stable"] + include: + - python-version: "3.10" + db-backend: "postgresql" + nautobot-version: "1.5.4" + - python-version: "3.7" + db-backend: "mysql" + nautobot-version: "1.5.4" + - python-version: "3.10" + db-backend: "mysql" + nautobot-version: "stable" runs-on: "ubuntu-20.04" env: INVOKE_NAUTOBOT_BGP_MODELS_PYTHON_VER: "${{ matrix.python-version }}" @@ -127,7 +140,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v2" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v4" - name: "Set up Docker Buildx" id: "buildx" uses: "docker/setup-buildx-action@v1" @@ -147,6 +160,9 @@ jobs: PYTHON_VER=${{ matrix.python-version }} - name: "Copy credentials" run: "cp development/creds.example.env development/creds.env" + - name: "Use Mysql invoke settings when needed" + run: "cp invoke.mysql.yml invoke.yml" + if: "matrix.db-backend == 'mysql'" - name: "Run Tests" run: "poetry run invoke unittest" publish_gh: @@ -173,7 +189,7 @@ jobs: - name: "Upload binaries to release" uses: "svenstaro/upload-release-action@v2" with: - repo_token: "${{ secrets.GH_NAUTOBOT_BOT_TOKEN }}" + repo_token: "${{ secrets.NTC_GITHUB_TOKEN }}" file: "dist/*" tag: "${{ github.ref }}" overwrite: true @@ -210,7 +226,7 @@ jobs: - "publish_pypi" runs-on: "ubuntu-20.04" env: - SLACK_WEBHOOK_URL: "${{ '{{ secrets.SLACK_WEBHOOK_URL }}' }}" + SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}" SLACK_MESSAGE: >- *NOTIFICATION: NEW-RELEASE-PUBLISHED*\n Repository: <${{ github.server_url }}/${{ github.repository }}|${{ github.repository }}>\n @@ -220,11 +236,12 @@ jobs: - name: "Send a notification to Slack" # ENVs cannot be used directly in job.if. This is a workaround to check # if SLACK_WEBHOOK_URL is present. - if: "${{ env.SLACK_WEBHOOK_URL != '' }}" + if: "env.SLACK_WEBHOOK_URL != ''" uses: "slackapi/slack-github-action@v1.17.0" with: payload: | { + "text": "${{ env.SLACK_MESSAGE }}", "blocks": [ { "type": "section", diff --git a/.github/workflows/upstream_testing.yml b/.github/workflows/upstream_testing.yml new file mode 100644 index 00000000..3731c556 --- /dev/null +++ b/.github/workflows/upstream_testing.yml @@ -0,0 +1,13 @@ +--- +name: "Nautobot Upstream Monitor" + +on: # yamllint disable-line rule:truthy rule:comments + schedule: + - cron: "0 4 */2 * *" # every other day at midnight + +jobs: + upstream-test: + uses: "nautobot/nautobot/.github/workflows/plugin_upstream_testing_base.yml@develop" + with: # Below could potentially be collapsed into a single argument if a concrete relationship between both is enforced + invoke_context_name: "NAUTOBOT_BGP_MODELS" + plugin_name: "nautobot-bgp-models" diff --git a/.gitignore b/.gitignore index c8dc4550..cbb9133b 100644 --- a/.gitignore +++ b/.gitignore @@ -297,6 +297,12 @@ fabric.properties # Rando creds.env +development/*.txt # Invoke overrides invoke.yml + +# Docs +docs/README.md +docs/CHANGELOG.md +public diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..9a0a64c7 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,22 @@ +--- +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python in the build environment. +build: + os: "ubuntu-22.04" + tools: + python: "3.10" + +mkdocs: + configuration: "mkdocs.yml" + fail_on_warning: true + +# Use our docs/requirements.txt during installation. +python: + install: + - requirements: "docs/requirements.txt" diff --git a/development/Dockerfile b/development/Dockerfile index 41c90f09..2a3015ff 100644 --- a/development/Dockerfile +++ b/development/Dockerfile @@ -1,18 +1,78 @@ +# ------------------------------------------------------------------------------------- +# Nautobot App Developement Dockerfile Template +# Version: 1.1.0 +# +# Apps that need to add additional steps or packages can do in the section below. +# ------------------------------------------------------------------------------------- +# !!! USE CAUTION WHEN MODIFYING LINES BELOW -ARG PYTHON_VER -ARG NAUTOBOT_VER +# Accepts a desired Nautobot version as build argument, default to 1.5 +ARG NAUTOBOT_VER="1.4" + +# Accepts a desired Python version as build argument, default to 3.8 +ARG PYTHON_VER="3.8" + +# Retrieve published development image of Nautobot base which should include most CI dependencies FROM ghcr.io/nautobot/nautobot-dev:${NAUTOBOT_VER}-py${PYTHON_VER} -WORKDIR /source +# Runtime argument and environment setup +ARG NAUTOBOT_ROOT=/opt/nautobot + +ENV prometheus_multiproc_dir=/prom_cache +ENV NAUTOBOT_ROOT ${NAUTOBOT_ROOT} + +# Install Poetry manually via its installer script; +# We might be using an older version of Nautobot that includes an older version of Poetry +# and CI and local development may have a newer version of Poetry +# Since this is only used for development and we don't ship this container, pinning Poetry back is not expressly necessary +# We also don't need virtual environments in container +RUN curl -sSL https://install.python-poetry.org | python3 - && \ + poetry config virtualenvs.create false + +# !!! USE CAUTION WHEN MODIFYING LINES ABOVE +# ------------------------------------------------------------------------------------- +# App-specifc system build/test dependencies. +# +# Example: LDAP requires `libldap2-dev` to be apt-installed before the Python package. +# ------------------------------------------------------------------------------------- +# --> Start safe to modify section -# Copy in only pyproject.toml/poetry.lock to help with caching this layer if no updates to dependencies -COPY poetry.lock pyproject.toml /source/ -# --no-root declares not to install the project package since we're wanting to take advantage of caching dependency installation -# and the project is copied in and installed after this step -RUN poetry install --no-interaction --no-ansi --no-root +# Uncomment the lines below if you are apt-installing any package. +# RUN apt-get -y update && apt-get -y install \ +# libldap2-dev \ +# && rm -rf /var/lib/apt/lists/* -# Copy in the rest of the source code and install local Nautobot plugin +# --> Stop safe to modify section +# ------------------------------------------------------------------------------------- +# Install Nautobot App +# ------------------------------------------------------------------------------------- +# !!! USE CAUTION WHEN MODIFYING LINES BELOW + +# Copy in the source code +WORKDIR /source COPY . /source -RUN poetry install --no-interaction --no-ansi -COPY development/nautobot_config.py /opt/nautobot/nautobot_config.py +# Get container's installed Nautobot version as a forced constraint +# NAUTOBOT_VER may be a branch name and not a published release therefor we need to get the installed version +# so pip can use it to recognize local constraints. +RUN pip show nautobot | grep "^Version: " | sed -e 's/Version: /nautobot==/' > constraints.txt + +# Use Poetry to grab dev dependencies from the lock file +# Can be improved in Poetry 1.2 which allows `poetry install --only dev` +# +# We can't use the entire freeze as it takes forever to resolve with rigidly fixed non-direct dependencies, +# especially those that are only direct to Nautobot but the container included versions slightly mismatch +RUN poetry export -f requirements.txt --without-hashes --output poetry_freeze_base.txt +RUN poetry export -f requirements.txt --with dev --without-hashes --output poetry_freeze_all.txt +RUN sort poetry_freeze_base.txt poetry_freeze_all.txt | uniq -u > poetry_freeze_dev.txt + +# Install all local project as editable, constrained on Nautobot version, to get any additional +# direct dependencies of the app +RUN pip install -c constraints.txt -e . + +# Install any dev dependencies frozen from Poetry +# Can be improved in Poetry 1.2 which allows `poetry install --only dev` +RUN pip install -c constraints.txt -r poetry_freeze_dev.txt + +COPY development/nautobot_config.py ${NAUTOBOT_ROOT}/nautobot_config.py +# !!! USE CAUTION WHEN MODIFYING LINES ABOVE diff --git a/development/creds.example.env b/development/creds.example.env index 94bbf310..26e24fad 100644 --- a/development/creds.example.env +++ b/development/creds.example.env @@ -1,10 +1,27 @@ -POSTGRES_PASSWORD=notverysecurepwd -REDIS_PASSWORD=notverysecurepwd -SECRET_KEY=r8OwDznj!!dci#P9ghmRfdu1Ysxm0AiPeDCQhKE+N_rClfWNj +################################################################################ +# CREDS File: Store private information. Copied to creds.env and always ignored +################################################################################ +# Nautobot Configuration Secret Items NAUTOBOT_CREATE_SUPERUSER=true -NAUTOBOT_SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567 +NAUTOBOT_DB_PASSWORD=changeme +NAUTOBOT_NAPALM_USERNAME='' +NAUTOBOT_NAPALM_PASSWORD='' +NAUTOBOT_REDIS_PASSWORD=changeme +NAUTOBOT_SECRET_KEY='changeme' +NAUTOBOT_SUPERUSER_NAME=admin +NAUTOBOT_SUPERUSER_EMAIL=admin@example.com NAUTOBOT_SUPERUSER_PASSWORD=admin -# POSTGRES_HOST=localhost -# REDIS_HOST=localhost -# NAUTOBOT_ROOT=./development +NAUTOBOT_SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567 + +# Postgres +POSTGRES_PASSWORD=${NAUTOBOT_DB_PASSWORD} +PGPASSWORD=${NAUTOBOT_DB_PASSWORD} + +# MySQL Credentials +MYSQL_ROOT_PASSWORD=${NAUTOBOT_DB_PASSWORD} +MYSQL_PASSWORD=${NAUTOBOT_DB_PASSWORD} +# Use these to override values in development.env +# NAUTOBOT_DB_HOST=localhost +# NAUTOBOT_REDIS_HOST=localhost +# NAUTOBOT_CONFIG=development/nautobot_config.py diff --git a/development/dev.env b/development/dev.env deleted file mode 100644 index 14e44598..00000000 --- a/development/dev.env +++ /dev/null @@ -1,17 +0,0 @@ -ALLOWED_HOSTS=* -BANNER_TOP="Local" -CHANGELOG_RETENTION=0 -DEBUG=True -MAX_PAGE_SIZE=0 -METRICS_ENABLED=True -NAPALM_TIMEOUT=5 -NAUTOBOT_ROOT=/opt/nautobot -POSTGRES_DB=nautobot -POSTGRES_HOST=postgres -POSTGRES_USER=nautobot -REDIS_HOST=redis -REDIS_PORT=6379 -# REDIS_SSL=True -# Uncomment REDIS_SSL if using SSL -SUPERUSER_EMAIL=admin@example.com -SUPERUSER_NAME=admin diff --git a/development/development.env b/development/development.env new file mode 100644 index 00000000..1945f95f --- /dev/null +++ b/development/development.env @@ -0,0 +1,40 @@ +################################################################################ +# DEV File: Store environment information. NOTE: Secrets NOT stored here! +################################################################################ +# Nautobot Configuration Environment Variables +NAUTOBOT_ALLOWED_HOSTS=* +NAUTOBOT_BANNER_TOP="Local" +NAUTOBOT_CHANGELOG_RETENTION=0 + +NAUTOBOT_DEBUG=True +NAUTOBOT_DJANGO_EXTENSIONS_ENABLED=True +NAUTOBOT_DJANGO_TOOLBAR_ENABLED=True +NAUTOBOT_LOG_LEVEL=DEBUG +NAUTOBOT_METRICS_ENABLED=True +NAUTOBOT_NAPALM_TIMEOUT=5 +NAUTOBOT_MAX_PAGE_SIZE=0 + +# Redis Configuration Environment Variables +NAUTOBOT_REDIS_HOST=redis +NAUTOBOT_REDIS_PORT=6379 +# Uncomment NAUTOBOT_REDIS_SSL if using SSL +# NAUTOBOT_REDIS_SSL=True + +# Nautobot DB Connection Environment Variables +NAUTOBOT_DB_NAME=nautobot +NAUTOBOT_DB_USER=nautobot +NAUTOBOT_DB_HOST=db +NAUTOBOT_DB_TIMEOUT=300 + +# Use them to overwrite the defaults in nautobot_config.py +# NAUTOBOT_DB_ENGINE=django.db.backends.postgresql +# NAUTOBOT_DB_PORT=5432 + +# Needed for Postgres should match the values for Nautobot above +POSTGRES_USER=${NAUTOBOT_DB_USER} +POSTGRES_DB=${NAUTOBOT_DB_NAME} + +# Needed for MYSQL should match the values for Nautobot above +MYSQL_USER=${NAUTOBOT_DB_USER} +MYSQL_DATABASE=${NAUTOBOT_DB_NAME} +MYSQL_ROOT_HOST=% diff --git a/development/development_mysql.env b/development/development_mysql.env new file mode 100644 index 00000000..b01fc8ab --- /dev/null +++ b/development/development_mysql.env @@ -0,0 +1,3 @@ +# Custom ENVs for Mysql +# Due to docker image limitations for Mysql, we need "root" user to create more than one database table +NAUTOBOT_DB_USER=root diff --git a/development/docker-compose.base.yml b/development/docker-compose.base.yml index 5ec5a5ca..23db95e6 100644 --- a/development/docker-compose.base.yml +++ b/development/docker-compose.base.yml @@ -9,22 +9,31 @@ x-nautobot-build: &nautobot-build x-nautobot-base: &nautobot-base image: "nautobot-bgp-models/nautobot:${NAUTOBOT_VER}-py${PYTHON_VER}" env_file: - - "dev.env" + - "development.env" - "creds.env" tty: true -version: "3.4" +version: "3.8" services: nautobot: depends_on: - - "postgres" - - "redis" + redis: + condition: "service_started" + db: + condition: "service_healthy" <<: *nautobot-build <<: *nautobot-base worker: - entrypoint: "nautobot-server rqworker" + entrypoint: + - "sh" + - "-c" # this is to evaluate the $NAUTOBOT_LOG_LEVEL from the env + - "nautobot-server celery worker -l $$NAUTOBOT_LOG_LEVEL --events" ## $$ because of docker-compose depends_on: - "nautobot" healthcheck: - disable: true + interval: "30s" + timeout: "10s" + start_period: "30s" + retries: 3 + test: ["CMD", "bash", "-c", "nautobot-server celery inspect ping --destination celery@$$HOSTNAME"] ## $$ because of docker-compose <<: *nautobot-base diff --git a/development/docker-compose.dev.yml b/development/docker-compose.dev.yml index 3bdd3502..565c13c9 100644 --- a/development/docker-compose.dev.yml +++ b/development/docker-compose.dev.yml @@ -3,7 +3,7 @@ # any override will need to include these volumes to use them. # see: https://github.com/docker/compose/issues/3729 --- -version: "3.4" +version: "3.8" services: nautobot: command: "nautobot-server runserver 0.0.0.0:8080" @@ -17,19 +17,23 @@ services: ports: - "8001:8080" volumes: - - "../docs:/source/docs:ro" - - "../mkdocs.yml:/source/mkdocs.yml:ro" + - "../:/source" image: "nautobot-bgp-models/nautobot:${NAUTOBOT_VER}-py${PYTHON_VER}" healthcheck: disable: true tty: true worker: + entrypoint: + - "sh" + - "-c" # this is to evaluate the $NAUTOBOT_LOG_LEVEL from the env + - "watchmedo auto-restart --directory './' --pattern '*.py' --recursive -- nautobot-server celery worker -l $$NAUTOBOT_LOG_LEVEL --events" ## $$ because of docker-compose volumes: - "./nautobot_config.py:/opt/nautobot/nautobot_config.py" - "../:/source" - postgres: - ports: - - "5432" - redis: - ports: - - "6379" +# To expose postgres or redis to the host uncomment the following +# postgres: +# ports: +# - "5432:5432" +# redis: +# ports: +# - "6379:6379" diff --git a/development/docker-compose.local.yml b/development/docker-compose.local.yml deleted file mode 100644 index 4efc2490..00000000 --- a/development/docker-compose.local.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -services: - postgres: - ports: - - "5432:5432" - redis: - ports: - - "6379:6379" diff --git a/development/docker-compose.mysql.yml b/development/docker-compose.mysql.yml new file mode 100644 index 00000000..c7fa6a1f --- /dev/null +++ b/development/docker-compose.mysql.yml @@ -0,0 +1,34 @@ +--- +version: "3.8" + +services: + nautobot: + environment: + - "NAUTOBOT_DB_ENGINE=django.db.backends.mysql" + env_file: + - "development.env" + - "creds.env" + - "development_mysql.env" + worker: + environment: + - "NAUTOBOT_DB_ENGINE=django.db.backends.mysql" + env_file: + - "development.env" + - "creds.env" + - "development_mysql.env" + db: + image: "mysql:8" + command: + - "--default-authentication-plugin=mysql_native_password" + env_file: + - "development.env" + - "creds.env" + - "development_mysql.env" + volumes: + - "mysql_data:/var/lib/mysql" + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + timeout: "20s" + retries: 10 +volumes: + mysql_data: {} diff --git a/development/docker-compose.postgres.yml b/development/docker-compose.postgres.yml new file mode 100644 index 00000000..55afdb70 --- /dev/null +++ b/development/docker-compose.postgres.yml @@ -0,0 +1,23 @@ +--- +version: "3.8" + +services: + nautobot: + environment: + - "NAUTOBOT_DB_ENGINE=django.db.backends.postgresql" + db: + image: "postgres:13-alpine" + env_file: + - "development.env" + - "creds.env" + volumes: + # - "./nautobot.sql:/tmp/nautobot.sql" + - "postgres_data:/var/lib/postgresql/data" + healthcheck: + test: "pg_isready --username=$$POSTGRES_USER --dbname=$$POSTGRES_DB" + interval: "10s" + timeout: "5s" + retries: 10 + +volumes: + postgres_data: {} diff --git a/development/docker-compose.redis.yml b/development/docker-compose.redis.yml new file mode 100644 index 00000000..6da9fa01 --- /dev/null +++ b/development/docker-compose.redis.yml @@ -0,0 +1,12 @@ +--- +version: "3.8" +services: + redis: + image: "redis:6-alpine" + command: + - "sh" + - "-c" # this is to evaluate the $NAUTOBOT_REDIS_PASSWORD from the env + - "redis-server --appendonly yes --requirepass $$NAUTOBOT_REDIS_PASSWORD" + env_file: + - "development.env" + - "creds.env" diff --git a/development/docker-compose.requirements.yml b/development/docker-compose.requirements.yml deleted file mode 100644 index 3194288f..00000000 --- a/development/docker-compose.requirements.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -version: "3.4" -services: - postgres: - image: "postgres:13-alpine" - env_file: - - "dev.env" - - "creds.env" - volumes: - - "postgres_data:/var/lib/postgresql/data" - redis: - image: "redis:6-alpine" - command: - - "sh" - - "-c" # this is to evaluate the $REDIS_PASSWORD from the env - - "redis-server --appendonly yes --requirepass $$REDIS_PASSWORD" - env_file: - - "dev.env" - - "creds.env" -volumes: - postgres_data: {} diff --git a/development/nautobot_config.py b/development/nautobot_config.py index 9d77e124..63caf628 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -1,79 +1,108 @@ -"""Nautobot configuration for development of the nautobot_bgp_models plugin.""" -######################### -# # -# Required settings # -# # -######################### - +"""Nautobot development configuration file.""" +# pylint: disable=invalid-envvar-default import os import sys -from distutils.util import strtobool -from django.core.exceptions import ImproperlyConfigured -from nautobot.core import settings - -# Enforce required configuration parameters -for key in [ - "ALLOWED_HOSTS", - "POSTGRES_DB", - "POSTGRES_USER", - "POSTGRES_HOST", - "POSTGRES_PASSWORD", - "REDIS_HOST", - "REDIS_PASSWORD", - "SECRET_KEY", -]: - if not os.environ.get(key): - raise ImproperlyConfigured(f"Required environment variable {key} is missing.") - +from nautobot.core.settings import * # noqa: F403 +from nautobot.core.settings_funcs import parse_redis_connection -def is_truthy(arg): - """Convert "truthy" strings into Booleans. - - Examples: - >>> is_truthy('yes') - True - Args: - arg (str): Truthy string (True values are y, yes, t, true, on and 1; false values are n, no, - f, false, off and 0. Raises ValueError if val is anything else. - """ - if isinstance(arg, bool): - return arg - return bool(strtobool(arg)) +# +# Misc. settings +# -TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" +ALLOWED_HOSTS = os.getenv("NAUTOBOT_ALLOWED_HOSTS", "").split(" ") +SECRET_KEY = os.getenv("NAUTOBOT_SECRET_KEY", "") -# This is a list of valid fully-qualified domain names (FQDNs) for the Nautobot server. Nautobot will not permit write -# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. -# -# Example: ALLOWED_HOSTS = ['nautobot.example.com', 'nautobot.internal.local'] -ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS").split(" ") -# PostgreSQL database configuration. See the Django documentation for a complete list of available parameters: -# https://docs.djangoproject.com/en/stable/ref/settings/#databases +nautobot_db_engine = os.getenv("NAUTOBOT_DB_ENGINE", "django.db.backends.postgresql") +default_db_settings = { + "django.db.backends.postgresql": { + "NAUTOBOT_DB_PORT": "5432", + }, + "django.db.backends.mysql": { + "NAUTOBOT_DB_PORT": "3306", + }, +} DATABASES = { "default": { - "NAME": os.getenv("POSTGRES_DB", "nautobot"), # Database name - "USER": os.getenv("POSTGRES_USER", ""), # Database username - "PASSWORD": os.getenv("POSTGRES_PASSWORD", ""), # Datbase password - "HOST": os.getenv("POSTGRES_HOST", "localhost"), # Database server - "PORT": os.getenv("POSTGRES_PORT", ""), # Database port (leave blank for default) - "CONN_MAX_AGE": os.getenv("POSTGRES_TIMEOUT", 300), # Database timeout - "ENGINE": "django.db.backends.postgresql", # Database driver (Postgres only supported!) + "NAME": os.getenv("NAUTOBOT_DB_NAME", "nautobot"), # Database name + "USER": os.getenv("NAUTOBOT_DB_USER", ""), # Database username + "PASSWORD": os.getenv("NAUTOBOT_DB_PASSWORD", ""), # Database password + "HOST": os.getenv("NAUTOBOT_DB_HOST", "localhost"), # Database server + "PORT": os.getenv( + "NAUTOBOT_DB_PORT", default_db_settings[nautobot_db_engine]["NAUTOBOT_DB_PORT"] + ), # Database port, default to postgres + "CONN_MAX_AGE": int(os.getenv("NAUTOBOT_DB_TIMEOUT", 300)), # Database timeout + "ENGINE": nautobot_db_engine, } } -# Redis variables -REDIS_HOST = os.getenv("REDIS_HOST", "localhost") -REDIS_PORT = os.getenv("REDIS_PORT", 6379) -REDIS_PASSWORD = os.getenv("REDIS_PASSWORD", "") +# Ensure proper Unicode handling for MySQL +if DATABASES["default"]["ENGINE"] == "django.db.backends.mysql": + DATABASES["default"]["OPTIONS"] = {"charset": "utf8mb4"} + +# +# Debug +# + +DEBUG = True + +# Django Debug Toolbar +DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG and not TESTING} + +if DEBUG and "debug_toolbar" not in INSTALLED_APPS: # noqa: F405 + INSTALLED_APPS.append("debug_toolbar") # noqa: F405 +if DEBUG and "debug_toolbar.middleware.DebugToolbarMiddleware" not in MIDDLEWARE: # noqa: F405 + MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware") # noqa: F405 + +# +# Logging +# + +LOG_LEVEL = "DEBUG" if DEBUG else "INFO" + +TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" + +# Verbose logging during normal development operation, but quiet logging during unit test execution +if not TESTING: + LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "normal": { + "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)s :\n %(message)s", + "datefmt": "%H:%M:%S", + }, + "verbose": { + "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)-20s %(filename)-15s %(funcName)30s() :\n %(message)s", + "datefmt": "%H:%M:%S", + }, + }, + "handlers": { + "normal_console": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "normal", + }, + "verbose_console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "verbose", + }, + }, + "loggers": { + "django": {"handlers": ["normal_console"], "level": "INFO"}, + "nautobot": { + "handlers": ["verbose_console" if DEBUG else "normal_console"], + "level": LOG_LEVEL, + }, + }, + } -# Check for Redis SSL -REDIS_SCHEME = "redis" -REDIS_SSL = is_truthy(os.environ.get("REDIS_SSL", False)) -if REDIS_SSL: - REDIS_SCHEME = "rediss" +# +# Redis +# # The django-redis cache is used to establish concurrent locks using Redis. The # django-rq settings will use the same instance/database by default. @@ -83,11 +112,10 @@ def is_truthy(arg): CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": f"{REDIS_SCHEME}://{REDIS_HOST}:{REDIS_PORT}/0", + "LOCATION": parse_redis_connection(redis_database=0), "TIMEOUT": 300, "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", - "PASSWORD": REDIS_PASSWORD, }, } } @@ -95,154 +123,13 @@ def is_truthy(arg): # RQ_QUEUES is not set here because it just uses the default that gets imported # up top via `from nautobot.core.settings import *`. -# REDIS CACHEOPS -CACHEOPS_REDIS = f"{REDIS_SCHEME}://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/1" - -# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. -# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and -# symbols. Nautobot will not run without this defined. For more information, see -# https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-SECRET_KEY -SECRET_KEY = os.environ["SECRET_KEY"] - - -######################### -# # -# Optional settings # -# # -######################### - -# Specify one or more name and email address tuples representing Nautobot administrators. These people will be notified of -# application errors (assuming correct email settings are provided). -ADMINS = [ - # ['John Doe', 'jdoe@example.com'], -] - -# URL schemes that are allowed within links in Nautobot -ALLOWED_URL_SCHEMES = ( - "file", - "ftp", - "ftps", - "http", - "https", - "irc", - "mailto", - "sftp", - "ssh", - "tel", - "telnet", - "tftp", - "vnc", - "xmpp", -) - -# Optionally display a persistent banner at the top and/or bottom of every page. HTML is allowed. To display the same -# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP. -BANNER_TOP = os.environ.get("BANNER_TOP", "") -BANNER_BOTTOM = os.environ.get("BANNER_BOTTOM", "") - -# Text to include on the login page above the login form. HTML is allowed. -BANNER_LOGIN = os.environ.get("BANNER_LOGIN", "") - -# Cache timeout in seconds. Cannot be 0. Defaults to 900 (15 minutes). To disable caching, set CACHEOPS_ENABLED to False -CACHEOPS_DEFAULTS = {"timeout": 900} - -# Set to False to disable caching with cacheops. (Default: True) -CACHEOPS_ENABLED = True - -# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90) -CHANGELOG_RETENTION = int(os.environ.get("CHANGELOG_RETENTION", 90)) +# Redis Cacheops +CACHEOPS_REDIS = parse_redis_connection(redis_database=1) -# If True, all origins will be allowed. Other settings restricting allowed origins will be ignored. -# Defaults to False. Setting this to True can be dangerous, as it allows any website to make -# cross-origin requests to yours. Generally you'll want to restrict the list of allowed origins with -# CORS_ALLOWED_ORIGINS or CORS_ALLOWED_ORIGIN_REGEXES. -CORS_ORIGIN_ALLOW_ALL = is_truthy(os.environ.get("CORS_ORIGIN_ALLOW_ALL", False)) - -# A list of origins that are authorized to make cross-site HTTP requests. Defaults to []. -CORS_ALLOWED_ORIGINS = [ - # 'https://hostname.example.com', -] - -# A list of strings representing regexes that match Origins that are authorized to make cross-site -# HTTP requests. Defaults to []. -CORS_ALLOWED_ORIGIN_REGEXES = [ - # r'^(https?://)?(\w+\.)?example\.com$', -] - -# The file path where jobs will be stored. A trailing slash is not needed. Note that the default value of -# this setting is inside the invoking user's home directory. -# JOBS_ROOT = os.path.expanduser('~/.nautobot/jobs') - -# Set to True to enable server debugging. WARNING: Debugging introduces a substantial performance penalty and may reveal -# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging -# on a production system. -DEBUG = is_truthy(os.environ.get("DEBUG", False)) - -# Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce unique IP space -# within the global table (all prefixes and IP addresses not assigned to a VRF), set -# ENFORCE_GLOBAL_UNIQUE to True. -ENFORCE_GLOBAL_UNIQUE = is_truthy(os.environ.get("ENFORCE_GLOBAL_UNIQUE", False)) - -# Exempt certain models from the enforcement of view permissions. Models listed here will be viewable by all users and -# by anonymous users. List models in the form `.`. Add '*' to this list to exempt all models. -EXEMPT_VIEW_PERMISSIONS = [ - # 'dcim.site', - # 'dcim.region', - # 'ipam.prefix', -] - -# HTTP proxies Nautobot should use when sending outbound HTTP requests (e.g. for webhooks). -# HTTP_PROXIES = { -# 'http': 'http://10.10.1.10:3128', -# 'https': 'http://10.10.1.10:1080', -# } - -# IP addresses recognized as internal to the system. The debugging toolbar will be available only to clients accessing -# Nautobot from an internal IP. -INTERNAL_IPS = ("127.0.0.1", "::1") - -# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs: -# https://docs.djangoproject.com/en/stable/topics/logging/ -LOGGING = {} - -# Setting this to True will display a "maintenance mode" banner at the top of every page. -MAINTENANCE_MODE = False - -# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g. -# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request -# all objects by specifying "?limit=0". -MAX_PAGE_SIZE = int(os.environ.get("MAX_PAGE_SIZE", 1000)) - -# The file path where uploaded media such as image attachments are stored. A trailing slash is not needed. Note that -# the default value of this setting is within the invoking user's home directory -# MEDIA_ROOT = os.path.expanduser('~/.nautobot/media') - -# By default uploaded media is stored on the local filesystem. Using Django-storages is also supported. Provide the -# class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG. For example: -# STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage' -# STORAGE_CONFIG = { -# 'AWS_ACCESS_KEY_ID': 'Key ID', -# 'AWS_SECRET_ACCESS_KEY': 'Secret', -# 'AWS_STORAGE_BUCKET_NAME': 'nautobot', -# 'AWS_S3_REGION_NAME': 'eu-west-1', -# } - -# Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics' -METRICS_ENABLED = False - -# Credentials that Nautobot will uses to authenticate to devices when connecting via NAPALM. -NAPALM_USERNAME = os.environ.get("NAPALM_USERNAME", "") -NAPALM_PASSWORD = os.environ.get("NAPALM_PASSWORD", "") - -# NAPALM timeout (in seconds). (Default: 30) -NAPALM_TIMEOUT = int(os.environ.get("NAPALM_TIMEOUT", 30)) - -# NAPALM optional arguments (see https://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must -# be provided as a dictionary. -NAPALM_ARGS = {} - -# Determine how many objects to display per page within a list. (Default: 50) -PAGINATE_COUNT = int(os.environ.get("PAGINATE_COUNT", 50)) +# +# Celery settings are not defined here because they can be overloaded with +# environment variables. By default they use `CACHES["default"]["LOCATION"]`. +# # Enable installed plugins. Add the name of each plugin to the list. PLUGINS = ["nautobot_bgp_models"] @@ -250,72 +137,8 @@ def is_truthy(arg): # Plugins configuration settings. These settings are used by various plugins that the user may have installed. # Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings. # PLUGINS_CONFIG = { -# 'my_plugin': { +# '{{cookiecutter.plugin_name}}': { # 'foo': 'bar', # 'buzz': 'bazz' # } # } - -# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to -# prefer IPv4 instead. -PREFER_IPV4 = is_truthy(os.environ.get("PREFER_IPV4", False)) - -# Rack elevation size defaults, in pixels. For best results, the ratio of width to height should be roughly 10:1. -RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = 22 -RACK_ELEVATION_DEFAULT_UNIT_WIDTH = 220 - -# Remote authentication support -REMOTE_AUTH_ENABLED = False -REMOTE_AUTH_BACKEND = "nautobot.core.authentication.RemoteUserBackend" -REMOTE_AUTH_HEADER = "HTTP_REMOTE_USER" -REMOTE_AUTH_AUTO_CREATE_USER = True -REMOTE_AUTH_DEFAULT_GROUPS = [] -REMOTE_AUTH_DEFAULT_PERMISSIONS = {} - -# This determines how often the GitHub API is called to check the latest release of Nautobot. Must be at least 1 hour. -RELEASE_CHECK_TIMEOUT = 24 * 3600 - -# This repository is used to check whether there is a new release of Nautobot available. Set to None to disable the -# version check or use the URL below to check for release in the official Nautobot repository. -RELEASE_CHECK_URL = None -# RELEASE_CHECK_URL = 'https://api.github.com/repos/nautobot/nautobot/releases' - -# Maximum execution time for background tasks, in seconds. -RQ_DEFAULT_TIMEOUT = 300 - -# The length of time (in seconds) for which a user will remain logged into the web UI before being prompted to -# re-authenticate. (Default: 1209600 [14 days]) -SESSION_COOKIE_AGE = 1209600 # 2 weeks, in seconds - - -# By default, Nautobot will store session data in the database. Alternatively, a file path can be specified here to use -# local file storage instead. (This can be useful for enabling authentication on a standby instance with read-only -# database access.) Note that the user as which Nautobot runs must have read and write permissions to this path. -SESSION_FILE_PATH = None - -# Configure SSO, for more information see docs/configuration/authentication/sso.md -SOCIAL_AUTH_ENABLED = False - -# Time zone (default: UTC) -TIME_ZONE = os.environ.get("TIME_ZONE", "UTC") - -# Date/time formatting. See the following link for supported formats: -# https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date -DATE_FORMAT = os.environ.get("DATE_FORMAT", "N j, Y") -SHORT_DATE_FORMAT = os.environ.get("SHORT_DATE_FORMAT", "Y-m-d") -TIME_FORMAT = os.environ.get("TIME_FORMAT", "g:i a") -SHORT_TIME_FORMAT = os.environ.get("SHORT_TIME_FORMAT", "H:i:s") -DATETIME_FORMAT = os.environ.get("DATETIME_FORMAT", "N j, Y g:i a") -SHORT_DATETIME_FORMAT = os.environ.get("SHORT_DATETIME_FORMAT", "Y-m-d H:i") - -# A list of strings designating all applications that are enabled in this Django installation. Each string should be a dotted Python path to an application configuration class (preferred), or a package containing an application. -# https://nautobot.readthedocs.io/en/latest/configuration/optional-settings/#extra-applications -EXTRA_INSTALLED_APPS = os.environ["EXTRA_INSTALLED_APPS"].split(",") if os.environ.get("EXTRA_INSTALLED_APPS") else [] - -# Django Debug Toolbar -DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG and not TESTING} - -if "debug_toolbar" not in EXTRA_INSTALLED_APPS: - EXTRA_INSTALLED_APPS.append("debug_toolbar") -if "debug_toolbar.middleware.DebugToolbarMiddleware" not in settings.MIDDLEWARE: - settings.MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware") diff --git a/invoke.example.yml b/invoke.example.yml new file mode 100644 index 00000000..b88500c6 --- /dev/null +++ b/invoke.example.yml @@ -0,0 +1,12 @@ +--- +nautobot_bgp_models: + project_name: "nautobot-bgp-models" + nautobot_ver: "1.5.4" + local: false + python_ver: "3.8" + compose_dir: "development" + compose_files: + - "docker-compose.base.yml" + - "docker-compose.redis.yml" + - "docker-compose.postgres.yml" + - "docker-compose.dev.yml" diff --git a/invoke.mysql.yml b/invoke.mysql.yml new file mode 100644 index 00000000..9b9a8a71 --- /dev/null +++ b/invoke.mysql.yml @@ -0,0 +1,12 @@ +--- +nautobot_bgp_models: + project_name: "nautobot-bgp-models" + nautobot_ver: "1.5.4" + local: false + python_ver: "3.8" + compose_dir: "development" + compose_files: + - "docker-compose.base.yml" + - "docker-compose.redis.yml" + - "docker-compose.mysql.yml" + - "docker-compose.dev.yml" diff --git a/poetry.lock b/poetry.lock index f9e9de72..dd29ac1a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. + [[package]] name = "amqp" version = "5.1.1" @@ -5,6 +7,10 @@ description = "Low-level AMQP client for Python (fork of amqplib)." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "amqp-5.1.1-py3-none-any.whl", hash = "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359"}, + {file = "amqp-5.1.1.tar.gz", hash = "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2"}, +] [package.dependencies] vine = ">=5.0.0" @@ -16,14 +22,22 @@ description = "A library for parsing ISO 8601 strings." category = "main" optional = false python-versions = "*" +files = [ + {file = "aniso8601-7.0.0-py2.py3-none-any.whl", hash = "sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b"}, + {file = "aniso8601-7.0.0.tar.gz", hash = "sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e"}, +] [[package]] name = "asgiref" -version = "3.5.2" +version = "3.6.0" description = "ASGI specs, helper code, and adapters" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "asgiref-3.6.0-py3-none-any.whl", hash = "sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac"}, + {file = "asgiref-3.6.0.tar.gz", hash = "sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506"}, +] [package.dependencies] typing-extensions = {version = "*", markers = "python_version < \"3.8\""} @@ -38,6 +52,10 @@ description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.6.2" +files = [ + {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, + {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, +] [package.dependencies] lazy-object-proxy = ">=1.4.0" @@ -53,41 +71,55 @@ description = "Timeout context manager for asyncio programs" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, + {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, +] [package.dependencies] typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} [[package]] name = "attrs" -version = "21.4.0" +version = "22.2.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" +files = [ + {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, + {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, +] [package.extras] -dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] -docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] -tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] +cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs[tests-no-zope]", "zope.interface"] +tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] [[package]] name = "bandit" -version = "1.7.4" +version = "1.7.5" description = "Security oriented static analyser for python code." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "bandit-1.7.5-py3-none-any.whl", hash = "sha256:75665181dc1e0096369112541a056c59d1c5f66f9bb74a8d686c3c362b83f549"}, + {file = "bandit-1.7.5.tar.gz", hash = "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e"}, +] [package.dependencies] colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} GitPython = ">=1.0.1" PyYAML = ">=5.3.1" +rich = "*" stevedore = ">=1.20.0" [package.extras] -test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"] -toml = ["toml"] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "tomli (>=1.1.0)"] +toml = ["tomli (>=1.1.0)"] yaml = ["PyYAML"] [[package]] @@ -97,21 +129,53 @@ description = "Python multiprocessing fork with improvements and bugfixes" category = "main" optional = false python-versions = "*" +files = [ + {file = "billiard-3.6.4.0-py3-none-any.whl", hash = "sha256:87103ea78fa6ab4d5c751c4909bcff74617d985de7fa8b672cf8618afd5a875b"}, + {file = "billiard-3.6.4.0.tar.gz", hash = "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547"}, +] [[package]] name = "black" -version = "22.6.0" +version = "23.1.0" description = "The uncompromising code formatter." category = "dev" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7" +files = [ + {file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"}, + {file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"}, + {file = "black-23.1.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b"}, + {file = "black-23.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"}, + {file = "black-23.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074"}, + {file = "black-23.1.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27"}, + {file = "black-23.1.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648"}, + {file = "black-23.1.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958"}, + {file = "black-23.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a"}, + {file = "black-23.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481"}, + {file = "black-23.1.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad"}, + {file = "black-23.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8"}, + {file = "black-23.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24"}, + {file = "black-23.1.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6"}, + {file = "black-23.1.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd"}, + {file = "black-23.1.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580"}, + {file = "black-23.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468"}, + {file = "black-23.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753"}, + {file = "black-23.1.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651"}, + {file = "black-23.1.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06"}, + {file = "black-23.1.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739"}, + {file = "black-23.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9"}, + {file = "black-23.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555"}, + {file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"}, + {file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"}, +] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" +packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} @@ -128,6 +192,10 @@ description = "A decorator for caching properties in classes." category = "main" optional = false python-versions = "*" +files = [ + {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, + {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, +] [[package]] name = "celery" @@ -136,6 +204,10 @@ description = "Distributed Task Queue." category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "celery-5.2.7-py3-none-any.whl", hash = "sha256:138420c020cd58d6707e6257b6beda91fd39af7afde5d36c6334d175302c0e14"}, + {file = "celery-5.2.7.tar.gz", hash = "sha256:fafbd82934d30f8a004f81e8f7a062e31413a23d444be8ee3326553915958c6d"}, +] [package.dependencies] billiard = ">=3.6.4.0,<4.0" @@ -188,6 +260,10 @@ description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, +] [[package]] name = "cffi" @@ -196,20 +272,160 @@ description = "Foreign Function Interface for Python calling C code." category = "main" optional = false python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] [package.dependencies] pycparser = "*" [[package]] name = "charset-normalizer" -version = "2.1.0" +version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false -python-versions = ">=3.6.0" - -[package.extras] -unicode-backport = ["unicodedata2"] +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, +] [[package]] name = "click" @@ -218,6 +434,10 @@ description = "Composable command line interface toolkit" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -230,6 +450,10 @@ description = "Enables git-like *did-you-mean* feature in click" category = "main" optional = false python-versions = ">=3.6.2,<4.0.0" +files = [ + {file = "click-didyoumean-0.3.0.tar.gz", hash = "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"}, + {file = "click_didyoumean-0.3.0-py3-none-any.whl", hash = "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667"}, +] [package.dependencies] click = ">=7" @@ -241,6 +465,10 @@ description = "An extension module for click to enable registering CLI commands category = "main" optional = false python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] [package.dependencies] click = ">=4.0" @@ -255,6 +483,10 @@ description = "REPL plugin for Click" category = "main" optional = false python-versions = "*" +files = [ + {file = "click-repl-0.2.0.tar.gz", hash = "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8"}, + {file = "click_repl-0.2.0-py3-none-any.whl", hash = "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b"}, +] [package.dependencies] click = "*" @@ -263,11 +495,15 @@ six = "*" [[package]] name = "colorama" -version = "0.4.5" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] [[package]] name = "coreapi" @@ -276,6 +512,10 @@ description = "Python client library for Core API." category = "main" optional = false python-versions = "*" +files = [ + {file = "coreapi-2.3.3-py2.py3-none-any.whl", hash = "sha256:bf39d118d6d3e171f10df9ede5666f63ad80bba9a29a8ec17726a66cf52ee6f3"}, + {file = "coreapi-2.3.3.tar.gz", hash = "sha256:46145fcc1f7017c076a2ef684969b641d18a2991051fddec9458ad3f78ffc1cb"}, +] [package.dependencies] coreschema = "*" @@ -290,6 +530,10 @@ description = "Core Schema." category = "main" optional = false python-versions = "*" +files = [ + {file = "coreschema-0.0.4-py2-none-any.whl", hash = "sha256:5e6ef7bf38c1525d5e55a895934ab4273548629f16aed5c0a6caa74ebf45551f"}, + {file = "coreschema-0.0.4.tar.gz", hash = "sha256:9503506007d482ab0867ba14724b93c18a33b22b6d19fb419ef2d239dd4a1607"}, +] [package.dependencies] jinja2 = "*" @@ -301,28 +545,109 @@ description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +files = [ + {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, + {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, + {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"}, + {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"}, + {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"}, + {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"}, + {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"}, + {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"}, + {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"}, + {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"}, + {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"}, + {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"}, + {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"}, + {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"}, + {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"}, + {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"}, + {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"}, + {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"}, + {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"}, + {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"}, + {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"}, + {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"}, + {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"}, + {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"}, + {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"}, + {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"}, + {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"}, + {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"}, + {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"}, + {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"}, + {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"}, + {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"}, + {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"}, + {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"}, + {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"}, + {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"}, + {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"}, + {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"}, + {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"}, + {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"}, + {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"}, + {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"}, + {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"}, + {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"}, + {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"}, + {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"}, + {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, + {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, +] [package.extras] toml = ["toml"] [[package]] name = "cryptography" -version = "37.0.4" +version = "39.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "cryptography-39.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:2725672bb53bb92dc7b4150d233cd4b8c59615cd8288d495eaa86db00d4e5c06"}, + {file = "cryptography-39.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:23df8ca3f24699167daf3e23e51f7ba7334d504af63a94af468f468b975b7dd7"}, + {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:eb40fe69cfc6f5cdab9a5ebd022131ba21453cf7b8a7fd3631f45bbf52bed612"}, + {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc0521cce2c1d541634b19f3ac661d7a64f9555135e9d8af3980965be717fd4a"}, + {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffd394c7896ed7821a6d13b24657c6a34b6e2650bd84ae063cf11ccffa4f1a97"}, + {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:e8a0772016feeb106efd28d4a328e77dc2edae84dfbac06061319fdb669ff828"}, + {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8f35c17bd4faed2bc7797d2a66cbb4f986242ce2e30340ab832e5d99ae60e011"}, + {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b49a88ff802e1993b7f749b1eeb31134f03c8d5c956e3c125c75558955cda536"}, + {file = "cryptography-39.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c682e736513db7d04349b4f6693690170f95aac449c56f97415c6980edef5"}, + {file = "cryptography-39.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:d7d84a512a59f4412ca8549b01f94be4161c94efc598bf09d027d67826beddc0"}, + {file = "cryptography-39.0.2-cp36-abi3-win32.whl", hash = "sha256:c43ac224aabcbf83a947eeb8b17eaf1547bce3767ee2d70093b461f31729a480"}, + {file = "cryptography-39.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:788b3921d763ee35dfdb04248d0e3de11e3ca8eb22e2e48fef880c42e1f3c8f9"}, + {file = "cryptography-39.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d15809e0dbdad486f4ad0979753518f47980020b7a34e9fc56e8be4f60702fac"}, + {file = "cryptography-39.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:50cadb9b2f961757e712a9737ef33d89b8190c3ea34d0fb6675e00edbe35d074"}, + {file = "cryptography-39.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:103e8f7155f3ce2ffa0049fe60169878d47a4364b277906386f8de21c9234aa1"}, + {file = "cryptography-39.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6236a9610c912b129610eb1a274bdc1350b5df834d124fa84729ebeaf7da42c3"}, + {file = "cryptography-39.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e944fe07b6f229f4c1a06a7ef906a19652bdd9fd54c761b0ff87e83ae7a30354"}, + {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:35d658536b0a4117c885728d1a7032bdc9a5974722ae298d6c533755a6ee3915"}, + {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:30b1d1bfd00f6fc80d11300a29f1d8ab2b8d9febb6ed4a38a76880ec564fae84"}, + {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e029b844c21116564b8b61216befabca4b500e6816fa9f0ba49527653cae2108"}, + {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fa507318e427169ade4e9eccef39e9011cdc19534f55ca2f36ec3f388c1f70f3"}, + {file = "cryptography-39.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8bc0008ef798231fac03fe7d26e82d601d15bd16f3afaad1c6113771566570f3"}, + {file = "cryptography-39.0.2.tar.gz", hash = "sha256:bc5b871e977c8ee5a1bbc42fa8d19bcc08baf0c51cbf1586b0e87a2694dde42f"}, +] [package.dependencies] cffi = ">=1.12" [package.extras] -docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx_rtd_theme"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] -sdist = ["setuptools_rust (>=0.11.4)"] +pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"] +sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"] +test-randomorder = ["pytest-randomly"] +tox = ["tox"] [[package]] name = "defusedxml" @@ -331,39 +656,37 @@ description = "XML bomb protection for Python stdlib modules" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "deprecated" -version = "1.2.13" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] [[package]] name = "dill" -version = "0.3.5.1" +version = "0.3.6" description = "serialize all of python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +python-versions = ">=3.7" +files = [ + {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, + {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, +] [package.extras] graph = ["objgraph (>=1.7.2)"] [[package]] name = "django" -version = "3.2.14" +version = "3.2.18" description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "Django-3.2.18-py3-none-any.whl", hash = "sha256:4d492d9024c7b3dfababf49f94511ab6a58e2c9c3c7207786f1ba4eb77750706"}, + {file = "Django-3.2.18.tar.gz", hash = "sha256:08208dfe892eb64fff073ca743b3b952311104f939e7f6dae954fe72dcc533ba"}, +] [package.dependencies] asgiref = ">=3.3.2,<4" @@ -381,6 +704,10 @@ description = "Django tag for ajax-enabled tables" category = "main" optional = false python-versions = "*" +files = [ + {file = "django_ajax_tables-1.1.1-py3-none-any.whl", hash = "sha256:62e0138949153c0a994eefbf469f5496b1ad98bc073e170bc021a1aada7a32d0"}, + {file = "django_ajax_tables-1.1.1.tar.gz", hash = "sha256:5a7e7bc7940aa6332a564916cde22010a858a3d29fc1090ce8061010ec76337c"}, +] [[package]] name = "django-appconf" @@ -389,6 +716,10 @@ description = "A helper class for handling configuration defaults of packaged ap category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-appconf-1.0.5.tar.gz", hash = "sha256:be3db0be6c81fa84742000b89a81c016d70ae66a7ccb620cdef592b1f1a6aaa4"}, + {file = "django_appconf-1.0.5-py3-none-any.whl", hash = "sha256:ae9f864ee1958c815a965ed63b3fba4874eec13de10236ba063a788f9a17389d"}, +] [package.dependencies] django = "*" @@ -400,6 +731,10 @@ description = "A slick ORM cache with automatic granular event-driven invalidati category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "django-cacheops-6.0.tar.gz", hash = "sha256:78e161ebd96a32e28e19ec7da31f2afed9e62a79726b8b5f0ed12dd16c2e5841"}, + {file = "django_cacheops-6.0-py2.py3-none-any.whl", hash = "sha256:ee38b969c9fc68f7c88e769b6c811e19563cca1ae08210d9f553ff758b6c3e17"}, +] [package.dependencies] django = ">=2.1" @@ -414,6 +749,10 @@ description = "Database-backed Periodic Tasks." category = "main" optional = false python-versions = "*" +files = [ + {file = "django-celery-beat-2.2.1.tar.gz", hash = "sha256:97ae5eb309541551bdb07bf60cc57cadacf42a74287560ced2d2c06298620234"}, + {file = "django_celery_beat-2.2.1-py2.py3-none-any.whl", hash = "sha256:ab43049634fd18dc037927d7c2c7d5f67f95283a20ebbda55f42f8606412e66c"}, +] [package.dependencies] celery = ">=5.0,<6.0" @@ -423,11 +762,15 @@ python-crontab = ">=2.3.4" [[package]] name = "django-constance" -version = "2.8.0" +version = "2.9.1" description = "Django live settings with pluggable backends, including Redis." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-constance-2.9.1.tar.gz", hash = "sha256:4c6a96a5f2cbce1bc3fa41aa20566b6ee26fbd896c9f91f996518a3a0904f6c8"}, + {file = "django_constance-2.9.1-py3-none-any.whl", hash = "sha256:bf0b392efa18a1f3f464eddb7eb36ac5c02598354a5e31d0d4ce4fc8b535694b"}, +] [package.dependencies] django-picklefield = {version = "*", optional = true, markers = "extra == \"database\""} @@ -438,14 +781,18 @@ redis = ["redis"] [[package]] name = "django-cors-headers" -version = "3.10.1" +version = "3.13.0" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "django-cors-headers-3.13.0.tar.gz", hash = "sha256:f9dc6b4e3f611c3199700b3e5f3398c28757dcd559c2f82932687f3d0443cfdf"}, + {file = "django_cors_headers-3.13.0-py3-none-any.whl", hash = "sha256:37e42883b5f1f2295df6b4bba96eb2417a14a03270cb24b2a07f021cd4487cf4"}, +] [package.dependencies] -Django = ">=2.2" +Django = ">=3.2" [[package]] name = "django-cryptography" @@ -454,6 +801,10 @@ description = "Easily encrypt data in Django" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "django-cryptography-1.0.tar.gz", hash = "sha256:13de5cf8f1250744c104b9e24774d03aa6d8488959dd40cdc016934043652445"}, + {file = "django_cryptography-1.0-py3-none-any.whl", hash = "sha256:0a99980b1cee7cc5e52f9b20b322620fea7cc124d770273e7bd285b20fd9d222"}, +] [package.dependencies] cryptography = "*" @@ -466,32 +817,43 @@ description = "Custom FILE_STORAGE for Django. Saves files in your database inst category = "main" optional = false python-versions = "*" +files = [ + {file = "django-db-file-storage-0.5.5.tar.gz", hash = "sha256:5d5da694b78ab202accab4508b958e0e37b3d146310e76f6f6125e1bdeaaad14"}, +] [package.dependencies] Django = "*" [[package]] name = "django-debug-toolbar" -version = "3.5.0" +version = "3.8.1" description = "A configurable set of panels that display various debug information about the current request/response." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "django_debug_toolbar-3.8.1-py3-none-any.whl", hash = "sha256:879f8a4672d41621c06a4d322dcffa630fc4df056cada6e417ed01db0e5e0478"}, + {file = "django_debug_toolbar-3.8.1.tar.gz", hash = "sha256:24ef1a7d44d25e60d7951e378454c6509bf536dce7e7d9d36e7c387db499bc27"}, +] [package.dependencies] -Django = ">=3.2" -sqlparse = ">=0.2.0" +django = ">=3.2.4" +sqlparse = ">=0.2" [[package]] name = "django-extensions" -version = "3.1.5" +version = "3.2.1" description = "Extensions for Django" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-extensions-3.2.1.tar.gz", hash = "sha256:2a4f4d757be2563cd1ff7cfdf2e57468f5f931cc88b23cf82ca75717aae504a4"}, + {file = "django_extensions-3.2.1-py3-none-any.whl", hash = "sha256:421464be390289513f86cb5e18eb43e5dc1de8b4c27ba9faa3b91261b0d67e09"}, +] [package.dependencies] -Django = ">=2.2" +Django = ">=3.2" [[package]] name = "django-filter" @@ -500,6 +862,10 @@ description = "Django-filter is a reusable Django application for allowing users category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-filter-21.1.tar.gz", hash = "sha256:632a251fa8f1aadb4b8cceff932bb52fe2f826dd7dfe7f3eac40e5c463d6836e"}, + {file = "django_filter-21.1-py3-none-any.whl", hash = "sha256:f4a6737a30104c98d2e2a5fb93043f36dd7978e0c7ddc92f5998e85433ea5063"}, +] [package.dependencies] Django = ">=2.2" @@ -511,6 +877,10 @@ description = "Run checks on services like databases, queue servers, celery proc category = "main" optional = false python-versions = "*" +files = [ + {file = "django-health-check-3.16.5.tar.gz", hash = "sha256:1edfd49293ccebbce29f9da609c407f307aee240ab799ab4201031341ae78c0f"}, + {file = "django_health_check-3.16.5-py2.py3-none-any.whl", hash = "sha256:8d66781a0ea82b1a8b44878187b38a27370e94f18287312e39be0593e72d8983"}, +] [package.dependencies] django = ">=2.2" @@ -522,6 +892,10 @@ description = "Jinja2 templating language integrated in Django." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-jinja-2.10.2.tar.gz", hash = "sha256:bfdfbb55c1f5a679d69ad575d550c4707d386634009152efe014089f3c4d1412"}, + {file = "django_jinja-2.10.2-py3-none-any.whl", hash = "sha256:dd003ec1c95c0989eb28a538831bced62b1b61da551cb44a5dfd708fcf75589f"}, +] [package.dependencies] django = ">=2.2" @@ -534,6 +908,10 @@ description = "script tag with additional attributes for django.forms.Media" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django_js_asset-2.0.0-py3-none-any.whl", hash = "sha256:86f9f300d682537ddaf0487dc2ab356581b8f50c069bdba91d334a46e449f923"}, + {file = "django_js_asset-2.0.0.tar.gz", hash = "sha256:adc1ee1efa853fad42054b540c02205344bb406c9bddf87c9e5377a41b7db90f"}, +] [package.dependencies] Django = ">=2.2" @@ -543,11 +921,15 @@ tests = ["coverage"] [[package]] name = "django-mptt" -version = "0.13.4" +version = "0.14.0" description = "Utilities for implementing Modified Preorder Tree Traversal with your Django Models and working with trees of Model instances." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-mptt-0.14.0.tar.gz", hash = "sha256:2c92a2b1614c53086278795ccf50580cf1f9b8564f3ff03055dd62bab5987711"}, + {file = "django_mptt-0.14.0-py3-none-any.whl", hash = "sha256:d9a87433ab0e4f35247c6f6d5a93ace6990860a4ba8796f815d185f773b9acfc"}, +] [package.dependencies] django-js-asset = "*" @@ -562,6 +944,10 @@ description = "Pickled object field for Django" category = "main" optional = false python-versions = ">=3" +files = [ + {file = "django-picklefield-3.1.tar.gz", hash = "sha256:c786cbeda78d6def2b43bff4840d19787809c8909f7ad683961703060398d356"}, + {file = "django_picklefield-3.1-py3-none-any.whl", hash = "sha256:d77c504df7311e8ec14e8b779f10ca6fec74de6c7f8e2c136e1ef60cf955125d"}, +] [package.dependencies] Django = ">=3.2" @@ -576,6 +962,10 @@ description = "Django middlewares to monitor your application with Prometheus.io category = "main" optional = false python-versions = "*" +files = [ + {file = "django-prometheus-2.2.0.tar.gz", hash = "sha256:240378a1307c408bd5fc85614a3a57f1ce633d4a222c9e291e2bbf325173b801"}, + {file = "django_prometheus-2.2.0-py2.py3-none-any.whl", hash = "sha256:e6616770d8820b8834762764bf1b76ec08e1b98e72a6f359d488a2e15fe3537c"}, +] [package.dependencies] prometheus-client = ">=0.7" @@ -587,6 +977,10 @@ description = "Full featured redis cache backend for Django." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-redis-5.2.0.tar.gz", hash = "sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de"}, + {file = "django_redis-5.2.0-py3-none-any.whl", hash = "sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026"}, +] [package.dependencies] Django = ">=2.2" @@ -602,6 +996,10 @@ description = "An app that provides django integration for RQ (Redis Queue)" category = "main" optional = false python-versions = "*" +files = [ + {file = "django-rq-2.5.1.tar.gz", hash = "sha256:f08486602664d73a6e335872c868d79663e380247e6307496d01b8fa770fefd8"}, + {file = "django_rq-2.5.1-py2.py3-none-any.whl", hash = "sha256:7be1e10e7091555f9f36edf100b0dbb205ea2b98683d74443d2bdf3c6649a03f"}, +] [package.dependencies] django = ">=2.0" @@ -619,6 +1017,10 @@ description = "Table/data-grid framework for Django" category = "main" optional = false python-versions = "*" +files = [ + {file = "django-tables2-2.4.1.tar.gz", hash = "sha256:6c72dd208358539e789e4c0efd7d151e43283a4aa4093a35f44c43489e7ddeaa"}, + {file = "django_tables2-2.4.1-py2.py3-none-any.whl", hash = "sha256:50762bf3d7c61a4eb70e763c3e278650d7266bb78d0497fc8fafcf4e507c9a64"}, +] [package.dependencies] Django = ">=1.11" @@ -628,14 +1030,18 @@ tablib = ["tablib"] [[package]] name = "django-taggit" -version = "1.5.1" +version = "3.0.0" description = "django-taggit is a reusable Django application for simple tagging." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "django-taggit-3.0.0.tar.gz", hash = "sha256:e645b8e3dd4f85989d5ef5c5a3d5ebbe5badf5d1e51b53e42d0af726240b00b9"}, + {file = "django_taggit-3.0.0-py3-none-any.whl", hash = "sha256:ca2df20399a11321db75988404afb640a08eff61e52bde35f6c16f307004ec9e"}, +] [package.dependencies] -Django = ">=2.2" +Django = ">=3.2" [[package]] name = "django-timezone-field" @@ -644,7 +1050,11 @@ description = "A Django app providing database and form fields for pytz timezone category = "main" optional = false python-versions = ">=3.5" - +files = [ + {file = "django-timezone-field-4.1.2.tar.gz", hash = "sha256:cffac62452d060e365938aa9c9f7b72d70d8b26b9c60243bce227b35abd1b9df"}, + {file = "django_timezone_field-4.1.2-py3-none-any.whl", hash = "sha256:897c06e40b619cf5731a30d6c156886a7c64cba3a90364832148da7ef32ccf36"}, +] + [package.dependencies] django = ">=2.2" pytz = "*" @@ -652,6 +1062,21 @@ pytz = "*" [package.extras] rest-framework = ["djangorestframework (>=3.0.0)"] +[[package]] +name = "django-tree-queries" +version = "0.11.0" +description = "Tree queries with explicit opt-in, without configurability" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "django_tree_queries-0.11.0-py3-none-any.whl", hash = "sha256:d74fe9e36dc67cb2c6f7df1969ef700627b0c49af2ada15990dd3ae44e4ddb23"}, + {file = "django_tree_queries-0.11.0.tar.gz", hash = "sha256:768bc75fd5ab617e19bec5c7e207964d7f2f6155f5f3d8c3332b41d9d0e6b436"}, +] + +[package.extras] +tests = ["coverage"] + [[package]] name = "django-webserver" version = "1.2.0" @@ -659,6 +1084,10 @@ description = "Django management commands for production webservers" category = "main" optional = false python-versions = "*" +files = [ + {file = "django-webserver-1.2.0.tar.gz", hash = "sha256:c976979d15b5ff9a212f7904d3b779e22219aebb4857860fcaf20e4e40f1da40"}, + {file = "django_webserver-1.2.0-py2.py3-none-any.whl", hash = "sha256:09200631f266484b9e944e38e92681d6e9aa7d90d089a5c86d5fb08fddad84fe"}, +] [package.dependencies] Django = "*" @@ -672,23 +1101,31 @@ waitress = ["waitress"] [[package]] name = "djangorestframework" -version = "3.13.1" +version = "3.14.0" description = "Web APIs for Django, made easy." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"}, + {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"}, +] [package.dependencies] -django = ">=2.2" +django = ">=3.0" pytz = "*" [[package]] name = "drf-spectacular" -version = "0.22.1" +version = "0.24.2" description = "Sane and flexible OpenAPI 3 schema generation for Django REST framework" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "drf-spectacular-0.24.2.tar.gz", hash = "sha256:be32417594080a52f996afd83fd47ea9c2b83cbf13f6d3fbf3de809a0dfa7ead"}, + {file = "drf_spectacular-0.24.2-py3-none-any.whl", hash = "sha256:b276e6f7bda6dfb911e742dab87c6e97bc67da2dafe82d6fd8df7cec6c8b03ec"}, +] [package.dependencies] Django = ">=2.2" @@ -706,22 +1143,30 @@ sidecar = ["drf-spectacular-sidecar"] [[package]] name = "drf-spectacular-sidecar" -version = "2022.7.1" +version = "2023.3.1" description = "Serve self-contained distribution builds of Swagger UI and Redoc with Django" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "drf-spectacular-sidecar-2023.3.1.tar.gz", hash = "sha256:ceb78fd59971bb79e90de38bf89afa50a60b043953f72b3cdeb4ca6a34623f92"}, + {file = "drf_spectacular_sidecar-2023.3.1-py3-none-any.whl", hash = "sha256:2b5ea98d976a4ba023d03cd9dfc2506892e0f26e2ba2869b58ddf344ab69f40f"}, +] [package.dependencies] Django = ">=2.2" [[package]] name = "drf-yasg" -version = "1.20.3" +version = "1.21.5" description = "Automated generation of real Swagger/OpenAPI 2.0 schemas from Django Rest Framework code." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "drf-yasg-1.21.5.tar.gz", hash = "sha256:ceef0c3b5dc4389781afd786e6dc3697af2a2fe0d8724ee1f637c23d75bbc5b2"}, + {file = "drf_yasg-1.21.5-py3-none-any.whl", hash = "sha256:ba9cf4bf79f259290daee9b400fa4fcdb0e78d2f043fa5e9f6589c939fd06d05"}, +] [package.dependencies] coreapi = ">=2.3.3" @@ -745,6 +1190,10 @@ description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] [package.dependencies] importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} @@ -754,30 +1203,42 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "funcy" -version = "1.17" +version = "1.18" description = "A fancy and practical functional tools" category = "main" optional = false python-versions = "*" +files = [ + {file = "funcy-1.18-py2.py3-none-any.whl", hash = "sha256:00ce91afc850357a131dc54f0db2ad8a1110d5087f1fa4480d7ea3ba0249f89d"}, + {file = "funcy-1.18.tar.gz", hash = "sha256:15448d19a8ebcc7a585afe7a384a19186d0bd67cbf56fb42cd1fd0f76313f9b2"}, +] [[package]] name = "gitdb" -version = "4.0.9" +version = "4.0.10" description = "Git Object Database" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, + {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, +] [package.dependencies] smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.27" -description = "GitPython is a python library used to interact with Git repositories" +version = "3.1.31" +description = "GitPython is a Python library used to interact with Git repositories" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.31-py3-none-any.whl", hash = "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"}, + {file = "GitPython-3.1.31.tar.gz", hash = "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573"}, +] [package.dependencies] gitdb = ">=4.0.1,<5" @@ -790,6 +1251,10 @@ description = "GraphQL Framework for Python" category = "main" optional = false python-versions = "*" +files = [ + {file = "graphene-2.1.9-py2.py3-none-any.whl", hash = "sha256:3d446eb1237c551052bc31155cf1a3a607053e4f58c9172b83a1b597beaa0868"}, + {file = "graphene-2.1.9.tar.gz", hash = "sha256:b9f2850e064eebfee9a3ef4a1f8aa0742848d97652173ab44c82cc8a62b9ed93"}, +] [package.dependencies] aniso8601 = ">=3,<=7" @@ -809,6 +1274,10 @@ description = "Graphene Django integration" category = "main" optional = false python-versions = "*" +files = [ + {file = "graphene-django-2.15.0.tar.gz", hash = "sha256:b78c9b05bc899016b9cc5bf13faa1f37fe1faa8c5407552c6ddd1a28f46fc31a"}, + {file = "graphene_django-2.15.0-py2.py3-none-any.whl", hash = "sha256:02671d195f0c09c8649acff2a8f4ad4f297d0f7d98ea6e6cdf034b81bab92880"}, +] [package.dependencies] Django = ">=1.11" @@ -831,6 +1300,9 @@ description = "Optimize database access inside graphene queries." category = "main" optional = false python-versions = "*" +files = [ + {file = "graphene-django-optimizer-0.8.0.tar.gz", hash = "sha256:79269880d59d0a35d41751ddcb419220c4ad3871960416371119f447cb2e1a77"}, +] [[package]] name = "graphql-core" @@ -839,6 +1311,10 @@ description = "GraphQL implementation for Python" category = "main" optional = false python-versions = "*" +files = [ + {file = "graphql-core-2.3.2.tar.gz", hash = "sha256:aac46a9ac524c9855910c14c48fc5d60474def7f99fd10245e76608eba7af746"}, + {file = "graphql_core-2.3.2-py2.py3-none-any.whl", hash = "sha256:44c9bac4514e5e30c5a595fac8e3c76c1975cae14db215e8174c7fe995825bad"}, +] [package.dependencies] promise = ">=2.3,<3" @@ -856,6 +1332,10 @@ description = "Relay implementation for Python" category = "main" optional = false python-versions = "*" +files = [ + {file = "graphql-relay-2.0.1.tar.gz", hash = "sha256:870b6b5304123a38a0b215a79eace021acce5a466bf40cd39fa18cb8528afabb"}, + {file = "graphql_relay-2.0.1-py3-none-any.whl", hash = "sha256:ac514cb86db9a43014d7e73511d521137ac12cf0101b2eaa5f0a3da2e10d913d"}, +] [package.dependencies] graphql-core = ">=2.2,<3" @@ -864,42 +1344,55 @@ six = ">=1.12" [[package]] name = "idna" -version = "3.3" +version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] [[package]] name = "importlib-metadata" -version = "4.4.0" +version = "4.13.0" description = "Read metadata from Python packages" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"}, + {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"}, +] [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +perf = ["ipython"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "importlib-resources" -version = "5.8.0" +version = "5.12.0" description = "Read resources from Python packages" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, + {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, +] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [[package]] name = "inflection" @@ -908,26 +1401,38 @@ description = "A port of Ruby on Rails inflector to Python" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, + {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, +] [[package]] name = "invoke" -version = "1.7.1" +version = "2.0.0" description = "Pythonic task execution" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" +files = [ + {file = "invoke-2.0.0-py3-none-any.whl", hash = "sha256:a860582bcf7a4b336fe18ef53937f0f28cec1c0053ffa767c2fcf7ba0b850f59"}, + {file = "invoke-2.0.0.tar.gz", hash = "sha256:7ab5dd9cd76b787d560a78b1a9810d252367ab595985c50612702be21d671dd7"}, +] [[package]] name = "isort" -version = "5.10.1" +version = "5.11.5" description = "A Python utility / library to sort Python imports." category = "dev" optional = false -python-versions = ">=3.6.1,<4.0" +python-versions = ">=3.7.0" +files = [ + {file = "isort-5.11.5-py3-none-any.whl", hash = "sha256:ba1d72fb2595a01c7895a5128f9585a5cc4b6d395f1c8d514989b9a7eb2a8746"}, + {file = "isort-5.11.5.tar.gz", hash = "sha256:6be1f76a507cb2ecf16c7cf14a37e41609ca082330be4e3436a18ef74add55db"}, +] [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile-deprecated-finder = ["pipreqs", "requirementslib"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] @@ -938,14 +1443,22 @@ description = "Simple immutable types for python." category = "main" optional = false python-versions = "*" +files = [ + {file = "itypes-1.2.0-py2.py3-none-any.whl", hash = "sha256:03da6872ca89d29aef62773672b2d408f490f80db48b23079a4b194c86dd04c6"}, + {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, +] [[package]] name = "jinja2" -version = "3.0.3" +version = "3.1.2" description = "A very fast and expressive template engine." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] [package.dependencies] MarkupSafe = ">=2.0" @@ -955,11 +1468,15 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.4.0" +version = "4.7.2" description = "An implementation of JSON Schema validation for Python" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.7.2-py3-none-any.whl", hash = "sha256:c7448a421b25e424fccfceea86b4e3a8672b4436e1988ccbde92c80828d4f085"}, + {file = "jsonschema-4.7.2.tar.gz", hash = "sha256:73764f461d61eb97a057c929368610a134d1d1fffd858acfe88864ee94f1f1d3"}, +] [package.dependencies] attrs = ">=17.4.0" @@ -979,6 +1496,10 @@ description = "Messaging library for Python." category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "kombu-5.2.4-py3-none-any.whl", hash = "sha256:8b213b24293d3417bcf0d2f5537b7f756079e3ea232a8386dcc89a59fd2361a4"}, + {file = "kombu-5.2.4.tar.gz", hash = "sha256:37cee3ee725f94ea8bb173eaab7c1760203ea53bbebae226328600f9d2799610"}, +] [package.dependencies] amqp = ">=5.0.9,<6.0.0" @@ -1004,11 +1525,49 @@ zookeeper = ["kazoo (>=1.3.1)"] [[package]] name = "lazy-object-proxy" -version = "1.7.1" +version = "1.9.0" description = "A fast and thorough lazy object proxy." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, +] [[package]] name = "markdown" @@ -1017,6 +1576,10 @@ description = "Python implementation of Markdown." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, + {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, +] [package.dependencies] importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} @@ -1024,13 +1587,91 @@ importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} [package.extras] testing = ["coverage", "pyyaml"] +[[package]] +name = "markdown-it-py" +version = "2.2.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +category = "dev" +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" +typing_extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} + +[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.1" +version = "2.1.2" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, + {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, +] [[package]] name = "mccabe" @@ -1039,73 +1680,99 @@ description = "McCabe checker, plugin for flake8" category = "dev" optional = false python-versions = "*" +files = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +category = "dev" +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 = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] [[package]] name = "nautobot" -version = "1.3.8" +version = "1.5.13" description = "Source of truth and network automation platform." category = "main" optional = false python-versions = ">=3.7,<4.0" +files = [ + {file = "nautobot-1.5.13-py3-none-any.whl", hash = "sha256:10db9a1b5a50adad0e079d9d11ce6e5a5fa1dd9df07ab5cfa325e87fdf023cea"}, + {file = "nautobot-1.5.13.tar.gz", hash = "sha256:70ead6cefd724fee18ed06febdc8110a49cc6e98d4af0d1e0921567343475464"}, +] [package.dependencies] -celery = ">=5.2.3,<5.3.0" -Django = ">=3.2.14,<3.3.0" +celery = ">=5.2.7,<5.3.0" +Django = ">=3.2.18,<3.3.0" django-ajax-tables = ">=1.1.1,<1.2.0" django-cacheops = ">=6.0,<6.1" django-celery-beat = ">=2.2.1,<2.3.0" -django-constance = {version = ">=2.8.0,<2.9.0", extras = ["database"]} -django-cors-headers = ">=3.10.1,<3.11.0" +django-constance = {version = ">=2.9.0,<2.10.0", extras = ["database"]} +django-cors-headers = ">=3.13.0,<3.14.0" django-cryptography = ">=1.0,<1.1" django-db-file-storage = ">=0.5.5,<0.6.0" -django-extensions = ">=3.1.5,<3.2.0" +django-extensions = ">=3.2.0,<3.3.0" django-filter = ">=21.1,<21.2" django-health-check = ">=3.16.5,<3.17.0" -django-jinja = ">=2.10.0,<2.11.0" -django-mptt = ">=0.13.4,<0.14.0" +django-jinja = ">=2.10.2,<2.11.0" +django-mptt = ">=0.14.0,<0.15.0" django-prometheus = ">=2.2.0,<2.3.0" django-redis = ">=5.2.0,<5.3.0" django-rq = ">=2.5.1,<2.6.0" django-tables2 = ">=2.4.1,<2.5.0" -django-taggit = ">=1.5.1,<1.6.0" +django-taggit = ">=3.0.0,<3.1.0" django-timezone-field = ">=4.1.2,<4.2.0" +django-tree-queries = ">=0.11,<0.12" django-webserver = ">=1.2.0,<1.3.0" -djangorestframework = ">=3.13.1,<3.14.0" -drf-spectacular = {version = ">=0.22.1,<0.23.0", extras = ["sidecar"]} -drf-yasg = {version = ">=1.20.0,<1.21.0", extras = ["validation"]} -GitPython = ">=3.1.27,<3.2.0" +djangorestframework = ">=3.14.0,<3.15.0" +drf-spectacular = {version = ">=0.24.2,<0.25.0", extras = ["sidecar"]} +drf-yasg = {version = ">=1.20.0,<2.0.0", extras = ["validation"]} +GitPython = ">=3.1.31,<3.2.0" graphene-django = ">=2.15.0,<2.16.0" graphene-django-optimizer = ">=0.8.0,<0.9.0" -importlib-metadata = {version = ">=4.4,<4.5", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.0.3,<3.1.0" -jsonschema = ">=4.4.0,<4.5.0" -Markdown = ">=3.3.6,<3.4.0" -MarkupSafe = ">=2.1.0,<2.2.0" +importlib-metadata = {version = ">=4.4,<5.0", markers = "python_version < \"3.8\""} +Jinja2 = ">=3.1.0,<3.2.0" +jsonschema = ">=4.7.0,<4.8.0" +Markdown = ">=3.3.7,<3.4.0" +MarkupSafe = ">=2.1.1,<2.2.0" netaddr = ">=0.8.0,<0.9.0" -netutils = ">=1.1.0,<1.2.0" -Pillow = ">=9.0.1,<9.1.0" -psycopg2-binary = ">=2.9.3,<2.10.0" +netutils = ">=1.4.1,<2.0.0" +Pillow = ">=9.3.0,<9.4.0" +prometheus-client = ">=0.14.1,<0.15.0" +psycopg2-binary = ">=2.9.5,<2.10.0" pycryptodome = ">=3.13.0,<3.14.0" -pyuwsgi = ">=2.0.20,<2.1.0" +pyuwsgi = ">=2.0.21,<2.1.0" PyYAML = ">=6.0,<6.1" social-auth-app-django = ">=5.0.0,<5.1.0" -svgwrite = ">=1.4.1,<1.5.0" +svgwrite = ">=1.4.2,<1.5.0" [package.extras] -all = ["django-auth-ldap (>=4.0.0,<4.1.0)", "django-storages (>=1.12.3,<1.13.0)", "mysqlclient (>=2.1.0,<2.2.0)", "napalm (>=3.3.1,<3.4.0)", "social-auth-core[openidconnect,saml] (>=4.2.0,<4.3.0)"] -ldap = ["django-auth-ldap (>=4.0.0,<4.1.0)"] +all = ["django-auth-ldap (>=4.1.0,<4.2.0)", "django-storages (>=1.12.3,<1.13.0)", "mysqlclient (>=2.1.0,<2.2.0)", "napalm (>=3.4.1,<3.5.0)", "social-auth-core[openidconnect,saml] (>=4.3.0,<4.4.0)"] +ldap = ["django-auth-ldap (>=4.1.0,<4.2.0)"] mysql = ["mysqlclient (>=2.1.0,<2.2.0)"] -napalm = ["napalm (>=3.3.1,<3.4.0)"] +napalm = ["napalm (>=3.4.1,<3.5.0)"] remote-storage = ["django-storages (>=1.12.3,<1.13.0)"] -sso = ["social-auth-core[openidconnect,saml] (>=4.2.0,<4.3.0)"] +sso = ["social-auth-core[openidconnect,saml] (>=4.3.0,<4.4.0)"] [[package]] name = "netaddr" @@ -1114,22 +1781,37 @@ description = "A network address manipulation library for Python" category = "main" optional = false python-versions = "*" +files = [ + {file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"}, + {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, +] [[package]] name = "netutils" -version = "1.1.0" +version = "1.4.1" description = "Common helper functions useful in network automation." category = "main" optional = false -python-versions = ">=3.6,<4.0" +python-versions = ">=3.7,<4.0" +files = [ + {file = "netutils-1.4.1-py3-none-any.whl", hash = "sha256:41002e42b205149fbe6739b7fdbc778ed843e87fabba9691d3d06a35f7876fd4"}, + {file = "netutils-1.4.1.tar.gz", hash = "sha256:4f7501478d810bcd3c64edfe064fa8962a1572636f4fceee2538fc9d3616fbe2"}, +] + +[package.extras] +optionals = ["napalm (>=4.0.0,<5.0.0)"] [[package]] name = "oauthlib" -version = "3.2.1" +version = "3.2.2" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] [package.extras] rsa = ["cryptography (>=3.0.0)"] @@ -1138,50 +1820,133 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "packaging" -version = "21.3" +version = "23.0" description = "Core utilities for Python packages" category = "main" optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +python-versions = ">=3.7" +files = [ + {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, + {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, +] [[package]] name = "pathspec" -version = "0.9.0" +version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, +] [[package]] name = "pbr" -version = "5.9.0" +version = "5.11.1" description = "Python Build Reasonableness" category = "dev" optional = false python-versions = ">=2.6" +files = [ + {file = "pbr-5.11.1-py2.py3-none-any.whl", hash = "sha256:567f09558bae2b3ab53cb3c1e2e33e726ff3338e7bae3db5dc954b3a44eef12b"}, + {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, +] [[package]] name = "pillow" -version = "9.0.1" +version = "9.3.0" description = "Python Imaging Library (Fork)" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "Pillow-9.3.0-1-cp37-cp37m-win32.whl", hash = "sha256:e6ea6b856a74d560d9326c0f5895ef8050126acfdc7ca08ad703eb0081e82b74"}, + {file = "Pillow-9.3.0-1-cp37-cp37m-win_amd64.whl", hash = "sha256:32a44128c4bdca7f31de5be641187367fe2a450ad83b833ef78910397db491aa"}, + {file = "Pillow-9.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:0b7257127d646ff8676ec8a15520013a698d1fdc48bc2a79ba4e53df792526f2"}, + {file = "Pillow-9.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b90f7616ea170e92820775ed47e136208e04c967271c9ef615b6fbd08d9af0e3"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68943d632f1f9e3dce98908e873b3a090f6cba1cbb1b892a9e8d97c938871fbe"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be55f8457cd1eac957af0c3f5ece7bc3f033f89b114ef30f710882717670b2a8"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d77adcd56a42d00cc1be30843d3426aa4e660cab4a61021dc84467123f7a00c"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:829f97c8e258593b9daa80638aee3789b7df9da5cf1336035016d76f03b8860c"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:801ec82e4188e935c7f5e22e006d01611d6b41661bba9fe45b60e7ac1a8f84de"}, + {file = "Pillow-9.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:871b72c3643e516db4ecf20efe735deb27fe30ca17800e661d769faab45a18d7"}, + {file = "Pillow-9.3.0-cp310-cp310-win32.whl", hash = "sha256:655a83b0058ba47c7c52e4e2df5ecf484c1b0b0349805896dd350cbc416bdd91"}, + {file = "Pillow-9.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:9f47eabcd2ded7698106b05c2c338672d16a6f2a485e74481f524e2a23c2794b"}, + {file = "Pillow-9.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:57751894f6618fd4308ed8e0c36c333e2f5469744c34729a27532b3db106ee20"}, + {file = "Pillow-9.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7db8b751ad307d7cf238f02101e8e36a128a6cb199326e867d1398067381bff4"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3033fbe1feb1b59394615a1cafaee85e49d01b51d54de0cbf6aa8e64182518a1"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22b012ea2d065fd163ca096f4e37e47cd8b59cf4b0fd47bfca6abb93df70b34c"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a65733d103311331875c1dca05cb4606997fd33d6acfed695b1232ba1df193"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:502526a2cbfa431d9fc2a079bdd9061a2397b842bb6bc4239bb176da00993812"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:90fb88843d3902fe7c9586d439d1e8c05258f41da473952aa8b328d8b907498c"}, + {file = "Pillow-9.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:89dca0ce00a2b49024df6325925555d406b14aa3efc2f752dbb5940c52c56b11"}, + {file = "Pillow-9.3.0-cp311-cp311-win32.whl", hash = "sha256:3168434d303babf495d4ba58fc22d6604f6e2afb97adc6a423e917dab828939c"}, + {file = "Pillow-9.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:18498994b29e1cf86d505edcb7edbe814d133d2232d256db8c7a8ceb34d18cef"}, + {file = "Pillow-9.3.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:772a91fc0e03eaf922c63badeca75e91baa80fe2f5f87bdaed4280662aad25c9"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa4107d1b306cdf8953edde0534562607fe8811b6c4d9a486298ad31de733b2"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4012d06c846dc2b80651b120e2cdd787b013deb39c09f407727ba90015c684f"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77ec3e7be99629898c9a6d24a09de089fa5356ee408cdffffe62d67bb75fdd72"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:6c738585d7a9961d8c2821a1eb3dcb978d14e238be3d70f0a706f7fa9316946b"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:828989c45c245518065a110434246c44a56a8b2b2f6347d1409c787e6e4651ee"}, + {file = "Pillow-9.3.0-cp37-cp37m-win32.whl", hash = "sha256:82409ffe29d70fd733ff3c1025a602abb3e67405d41b9403b00b01debc4c9a29"}, + {file = "Pillow-9.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:41e0051336807468be450d52b8edd12ac60bebaa97fe10c8b660f116e50b30e4"}, + {file = "Pillow-9.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b03ae6f1a1878233ac620c98f3459f79fd77c7e3c2b20d460284e1fb370557d4"}, + {file = "Pillow-9.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4390e9ce199fc1951fcfa65795f239a8a4944117b5935a9317fb320e7767b40f"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40e1ce476a7804b0fb74bcfa80b0a2206ea6a882938eaba917f7a0f004b42502"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0a06a052c5f37b4ed81c613a455a81f9a3a69429b4fd7bb913c3fa98abefc20"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03150abd92771742d4a8cd6f2fa6246d847dcd2e332a18d0c15cc75bf6703040"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:15c42fb9dea42465dfd902fb0ecf584b8848ceb28b41ee2b58f866411be33f07"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:51e0e543a33ed92db9f5ef69a0356e0b1a7a6b6a71b80df99f1d181ae5875636"}, + {file = "Pillow-9.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3dd6caf940756101205dffc5367babf288a30043d35f80936f9bfb37f8355b32"}, + {file = "Pillow-9.3.0-cp38-cp38-win32.whl", hash = "sha256:f1ff2ee69f10f13a9596480335f406dd1f70c3650349e2be67ca3139280cade0"}, + {file = "Pillow-9.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:276a5ca930c913f714e372b2591a22c4bd3b81a418c0f6635ba832daec1cbcfc"}, + {file = "Pillow-9.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:73bd195e43f3fadecfc50c682f5055ec32ee2c933243cafbfdec69ab1aa87cad"}, + {file = "Pillow-9.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c7c8ae3864846fc95f4611c78129301e203aaa2af813b703c55d10cc1628535"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0918e03aa0c72ea56edbb00d4d664294815aa11291a11504a377ea018330d3"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0915e734b33a474d76c28e07292f196cdf2a590a0d25bcc06e64e545f2d146c"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0372acb5d3598f36ec0914deed2a63f6bcdb7b606da04dc19a88d31bf0c05b"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ad58d27a5b0262c0c19b47d54c5802db9b34d38bbf886665b626aff83c74bacd"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c"}, + {file = "Pillow-9.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9aaa107275d8527e9d6e7670b64aabaaa36e5b6bd71a1015ddd21da0d4e06448"}, + {file = "Pillow-9.3.0-cp39-cp39-win32.whl", hash = "sha256:bac18ab8d2d1e6b4ce25e3424f709aceef668347db8637c2296bcf41acb7cf48"}, + {file = "Pillow-9.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:b472b5ea442148d1c3e2209f20f1e0bb0eb556538690fa70b5e1f79fa0ba8dc2"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ab388aaa3f6ce52ac1cb8e122c4bd46657c15905904b3120a6248b5b8b0bc228"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbb8e7f2abee51cef77673be97760abff1674ed32847ce04b4af90f610144c7b"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca31dd6014cb8b0b2db1e46081b0ca7d936f856da3b39744aef499db5d84d02"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c7025dce65566eb6e89f56c9509d4f628fddcedb131d9465cacd3d8bac337e7e"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ebf2029c1f464c59b8bdbe5143c79fa2045a581ac53679733d3a91d400ff9efb"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b59430236b8e58840a0dfb4099a0e8717ffb779c952426a69ae435ca1f57210c"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12ce4932caf2ddf3e41d17fc9c02d67126935a44b86df6a206cf0d7161548627"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae5331c23ce118c53b172fa64a4c037eb83c9165aba3a7ba9ddd3ec9fa64a699"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0b07fffc13f474264c336298d1b4ce01d9c5a011415b79d4ee5527bb69ae6f65"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:073adb2ae23431d3b9bcbcff3fe698b62ed47211d0716b067385538a1b0f28b8"}, + {file = "Pillow-9.3.0.tar.gz", hash = "sha256:c935a22a557a560108d780f9a0fc426dd7459940dc54faa49d83249c8d3e760f"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] [[package]] name = "platformdirs" -version = "2.5.2" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "3.1.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"}, + {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} [package.extras] -docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"] -test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "prometheus-client" @@ -1190,6 +1955,10 @@ description = "Python client for the Prometheus monitoring system." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "prometheus_client-0.14.1-py3-none-any.whl", hash = "sha256:522fded625282822a89e2773452f42df14b5a8e84a86433e3f8a189c1d54dc01"}, + {file = "prometheus_client-0.14.1.tar.gz", hash = "sha256:5459c427624961076277fdc6dc50540e2bacb98eebde99886e59ec55ed92093a"}, +] [package.extras] twisted = ["twisted"] @@ -1201,6 +1970,9 @@ description = "Promises/A+ implementation for Python" category = "main" optional = false python-versions = "*" +files = [ + {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"}, +] [package.dependencies] six = "*" @@ -1210,22 +1982,99 @@ test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", [[package]] name = "prompt-toolkit" -version = "3.0.30" +version = "3.0.38" description = "Library for building powerful interactive command lines in Python" category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, + {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, +] [package.dependencies] wcwidth = "*" [[package]] name = "psycopg2-binary" -version = "2.9.3" +version = "2.9.5" description = "psycopg2 - Python-PostgreSQL Database Adapter" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "psycopg2-binary-2.9.5.tar.gz", hash = "sha256:33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:0775d6252ccb22b15da3b5d7adbbf8cfe284916b14b6dc0ff503a23edb01ee85"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ec46ed947801652c9643e0b1dc334cfb2781232e375ba97312c2fc256597632"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3520d7af1ebc838cc6084a3281145d5cd5bdd43fdef139e6db5af01b92596cb7"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cbc554ba47ecca8cd3396ddaca85e1ecfe3e48dd57dc5e415e59551affe568e"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:5d28ecdf191db558d0c07d0f16524ee9d67896edf2b7990eea800abeb23ebd61"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:b9c33d4aef08dfecbd1736ceab8b7b3c4358bf10a0121483e5cd60d3d308cc64"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:05b3d479425e047c848b9782cd7aac9c6727ce23181eb9647baf64ffdfc3da41"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1e491e6489a6cb1d079df8eaa15957c277fdedb102b6a68cfbf40c4994412fd0"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:9e32cedc389bcb76d9f24ea8a012b3cb8385ee362ea437e1d012ffaed106c17d"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46850a640df62ae940e34a163f72e26aca1f88e2da79148e1862faaac985c302"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-win32.whl", hash = "sha256:3d790f84201c3698d1bfb404c917f36e40531577a6dda02e45ba29b64d539867"}, + {file = "psycopg2_binary-2.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:1764546ffeaed4f9428707be61d68972eb5ede81239b46a45843e0071104d0dd"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_10_9_universal2.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:426c2ae999135d64e6a18849a7d1ad0e1bd007277e4a8f4752eaa40a96b550ff"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cf1d44e710ca3a9ce952bda2855830fe9f9017ed6259e01fcd71ea6287565f5"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:024030b13bdcbd53d8a93891a2cf07719715724fc9fee40243f3bd78b4264b8f"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcda1c84a1c533c528356da5490d464a139b6e84eb77cc0b432e38c5c6dd7882"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:2ef892cabdccefe577088a79580301f09f2a713eb239f4f9f62b2b29cafb0577"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:af0516e1711995cb08dc19bbd05bec7dbdebf4185f68870595156718d237df3e"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e67b3c26e9b6d37b370c83aa790bbc121775c57bfb096c2e77eacca25fd0233b"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5fc447058d083b8c6ac076fc26b446d44f0145308465d745fba93a28c14c9e32"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d892bfa1d023c3781a3cab8dd5af76b626c483484d782e8bd047c180db590e4c"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-win32.whl", hash = "sha256:2abccab84d057723d2ca8f99ff7b619285d40da6814d50366f61f0fc385c3903"}, + {file = "psycopg2_binary-2.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:bef7e3f9dc6f0c13afdd671008534be5744e0e682fb851584c8c3a025ec09720"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:6e63814ec71db9bdb42905c925639f319c80e7909fb76c3b84edc79dadef8d60"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:212757ffcecb3e1a5338d4e6761bf9c04f750e7d027117e74aa3cd8a75bb6fbd"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f8a9bcab7b6db2e3dbf65b214dfc795b4c6b3bb3af922901b6a67f7cb47d5f8"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:56b2957a145f816726b109ee3d4e6822c23f919a7d91af5a94593723ed667835"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:70831e03bd53702c941da1a1ad36c17d825a24fbb26857b40913d58df82ec18b"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:dbc332beaf8492b5731229a881807cd7b91b50dbbbaf7fe2faf46942eda64a24"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:2d964eb24c8b021623df1c93c626671420c6efadbdb8655cb2bd5e0c6fa422ba"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:95076399ec3b27a8f7fa1cc9a83417b1c920d55cf7a97f718a94efbb96c7f503"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-win32.whl", hash = "sha256:3fc33295cfccad697a97a76dec3f1e94ad848b7b163c3228c1636977966b51e2"}, + {file = "psycopg2_binary-2.9.5-cp36-cp36m-win_amd64.whl", hash = "sha256:02551647542f2bf89073d129c73c05a25c372fc0a49aa50e0de65c3c143d8bd0"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:63e318dbe52709ed10d516a356f22a635e07a2e34c68145484ed96a19b0c4c68"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7e518a0911c50f60313cb9e74a169a65b5d293770db4770ebf004245f24b5c5"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9d38a4656e4e715d637abdf7296e98d6267df0cc0a8e9a016f8ba07e4aa3eeb"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:68d81a2fe184030aa0c5c11e518292e15d342a667184d91e30644c9d533e53e1"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:7ee3095d02d6f38bd7d9a5358fcc9ea78fcdb7176921528dd709cc63f40184f5"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:46512486be6fbceef51d7660dec017394ba3e170299d1dc30928cbedebbf103a"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b911dfb727e247340d36ae20c4b9259e4a64013ab9888ccb3cbba69b77fd9636"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:422e3d43b47ac20141bc84b3d342eead8d8099a62881a501e97d15f6addabfe9"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c5682a45df7d9642eff590abc73157c887a68f016df0a8ad722dcc0f888f56d7"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-win32.whl", hash = "sha256:b8104f709590fff72af801e916817560dbe1698028cd0afe5a52d75ceb1fce5f"}, + {file = "psycopg2_binary-2.9.5-cp37-cp37m-win_amd64.whl", hash = "sha256:7b3751857da3e224f5629400736a7b11e940b5da5f95fa631d86219a1beaafec"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:043a9fd45a03858ff72364b4b75090679bd875ee44df9c0613dc862ca6b98460"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9ffdc51001136b699f9563b1c74cc1f8c07f66ef7219beb6417a4c8aaa896c28"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15ba5982c177bc4b23a7940c7e4394197e2d6a424a2d282e7c236b66da6d896"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc85b3777068ed30aff8242be2813038a929f2084f69e43ef869daddae50f6ee"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:215d6bf7e66732a514f47614f828d8c0aaac9a648c46a831955cb103473c7147"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:7d07f552d1e412f4b4e64ce386d4c777a41da3b33f7098b6219012ba534fb2c2"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a0adef094c49f242122bb145c3c8af442070dc0e4312db17e49058c1702606d4"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:00475004e5ed3e3bf5e056d66e5dcdf41a0dc62efcd57997acd9135c40a08a50"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7d88db096fa19d94f433420eaaf9f3c45382da2dd014b93e4bf3215639047c16"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:902844f9c4fb19b17dfa84d9e2ca053d4a4ba265723d62ea5c9c26b38e0aa1e6"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-win32.whl", hash = "sha256:4e7904d1920c0c89105c0517dc7e3f5c20fb4e56ba9cdef13048db76947f1d79"}, + {file = "psycopg2_binary-2.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:a36a0e791805aa136e9cbd0ffa040d09adec8610453ee8a753f23481a0057af5"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:25382c7d174c679ce6927c16b6fbb68b10e56ee44b1acb40671e02d29f2fce7c"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9c38d3869238e9d3409239bc05bc27d6b7c99c2a460ea337d2814b35fb4fea1b"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c6527c8efa5226a9e787507652dd5ba97b62d29b53c371a85cd13f957fe4d42"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e59137cdb970249ae60be2a49774c6dfb015bd0403f05af1fe61862e9626642d"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:d4c7b3a31502184e856df1f7bbb2c3735a05a8ce0ade34c5277e1577738a5c91"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:b9a794cef1d9c1772b94a72eec6da144c18e18041d294a9ab47669bc77a80c1d"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5254cbd4f4855e11cebf678c1a848a3042d455a22a4ce61349c36aafd4c2267"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c5e65c6ac0ae4bf5bef1667029f81010b6017795dcb817ba5c7b8a8d61fab76f"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:74eddec4537ab1f701a1647214734bc52cee2794df748f6ae5908e00771f180a"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-win32.whl", hash = "sha256:937880290775033a743f4836aa253087b85e62784b63fd099ee725d567a48aa1"}, + {file = "psycopg2_binary-2.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:484405b883630f3e74ed32041a87456c5e0e63a8e3429aa93e8714c366d62bd1"}, +] [[package]] name = "pycodestyle" @@ -1234,6 +2083,10 @@ description = "Python style guide checker" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] [[package]] name = "pycparser" @@ -1242,6 +2095,10 @@ description = "C parser in Python" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] [[package]] name = "pycryptodome" @@ -1250,20 +2107,57 @@ description = "Cryptographic library for Python" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodome-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e468724173df02f9d83f3fea830bf0d04aa291b5add22b4a78e01c97aab04873"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fb7a6f222072412f320b9e48d3ce981920efbfce37b06d028ec9bd94093b37f"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4f1b594d0cf35bd12ec4244df1155a7f565bf6e6245976ac36174c1564688c90"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9ea70f6c3f6566159e3798e4593a4a8016994a0080ac29a45200615b45091a1b"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f7aad304575d075faf2806977b726b67da7ba294adc97d878f92a062e357a56a"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:702446a012fd9337b9327d168bb0c7dc714eb93ad361f6f61af9ca8305a301f1"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-win32.whl", hash = "sha256:681ac47c538c64305d710eaed2bb49532f62b3f4c93aa7c423c520df981392e5"}, + {file = "pycryptodome-3.13.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7b3478a187d897f003b2aa1793bcc59463e8d57a42e2aafbcbbe9cd47ec46863"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:eec02d9199af4b1ccfe1f9c587691a07a1fa39d949d2c1dc69d079ab9af8212f"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9c8e0e6c5e982699801b20fa74f43c19aa080d2b53a39f3c132d35958e153bd4"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f5457e44d3f26d9946091e92b28f3e970a56538b96c87b4b155a84e32a40b7b5"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:88d6d54e83cf9bbd665ce1e7b9079983ee2d97a05f42e0569ff00a70f1dd8b1e"}, + {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:72de8c4d71e6b11d54528bb924447fa4fdabcbb3d76cc0e7f61d3b6075def6b3"}, + {file = "pycryptodome-3.13.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:008ef2c631f112cd5a58736e0b29f4a28b4bb853e68878689f8b476fd56e0691"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:51ebe9624ad0a0b4da1aaaa2d43aabadf8537737fd494cee0ffa37cd6326de02"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:deede160bdf87ddb71f0a1314ad5a267b1a960be314ea7dc6b7ad86da6da89a3"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:857c16bffd938254e3a834cd6b2a755ed24e1a953b1a86e33da136d3e4c16a6f"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:ca6db61335d07220de0b665bfee7b8e9615b2dfc67a54016db4826dac34c2dd2"}, + {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:073dedf0f9c490ae22ca081b86357646ac9b76f3e2bd89119d137fc697a9e3b6"}, + {file = "pycryptodome-3.13.0-cp35-abi3-win32.whl", hash = "sha256:e3affa03c49cce7b0a9501cc7f608d4f8e61fb2522b276d599ac049b5955576d"}, + {file = "pycryptodome-3.13.0-cp35-abi3-win_amd64.whl", hash = "sha256:e5d72be02b17e6bd7919555811264403468d1d052fa67c946e402257c3c29a27"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:0896d5d15ffe584d46cb9b69a75cf14a2bc8f6daf635b7bf16c1b041342a44b1"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:e420cdfca73f80fe15f79bb34756959945231a052440813e5fce531e6e96331a"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:720fafdf3e5c5de93039d8308f765cc60b8e9e7e852ad7135aa65dd89238191f"}, + {file = "pycryptodome-3.13.0-pp27-pypy_73-win32.whl", hash = "sha256:7a8b0e526ff239b4f4c61dd6898e2474d609843ffc437267f3a27ddff626e6f6"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d92a5eddffb0ad39f582f07c1de26e9daf6880e3e782a94bb7ebaf939567f8bf"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:cb9453c981554984c6f5c5ce7682d7286e65e2173d7416114c3593a977a01bf5"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:765b8b16bc1fd699e183dde642c7f2653b8f3c9c1a50051139908e9683f97732"}, + {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:b3af53dddf848afb38b3ac2bae7159ddad1feb9bac14aa3acec6ef1797b82f8d"}, + {file = "pycryptodome-3.13.0.tar.gz", hash = "sha256:95bacf9ff7d1b90bba537d3f5f6c834efe6bfbb1a0195cb3573f29e6716ef08d"}, +] [[package]] name = "pydocstyle" -version = "6.1.1" +version = "6.3.0" description = "Python docstring style checker" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, + {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, +] [package.dependencies] -snowballstemmer = "*" +importlib-metadata = {version = ">=2.0.0,<5.0.0", markers = "python_version < \"3.8\""} +snowballstemmer = ">=2.2.0" [package.extras] -toml = ["toml"] +toml = ["tomli (>=1.2.3)"] [[package]] name = "pyflakes" @@ -1272,19 +2166,42 @@ description = "passive checker of Python programs" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] + +[[package]] +name = "pygments" +version = "2.14.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, + {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, +] + +[package.extras] +plugins = ["importlib-metadata"] [[package]] name = "pyjwt" -version = "2.4.0" +version = "2.6.0" description = "JSON Web Token implementation in Python" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "PyJWT-2.6.0-py3-none-any.whl", hash = "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14"}, + {file = "PyJWT-2.6.0.tar.gz", hash = "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd"}, +] [package.extras] -crypto = ["cryptography (>=3.3.1)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.3.1)", "mypy", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] @@ -1294,6 +2211,10 @@ description = "python code static checker" category = "dev" optional = false python-versions = ">=3.6.2" +files = [ + {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, + {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, +] [package.dependencies] astroid = ">=2.11.5,<=2.12.0-dev0" @@ -1315,6 +2236,10 @@ description = "A Pylint plugin to help Pylint understand the Django web framewor category = "dev" optional = false python-versions = "*" +files = [ + {file = "pylint-django-2.5.3.tar.gz", hash = "sha256:0ac090d106c62fe33782a1d01bda1610b761bb1c9bf5035ced9d5f23a13d8591"}, + {file = "pylint_django-2.5.3-py3-none-any.whl", hash = "sha256:56b12b6adf56d548412445bd35483034394a1a94901c3f8571980a13882299d5"}, +] [package.dependencies] pylint = ">=2.0,<3" @@ -1331,36 +2256,62 @@ description = "Utilities and helpers for writing Pylint plugins" category = "dev" optional = false python-versions = ">=3.6.2" +files = [ + {file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"}, + {file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"}, +] [package.dependencies] pylint = ">=1.7" -[[package]] -name = "pyparsing" -version = "3.0.9" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "main" -optional = false -python-versions = ">=3.6.8" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pyrsistent" -version = "0.18.1" +version = "0.19.3" description = "Persistent/Functional/Immutable data structures" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, + {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, + {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, + {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, + {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, + {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, +] [[package]] name = "python-crontab" -version = "2.6.0" +version = "2.7.1" description = "Python Crontab API" category = "main" optional = false python-versions = "*" +files = [ + {file = "python-crontab-2.7.1.tar.gz", hash = "sha256:b21af4647c7bbb848fef2f020616c6b0289dcb9f94b4f991a55310ff9bec5749"}, + {file = "python_crontab-2.7.1-py3-none-any.whl", hash = "sha256:9c374d1c9d401afdd8dd958f20077f74c158ab3fffb9604296802715e887fe48"}, +] [package.dependencies] python-dateutil = "*" @@ -1376,6 +2327,10 @@ description = "Extensions to the standard Python datetime module" category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] [package.dependencies] six = ">=1.5" @@ -1387,6 +2342,10 @@ description = "OpenID support for modern servers and consumers." category = "main" optional = false python-versions = "*" +files = [ + {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"}, + {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"}, +] [package.dependencies] defusedxml = "*" @@ -1397,19 +2356,61 @@ postgresql = ["psycopg2"] [[package]] name = "pytz" -version = "2022.1" +version = "2022.7.1" description = "World timezone definitions, modern and historical" category = "main" optional = false python-versions = "*" +files = [ + {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, + {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, +] [[package]] name = "pyuwsgi" -version = "2.0.20" +version = "2.0.21" description = "The uWSGI server" category = "main" optional = false python-versions = "*" +files = [ + {file = "pyuwsgi-2.0.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10cce470f3db6e5206c3fb9d46b86c5c915dcb6616a617101411006463e833ea"}, + {file = "pyuwsgi-2.0.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e06b41ad50b8d3d5a46374af8c8ed9bcf2627ea97f5718ef2da693ab3425656"}, + {file = "pyuwsgi-2.0.21-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:977ce0f87e3f07571267b6572dcbe8b3d5d488cbc351d33c93ec6cce9737099a"}, + {file = "pyuwsgi-2.0.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:243de3964aa40e9f15cc4be64bf5594bb4d3e847f9b563b3d8f3b2df9c1c1581"}, + {file = "pyuwsgi-2.0.21-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:47e29aca1e856315b18999e6527347cf461f7b333af13b33ba5926e2718c0a3c"}, + {file = "pyuwsgi-2.0.21-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0a6209bf09e14d3ceee1db6d1381346c361245552307388a1cf65229d33d306c"}, + {file = "pyuwsgi-2.0.21-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:09942a86c5501367381b86561dcb69efa4207e1f604a4c5c4e58849f0b895619"}, + {file = "pyuwsgi-2.0.21-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7139eb6bdcb32b64431ba5d3058975d6a34cc52d58c2ffbf611625cd058018a7"}, + {file = "pyuwsgi-2.0.21-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:871d0b9a61a143da0b0ba4a7249d198c804ad63a2374b5bccae7c584d805bdcd"}, + {file = "pyuwsgi-2.0.21-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78c3aaf8e89ee912730ad57e60832c0d10a267b521715c8d832eef19373075aa"}, + {file = "pyuwsgi-2.0.21-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8da171f2519739caad4bf4682a71b92527489eb71b3af41319bbc13f61e14dc"}, + {file = "pyuwsgi-2.0.21-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c9b67d7211e5d9439d1ecc11cf909fc214d05c332e47121d5f92913ebdf5c28c"}, + {file = "pyuwsgi-2.0.21-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c9fdd5032bd4a5d697ccfb50e2e5296c419eb53a8b44cacfcc55d7ceb629be2f"}, + {file = "pyuwsgi-2.0.21-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:445998892e164e7f253d20ffd1ab6f7c9441c77e8d05e8a2525532ba663de0af"}, + {file = "pyuwsgi-2.0.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f76540fbcea52d333acfe172c7c91f284c4526eae8b0d146c60672dbcaece705"}, + {file = "pyuwsgi-2.0.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32eace989380b3677131fea2d5e719a870fcecb2a1db5830d80997e9f501c6db"}, + {file = "pyuwsgi-2.0.21-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26876ce2e934e004d1d98a06abb170743ec743a5cecc3867260f071f31c269e0"}, + {file = "pyuwsgi-2.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e77e27ce32b64b34de26a2ec84cb8fff620153d7a207ea3cbea69b39c0b571b1"}, + {file = "pyuwsgi-2.0.21-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:62d9927a1178af61285b697caa736dfa34fcc48090db45f965859e1fa641f4bc"}, + {file = "pyuwsgi-2.0.21-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ed867fa6d704338820304bd13bc6b20687e823ef70dfaf35c1db324598b60af4"}, + {file = "pyuwsgi-2.0.21-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c38f1e68db1dea7e8b47a64b855cd15e491d1920908be5887189a98ce5e968e9"}, + {file = "pyuwsgi-2.0.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be994a0cdaaf9733e00c2e3275b368586db067802cd0a1af682b0c55070f39c7"}, + {file = "pyuwsgi-2.0.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0753b7ec6174afa590bd5724d25541209387b67f080dbe13db7d9655ef0077df"}, + {file = "pyuwsgi-2.0.21-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c17abbbba53eabdba7fc92a0321864adbf97e8460cfd9c01b714d6c3e3ccc4c"}, + {file = "pyuwsgi-2.0.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13524cea71a1cd2bb4586c773cbf6a9a1085f3e4ba1c52648b2823385c8d7d74"}, + {file = "pyuwsgi-2.0.21-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f5b6c6d413430015f9cbadef2687ce334b2960d0df3cfba4181e39c4af242933"}, + {file = "pyuwsgi-2.0.21-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f44454a0cf419436c0a99bd37586ce9776e3c10454dd3387d2afa9c4c9c4404"}, + {file = "pyuwsgi-2.0.21-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7375666a7dd22f1c9ad4c7d01e957c5941baa489f02cd76cf2064a63a8946dfe"}, + {file = "pyuwsgi-2.0.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56f92e057461bcd32e991661db3fb505a59b8ff35da5af12b062b9ebf1ddfc57"}, + {file = "pyuwsgi-2.0.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c005b1357c525fe63dfb83299ca77f478db4842ee8204e8ac6cb47267fc1920"}, + {file = "pyuwsgi-2.0.21-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10d36e255bd54e7d52ed7dc360821b06748e87a7d5aa826a48ddfa7c9baedb52"}, + {file = "pyuwsgi-2.0.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8693e2a71da6e5f78fa4142893c1b201daadaf71d87275fd906ce6d02e3c9910"}, + {file = "pyuwsgi-2.0.21-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e448bdd8fbacbd27dcdd58f1191ee61c58795a672cedc4ca661a8b83606a158a"}, + {file = "pyuwsgi-2.0.21-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:837d295d3df3d4b6e1a9850922e25fc7a8836949f424a36985491be473f00d21"}, + {file = "pyuwsgi-2.0.21-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92371cb638707574fe93127f9c270216d12751a96e6a624237820a089f846ef5"}, + {file = "pyuwsgi-2.0.21.tar.gz", hash = "sha256:211e8877f5191e347ba905232d04ab30e05ce31ba7a6dac4bfcb48de9845bb52"}, +] [[package]] name = "pyyaml" @@ -1418,20 +2419,64 @@ description = "YAML parser and emitter for Python" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] [[package]] name = "redis" -version = "4.3.4" +version = "4.5.1" description = "Python client for Redis database and key-value store" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "redis-4.5.1-py3-none-any.whl", hash = "sha256:5deb072d26e67d2be1712603bfb7947ec3431fb0eec9c578994052e33035af6d"}, + {file = "redis-4.5.1.tar.gz", hash = "sha256:1eec3741cda408d3a5f84b78d089c8b8d895f21b3b050988351e925faf202864"}, +] [package.dependencies] async-timeout = ">=4.0.2" -deprecated = ">=1.2.3" importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} -packaging = ">=20.4" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] @@ -1440,15 +2485,19 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "requests" -version = "2.28.1" +version = "2.28.2" description = "Python HTTP for Humans." category = "main" optional = false python-versions = ">=3.7, <4" +files = [ + {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, + {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, +] [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = ">=2,<3" +charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" @@ -1463,6 +2512,10 @@ description = "OAuthlib authentication support for Requests." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, + {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, +] [package.dependencies] oauthlib = ">=3.0.0" @@ -1471,25 +2524,53 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] +[[package]] +name = "rich" +version = "13.3.2" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "dev" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.3.2-py3-none-any.whl", hash = "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f"}, + {file = "rich-13.3.2.tar.gz", hash = "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0,<3.0.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "rq" -version = "1.10.1" +version = "1.13.0" description = "RQ is a simple, lightweight, library for creating background jobs, and processing them." category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" +files = [ + {file = "rq-1.13.0-py2.py3-none-any.whl", hash = "sha256:621966d7cbf96d5609557a4bd3fd77f749d6d10997d2e353a3e89a14e08eea16"}, + {file = "rq-1.13.0.tar.gz", hash = "sha256:5bb0380a17597200520731686766bb72faf16ebffb602663560d91ea2c9e7103"}, +] [package.dependencies] click = ">=5.0.0" redis = ">=3.5.0" [[package]] -name = "ruamel.yaml" +name = "ruamel-yaml" version = "0.17.21" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" category = "main" optional = false python-versions = ">=3" +files = [ + {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, + {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, +] [package.dependencies] "ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""} @@ -1499,48 +2580,94 @@ docs = ["ryd"] jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] [[package]] -name = "ruamel.yaml.clib" -version = "0.2.6" +name = "ruamel-yaml-clib" +version = "0.2.7" description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, + {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, +] [[package]] name = "rx" -version = "1.6.1" +version = "1.6.3" description = "Reactive Extensions (Rx) for Python" category = "main" optional = false python-versions = "*" +files = [ + {file = "Rx-1.6.3.tar.gz", hash = "sha256:ca71b65d0fc0603a3b5cfaa9e33f5ba81e4aae10a58491133595088d7734b2da"}, +] [[package]] name = "setuptools" -version = "65.3.0" +version = "67.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "setuptools-67.6.0-py3-none-any.whl", hash = "sha256:b78aaa36f6b90a074c1fa651168723acbf45d14cb1196b6f02c0fd07f17623b2"}, + {file = "setuptools-67.6.0.tar.gz", hash = "sha256:2ee892cd5f29f3373097f5a814697e397cf3ce313616df0af11231e2ad118077"}, +] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "singledispatch" -version = "3.7.0" -description = "Backport functools.singledispatch from Python 3.4 to Python 2.6-3.3." +version = "4.0.0" +description = "Backport functools.singledispatch to older Pythons." category = "main" optional = false -python-versions = ">=2.6" - -[package.dependencies] -six = "*" +python-versions = ">=3.7" +files = [ + {file = "singledispatch-4.0.0-py2.py3-none-any.whl", hash = "sha256:b8f69397a454b45b91e2f949fcc87896c53718ca59aab6367966e8b3f010ec77"}, + {file = "singledispatch-4.0.0.tar.gz", hash = "sha256:f3c327a968651a7f4b03586eab7d90a07b05ff3ef7942d1967036eb9f75ab8fc"}, +] [package.extras] -docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-flake8", "unittest2"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [[package]] name = "six" @@ -1549,6 +2676,10 @@ description = "Python 2 and 3 compatibility utilities" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] [[package]] name = "smmap" @@ -1557,6 +2688,10 @@ description = "A pure Python implementation of a sliding window memory map manag category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, + {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, +] [[package]] name = "snowballstemmer" @@ -1565,6 +2700,10 @@ description = "This package provides 29 stemmers for 28 languages generated from category = "dev" 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 = "social-auth-app-django" @@ -1573,17 +2712,25 @@ description = "Python Social Authentication, Django integration." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "social-auth-app-django-5.0.0.tar.gz", hash = "sha256:b6e3132ce087cdd6e1707aeb1b588be41d318408fcf6395435da0bc6fe9a9795"}, + {file = "social_auth_app_django-5.0.0-py3-none-any.whl", hash = "sha256:52241a25445a010ab1c108bafff21fc5522d5c8cd0d48a92c39c7371824b065d"}, +] [package.dependencies] social-auth-core = ">=4.1.0" [[package]] name = "social-auth-core" -version = "4.3.0" +version = "4.4.0" description = "Python social authentication made simple." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "social-auth-core-4.4.0.tar.gz", hash = "sha256:359f6be5bb2d4caef6500eb6e1b40821a40dde9add8d339d539b1adbba2c9bf7"}, + {file = "social_auth_core-4.4.0-py3-none-any.whl", hash = "sha256:89536f218fa1a769caeaa56ef90f965ea50a81b9a7e3e5a2c5a61b832df11bde"}, +] [package.dependencies] cryptography = ">=1.4" @@ -1595,27 +2742,35 @@ requests = ">=2.9.1" requests-oauthlib = ">=0.6.1" [package.extras] -all = ["cryptography (>=2.1.1)", "lxml (<4.7)", "python-jose (>=3.0.0)", "python3-saml (>=1.2.1)"] -allpy3 = ["cryptography (>=2.1.1)", "lxml (<4.7)", "python-jose (>=3.0.0)", "python3-saml (>=1.2.1)"] +all = ["cryptography (>=2.1.1)", "python-jose (>=3.0.0)", "python3-saml (>=1.5.0)"] +allpy3 = ["cryptography (>=2.1.1)", "python-jose (>=3.0.0)", "python3-saml (>=1.5.0)"] azuread = ["cryptography (>=2.1.1)"] openidconnect = ["python-jose (>=3.0.0)"] -saml = ["lxml (<4.7)", "python3-saml (>=1.2.1)"] +saml = ["python3-saml (>=1.5.0)"] [[package]] name = "sqlparse" -version = "0.4.2" +version = "0.4.3" description = "A non-validating SQL parser." category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "sqlparse-0.4.3-py3-none-any.whl", hash = "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34"}, + {file = "sqlparse-0.4.3.tar.gz", hash = "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268"}, +] [[package]] name = "stevedore" -version = "3.5.0" +version = "3.5.2" description = "Manage dynamic plugins for Python applications" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "stevedore-3.5.2-py3-none-any.whl", hash = "sha256:fa2630e3d0ad3e22d4914aff2501445815b9a4467a6edc49387c667a38faf5bf"}, + {file = "stevedore-3.5.2.tar.gz", hash = "sha256:cf99f41fc0d5a4f185ca4d3d42b03be9011b0a1ec1a4ea1a282be1b4b306dcc2"}, +] [package.dependencies] importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} @@ -1628,19 +2783,27 @@ description = "A Python library to create SVG drawings." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "svgwrite-1.4.3-py3-none-any.whl", hash = "sha256:bb6b2b5450f1edbfa597d924f9ac2dd099e625562e492021d7dd614f65f8a22d"}, + {file = "svgwrite-1.4.3.zip", hash = "sha256:a8fbdfd4443302a6619a7f76bc937fc683daf2628d9b737c891ec08b8ce524c3"}, +] [[package]] name = "swagger-spec-validator" -version = "2.7.4" +version = "3.0.3" description = "Validation of Swagger specifications" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" +files = [ + {file = "swagger-spec-validator-3.0.3.tar.gz", hash = "sha256:16a5ce08c772824a77b1a4a05efc047d72eef1ed53fb969dfe0a18f437ac30a8"}, + {file = "swagger_spec_validator-3.0.3-py2.py3-none-any.whl", hash = "sha256:174b5de4ab0899df9a57d35c880aaa515511c4b8b578d9d519b09a9596537055"}, +] [package.dependencies] jsonschema = "*" pyyaml = "*" -six = "*" +typing-extensions = "*" [[package]] name = "text-unidecode" @@ -1649,6 +2812,10 @@ description = "The most basic Text::Unidecode port" category = "main" optional = false python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] [[package]] name = "tomli" @@ -1657,6 +2824,10 @@ description = "A lil' TOML parser" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] [[package]] name = "typed-ast" @@ -1665,14 +2836,44 @@ description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, +] [[package]] name = "typing-extensions" -version = "4.3.0" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, +] [[package]] name = "uritemplate" @@ -1681,18 +2882,26 @@ description = "Implementation of RFC 6570 URI Templates" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, + {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, +] [[package]] name = "urllib3" -version = "1.26.10" +version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, + {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, +] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] @@ -1702,30 +2911,119 @@ description = "Promises, promises, promises." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"}, + {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, +] [[package]] name = "wcwidth" -version = "0.2.5" +version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" category = "main" optional = false python-versions = "*" +files = [ + {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, + {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, +] [[package]] name = "wrapt" -version = "1.14.1" +version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "main" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, + {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, + {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, + {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, + {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, + {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, + {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, + {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, + {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, + {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, + {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, + {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, + {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, + {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, + {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, + {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, + {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, + {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, + {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, + {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, + {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, + {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, + {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, + {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, + {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, + {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, + {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, +] [[package]] name = "yamllint" -version = "1.27.1" +version = "1.29.0" description = "A linter for YAML files." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "yamllint-1.29.0-py3-none-any.whl", hash = "sha256:5153bf9f8205aa9dc6af6217e38bd4f5baf09d9a7c6f4ae1e23f90d9c00c49c5"}, + {file = "yamllint-1.29.0.tar.gz", hash = "sha256:66a755d5fbcbb8831f1a9568676329b5bac82c37995bcc9afd048b6459f9fa48"}, +] [package.dependencies] pathspec = ">=0.5.3" @@ -1734,1109 +3032,21 @@ setuptools = "*" [[package]] name = "zipp" -version = "3.8.1" +version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, + {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, +] [package.extras] -docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] -testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] -lock-version = "1.1" +lock-version = "2.0" python-versions = "^3.7" -content-hash = "398413b19078a713f4d39be5160e8076355abe07629182d8aa2f921d08de87d1" - -[metadata.files] -amqp = [ - {file = "amqp-5.1.1-py3-none-any.whl", hash = "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359"}, - {file = "amqp-5.1.1.tar.gz", hash = "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2"}, -] -aniso8601 = [ - {file = "aniso8601-7.0.0-py2.py3-none-any.whl", hash = "sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b"}, - {file = "aniso8601-7.0.0.tar.gz", hash = "sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e"}, -] -asgiref = [ - {file = "asgiref-3.5.2-py3-none-any.whl", hash = "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4"}, - {file = "asgiref-3.5.2.tar.gz", hash = "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"}, -] -astroid = [ - {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, - {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, -] -async-timeout = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, -] -attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, -] -bandit = [ - {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, - {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, -] -billiard = [ - {file = "billiard-3.6.4.0-py3-none-any.whl", hash = "sha256:87103ea78fa6ab4d5c751c4909bcff74617d985de7fa8b672cf8618afd5a875b"}, - {file = "billiard-3.6.4.0.tar.gz", hash = "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547"}, -] -black = [ - {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"}, - {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"}, - {file = "black-22.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e"}, - {file = "black-22.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def"}, - {file = "black-22.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"}, - {file = "black-22.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d"}, - {file = "black-22.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256"}, - {file = "black-22.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78"}, - {file = "black-22.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849"}, - {file = "black-22.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c"}, - {file = "black-22.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90"}, - {file = "black-22.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f"}, - {file = "black-22.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e"}, - {file = "black-22.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6"}, - {file = "black-22.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad"}, - {file = "black-22.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf"}, - {file = "black-22.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c"}, - {file = "black-22.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2"}, - {file = "black-22.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee"}, - {file = "black-22.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b"}, - {file = "black-22.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4"}, - {file = "black-22.6.0-py3-none-any.whl", hash = "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c"}, - {file = "black-22.6.0.tar.gz", hash = "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9"}, -] -cached-property = [ - {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, - {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, -] -celery = [ - {file = "celery-5.2.7-py3-none-any.whl", hash = "sha256:138420c020cd58d6707e6257b6beda91fd39af7afde5d36c6334d175302c0e14"}, - {file = "celery-5.2.7.tar.gz", hash = "sha256:fafbd82934d30f8a004f81e8f7a062e31413a23d444be8ee3326553915958c6d"}, -] -certifi = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, -] -cffi = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, - {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, -] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] -click-didyoumean = [ - {file = "click-didyoumean-0.3.0.tar.gz", hash = "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"}, - {file = "click_didyoumean-0.3.0-py3-none-any.whl", hash = "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667"}, -] -click-plugins = [ - {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, - {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, -] -click-repl = [ - {file = "click-repl-0.2.0.tar.gz", hash = "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8"}, - {file = "click_repl-0.2.0-py3-none-any.whl", hash = "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b"}, -] -colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, -] -coreapi = [ - {file = "coreapi-2.3.3-py2.py3-none-any.whl", hash = "sha256:bf39d118d6d3e171f10df9ede5666f63ad80bba9a29a8ec17726a66cf52ee6f3"}, - {file = "coreapi-2.3.3.tar.gz", hash = "sha256:46145fcc1f7017c076a2ef684969b641d18a2991051fddec9458ad3f78ffc1cb"}, -] -coreschema = [ - {file = "coreschema-0.0.4-py2-none-any.whl", hash = "sha256:5e6ef7bf38c1525d5e55a895934ab4273548629f16aed5c0a6caa74ebf45551f"}, - {file = "coreschema-0.0.4.tar.gz", hash = "sha256:9503506007d482ab0867ba14724b93c18a33b22b6d19fb419ef2d239dd4a1607"}, -] -coverage = [ - {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"}, - {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"}, - {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"}, - {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"}, - {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"}, - {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"}, - {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"}, - {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"}, - {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"}, - {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"}, - {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"}, - {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"}, - {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"}, - {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"}, - {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"}, - {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"}, - {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"}, - {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"}, - {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"}, - {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"}, - {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"}, - {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"}, - {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, - {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, -] -cryptography = [ - {file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884"}, - {file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6"}, - {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046"}, - {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5"}, - {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b"}, - {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8"}, - {file = "cryptography-37.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280"}, - {file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3"}, - {file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59"}, - {file = "cryptography-37.0.4-cp36-abi3-win32.whl", hash = "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157"}, - {file = "cryptography-37.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327"}, - {file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b"}, - {file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9"}, - {file = "cryptography-37.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67"}, - {file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d"}, - {file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282"}, - {file = "cryptography-37.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa"}, - {file = "cryptography-37.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441"}, - {file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596"}, - {file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a"}, - {file = "cryptography-37.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab"}, - {file = "cryptography-37.0.4.tar.gz", hash = "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82"}, -] -defusedxml = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] -deprecated = [ - {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, - {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, -] -dill = [ - {file = "dill-0.3.5.1-py2.py3-none-any.whl", hash = "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302"}, - {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"}, -] -django = [ - {file = "Django-3.2.14-py3-none-any.whl", hash = "sha256:a8681e098fa60f7c33a4b628d6fcd3fe983a0939ff1301ecacac21d0b38bad56"}, - {file = "Django-3.2.14.tar.gz", hash = "sha256:677182ba8b5b285a4e072f3ac17ceee6aff1b5ce77fd173cc5b6a2d3dc022fcf"}, -] -django-ajax-tables = [ - {file = "django_ajax_tables-1.1.1-py3-none-any.whl", hash = "sha256:62e0138949153c0a994eefbf469f5496b1ad98bc073e170bc021a1aada7a32d0"}, - {file = "django_ajax_tables-1.1.1.tar.gz", hash = "sha256:5a7e7bc7940aa6332a564916cde22010a858a3d29fc1090ce8061010ec76337c"}, -] -django-appconf = [ - {file = "django-appconf-1.0.5.tar.gz", hash = "sha256:be3db0be6c81fa84742000b89a81c016d70ae66a7ccb620cdef592b1f1a6aaa4"}, - {file = "django_appconf-1.0.5-py3-none-any.whl", hash = "sha256:ae9f864ee1958c815a965ed63b3fba4874eec13de10236ba063a788f9a17389d"}, -] -django-cacheops = [ - {file = "django-cacheops-6.0.tar.gz", hash = "sha256:78e161ebd96a32e28e19ec7da31f2afed9e62a79726b8b5f0ed12dd16c2e5841"}, - {file = "django_cacheops-6.0-py2.py3-none-any.whl", hash = "sha256:ee38b969c9fc68f7c88e769b6c811e19563cca1ae08210d9f553ff758b6c3e17"}, -] -django-celery-beat = [ - {file = "django-celery-beat-2.2.1.tar.gz", hash = "sha256:97ae5eb309541551bdb07bf60cc57cadacf42a74287560ced2d2c06298620234"}, - {file = "django_celery_beat-2.2.1-py2.py3-none-any.whl", hash = "sha256:ab43049634fd18dc037927d7c2c7d5f67f95283a20ebbda55f42f8606412e66c"}, -] -django-constance = [ - {file = "django-constance-2.8.0.tar.gz", hash = "sha256:0a492454acc78799ce7b9f7a28a00c53427d513f34f8bf6fdc90a46d8864b2af"}, - {file = "django_constance-2.8.0-py3-none-any.whl", hash = "sha256:60fec73e397d5f4f7440f611b18d3e7ce5342647f316fedc47b62e1411c849e7"}, -] -django-cors-headers = [ - {file = "django-cors-headers-3.10.1.tar.gz", hash = "sha256:b5a874b492bcad99f544bb76ef679472259eb41ee5644ca62d1a94ddb26b7f6e"}, - {file = "django_cors_headers-3.10.1-py3-none-any.whl", hash = "sha256:1390b5846e9835b0911e2574409788af87cd9154246aafbdc8ec546c93698fe6"}, -] -django-cryptography = [ - {file = "django-cryptography-1.0.tar.gz", hash = "sha256:13de5cf8f1250744c104b9e24774d03aa6d8488959dd40cdc016934043652445"}, - {file = "django_cryptography-1.0-py3-none-any.whl", hash = "sha256:0a99980b1cee7cc5e52f9b20b322620fea7cc124d770273e7bd285b20fd9d222"}, -] -django-db-file-storage = [ - {file = "django-db-file-storage-0.5.5.tar.gz", hash = "sha256:5d5da694b78ab202accab4508b958e0e37b3d146310e76f6f6125e1bdeaaad14"}, -] -django-debug-toolbar = [ - {file = "django-debug-toolbar-3.5.0.tar.gz", hash = "sha256:97965f2630692de316ea0c1ca5bfa81660d7ba13146dbc6be2059cf55b35d0e5"}, - {file = "django_debug_toolbar-3.5.0-py3-none-any.whl", hash = "sha256:89a52128309eb4da12738801ff0c202d2ff8730d1c3225fac6acf630c303e661"}, -] -django-extensions = [ - {file = "django-extensions-3.1.5.tar.gz", hash = "sha256:28e1e1bf49f0e00307ba574d645b0af3564c981a6dfc87209d48cb98f77d0b1a"}, - {file = "django_extensions-3.1.5-py3-none-any.whl", hash = "sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069"}, -] -django-filter = [ - {file = "django-filter-21.1.tar.gz", hash = "sha256:632a251fa8f1aadb4b8cceff932bb52fe2f826dd7dfe7f3eac40e5c463d6836e"}, - {file = "django_filter-21.1-py3-none-any.whl", hash = "sha256:f4a6737a30104c98d2e2a5fb93043f36dd7978e0c7ddc92f5998e85433ea5063"}, -] -django-health-check = [ - {file = "django-health-check-3.16.5.tar.gz", hash = "sha256:1edfd49293ccebbce29f9da609c407f307aee240ab799ab4201031341ae78c0f"}, - {file = "django_health_check-3.16.5-py2.py3-none-any.whl", hash = "sha256:8d66781a0ea82b1a8b44878187b38a27370e94f18287312e39be0593e72d8983"}, -] -django-jinja = [ - {file = "django-jinja-2.10.2.tar.gz", hash = "sha256:bfdfbb55c1f5a679d69ad575d550c4707d386634009152efe014089f3c4d1412"}, - {file = "django_jinja-2.10.2-py3-none-any.whl", hash = "sha256:dd003ec1c95c0989eb28a538831bced62b1b61da551cb44a5dfd708fcf75589f"}, -] -django-js-asset = [ - {file = "django_js_asset-2.0.0-py3-none-any.whl", hash = "sha256:86f9f300d682537ddaf0487dc2ab356581b8f50c069bdba91d334a46e449f923"}, - {file = "django_js_asset-2.0.0.tar.gz", hash = "sha256:adc1ee1efa853fad42054b540c02205344bb406c9bddf87c9e5377a41b7db90f"}, -] -django-mptt = [ - {file = "django-mptt-0.13.4.tar.gz", hash = "sha256:80c9fb34df7796a4e5af0cb6b8ade3697555b1aa438bd07a01f32b3ab5202b63"}, - {file = "django_mptt-0.13.4-py3-none-any.whl", hash = "sha256:75745b621ae31d97957ed924155a750dfa8cacd9543799ada2d713fd6bc3f5c7"}, -] -django-picklefield = [ - {file = "django-picklefield-3.1.tar.gz", hash = "sha256:c786cbeda78d6def2b43bff4840d19787809c8909f7ad683961703060398d356"}, - {file = "django_picklefield-3.1-py3-none-any.whl", hash = "sha256:d77c504df7311e8ec14e8b779f10ca6fec74de6c7f8e2c136e1ef60cf955125d"}, -] -django-prometheus = [ - {file = "django-prometheus-2.2.0.tar.gz", hash = "sha256:240378a1307c408bd5fc85614a3a57f1ce633d4a222c9e291e2bbf325173b801"}, - {file = "django_prometheus-2.2.0-py2.py3-none-any.whl", hash = "sha256:e6616770d8820b8834762764bf1b76ec08e1b98e72a6f359d488a2e15fe3537c"}, -] -django-redis = [ - {file = "django-redis-5.2.0.tar.gz", hash = "sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de"}, - {file = "django_redis-5.2.0-py3-none-any.whl", hash = "sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026"}, -] -django-rq = [ - {file = "django-rq-2.5.1.tar.gz", hash = "sha256:f08486602664d73a6e335872c868d79663e380247e6307496d01b8fa770fefd8"}, - {file = "django_rq-2.5.1-py2.py3-none-any.whl", hash = "sha256:7be1e10e7091555f9f36edf100b0dbb205ea2b98683d74443d2bdf3c6649a03f"}, -] -django-tables2 = [ - {file = "django-tables2-2.4.1.tar.gz", hash = "sha256:6c72dd208358539e789e4c0efd7d151e43283a4aa4093a35f44c43489e7ddeaa"}, - {file = "django_tables2-2.4.1-py2.py3-none-any.whl", hash = "sha256:50762bf3d7c61a4eb70e763c3e278650d7266bb78d0497fc8fafcf4e507c9a64"}, -] -django-taggit = [ - {file = "django-taggit-1.5.1.tar.gz", hash = "sha256:e5bb62891f458d55332e36a32e19c08d20142c43f74bc5656c803f8af25c084a"}, - {file = "django_taggit-1.5.1-py3-none-any.whl", hash = "sha256:dfe9e9c10b5929132041de0c00093ef0072c73c2a97d0f74a818ae50fa77149a"}, -] -django-timezone-field = [ - {file = "django-timezone-field-4.1.2.tar.gz", hash = "sha256:cffac62452d060e365938aa9c9f7b72d70d8b26b9c60243bce227b35abd1b9df"}, - {file = "django_timezone_field-4.1.2-py3-none-any.whl", hash = "sha256:897c06e40b619cf5731a30d6c156886a7c64cba3a90364832148da7ef32ccf36"}, -] -django-webserver = [ - {file = "django-webserver-1.2.0.tar.gz", hash = "sha256:c976979d15b5ff9a212f7904d3b779e22219aebb4857860fcaf20e4e40f1da40"}, - {file = "django_webserver-1.2.0-py2.py3-none-any.whl", hash = "sha256:09200631f266484b9e944e38e92681d6e9aa7d90d089a5c86d5fb08fddad84fe"}, -] -djangorestframework = [ - {file = "djangorestframework-3.13.1-py3-none-any.whl", hash = "sha256:24c4bf58ed7e85d1fe4ba250ab2da926d263cd57d64b03e8dcef0ac683f8b1aa"}, - {file = "djangorestframework-3.13.1.tar.gz", hash = "sha256:0c33407ce23acc68eca2a6e46424b008c9c02eceb8cf18581921d0092bc1f2ee"}, -] -drf-spectacular = [ - {file = "drf-spectacular-0.22.1.tar.gz", hash = "sha256:866e16ddaae167a1234c76cd8c351161373551db994ce9665b347b32d5daf38b"}, - {file = "drf_spectacular-0.22.1-py3-none-any.whl", hash = "sha256:17ac5e31e5d6150dd5fa10843b429202f4f38069202acc44394cc5a771de63d9"}, -] -drf-spectacular-sidecar = [ - {file = "drf-spectacular-sidecar-2022.7.1.tar.gz", hash = "sha256:2dd95042a515e860993bbf945a49b78c454b824507a370bd8ba43f2b51b76399"}, - {file = "drf_spectacular_sidecar-2022.7.1-py3-none-any.whl", hash = "sha256:f0c304a6f56c3064f697d6ab815f632e4c3c9d385e79c6a9e69d6d5aa210ab09"}, -] -drf-yasg = [ - {file = "drf-yasg-1.20.3.tar.gz", hash = "sha256:1c66929fba56724c477951ab07266e69bbd0cb280e84b675957df19e3b567958"}, - {file = "drf_yasg-1.20.3-py2.py3-none-any.whl", hash = "sha256:915a16dae564143ebcbc1787e4aaad38062ccd95d1e6f97c2d33086575335bb8"}, -] -flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, -] -funcy = [ - {file = "funcy-1.17-py2.py3-none-any.whl", hash = "sha256:ba7af5e58bfc69321aaf860a1547f18d35e145706b95d1b3c966abc4f0b60309"}, - {file = "funcy-1.17.tar.gz", hash = "sha256:40b9b9a88141ae6a174df1a95861f2b82f2fdc17669080788b73a3ed9370e968"}, -] -gitdb = [ - {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, - {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, -] -gitpython = [ - {file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"}, - {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"}, -] -graphene = [ - {file = "graphene-2.1.9-py2.py3-none-any.whl", hash = "sha256:3d446eb1237c551052bc31155cf1a3a607053e4f58c9172b83a1b597beaa0868"}, - {file = "graphene-2.1.9.tar.gz", hash = "sha256:b9f2850e064eebfee9a3ef4a1f8aa0742848d97652173ab44c82cc8a62b9ed93"}, -] -graphene-django = [ - {file = "graphene-django-2.15.0.tar.gz", hash = "sha256:b78c9b05bc899016b9cc5bf13faa1f37fe1faa8c5407552c6ddd1a28f46fc31a"}, - {file = "graphene_django-2.15.0-py2.py3-none-any.whl", hash = "sha256:02671d195f0c09c8649acff2a8f4ad4f297d0f7d98ea6e6cdf034b81bab92880"}, -] -graphene-django-optimizer = [ - {file = "graphene-django-optimizer-0.8.0.tar.gz", hash = "sha256:79269880d59d0a35d41751ddcb419220c4ad3871960416371119f447cb2e1a77"}, -] -graphql-core = [ - {file = "graphql-core-2.3.2.tar.gz", hash = "sha256:aac46a9ac524c9855910c14c48fc5d60474def7f99fd10245e76608eba7af746"}, - {file = "graphql_core-2.3.2-py2.py3-none-any.whl", hash = "sha256:44c9bac4514e5e30c5a595fac8e3c76c1975cae14db215e8174c7fe995825bad"}, -] -graphql-relay = [ - {file = "graphql-relay-2.0.1.tar.gz", hash = "sha256:870b6b5304123a38a0b215a79eace021acce5a466bf40cd39fa18cb8528afabb"}, - {file = "graphql_relay-2.0.1-py3-none-any.whl", hash = "sha256:ac514cb86db9a43014d7e73511d521137ac12cf0101b2eaa5f0a3da2e10d913d"}, -] -idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, -] -importlib-metadata = [ - {file = "importlib_metadata-4.4.0-py3-none-any.whl", hash = "sha256:960d52ba7c21377c990412aca380bf3642d734c2eaab78a2c39319f67c6a5786"}, - {file = "importlib_metadata-4.4.0.tar.gz", hash = "sha256:e592faad8de1bda9fe920cf41e15261e7131bcf266c30306eec00e8e225c1dd5"}, -] -importlib-resources = [ - {file = "importlib_resources-5.8.0-py3-none-any.whl", hash = "sha256:7952325ffd516c05a8ad0858c74dff2c3343f136fe66a6002b2623dd1d43f223"}, - {file = "importlib_resources-5.8.0.tar.gz", hash = "sha256:568c9f16cb204f9decc8d6d24a572eeea27dacbb4cee9e6b03a8025736769751"}, -] -inflection = [ - {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, - {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, -] -invoke = [ - {file = "invoke-1.7.1-py3-none-any.whl", hash = "sha256:2dc975b4f92be0c0a174ad2d063010c8a1fdb5e9389d69871001118b4fcac4fb"}, - {file = "invoke-1.7.1.tar.gz", hash = "sha256:7b6deaf585eee0a848205d0b8c0014b9bf6f287a8eb798818a642dff1df14b19"}, -] -isort = [ - {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, - {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, -] -itypes = [ - {file = "itypes-1.2.0-py2.py3-none-any.whl", hash = "sha256:03da6872ca89d29aef62773672b2d408f490f80db48b23079a4b194c86dd04c6"}, - {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, -] -jinja2 = [ - {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, - {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, -] -jsonschema = [ - {file = "jsonschema-4.4.0-py3-none-any.whl", hash = "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823"}, - {file = "jsonschema-4.4.0.tar.gz", hash = "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83"}, -] -kombu = [ - {file = "kombu-5.2.4-py3-none-any.whl", hash = "sha256:8b213b24293d3417bcf0d2f5537b7f756079e3ea232a8386dcc89a59fd2361a4"}, - {file = "kombu-5.2.4.tar.gz", hash = "sha256:37cee3ee725f94ea8bb173eaab7c1760203ea53bbebae226328600f9d2799610"}, -] -lazy-object-proxy = [ - {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, - {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, -] -markdown = [ - {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, - {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, -] -markupsafe = [ - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, - {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, -] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -nautobot = [ - {file = "nautobot-1.3.8-py3-none-any.whl", hash = "sha256:aab13bd51070cca315bfd4e0c7e907a1b37f782e1ef2739d3a48d5d3595d7f69"}, - {file = "nautobot-1.3.8.tar.gz", hash = "sha256:39b6f266e3bc59bee14a7e44875354ee9ea7a540b4c781bf29247e3b95c81874"}, -] -netaddr = [ - {file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"}, - {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, -] -netutils = [ - {file = "netutils-1.1.0-py3-none-any.whl", hash = "sha256:bcb4367689c773cd30bf898b15bed38f22dc8bd69e64f2272bb9dd4726bf41d4"}, - {file = "netutils-1.1.0.tar.gz", hash = "sha256:90ab637c60ae18c515191224c52a7b0a1eb6fdde2f8dd40dfac638f2dd06ef2c"}, -] -oauthlib = [ - {file = "oauthlib-3.2.1-py3-none-any.whl", hash = "sha256:88e912ca1ad915e1dcc1c06fc9259d19de8deacd6fd17cc2df266decc2e49066"}, - {file = "oauthlib-3.2.1.tar.gz", hash = "sha256:1565237372795bf6ee3e5aba5e2a85bd5a65d0e2aa5c628b9a97b7d7a0da3721"}, -] -packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, -] -pathspec = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, -] -pbr = [ - {file = "pbr-5.9.0-py2.py3-none-any.whl", hash = "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a"}, - {file = "pbr-5.9.0.tar.gz", hash = "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308"}, -] -pillow = [ - {file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"}, - {file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"}, - {file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"}, - {file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"}, - {file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"}, - {file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"}, - {file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"}, - {file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"}, - {file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"}, - {file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"}, - {file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"}, - {file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"}, - {file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"}, - {file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"}, -] -platformdirs = [ - {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, - {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, -] -prometheus-client = [ - {file = "prometheus_client-0.14.1-py3-none-any.whl", hash = "sha256:522fded625282822a89e2773452f42df14b5a8e84a86433e3f8a189c1d54dc01"}, - {file = "prometheus_client-0.14.1.tar.gz", hash = "sha256:5459c427624961076277fdc6dc50540e2bacb98eebde99886e59ec55ed92093a"}, -] -promise = [ - {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"}, -] -prompt-toolkit = [ - {file = "prompt_toolkit-3.0.30-py3-none-any.whl", hash = "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"}, - {file = "prompt_toolkit-3.0.30.tar.gz", hash = "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0"}, -] -psycopg2-binary = [ - {file = "psycopg2-binary-2.9.3.tar.gz", hash = "sha256:761df5313dc15da1502b21453642d7599d26be88bff659382f8f9747c7ebea4e"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:539b28661b71da7c0e428692438efbcd048ca21ea81af618d845e06ebfd29478"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f2534ab7dc7e776a263b463a16e189eb30e85ec9bbe1bff9e78dae802608932"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e82d38390a03da28c7985b394ec3f56873174e2c88130e6966cb1c946508e65"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57804fc02ca3ce0dbfbef35c4b3a4a774da66d66ea20f4bda601294ad2ea6092"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:083a55275f09a62b8ca4902dd11f4b33075b743cf0d360419e2051a8a5d5ff76"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:0a29729145aaaf1ad8bafe663131890e2111f13416b60e460dae0a96af5905c9"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a79d622f5206d695d7824cbf609a4f5b88ea6d6dab5f7c147fc6d333a8787e4"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:090f3348c0ab2cceb6dfbe6bf721ef61262ddf518cd6cc6ecc7d334996d64efa"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a9e1f75f96ea388fbcef36c70640c4efbe4650658f3d6a2967b4cc70e907352e"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c3ae8e75eb7160851e59adc77b3a19a976e50622e44fd4fd47b8b18208189d42"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-win32.whl", hash = "sha256:7b1e9b80afca7b7a386ef087db614faebbf8839b7f4db5eb107d0f1a53225029"}, - {file = "psycopg2_binary-2.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:8b344adbb9a862de0c635f4f0425b7958bf5a4b927c8594e6e8d261775796d53"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:e847774f8ffd5b398a75bc1c18fbb56564cda3d629fe68fd81971fece2d3c67e"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68641a34023d306be959101b345732360fc2ea4938982309b786f7be1b43a4a1"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3303f8807f342641851578ee7ed1f3efc9802d00a6f83c101d21c608cb864460"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:e3699852e22aa68c10de06524a3721ade969abf382da95884e6a10ff798f9281"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:526ea0378246d9b080148f2d6681229f4b5964543c170dd10bf4faaab6e0d27f"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b1c8068513f5b158cf7e29c43a77eb34b407db29aca749d3eb9293ee0d3103ca"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:15803fa813ea05bef089fa78835118b5434204f3a17cb9f1e5dbfd0b9deea5af"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:152f09f57417b831418304c7f30d727dc83a12761627bb826951692cc6491e57"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:404224e5fef3b193f892abdbf8961ce20e0b6642886cfe1fe1923f41aaa75c9d"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-win32.whl", hash = "sha256:1f6b813106a3abdf7b03640d36e24669234120c72e91d5cbaeb87c5f7c36c65b"}, - {file = "psycopg2_binary-2.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:2d872e3c9d5d075a2e104540965a1cf898b52274a5923936e5bfddb58c59c7c2"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:10bb90fb4d523a2aa67773d4ff2b833ec00857f5912bafcfd5f5414e45280fb1"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a52ecab70af13e899f7847b3e074eeb16ebac5615665db33bce8a1009cf33"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a29b3ca4ec9defec6d42bf5feb36bb5817ba3c0230dd83b4edf4bf02684cd0ae"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:12b11322ea00ad8db8c46f18b7dfc47ae215e4df55b46c67a94b4effbaec7094"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:53293533fcbb94c202b7c800a12c873cfe24599656b341f56e71dd2b557be063"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c381bda330ddf2fccbafab789d83ebc6c53db126e4383e73794c74eedce855ef"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d29409b625a143649d03d0fd7b57e4b92e0ecad9726ba682244b73be91d2fdb"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:183a517a3a63503f70f808b58bfbf962f23d73b6dccddae5aa56152ef2bcb232"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:15c4e4cfa45f5a60599d9cec5f46cd7b1b29d86a6390ec23e8eebaae84e64554"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-win32.whl", hash = "sha256:adf20d9a67e0b6393eac162eb81fb10bc9130a80540f4df7e7355c2dd4af9fba"}, - {file = "psycopg2_binary-2.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2f9ffd643bc7349eeb664eba8864d9e01f057880f510e4681ba40a6532f93c71"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:def68d7c21984b0f8218e8a15d514f714d96904265164f75f8d3a70f9c295667"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e6aa71ae45f952a2205377773e76f4e3f27951df38e69a4c95440c779e013560"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dffc08ca91c9ac09008870c9eb77b00a46b3378719584059c034b8945e26b272"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:280b0bb5cbfe8039205c7981cceb006156a675362a00fe29b16fbc264e242834"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:af9813db73395fb1fc211bac696faea4ca9ef53f32dc0cfa27e4e7cf766dcf24"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:63638d875be8c2784cfc952c9ac34e2b50e43f9f0a0660b65e2a87d656b3116c"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ffb7a888a047696e7f8240d649b43fb3644f14f0ee229077e7f6b9f9081635bd"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0c9d5450c566c80c396b7402895c4369a410cab5a82707b11aee1e624da7d004"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:d1c1b569ecafe3a69380a94e6ae09a4789bbb23666f3d3a08d06bbd2451f5ef1"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8fc53f9af09426a61db9ba357865c77f26076d48669f2e1bb24d85a22fb52307"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-win32.whl", hash = "sha256:6472a178e291b59e7f16ab49ec8b4f3bdada0a879c68d3817ff0963e722a82ce"}, - {file = "psycopg2_binary-2.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:35168209c9d51b145e459e05c31a9eaeffa9a6b0fd61689b48e07464ffd1a83e"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:47133f3f872faf28c1e87d4357220e809dfd3fa7c64295a4a148bcd1e6e34ec9"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b3a24a1982ae56461cc24f6680604fffa2c1b818e9dc55680da038792e004d18"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91920527dea30175cc02a1099f331aa8c1ba39bf8b7762b7b56cbf54bc5cce42"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887dd9aac71765ac0d0bac1d0d4b4f2c99d5f5c1382d8b770404f0f3d0ce8a39"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:1f14c8b0942714eb3c74e1e71700cbbcb415acbc311c730370e70c578a44a25c"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:7af0dd86ddb2f8af5da57a976d27cd2cd15510518d582b478fbb2292428710b4"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93cd1967a18aa0edd4b95b1dfd554cf15af657cb606280996d393dadc88c3c35"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bda845b664bb6c91446ca9609fc69f7db6c334ec5e4adc87571c34e4f47b7ddb"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:01310cf4cf26db9aea5158c217caa92d291f0500051a6469ac52166e1a16f5b7"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:99485cab9ba0fa9b84f1f9e1fef106f44a46ef6afdeec8885e0b88d0772b49e8"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-win32.whl", hash = "sha256:46f0e0a6b5fa5851bbd9ab1bc805eef362d3a230fbdfbc209f4a236d0a7a990d"}, - {file = "psycopg2_binary-2.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:accfe7e982411da3178ec690baaceaad3c278652998b2c45828aaac66cd8285f"}, -] -pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, -] -pycparser = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] -pycryptodome = [ - {file = "pycryptodome-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e468724173df02f9d83f3fea830bf0d04aa291b5add22b4a78e01c97aab04873"}, - {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fb7a6f222072412f320b9e48d3ce981920efbfce37b06d028ec9bd94093b37f"}, - {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4f1b594d0cf35bd12ec4244df1155a7f565bf6e6245976ac36174c1564688c90"}, - {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9ea70f6c3f6566159e3798e4593a4a8016994a0080ac29a45200615b45091a1b"}, - {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f7aad304575d075faf2806977b726b67da7ba294adc97d878f92a062e357a56a"}, - {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:702446a012fd9337b9327d168bb0c7dc714eb93ad361f6f61af9ca8305a301f1"}, - {file = "pycryptodome-3.13.0-cp27-cp27m-win32.whl", hash = "sha256:681ac47c538c64305d710eaed2bb49532f62b3f4c93aa7c423c520df981392e5"}, - {file = "pycryptodome-3.13.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7b3478a187d897f003b2aa1793bcc59463e8d57a42e2aafbcbbe9cd47ec46863"}, - {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:eec02d9199af4b1ccfe1f9c587691a07a1fa39d949d2c1dc69d079ab9af8212f"}, - {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9c8e0e6c5e982699801b20fa74f43c19aa080d2b53a39f3c132d35958e153bd4"}, - {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f5457e44d3f26d9946091e92b28f3e970a56538b96c87b4b155a84e32a40b7b5"}, - {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:88d6d54e83cf9bbd665ce1e7b9079983ee2d97a05f42e0569ff00a70f1dd8b1e"}, - {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:72de8c4d71e6b11d54528bb924447fa4fdabcbb3d76cc0e7f61d3b6075def6b3"}, - {file = "pycryptodome-3.13.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:008ef2c631f112cd5a58736e0b29f4a28b4bb853e68878689f8b476fd56e0691"}, - {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:51ebe9624ad0a0b4da1aaaa2d43aabadf8537737fd494cee0ffa37cd6326de02"}, - {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:deede160bdf87ddb71f0a1314ad5a267b1a960be314ea7dc6b7ad86da6da89a3"}, - {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:857c16bffd938254e3a834cd6b2a755ed24e1a953b1a86e33da136d3e4c16a6f"}, - {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:ca6db61335d07220de0b665bfee7b8e9615b2dfc67a54016db4826dac34c2dd2"}, - {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:073dedf0f9c490ae22ca081b86357646ac9b76f3e2bd89119d137fc697a9e3b6"}, - {file = "pycryptodome-3.13.0-cp35-abi3-win32.whl", hash = "sha256:e3affa03c49cce7b0a9501cc7f608d4f8e61fb2522b276d599ac049b5955576d"}, - {file = "pycryptodome-3.13.0-cp35-abi3-win_amd64.whl", hash = "sha256:e5d72be02b17e6bd7919555811264403468d1d052fa67c946e402257c3c29a27"}, - {file = "pycryptodome-3.13.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:0896d5d15ffe584d46cb9b69a75cf14a2bc8f6daf635b7bf16c1b041342a44b1"}, - {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:e420cdfca73f80fe15f79bb34756959945231a052440813e5fce531e6e96331a"}, - {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:720fafdf3e5c5de93039d8308f765cc60b8e9e7e852ad7135aa65dd89238191f"}, - {file = "pycryptodome-3.13.0-pp27-pypy_73-win32.whl", hash = "sha256:7a8b0e526ff239b4f4c61dd6898e2474d609843ffc437267f3a27ddff626e6f6"}, - {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d92a5eddffb0ad39f582f07c1de26e9daf6880e3e782a94bb7ebaf939567f8bf"}, - {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:cb9453c981554984c6f5c5ce7682d7286e65e2173d7416114c3593a977a01bf5"}, - {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:765b8b16bc1fd699e183dde642c7f2653b8f3c9c1a50051139908e9683f97732"}, - {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:b3af53dddf848afb38b3ac2bae7159ddad1feb9bac14aa3acec6ef1797b82f8d"}, - {file = "pycryptodome-3.13.0.tar.gz", hash = "sha256:95bacf9ff7d1b90bba537d3f5f6c834efe6bfbb1a0195cb3573f29e6716ef08d"}, -] -pydocstyle = [ - {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, - {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, -] -pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, -] -pyjwt = [ - {file = "PyJWT-2.4.0-py3-none-any.whl", hash = "sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf"}, - {file = "PyJWT-2.4.0.tar.gz", hash = "sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba"}, -] -pylint = [ - {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, - {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, -] -pylint-django = [ - {file = "pylint-django-2.5.3.tar.gz", hash = "sha256:0ac090d106c62fe33782a1d01bda1610b761bb1c9bf5035ced9d5f23a13d8591"}, - {file = "pylint_django-2.5.3-py3-none-any.whl", hash = "sha256:56b12b6adf56d548412445bd35483034394a1a94901c3f8571980a13882299d5"}, -] -pylint-plugin-utils = [ - {file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"}, - {file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"}, -] -pyparsing = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] -pyrsistent = [ - {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, - {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, - {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, - {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, -] -python-crontab = [ - {file = "python-crontab-2.6.0.tar.gz", hash = "sha256:1e35ed7a3cdc3100545b43e196d34754e6551e7f95e4caebbe0e1c0ca41c2f1b"}, -] -python-dateutil = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] -python3-openid = [ - {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"}, - {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"}, -] -pytz = [ - {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, - {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, -] -pyuwsgi = [ - {file = "pyuwsgi-2.0.20-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd09a7328558728f6e38f77609f44d16f18d8b4dc5f8b8776f657c8892b70337"}, - {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:210ad768b8af02bbfd3c0345a51c6d2c56a2333ac268d9a97ecf2d4209f78ef8"}, - {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e33111308a79dbd202094963fd3a537dab30854e375d9be018f642fcd359e03d"}, - {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0306c3ca6f781ed7409774e44a2a90217824d3efb44e075a1f39a78a54ffe7d"}, - {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3eeea48fd965b68801618fc20eda2cb65dc2aeb4121955c9c422685f046311da"}, - {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dd048b85abb90c79a34afbf787995ab2933cb2a8b210a6e064e5fca0a9bdf2d8"}, - {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f612a72437c2934e39393fb575fab791e919efc102a0aa1a27b5d9a301d462e9"}, - {file = "pyuwsgi-2.0.20-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:78ac2d8b7d307232f8276cb8a45300211b0fae179c0494f2a3e3178c70693f81"}, - {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f84fc44bba77d05fa9d01189028501ff8e6a2d63db184ceea42085ce28196317"}, - {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:342c312949c2f494f5d9ac272965715483cb22ed0353c18abb1b4590769ef00f"}, - {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5740b84a016a246c69edef0df11912560df9a45c2adf6e47701329a974e37a71"}, - {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:82058f6b6656f12dbc66c963be2d7c0b977f481ddca5d4d3918e26def003b60d"}, - {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:dc99724df6d5613300d3357c4017cde840830ca132fe98f0a4feab9a6af48622"}, - {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:70096084ccfa18f058dfb3380aa10e80d48958ddfdb888b827f06aacb72f80b8"}, - {file = "pyuwsgi-2.0.20-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e7a8576452635612c82f660e5be99ba42cdcdff142948f5c263b5278f2c17b0"}, - {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2844205e0095a29d3a6e9e23bd37bcf18d65e4e5ab23a14a45f5159c03a3b890"}, - {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e2c0d5dafb9faacc8ed5b662f9eacb22e723fbc3cb7152b2ebf09a92b8bd6c0d"}, - {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087397457837c5fd653eda91c5d2c7948e06da589c786d26145bdcc397656bb2"}, - {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:da24ddb7e3522d36b4cdc2dbf131141d559084862f515d37f9a4b7b5c8b538b1"}, - {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:99b0c5a87aa95dcbaca2ccb599d783f37461600e098881d4ec9796ba68e3ff8f"}, - {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:df08a05dda4a92da46bd56af755dac091b145815c3cf6dda1855e01e40d12a99"}, - {file = "pyuwsgi-2.0.20-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c8ac4b2f411d15222f53a96627b8fa79056b39606925f429f59a51668bd95ab"}, - {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f1494d00df440865b1ee269a350187766c9c364ba5f124eddb064f366c4b6d8a"}, - {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5ee8782932dbacdb4dd98714c3575cbbb88ba87d7bcb3149c828725ba048897"}, - {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cdc4b32234b40fa2d515108a2f56a159896134ef16394f26dba764635142976"}, - {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:300417d6669171a454da19991fc7f910b3975232dac5b2dbc359e26f1038624b"}, - {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:015a8d310503eb8c0028ac8f98c7df3b49bc937c7db137aaf149ca7fae64c777"}, - {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9fc3d256270adf24b87f1dff893f3bc59bd5ee20c4ebb5add25e944c36359e1e"}, - {file = "pyuwsgi-2.0.20-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:052fe12d6a9ab9e9fc7814e40d2d28061aaea1a610069008d773e1d8a71feb11"}, - {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7d160c7bfa8f2974fc6b807a8fc080be0d130b1a4ad0b463c0320e707e6a6eb6"}, - {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7691ca470e541133c444b23f83c6f07ecca12f4771a49e0e3a04b05f4c80f2d3"}, - {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c87fb1d56dd2c6f18b87b08496be326afb6cf57c6a059261b01ce99046d9147"}, - {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8eb97cf51f58df05ec0dd74d83510172a2f5bcd8adc91382e24690a2abddc2f3"}, - {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a8fc4d52232f55df16e9cbf6faf4bf16910d15042229d5f8c717278fd4ea37a5"}, - {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1acedb1841aa0e60e1a7245ae483a5fcb30e39cf0cdfe3987e14de4746daf75b"}, - {file = "pyuwsgi-2.0.20.tar.gz", hash = "sha256:8b0936a964511fa0e2ac2847c2435e95130e7c98619f06fe1f67320527576043"}, -] -pyyaml = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, -] -redis = [ - {file = "redis-4.3.4-py3-none-any.whl", hash = "sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54"}, - {file = "redis-4.3.4.tar.gz", hash = "sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880"}, -] -requests = [ - {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, - {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, -] -requests-oauthlib = [ - {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, - {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, -] -rq = [ - {file = "rq-1.10.1-py2.py3-none-any.whl", hash = "sha256:92f4cf38b2364c1697b541e77c0fe62b7e5242fa864324f262be126ee2a07e3a"}, - {file = "rq-1.10.1.tar.gz", hash = "sha256:62d06b44c3acfa5d1933c5a4ec3fbc2484144a8af60e318d0b8447c5236271e2"}, -] -"ruamel.yaml" = [ - {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, - {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, -] -"ruamel.yaml.clib" = [ - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:066f886bc90cc2ce44df8b5f7acfc6a7e2b2e672713f027136464492b0c34d7c"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d3c620a54748a3d4cf0bcfe623e388407c8e85a4b06b8188e126302bcab93ea8"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:210c8fcfeff90514b7133010bf14e3bad652c8efde6b20e00c43854bf94fa5a6"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:61bc5e5ca632d95925907c569daa559ea194a4d16084ba86084be98ab1cec1c6"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1b4139a6ffbca8ef60fdaf9b33dec05143ba746a6f0ae0f9d11d38239211d335"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"}, - {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"}, -] -rx = [ - {file = "Rx-1.6.1-py2.py3-none-any.whl", hash = "sha256:7357592bc7e881a95e0c2013b73326f704953301ab551fbc8133a6fadab84105"}, - {file = "Rx-1.6.1.tar.gz", hash = "sha256:13a1d8d9e252625c173dc795471e614eadfe1cf40ffc684e08b8fff0d9748c23"}, -] -setuptools = [ - {file = "setuptools-65.3.0-py3-none-any.whl", hash = "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82"}, - {file = "setuptools-65.3.0.tar.gz", hash = "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57"}, -] -singledispatch = [ - {file = "singledispatch-3.7.0-py2.py3-none-any.whl", hash = "sha256:bc77afa97c8a22596d6d4fc20f1b7bdd2b86edc2a65a4262bdd7cc3cc19aa989"}, - {file = "singledispatch-3.7.0.tar.gz", hash = "sha256:c1a4d5c1da310c3fd8fccfb8d4e1cb7df076148fd5d858a819e37fffe44f3092"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -smmap = [ - {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, - {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, -] -snowballstemmer = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] -social-auth-app-django = [ - {file = "social-auth-app-django-5.0.0.tar.gz", hash = "sha256:b6e3132ce087cdd6e1707aeb1b588be41d318408fcf6395435da0bc6fe9a9795"}, - {file = "social_auth_app_django-5.0.0-py3-none-any.whl", hash = "sha256:52241a25445a010ab1c108bafff21fc5522d5c8cd0d48a92c39c7371824b065d"}, -] -social-auth-core = [ - {file = "social-auth-core-4.3.0.tar.gz", hash = "sha256:4686f0e43cf12954216875a32e944847bb1dc69e7cd9573d16a9003bb05ca477"}, - {file = "social_auth_core-4.3.0-py3-none-any.whl", hash = "sha256:1e3440d104f743b02dfe258c9d4dba5b4065abf24b2f7eb362b47054d21797df"}, -] -sqlparse = [ - {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, - {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, -] -stevedore = [ - {file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"}, - {file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"}, -] -svgwrite = [ - {file = "svgwrite-1.4.3-py3-none-any.whl", hash = "sha256:bb6b2b5450f1edbfa597d924f9ac2dd099e625562e492021d7dd614f65f8a22d"}, - {file = "svgwrite-1.4.3.zip", hash = "sha256:a8fbdfd4443302a6619a7f76bc937fc683daf2628d9b737c891ec08b8ce524c3"}, -] -swagger-spec-validator = [ - {file = "swagger-spec-validator-2.7.4.tar.gz", hash = "sha256:2aee5e1fc0503be9f8299378b10c92169572781573c6de3315e831fd0559ba73"}, - {file = "swagger_spec_validator-2.7.4-py2.py3-none-any.whl", hash = "sha256:4e373a4db5262e7257fde17d84c5c0178327b8057985ab1be63f580bfa009855"}, -] -text-unidecode = [ - {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, - {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, -] -tomli = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] -typed-ast = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, -] -typing-extensions = [ - {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"}, - {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"}, -] -uritemplate = [ - {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, - {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, -] -urllib3 = [ - {file = "urllib3-1.26.10-py2.py3-none-any.whl", hash = "sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec"}, - {file = "urllib3-1.26.10.tar.gz", hash = "sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6"}, -] -vine = [ - {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"}, - {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, -] -wcwidth = [ - {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, - {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, -] -wrapt = [ - {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, - {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, - {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, - {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, - {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, - {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, - {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, - {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, - {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, - {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, - {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, - {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, - {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, - {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, - {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, - {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, - {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, - {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, - {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, - {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, - {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, - {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, -] -yamllint = [ - {file = "yamllint-1.27.1.tar.gz", hash = "sha256:e688324b58560ab68a1a3cff2c0a474e3fed371dfe8da5d1b9817b7df55039ce"}, -] -zipp = [ - {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"}, - {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"}, -] +content-hash = "6736f30292f44183c14ea7af7ade951638adf2550534f07ea96472dd0c8084bf" diff --git a/pyproject.toml b/pyproject.toml index 63b6a68c..6c4a8fb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ packages = [ [tool.poetry.dependencies] python = "^3.7" -nautobot = "^1.3" +nautobot = "^1.5.4" [tool.poetry.dev-dependencies] invoke = "*" @@ -31,7 +31,9 @@ bandit = "*" pylint = "^2" pylint-django = "*" pydocstyle = "*" -flake8 = "*" +# we need to pin flake8 because of package dependencies that cause it to downgrade and +# therefore cause issues with linting since older versions do not take .flake8 as config +flake8 = "^3.9.2" coverage = "^5.5" [tool.black] diff --git a/tasks.py b/tasks.py index ee9a6884..d8fe30c5 100644 --- a/tasks.py +++ b/tasks.py @@ -38,12 +38,18 @@ def is_truthy(arg): namespace.configure( { "nautobot_bgp_models": { - "nautobot_ver": "1.3.8", + "nautobot_ver": "1.5.4", "project_name": "nautobot-bgp-models", "python_ver": "3.8", "local": False, "compose_dir": os.path.join(os.path.dirname(__file__), "development"), - "compose_files": ["docker-compose.requirements.yml", "docker-compose.base.yml", "docker-compose.dev.yml"], + "compose_files": [ + "docker-compose.base.yml", + "docker-compose.redis.yml", + "docker-compose.postgres.yml", + "docker-compose.dev.yml", + ], + "compose_http_timeout": "86400", } } ) @@ -77,15 +83,32 @@ def docker_compose(context, command, **kwargs): **kwargs: Passed through to the context.run() call. """ build_env = { + # Note: 'docker-compose logs' will stop following after 60 seconds by default, + # so we are overriding that by setting this environment variable. + "COMPOSE_HTTP_TIMEOUT": context.nautobot_bgp_models.compose_http_timeout, "NAUTOBOT_VER": context.nautobot_bgp_models.nautobot_ver, "PYTHON_VER": context.nautobot_bgp_models.python_ver, } - compose_command = f'docker-compose --project-name {context.nautobot_bgp_models.project_name} --project-directory "{context.nautobot_bgp_models.compose_dir}"' + compose_command_tokens = [ + "docker-compose", + f"--project-name {context.nautobot_bgp_models.project_name}", + f'--project-directory "{context.nautobot_bgp_models.compose_dir}"', + ] + for compose_file in context.nautobot_bgp_models.compose_files: compose_file_path = os.path.join(context.nautobot_bgp_models.compose_dir, compose_file) - compose_command += f' -f "{compose_file_path}"' - compose_command += f" {command}" + compose_command_tokens.append(f' -f "{compose_file_path}"') + + compose_command_tokens.append(command) + + # If `service` was passed as a kwarg, add it to the end. + service = kwargs.pop("service", None) + if service is not None: + compose_command_tokens.append(service) + print(f'Running docker-compose command "{command}"') + compose_command = " ".join(compose_command_tokens) + return context.run(compose_command, env=build_env, **kwargs) @@ -94,7 +117,7 @@ def run_command(context, command, **kwargs): if is_truthy(context.nautobot_bgp_models.local): context.run(command, **kwargs) else: - # Check if netbox is running, no need to start another netbox container to run a command + # Check if nautobot is running, no need to start another nautobot container to run a command docker_compose_status = "ps --services --filter status=running" results = docker_compose(context, docker_compose_status, hide="out") if "nautobot" in results.stdout: @@ -169,7 +192,6 @@ def stop(context): def destroy(context): """Destroy all containers and volumes.""" print("Destroying Nautobot...") - context.run("docker network prune --force") docker_compose(context, "down --volumes") @@ -181,6 +203,26 @@ def vscode(context): context.run(command) +@task( + help={ + "service": "Docker-compose service name to view (default: nautobot)", + "follow": "Follow logs", + "tail": "Tail N number of lines or 'all'", + } +) +def logs(context, service="nautobot", follow=False, tail=None): + """View the logs of a docker-compose service.""" + command = "logs " + + if follow: + command += "--follow " + if tail: + command += f"--tail={tail} " + + command += service + docker_compose(context, command) + + # ------------------------------------------------------------------------------ # ACTIONS # ------------------------------------------------------------------------------ @@ -191,6 +233,13 @@ def nbshell(context): run_command(context, command) +@task +def shell_plus(context): + """Launch an interactive shell_plus session.""" + command = "nautobot-server shell_plus" + run_command(context, command) + + @task def cli(context): """Launch a bash shell inside the running Nautobot container.""" @@ -216,7 +265,7 @@ def createsuperuser(context, user="admin"): ) def makemigrations(context, name=""): """Perform makemigrations operation in Django.""" - command = "nautobot-server makemigrations nautobot_bgp_models" + command = "nautobot-server makemigrations nautobot_bgp_plugin" if name: command += f" --name {name}" @@ -251,6 +300,21 @@ def post_upgrade(context): run_command(context, command) +# ------------------------------------------------------------------------------ +# DOCS +# ------------------------------------------------------------------------------ +@task +def docs(context): + """Build and serve docs locally for development.""" + command = "mkdocs serve -v" + + if is_truthy(context.nautobot_bgp_models.local): + print(">>> Serving Documentation at http://localhost:8001") + run_command(context, command) + else: + start(context, servics="docs") + + # ------------------------------------------------------------------------------ # TESTS # ------------------------------------------------------------------------------ @@ -274,7 +338,7 @@ def black(context, autoformat=False): @task def flake8(context): """Check for PEP8 compliance and other style issues.""" - command = "flake8 ." + command = "flake8 . --config .flake8" run_command(context, command) @@ -296,7 +360,7 @@ def pylint(context): def pydocstyle(context): """Run pydocstyle to validate docstring formatting adheres to NTC defined standards.""" # We exclude the /migrations/ directory since it is autogenerated code - command = "pydocstyle --config=.pydocstyle.ini ." + command = "pydocstyle ." run_command(context, command) @@ -307,6 +371,17 @@ def bandit(context): run_command(context, command) +@task +def yamllint(context): + """Run yamllint to validate formating adheres to NTC defined YAML standards. + + Args: + context (obj): Used to run specific commands + """ + command = "yamllint . --format standard" + run_command(context, command) + + @task def check_migrations(context): """Check for missing migrations.""" @@ -344,25 +419,6 @@ def unittest_coverage(context): run_command(context, command) -@task -def check_docs(context): - """Build and test docs.""" - command = "mkdocs build --no-directory-urls --strict" - - run_command(context, command) - - -@task -def yamllint(context): - """Run yamllint to validate formating adheres to NTC defined YAML standards. - - Args: - context (obj): Used to run specific commands - """ - command = "yamllint . --format standard" - run_command(context, command) - - @task( help={ "failfast": "fail as soon as a single test fails don't run the entire test suite", @@ -379,16 +435,14 @@ def tests(context, failfast=False): black(context) print("Running flake8...") flake8(context) - print("Running yamllint...") - yamllint(context) print("Running bandit...") bandit(context) print("Running pydocstyle...") pydocstyle(context) + print("Running yamllint...") + yamllint(context) print("Running pylint...") pylint(context) - print("Running mkdocs...") - check_docs(context) print("Running unit tests...") unittest(context, failfast=failfast) print("All tests have passed!") From 378d0a62481719643baa540bdb1d749a0eb76da0 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 16 Mar 2023 17:44:49 +0100 Subject: [PATCH 14/61] Fixing for black and flake8 compliance --- nautobot_bgp_models/api/serializers.py | 18 +++++++++--------- nautobot_bgp_models/dolt_compat.py | 1 - nautobot_bgp_models/migrations/0001_initial.py | 1 - 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/nautobot_bgp_models/api/serializers.py b/nautobot_bgp_models/api/serializers.py index b9e37f3a..6920d74c 100644 --- a/nautobot_bgp_models/api/serializers.py +++ b/nautobot_bgp_models/api/serializers.py @@ -73,7 +73,7 @@ class PeerGroupTemplateSerializer(CustomFieldModelSerializer, ExtraAttributesSer url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peergrouptemplate-detail") - autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) + autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 secret = NestedSecretSerializer(required=False, allow_null=True) class Meta: @@ -99,11 +99,11 @@ class PeerGroupSerializer(InheritableFieldsSerializerMixin, CustomFieldModelSeri source_ip = NestedIPAddressSerializer(required=False, allow_null=True) # noqa: F405 source_interface = NestedInterfaceSerializer(required=False, allow_null=True) # noqa: F405 - routing_instance = NestedRoutingInstanceSerializer(required=True) + routing_instance = NestedRoutingInstanceSerializer(required=True) # noqa: F405 - autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) + autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 - template = NestedPeerGroupTemplateSerializer(required=False, allow_null=True) + template = NestedPeerGroupTemplateSerializer(required=False, allow_null=True) # noqa: F405 secret = NestedSecretSerializer(required=False, allow_null=True) @@ -141,9 +141,9 @@ class PeerEndpointSerializer( source_interface = NestedInterfaceSerializer(required=False, allow_null=True) # noqa: F405 peer = NestedPeerEndpointSerializer(required=False, allow_null=True) # noqa: F405 peering = NestedPeeringSerializer(required=True, allow_null=True) # noqa: F405 - peer_group = NestedPeerGroupSerializer(required=False, allow_null=True) - routing_instance = NestedRoutingInstanceSerializer(required=False, allow_null=True) - autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) + peer_group = NestedPeerGroupSerializer(required=False, allow_null=True) # noqa: F405 + routing_instance = NestedRoutingInstanceSerializer(required=False, allow_null=True) # noqa: F405 + autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 secret = NestedSecretSerializer(required=False, allow_null=True) class Meta: @@ -196,7 +196,7 @@ class BGPRoutingInstanceSerializer(CustomFieldModelSerializer, ExtraAttributesSe device = NestedDeviceSerializer() - autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) + autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 router_id = NestedIPAddressSerializer(required=False, allow_null=True) # noqa: F405 @@ -235,7 +235,7 @@ class AddressFamilySerializer(CustomFieldModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:addressfamily-detail") - routing_instance = NestedRoutingInstanceSerializer(required=True) + routing_instance = NestedRoutingInstanceSerializer(required=True) # noqa: F405 vrf = NestedVRFSerializer(required=False, allow_null=True) diff --git a/nautobot_bgp_models/dolt_compat.py b/nautobot_bgp_models/dolt_compat.py index 5eee3144..6d9a7466 100644 --- a/nautobot_bgp_models/dolt_compat.py +++ b/nautobot_bgp_models/dolt_compat.py @@ -12,7 +12,6 @@ # Only do this if Dolt is available (aka "version control"). if DOLT_AVAILABLE: - # Tables used to display diffs dolt.register_diff_tables( { diff --git a/nautobot_bgp_models/migrations/0001_initial.py b/nautobot_bgp_models/migrations/0001_initial.py index b964045f..14f577c6 100644 --- a/nautobot_bgp_models/migrations/0001_initial.py +++ b/nautobot_bgp_models/migrations/0001_initial.py @@ -13,7 +13,6 @@ class Migration(migrations.Migration): - initial = True dependencies = [ From 429233b1948348aa85ff599ea1c5193746f731d7 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 09:28:09 +0000 Subject: [PATCH 15/61] chore: Ignore static files in git --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index cbb9133b..36a369bd 100644 --- a/.gitignore +++ b/.gitignore @@ -306,3 +306,5 @@ invoke.yml docs/README.md docs/CHANGELOG.md public + +nautobot_bgp_models/static From c4b6513908aff66175bd4ba7e8ef125ab1b67978 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 09:28:25 +0000 Subject: [PATCH 16/61] fix: Set minimal Nautobot version to 1.5.4 --- README.md | 2 +- development/Dockerfile | 4 ++-- docs/index.md | 2 +- nautobot_bgp_models/__init__.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6e959a9d..4f3ca7bd 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ The plugin is available as a Python package in PyPI and can be installed with `p pip install nautobot-bgp-models ``` -> The plugin is compatible with Nautobot 1.3 and higher +> The plugin is compatible with Nautobot 1.5.4 and higher To ensure Nautobot BGP Models Plugin is automatically re-installed during future upgrades, create a file named `local_requirements.txt` (if not already existing) in the Nautobot root directory (alongside `requirements.txt`) and list the `nautobot-bgp-models` package: diff --git a/development/Dockerfile b/development/Dockerfile index 2a3015ff..ad2357c4 100644 --- a/development/Dockerfile +++ b/development/Dockerfile @@ -6,8 +6,8 @@ # ------------------------------------------------------------------------------------- # !!! USE CAUTION WHEN MODIFYING LINES BELOW -# Accepts a desired Nautobot version as build argument, default to 1.5 -ARG NAUTOBOT_VER="1.4" +# Accepts a desired Nautobot version as build argument, default to 1.5.4 +ARG NAUTOBOT_VER="1.5.4" # Accepts a desired Python version as build argument, default to 3.8 ARG PYTHON_VER="3.8" diff --git a/docs/index.md b/docs/index.md index ebb646d1..0cc3c833 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ The plugin is available as a Python package in PyPI and can be installed with `p pip install nautobot-bgp-models ``` -> The plugin is compatible with Nautobot 1.3 and higher +> The plugin is compatible with Nautobot 1.5.4 and higher To ensure Nautobot BGP Models Plugin is automatically re-installed during future upgrades, create a file named `local_requirements.txt` (if not already existing) in the Nautobot root directory (alongside `requirements.txt`) and list the `nautobot-bgp-models` package: diff --git a/nautobot_bgp_models/__init__.py b/nautobot_bgp_models/__init__.py index 9491bf2b..3d2efeba 100644 --- a/nautobot_bgp_models/__init__.py +++ b/nautobot_bgp_models/__init__.py @@ -23,7 +23,7 @@ class NautobotBGPModelsConfig(PluginConfig): description = "Nautobot BGP Models Plugin." base_url = "bgp" required_settings = [] - min_version = "1.3.0" + min_version = "1.5.4" max_version = "1.999" default_settings = { "default_statuses": { From 518c5b09ecd3c0dd7439f81f09c317bd7218815a Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 09:36:44 +0000 Subject: [PATCH 17/61] fix: Skip tests on disabled routes --- nautobot_bgp_models/tests/test_views.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/nautobot_bgp_models/tests/test_views.py b/nautobot_bgp_models/tests/test_views.py index afdc9947..e36715be 100644 --- a/nautobot_bgp_models/tests/test_views.py +++ b/nautobot_bgp_models/tests/test_views.py @@ -9,6 +9,7 @@ from nautobot_bgp_models import models from nautobot_bgp_models.choices import AFISAFIChoices +from unittest import skip class AutonomousSystemTestCase(ViewTestCases.PrimaryObjectViewTestCase): @@ -20,6 +21,14 @@ class AutonomousSystemTestCase(ViewTestCases.PrimaryObjectViewTestCase): test_bulk_import_objects_with_permission = None test_bulk_import_objects_with_constrained_permission = None + @skip("Route disabled in commit `c97f037f`") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + + @skip("Route disabled in commit `c97f037f`") + def test_get_object_notes(self): + pass + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name @@ -71,6 +80,14 @@ class PeeringRoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTe test_bulk_import_objects_with_permission = None test_bulk_import_objects_with_constrained_permission = None + @skip("Route disabled in commit `c97f037f`") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + + @skip("Route disabled in commit `c97f037f`") + def test_get_object_notes(self): + pass + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name From d947c0c2a22791025e787dbee6d9047624b0a78e Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 09:40:04 +0000 Subject: [PATCH 18/61] fix: Align CI with the template --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85971992..0fa7bbf1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,7 +119,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10"] db-backend: ["postgresql"] nautobot-version: ["stable"] include: From a904285cc49cdd7173fa8882508370696ef22ce3 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 10:04:33 +0000 Subject: [PATCH 19/61] fix: pylint invalid import --- nautobot_bgp_models/tests/test_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nautobot_bgp_models/tests/test_views.py b/nautobot_bgp_models/tests/test_views.py index e36715be..872f29a8 100644 --- a/nautobot_bgp_models/tests/test_views.py +++ b/nautobot_bgp_models/tests/test_views.py @@ -1,5 +1,6 @@ """Unit test automation for Model classes in nautobot_bgp_models.""" +from unittest import skip from django.contrib.contenttypes.models import ContentType from nautobot.circuits.models import Provider from nautobot.dcim.models import Device, DeviceRole, DeviceType, Interface, Manufacturer, Site @@ -9,7 +10,6 @@ from nautobot_bgp_models import models from nautobot_bgp_models.choices import AFISAFIChoices -from unittest import skip class AutonomousSystemTestCase(ViewTestCases.PrimaryObjectViewTestCase): From 4c1ab9a01480148ffdc7e67893d87d0ed6e4f0d5 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 10:05:01 +0000 Subject: [PATCH 20/61] fix: `TESTING` used before defined --- development/nautobot_config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/development/nautobot_config.py b/development/nautobot_config.py index 63caf628..77bb815e 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -48,6 +48,8 @@ DEBUG = True +TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" + # Django Debug Toolbar DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG and not TESTING} @@ -62,8 +64,6 @@ LOG_LEVEL = "DEBUG" if DEBUG else "INFO" -TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" - # Verbose logging during normal development operation, but quiet logging during unit test execution if not TESTING: LOGGING = { @@ -137,7 +137,7 @@ # Plugins configuration settings. These settings are used by various plugins that the user may have installed. # Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings. # PLUGINS_CONFIG = { -# '{{cookiecutter.plugin_name}}': { +# 'nautobot_bgp_models': { # 'foo': 'bar', # 'buzz': 'bazz' # } From fa2de0c49db4d32721ea604ef0e9de311dc0ffd6 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 10:06:06 +0000 Subject: [PATCH 21/61] chore: Align tasks with the template --- tasks.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasks.py b/tasks.py index d8fe30c5..b13586d4 100644 --- a/tasks.py +++ b/tasks.py @@ -39,7 +39,7 @@ def is_truthy(arg): { "nautobot_bgp_models": { "nautobot_ver": "1.5.4", - "project_name": "nautobot-bgp-models", + "project_name": "nautobot_bgp_models", "python_ver": "3.8", "local": False, "compose_dir": os.path.join(os.path.dirname(__file__), "development"), @@ -167,11 +167,11 @@ def debug(context): docker_compose(context, "up") -@task -def start(context): +@task(help={"service": "If specified, only affect this service."}) +def start(context, service=None): """Start Nautobot and its dependencies in detached mode.""" print("Starting Nautobot in detached mode...") - docker_compose(context, "up --detach") + docker_compose(context, "up --detach", service=service) @task @@ -265,7 +265,7 @@ def createsuperuser(context, user="admin"): ) def makemigrations(context, name=""): """Perform makemigrations operation in Django.""" - command = "nautobot-server makemigrations nautobot_bgp_plugin" + command = "nautobot-server makemigrations nautobot_bgp_models" if name: command += f" --name {name}" From e089cc294d8d2cb7bc772abbce9da060ecf2da58 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 10:06:25 +0000 Subject: [PATCH 22/61] chore: Temporary enable upstream tests on push --- .github/workflows/upstream_testing.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/upstream_testing.yml b/.github/workflows/upstream_testing.yml index 3731c556..ded61ef7 100644 --- a/.github/workflows/upstream_testing.yml +++ b/.github/workflows/upstream_testing.yml @@ -4,6 +4,7 @@ name: "Nautobot Upstream Monitor" on: # yamllint disable-line rule:truthy rule:comments schedule: - cron: "0 4 */2 * *" # every other day at midnight + push: {} # to trigger upstream tests during PR development, will be removed jobs: upstream-test: From fc4db5308735ac6cb7e01adb307ebe4f0df9f682 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 10:45:39 +0000 Subject: [PATCH 23/61] fix: Skip not implemented `test_notes` --- nautobot_bgp_models/tests/test_api.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/nautobot_bgp_models/tests/test_api.py b/nautobot_bgp_models/tests/test_api.py index d416ce20..b20e6441 100644 --- a/nautobot_bgp_models/tests/test_api.py +++ b/nautobot_bgp_models/tests/test_api.py @@ -1,4 +1,5 @@ """Unit tests for nautobot_bgp_models.""" +from unittest import skip from django.contrib.contenttypes.models import ContentType from nautobot.circuits.models import Provider @@ -48,6 +49,10 @@ def setUpTestData(cls): {"asn": 4294967294, "status": "active", "description": "Reserved for private use"}, ] + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + class PeeringRoleAPITestCase(APIViewTestCases.APIViewTestCase): """Test the PeeringRole API.""" @@ -70,6 +75,10 @@ def setUpTestData(cls): models.PeeringRole.objects.create(name="Beta", slug="beta", color="00ff00") models.PeeringRole.objects.create(name="Gamma", slug="gamma", color="0000ff") + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + class PeerGroupAPITestCase(APIViewTestCases.APIViewTestCase): """Test the PeerGroup API.""" @@ -153,6 +162,10 @@ def setUpTestData(cls): cls.maxDiff = None + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + # @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) # def test_get_object_include_inherited(self): # """Test object retrieval with the `include_inherited` flag.""" @@ -339,6 +352,10 @@ def setUpTestData(cls): cls.maxDiff = None + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + # @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) # def test_get_object_include_inherited(self): @@ -481,6 +498,10 @@ def setUpTestData(cls): "status": "provisioning", } + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + class AddressFamilyAPITestCase(APIViewTestCases.APIViewTestCase): """Test the AddressFamily API.""" @@ -594,6 +615,10 @@ def setUpTestData(cls): # pylint: disable=too-many-locals "export_policy": "EXPORT_V4", } + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + # @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) # def test_get_object_include_inherited(self): From 4f2781faeb9a45f034789be4bd5d24ef2a9f5a98 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 10:46:27 +0000 Subject: [PATCH 24/61] fix: Missing `relationships` in API responses --- nautobot_bgp_models/api/serializers.py | 41 +++++++++++++++++++------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/nautobot_bgp_models/api/serializers.py b/nautobot_bgp_models/api/serializers.py index 6920d74c..0205b133 100644 --- a/nautobot_bgp_models/api/serializers.py +++ b/nautobot_bgp_models/api/serializers.py @@ -4,8 +4,13 @@ from nautobot.dcim.api.serializers import NestedDeviceSerializer, NestedInterfaceSerializer from nautobot.ipam.api.serializers import NestedVRFSerializer, NestedIPAddressSerializer -from nautobot.extras.api.customfields import CustomFieldModelSerializer -from nautobot.extras.api.serializers import TaggedObjectSerializer, StatusModelSerializerMixin, NestedSecretSerializer +from nautobot.apps.api import ( + CustomFieldModelSerializerMixin, + RelationshipModelSerializerMixin, + StatusModelSerializerMixin, + TaggedModelSerializerMixin, +) +from nautobot.extras.api.serializers import NestedSecretSerializer from nautobot.core.settings_funcs import is_truthy from nautobot.circuits.api.serializers import NestedProviderSerializer @@ -16,7 +21,12 @@ from .nested_serializers import * # noqa:F401,F403 pylint: disable=wildcard-import,unused-wildcard-import -class AutonomousSystemSerializer(TaggedObjectSerializer, StatusModelSerializerMixin, CustomFieldModelSerializer): +class AutonomousSystemSerializer( + TaggedModelSerializerMixin, + StatusModelSerializerMixin, + CustomFieldModelSerializerMixin, + RelationshipModelSerializerMixin, +): """REST API serializer for AutonomousSystem records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:autonomoussystem-detail") @@ -27,7 +37,7 @@ class Meta: fields = ["id", "url", "asn", "description", "status", "provider", "tags"] -class PeeringRoleSerializer(CustomFieldModelSerializer): +class PeeringRoleSerializer(CustomFieldModelSerializerMixin, RelationshipModelSerializerMixin): """REST API serializer for PeeringRole records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peeringrole-detail") @@ -68,7 +78,7 @@ def get_extra_attributes(self, instance): return instance.extra_attributes -class PeerGroupTemplateSerializer(CustomFieldModelSerializer, ExtraAttributesSerializerMixin): +class PeerGroupTemplateSerializer(CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin): """REST API serializer for PeerGroup records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peergrouptemplate-detail") @@ -92,7 +102,12 @@ class Meta: ] -class PeerGroupSerializer(InheritableFieldsSerializerMixin, CustomFieldModelSerializer, ExtraAttributesSerializerMixin): +class PeerGroupSerializer( + InheritableFieldsSerializerMixin, + CustomFieldModelSerializerMixin, + ExtraAttributesSerializerMixin, + RelationshipModelSerializerMixin, +): """REST API serializer for PeerGroup records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peergroup-detail") @@ -130,9 +145,10 @@ class Meta: class PeerEndpointSerializer( InheritableFieldsSerializerMixin, - TaggedObjectSerializer, - CustomFieldModelSerializer, + TaggedModelSerializerMixin, + CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin, + RelationshipModelSerializerMixin, ): """REST API serializer for PeerEndpoint records.""" @@ -185,7 +201,7 @@ def update(self, instance, validated_data): return result -class BGPRoutingInstanceSerializer(CustomFieldModelSerializer, ExtraAttributesSerializerMixin): +class BGPRoutingInstanceSerializer(CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin): """REST API serializer for Peering records.""" url = serializers.HyperlinkedIdentityField( @@ -213,7 +229,7 @@ class Meta: ] -class PeeringSerializer(CustomFieldModelSerializer, StatusModelSerializerMixin): +class PeeringSerializer(CustomFieldModelSerializerMixin, StatusModelSerializerMixin, RelationshipModelSerializerMixin): """REST API serializer for Peering records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peering-detail") @@ -230,7 +246,10 @@ class Meta: ] -class AddressFamilySerializer(CustomFieldModelSerializer): +class AddressFamilySerializer( + CustomFieldModelSerializerMixin, + RelationshipModelSerializerMixin, +): """REST API serializer for AddressFamily records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:addressfamily-detail") From 9758fd29804572545cb4c5e06e13548ba06b1bd1 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 12:03:03 +0000 Subject: [PATCH 25/61] fix: Skip list view tests for Nautobot < 1.5.12 --- nautobot_bgp_models/tests/test_views.py | 38 ++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/nautobot_bgp_models/tests/test_views.py b/nautobot_bgp_models/tests/test_views.py index 872f29a8..d834ccec 100644 --- a/nautobot_bgp_models/tests/test_views.py +++ b/nautobot_bgp_models/tests/test_views.py @@ -1,6 +1,8 @@ """Unit test automation for Model classes in nautobot_bgp_models.""" -from unittest import skip +from unittest import skip, skipIf +from packaging import version + from django.contrib.contenttypes.models import ContentType from nautobot.circuits.models import Provider from nautobot.dcim.models import Device, DeviceRole, DeviceType, Interface, Manufacturer, Site @@ -11,6 +13,16 @@ from nautobot_bgp_models import models from nautobot_bgp_models.choices import AFISAFIChoices +try: + from importlib import metadata +except ImportError: + # Running on pre-3.8 Python; use importlib-metadata package + import importlib_metadata as metadata + +_NAUTOBOT_VERSION = version.parse(metadata.version("nautobot")) +# Related to this issue: https://github.com/nautobot/nautobot/issues/2948 +_FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS = [version.parse("1.5.4"), version.parse("1.5.5")] + class AutonomousSystemTestCase(ViewTestCases.PrimaryObjectViewTestCase): """Test views related to the AutonomousSystem model.""" @@ -29,6 +41,10 @@ def test_bulk_import_objects_with_permission_csv_file(self): def test_get_object_notes(self): pass + @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") + def test_list_objects_with_permission(self): + super().test_list_objects_with_permission() + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name @@ -88,6 +104,10 @@ def test_bulk_import_objects_with_permission_csv_file(self): def test_get_object_notes(self): pass + @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") + def test_list_objects_with_permission(self): + super().test_list_objects_with_permission() + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name @@ -133,6 +153,10 @@ class PeerGroupTestCase( test_create_object_with_constrained_permission = None # TODO(mzb): FIXME + @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") + def test_list_objects_with_permission(self): + super().test_list_objects_with_permission() + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name @@ -184,6 +208,10 @@ class PeerEndpointTestCase( model = models.PeerEndpoint maxDiff = None + @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") + def test_list_objects_with_permission(self): + super().test_list_objects_with_permission() + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name @@ -271,6 +299,10 @@ class PeeringTestCase( model = models.Peering maxDiff = None + @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") + def test_list_objects_with_permission(self): + super().test_list_objects_with_permission() + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name @@ -326,6 +358,10 @@ class AddressFamilyTestCase( model = models.AddressFamily maxDiff = None + @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") + def test_list_objects_with_permission(self): + super().test_list_objects_with_permission() + def _get_base_url(self): return "plugins:{}:{}_{{}}".format( # pylint: disable=consider-using-f-string self.model._meta.app_label, self.model._meta.model_name From b03a41c74e205d1bab94208d6aced618890c2dc1 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Fri, 17 Mar 2023 13:42:36 +0000 Subject: [PATCH 26/61] chore: Do not trigger upstream tests on push --- .github/workflows/upstream_testing.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/upstream_testing.yml b/.github/workflows/upstream_testing.yml index ded61ef7..3731c556 100644 --- a/.github/workflows/upstream_testing.yml +++ b/.github/workflows/upstream_testing.yml @@ -4,7 +4,6 @@ name: "Nautobot Upstream Monitor" on: # yamllint disable-line rule:truthy rule:comments schedule: - cron: "0 4 */2 * *" # every other day at midnight - push: {} # to trigger upstream tests during PR development, will be removed jobs: upstream-test: From 5e32a0bcc5cd48f5654154266f98364a41d7fc77 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Tue, 21 Mar 2023 07:53:57 +0000 Subject: [PATCH 27/61] fix: Add mkdocs to invoke and ci --- .github/workflows/ci.yml | 8 ++++++++ tasks.py | 11 ++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fa7bbf1..6fa80010 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -184,6 +184,10 @@ jobs: run: "echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV" - name: "Run Poetry Version" run: "poetry version $RELEASE_VERSION" + - name: "Install Dependencies (needed for mkdocs)" + run: "poetry install" + - name: "Build Documentation" + run: "poetry run mkdocs build --no-directory-urls --strict" - name: "Run Poetry Build" run: "poetry build" - name: "Upload binaries to release" @@ -213,6 +217,10 @@ jobs: run: "echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV" - name: "Run Poetry Version" run: "poetry version $RELEASE_VERSION" + - name: "Install Dependencies (needed for mkdocs)" + run: "poetry install" + - name: "Build Documentation" + run: "poetry run mkdocs build --no-directory-urls --strict" - name: "Run Poetry Build" run: "poetry build" - name: "Push to PyPI" diff --git a/tasks.py b/tasks.py index b13586d4..6d06d39d 100644 --- a/tasks.py +++ b/tasks.py @@ -312,7 +312,7 @@ def docs(context): print(">>> Serving Documentation at http://localhost:8001") run_command(context, command) else: - start(context, servics="docs") + start(context, service="docs") # ------------------------------------------------------------------------------ @@ -390,6 +390,13 @@ def check_migrations(context): run_command(context, command) +@task +def build_and_check_docs(context): + """Build documentation to be available within Nautobot.""" + command = "mkdocs build --no-directory-urls --strict" + run_command(context, command) + + @task( help={ "keepdb": "save and re-use test database between test runs for faster re-testing.", @@ -443,6 +450,8 @@ def tests(context, failfast=False): yamllint(context) print("Running pylint...") pylint(context) + print("Running mkdocs...") + build_and_check_docs(context) print("Running unit tests...") unittest(context, failfast=failfast) print("All tests have passed!") From 815dae299eb218c573f26e59e8a1d20b4be25efb Mon Sep 17 00:00:00 2001 From: Cristian Sirbu Date: Tue, 13 Dec 2022 17:34:23 +0000 Subject: [PATCH 28/61] Existing docs migrated to new structure --- CHANGELOG.md | 1 - CONTRIBUTING.md | 12 - README.md | 100 ++-- docs/admin/compatibility_matrix.md | 6 + docs/admin/install.md | 79 +++ docs/admin/release_notes/index.md | 3 + docs/admin/release_notes/version_0.7.md | 13 + docs/admin/uninstall.md | 11 + docs/admin/upgrade.md | 7 + docs/assets/extra.css | 152 ++++++ docs/assets/favicon.ico | Bin 0 -> 15086 bytes docs/assets/nautobot_logo.png | Bin 0 -> 9204 bytes docs/assets/nautobot_logo.svg | 131 +++++ docs/assets/networktocode_bw.png | Bin 0 -> 7562 bytes docs/assets/overrides/partials/copyright.html | 22 + docs/dev/code_reference/api.md | 5 + docs/dev/code_reference/index.md | 3 + docs/dev/code_reference/package.md | 1 + docs/dev/contributing.md | 15 + docs/dev/dev_environment.md | 474 ++++++++++++++++++ docs/dev/extending.md | 3 + docs/{ => dev}/models.md | 15 +- docs/development.md | 120 ----- docs/example.md | 11 - docs/extra.css | 19 - .../add_asn_12345.png | Bin .../add_external_peering.png | Bin .../add_internal_peering.png | Bin docs/{images_manual => images}/add_new_ri.png | Bin .../external_peering_created.png | Bin docs/images/icon-nautobot-bgp-models.png | Bin 0 -> 74601 bytes .../internal_peering_created.png | Bin docs/{images_manual => images}/menu.png | Bin .../ri_list_view.png | Bin docs/index.md | 63 +-- docs/requirements.txt | 8 +- .../app_getting_started.md} | 59 ++- docs/user/app_overview.md | 59 +++ docs/user/app_use_cases.md | 41 ++ docs/{ => user}/cisco_use_case.md | 72 +-- FAQ.md => docs/user/faq.md | 0 docs/{ => user}/juniper_use_case.md | 6 +- mkdocs.yml | 118 ++++- nautobot_bgp_models/tests/test_basic.py | 33 ++ pyproject.toml | 9 + 45 files changed, 1303 insertions(+), 368 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 CONTRIBUTING.md create mode 100644 docs/admin/compatibility_matrix.md create mode 100644 docs/admin/install.md create mode 100644 docs/admin/release_notes/index.md create mode 100644 docs/admin/release_notes/version_0.7.md create mode 100644 docs/admin/uninstall.md create mode 100644 docs/admin/upgrade.md create mode 100644 docs/assets/extra.css create mode 100644 docs/assets/favicon.ico create mode 100644 docs/assets/nautobot_logo.png create mode 100644 docs/assets/nautobot_logo.svg create mode 100644 docs/assets/networktocode_bw.png create mode 100644 docs/assets/overrides/partials/copyright.html create mode 100644 docs/dev/code_reference/api.md create mode 100644 docs/dev/code_reference/index.md create mode 100644 docs/dev/code_reference/package.md create mode 100644 docs/dev/contributing.md create mode 100644 docs/dev/dev_environment.md create mode 100644 docs/dev/extending.md rename docs/{ => dev}/models.md (92%) delete mode 100644 docs/development.md delete mode 100644 docs/example.md delete mode 100644 docs/extra.css rename docs/{images_manual => images}/add_asn_12345.png (100%) rename docs/{images_manual => images}/add_external_peering.png (100%) rename docs/{images_manual => images}/add_internal_peering.png (100%) rename docs/{images_manual => images}/add_new_ri.png (100%) rename docs/{images_manual => images}/external_peering_created.png (100%) create mode 100644 docs/images/icon-nautobot-bgp-models.png rename docs/{images_manual => images}/internal_peering_created.png (100%) rename docs/{images_manual => images}/menu.png (100%) rename docs/{images_manual => images}/ri_list_view.png (100%) rename docs/{manual.md => user/app_getting_started.md} (57%) create mode 100644 docs/user/app_overview.md create mode 100644 docs/user/app_use_cases.md rename docs/{ => user}/cisco_use_case.md (87%) rename FAQ.md => docs/user/faq.md (100%) rename docs/{ => user}/juniper_use_case.md (99%) create mode 100644 nautobot_bgp_models/tests/test_basic.py diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 825c32f0..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# Changelog diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index f0cbd951..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,12 +0,0 @@ -# CONTRIBUTING - -To contribute, follow this workflow. - -1. Open an issue -2. Get approval from one of the codeowners before working on the issue -3. If working on the issue, assign the issue to yourself -4. Open a PR into develop -5. Get peer review and approval to merge from one of the codeowners -6. Once approval has been gained, merge the PR into develop -7. Once the PR is merged, delete the branch -8. One of the codeowners will enumerate the features added per the contributer's PR when a tagged release is merged into master \ No newline at end of file diff --git a/README.md b/README.md index 4f3ca7bd..5fa1b4cc 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,63 @@ -# Nautobot BGP Models Plugin +# BGP Models -A plugin for [Nautobot](https://github.com/nautobot/nautobot) extending the core models with BGP-specific models. +

+ +
+ + + + +
+ An App for Nautobot. +

-New models enable modeling and management of BGP peerings, whether or not the peer device is present in Nautobot. +## Overview -> The initial development of this plugin was sponsored by Riot Games, Inc. - -## Data Models - -Navigate to [Data Models](docs/cisco_use_case.md) for detailed descriptions on additional data models provided in the plugin. - -## Use Cases - -To make the start with the plugin easier, we provide two example use cases for common OS platforms: Cisco and Juniper. - -### Cisco Configuration Modeling and Rendering +An app for [Nautobot](https://github.com/nautobot/nautobot), extending the core models with BGP-specific models. They enable modeling and management of BGP peerings, whether or not the peer device is present in Nautobot. -Navigate to [Cisco Example Use Case](docs/cisco_use_case.md) for detailed instructions how to consume BGP Models plugin on Cisco devices. - -### Juniper Configuration Modeling and Rendering - -Navigate to [Juniper Example Use Case](docs/juniper_use_case.md) for detailed instructions how to consume BGP Models plugin on Juniper devices. - -## Installation - -The plugin is available as a Python package in PyPI and can be installed with `pip`: - -```shell -pip install nautobot-bgp-models -``` +> The initial development of this plugin was sponsored by Riot Games, Inc. -> The plugin is compatible with Nautobot 1.5.4 and higher +### Screenshots -To ensure Nautobot BGP Models Plugin is automatically re-installed during future upgrades, create a file named `local_requirements.txt` (if not already existing) in the Nautobot root directory (alongside `requirements.txt`) and list the `nautobot-bgp-models` package: +More screenshots can be found in the [Using the App](https://docs.nautobot.com/projects/bgp-models/en/latest/user/app_use_cases/) page in the documentation. Here's a quick overview of some of the plugin's added functionality: -```no-highlight -# echo nautobot-bgp-models >> local_requirements.txt -``` +![Menu](https://raw.githubusercontent.com/nautobot/nautobot-plugin-bgp-models/develop/docs/images/main-page-menu.png) -Once installed, the plugin needs to be enabled in your `nautobot_config.py` +![Autonomous System](https://raw.githubusercontent.com/nautobot/nautobot-plugin-bgp-models/develop/docs/images/autonomous_system_01.png) -```python -# In your configuration.py -PLUGINS = ["nautobot_bgp_models"] -``` +![Peering List](https://raw.githubusercontent.com/nautobot/nautobot-plugin-bgp-models/develop/docs/images/peering_list.png) -```python -PLUGINS_CONFIG = { - "nautobot_bgp_models": { - "default_statuses": { - "AutonomousSystem": ["active", "available", "planned"], - "Peering": ["active", "decommissioned", "deprovisioning", "offline", "planned", "provisioning"], - } - } -} -``` +![Peering](https://raw.githubusercontent.com/nautobot/nautobot-plugin-bgp-models/develop/docs/images/peering_01.png) -In the `default_statuses` section, you can define a list of default statuses to make available to `AutonomousSystem` and/or `Peering`. The lists must be composed of valid slugs of existing Status objects. +![Peer Endpoint](https://raw.githubusercontent.com/nautobot/nautobot-plugin-bgp-models/develop/docs/images/peer_endpoint_01.png) -## Screenshots +![Peer Group](https://raw.githubusercontent.com/nautobot/nautobot-plugin-bgp-models/develop/docs/images/peer_group_01.png) -![Menu](https://github.com/nautobot/nautobot-plugin-bgp-models/blob/main/docs/images/main-page-menu.png) -![Autonomous System](https://github.com/nautobot/nautobot-plugin-bgp-models/blob/main/docs/images/autonomous_system_01.png) +## Try it out! -![Peering List](https://github.com/nautobot/nautobot-plugin-bgp-models/blob/main/docs/images/peering_list.png) +This App is installed in the Nautobot Community Sandbox found over at [demo.nautobot.com](https://demo.nautobot.com/)! -![Peering](https://github.com/nautobot/nautobot-plugin-bgp-models/blob/main/docs/images/peering_01.png) +> For a full list of all the available always-on sandbox environments, head over to the main page on [networktocode.com](https://www.networktocode.com/nautobot/sandbox-environments/). -![Peer Endpoint](https://github.com/nautobot/nautobot-plugin-bgp-models/blob/main/docs/images/peer_endpoint_01.png) +## Documentation -![Peer Group](https://github.com/nautobot/nautobot-plugin-bgp-models/blob/main/docs/images/peer_group_01.png) +Full documentation for this App can be found over on the [Nautobot Docs](https://docs.nautobot.com) website: -## Contributing +- [User Guide](https://docs.nautobot.com/projects/bgp-models/en/latest/user/app_overview/) - Overview, Using the App, Getting Started. +- [Administrator Guide](https://docs.nautobot.com/projects/bgp-models/en/latest/admin/install/) - How to Install, Configure, Upgrade, or Uninstall the App. +- [Developer Guide](https://docs.nautobot.com/projects/bgp-models/en/latest/dev/contributing/) - Extending the App, Code Reference, Contribution Guide. +- [Release Notes / Changelog](https://docs.nautobot.com/projects/bgp-models/en/latest/admin/release_notes/). +- [Frequently Asked Questions](https://docs.nautobot.com/projects/bgp-models/en/latest/user/faq/). -Pull requests are welcomed and automatically built and tested against multiple version of Python and multiple version of Nautobot through TravisCI. +### Contributing to the Documentation -The project is packaged with a light development environment based on `docker-compose` to help with the local development of the project and to run the tests within TravisCI. +You can find all the Markdown source for the App documentation under the [`docs`](https://github.com/nautobot/nautobot-plugin-bgp-models/tree/develop/docs) folder in this repository. For simple edits, a Markdown capable editor is sufficient: clone the repository and edit away. -The project is following Network to Code software development guideline and is leveraging: +If you need to view the fully-generated documentation site, you can build it with [MkDocs](https://www.mkdocs.org/). A container hosting the documentation can be started using the `invoke` commands (details in the [Development Environment Guide](https://docs.nautobot.com/projects/bgp-models/en/latest/dev/dev_environment/#docker-development-environment)) on [http://localhost:8001](http://localhost:8001). Using this container, as your changes to the documentation are saved, they will be automatically rebuilt and any pages currently being viewed will be reloaded in your browser. -- Black, Pylint, Bandit and pydocstyle for Python linting and formatting. -- Django unit test to ensure the plugin is working properly. +Any PRs with fixes or improvements are very welcome! ## Questions -For any questions or comments, please check the [FAQ](FAQ.md) first and feel free to swing by the [Network to Code slack channel](https://networktocode.slack.com/) (channel #networktocode). -Sign up [here](http://slack.networktocode.com/) +For any questions or comments, please check the [FAQ](https://docs.nautobot.com/projects/bgp-models/en/latest/user/faq/) first. Feel free to also swing by the [Network to Code Slack](https://networktocode.slack.com/) (channel `#nautobot`), sign up [here](http://slack.networktocode.com/) if you don't have an account. diff --git a/docs/admin/compatibility_matrix.md b/docs/admin/compatibility_matrix.md new file mode 100644 index 00000000..20e44832 --- /dev/null +++ b/docs/admin/compatibility_matrix.md @@ -0,0 +1,6 @@ +# Compatibility Matrix + +| BGP Models Version | Nautobot First Support Version | Nautobot Last Support Version | +|--------------------|--------------------------------|-------------------------------| +| 0.7.X | 1.3.0 | 1.99.99 | +| 0.8.X | 1.5.4 | 1.99.99 | diff --git a/docs/admin/install.md b/docs/admin/install.md new file mode 100644 index 00000000..16edf3c8 --- /dev/null +++ b/docs/admin/install.md @@ -0,0 +1,79 @@ +# Installing the App in Nautobot + +Here you will find detailed instructions on how to **install** and **configure** the App within your Nautobot environment. + + +## Prerequisites + +- The plugin is compatible with Nautobot 1.3.0 and higher. +- Databases supported: PostgreSQL, MySQL + +!!! note + Please check the [dedicated page](compatibility_matrix.md) for a full compatibility matrix and the deprecation policy. + + +## Install Guide + +!!! note + Plugins can be installed manually or using Python's `pip`. See the [nautobot documentation](https://docs.nautobot.com/projects/core/en/stable/plugins/#install-the-package) for more details. The pip package name for this plugin is [`nautobot-bgp-models`](https://pypi.org/project/nautobot-bgp-models/). + +The plugin is available as a Python package via PyPI and can be installed with `pip`: + +```shell +pip install nautobot-bgp-models +``` + +To ensure BGP Models is automatically re-installed during future upgrades, create a file named `local_requirements.txt` (if not already existing) in the Nautobot root directory (alongside `requirements.txt`) and list the `nautobot-bgp-models` package: + +```shell +echo nautobot-bgp-models >> local_requirements.txt +``` + +Once installed, the plugin needs to be enabled in your Nautobot configuration. The following block of code below shows the additional configuration required to be added to your `nautobot_config.py` file: + +- Append `"nautobot_bgp_models"` to the `PLUGINS` list. +- Append the `"nautobot_bgp_models"` dictionary to the `PLUGINS_CONFIG` dictionary and override any defaults. + +```python +# In your nautobot_config.py +PLUGINS = ["nautobot_bgp_models"] + +# PLUGINS_CONFIG = { +# "nautobot_bgp_models": { +# ADD YOUR SETTINGS HERE +# } +# } +``` + +Once the Nautobot configuration is updated, run the Post Upgrade command (`nautobot-server post_upgrade`) to run migrations and clear any cache: + +```shell +nautobot-server post_upgrade +``` + +Then restart (if necessary) the Nautobot services which may include: + +- Nautobot +- Nautobot Workers +- Nautobot Scheduler + +```shell +sudo systemctl restart nautobot nautobot-worker nautobot-scheduler +``` + +## App Configuration + +An example configuration is provided below: + +```python +PLUGINS_CONFIG = { + "nautobot_bgp_models": { + "default_statuses": { + "AutonomousSystem": ["active", "available", "planned"], + "Peering": ["active", "decommissioned", "deprovisioning", "offline", "planned", "provisioning"], + } + } +} +``` + +In the `default_statuses` section, you can define a list of default statuses to make available to `AutonomousSystem` and/or `Peering`. The lists must be composed of valid slugs of existing Status objects. diff --git a/docs/admin/release_notes/index.md b/docs/admin/release_notes/index.md new file mode 100644 index 00000000..12cb5169 --- /dev/null +++ b/docs/admin/release_notes/index.md @@ -0,0 +1,3 @@ +# Release Notes + +All the published release notes can be found via the navigation menu. All patch releases are included in the same minor release (e.g. `v1.2`) document. diff --git a/docs/admin/release_notes/version_0.7.md b/docs/admin/release_notes/version_0.7.md new file mode 100644 index 00000000..256f6f78 --- /dev/null +++ b/docs/admin/release_notes/version_0.7.md @@ -0,0 +1,13 @@ +# v0.7 Release Notes + +## Release Overview + +- Initial BGP Models release + +## [v0.7.0-beta.1] - 2022-09-20 + +### Added + +### Changed + +### Fixed diff --git a/docs/admin/uninstall.md b/docs/admin/uninstall.md new file mode 100644 index 00000000..820ef0d0 --- /dev/null +++ b/docs/admin/uninstall.md @@ -0,0 +1,11 @@ +# Uninstall the App from Nautobot + +Here you will find any steps necessary to cleanly remove the App from your Nautobot environment. + +## Uninstall Guide + +Remove the configuration you added in `nautobot_config.py` from `PLUGINS` & `PLUGINS_CONFIG`. + +## Database Cleanup + +Drop all tables from the plugin: `nautobot_plugin_bgp_models*`. diff --git a/docs/admin/upgrade.md b/docs/admin/upgrade.md new file mode 100644 index 00000000..af9c40be --- /dev/null +++ b/docs/admin/upgrade.md @@ -0,0 +1,7 @@ +# Upgrading the App + +Here you will find any steps necessary to upgrade the App in your Nautobot environment. + +## Upgrade Guide + +When a new release comes out it may be necessary to run a migration of the database to account for any changes in the data models used by this plugin. Execute the command `nautobot-server post-upgrade` within the runtime environment of your Nautobot installation after updating the `nautobot-bgp-models` package via `pip`. diff --git a/docs/assets/extra.css b/docs/assets/extra.css new file mode 100644 index 00000000..a51ccd3e --- /dev/null +++ b/docs/assets/extra.css @@ -0,0 +1,152 @@ +:root>* { + --md-accent-fg-color: #ff8504; + --md-primary-fg-color: #ff8504; + --md-typeset-a-color: #0097ff; +} + +[data-md-color-scheme="slate"] { + --md-default-bg-color: hsla(var(--md-hue), 0%, 15%, 1); + --md-typeset-a-color: #0097ff; +} + +/* Accessibility: Increase fonts for dark theme */ +[data-md-color-scheme="slate"] .md-typeset { + font-size: 0.9rem; +} + +[data-md-color-scheme="slate"] .md-typeset table:not([class]) { + font-size: 0.7rem; +} + +.md-tabs__link { + font-size: 0.8rem; +} + +.md-tabs__link--active { + color: var(--md-primary-fg-color); +} + +.md-header__button.md-logo :is(img, svg) { + height: 2rem; +} + +.md-header__button.md-logo :-webkit-any(img, svg) { + height: 2rem; +} + +.md-header__title { + font-size: 1.2rem; +} + +img.logo { + height: 200px; +} + +img.copyright-logo { + height: 24px; + vertical-align: middle; +} + +[data-md-color-primary=black] .md-header { + background-color: #212121; +} + +@media screen and (min-width: 76.25em) { + [data-md-color-primary=black] .md-tabs { + background-color: #212121; + } +} + +/* Customization for mkdocstrings */ +/* Indentation. */ +div.doc-contents:not(.first) { + padding-left: 25px; + border-left: .2rem solid var(--md-typeset-table-color); +} + +/* Mark external links as such. */ +a.autorefs-external::after { + /* https://primer.style/octicons/arrow-up-right-24 */ + background-image: url('data:image/svg+xml,'); + content: ' '; + + display: inline-block; + position: relative; + top: 0.1em; + margin-left: 0.2em; + margin-right: 0.1em; + + height: 1em; + width: 1em; + border-radius: 100%; + background-color: var(--md-typeset-a-color); +} + +a.autorefs-external:hover::after { + background-color: var(--md-accent-fg-color); +} + + +/* Customization for mkdocs-version-annotations */ +:root { + /* Icon for "version-added" admonition: Material Design Icons "plus-box-outline" */ + --md-admonition-icon--version-added: url('data:image/svg+xml;charset=utf-8,'); + /* Icon for "version-changed" admonition: Material Design Icons "delta" */ + --md-admonition-icon--version-changed: url('data:image/svg+xml;charset=utf-8,'); + /* Icon for "version-removed" admonition: Material Design Icons "minus-circle-outline" */ + --md-admonition-icon--version-removed: url('data:image/svg+xml;charset=utf-8,'); +} + +/* "version-added" admonition in green */ +.md-typeset .admonition.version-added, +.md-typeset details.version-added { + border-color: rgb(0, 200, 83); +} + +.md-typeset .version-added>.admonition-title, +.md-typeset .version-added>summary { + background-color: rgba(0, 200, 83, .1); +} + +.md-typeset .version-added>.admonition-title::before, +.md-typeset .version-added>summary::before { + background-color: rgb(0, 200, 83); + -webkit-mask-image: var(--md-admonition-icon--version-added); + mask-image: var(--md-admonition-icon--version-added); +} + +/* "version-changed" admonition in orange */ +.md-typeset .admonition.version-changed, +.md-typeset details.version-changed { + border-color: rgb(255, 145, 0); +} + +.md-typeset .version-changed>.admonition-title, +.md-typeset .version-changed>summary { + background-color: rgba(255, 145, 0, .1); +} + +.md-typeset .version-changed>.admonition-title::before, +.md-typeset .version-changed>summary::before { + background-color: rgb(255, 145, 0); + -webkit-mask-image: var(--md-admonition-icon--version-changed); + mask-image: var(--md-admonition-icon--version-changed); +} + +/* "version-removed" admonition in red */ +.md-typeset .admonition.version-removed, +.md-typeset details.version-removed { + border-color: rgb(255, 82, 82); +} + +.md-typeset .version-removed>.admonition-title, +.md-typeset .version-removed>summary { + background-color: rgba(255, 82, 82, .1); +} + +.md-typeset .version-removed>.admonition-title::before, +.md-typeset .version-removed>summary::before { + background-color: rgb(255, 82, 82); + -webkit-mask-image: var(--md-admonition-icon--version-removed); + mask-image: var(--md-admonition-icon--version-removed); +} diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fcaa3d653334894025d867436969693afa2d7c51 GIT binary patch literal 15086 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 KMNUMnLSTZbe~(ZA literal 0 HcmV?d00001 diff --git a/docs/assets/nautobot_logo.svg b/docs/assets/nautobot_logo.svg new file mode 100644 index 00000000..c9bba8e9 --- /dev/null +++ b/docs/assets/nautobot_logo.svg @@ -0,0 +1,131 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/assets/networktocode_bw.png b/docs/assets/networktocode_bw.png new file mode 100644 index 0000000000000000000000000000000000000000..075c4926d570b9db02c8808f34f40c8eb5f18a90 GIT binary patch literal 7562 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 + {% if config.copyright %} + + Apache-2.0 LICENSE + {% endif %} + + + + + +
+ diff --git a/docs/dev/code_reference/api.md b/docs/dev/code_reference/api.md new file mode 100644 index 00000000..39c5b288 --- /dev/null +++ b/docs/dev/code_reference/api.md @@ -0,0 +1,5 @@ +# BGP Models API Package + +::: nautobot_bgp_models.api + options: + show_submodules: True diff --git a/docs/dev/code_reference/index.md b/docs/dev/code_reference/index.md new file mode 100644 index 00000000..473f2c40 --- /dev/null +++ b/docs/dev/code_reference/index.md @@ -0,0 +1,3 @@ +# Code Reference + +Auto-generated code reference documentation from docstrings. diff --git a/docs/dev/code_reference/package.md b/docs/dev/code_reference/package.md new file mode 100644 index 00000000..554438ed --- /dev/null +++ b/docs/dev/code_reference/package.md @@ -0,0 +1 @@ +::: nautobot_bgp_models diff --git a/docs/dev/contributing.md b/docs/dev/contributing.md new file mode 100644 index 00000000..483b2269 --- /dev/null +++ b/docs/dev/contributing.md @@ -0,0 +1,15 @@ +# Contributing to the App + +The project is packaged with a light [development environment](dev_environment.md) based on `docker-compose` to help with the local development of the project and to run tests. + +The project is following Network to Code software development guidelines and is leveraging the following: + +- Python linting and formatting: `black`, `pylint`, `bandit`, `flake8`, and `pydocstyle`. +- YAML linting is done with `yamllint`. +- Django unit test to ensure the plugin is working properly. + +Documentation is built using [mkdocs](https://www.mkdocs.org/). The [Docker based development environment](dev_environment.md#docker-development-environment) automatically starts a container hosting a live version of the documentation website on [http://localhost:8001](http://localhost:8001) that auto-refreshes when you make any changes to your local files. + +## Branching Policy + +## Release Policy diff --git a/docs/dev/dev_environment.md b/docs/dev/dev_environment.md new file mode 100644 index 00000000..eb60200c --- /dev/null +++ b/docs/dev/dev_environment.md @@ -0,0 +1,474 @@ +# Building Your Development Environment + +## Quickstart Guide + +The development environment can be used in two ways: + +1. **(Recommended)** All services, including Nautobot, are spun up using Docker containers and a volume mount so you can develop locally. +2. With a local Poetry environment if you wish to develop outside of Docker, with the caveat of using external services provided by Docker for the database (PostgreSQL by default, MySQL optionally) and Redis services. + +This is a quick reference guide if you're already familiar with the development environment provided, which you can read more about later in this document. + +### Invoke + +The [Invoke](http://www.pyinvoke.org/) library is used to provide some helper commands based on the environment. There are a few configuration parameters which can be passed to Invoke to override the default configuration: + +- `nautobot_ver`: the version of Nautobot to use as a base for any built docker containers (default: latest) +- `project_name`: the default docker compose project name (default: `nautobot_bgp_models`) +- `python_ver`: the version of Python to use as a base for any built docker containers (default: 3.8) +- `local`: a boolean flag indicating if invoke tasks should be run on the host or inside the docker containers (default: False, commands will be run in docker containers) +- `compose_dir`: the full path to a directory containing the project compose files +- `compose_files`: a list of compose files applied in order (see [Multiple Compose files](https://docs.docker.com/compose/extends/#multiple-compose-files) for more information) + +Using **Invoke** these configuration options can be overridden using [several methods](https://docs.pyinvoke.org/en/stable/concepts/configuration.html). Perhaps the simplest is setting an environment variable `INVOKE_NAUTOBOT_BGP_MODELS_VARIABLE_NAME` where `VARIABLE_NAME` is the variable you are trying to override. The only exception is `compose_files`, because it is a list it must be overridden in a YAML file. There is an example `invoke.yml` (`invoke.example.yml`) in this directory which can be used as a starting point. + +### Docker Development Environment + +!!! tip + This is the recommended option for development. + +This project is managed by [Python Poetry](https://python-poetry.org/) and has a few requirements to setup your development environment: + +1. Install Poetry, see the [Poetry Documentation](https://python-poetry.org/docs/#installation) for your operating system. +2. Install Docker, see the [Docker documentation](https://docs.docker.com/get-docker/) for your operating system. + +Once you have Poetry and Docker installed you can run the following commands (in the root of the repository) to install all other development dependencies in an isolated Python virtual environment: + +```shell +poetry shell +poetry install +cp development/creds.example.env development/creds.env +invoke build +invoke start +``` + +The Nautobot server can now be accessed at [http://localhost:8080](http://localhost:8080) and the live documentation at [http://localhost:8001](http://localhost:8001). + +To either stop or destroy the development environment use the following options. + +- **invoke stop** - Stop the containers, but keep all underlying systems intact +- **invoke destroy** - Stop and remove all containers, volumes, etc. (This results in data loss due to the volume being deleted) + +### Local Poetry Development Environment + +- Create an `invoke.yml` file with the following contents at the root of the repo and edit as necessary + +```yaml +--- +nautobot_bgp_models: + local: true + compose_files: + - "docker-compose.requirements.yml" +``` + +Run the following commands: + +```shell +poetry shell +poetry install --extras nautobot +export $(cat development/dev.env | xargs) +export $(cat development/creds.env | xargs) +invoke start && sleep 5 +nautobot-server migrate +``` + +!!! note + If you want to develop on the latest develop branch of Nautobot, run the following command: `poetry add --optional git+https://github.com/nautobot/nautobot@develop`. After the `@` symbol must match either a branch or a tag. + +You can now run `nautobot-server` commands as you would from the [Nautobot documentation](https://docs.nautobot.com/projects/core/en/stable/) for example to start the development server: + +```shell +nautobot-server runserver 0.0.0.0:8080 --insecure +``` + +Nautobot server can now be accessed at [http://localhost:8080](http://localhost:8080). + +It is typically recommended to launch the Nautobot **runserver** command in a separate shell so you can keep developing and manage the webserver separately. + +### Updating the Documentation + +Documentation dependencies are pinned to exact versions to ensure consistent results. For the development environment, they are defined in the `pyproject.toml` file. + +If you need to update any of the documentation dependencies to a newer version, make sure you copy the exact same versions pinned in `pyproject.toml` to the `docs/requirements.txt` file as well. The latter is used in the automated build pipeline on ReadTheDocs to build the live version of the documentation. + +### CLI Helper Commands + +The project features a CLI helper based on [Invoke](https://www.pyinvoke.org/) to help setup the development environment. The commands are listed below in 3 categories: + +- `dev environment` +- `utility` +- `testing` + +Each command can be executed with `invoke `. All commands support the arguments `--nautobot-ver` and `--python-ver` if you want to manually define the version of Python and Nautobot to use. Each command also has its own help `invoke --help` + +!!! note + To run the mysql (mariadb) development environment, set the environment variable as such `export NAUTOBOT_USE_MYSQL=1`. + +#### Local Development Environment + +``` + build Build all docker images. + debug Start Nautobot and its dependencies in debug mode. + destroy Destroy all containers and volumes. + restart Restart Nautobot and its dependencies in detached mode. + start Start Nautobot and its dependencies in detached mode. + stop Stop Nautobot and its dependencies. +``` + +#### Utility + +``` + cli Launch a bash shell inside the running Nautobot container. + create-user Create a new user in django (default: admin), will prompt for password. + makemigrations Run Make Migration in Django. + nbshell Launch a nbshell session. +``` + +#### Testing + +``` + bandit Run bandit to validate basic static code security analysis. + black Run black to check that Python files adhere to its style standards. + flake8 Run flake8 to check that Python files adhere to its style standards. + pydocstyle Run pydocstyle to validate docstring formatting adheres to NTC defined standards. + pylint Run pylint code analysis. + tests Run all tests for this plugin. + unittest Run Django unit tests for the plugin. +``` + + +## Project Overview + +This project provides the ability to develop and manage the Nautobot server locally (with supporting services being *Dockerized*) or by using only Docker containers to manage Nautobot. The main difference between the two environments is the ability to debug and use **pdb** when developing locally. Debugging with **pdb** within the Docker container is more complicated, but can still be accomplished by either entering into the container (via `docker exec`) or attaching your IDE to the container and running the Nautobot service manually within the container. + +The upside to having the Nautobot service handled by Docker rather than locally is that you do not have to manage the Nautobot server. The [Docker logs](#docker-logs) provide the majority of the information you will need to help troubleshoot, while getting started quickly and not requiring you to perform several manual steps and remembering to have the Nautobot server running in a separate terminal while you develop. + +!!! note + The local environment still uses Docker containers for the supporting services (Postgres, Redis, and RQ Worker), but the Nautobot server is handled locally by you, the developer. + +Follow the directions below for the specific development environment that you choose. + +## Poetry + +Poetry is used in lieu of the "virtualenv" commands and is leveraged in both environments. The virtual environment will provide all of the Python packages required to manage the development environment such as **Invoke**. See the [Local Development Environment](#local-poetry-development-environment) section to see how to install Nautobot if you're going to be developing locally (i.e. not using the Docker container). + +The `pyproject.toml` file outlines all of the relevant dependencies for the project: + +- `tool.poetry.dependencies` - the main list of dependencies. +- `tool.poetry.dev-dependencies` - development dependencies, to facilitate linting, testing, and documentation building. + +The `poetry shell` command is used to create and enable a virtual environment managed by Poetry, so all commands ran going forward are executed within the virtual environment. This is similar to running the `source venv/bin/activate` command with virtualenvs. To install project dependencies in the virtual environment, you should run `poetry install` - this will install **both** project and development dependencies. + +For more details about Poetry and its commands please check out its [online documentation](https://python-poetry.org/docs/). + +## Full Docker Development Environment + +This project is set up with a number of **Invoke** tasks consumed as simple CLI commands to get developing fast. You'll use a few `invoke` commands to get your environment up and running. + +### Copy the credentials file for Nautobot + +First, you need to create the `development/creds.env` file - it stores a bunch of private information such as passwords and tokens for your local Nautobot install. You can make a copy of the `development/creds.example.env` and modify it to suit you. + +```shell +cp development/creds.example.env development/creds.env +``` + +### Invoke - Building the Docker Image + +The first thing you need to do is build the necessary Docker image for Nautobot that installs the specific `nautobot_ver`. The image is used for Nautobot and the Celery worker service used by Docker Compose. + +```bash +➜ invoke build +... +#14 exporting to image +#14 sha256:e8c613e07b0b7ff33893b694f7759a10d42e180f2b4dc349fb57dc6b71dcab00 +#14 exporting layers +#14 exporting layers 1.2s done +#14 writing image sha256:2d524bc1665327faa0d34001b0a9d2ccf450612bf8feeb969312e96a2d3e3503 done +#14 naming to docker.io/nautobot-bgp-models/nautobot:latest-py3.7 done +``` + +### Invoke - Starting the Development Environment + +Next, you need to start up your Docker containers. + +```bash +➜ invoke start +Starting Nautobot in detached mode... +Running docker-compose command "up --detach" +Creating network "nautobot_bgp_models_default" with the default driver +Creating volume "nautobot_bgp_models_postgres_data" with default driver +Creating nautobot_bgp_models_redis_1 ... +Creating nautobot_bgp_models_docs_1 ... +Creating nautobot_bgp_models_postgres_1 ... +Creating nautobot_bgp_models_postgres_1 ... done +Creating nautobot_bgp_models_redis_1 ... done +Creating nautobot_bgp_models_nautobot_1 ... +Creating nautobot_bgp_models_docs_1 ... done +Creating nautobot_bgp_models_nautobot_1 ... done +Creating nautobot_bgp_models_worker_1 ... +Creating nautobot_bgp_models_worker_1 ... done +Docker Compose is now in the Docker CLI, try `docker compose up` +``` + +This will start all of the Docker containers used for hosting Nautobot. You should see the following containers running after `invoke start` is finished. + +```bash +➜ docker ps +****CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +ee90fbfabd77 nautobot-bgp-models/nautobot:latest-py3.7 "nautobot-server rqw…" 16 seconds ago Up 13 seconds nautobot_bgp_models_worker_1 +b8adb781d013 nautobot-bgp-models/nautobot:latest-py3.7 "/docker-entrypoint.…" 20 seconds ago Up 15 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp nautobot_bgp_models_nautobot_1 +d64ebd60675d nautobot-bgp-models/nautobot:latest-py3.7 "mkdocs serve -v -a …" 25 seconds ago Up 18 seconds 0.0.0.0:8001->8080/tcp, :::8001->8080/tcp nautobot_bgp_models_docs_1 +e72d63129b36 postgres:13-alpine "docker-entrypoint.s…" 25 seconds ago Up 19 seconds 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp nautobot_bgp_models_postgres_1 +96c6ff66997c redis:6-alpine "docker-entrypoint.s…" 25 seconds ago Up 21 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp nautobot_bgp_models_redis_1 +``` + +Once the containers are fully up, you should be able to open up a web browser, and view: + +- The Nautobot homepage at [http://localhost:8080](http://localhost:8080) +- A live version of the documentation at [http://localhost:8001](http://localhost:8001) + +!!! note + Sometimes the containers take a minute to fully spin up. If the page doesn't load right away, wait a minute and try again. + +### Invoke - Creating a Superuser + +The Nautobot development image will automatically provision a super user when specifying the following variables within `creds.env` which is the default when copying `creds.example.env` to `creds.env`. + +- `NAUTOBOT_CREATE_SUPERUSER=true` +- `NAUTOBOT_SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567` +- `NAUTOBOT_SUPERUSER_PASSWORD=admin` + +!!! note + The default username is **admin**, but can be overridden by specifying **NAUTOBOT_SUPERUSER_USERNAME**. + +If you need to create additional superusers, run the follow commands. + +```bash +➜ invoke createsuperuser +Running docker-compose command "ps --services --filter status=running" +Running docker-compose command "exec nautobot nautobot-server createsuperuser --username admin" +Error: That username is already taken. +Username: ntc +Email address: ntc@networktocode.com +Password: +Password (again): +Superuser created successfully. +``` + +### Invoke - Stopping the Development Environment + +The last command to know for now is `invoke stop`. + +```bash +➜ invoke stop +Stopping Nautobot... +Running docker-compose command "down" +Stopping nautobot_bgp_models_worker_1 ... +Stopping nautobot_bgp_models_nautobot_1 ... +Stopping nautobot_bgp_models_docs_1 ... +Stopping nautobot_bgp_models_redis_1 ... +Stopping nautobot_bgp_models_postgres_1 ... +Stopping nautobot_bgp_models_worker_1 ... done +Stopping nautobot_bgp_models_nautobot_1 ... done +Stopping nautobot_bgp_models_postgres_1 ... done +Stopping nautobot_bgp_models_redis_1 ... done +Stopping nautobot_bgp_models_docs_1 ... done +Removing nautobot_bgp_models_worker_1 ... +Removing nautobot_bgp_models_nautobot_1 ... +Removing nautobot_bgp_models_docs_1 ... +Removing nautobot_bgp_models_redis_1 ... +Removing nautobot_bgp_models_postgres_1 ... +Removing nautobot_bgp_models_postgres_1 ... done +Removing nautobot_bgp_models_docs_1 ... done +Removing nautobot_bgp_models_worker_1 ... done +Removing nautobot_bgp_models_redis_1 ... done +Removing nautobot_bgp_models_nautobot_1 ... done +Removing network nautobot_bgp_models_default +``` + +This will safely shut down all of your running Docker containers for this project. When you are ready to spin containers back up, it is as simple as running `invoke start` again [as seen previously](#invoke-starting-the-development-environment). + +!!! warning + If you're wanting to reset the database and configuration settings, you can use the `invoke destroy` command, but **you will lose any data stored in those containers**, so make sure that is what you want to do. + +### Real-Time Updates? How Cool! + +Your environment should now be fully setup, all necessary Docker containers are created and running, and you're logged into Nautobot in your web browser. Now what? + +Now you can start developing your plugin in the project folder! + +The magic here is the root directory is mounted inside your Docker containers when built and ran, so **any** changes made to the files in here are directly updated to the Nautobot plugin code running in Docker. This means that as you modify the code in your plugin folder, the changes will be instantly updated in Nautobot. + +!!! warning + There are a few exceptions to this, as outlined in the section [To Rebuild or Not To Rebuild](#to-rebuild-or-not-to-rebuild). + +The back-end Django process is setup to automatically reload itself (it only takes a couple of seconds) every time a file is updated (saved). So for example, if you were to update one of the files like `tables.py`, then save it, the changes will be visible right away in the web browser! + +!!! note + You may get connection refused while Django reloads, but it should be refreshed fairly quickly. + +### Docker Logs + +When trying to debug an issue, one helpful thing you can look at are the logs within the Docker containers. + +```bash +➜ docker logs -f +``` + +!!! note + The `-f` tag will keep the logs open, and output them in realtime as they are generated. + +So for example, our plugin is named `nautobot-bgp-models`, the command would most likely be `docker logs nautobot_bgp_models_nautobot_1 -f`. You can find the name of all running containers via `docker ps`. + +If you want to view the logs specific to the worker container, simply use the name of that container instead. + +## To Rebuild or Not to Rebuild + +Most of the time, you will not need to rebuild your images. Simply running `invoke start` and `invoke stop` is enough to keep your environment going. + +However there are a couple of instances when you will want to. + +### Updating Environment Variables + +To add environment variables to your containers, thus allowing Nautobot to use them, you will update/add them in the `development/development.env` file. However, doing so is considered updating the underlying container shell, instead of Django (which auto restarts itself on changes). + +To get new environment variables to take effect, you will need stop any running images, rebuild the images, then restart them. This can easily be done with 3 commands: + +```bash +➜ invoke stop +➜ invoke build +➜ invoke start +``` + +Once completed, the new/updated environment variables should now be live. + +### Installing Additional Python Packages + +If you want your plugin to leverage another available Nautobot plugin or another Python package, you can easily add them into your Docker environment. + +```bash +➜ poetry shell +➜ poetry add +``` + +Once the dependencies are resolved, stop the existing containers, rebuild the Docker image, and then start all containers again. + +```bash +➜ invoke stop +➜ invoke build +➜ invoke start +``` + +### Installing Additional Nautobot Plugins + +Let's say for example you want the new plugin you're creating to integrate into Slack. To do this, you will want to integrate into the existing Nautobot ChatOps Plugin. + +```bash +➜ poetry shell +➜ poetry add nautobot-chatops +``` + +Once you activate the virtual environment via Poetry, you then tell Poetry to install the new plugin. + +Before you continue, you'll need to update the file `development/nautobot_config.py` accordingly with the name of the new plugin under `PLUGINS` and any relevant settings as necessary for the plugin under `PLUGINS_CONFIG`. Since you're modifying the underlying OS (not just Django files), you need to rebuild the image. This is a similar process to updating environment variables, which was explained earlier. + +```bash +➜ invoke stop +➜ invoke build +➜ invoke start +``` + +Once the containers are up and running, you should now see the new plugin installed in your Nautobot instance. + +!!! note + You can even launch an `ngrok` service locally on your laptop, pointing to port 8080 (such as for chatops development), and it will point traffic directly to your Docker images. + +### Updating Python Version + +To update the Python version, you can update it within `tasks.py`. + +```python +namespace = Collection("nautobot_bgp_models") +namespace.configure( + { + "nautobot_bgp_models": { + ... + "python_ver": "3.7", + ... + } + } +) +``` + +Or set the `INVOKE_NAUTOBOT_GOLDEN_CONFIG_PYTHON_VER` variable. + +### Updating Nautobot Version + +To update the Nautobot version, you can update it within `tasks.py`. + +```python +namespace = Collection("nautobot_bgp_models") +namespace.configure( + { + "nautobot_bgp_models": { + ... + "nautobot_ver": "1.0.2", + ... + } + } +) +``` + +Or set the `INVOKE_NAUTOBOT_BGP_MODELS_NAUTOBOT_VER` variable. + +## Other Miscellaneous Commands To Know + +### Python Shell + +To drop into a Django shell for Nautobot (in the Docker container) run: + +```bash +➜ invoke nbshell +``` + +This is the same as running: + +```bash +➜ invoke cli +➜ nautobot-server nbshell +``` + +### iPython Shell Plus + +Django also has a more advanced shell that uses iPython and that will automatically import all the models: + +```bash +➜ invoke shell-plus +``` + +This is the same as running: + +```bash +➜ invoke cli +➜ nautobot-server shell_plus +``` + +### Tests + +To run tests against your code, you can run all of the tests that TravisCI runs against any new PR with: + +```bash +➜ invoke tests +``` + +To run an individual test, you can run any or all of the following: + +```bash +➜ invoke unittest +➜ invoke bandit +➜ invoke black +➜ invoke flake8 +➜ invoke pydocstyle +➜ invoke pylint +``` diff --git a/docs/dev/extending.md b/docs/dev/extending.md new file mode 100644 index 00000000..035f2923 --- /dev/null +++ b/docs/dev/extending.md @@ -0,0 +1,3 @@ +# Extending the App + +Extending the application is welcome, however it is best to open an issue first, to ensure that a PR would be accepted and makes sense in terms of features and design. diff --git a/docs/models.md b/docs/dev/models.md similarity index 92% rename from docs/models.md rename to docs/dev/models.md index 2621615e..2d9d79a0 100644 --- a/docs/models.md +++ b/docs/dev/models.md @@ -1,4 +1,4 @@ -# Data Models +# BGP Data Models This plugin adds the following data models to Nautobot: @@ -24,7 +24,8 @@ The data models introduced by the BGP plugin support the following Nautobot feat - Custom data validation logic - Webhooks -> The data models defined in this plugin were inspired by the [Openconfig BGP data model](https://yangcatalog.org/api/services/tree/openconfig-bgp@2021-06-16.yang) and the [RFC 9234](https://datatracker.ietf.org/doc/rfc9234/). +!!! note + The data models defined in this plugin were inspired by the [Openconfig BGP data model](https://yangcatalog.org/api/services/tree/openconfig-bgp@2021-06-16.yang) and the [RFC 9234](https://datatracker.ietf.org/doc/rfc9234/). ### AutonomousSystem @@ -32,7 +33,7 @@ This model represents a network-wide description of a BGP autonomous system (AS) ### BGPRoutingInstance -This model represents a device specific BGP process. It has a mandatory FK to a Nautobot `Device`, mandatory FK to a `AutonomousSystem` and following fields: +This model represents a device specific BGP process. It has a mandatory FK to a Nautobot `Device`, mandatory FK to a `AutonomousSystem` and following fields: - Router ID (optional, FK to Nautobot `IPAddress`) - Description (optional, string) @@ -93,7 +94,7 @@ This model represents a common configuration for a group of functionally related PeerEndpoint records are created when the Peering instance is created. -This model represents the configuration of a single device for a single BGP peering. +This model represents the configuration of a single device for a single BGP peering. Note that in the case of an external peering (connection with an ISP or Transit Provider), there is no need to create and model the provider's `Device` object. However, as a minimum `PeerEndpoint` (representing the provider's side of `Peering`) created during `Peering` object creation, will have to store IP Address and ASN. @@ -143,7 +144,8 @@ This model represents the shared configuration of a single BGP peer relationship - Status (FK to Nautobot `Status`) -> The classification of a session as BGP "internal" or "external" is useful in the construction of queries and filters but does not need to be stored as an actual database attribute (as it is implied by whether the ASNs of the two BGPPeerEndpoints involved are identical or different). It is implemented as a derived property of the `Peering` model. +!!! note + The classification of a session as BGP "internal" or "external" is useful in the construction of queries and filters but does not need to be stored as an actual database attribute (as it is implied by whether the ASNs of the two BGPPeerEndpoints involved are identical or different). It is implemented as a derived property of the `Peering` model. ### Inheritance between models @@ -169,7 +171,8 @@ As an example, a `PeerEndpoint` associated with a `PeerGroup` will automatically The inherited values will be automatically displayed in the UI and can be retrieved from the REST API by adding `?include_inherited=true` parameter. -(*) **BGP models Custom Fields and GraphQL currently does not offer support for BGP Field Inheritance.** See [GraphQL issue #43](https://github.com/nautobot/nautobot-plugin-bgp-models/issues/43) for details. +!!! warning + **BGP models Custom Fields and GraphQL currently does not offer support for BGP Field Inheritance.** See [GraphQL issue #43](https://github.com/nautobot/nautobot-plugin-bgp-models/issues/43) for details. Following is the complete documentation of the field inheritance hierarchy. Models are ordered with the topmost having the highest priority. The first model with an assigned attribute value will be used as an inheritance source. diff --git a/docs/development.md b/docs/development.md deleted file mode 100644 index 5c6f7395..00000000 --- a/docs/development.md +++ /dev/null @@ -1,120 +0,0 @@ -# Development Environment - -The development environment can be used in 2 ways. First, with a local Poetry environment if you wish to develop outside of Docker with the caveat of using external services provided by Docker for PostgresQL and Redis. Second, all services are spun up using Docker and a local mount so you can develop locally, but Nautobot is spun up within the Docker container. - -Below is a quick start guide if you're already familiar with the development environment provided, but if you're not familiar, please read the Getting Started guide in the repo. - -## Invoke - -The [Invoke](http://www.pyinvoke.org/) library is used to provide some helper commands based on the environment. There are a few configuration parameters which can be passed to Invoke to override the default configuration: - -* `nautobot_ver`: the version of Nautobot to use as a base for any built Docker containers (default: 1.1.4) -* `project_name`: the Docker Compose project name (default: nautobot_bgp_models) -* `python_ver`: the version of Python to use as a base for any built Docker containers (default: 3.6) -* `local`: a boolean flag indicating if Invoke tasks should be run on the host or inside the Docker containers (default: False, commands will be run in Docker containers) -* `compose_dir`: the full path to a directory containing the project Compose files -* `compose_files`: a list of Compose files applied in order (see [Multiple Compose files](https://docs.docker.com/compose/extends/#multiple-compose-files) for more information) - -Using **Invoke** these configuration options can be overridden using [several methods](http://docs.pyinvoke.org/en/stable/concepts/configuration.html). Perhaps the simplest is simply setting an environment variable `INVOKE_NAUTOBOT_BGP_MODELS_VARIABLE_NAME` where `VARIABLE_NAME` is the variable you are trying to override. The only exception is `compose_files`, because it is a list it must be overridden in a YAML file. There is an example `invoke.yml` (`invoke.example.yml`) in this directory which can be used as a starting point. - -## Local Poetry Development Environment - -1. Copy `development/creds.example.env` to `development/creds.env` (This file will be ignored by Git and Docker) -2. Uncomment the `POSTGRES_HOST`, `REDIS_HOST`, and `NAUTOBOT_ROOT` variables in `development/creds.env` -3. Create an `invoke.yml` file with the following contents at the root of the repo (you can also copy the file with `cp invoke.example.yml invoke.yml` and edit as necessary): - - ```yaml - --- - nautobot_bgp_models: - local: true - compose_files: - - "docker-compose.requirements.yml" - ``` - -4. Run the following commands: - - ```shell - poetry shell - poetry install --extras nautobot - export $(cat development/dev.env | xargs) - export $(cat development/creds.env | xargs) - invoke start && sleep 5 - nautobot-server migrate - ``` - - > If you want to develop on the latest develop branch of Nautobot, run the following command: `poetry add --optional git+https://github.com/nautobot/nautobot@develop`. The string after the `@` symbol must match either a branch or a tag. - -5. You can now run `nautobot-server` commands as you would from the [Nautobot documentation](https://nautobot.readthedocs.io/en/latest/) for example to start the development server: - -```shell -nautobot-server runserver 0.0.0.0:8080 --insecure -``` - -Nautobot server can now be accessed at [http://localhost:8080](http://localhost:8080). - -It is typically recommended to launch the Nautobot **runserver** command in a separate shell so you can keep developing and manage the webserver separately. - -## Docker Development Environment - -This project is managed by [Python Poetry](https://python-poetry.org/) and has a few requirements to setup your development environment: - -1. Install Poetry, see the [Poetry Documentation](https://python-poetry.org/docs/#installation) for your operating system. -2. Install Docker, see the [Docker documentation](https://docs.docker.com/get-docker/) for your operating system. - -Once you have Poetry and Docker installed you can run the following commands to install all other development dependencies in an isolated python virtual environment: - -```shell -poetry shell -poetry install -invoke start -``` - -Nautobot server can now be accessed at [http://localhost:8080](http://localhost:8080). - -To either stop or destroy the development environment use the following options. - -* **invoke stop** - Stop the containers, but keep all underlying systems intact -* **invoke destroy** - Stop and remove all containers, volumes, etc. (This results in data loss due to the volume being deleted) - -### CLI Helper Commands - -The project comes with a CLI helper based on [Invoke](http://www.pyinvoke.org/) to help setup the development environment. The commands are listed below in 3 categories `dev environment`, `utility` and `testing`. - -Each command can be executed with `invoke `. Environment variables `INVOKE_NAUTOBOT_BGP_MODELS_PYTHON_VER` and `INVOKE_NAUTOBOT_BGP_MODEL_NAUTOBOT_VER` may be specified to override the default versions. Each command also has its own help `invoke --help` - -## Docker dev environment - -```no-highlight - build Build all docker images. - debug Start Nautobot and its dependencies in debug mode. - destroy Destroy all containers and volumes. - restart Restart Nautobot and its dependencies. - start Start Nautobot and its dependencies in detached mode. - stop Stop Nautobot and its dependencies. -``` - -## Utility - -```no-highlight - cli Launch a bash shell inside the running Nautobot container. - create-user Create a new user in django (default: admin), will prompt for password. - makemigrations Run Make Migration in Django. - nbshell Launch a nbshell session. - shell-plus Launch a shell_plus session, which uses iPython and automatically imports all models. -``` - -## Testing - -```no-highlight - bandit Run bandit to validate basic static code security analysis. - black Run black to check that Python files adhere to its style standards. - flake8 This will run flake8 for the specified name and Python version. - pydocstyle Run pydocstyle to validate docstring formatting adheres to NTC defined standards. - pylint Run pylint code analysis. - tests Run all tests for this plugin. - unittest Run Django unit tests for the plugin. -``` - -## Project Documentation - -Project documentation is generated by [mkdocs](https://www.mkdocs.org/) from the documentation located in the docs folder. You can configure [readthedocs.io](https://readthedocs.io/) to point at this folder in your repo. A container hosting the docs will be started using the invoke commands on [http://localhost:8001](http://localhost:8001), as changes are saved the docs will be automatically reloaded. diff --git a/docs/example.md b/docs/example.md deleted file mode 100644 index 9d0d3730..00000000 --- a/docs/example.md +++ /dev/null @@ -1,11 +0,0 @@ -# Examples - -To make the start with the plugin easier, we provide two example use cases for common OS platforms: Cisco and Juniper. - -## Cisco Configuration Modeling and Rendering - -Navigate to [Cisco Example Use Case](cisco_use_case.md) for detailed instructions on how to consume the BGP Models plugin on Cisco devices. - -## Juniper Configuration Modeling and Rendering - -Navigate to [Juniper Example Use Case](juniper_use_case.md) for detailed instructions on how to consume the BGP Models plugin on Juniper devices. diff --git a/docs/extra.css b/docs/extra.css deleted file mode 100644 index 6a95f356..00000000 --- a/docs/extra.css +++ /dev/null @@ -1,19 +0,0 @@ -/* Images */ -img { - display: block; - margin-left: auto; - margin-right: auto; -} - -/* Tables */ -table { - margin-bottom: 24px; - width: 100%; -} -th { - background-color: #f0f0f0; - padding: 6px; -} -td { - padding: 6px; -} diff --git a/docs/images_manual/add_asn_12345.png b/docs/images/add_asn_12345.png similarity index 100% rename from docs/images_manual/add_asn_12345.png rename to docs/images/add_asn_12345.png diff --git a/docs/images_manual/add_external_peering.png b/docs/images/add_external_peering.png similarity index 100% rename from docs/images_manual/add_external_peering.png rename to docs/images/add_external_peering.png diff --git a/docs/images_manual/add_internal_peering.png b/docs/images/add_internal_peering.png similarity index 100% rename from docs/images_manual/add_internal_peering.png rename to docs/images/add_internal_peering.png diff --git a/docs/images_manual/add_new_ri.png b/docs/images/add_new_ri.png similarity index 100% rename from docs/images_manual/add_new_ri.png rename to docs/images/add_new_ri.png diff --git a/docs/images_manual/external_peering_created.png b/docs/images/external_peering_created.png similarity index 100% rename from docs/images_manual/external_peering_created.png rename to docs/images/external_peering_created.png diff --git a/docs/images/icon-nautobot-bgp-models.png b/docs/images/icon-nautobot-bgp-models.png new file mode 100644 index 0000000000000000000000000000000000000000..7e00cf6ae0ee76324adab30d68d64206678a85e1 GIT binary patch literal 74601 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
@5hb{hC=~cCz;d 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 literal 0 HcmV?d00001 diff --git a/docs/images_manual/internal_peering_created.png b/docs/images/internal_peering_created.png similarity index 100% rename from docs/images_manual/internal_peering_created.png rename to docs/images/internal_peering_created.png diff --git a/docs/images_manual/menu.png b/docs/images/menu.png similarity index 100% rename from docs/images_manual/menu.png rename to docs/images/menu.png diff --git a/docs/images_manual/ri_list_view.png b/docs/images/ri_list_view.png similarity index 100% rename from docs/images_manual/ri_list_view.png rename to docs/images/ri_list_view.png diff --git a/docs/index.md b/docs/index.md index 0cc3c833..f32fd72b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,59 +1,6 @@ -# Nautobot BGP Models Plugin +--- +hide: + - navigation +--- -A plugin for [Nautobot](https://github.com/nautobot/nautobot) extending the core models with BGP-specific models. - -New models enable modeling and management of BGP peerings, whether or not the peer device is present in Nautobot. - -> The initial development of this plugin was sponsored by Riot Games, Inc. - -## Installation - -The plugin is available as a Python package in PyPI and can be installed with `pip`: - -```shell -pip install nautobot-bgp-models -``` - -> The plugin is compatible with Nautobot 1.5.4 and higher - -To ensure Nautobot BGP Models Plugin is automatically re-installed during future upgrades, create a file named `local_requirements.txt` (if not already existing) in the Nautobot root directory (alongside `requirements.txt`) and list the `nautobot-bgp-models` package: - -```no-highlight -# echo nautobot-bgp-models >> local_requirements.txt -``` - -Once installed, the plugin needs to be enabled in your `nautobot_config.py` - -```python -# In your configuration.py -PLUGINS = ["nautobot_bgp_models"] -``` - -```python -PLUGINS_CONFIG = { - "nautobot_bgp_models": { - "default_statuses": { - "AutonomousSystem": ["active", "available", "planned"], - "Peering": ["active", "decommissioned", "deprovisioning", "offline", "planned", "provisioning"], - } - } -} -``` - -In the `default_statuses` section, you can define a list of default statuses to make available to `AutonomousSystem` and/or `Peering`. The lists must be composed of valid slugs of existing Status objects. - -## Contributing - -Pull requests are welcomed and automatically built and tested against multiple version of Python and multiple version of Nautobot through TravisCI. - -The project is packaged with a light development environment based on `docker-compose` to help with the local development of the project and to run the tests within TravisCI. - -The project is following Network to Code software development guideline and is leveraging: - -- Black, Pylint, Bandit and pydocstyle for Python linting and formatting. -- Django unit test to ensure the plugin is working properly. - -## Questions - -For any questions or comments, please feel free to swing by the [Network to Code slack channel](https://networktocode.slack.com/) (channel #networktocode). -Sign up [here](http://slack.networktocode.com/) +--8<-- "README.md" diff --git a/docs/requirements.txt b/docs/requirements.txt index f8549b5b..8cd16e3d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,5 @@ -Jinja2==3.0.3 -mkdocs==1.3.0 -mkdocs-include-markdown-plugin==3.2.3 \ No newline at end of file +mkdocs==1.3.1 +mkdocs-material==8.4.2 +mkdocstrings==0.19 +mkdocstrings-python==0.7.1 +mkdocs-version-annotations==1.0.0 diff --git a/docs/manual.md b/docs/user/app_getting_started.md similarity index 57% rename from docs/manual.md rename to docs/user/app_getting_started.md index c33a5a7d..d822d5fc 100644 --- a/docs/manual.md +++ b/docs/user/app_getting_started.md @@ -1,61 +1,70 @@ -# Introduction +# Getting Started with the App -Below shows the workflows for the two most common BGP Plugin use cases: modeling internal and external peering. We will showcase how to create each type of peering with the minimum number of steps and inputs required from users. +This document provides a step-by-step tutorial on how to get the App going and how to use it. -## Menu Item +## Install the App + +To install the App, please follow the instructions detailed in the [Installation Guide](../admin/install.md). + +## First steps with the App + +We will now explore the workflows for the two most common BGP Plugin use cases: modeling internal and external peerings. We will showcase how to create each type of peering with the minimum number of steps and inputs required from users. + +### Menu Item All of the "Add object" actions are available under BGP Models Plugin Menu in the top navigation bar: -![Routing menu](images_manual/menu.png "Routing Menu") -## Internal Peering Creation +![Routing menu](../images/menu.png "Routing Menu") + +### Internal Peering Creation To model an internal peering (two devices sharing the same ASN), following has to be defined for two BGP speaker devices: - a BGP Routing Instance - IP Address of an endpoint +!!! Note + Having a BGP Routing Instance is not mandatory, however we recommend creating this object for devices modeled in Nautobot. -Note that having a BGP Routing Instance is not mandatory, however we recommend creating this object for devices modeled in Nautobot. - -### Autonomous System Creation +#### Autonomous System Creation The first step is to add an Autonomous System object (via the top menu). Fill the object details: -![Autonomous System Form](images_manual/add_asn_12345.png "Autonomous System Form") +![Autonomous System Form](../images/add_asn_12345.png "Autonomous System Form") -### BGP Routing Instances creation +#### BGP Routing Instances creation The next step is to create a BGP Routing Instance for each device of an internal BGP peering. A BGP Routing Instance itself is a representation (or a declaration) of a BGP process on a given device. Fill the object details: -![BGP Routing Instance Form](images_manual/add_new_ri.png "BGP Routing Instance Form") +![BGP Routing Instance Form](../images/add_new_ri.png "BGP Routing Instance Form") Repeat for next devices and check the overall result in the BGP Routing Instance list view: -![BGP Routing Instances List](images_manual/ri_list_view.png "BGP Routing Instances List") +![BGP Routing Instances List](../images/ri_list_view.png "BGP Routing Instances List") -### Peering creation +#### Peering creation Under the menu "BGP Peerings - Peerings" click on the "Add" button to add a new peering. You will be redirected to a view with two columns in a table, each column representing one side of a BGP peering. To create a BGP Peering, you have to complete information for two sides. -![BGP Peering Form](images_manual/add_internal_peering.png "BGP Peering Form") +![BGP Peering Form](../images/add_internal_peering.png "BGP Peering Form") To create an internal BGP Peering, you only need to specify an existing BGP Routing Instance and an IP Address. -### Peering detail view +#### Peering detail view Once the BGP Peering is created, you could review its details. -![BGP Peering Details](images_manual/internal_peering_created.png "BGP Peering Details") +![BGP Peering Details](../images/internal_peering_created.png "BGP Peering Details") -## External Peering Creation +### External Peering Creation To model an external peering (two devices having different ASN), the following has to be defined: @@ -69,24 +78,30 @@ To model an external peering (two devices having different ASN), the following h The steps required to create an internal peer have been explained in the previous section. -### Autonomous System Creation - for Provider +#### Autonomous System Creation - for Provider The first step is to add an Autonomous System object for a Provider. Fill in the object details and ensure the optional field "Provider" is filled. -### Peering creation +#### Peering creation Once the Autonomous System and BGP Routing Instance objects have been created you are ready to create a peering between two devices. Under the menu "BGP Peerings - Peerings" click on the "Add" button to add a new peering. You will be redirected to a view with two columns in a table, each column representing one side of a BGP peering. To create a BGP Peering, You have to complete information for both sides. -![BGP Peering Form](images_manual/add_external_peering.png "BGP Peering Form") +![BGP Peering Form](../images/add_external_peering.png "BGP Peering Form") To create an external BGP Peering, for the Provider's side You have to fill in the information with the Provider's ASN and IP Address of the provider's endpoint. -### Peering detail view +#### Peering detail view Once the BGP Peering is created, you could review its details. -![BGP Peering Details](images_manual/external_peering_created.png "BGP Peering Details") +![BGP Peering Details](../images/external_peering_created.png "BGP Peering Details") + + + +## What are the next steps? + +Check out the [Cisco](cisco_use_case.md) or [Juniper](juniper_use_case.md) configuration example use-cases. diff --git a/docs/user/app_overview.md b/docs/user/app_overview.md new file mode 100644 index 00000000..a7647732 --- /dev/null +++ b/docs/user/app_overview.md @@ -0,0 +1,59 @@ +# App Overview + +This document provides an overview of the App including critical information and import considerations when applying it to your Nautobot environment. + +!!! note + Throughout this documentation, the terms "app" and "plugin" will be used interchangeably. + +## Description + +An app for [Nautobot](https://github.com/nautobot/nautobot), extending the core models with BGP-specific models. They enable modeling and management of BGP peerings, whether or not the peer device is present in Nautobot. + +This application adds the following new data models into Nautobot: + +- **BGP Routing Instance**: device-specific BGP process +- **Autonomous System**: network-wide description of a BGP autonomous system (AS) +- **Peer Group Template**: network-wide template for Peer Group objects +- **Peer Group**: device-specific configuration for a group of functionally related BGP peers +- **Address Family**: device-specific configuration of a BGP address family (AFI-SAFI) +- **Peering and Peer Endpoints**: A BGP Peering is represented by a Peering object and two endpoints, each representing the configuration of one side of the BGP peering. A Peer Endpoint must be associated with a BGP Routing Instance. +- **Peering Role**: describes the valid options for PeerGroup, PeerGroupTemplate, and/or Peering roles + +With these new models, it's now possible to populate the Source of Truth (SoT) with any BGP peerings, internal or external, regardless of whether both endpoints are fully defined in the Source of Truth. + +The minimum requirement to define a BGP peering is two IP addresses and one or two autonomous systems (one ASN for iBGP, two ASNs for eBGP). + +## Audience (User Personas) - Who should use this App? + +Network Admins who need to model their BGP internal and external peerings inside of their Source of Truth so they can programmatically generate BGP configuration for their devices. + +## Authors and Maintainers + +- Glenn Matthews (@glennmatthews) +- Marek Zbroch (@mzbroch) + +## Nautobot Features Used + +This plugin adds the following data models to Nautobot: + +- AutonomousSystem +- BGPRoutingInstance +- PeerEndpoint +- PeerGroup +- PeerGroupTemplate +- AddressFamily +- Peering +- PeeringRole + +The data models introduced by the BGP plugin support the following Nautobot features: + +- Rest API +- GraphQL +- Custom fields +- Custom Links +- Relationships +- Change logging +- Custom data validation logic +- Webhooks + +For more details please visit the [BGP Data Models](../dev/models.md) page. diff --git a/docs/user/app_use_cases.md b/docs/user/app_use_cases.md new file mode 100644 index 00000000..6d4c338f --- /dev/null +++ b/docs/user/app_use_cases.md @@ -0,0 +1,41 @@ +# Using the App + +This document describes common use-cases and scenarios for this App. + +## Use-cases and common workflows + +To make getting started with the plugin easier, we provide example use-cases for two common OS platforms: Cisco and Juniper. + +### Cisco Configuration Modeling and Rendering + +Navigate to [Cisco Example Use Case](cisco_use_case.md) for detailed instructions how to consume BGP Models plugin on Cisco devices. + +### Juniper Configuration Modeling and Rendering + +Navigate to [Juniper Example Use Case](juniper_use_case.md) for detailed instructions how to consume BGP Models plugin on Juniper devices. + +## Screenshots + +### Routing Menu + +![Menu](../images/main-page-menu.png) + +### Autonomous System + +![Autonomous System](../images/autonomous_system_01.png) + +### Peering List + +![Peering List](../images/peering_list.png) + +### BGP Peering + +![Peering](../images/peering_01.png) + +### Peer Endpoint + +![Peer Endpoint](../images/peer_endpoint_01.png) + +### Peer Group + +![Peer Group](../images/peer_group_01.png) diff --git a/docs/cisco_use_case.md b/docs/user/cisco_use_case.md similarity index 87% rename from docs/cisco_use_case.md rename to docs/user/cisco_use_case.md index 32fbfcd3..40e2c1c5 100644 --- a/docs/cisco_use_case.md +++ b/docs/user/cisco_use_case.md @@ -309,7 +309,7 @@ An example data returned from Nautobot is presented below. } ``` -## Creating Cisco Jinja2 BGP Configuration Template +## Creating a Cisco Jinja2 BGP Configuration Template Following snippet represents an example Cisco BGP Configuration Template: @@ -355,39 +355,39 @@ router bgp {{ data.device.bgp_routing_instances.0.autonomous_system.asn }} Following snippet represents an example Cisco BGP Renderer Configuration: ```text -! -router bgp 65535 - neighbor EDGE-to-LEAF peer-group - neighbor EDGE-to-LEAF route-map BGP-LEAF-IN in - neighbor EDGE-to-LEAF route-map BGP-LEAF-OUT out - neighbor EDGE-to-LEAF next-hop-self - neighbor EDGE-to-LEAF send-community - neighbor EDGE-to-TRANSIT peer-group - neighbor EDGE-to-TRANSIT route-map BGP-TRANSIT-IN in - neighbor EDGE-to-TRANSIT route-map BGP-TRANSIT-OUT out - neighbor EDGE-to-TRANSIT ttl-security hops 1 -! - neighbor 10.11.192.13 remote-as 4200000000 - neighbor 10.11.192.13 peer-group EDGE-to-LEAF - neighbor 10.11.192.29 remote-as 4200000000 - neighbor 10.11.192.29 peer-group EDGE-to-LEAF - neighbor 10.11.192.9 remote-as 4200000000 - neighbor 10.11.192.9 peer-group EDGE-to-LEAF - neighbor 10.11.192.25 remote-as 4200000000 - neighbor 10.11.192.25 peer-group EDGE-to-LEAF - neighbor 10.11.192.5 remote-as 4200000000 - neighbor 10.11.192.5 peer-group EDGE-to-LEAF - neighbor 10.11.192.21 remote-as 4200000000 - neighbor 10.11.192.21 peer-group EDGE-to-LEAF - neighbor 10.11.192.17 remote-as 4200000000 - neighbor 10.11.192.17 peer-group EDGE-to-LEAF - neighbor 10.11.192.33 remote-as 4200000000 - neighbor 10.11.192.33 peer-group EDGE-to-LEAF - neighbor 104.94.128.2 remote-as 1299 - neighbor 104.94.128.2 peer-group EDGE-to-TRANSIT - neighbor 104.94.128.10 remote-as 2914 - neighbor 104.94.128.10 peer-group EDGE-to-TRANSIT -! - no synchronization ! -``` \ No newline at end of file +router bgp 65535 + neighbor EDGE-to-LEAF peer-group + neighbor EDGE-to-LEAF route-map BGP-LEAF-IN in + neighbor EDGE-to-LEAF route-map BGP-LEAF-OUT out + neighbor EDGE-to-LEAF next-hop-self + neighbor EDGE-to-LEAF send-community + neighbor EDGE-to-TRANSIT peer-group + neighbor EDGE-to-TRANSIT route-map BGP-TRANSIT-IN in + neighbor EDGE-to-TRANSIT route-map BGP-TRANSIT-OUT out + neighbor EDGE-to-TRANSIT ttl-security hops 1 +! + neighbor 10.11.192.13 remote-as 4200000000 + neighbor 10.11.192.13 peer-group EDGE-to-LEAF + neighbor 10.11.192.29 remote-as 4200000000 + neighbor 10.11.192.29 peer-group EDGE-to-LEAF + neighbor 10.11.192.9 remote-as 4200000000 + neighbor 10.11.192.9 peer-group EDGE-to-LEAF + neighbor 10.11.192.25 remote-as 4200000000 + neighbor 10.11.192.25 peer-group EDGE-to-LEAF + neighbor 10.11.192.5 remote-as 4200000000 + neighbor 10.11.192.5 peer-group EDGE-to-LEAF + neighbor 10.11.192.21 remote-as 4200000000 + neighbor 10.11.192.21 peer-group EDGE-to-LEAF + neighbor 10.11.192.17 remote-as 4200000000 + neighbor 10.11.192.17 peer-group EDGE-to-LEAF + neighbor 10.11.192.33 remote-as 4200000000 + neighbor 10.11.192.33 peer-group EDGE-to-LEAF + neighbor 104.94.128.2 remote-as 1299 + neighbor 104.94.128.2 peer-group EDGE-to-TRANSIT + neighbor 104.94.128.10 remote-as 2914 + neighbor 104.94.128.10 peer-group EDGE-to-TRANSIT +! + no synchronization +! +``` diff --git a/FAQ.md b/docs/user/faq.md similarity index 100% rename from FAQ.md rename to docs/user/faq.md diff --git a/docs/juniper_use_case.md b/docs/user/juniper_use_case.md similarity index 99% rename from docs/juniper_use_case.md rename to docs/user/juniper_use_case.md index a26cce68..b3e67e53 100644 --- a/docs/juniper_use_case.md +++ b/docs/user/juniper_use_case.md @@ -309,7 +309,7 @@ An example data returned from Nautobot is presented below. } ``` -## Creating Juniper Jinja2 BGP Configuration Template +## Creating a Juniper Jinja2 BGP Configuration Template Following snippet represents an example Juniper BGP Configuration Template: @@ -317,7 +317,7 @@ Following snippet represents an example Juniper BGP Configuration Template: # Set the ASN for Routing Instance set routing-options autonomous-system {{ data.device.bgp_routing_instances.0.autonomous_system.asn }} -# Configure Groups +# Configure Groups {%- for peer_group in data.device.bgp_routing_instances.0.peer_groups %} {%- if peer_group.template.role.slug == "peer" %} set protocols bgp group {{ peer_group.name }} type internal @@ -396,4 +396,4 @@ root# show routing-options autonomous-system 65535; [edit] -``` \ No newline at end of file +``` diff --git a/mkdocs.yml b/mkdocs.yml index e0b06d61..83bb0b6d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,31 +1,121 @@ --- dev_addr: "127.0.0.1:8001" -edit_uri: "edit/main/nautobot-plugin-bgp-models/docs" -site_name: "Nautobot BGP Models Plugin Documentation" -site_url: "https://nautobot-plugin-bgp-models.readthedocs.io/" +edit_uri: "edit/develop/docs" site_dir: "nautobot_bgp_models/static/nautobot_bgp_models/docs" +site_name: "BGP Models Documentation" +site_url: "https://docs.nautobot.com/projects/bgp-models/en/latest/" repo_url: "https://github.com/nautobot/nautobot-plugin-bgp-models" +copyright: "Copyright © The Authors" theme: - name: "readthedocs" + name: "material" navigation_depth: 4 + custom_dir: "docs/assets/overrides" hljs_languages: - "django" - "yaml" + features: + - "navigation.tracking" + - "navigation.tabs" + - "navigation.tabs.sticky" + - "search.suggest" + - "search.highlight" + - "search.share" + - "navigation.indexes" + favicon: "assets/favicon.ico" + logo: "assets/nautobot_logo.svg" + palette: + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: "default" + primary: "black" + toggle: + icon: "material/weather-sunny" + name: "Switch to dark mode" + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: "slate" + primary: "black" + toggle: + icon: "material/weather-night" + name: "Switch to light mode" extra_css: - - "extra.css" + - "assets/extra.css" + +# needed for RTD version flyout menu +# jquery is not (yet) injected by RTD automatically and it might be dropped +# as a dependency in the future +extra_javascript: + - "https://code.jquery.com/jquery-3.6.0.min.js" + +extra: + generator: false + ntc_sponsor: true + social: + - icon: "fontawesome/solid/rss" + link: "https://blog.networktocode.com/blog/tags/nautobot" + name: "Network to Code Blog" + - icon: "fontawesome/brands/youtube" + link: "https://www.youtube.com/playlist?list=PLjA0bhxgryJ2Ts4GJMDA-tPzVWEncv4pb" + name: "Nautobot Videos" + - icon: "fontawesome/brands/slack" + link: "https://www.networktocode.com/community/" + name: "Network to Code Community" + - icon: "fontawesome/brands/github" + link: "https://github.com/nautobot/nautobot" + name: "GitHub Repo" + - icon: "fontawesome/brands/twitter" + link: "https://twitter.com/networktocode" + name: "Network to Code Twitter" markdown_extensions: - "admonition" - - toc: + - "toc": permalink: true + - "attr_list" + - "md_in_html" + - "pymdownx.highlight": + anchor_linenums: true + - "pymdownx.inlinehilite" + - "pymdownx.snippets" + - "pymdownx.superfences" + - "footnotes" plugins: - - "include-markdown" + - "search" + - "mkdocs-version-annotations" + - "mkdocstrings": + default_handler: "python" + handlers: + python: + paths: ["."] + options: + show_root_heading: true +watch: + - "README.md" + nav: - - Introduction: "index.md" + - Overview: "index.md" - User Guide: - - Models: "models.md" - - Examples: - - Creating peerings workflow: "manual.md" - - Generating Cisco BGP Config: "cisco_use_case.md" - - Generating Juniper BGP Config: "juniper_use_case.md" + - App Overview: "user/app_overview.md" + - Getting Started: "user/app_getting_started.md" + - Using the App: "user/app_use_cases.md" + - Cisco Example Use Case: "user/cisco_use_case.md" + - Juniper Example Use Case: "user/juniper_use_case.md" + - Frequently Asked Questions: "user/faq.md" + - Administrator Guide: + - Install and Configure: "admin/install.md" + - Upgrade: "admin/upgrade.md" + - Uninstall: "admin/uninstall.md" + - Compatibility Matrix: "admin/compatibility_matrix.md" + - Release Notes: + - "admin/release_notes/index.md" + - v0.7: "admin/release_notes/version_0.7.md" - Developer Guide: - - Development Environment: "development.md" + - BGP Data Models: "dev/models.md" + - Extending the App: "dev/extending.md" + - Contributing to the App: "dev/contributing.md" + - Development Environment: "dev/dev_environment.md" + - Code Reference: + - "dev/code_reference/index.md" + - Package: "dev/code_reference/package.md" + - API: "dev/code_reference/api.md" + - Nautobot Docs Home ↗︎: "https://docs.nautobot.com" diff --git a/nautobot_bgp_models/tests/test_basic.py b/nautobot_bgp_models/tests/test_basic.py new file mode 100644 index 00000000..5c2f9d1f --- /dev/null +++ b/nautobot_bgp_models/tests/test_basic.py @@ -0,0 +1,33 @@ +"""Basic tests that do not require Django.""" +import unittest +import os +import toml + +from nautobot_bgp_models import __version__ as project_version + + +class TestVersion(unittest.TestCase): + """Test Version is the same.""" + + def test_version(self): + """Verify that pyproject.toml version is same as version specified in the package.""" + parent_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) + poetry_version = toml.load(os.path.join(parent_path, "pyproject.toml"))["tool"]["poetry"]["version"] + self.assertEqual(project_version, poetry_version) + + +class TestDocsPackaging(unittest.TestCase): + """Test Version in doc requirements is the same pyproject.""" + + def test_version(self): + """Verify that pyproject.toml dev dependecies have the same versions as in the docs requirements.txt.""" + parent_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) + poetry_details = toml.load(os.path.join(parent_path, "pyproject.toml"))["tool"]["poetry"]["dev-dependencies"] + with open(f"{parent_path}/docs/requirements.txt", "r", encoding="utf-8") as file: + requirements = [line for line in file.read().splitlines() if (len(line) > 0 and not line.startswith("#"))] + for pkg in requirements: + if len(pkg.split("==")) == 2: + pkg, version = pkg.split("==") + else: + version = "*" + self.assertEqual(poetry_details[pkg], version) diff --git a/pyproject.toml b/pyproject.toml index 6c4a8fb5..d207905a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,15 @@ pydocstyle = "*" # therefore cause issues with linting since older versions do not take .flake8 as config flake8 = "^3.9.2" coverage = "^5.5" +# Rendering docs to HTML +mkdocs = "1.3.1" +# Material for MkDocs theme +mkdocs-material = "8.4.2" +# Render custom markdown for version added/changed/remove notes +mkdocs-version-annotations = "1.0.0" +# Automatic documentation from sources, for MkDocs +mkdocstrings = "0.19" +mkdocstrings-python = "0.7.1" [tool.black] line-length = 120 From dbcca69b37c07ef46d05dfded0af597110c1acbf Mon Sep 17 00:00:00 2001 From: root Date: Thu, 23 Mar 2023 09:47:50 +0100 Subject: [PATCH 29/61] Updating poetry.lock --- poetry.lock | 271 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 259 insertions(+), 12 deletions(-) diff --git a/poetry.lock b/poetry.lock index dd29ac1a..ad149bef 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. +# This file is automatically @generated by Poetry and should not be changed by hand. [[package]] name = "amqp" @@ -1213,6 +1213,24 @@ files = [ {file = "funcy-1.18.tar.gz", hash = "sha256:15448d19a8ebcc7a585afe7a384a19186d0bd67cbf56fb42cd1fd0f76313f9b2"}, ] +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + [[package]] name = "gitdb" version = "4.0.10" @@ -1342,6 +1360,25 @@ graphql-core = ">=2.2,<3" promise = ">=2.2,<3" six = ">=1.12" +[[package]] +name = "griffe" +version = "0.25.5" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "griffe-0.25.5-py3-none-any.whl", hash = "sha256:1fb9edff48e66d4873014a2ebf21aca5f271d0006a4c937826e3cf592ffb3706"}, + {file = "griffe-0.25.5.tar.gz", hash = "sha256:11ea3403ef0560a1cbcf7f302eb5d21cf4c1d8ed3f8a16a75aa9f6f458caf3f1"}, +] + +[package.dependencies] +cached-property = {version = "*", markers = "python_version < \"3.8\""} +colorama = ">=0.4" + +[package.extras] +async = ["aiofiles (>=0.7,<1.0)"] + [[package]] name = "idna" version = "3.4" @@ -1697,6 +1734,146 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.3.1" +description = "Project documentation with Markdown." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-1.3.1-py3-none-any.whl", hash = "sha256:fda92466393127d2da830bc6edc3a625a14b436316d1caf347690648e774c4f0"}, + {file = "mkdocs-1.3.1.tar.gz", hash = "sha256:a41a2ff25ce3bbacc953f9844ba07d106233cd76c88bac1f59cb1564ac0d87ed"}, +] + +[package.dependencies] +click = ">=3.3" +ghp-import = ">=1.0" +importlib-metadata = ">=4.3" +Jinja2 = ">=2.10.2" +Markdown = ">=3.2.1,<3.4" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +PyYAML = ">=3.10" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] + +[[package]] +name = "mkdocs-autorefs" +version = "0.4.1" +description = "Automatically link across pages in MkDocs." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-autorefs-0.4.1.tar.gz", hash = "sha256:70748a7bd025f9ecd6d6feeba8ba63f8e891a1af55f48e366d6d6e78493aba84"}, + {file = "mkdocs_autorefs-0.4.1-py3-none-any.whl", hash = "sha256:a2248a9501b29dc0cc8ba4c09f4f47ff121945f6ce33d760f145d6f89d313f5b"}, +] + +[package.dependencies] +Markdown = ">=3.3" +mkdocs = ">=1.1" + +[[package]] +name = "mkdocs-material" +version = "8.4.2" +description = "Documentation that simply works" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-material-8.4.2.tar.gz", hash = "sha256:704c64c3fff126a3923c2961d95f26b19be621342a6a4e49ed039f0bb7a5c540"}, + {file = "mkdocs_material-8.4.2-py2.py3-none-any.whl", hash = "sha256:166287bb0e4197804906bf0389a852d5ced43182c30127ac8b48a4e497ecd7e5"}, +] + +[package.dependencies] +jinja2 = ">=3.0.2" +markdown = ">=3.2" +mkdocs = ">=1.3.0" +mkdocs-material-extensions = ">=1.0.3" +pygments = ">=2.12" +pymdown-extensions = ">=9.4" + +[[package]] +name = "mkdocs-material-extensions" +version = "1.1.1" +description = "Extension pack for Python Markdown and MkDocs Material." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, + {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, +] + +[[package]] +name = "mkdocs-version-annotations" +version = "1.0.0" +description = "MkDocs plugin to add custom admonitions for documenting version differences" +category = "dev" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "mkdocs-version-annotations-1.0.0.tar.gz", hash = "sha256:6786024b37d27b330fda240b76ebec8e7ce48bd5a9d7a66e99804559d088dffa"}, + {file = "mkdocs_version_annotations-1.0.0-py3-none-any.whl", hash = "sha256:385004eb4a7530dd87a227e08cd907ce7a8fe21fdf297720a4149c511bcf05f5"}, +] + +[[package]] +name = "mkdocstrings" +version = "0.19.0" +description = "Automatic documentation from sources, for MkDocs." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocstrings-0.19.0-py3-none-any.whl", hash = "sha256:3217d510d385c961f69385a670b2677e68e07b5fea4a504d86bf54c006c87c7d"}, + {file = "mkdocstrings-0.19.0.tar.gz", hash = "sha256:efa34a67bad11229d532d89f6836a8a215937548623b64f3698a1df62e01cc3e"}, +] + +[package.dependencies] +Jinja2 = ">=2.11.1" +Markdown = ">=3.3" +MarkupSafe = ">=1.1" +mkdocs = ">=1.2" +mkdocs-autorefs = ">=0.3.1" +pymdown-extensions = ">=6.3" + +[package.extras] +crystal = ["mkdocstrings-crystal (>=0.3.4)"] +python = ["mkdocstrings-python (>=0.5.2)"] +python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] + +[[package]] +name = "mkdocstrings-python" +version = "0.7.1" +description = "A Python handler for mkdocstrings." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocstrings-python-0.7.1.tar.gz", hash = "sha256:c334b382dca202dfa37071c182418a6df5818356a95d54362a2b24822ca3af71"}, + {file = "mkdocstrings_python-0.7.1-py3-none-any.whl", hash = "sha256:a22060bfa374697678e9af4e62b020d990dad2711c98f7a9fac5c0345bef93c7"}, +] + +[package.dependencies] +griffe = ">=0.11.1" +mkdocstrings = ">=0.19" + [[package]] name = "mypy-extensions" version = "1.0.0" @@ -1711,14 +1888,14 @@ files = [ [[package]] name = "nautobot" -version = "1.5.13" +version = "1.5.14" description = "Source of truth and network automation platform." category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "nautobot-1.5.13-py3-none-any.whl", hash = "sha256:10db9a1b5a50adad0e079d9d11ce6e5a5fa1dd9df07ab5cfa325e87fdf023cea"}, - {file = "nautobot-1.5.13.tar.gz", hash = "sha256:70ead6cefd724fee18ed06febdc8110a49cc6e98d4af0d1e0921567343475464"}, + {file = "nautobot-1.5.14-py3-none-any.whl", hash = "sha256:8ea60d938b6d746b6791f986d1110aeadea8d70032f46a0ff747994af81250e4"}, + {file = "nautobot-1.5.14.tar.gz", hash = "sha256:4ead01f85ad9179a3523d233a4da20e8ad15250fa34b93ca49adc8b8318b55ac"}, ] [package.dependencies] @@ -2264,6 +2441,22 @@ files = [ [package.dependencies] pylint = ">=1.7" +[[package]] +name = "pymdown-extensions" +version = "9.10" +description = "Extension pack for Python Markdown." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pymdown_extensions-9.10-py3-none-any.whl", hash = "sha256:31eaa76ce6f96aabfcea98787c2fff2c5c0611b20a53a94213970cfbf05f02b8"}, + {file = "pymdown_extensions-9.10.tar.gz", hash = "sha256:562c38eee4ce3f101ce631b804bfc2177a8a76c7e4dc908871fb6741a90257a7"}, +] + +[package.dependencies] +markdown = ">=3.2" +pyyaml = "*" + [[package]] name = "pyrsistent" version = "0.19.3" @@ -2462,20 +2655,35 @@ files = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + [[package]] name = "redis" -version = "4.5.1" +version = "4.5.3" description = "Python client for Redis database and key-value store" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "redis-4.5.1-py3-none-any.whl", hash = "sha256:5deb072d26e67d2be1712603bfb7947ec3431fb0eec9c578994052e33035af6d"}, - {file = "redis-4.5.1.tar.gz", hash = "sha256:1eec3741cda408d3a5f84b78d089c8b8d895f21b3b050988351e925faf202864"}, + {file = "redis-4.5.3-py3-none-any.whl", hash = "sha256:7df17a0a2b72a4c8895b462dd07616c51b1dcb48fdd7ecb7b6f4bf39ecb2e94e"}, + {file = "redis-4.5.3.tar.gz", hash = "sha256:56732e156fe31801c4f43396bd3ca0c2a7f6f83d7936798531b9848d103381aa"}, ] [package.dependencies] -async-timeout = ">=4.0.2" +async-timeout = {version = ">=4.0.2", markers = "python_version < \"3.11\""} importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} typing-extensions = {version = "*", markers = "python_version < \"3.8\""} @@ -2916,6 +3124,46 @@ files = [ {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, ] +[[package]] +name = "watchdog" +version = "3.0.0" +description = "Filesystem events monitoring" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, + {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, + {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, + {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, + {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, + {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, + {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, + {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, + {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + [[package]] name = "wcwidth" version = "0.2.6" @@ -3015,14 +3263,13 @@ files = [ [[package]] name = "yamllint" -version = "1.29.0" +version = "1.30.0" description = "A linter for YAML files." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "yamllint-1.29.0-py3-none-any.whl", hash = "sha256:5153bf9f8205aa9dc6af6217e38bd4f5baf09d9a7c6f4ae1e23f90d9c00c49c5"}, - {file = "yamllint-1.29.0.tar.gz", hash = "sha256:66a755d5fbcbb8831f1a9568676329b5bac82c37995bcc9afd048b6459f9fa48"}, + {file = "yamllint-1.30.0.tar.gz", hash = "sha256:4f58f323aedda16189a489d183ecc25c66d7a9cc0fe88f61b650fef167b13190"}, ] [package.dependencies] @@ -3049,4 +3296,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "6736f30292f44183c14ea7af7ade951638adf2550534f07ea96472dd0c8084bf" +content-hash = "9bff4614f4789110d9842d9cef501144c1f46cb591b46b1bd185a75a7fabc2f5" From 6367bb3afe0ea46f45e4ee9f80e411028faf93e2 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Wed, 29 Mar 2023 10:09:27 +0200 Subject: [PATCH 30/61] fix: update version to correct format in pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d207905a..1898ddf7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-bgp-models" -version = "0.7.0-beta.1" +version = "0.7.0b1" description = "Nautobot BGP Models Plugin" authors = ["Network to Code, LLC "] From ed3fba7824989d93d98fece9550c56070c20a091 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Wed, 10 May 2023 15:28:12 +0200 Subject: [PATCH 31/61] fix: allow read/write for extra attributes from API --- nautobot_bgp_models/api/serializers.py | 16 ++++++----- nautobot_bgp_models/tests/test_api.py | 39 ++++++++++++++++++-------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/nautobot_bgp_models/api/serializers.py b/nautobot_bgp_models/api/serializers.py index 0205b133..e0f3d191 100644 --- a/nautobot_bgp_models/api/serializers.py +++ b/nautobot_bgp_models/api/serializers.py @@ -66,16 +66,17 @@ def to_representation(self, instance): class ExtraAttributesSerializerMixin(serializers.Serializer): # pylint: disable=abstract-method """Common mixin for BGP Extra Attributes.""" - extra_attributes = serializers.SerializerMethodField(read_only=True) + extra_attributes = serializers.JSONField(required=False, allow_null=True) - def get_extra_attributes(self, instance): - """Return either the `display` property of the instance or `str(instance)`.""" - req = self.context["request"] + def to_representation(self, instance): + """Render the model instance to a Python dict. + If `include_inherited` is specified as a request parameter, include object's get_extra_attributes(). + """ + req = self.context["request"] if hasattr(req, "query_params") and is_truthy(req.query_params.get("include_inherited", False)): - return instance.get_extra_attributes() - - return instance.extra_attributes + setattr(instance, "extra_attributes", instance.get_extra_attributes()) + return super().to_representation(instance) class PeerGroupTemplateSerializer(CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin): @@ -98,6 +99,7 @@ class Meta: "autonomous_system", "import_policy", "export_policy", + "extra_attributes", "secret", ] diff --git a/nautobot_bgp_models/tests/test_api.py b/nautobot_bgp_models/tests/test_api.py index b20e6441..2011e20a 100644 --- a/nautobot_bgp_models/tests/test_api.py +++ b/nautobot_bgp_models/tests/test_api.py @@ -6,7 +6,7 @@ from nautobot.dcim.choices import InterfaceTypeChoices from nautobot.dcim.models import Device, DeviceRole, DeviceType, Interface, Manufacturer, Site from nautobot.extras.models import Status -from nautobot.ipam.models import IPAddress +from nautobot.ipam.models import IPAddress, VRF from nautobot.utilities.testing.api import APIViewTestCases from nautobot_bgp_models import models @@ -81,7 +81,10 @@ def test_notes_url_on_object(self): class PeerGroupAPITestCase(APIViewTestCases.APIViewTestCase): - """Test the PeerGroup API.""" + """Test the PeerGroup API. + + TODO(mzb): Add unittests: prevent changing related BGP Routing Instance. + """ model = models.PeerGroup view_namespace = "plugins-api:nautobot_bgp_models" @@ -107,14 +110,15 @@ def setUpTestData(cls): device = Device.objects.create( device_type=devicetype, device_role=devicerole, name="Device 1", site=site, status=status_active ) - # interface = Interface.objects.create(device=device, name="Loopback1", type=InterfaceTypeChoices.TYPE_VIRTUAL) + interface = Interface.objects.create(device=device, name="Loopback1", type=InterfaceTypeChoices.TYPE_VIRTUAL) - # vrf = VRF.objects.create(name="Ark B") - # cls.address = IPAddress.objects.create( - # address="10.1.1.1/24", status=status_active, vrf=vrf, assigned_object=interface - # ) + vrf = VRF.objects.create(name="Ark B") + address = IPAddress.objects.create( + address="10.1.1.1/24", status=status_active, vrf=vrf, assigned_object=interface + ) peeringrole = models.PeeringRole.objects.create(name="Internal", slug="internal", color="333333") + external_peeringrole = models.PeeringRole.objects.create(name="External", slug="external", color="333334") asn_15521 = models.AutonomousSystem.objects.create( asn=15521, status=status_active, description="Hi ex Premium Internet AS!" @@ -136,11 +140,15 @@ def setUpTestData(cls): "role": peeringrole.pk, "description": "Telephone sanitizers", "enabled": True, + "import_policy": "BGP-IN", + "export_policy": "BGP-OUT", + "source_ip": address.pk, }, { "name": "Group B", "routing_instance": bgp_routing_instance.pk, "role": peeringrole.pk, + "extra_attributes": {"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}}, }, { "name": "Group C", @@ -150,11 +158,18 @@ def setUpTestData(cls): }, ] - # router_id_relation = Relationship.objects.get(slug="bgp_device_router_id") - # RelationshipAssociation.objects.create(relationship=router_id_relation, source=device, destination=cls.address) - - # asn_relation = Relationship.objects.get(slug="bgp_asn") - # RelationshipAssociation.objects.create(relationship=asn_relation, source=cls.asn, destination=device) + cls.update_data = { + "name": "Updated Group A", + "role": external_peeringrole.pk, + "description": "Updated telephone sanitizers", + "enabled": False, + "autonomous_system": asn_8545.pk, + "import_policy": "BGP-IN-v2", + "export_policy": "BGP-OUT-v2", + "source_ip": None, + "source_interface": interface.pk, + "extra_attributes": '{"key1": "value1", "key2": {"nested_key2": "nested_value2"}}', + } models.PeerGroup.objects.create(name="Group 1", role=peeringrole, routing_instance=bgp_routing_instance) models.PeerGroup.objects.create(name="Group 2", role=peeringrole, routing_instance=bgp_routing_instance) From d9ed3c4613d9a6bf4f1a6156bbd5b2ec67ee0ecf Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Mon, 15 May 2023 09:59:03 +0200 Subject: [PATCH 32/61] unittest: Disable peer endpoint update/create testcase. --- nautobot_bgp_models/tests/test_api.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nautobot_bgp_models/tests/test_api.py b/nautobot_bgp_models/tests/test_api.py index 2011e20a..3edb6de3 100644 --- a/nautobot_bgp_models/tests/test_api.py +++ b/nautobot_bgp_models/tests/test_api.py @@ -224,8 +224,13 @@ class PeerEndpointAPITestCase(APIViewTestCases.APIViewTestCase): # Nautobot testing doesn't correctly handle the API representation of a Status as a slug instead of a PK yet. validation_excluded_fields = ["status"] - # TODO(mzb): Fix object changelog issue (2!=1) - test_create_object = None + @skip("PeerEndpoint updates two objects") + def test_update_object(self): + pass + + @skip("PeerEndpoint creates two objects") + def test_create_object(self): + pass @classmethod def setUpTestData(cls): From afcb05d266abac20774c25a56a1dad4fed85ff07 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Tue, 16 May 2023 10:17:07 +0200 Subject: [PATCH 33/61] release: version 0.7.0 --- docs/admin/release_notes/version_0.7.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/admin/release_notes/version_0.7.md b/docs/admin/release_notes/version_0.7.md index 256f6f78..821e5160 100644 --- a/docs/admin/release_notes/version_0.7.md +++ b/docs/admin/release_notes/version_0.7.md @@ -11,3 +11,15 @@ ### Changed ### Fixed + +## [v0.7.0] - 2023-05-16 + +### Added + +### Changed +- [#73](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/73) - Documentation Update +- [#90](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/90) - Development environments updates + +### Fixed + +- [#99](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/99) - fix: allow read/write for extra attributes from API From b3657ec9cf423b9bf992f077231650502b177fac Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Tue, 16 May 2023 10:23:14 +0200 Subject: [PATCH 34/61] release: version 0.7.0 --- poetry.lock | 435 ++++++++++++++++++++++++------------------------- pyproject.toml | 2 +- 2 files changed, 218 insertions(+), 219 deletions(-) diff --git a/poetry.lock b/poetry.lock index ad149bef..84890f65 100644 --- a/poetry.lock +++ b/poetry.lock @@ -81,22 +81,25 @@ typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} [[package]] name = "attrs" -version = "22.2.0" +version = "23.1.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, - {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, ] +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + [package.extras] -cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] -tests = ["attrs[tests-no-zope]", "zope.interface"] -tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] [[package]] name = "bandit" @@ -136,37 +139,37 @@ files = [ [[package]] name = "black" -version = "23.1.0" +version = "23.3.0" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"}, - {file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"}, - {file = "black-23.1.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b"}, - {file = "black-23.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"}, - {file = "black-23.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074"}, - {file = "black-23.1.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27"}, - {file = "black-23.1.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648"}, - {file = "black-23.1.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958"}, - {file = "black-23.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a"}, - {file = "black-23.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481"}, - {file = "black-23.1.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad"}, - {file = "black-23.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8"}, - {file = "black-23.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24"}, - {file = "black-23.1.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6"}, - {file = "black-23.1.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd"}, - {file = "black-23.1.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580"}, - {file = "black-23.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468"}, - {file = "black-23.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753"}, - {file = "black-23.1.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651"}, - {file = "black-23.1.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06"}, - {file = "black-23.1.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739"}, - {file = "black-23.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9"}, - {file = "black-23.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555"}, - {file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"}, - {file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, + {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, + {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, + {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, + {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, + {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, + {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, + {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, + {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, + {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, + {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, + {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, + {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, + {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, ] [package.dependencies] @@ -255,14 +258,14 @@ zstd = ["zstandard"] [[package]] name = "certifi" -version = "2022.12.7" +version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, ] [[package]] @@ -605,35 +608,31 @@ toml = ["toml"] [[package]] name = "cryptography" -version = "39.0.2" +version = "40.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "cryptography-39.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:2725672bb53bb92dc7b4150d233cd4b8c59615cd8288d495eaa86db00d4e5c06"}, - {file = "cryptography-39.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:23df8ca3f24699167daf3e23e51f7ba7334d504af63a94af468f468b975b7dd7"}, - {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:eb40fe69cfc6f5cdab9a5ebd022131ba21453cf7b8a7fd3631f45bbf52bed612"}, - {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc0521cce2c1d541634b19f3ac661d7a64f9555135e9d8af3980965be717fd4a"}, - {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffd394c7896ed7821a6d13b24657c6a34b6e2650bd84ae063cf11ccffa4f1a97"}, - {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:e8a0772016feeb106efd28d4a328e77dc2edae84dfbac06061319fdb669ff828"}, - {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8f35c17bd4faed2bc7797d2a66cbb4f986242ce2e30340ab832e5d99ae60e011"}, - {file = "cryptography-39.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b49a88ff802e1993b7f749b1eeb31134f03c8d5c956e3c125c75558955cda536"}, - {file = "cryptography-39.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c682e736513db7d04349b4f6693690170f95aac449c56f97415c6980edef5"}, - {file = "cryptography-39.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:d7d84a512a59f4412ca8549b01f94be4161c94efc598bf09d027d67826beddc0"}, - {file = "cryptography-39.0.2-cp36-abi3-win32.whl", hash = "sha256:c43ac224aabcbf83a947eeb8b17eaf1547bce3767ee2d70093b461f31729a480"}, - {file = "cryptography-39.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:788b3921d763ee35dfdb04248d0e3de11e3ca8eb22e2e48fef880c42e1f3c8f9"}, - {file = "cryptography-39.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d15809e0dbdad486f4ad0979753518f47980020b7a34e9fc56e8be4f60702fac"}, - {file = "cryptography-39.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:50cadb9b2f961757e712a9737ef33d89b8190c3ea34d0fb6675e00edbe35d074"}, - {file = "cryptography-39.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:103e8f7155f3ce2ffa0049fe60169878d47a4364b277906386f8de21c9234aa1"}, - {file = "cryptography-39.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6236a9610c912b129610eb1a274bdc1350b5df834d124fa84729ebeaf7da42c3"}, - {file = "cryptography-39.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e944fe07b6f229f4c1a06a7ef906a19652bdd9fd54c761b0ff87e83ae7a30354"}, - {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:35d658536b0a4117c885728d1a7032bdc9a5974722ae298d6c533755a6ee3915"}, - {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:30b1d1bfd00f6fc80d11300a29f1d8ab2b8d9febb6ed4a38a76880ec564fae84"}, - {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e029b844c21116564b8b61216befabca4b500e6816fa9f0ba49527653cae2108"}, - {file = "cryptography-39.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fa507318e427169ade4e9eccef39e9011cdc19534f55ca2f36ec3f388c1f70f3"}, - {file = "cryptography-39.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8bc0008ef798231fac03fe7d26e82d601d15bd16f3afaad1c6113771566570f3"}, - {file = "cryptography-39.0.2.tar.gz", hash = "sha256:bc5b871e977c8ee5a1bbc42fa8d19bcc08baf0c51cbf1586b0e87a2694dde42f"}, + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, + {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, + {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, + {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, ] [package.dependencies] @@ -642,10 +641,10 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"] +pep8test = ["black", "check-manifest", "mypy", "ruff"] sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"] +test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] test-randomorder = ["pytest-randomly"] tox = ["tox"] @@ -678,14 +677,14 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "django" -version = "3.2.18" +version = "3.2.19" description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "Django-3.2.18-py3-none-any.whl", hash = "sha256:4d492d9024c7b3dfababf49f94511ab6a58e2c9c3c7207786f1ba4eb77750706"}, - {file = "Django-3.2.18.tar.gz", hash = "sha256:08208dfe892eb64fff073ca743b3b952311104f939e7f6dae954fe72dcc533ba"}, + {file = "Django-3.2.19-py3-none-any.whl", hash = "sha256:21cc991466245d659ab79cb01204f9515690f8dae00e5eabde307f14d24d4d7d"}, + {file = "Django-3.2.19.tar.gz", hash = "sha256:031365bae96814da19c10706218c44dff3b654cc4de20a98bd2d29b9bde469f0"}, ] [package.dependencies] @@ -1143,14 +1142,14 @@ sidecar = ["drf-spectacular-sidecar"] [[package]] name = "drf-spectacular-sidecar" -version = "2023.3.1" +version = "2023.5.1" description = "Serve self-contained distribution builds of Swagger UI and Redoc with Django" category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "drf-spectacular-sidecar-2023.3.1.tar.gz", hash = "sha256:ceb78fd59971bb79e90de38bf89afa50a60b043953f72b3cdeb4ca6a34623f92"}, - {file = "drf_spectacular_sidecar-2023.3.1-py3-none-any.whl", hash = "sha256:2b5ea98d976a4ba023d03cd9dfc2506892e0f26e2ba2869b58ddf344ab69f40f"}, + {file = "drf-spectacular-sidecar-2023.5.1.tar.gz", hash = "sha256:58358215fee6c4634d77335d4c341b8132dc0847b282fb2fe4b22530dc2a56ca"}, + {file = "drf_spectacular_sidecar-2023.5.1-py3-none-any.whl", hash = "sha256:10ab069a3475f763acbae76414ee80fc67a42c00394918777996bbfa9239f155"}, ] [package.dependencies] @@ -1362,23 +1361,20 @@ six = ">=1.12" [[package]] name = "griffe" -version = "0.25.5" +version = "0.27.5" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "griffe-0.25.5-py3-none-any.whl", hash = "sha256:1fb9edff48e66d4873014a2ebf21aca5f271d0006a4c937826e3cf592ffb3706"}, - {file = "griffe-0.25.5.tar.gz", hash = "sha256:11ea3403ef0560a1cbcf7f302eb5d21cf4c1d8ed3f8a16a75aa9f6f458caf3f1"}, + {file = "griffe-0.27.5-py3-none-any.whl", hash = "sha256:15b48fc3cebfc1c1a1a2f6e8177f6644a4a54517322e08e224fdf671454b34d7"}, + {file = "griffe-0.27.5.tar.gz", hash = "sha256:96fbc7a264bdb32b4da227bed6a16f2509e028a12d7471dbb48c2785bb01817f"}, ] [package.dependencies] cached-property = {version = "*", markers = "python_version < \"3.8\""} colorama = ">=0.4" -[package.extras] -async = ["aiofiles (>=0.7,<1.0)"] - [[package]] name = "idna" version = "3.4" @@ -1445,14 +1441,14 @@ files = [ [[package]] name = "invoke" -version = "2.0.0" +version = "2.1.2" description = "Pythonic task execution" category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "invoke-2.0.0-py3-none-any.whl", hash = "sha256:a860582bcf7a4b336fe18ef53937f0f28cec1c0053ffa767c2fcf7ba0b850f59"}, - {file = "invoke-2.0.0.tar.gz", hash = "sha256:7ab5dd9cd76b787d560a78b1a9810d252367ab595985c50612702be21d671dd7"}, + {file = "invoke-2.1.2-py3-none-any.whl", hash = "sha256:bfc904df1c9e9fe1a881933de661fe054b8db616ff2c4cf78e00407fe473ba5d"}, + {file = "invoke-2.1.2.tar.gz", hash = "sha256:a6cc1f06f75bacd0b1e11488fa3bf3e62f85e31f62e2c0172188613ba5b070e2"}, ] [[package]] @@ -1888,14 +1884,14 @@ files = [ [[package]] name = "nautobot" -version = "1.5.14" +version = "1.5.16" description = "Source of truth and network automation platform." category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "nautobot-1.5.14-py3-none-any.whl", hash = "sha256:8ea60d938b6d746b6791f986d1110aeadea8d70032f46a0ff747994af81250e4"}, - {file = "nautobot-1.5.14.tar.gz", hash = "sha256:4ead01f85ad9179a3523d233a4da20e8ad15250fa34b93ca49adc8b8318b55ac"}, + {file = "nautobot-1.5.16-py3-none-any.whl", hash = "sha256:9ca3c5e277377155549ffe5a3c2b886ee148c1639fced438eb4f08ba8f7bcec1"}, + {file = "nautobot-1.5.16.tar.gz", hash = "sha256:36b73ffc8b63c2e2667cbc40b05137fd9291335d652adb088c364f546add9adf"}, ] [package.dependencies] @@ -1997,14 +1993,14 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "packaging" -version = "23.0" +version = "23.1" description = "Core utilities for Python packages" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, - {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] [[package]] @@ -2108,22 +2104,22 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa [[package]] name = "platformdirs" -version = "3.1.1" +version = "3.5.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"}, - {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"}, + {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, + {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, ] [package.dependencies] -typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""} [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "prometheus-client" @@ -2174,83 +2170,74 @@ wcwidth = "*" [[package]] name = "psycopg2-binary" -version = "2.9.5" +version = "2.9.6" description = "psycopg2 - Python-PostgreSQL Database Adapter" category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "psycopg2-binary-2.9.5.tar.gz", hash = "sha256:33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:0775d6252ccb22b15da3b5d7adbbf8cfe284916b14b6dc0ff503a23edb01ee85"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ec46ed947801652c9643e0b1dc334cfb2781232e375ba97312c2fc256597632"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3520d7af1ebc838cc6084a3281145d5cd5bdd43fdef139e6db5af01b92596cb7"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cbc554ba47ecca8cd3396ddaca85e1ecfe3e48dd57dc5e415e59551affe568e"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:5d28ecdf191db558d0c07d0f16524ee9d67896edf2b7990eea800abeb23ebd61"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:b9c33d4aef08dfecbd1736ceab8b7b3c4358bf10a0121483e5cd60d3d308cc64"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:05b3d479425e047c848b9782cd7aac9c6727ce23181eb9647baf64ffdfc3da41"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1e491e6489a6cb1d079df8eaa15957c277fdedb102b6a68cfbf40c4994412fd0"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:9e32cedc389bcb76d9f24ea8a012b3cb8385ee362ea437e1d012ffaed106c17d"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46850a640df62ae940e34a163f72e26aca1f88e2da79148e1862faaac985c302"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-win32.whl", hash = "sha256:3d790f84201c3698d1bfb404c917f36e40531577a6dda02e45ba29b64d539867"}, - {file = "psycopg2_binary-2.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:1764546ffeaed4f9428707be61d68972eb5ede81239b46a45843e0071104d0dd"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_10_9_universal2.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:426c2ae999135d64e6a18849a7d1ad0e1bd007277e4a8f4752eaa40a96b550ff"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cf1d44e710ca3a9ce952bda2855830fe9f9017ed6259e01fcd71ea6287565f5"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:024030b13bdcbd53d8a93891a2cf07719715724fc9fee40243f3bd78b4264b8f"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcda1c84a1c533c528356da5490d464a139b6e84eb77cc0b432e38c5c6dd7882"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:2ef892cabdccefe577088a79580301f09f2a713eb239f4f9f62b2b29cafb0577"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:af0516e1711995cb08dc19bbd05bec7dbdebf4185f68870595156718d237df3e"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e67b3c26e9b6d37b370c83aa790bbc121775c57bfb096c2e77eacca25fd0233b"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5fc447058d083b8c6ac076fc26b446d44f0145308465d745fba93a28c14c9e32"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d892bfa1d023c3781a3cab8dd5af76b626c483484d782e8bd047c180db590e4c"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-win32.whl", hash = "sha256:2abccab84d057723d2ca8f99ff7b619285d40da6814d50366f61f0fc385c3903"}, - {file = "psycopg2_binary-2.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:bef7e3f9dc6f0c13afdd671008534be5744e0e682fb851584c8c3a025ec09720"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:6e63814ec71db9bdb42905c925639f319c80e7909fb76c3b84edc79dadef8d60"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:212757ffcecb3e1a5338d4e6761bf9c04f750e7d027117e74aa3cd8a75bb6fbd"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f8a9bcab7b6db2e3dbf65b214dfc795b4c6b3bb3af922901b6a67f7cb47d5f8"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:56b2957a145f816726b109ee3d4e6822c23f919a7d91af5a94593723ed667835"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:70831e03bd53702c941da1a1ad36c17d825a24fbb26857b40913d58df82ec18b"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:dbc332beaf8492b5731229a881807cd7b91b50dbbbaf7fe2faf46942eda64a24"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:2d964eb24c8b021623df1c93c626671420c6efadbdb8655cb2bd5e0c6fa422ba"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:95076399ec3b27a8f7fa1cc9a83417b1c920d55cf7a97f718a94efbb96c7f503"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-win32.whl", hash = "sha256:3fc33295cfccad697a97a76dec3f1e94ad848b7b163c3228c1636977966b51e2"}, - {file = "psycopg2_binary-2.9.5-cp36-cp36m-win_amd64.whl", hash = "sha256:02551647542f2bf89073d129c73c05a25c372fc0a49aa50e0de65c3c143d8bd0"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:63e318dbe52709ed10d516a356f22a635e07a2e34c68145484ed96a19b0c4c68"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7e518a0911c50f60313cb9e74a169a65b5d293770db4770ebf004245f24b5c5"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9d38a4656e4e715d637abdf7296e98d6267df0cc0a8e9a016f8ba07e4aa3eeb"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:68d81a2fe184030aa0c5c11e518292e15d342a667184d91e30644c9d533e53e1"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:7ee3095d02d6f38bd7d9a5358fcc9ea78fcdb7176921528dd709cc63f40184f5"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:46512486be6fbceef51d7660dec017394ba3e170299d1dc30928cbedebbf103a"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b911dfb727e247340d36ae20c4b9259e4a64013ab9888ccb3cbba69b77fd9636"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:422e3d43b47ac20141bc84b3d342eead8d8099a62881a501e97d15f6addabfe9"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c5682a45df7d9642eff590abc73157c887a68f016df0a8ad722dcc0f888f56d7"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-win32.whl", hash = "sha256:b8104f709590fff72af801e916817560dbe1698028cd0afe5a52d75ceb1fce5f"}, - {file = "psycopg2_binary-2.9.5-cp37-cp37m-win_amd64.whl", hash = "sha256:7b3751857da3e224f5629400736a7b11e940b5da5f95fa631d86219a1beaafec"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:043a9fd45a03858ff72364b4b75090679bd875ee44df9c0613dc862ca6b98460"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9ffdc51001136b699f9563b1c74cc1f8c07f66ef7219beb6417a4c8aaa896c28"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15ba5982c177bc4b23a7940c7e4394197e2d6a424a2d282e7c236b66da6d896"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc85b3777068ed30aff8242be2813038a929f2084f69e43ef869daddae50f6ee"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:215d6bf7e66732a514f47614f828d8c0aaac9a648c46a831955cb103473c7147"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:7d07f552d1e412f4b4e64ce386d4c777a41da3b33f7098b6219012ba534fb2c2"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a0adef094c49f242122bb145c3c8af442070dc0e4312db17e49058c1702606d4"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:00475004e5ed3e3bf5e056d66e5dcdf41a0dc62efcd57997acd9135c40a08a50"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7d88db096fa19d94f433420eaaf9f3c45382da2dd014b93e4bf3215639047c16"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:902844f9c4fb19b17dfa84d9e2ca053d4a4ba265723d62ea5c9c26b38e0aa1e6"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-win32.whl", hash = "sha256:4e7904d1920c0c89105c0517dc7e3f5c20fb4e56ba9cdef13048db76947f1d79"}, - {file = "psycopg2_binary-2.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:a36a0e791805aa136e9cbd0ffa040d09adec8610453ee8a753f23481a0057af5"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:25382c7d174c679ce6927c16b6fbb68b10e56ee44b1acb40671e02d29f2fce7c"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9c38d3869238e9d3409239bc05bc27d6b7c99c2a460ea337d2814b35fb4fea1b"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c6527c8efa5226a9e787507652dd5ba97b62d29b53c371a85cd13f957fe4d42"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e59137cdb970249ae60be2a49774c6dfb015bd0403f05af1fe61862e9626642d"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:d4c7b3a31502184e856df1f7bbb2c3735a05a8ce0ade34c5277e1577738a5c91"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:b9a794cef1d9c1772b94a72eec6da144c18e18041d294a9ab47669bc77a80c1d"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5254cbd4f4855e11cebf678c1a848a3042d455a22a4ce61349c36aafd4c2267"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c5e65c6ac0ae4bf5bef1667029f81010b6017795dcb817ba5c7b8a8d61fab76f"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:74eddec4537ab1f701a1647214734bc52cee2794df748f6ae5908e00771f180a"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-win32.whl", hash = "sha256:937880290775033a743f4836aa253087b85e62784b63fd099ee725d567a48aa1"}, - {file = "psycopg2_binary-2.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:484405b883630f3e74ed32041a87456c5e0e63a8e3429aa93e8714c366d62bd1"}, + {file = "psycopg2-binary-2.9.6.tar.gz", hash = "sha256:1f64dcfb8f6e0c014c7f55e51c9759f024f70ea572fbdef123f85318c297947c"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d26e0342183c762de3276cca7a530d574d4e25121ca7d6e4a98e4f05cb8e4df7"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c48d8f2db17f27d41fb0e2ecd703ea41984ee19362cbce52c097963b3a1b4365"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe9dc0a884a8848075e576c1de0290d85a533a9f6e9c4e564f19adf8f6e54a7"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a76e027f87753f9bd1ab5f7c9cb8c7628d1077ef927f5e2446477153a602f2c"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6460c7a99fc939b849431f1e73e013d54aa54293f30f1109019c56a0b2b2ec2f"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae102a98c547ee2288637af07393dd33f440c25e5cd79556b04e3fca13325e5f"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9972aad21f965599ed0106f65334230ce826e5ae69fda7cbd688d24fa922415e"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a40c00dbe17c0af5bdd55aafd6ff6679f94a9be9513a4c7e071baf3d7d22a70"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:cacbdc5839bdff804dfebc058fe25684cae322987f7a38b0168bc1b2df703fb1"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f0438fa20fb6c7e202863e0d5ab02c246d35efb1d164e052f2f3bfe2b152bd0"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-win32.whl", hash = "sha256:b6c8288bb8a84b47e07013bb4850f50538aa913d487579e1921724631d02ea1b"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:61b047a0537bbc3afae10f134dc6393823882eb263088c271331602b672e52e9"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:964b4dfb7c1c1965ac4c1978b0f755cc4bd698e8aa2b7667c575fb5f04ebe06b"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afe64e9b8ea66866a771996f6ff14447e8082ea26e675a295ad3bdbffdd72afb"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15e2ee79e7cf29582ef770de7dab3d286431b01c3bb598f8e05e09601b890081"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa74c903a3c1f0d9b1c7e7b53ed2d929a4910e272add6700c38f365a6002820"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b83456c2d4979e08ff56180a76429263ea254c3f6552cd14ada95cff1dec9bb8"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0645376d399bfd64da57148694d78e1f431b1e1ee1054872a5713125681cf1be"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e99e34c82309dd78959ba3c1590975b5d3c862d6f279f843d47d26ff89d7d7e1"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ea29fc3ad9d91162c52b578f211ff1c931d8a38e1f58e684c45aa470adf19e2"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4ac30da8b4f57187dbf449294d23b808f8f53cad6b1fc3623fa8a6c11d176dd0"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e78e6e2a00c223e164c417628572a90093c031ed724492c763721c2e0bc2a8df"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-win32.whl", hash = "sha256:1876843d8e31c89c399e31b97d4b9725a3575bb9c2af92038464231ec40f9edb"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b4b24f75d16a89cc6b4cdff0eb6a910a966ecd476d1e73f7ce5985ff1328e9a6"}, + {file = "psycopg2_binary-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:498807b927ca2510baea1b05cc91d7da4718a0f53cb766c154c417a39f1820a0"}, + {file = "psycopg2_binary-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0d236c2825fa656a2d98bbb0e52370a2e852e5a0ec45fc4f402977313329174d"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:34b9ccdf210cbbb1303c7c4db2905fa0319391bd5904d32689e6dd5c963d2ea8"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d2222e61f313c4848ff05353653bf5f5cf6ce34df540e4274516880d9c3763"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30637a20623e2a2eacc420059be11527f4458ef54352d870b8181a4c3020ae6b"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8122cfc7cae0da9a3077216528b8bb3629c43b25053284cc868744bfe71eb141"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38601cbbfe600362c43714482f43b7c110b20cb0f8172422c616b09b85a750c5"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c7e62ab8b332147a7593a385d4f368874d5fe4ad4e341770d4983442d89603e3"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2ab652e729ff4ad76d400df2624d223d6e265ef81bb8aa17fbd63607878ecbee"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c83a74b68270028dc8ee74d38ecfaf9c90eed23c8959fca95bd703d25b82c88e"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d4e6036decf4b72d6425d5b29bbd3e8f0ff1059cda7ac7b96d6ac5ed34ffbacd"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:a8c28fd40a4226b4a84bdf2d2b5b37d2c7bd49486b5adcc200e8c7ec991dfa7e"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:51537e3d299be0db9137b321dfb6a5022caaab275775680e0c3d281feefaca6b"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4499e0a83b7b7edcb8dabecbd8501d0d3a5ef66457200f77bde3d210d5debb"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e13a5a2c01151f1208d5207e42f33ba86d561b7a89fca67c700b9486a06d0e2"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e0f754d27fddcfd74006455b6e04e6705d6c31a612ec69ddc040a5468e44b4e"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d57c3fd55d9058645d26ae37d76e61156a27722097229d32a9e73ed54819982a"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71f14375d6f73b62800530b581aed3ada394039877818b2d5f7fc77e3bb6894d"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:441cc2f8869a4f0f4bb408475e5ae0ee1f3b55b33f350406150277f7f35384fc"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:65bee1e49fa6f9cf327ce0e01c4c10f39165ee76d35c846ade7cb0ec6683e303"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:af335bac6b666cc6aea16f11d486c3b794029d9df029967f9938a4bed59b6a19"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cfec476887aa231b8548ece2e06d28edc87c1397ebd83922299af2e051cf2827"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65c07febd1936d63bfde78948b76cd4c2a411572a44ac50719ead41947d0f26b"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-win32.whl", hash = "sha256:4dfb4be774c4436a4526d0c554af0cc2e02082c38303852a36f6456ece7b3503"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:02c6e3cf3439e213e4ee930308dc122d6fb4d4bea9aef4a12535fbd605d1a2fe"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9182eb20f41417ea1dd8e8f7888c4d7c6e805f8a7c98c1081778a3da2bee3e4"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a6979cf527e2603d349a91060f428bcb135aea2be3201dff794813256c274f1"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8338a271cb71d8da40b023a35d9c1e919eba6cbd8fa20a54b748a332c355d896"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ed340d2b858d6e6fb5083f87c09996506af483227735de6964a6100b4e6a54"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f81e65376e52f03422e1fb475c9514185669943798ed019ac50410fb4c4df232"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb13af3c5dd3a9588000910178de17010ebcccd37b4f9794b00595e3a8ddad3"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4c727b597c6444a16e9119386b59388f8a424223302d0c06c676ec8b4bc1f963"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d67fbdaf177da06374473ef6f7ed8cc0a9dc640b01abfe9e8a2ccb1b1402c1f"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0892ef645c2fabb0c75ec32d79f4252542d0caec1d5d949630e7d242ca4681a3"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:02c0f3757a4300cf379eb49f543fb7ac527fb00144d39246ee40e1df684ab514"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-win32.whl", hash = "sha256:c3dba7dab16709a33a847e5cd756767271697041fbe3fe97c215b1fc1f5c9848"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"}, ] [[package]] @@ -2350,14 +2337,14 @@ files = [ [[package]] name = "pygments" -version = "2.14.0" +version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, - {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, + {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, + {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, ] [package.extras] @@ -2365,16 +2352,19 @@ plugins = ["importlib-metadata"] [[package]] name = "pyjwt" -version = "2.6.0" +version = "2.7.0" description = "JSON Web Token implementation in Python" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "PyJWT-2.6.0-py3-none-any.whl", hash = "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14"}, - {file = "PyJWT-2.6.0.tar.gz", hash = "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd"}, + {file = "PyJWT-2.7.0-py3-none-any.whl", hash = "sha256:ba2b425b15ad5ef12f200dc67dd56af4e26de2331f965c5439994dad075876e1"}, + {file = "PyJWT-2.7.0.tar.gz", hash = "sha256:bd6ca4a3c4285c1a2d4349e5a035fdf8fb94e04ccd0fcbe6ba289dae9cc3e074"}, ] +[package.dependencies] +typing-extensions = {version = "*", markers = "python_version <= \"3.7\""} + [package.extras] crypto = ["cryptography (>=3.4.0)"] dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] @@ -2428,14 +2418,14 @@ with-django = ["Django"] [[package]] name = "pylint-plugin-utils" -version = "0.7" +version = "0.8.1" description = "Utilities and helpers for writing Pylint plugins" category = "dev" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7,<4.0" files = [ - {file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"}, - {file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"}, + {file = "pylint_plugin_utils-0.8.1-py3-none-any.whl", hash = "sha256:8d753118eb4189b0f5d07483ab6bbc5770dcd52799ceb6456b0e96309218c80c"}, + {file = "pylint_plugin_utils-0.8.1.tar.gz", hash = "sha256:a595517d238d2ebe586fd867325cc656d4fac8d22b99421ff4cfb51b8c823a93"}, ] [package.dependencies] @@ -2443,14 +2433,14 @@ pylint = ">=1.7" [[package]] name = "pymdown-extensions" -version = "9.10" +version = "10.0.1" description = "Extension pack for Python Markdown." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pymdown_extensions-9.10-py3-none-any.whl", hash = "sha256:31eaa76ce6f96aabfcea98787c2fff2c5c0611b20a53a94213970cfbf05f02b8"}, - {file = "pymdown_extensions-9.10.tar.gz", hash = "sha256:562c38eee4ce3f101ce631b804bfc2177a8a76c7e4dc908871fb6741a90257a7"}, + {file = "pymdown_extensions-10.0.1-py3-none-any.whl", hash = "sha256:ae66d84013c5d027ce055693e09a4628b67e9dec5bce05727e45b0918e36f274"}, + {file = "pymdown_extensions-10.0.1.tar.gz", hash = "sha256:b44e1093a43b8a975eae17b03c3a77aad4681b3b56fce60ce746dbef1944c8cb"}, ] [package.dependencies] @@ -2549,14 +2539,14 @@ postgresql = ["psycopg2"] [[package]] name = "pytz" -version = "2022.7.1" +version = "2023.3" description = "World timezone definitions, modern and historical" category = "main" optional = false python-versions = "*" files = [ - {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, - {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] [[package]] @@ -2672,18 +2662,18 @@ pyyaml = "*" [[package]] name = "redis" -version = "4.5.3" +version = "4.5.5" description = "Python client for Redis database and key-value store" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "redis-4.5.3-py3-none-any.whl", hash = "sha256:7df17a0a2b72a4c8895b462dd07616c51b1dcb48fdd7ecb7b6f4bf39ecb2e94e"}, - {file = "redis-4.5.3.tar.gz", hash = "sha256:56732e156fe31801c4f43396bd3ca0c2a7f6f83d7936798531b9848d103381aa"}, + {file = "redis-4.5.5-py3-none-any.whl", hash = "sha256:77929bc7f5dab9adf3acba2d3bb7d7658f1e0c2f1cafe7eb36434e751c471119"}, + {file = "redis-4.5.5.tar.gz", hash = "sha256:dc87a0bdef6c8bfe1ef1e1c40be7034390c2ae02d92dcd0c7ca1729443899880"}, ] [package.dependencies] -async-timeout = {version = ">=4.0.2", markers = "python_version < \"3.11\""} +async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} typing-extensions = {version = "*", markers = "python_version < \"3.8\""} @@ -2693,21 +2683,21 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "requests" -version = "2.28.2" +version = "2.30.0" description = "Python HTTP for Humans." category = "main" optional = false -python-versions = ">=3.7, <4" +python-versions = ">=3.7" files = [ - {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, - {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, + {file = "requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"}, + {file = "requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" +urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] @@ -2734,14 +2724,14 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"] [[package]] name = "rich" -version = "13.3.2" +version = "13.3.5" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.2-py3-none-any.whl", hash = "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f"}, - {file = "rich-13.3.2.tar.gz", hash = "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001"}, + {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, + {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, ] [package.dependencies] @@ -2754,14 +2744,14 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rq" -version = "1.13.0" +version = "1.14.1" description = "RQ is a simple, lightweight, library for creating background jobs, and processing them." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "rq-1.13.0-py2.py3-none-any.whl", hash = "sha256:621966d7cbf96d5609557a4bd3fd77f749d6d10997d2e353a3e89a14e08eea16"}, - {file = "rq-1.13.0.tar.gz", hash = "sha256:5bb0380a17597200520731686766bb72faf16ebffb602663560d91ea2c9e7103"}, + {file = "rq-1.14.1-py2.py3-none-any.whl", hash = "sha256:37e003db1da205e08db6cc4653b7c6ccfd9292000954240308abfce2ebde43ba"}, + {file = "rq-1.14.1.tar.gz", hash = "sha256:5fb86038922ddd76eb2d9aa0adeec6dcf64f159dbbe730b26358b1417120dd44"}, ] [package.dependencies] @@ -2770,18 +2760,18 @@ redis = ">=3.5.0" [[package]] name = "ruamel-yaml" -version = "0.17.21" +version = "0.17.26" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" category = "main" optional = false python-versions = ">=3" files = [ - {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, - {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, + {file = "ruamel.yaml-0.17.26-py3-none-any.whl", hash = "sha256:25d0ee82a0a9a6f44683dcf8c282340def4074a4562f3a24f55695bb254c1693"}, + {file = "ruamel.yaml-0.17.26.tar.gz", hash = "sha256:baa2d0a5aad2034826c439ce61c142c07082b76f4791d54145e131206e998059"}, ] [package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""} +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.12\""} [package.extras] docs = ["ryd"] @@ -2846,14 +2836,14 @@ files = [ [[package]] name = "setuptools" -version = "67.6.0" +version = "67.7.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.6.0-py3-none-any.whl", hash = "sha256:b78aaa36f6b90a074c1fa651168723acbf45d14cb1196b6f02c0fd07f17623b2"}, - {file = "setuptools-67.6.0.tar.gz", hash = "sha256:2ee892cd5f29f3373097f5a814697e397cf3ce313616df0af11231e2ad118077"}, + {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, + {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, ] [package.extras] @@ -2930,14 +2920,14 @@ social-auth-core = ">=4.1.0" [[package]] name = "social-auth-core" -version = "4.4.0" +version = "4.4.2" description = "Python social authentication made simple." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "social-auth-core-4.4.0.tar.gz", hash = "sha256:359f6be5bb2d4caef6500eb6e1b40821a40dde9add8d339d539b1adbba2c9bf7"}, - {file = "social_auth_core-4.4.0-py3-none-any.whl", hash = "sha256:89536f218fa1a769caeaa56ef90f965ea50a81b9a7e3e5a2c5a61b832df11bde"}, + {file = "social-auth-core-4.4.2.tar.gz", hash = "sha256:9791d7c7aee2ac8517fe7a2ea2f942a8a5492b3a4ccb44a9b0dacc87d182f2aa"}, + {file = "social_auth_core-4.4.2-py3-none-any.whl", hash = "sha256:ea7a19c46b791b767e95f467881b53c5fd0d1efb40048d9ed3dbc46daa05c954"}, ] [package.dependencies] @@ -2958,16 +2948,21 @@ saml = ["python3-saml (>=1.5.0)"] [[package]] name = "sqlparse" -version = "0.4.3" +version = "0.4.4" description = "A non-validating SQL parser." category = "main" optional = false python-versions = ">=3.5" files = [ - {file = "sqlparse-0.4.3-py3-none-any.whl", hash = "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34"}, - {file = "sqlparse-0.4.3.tar.gz", hash = "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268"}, + {file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"}, + {file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"}, ] +[package.extras] +dev = ["build", "flake8"] +doc = ["sphinx"] +test = ["pytest", "pytest-cov"] + [[package]] name = "stevedore" version = "3.5.2" @@ -3097,20 +3092,21 @@ files = [ [[package]] name = "urllib3" -version = "1.26.15" +version = "2.0.2" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.7" files = [ - {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, - {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, + {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "vine" @@ -3263,19 +3259,22 @@ files = [ [[package]] name = "yamllint" -version = "1.30.0" +version = "1.31.0" description = "A linter for YAML files." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "yamllint-1.30.0.tar.gz", hash = "sha256:4f58f323aedda16189a489d183ecc25c66d7a9cc0fe88f61b650fef167b13190"}, + {file = "yamllint-1.31.0-py3-none-any.whl", hash = "sha256:15f4bdb645e6a4a0a22fe5415bc38b4a934c51419b30104896d2f3f95e329185"}, + {file = "yamllint-1.31.0.tar.gz", hash = "sha256:2d83f1d12f733e162a87e06b176149d7bb9c5bae4a9e5fce1c771d7f703f7a65"}, ] [package.dependencies] pathspec = ">=0.5.3" pyyaml = "*" -setuptools = "*" + +[package.extras] +dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] [[package]] name = "zipp" diff --git a/pyproject.toml b/pyproject.toml index 1898ddf7..c28491f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-bgp-models" -version = "0.7.0b1" +version = "0.7.0" description = "Nautobot BGP Models Plugin" authors = ["Network to Code, LLC "] From 088f801e988d3f9ff233d0e8660863eb4361df9e Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Tue, 16 May 2023 11:10:51 +0200 Subject: [PATCH 35/61] release: version 0.7.0 - updating gh token --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6fa80010..5ac8ee38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -193,7 +193,7 @@ jobs: - name: "Upload binaries to release" uses: "svenstaro/upload-release-action@v2" with: - repo_token: "${{ secrets.NTC_GITHUB_TOKEN }}" + repo_token: "${{ secrets.GH_NAUTOBOT_BOT_TOKEN }}" file: "dist/*" tag: "${{ github.ref }}" overwrite: true From 146320390055573f71043173caa0fbd92fca77c7 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Wed, 17 May 2023 12:32:09 +0200 Subject: [PATCH 36/61] fix: - adds basic BGPRoutingInstanceAPITestCase test cases - nested serializer for BGP Routing Instance model - adds missing extra_attributes on BGP Routing Instance model --- nautobot_bgp_models/api/nested_serializers.py | 6 +- nautobot_bgp_models/api/serializers.py | 14 ++- nautobot_bgp_models/tests/test_api.py | 87 +++++++++++++++++++ 3 files changed, 100 insertions(+), 7 deletions(-) diff --git a/nautobot_bgp_models/api/nested_serializers.py b/nautobot_bgp_models/api/nested_serializers.py index a5a05620..7edfa96d 100644 --- a/nautobot_bgp_models/api/nested_serializers.py +++ b/nautobot_bgp_models/api/nested_serializers.py @@ -14,7 +14,7 @@ "NestedPeerEndpointSerializer", "NestedPeeringSerializer", "NestedAddressFamilySerializer", - "NestedRoutingInstanceSerializer", + "NestedBGPRoutingInstanceSerializer", ) @@ -68,7 +68,7 @@ class Meta: fields = ["id", "url"] -class NestedRoutingInstanceSerializer(WritableNestedSerializer): +class NestedBGPRoutingInstanceSerializer(WritableNestedSerializer): """Nested/brief serializer for PeerEndpoint.""" url = serializers.HyperlinkedIdentityField( @@ -77,7 +77,7 @@ class NestedRoutingInstanceSerializer(WritableNestedSerializer): class Meta: model = models.BGPRoutingInstance - fields = ["id", "url"] + fields = ["display", "id", "url"] class NestedPeeringSerializer(WritableNestedSerializer): diff --git a/nautobot_bgp_models/api/serializers.py b/nautobot_bgp_models/api/serializers.py index e0f3d191..ed03ce00 100644 --- a/nautobot_bgp_models/api/serializers.py +++ b/nautobot_bgp_models/api/serializers.py @@ -116,7 +116,7 @@ class PeerGroupSerializer( source_ip = NestedIPAddressSerializer(required=False, allow_null=True) # noqa: F405 source_interface = NestedInterfaceSerializer(required=False, allow_null=True) # noqa: F405 - routing_instance = NestedRoutingInstanceSerializer(required=True) # noqa: F405 + routing_instance = NestedBGPRoutingInstanceSerializer(required=True) # noqa: F405 autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 @@ -160,7 +160,7 @@ class PeerEndpointSerializer( peer = NestedPeerEndpointSerializer(required=False, allow_null=True) # noqa: F405 peering = NestedPeeringSerializer(required=True, allow_null=True) # noqa: F405 peer_group = NestedPeerGroupSerializer(required=False, allow_null=True) # noqa: F405 - routing_instance = NestedRoutingInstanceSerializer(required=False, allow_null=True) # noqa: F405 + routing_instance = NestedBGPRoutingInstanceSerializer(required=False, allow_null=True) # noqa: F405 autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 secret = NestedSecretSerializer(required=False, allow_null=True) @@ -181,6 +181,7 @@ class Meta: "secret", "tags", "enabled", + "extra_attributes", ] def create(self, validated_data): @@ -203,7 +204,11 @@ def update(self, instance, validated_data): return result -class BGPRoutingInstanceSerializer(CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin): +class BGPRoutingInstanceSerializer( + CustomFieldModelSerializerMixin, + ExtraAttributesSerializerMixin, + RelationshipModelSerializerMixin +): """REST API serializer for Peering records.""" url = serializers.HyperlinkedIdentityField( @@ -228,6 +233,7 @@ class Meta: "router_id", "autonomous_system", "endpoints", + "extra_attributes", ] @@ -256,7 +262,7 @@ class AddressFamilySerializer( url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:addressfamily-detail") - routing_instance = NestedRoutingInstanceSerializer(required=True) # noqa: F405 + routing_instance = NestedBGPRoutingInstanceSerializer(required=True) # noqa: F405 vrf = NestedVRFSerializer(required=False, allow_null=True) diff --git a/nautobot_bgp_models/tests/test_api.py b/nautobot_bgp_models/tests/test_api.py index 3edb6de3..7de570e3 100644 --- a/nautobot_bgp_models/tests/test_api.py +++ b/nautobot_bgp_models/tests/test_api.py @@ -80,6 +80,93 @@ def test_notes_url_on_object(self): pass +class BGPRoutingInstanceAPITestCase(APIViewTestCases.APIViewTestCase): + """Test the BGPRoutingInstance API.""" + + model = models.BGPRoutingInstance + view_namespace = "plugins-api:nautobot_bgp_models" + brief_fields = ["display", "id", "url"] + bulk_update_data = { + "description": "Glenn was here.", + } + + # Nautobot testing doesn't correctly handle the API representation of a Status as a slug instead of a PK yet. + validation_excluded_fields = ["status"] + + @classmethod + def setUpTestData(cls): # pylint: disable=too-many-locals + status_active = Status.objects.get(slug="active") + status_active.content_types.add(ContentType.objects.get_for_model(models.AutonomousSystem)) + + manufacturer = Manufacturer.objects.create(name="Cisco", slug="cisco") + devicetype = DeviceType.objects.create(manufacturer=manufacturer, model="CSR 1000V", slug="csr1000v") + site = Site.objects.create(name="Site 1", slug="site-1") + devicerole = DeviceRole.objects.create(name="Router", slug="router", color="ff0000") + device_1 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name="Device 1", site=site, status=status_active + ) + device_2 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name="Device 2", site=site, status=status_active + ) + device_3 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name="Device 3", site=site, status=status_active + ) + device_4 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name="Device 4", site=site, status=status_active + ) + interface = Interface.objects.create(device=device_1, name="Loopback1", type=InterfaceTypeChoices.TYPE_VIRTUAL) + + vrf = VRF.objects.create(name="Ark B") + address = IPAddress.objects.create( + address="10.1.1.1/24", status=status_active, vrf=vrf, assigned_object=interface + ) + + # Marek's ex ASes + asn_5616 = models.AutonomousSystem.objects.create(asn=5616, status=status_active, description="ex Mediatel AS!") + + asn_8545 = models.AutonomousSystem.objects.create(asn=8545, status=status_active, description="Hi ex PL-IX AS!") + + asn_15521 = models.AutonomousSystem.objects.create( + asn=15521, status=status_active, description="Hi ex Premium Internet AS!" + ) + + cls.create_data = [ + { + "description": "Hello World!", + "autonomous_system": asn_8545.pk, + "device": device_1.pk, + "router_id": address.pk, + "extra_attributes": {"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}}, + }, + ] + + cls.update_data = { + "description": "Hello World!!!", + "extra_attributes": '{"key1": "value1"}', + "router_id": None, + } + + models.BGPRoutingInstance.objects.create( + device=device_2, + autonomous_system=asn_5616, + extra_attributes={"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}}, + ) + models.BGPRoutingInstance.objects.create( + device=device_3, + autonomous_system=asn_8545, + ) + models.BGPRoutingInstance.objects.create( + device=device_4, + autonomous_system=asn_15521, + ) + + cls.maxDiff = None + + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + + class PeerGroupAPITestCase(APIViewTestCases.APIViewTestCase): """Test the PeerGroup API. From 2c808733720e5351e395bdad0a0820f1b97260bd Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 18 May 2023 09:34:53 +0200 Subject: [PATCH 37/61] change: remove role and enabled from brief fields in PeerGroupTemplate nested serializer --- nautobot_bgp_models/api/nested_serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nautobot_bgp_models/api/nested_serializers.py b/nautobot_bgp_models/api/nested_serializers.py index 7edfa96d..ed628c3c 100644 --- a/nautobot_bgp_models/api/nested_serializers.py +++ b/nautobot_bgp_models/api/nested_serializers.py @@ -55,7 +55,7 @@ class NestedPeerGroupTemplateSerializer(WritableNestedSerializer): class Meta: model = models.PeerGroupTemplate - fields = ["id", "url", "name", "role", "enabled"] + fields = ["id", "url", "name"] class NestedPeerEndpointSerializer(WritableNestedSerializer): From 798081a4aef8734ad0c27a581cd9fea0cfffb6ad Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 18 May 2023 10:41:47 +0200 Subject: [PATCH 38/61] change: add RelationshipModelSerializerMixin for PeerGroupTemplate and BGPRoutingInstance serializers --- nautobot_bgp_models/api/serializers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nautobot_bgp_models/api/serializers.py b/nautobot_bgp_models/api/serializers.py index ed03ce00..33920589 100644 --- a/nautobot_bgp_models/api/serializers.py +++ b/nautobot_bgp_models/api/serializers.py @@ -79,7 +79,9 @@ def to_representation(self, instance): return super().to_representation(instance) -class PeerGroupTemplateSerializer(CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin): +class PeerGroupTemplateSerializer( + CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin, RelationshipModelSerializerMixin +): """REST API serializer for PeerGroup records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peergrouptemplate-detail") @@ -205,9 +207,7 @@ def update(self, instance, validated_data): class BGPRoutingInstanceSerializer( - CustomFieldModelSerializerMixin, - ExtraAttributesSerializerMixin, - RelationshipModelSerializerMixin + CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin, RelationshipModelSerializerMixin ): """REST API serializer for Peering records.""" From 97194cf7ac6ca563e5b4bec00eec4cdc3523f43a Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 18 May 2023 10:42:29 +0200 Subject: [PATCH 39/61] change: add PeerGroupTemplateAPITestCase change: add test cases for extra_attributes --- nautobot_bgp_models/tests/test_api.py | 313 +++++++++++++++++++++++++- 1 file changed, 306 insertions(+), 7 deletions(-) diff --git a/nautobot_bgp_models/tests/test_api.py b/nautobot_bgp_models/tests/test_api.py index 7de570e3..1f903188 100644 --- a/nautobot_bgp_models/tests/test_api.py +++ b/nautobot_bgp_models/tests/test_api.py @@ -1,5 +1,7 @@ -"""Unit tests for nautobot_bgp_models.""" +"""Unit tests for nautobot_bgp_models.""" # pylint: disable=too-many-lines from unittest import skip +from rest_framework import status +from django.test import override_settings from django.contrib.contenttypes.models import ContentType from nautobot.circuits.models import Provider @@ -8,6 +10,7 @@ from nautobot.extras.models import Status from nautobot.ipam.models import IPAddress, VRF from nautobot.utilities.testing.api import APIViewTestCases +from nautobot.users.models import ObjectPermission from nautobot_bgp_models import models @@ -80,6 +83,106 @@ def test_notes_url_on_object(self): pass +class PeerGroupTemplateAPITestCase(APIViewTestCases.APIViewTestCase): + """Test the PeerGroupTemplate API.""" + + model = models.PeerGroupTemplate + view_namespace = "plugins-api:nautobot_bgp_models" + brief_fields = ["display", "id", "name", "url"] + + # TODO(mzb): Fix bulk update via #96 - ViewSets migration + # bulk_update_data = { + # } + + @classmethod + def setUpTestData(cls): + status_active = Status.objects.get(slug="active") + status_active.content_types.add(ContentType.objects.get_for_model(models.AutonomousSystem)) + + # Marek's ex ASes + asn_5616 = models.AutonomousSystem.objects.create(asn=5616, status=status_active, description="ex Mediatel AS!") + asn_8545 = models.AutonomousSystem.objects.create(asn=8545, status=status_active, description="Hi ex PL-IX AS!") + + peeringrole_int = models.PeeringRole.objects.create(name="Internal", slug="internal", color="333333") + peeringrole_ext = models.PeeringRole.objects.create(name="External", slug="external", color="333334") + + cls.create_data = [ + { + "name": "Parent Peer Group Template 1", + "enabled": True, + "role": peeringrole_int.pk, + "description": "Marek was here", + "autonomous_system": asn_5616.pk, + "import_policy": "bgp_policy_in", + "export_policy": "bgp_policy_out", + "extra_attributes": {"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}}, + }, + ] + + cls.update_data = { + "name": "Parent Peer Group Template 1 - modified", + "enabled": False, + "role": peeringrole_ext.pk, + "description": "Marek was here", + "autonomous_system": asn_8545.pk, + "import_policy": "bgp_policy_in_2", + "export_policy": "bgp_policy_out_2", + "extra_attributes": {"key1": 2}, + } + + # PGT1 re-used by subsequent test-cases. + models.PeerGroupTemplate.objects.create( + name="PGT1", + autonomous_system=asn_5616, + enabled=True, + extra_attributes={"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}}, + ) + models.PeerGroupTemplate.objects.create( + name="PGT2", + enabled=True, + autonomous_system=asn_8545, + extra_attributes={"key1": 2}, + ) + models.PeerGroupTemplate.objects.create( + name="PGT3", + enabled=False, + autonomous_system=asn_8545, + extra_attributes={"key3": 3}, + ) + + @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) + def test_peer_group_template_extra_attributes(self): + """Test PeerGroup's inheritance path for extra attributes.""" + instance = models.PeerGroupTemplate.objects.get(name="PGT1") + url = self._get_detail_url(instance) + + # Add object-level permission + obj_perm = ObjectPermission( + name="Test permission", + constraints={"pk": instance.pk}, + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + + pgt1_ea = {"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}} + + # URLs tested. In each case, PeerGroupTemplate extra attribute should be the same. + # PeerGroupTemplate does not support include_inherited filter param. + # TODO(mzb): add negative test case for not-supported include_inherited. + response = self.client.get(url, **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + extra_attrs = dict(response.data["extra_attributes"]) + + # Ensure extra_attributes are as on the model + self.assertEqual(extra_attrs, pgt1_ea) + + @skip("Not implemented") + def test_notes_url_on_object(self): + pass + + class BGPRoutingInstanceAPITestCase(APIViewTestCases.APIViewTestCase): """Test the BGPRoutingInstance API.""" @@ -162,6 +265,34 @@ def setUpTestData(cls): # pylint: disable=too-many-locals cls.maxDiff = None + @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) + def test_bgp_routing_instance_extra_attributes(self): + """Test PeerGroup's inheritance path for extra attributes.""" + instance = models.BGPRoutingInstance.objects.get(device__name="Device 2") + url = self._get_detail_url(instance) + + # Add object-level permission + obj_perm = ObjectPermission( + name="Test permission", + constraints={"pk": instance.pk}, + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + + device_2_extra_attributes = {"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}} + + # URLs tested. In each case, BGPRoutingInstance extra attribute should be the same. + # PeerGroupTemplate does not support include_inherited filter param. + # TODO(mzb): add negative test case for not-supported include_inherited. + response = self.client.get(url, **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + extra_attrs = dict(response.data["extra_attributes"]) + + # Ensure extra_attributes are as on the model + self.assertEqual(extra_attrs, device_2_extra_attributes) + @skip("Not implemented") def test_notes_url_on_object(self): pass @@ -186,7 +317,7 @@ class PeerGroupAPITestCase(APIViewTestCases.APIViewTestCase): validation_excluded_fields = ["status"] @classmethod - def setUpTestData(cls): + def setUpTestData(cls): # pylint: disable=too-many-locals status_active = Status.objects.get(slug="active") status_active.content_types.add(ContentType.objects.get_for_model(models.AutonomousSystem)) @@ -217,6 +348,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=asn_8545, device=device, + extra_attributes={"ri_key": "ri_value", "ri_nk": {"ri_nk": "ri_nv", "ri_nk2": "ri_nv2"}}, ) cls.create_data = [ @@ -257,13 +389,106 @@ def setUpTestData(cls): "source_interface": interface.pk, "extra_attributes": '{"key1": "value1", "key2": {"nested_key2": "nested_value2"}}', } + pgt1 = models.PeerGroupTemplate.objects.create( + name="PGT1", + extra_attributes={"pgt1_key": "pgt1_value"}, + ) + + # Note: PeerGroup "Group 1" re-used in subsequent inheritance test-cases. + models.PeerGroup.objects.create( + name="Group 1", + role=peeringrole, + routing_instance=bgp_routing_instance, + extra_attributes={"pg_key": "pg_value", "ri_nk": {"pg_nk": "pg_nv", "ri_nk2": "pg_nv2"}}, + template=pgt1, + ) - models.PeerGroup.objects.create(name="Group 1", role=peeringrole, routing_instance=bgp_routing_instance) models.PeerGroup.objects.create(name="Group 2", role=peeringrole, routing_instance=bgp_routing_instance) + models.PeerGroup.objects.create(name="Group 3", role=peeringrole, routing_instance=bgp_routing_instance) cls.maxDiff = None + @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) + def test_peergroup_inherits_extra_attributes(self): + """Test PeerGroup's inheritance path for extra attributes.""" + instance = models.PeerGroup.objects.get(name="Group 1") + url = self._get_detail_url(instance) + + # Add object-level permission + obj_perm = ObjectPermission( + name="Test permission", + constraints={"pk": instance.pk}, + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + + urls = [ + f"{url}?include_inherited=true", + f"{url}?include_inherited=True", + f"{url}?include_inherited=1", + ] + + for _url in urls: + response = self.client.get(_url, **self.header) + + self.assertHttpStatus(response, status.HTTP_200_OK) + api_extra_attrs = dict(response.data["extra_attributes"]) + + # BGPRoutingInstance extra_attrs: {"ri_key": "ri_value", "ri_nk": {"ri_nk": "ri_nv", "ri_nk2": "ri_nv2"}} + # PeerGroup's extra_attrs: {"pg_key": "pg_value", "ri_nk": {"pg_nk": "pg_nv", "ri_nk2": "pg_nv2"}}, + # pgt1_extra_attributes = {"pgt1_key": "pgt1_value"}, + + # Ensure extra_attributes are deep-merged + self.assertEqual( + api_extra_attrs, + { + "ri_key": "ri_value", # Root-inherited from BGP RI + "pgt1_key": "pgt1_value", # Root-inherited from PeerGroupTemplate + "pg_key": "pg_value", # Root-added by PeerGroup + "ri_nk": { + "pg_nk": "pg_nv", # Deep-added by PeerGroup + "ri_nk": "ri_nv", # Deep-Inherited from BGP RI + "ri_nk2": "pg_nv2", # Deep-Overriden from BGP RI + }, + }, + ) + + @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) + def test_peergroup_owns_extra_attributes(self): + """Test PeerGroup's inheritance path for extra attributes.""" + instance = models.PeerGroup.objects.get(name="Group 1") + url = self._get_detail_url(instance) + + # Add object-level permission + obj_perm = ObjectPermission( + name="Test permission", + constraints={"pk": instance.pk}, + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + + urls = [ + f"{url}?include_inherited=false", + f"{url}?include_inherited=False", + f"{url}?include_inherited=0", + f"{url}", + ] + + for _url in urls: + response = self.client.get(_url, **self.header) + + self.assertHttpStatus(response, status.HTTP_200_OK) + api_extra_attrs = dict(response.data["extra_attributes"]) + pg_extra_attrs = {"pg_key": "pg_value", "ri_nk": {"pg_nk": "pg_nv", "ri_nk2": "pg_nv2"}} + + # Ensure extra_attributes are not deep-merged and returned as defined on the model instance. + self.assertEqual(api_extra_attrs, pg_extra_attrs) + @skip("Not implemented") def test_notes_url_on_object(self): pass @@ -298,10 +523,7 @@ class PeerEndpointAPITestCase(APIViewTestCases.APIViewTestCase): view_namespace = "plugins-api:nautobot_bgp_models" brief_fields = [ "display", - # "enabled", "id", - # "local_ip", - # "peer_group", "url", ] bulk_update_data = { @@ -402,21 +624,29 @@ def setUpTestData(cls): device=device, ) + cls.pgt1 = models.PeerGroupTemplate.objects.create( + name="PGT1", + extra_attributes={"pgt_key": "pgt_value"}, + ) + peergroup = models.PeerGroup.objects.create( name="Group 1", role=cls.peeringrole, routing_instance=cls.bgp_routing_instance, + template=cls.pgt1, + extra_attributes={"pg_key": "pg_value"}, # vrf=cls.vrf, # router_id=cls.addresses[3], # autonomous_system=cls.asn, ) # Peering #0 - models.PeerEndpoint.objects.create( + cls.pe = models.PeerEndpoint.objects.create( routing_instance=cls.bgp_routing_instance, source_ip=cls.addresses[0], peer_group=peergroup, peering=cls.peering[0], + extra_attributes={"pe_key": "pe_value"}, ) models.PeerEndpoint.objects.create( source_ip=cls.addresses[3], @@ -463,6 +693,75 @@ def setUpTestData(cls): def test_notes_url_on_object(self): pass + @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) + def test_peerendpoint_inherits_extra_attributes(self): + """Test PeerEndpoint's inheritance path for extra attributes.""" + instance = self.pe + url = self._get_detail_url(instance) + + # Add object-level permission + obj_perm = ObjectPermission( + name="Test permission", + constraints={"pk": instance.pk}, + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + + urls = [ + f"{url}?include_inherited=true", + f"{url}?include_inherited=True", + f"{url}?include_inherited=1", + ] + + for _url in urls: + response = self.client.get(_url, **self.header) + + self.assertHttpStatus(response, status.HTTP_200_OK) + api_extra_attrs = dict(response.data["extra_attributes"]) + inherited_extra_attrs = { + "pe_key": "pe_value", + "pg_key": "pg_value", + "pgt_key": "pgt_value", + } + # Ensure extra_attributes are deep-merged + self.assertEqual(api_extra_attrs, inherited_extra_attrs) + + @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) + def test_peerendpoint_owns_extra_attributes(self): + """Test PeerEndpoint's inheritance path for extra attributes.""" + instance = self.pe + url = self._get_detail_url(instance) + + # Add object-level permission + obj_perm = ObjectPermission( + name="Test permission", + constraints={"pk": instance.pk}, + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + + urls = [ + f"{url}?include_inherited=false", + f"{url}?include_inherited=False", + f"{url}?include_inherited=0", + f"{url}", + ] + + for _url in urls: + response = self.client.get(_url, **self.header) + + self.assertHttpStatus(response, status.HTTP_200_OK) + api_extra_attrs = dict(response.data["extra_attributes"]) + # Extra attrs defined on the cls.pe. (class' peerendpoint) + pe_extra_attrs = {"pe_key": "pe_value"} + + # Ensure extra_attributes are not deep-merged and returned as defined on the model instance. + self.assertEqual(api_extra_attrs, pe_extra_attrs) + # @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) # def test_get_object_include_inherited(self): From f205f65e12b42b863782b7f02c48c557cd65f238 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Fri, 19 May 2023 09:05:21 +0200 Subject: [PATCH 40/61] release: 0.7.1 --- docs/admin/compatibility_matrix.md | 4 ++-- docs/admin/release_notes/version_0.7.md | 10 ++++++++++ pyproject.toml | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/admin/compatibility_matrix.md b/docs/admin/compatibility_matrix.md index 20e44832..ac35baa9 100644 --- a/docs/admin/compatibility_matrix.md +++ b/docs/admin/compatibility_matrix.md @@ -2,5 +2,5 @@ | BGP Models Version | Nautobot First Support Version | Nautobot Last Support Version | |--------------------|--------------------------------|-------------------------------| -| 0.7.X | 1.3.0 | 1.99.99 | -| 0.8.X | 1.5.4 | 1.99.99 | +| 0.7.0 | 1.3.0 | 1.99.99 | +| 0.7.1 | 1.5.4 | 1.99.99 | diff --git a/docs/admin/release_notes/version_0.7.md b/docs/admin/release_notes/version_0.7.md index 821e5160..102a3d0e 100644 --- a/docs/admin/release_notes/version_0.7.md +++ b/docs/admin/release_notes/version_0.7.md @@ -23,3 +23,13 @@ ### Fixed - [#99](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/99) - fix: allow read/write for extra attributes from API + +## [v0.7.1] - 2023-05-19 + +### Added + +### Changed + +### Fixed + +- [#104](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/104) - Multiple fixes for test cases and serializers diff --git a/pyproject.toml b/pyproject.toml index c28491f8..f6c1e3f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-bgp-models" -version = "0.7.0" +version = "0.7.1" description = "Nautobot BGP Models Plugin" authors = ["Network to Code, LLC "] From cc9bcb2a14533f7e619fa8ee3430fa6f97534fac Mon Sep 17 00:00:00 2001 From: Jeremy White Date: Tue, 14 Mar 2023 18:04:00 -0500 Subject: [PATCH 41/61] Migrate to viewsets Add BGPRoutingInstance status field Add CSV import and export --- nautobot_bgp_models/__init__.py | 1 + nautobot_bgp_models/api/serializers.py | 34 +- nautobot_bgp_models/api/views.py | 4 +- nautobot_bgp_models/forms.py | 332 +++++++++---- ...e_template_peergroup_peergroup_template.py | 17 + .../0003_bgproutinginstance_status.py | 25 + nautobot_bgp_models/models.py | 129 ++++- nautobot_bgp_models/navigation.py | 28 +- nautobot_bgp_models/tables.py | 9 +- ...amily.html => addressfamily_retrieve.html} | 0 ...em.html => autonomoussystem_retrieve.html} | 0 ....html => bgproutinginstance_retrieve.html} | 0 ...dpoint.html => peerendpoint_retrieve.html} | 0 ...peergroup.html => peergroup_retrieve.html} | 2 +- ...e.html => peergrouptemplate_retrieve.html} | 0 .../{peering_create.html => peering_add.html} | 0 .../{peering.html => peering_retrieve.html} | 0 ...ingrole.html => peeringrole_retrieve.html} | 0 nautobot_bgp_models/tests/test_api.py | 40 +- nautobot_bgp_models/tests/test_filters.py | 4 + nautobot_bgp_models/tests/test_forms.py | 3 + nautobot_bgp_models/tests/test_models.py | 21 +- nautobot_bgp_models/tests/test_views.py | 40 +- nautobot_bgp_models/urls.py | 161 +----- nautobot_bgp_models/views.py | 465 +++++------------- 25 files changed, 611 insertions(+), 704 deletions(-) create mode 100644 nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py create mode 100644 nautobot_bgp_models/migrations/0003_bgproutinginstance_status.py rename nautobot_bgp_models/templates/nautobot_bgp_models/{addressfamily.html => addressfamily_retrieve.html} (100%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{autonomoussystem.html => autonomoussystem_retrieve.html} (100%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{bgproutinginstance.html => bgproutinginstance_retrieve.html} (100%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{peerendpoint.html => peerendpoint_retrieve.html} (100%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{peergroup.html => peergroup_retrieve.html} (98%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{peergrouptemplate.html => peergrouptemplate_retrieve.html} (100%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{peering_create.html => peering_add.html} (100%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{peering.html => peering_retrieve.html} (100%) rename nautobot_bgp_models/templates/nautobot_bgp_models/{peeringrole.html => peeringrole_retrieve.html} (100%) diff --git a/nautobot_bgp_models/__init__.py b/nautobot_bgp_models/__init__.py index 3d2efeba..13e854fa 100644 --- a/nautobot_bgp_models/__init__.py +++ b/nautobot_bgp_models/__init__.py @@ -28,6 +28,7 @@ class NautobotBGPModelsConfig(PluginConfig): default_settings = { "default_statuses": { "AutonomousSystem": ["active", "available", "planned"], + "BGPRoutingInstance": ["planned", "active", "decommissioned"], "Peering": ["active", "decommissioned", "deprovisioning", "offline", "planned", "provisioning"], } } diff --git a/nautobot_bgp_models/api/serializers.py b/nautobot_bgp_models/api/serializers.py index 33920589..e8cc2099 100644 --- a/nautobot_bgp_models/api/serializers.py +++ b/nautobot_bgp_models/api/serializers.py @@ -5,8 +5,7 @@ from nautobot.dcim.api.serializers import NestedDeviceSerializer, NestedInterfaceSerializer from nautobot.ipam.api.serializers import NestedVRFSerializer, NestedIPAddressSerializer from nautobot.apps.api import ( - CustomFieldModelSerializerMixin, - RelationshipModelSerializerMixin, + NautobotModelSerializer, StatusModelSerializerMixin, TaggedModelSerializerMixin, ) @@ -22,10 +21,9 @@ class AutonomousSystemSerializer( + NautobotModelSerializer, TaggedModelSerializerMixin, StatusModelSerializerMixin, - CustomFieldModelSerializerMixin, - RelationshipModelSerializerMixin, ): """REST API serializer for AutonomousSystem records.""" @@ -37,7 +35,7 @@ class Meta: fields = ["id", "url", "asn", "description", "status", "provider", "tags"] -class PeeringRoleSerializer(CustomFieldModelSerializerMixin, RelationshipModelSerializerMixin): +class PeeringRoleSerializer(NautobotModelSerializer): """REST API serializer for PeeringRole records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peeringrole-detail") @@ -79,9 +77,7 @@ def to_representation(self, instance): return super().to_representation(instance) -class PeerGroupTemplateSerializer( - CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin, RelationshipModelSerializerMixin -): +class PeerGroupTemplateSerializer(NautobotModelSerializer, ExtraAttributesSerializerMixin): """REST API serializer for PeerGroup records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peergrouptemplate-detail") @@ -108,9 +104,8 @@ class Meta: class PeerGroupSerializer( InheritableFieldsSerializerMixin, - CustomFieldModelSerializerMixin, + NautobotModelSerializer, ExtraAttributesSerializerMixin, - RelationshipModelSerializerMixin, ): """REST API serializer for PeerGroup records.""" @@ -122,7 +117,7 @@ class PeerGroupSerializer( autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 - template = NestedPeerGroupTemplateSerializer(required=False, allow_null=True) # noqa: F405 + peergroup_template = NestedPeerGroupTemplateSerializer(required=False, allow_null=True) # noqa: F405 secret = NestedSecretSerializer(required=False, allow_null=True) @@ -138,7 +133,7 @@ class Meta: "enabled", "autonomous_system", "routing_instance", - "template", + "peergroup_template", "secret", "extra_attributes", "role", @@ -150,9 +145,8 @@ class Meta: class PeerEndpointSerializer( InheritableFieldsSerializerMixin, TaggedModelSerializerMixin, - CustomFieldModelSerializerMixin, + NautobotModelSerializer, ExtraAttributesSerializerMixin, - RelationshipModelSerializerMixin, ): """REST API serializer for PeerEndpoint records.""" @@ -206,9 +200,7 @@ def update(self, instance, validated_data): return result -class BGPRoutingInstanceSerializer( - CustomFieldModelSerializerMixin, ExtraAttributesSerializerMixin, RelationshipModelSerializerMixin -): +class BGPRoutingInstanceSerializer(NautobotModelSerializer, StatusModelSerializerMixin, ExtraAttributesSerializerMixin): """REST API serializer for Peering records.""" url = serializers.HyperlinkedIdentityField( @@ -229,6 +221,7 @@ class Meta: "id", "url", "device", + "status", "description", "router_id", "autonomous_system", @@ -237,7 +230,7 @@ class Meta: ] -class PeeringSerializer(CustomFieldModelSerializerMixin, StatusModelSerializerMixin, RelationshipModelSerializerMixin): +class PeeringSerializer(NautobotModelSerializer, StatusModelSerializerMixin): """REST API serializer for Peering records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:peering-detail") @@ -254,10 +247,7 @@ class Meta: ] -class AddressFamilySerializer( - CustomFieldModelSerializerMixin, - RelationshipModelSerializerMixin, -): +class AddressFamilySerializer(NautobotModelSerializer): """REST API serializer for AddressFamily records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:addressfamily-detail") diff --git a/nautobot_bgp_models/api/views.py b/nautobot_bgp_models/api/views.py index 53c85f09..77b0523e 100644 --- a/nautobot_bgp_models/api/views.py +++ b/nautobot_bgp_models/api/views.py @@ -2,7 +2,7 @@ from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import extend_schema, OpenApiParameter -from nautobot.extras.api.views import CustomFieldModelViewSet, StatusViewSetMixin +from nautobot.extras.api.views import NautobotModelViewSet, StatusViewSetMixin from nautobot.utilities.utils import dynamic_import from nautobot_bgp_models import filters @@ -11,7 +11,7 @@ from . import serializers -class PluginModelViewSet(CustomFieldModelViewSet): +class PluginModelViewSet(NautobotModelViewSet): """Base class for all REST API viewsets in this plugin.""" def get_serializer_class(self): diff --git a/nautobot_bgp_models/forms.py b/nautobot_bgp_models/forms.py index 729ba920..436dee51 100644 --- a/nautobot_bgp_models/forms.py +++ b/nautobot_bgp_models/forms.py @@ -1,50 +1,62 @@ """Forms and FilterForms for nautobot_bgp_models.""" +from django import forms -import nautobot.extras.forms as extras_forms import nautobot.utilities.forms as utilities_forms -from django import forms +from nautobot.apps.forms import ( + CSVModelChoiceField, + CSVModelForm, + DynamicModelMultipleChoiceField, + DynamicModelChoiceField, + NautobotModelForm, + NautobotBulkEditForm, + StatusModelCSVFormMixin, + TagFilterField, + TagsBulkEditFormMixin, +) from nautobot.circuits.models import Provider from nautobot.dcim.models import Device, Interface +from nautobot.extras.forms import NautobotFilterForm from nautobot.extras.models import Tag, Secret from nautobot.ipam.models import VRF, IPAddress from . import choices, models -class AutonomousSystemForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class AutonomousSystemForm(NautobotModelForm): """Form for creating/updating AutonomousSystem records.""" - tags = utilities_forms.DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False) - provider = utilities_forms.DynamicModelChoiceField(queryset=Provider.objects.all(), required=False) + tags = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False) + provider = DynamicModelChoiceField(queryset=Provider.objects.all(), required=False) class Meta: model = models.AutonomousSystem fields = ("asn", "description", "provider", "status", "tags") -class AutonomousSystemFilterForm( - utilities_forms.BootstrapMixin, extras_forms.StatusFilterFormMixin, extras_forms.CustomFieldFilterForm -): +class AutonomousSystemFilterForm(NautobotFilterForm): """Form for filtering AutonomousSystem records in combination with AutonomousSystemFilterSet.""" model = models.AutonomousSystem field_order = ["status", "tag"] - tag = utilities_forms.TagFilterField(model) + tag = TagFilterField(model) + +class AutonomousSystemCSVForm(StatusModelCSVFormMixin, CSVModelForm): + """Form for importing AutonomousSystems from CSV data.""" + + provider = CSVModelChoiceField( + queryset=Provider.objects.all(), + to_field_name="name", + help_text="Provider name", + required=False, + ) -# class AutonomousSystemCSVForm(extras_forms.StatusModelCSVFormMixin, extras_forms.CustomFieldModelCSVForm): -# """Form for importing AutonomousSystems from CSV data.""" -# -# class Meta: -# model = models.AutonomousSystem -# fields = models.AutonomousSystem.csv_headers + class Meta: + model = models.AutonomousSystem + fields = models.AutonomousSystem.csv_headers -class AutonomousSystemBulkEditForm( - utilities_forms.BootstrapMixin, extras_forms.AddRemoveTagsForm, extras_forms.CustomFieldBulkEditForm -): +class AutonomousSystemBulkEditForm(TagsBulkEditFormMixin, NautobotBulkEditForm): """Form for bulk-editing multiple AutonomousSystem records.""" pk = forms.ModelMultipleChoiceField( @@ -58,9 +70,7 @@ class Meta: ] -class BGPRoutingInstanceForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class BGPRoutingInstanceForm(NautobotModelForm): """Form for creating/updating BGPRoutingInstance records.""" def __init__(self, *args, **kwargs): @@ -69,26 +79,26 @@ def __init__(self, *args, **kwargs): if self.initial.get("device"): self.fields["device"].disabled = True - self.fields.pop("template") + self.fields.pop("peergroup_template") - device = utilities_forms.DynamicModelChoiceField( + device = DynamicModelChoiceField( queryset=Device.objects.all(), ) - autonomous_system = utilities_forms.DynamicModelChoiceField( + autonomous_system = DynamicModelChoiceField( queryset=models.AutonomousSystem.objects.all(), ) - router_id = utilities_forms.DynamicModelChoiceField( + router_id = DynamicModelChoiceField( queryset=IPAddress.objects.all(), label="Router ID", required=False, query_params={"device_id": "$device"}, ) - tags = utilities_forms.DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False) + tags = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False) - template = utilities_forms.DynamicModelMultipleChoiceField( + peergroup_template = DynamicModelMultipleChoiceField( queryset=models.PeerGroupTemplate.objects.all(), required=False, label="Peer Group Templates", @@ -103,10 +113,10 @@ def save(self, commit=True): if commit: # Initiate local templates as indicated in the creation form. # Templates are only created during object creation. - for t in self.cleaned_data.get("template", []): # pylint: disable=invalid-name + for t in self.cleaned_data.get("peergroup_template", []): # pylint: disable=invalid-name models.PeerGroup.objects.create( name=t.name, - template=t, + peergroup_template=t, routing_instance=obj, ) @@ -114,29 +124,37 @@ def save(self, commit=True): class Meta: model = models.BGPRoutingInstance - fields = ("device", "autonomous_system", "description", "router_id", "template", "tags", "extra_attributes") + fields = ( + "device", + "autonomous_system", + "description", + "router_id", + "peergroup_template", + "tags", + "extra_attributes", + ) -class BGPRoutingInstanceFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldFilterForm): +class BGPRoutingInstanceFilterForm(NautobotFilterForm): """Form for filtering BGPRoutingInstance records in combination with BGPRoutingInstanceFilterSet.""" q = forms.CharField(required=False, label="Search") model = models.BGPRoutingInstance - device = utilities_forms.DynamicModelMultipleChoiceField( + device = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, to_field_name="name", ) - autonomous_system = utilities_forms.DynamicModelMultipleChoiceField( + autonomous_system = DynamicModelMultipleChoiceField( queryset=models.AutonomousSystem.objects.all(), required=False, to_field_name="asn", ) - tag = utilities_forms.TagFilterField(model) + tag = TagFilterField(model) field_order = [ "q", @@ -147,9 +165,7 @@ class BGPRoutingInstanceFilterForm(utilities_forms.BootstrapMixin, extras_forms. ] -class BGPRoutingInstanceBulkEditForm( - utilities_forms.BootstrapMixin, extras_forms.AddRemoveTagsForm, extras_forms.CustomFieldBulkEditForm -): +class BGPRoutingInstanceBulkEditForm(NautobotBulkEditForm): """Form for bulk-editing multiple BGPRoutingInstance records.""" pk = forms.ModelMultipleChoiceField( @@ -163,9 +179,34 @@ class Meta: ] -class PeeringRoleForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class BGPRoutingInstanceCSVForm(StatusModelCSVFormMixin, CSVModelForm): + """Form for importing BGPRoutingInstance from CSV data.""" + + device = CSVModelChoiceField( + queryset=Device.objects.all(), + to_field_name="name", + help_text="Assigned device's name", + ) + + autonomous_system = CSVModelChoiceField( + queryset=models.AutonomousSystem.objects.all(), + to_field_name="asn", + help_text="Assigned autonomous system number", + ) + + router_id = CSVModelChoiceField( + queryset=IPAddress.objects.all(), + to_field_name="address", + help_text="Router ID - IP Address", + required=False, + ) + + class Meta: + model = models.BGPRoutingInstance + fields = models.BGPRoutingInstance.csv_headers + + +class PeeringRoleForm(NautobotModelForm): """Form for creating/updating PeeringRole records.""" slug = utilities_forms.SlugField() @@ -175,7 +216,7 @@ class Meta: fields = ("name", "slug", "color", "description") -class PeeringRoleFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldFilterForm): +class PeeringRoleFilterForm(NautobotFilterForm): """Form for filtering PeeringRole records in combination with PeeringRoleFilterSet.""" model = models.PeeringRole @@ -183,7 +224,7 @@ class PeeringRoleFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomF color = forms.CharField(max_length=6, required=False, widget=utilities_forms.ColorSelect()) -class PeeringRoleCSVForm(extras_forms.CustomFieldModelCSVForm): +class PeeringRoleCSVForm(CSVModelForm): """Form for importing PeeringRole records from CSV data.""" class Meta: @@ -191,7 +232,7 @@ class Meta: fields = models.PeeringRole.csv_headers -class PeeringRoleBulkEditForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldBulkEditForm): +class PeeringRoleBulkEditForm(NautobotBulkEditForm): """Form for bulk-editing multiple PeeringRole records.""" pk = forms.ModelMultipleChoiceField(queryset=models.PeeringRole.objects.all(), widget=forms.MultipleHiddenInput()) @@ -204,9 +245,7 @@ class Meta: ] -class PeerGroupForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class PeerGroupForm(NautobotModelForm): """Form for creating/updating PeerGroup records.""" def __init__(self, *args, **kwargs): @@ -216,45 +255,45 @@ def __init__(self, *args, **kwargs): if self.initial.get("routing_instance"): self.fields["routing_instance"].disabled = True - routing_instance = utilities_forms.DynamicModelChoiceField( + routing_instance = DynamicModelChoiceField( queryset=models.BGPRoutingInstance.objects.all(), required=True, label="BGP Routing Instance", help_text="Specify related Routing Instance (Device)", ) - source_ip = utilities_forms.DynamicModelChoiceField( + source_ip = DynamicModelChoiceField( queryset=IPAddress.objects.all(), required=False, label="Source IP Address", query_params={"nautobot_bgp_models_ips_bgp_routing_instance": "$routing_instance"}, ) - source_interface = utilities_forms.DynamicModelChoiceField( + source_interface = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, label="Source Interface", query_params={"nautobot_bgp_models_interfaces_bgp_routing_instance": "$routing_instance"}, ) - autonomous_system = utilities_forms.DynamicModelChoiceField( + autonomous_system = DynamicModelChoiceField( queryset=models.AutonomousSystem.objects.all(), required=False, label="Autonomous System", ) - role = utilities_forms.DynamicModelChoiceField(queryset=models.PeeringRole.objects.all(), required=False) + role = DynamicModelChoiceField(queryset=models.PeeringRole.objects.all(), required=False) - template = utilities_forms.DynamicModelChoiceField(queryset=models.PeerGroupTemplate.objects.all(), required=False) + peergroup_template = DynamicModelChoiceField(queryset=models.PeerGroupTemplate.objects.all(), required=False) - secret = utilities_forms.DynamicModelChoiceField(queryset=Secret.objects.all(), required=False) + secret = DynamicModelChoiceField(queryset=Secret.objects.all(), required=False) class Meta: model = models.PeerGroup fields = ( "routing_instance", "name", - "template", + "peergroup_template", "description", "enabled", "role", @@ -268,9 +307,7 @@ class Meta: ) -class PeerGroupBulkEditForm( - utilities_forms.BootstrapMixin, extras_forms.AddRemoveTagsForm, extras_forms.CustomFieldBulkEditForm -): +class PeerGroupBulkEditForm(NautobotBulkEditForm): """Form for bulk-editing multiple PeerGroup records.""" pk = forms.ModelMultipleChoiceField( @@ -284,20 +321,18 @@ class Meta: ] -class PeerGroupTemplateForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class PeerGroupTemplateForm(NautobotModelForm): """Form for creating/updating PeerGroup records.""" - autonomous_system = utilities_forms.DynamicModelChoiceField( + autonomous_system = DynamicModelChoiceField( queryset=models.AutonomousSystem.objects.all(), required=False, label="Autonomous System", ) - role = utilities_forms.DynamicModelChoiceField(queryset=models.PeeringRole.objects.all(), required=False) + role = DynamicModelChoiceField(queryset=models.PeeringRole.objects.all(), required=False) - secret = utilities_forms.DynamicModelChoiceField(queryset=Secret.objects.all(), required=False) + secret = DynamicModelChoiceField(queryset=Secret.objects.all(), required=False) class Meta: model = models.PeerGroupTemplate @@ -313,9 +348,7 @@ class Meta: ) -class PeerGroupTemplateBulkEditForm( - utilities_forms.BootstrapMixin, extras_forms.AddRemoveTagsForm, extras_forms.CustomFieldBulkEditForm -): +class PeerGroupTemplateBulkEditForm(NautobotBulkEditForm): """Form for bulk-editing multiple PeerGroupTemplate records.""" pk = forms.ModelMultipleChoiceField( @@ -329,14 +362,14 @@ class Meta: ] -class PeerGroupFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldFilterForm): +class PeerGroupFilterForm(NautobotFilterForm): """Form for filtering PeerGroup records in combination with PeerGroupFilterSet.""" model = models.PeerGroup q = forms.CharField(required=False, label="Search") - role = utilities_forms.DynamicModelMultipleChoiceField( + role = DynamicModelMultipleChoiceField( queryset=models.PeeringRole.objects.all(), to_field_name="slug", required=False ) @@ -344,19 +377,19 @@ class PeerGroupFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFie required=False, widget=utilities_forms.StaticSelect2(choices=utilities_forms.BOOLEAN_WITH_BLANK_CHOICES) ) - autonomous_system = utilities_forms.DynamicModelMultipleChoiceField( + autonomous_system = DynamicModelMultipleChoiceField( queryset=models.AutonomousSystem.objects.all(), to_field_name="asn", required=False ) -class PeerGroupTemplateFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldFilterForm): +class PeerGroupTemplateFilterForm(NautobotFilterForm): """Form for filtering PeerGroupTemplate records in combination with PeerGroupTemplateFilterSet.""" model = models.PeerGroup q = forms.CharField(required=False, label="Search") - role = utilities_forms.DynamicModelMultipleChoiceField( + role = DynamicModelMultipleChoiceField( queryset=models.PeeringRole.objects.all(), to_field_name="slug", required=False ) @@ -364,14 +397,77 @@ class PeerGroupTemplateFilterForm(utilities_forms.BootstrapMixin, extras_forms.C required=False, widget=utilities_forms.StaticSelect2(choices=utilities_forms.BOOLEAN_WITH_BLANK_CHOICES) ) - autonomous_system = utilities_forms.DynamicModelMultipleChoiceField( + autonomous_system = DynamicModelMultipleChoiceField( queryset=models.AutonomousSystem.objects.all(), to_field_name="asn", required=False ) -class PeerEndpointForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class PeerGroupTemplateCSVForm(CSVModelForm): + """Form for importing PeerGroupTemplate from CSV data.""" + + role = CSVModelChoiceField( + queryset=models.PeeringRole.objects.all(), + to_field_name="name", + help_text="Assigned Peering Role name", + required=False, + ) + + autonomous_system = CSVModelChoiceField( + queryset=models.AutonomousSystem.objects.all(), + to_field_name="asn", + help_text="Assigned autonomous system number", + required=False, + ) + + class Meta: + model = models.PeerGroupTemplate + fields = models.PeerGroupTemplate.csv_headers + + +class PeerGroupCSVForm(CSVModelForm): + """Form for importing PeerGroup from CSV data.""" + + peergroup_template = CSVModelChoiceField( + queryset=models.PeerGroupTemplate.objects.all(), + to_field_name="name", + help_text="Assigned peering group template name", + required=False, + ) + + autonomous_system = CSVModelChoiceField( + queryset=models.AutonomousSystem.objects.all(), + to_field_name="asn", + help_text="Assigned autonomous system number", + required=False, + ) + + role = CSVModelChoiceField( + queryset=models.PeeringRole.objects.all(), + to_field_name="name", + help_text="Assigned Peering Role name", + required=False, + ) + + source_interface = CSVModelChoiceField( + queryset=Interface.objects.all(), + to_field_name="name", + help_text="Peer group source Interface name", + required=False, + ) + + source_ip = CSVModelChoiceField( + queryset=IPAddress.objects.all(), + # to_field_name="name", + help_text="Peer group source IP address", + required=False, + ) + + class Meta: + model = models.PeerGroup + fields = models.PeerGroup.csv_headers + + +class PeerEndpointForm(NautobotModelForm): """Form for creating/updating PeerEndpoint records.""" def __init__(self, *args, **kwargs): @@ -390,42 +486,42 @@ def __init__(self, *args, **kwargs): ) self.fields["peer_group"].widget.add_query_param("routing_instance", f"${_prefix}routing_instance") - routing_instance = utilities_forms.DynamicModelChoiceField( + routing_instance = DynamicModelChoiceField( queryset=models.BGPRoutingInstance.objects.all(), required=False, label="BGP Routing Instance", help_text="Specify related Routing Instance (Device)", ) - autonomous_system = utilities_forms.DynamicModelChoiceField( + autonomous_system = DynamicModelChoiceField( queryset=models.AutonomousSystem.objects.all(), required=False, label="Autonomous System", ) - source_ip = utilities_forms.DynamicModelChoiceField( + source_ip = DynamicModelChoiceField( queryset=IPAddress.objects.all(), required=False, label="Source IP Address", ) - source_interface = utilities_forms.DynamicModelChoiceField( + source_interface = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, label="Source Interface", ) - peer_group = utilities_forms.DynamicModelChoiceField( + peer_group = DynamicModelChoiceField( queryset=models.PeerGroup.objects.all(), required=False, label="Peer Group", ) - role = utilities_forms.DynamicModelChoiceField(queryset=models.PeeringRole.objects.all(), required=False) + role = DynamicModelChoiceField(queryset=models.PeeringRole.objects.all(), required=False) - secret = utilities_forms.DynamicModelChoiceField(queryset=Secret.objects.all(), required=False) + secret = DynamicModelChoiceField(queryset=Secret.objects.all(), required=False) - peering = utilities_forms.DynamicModelChoiceField( # Hidden & optional - update peers manually for new peerings. + peering = DynamicModelChoiceField( # Hidden & optional - update peers manually for new peerings. queryset=models.Peering.objects.all(), widget=forms.HiddenInput(), required=False, @@ -459,9 +555,31 @@ def save(self, commit=True): return endpoint -class PeeringForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class PeerEndpointCSVForm(CSVModelForm): + """Form for importing PeerEndpoint from CSV data.""" + + class Meta: + model = models.PeerEndpoint + fields = models.PeerEndpoint.csv_headers + + +class PeerEndpointFilterForm(NautobotFilterForm): + """Form for filtering PeerEndpoint records in combination with PeerEndpointFilterSet.""" + + model = models.PeerEndpoint + tag = TagFilterField(model) + + +class PeerEndpointBulkEditForm(NautobotBulkEditForm): + """Form for bulk-editing multiple PeerEndpoint records.""" + + pk = forms.ModelMultipleChoiceField(queryset=models.PeerEndpoint.objects.all(), widget=forms.MultipleHiddenInput()) + + class Meta: + nullable_fields = [] + + +class PeeringForm(NautobotModelForm): """Form for creating/updating Peering records.""" class Meta: @@ -469,9 +587,7 @@ class Meta: fields = ("status",) -class PeeringFilterForm( - utilities_forms.BootstrapMixin, extras_forms.StatusFilterFormMixin, extras_forms.CustomFieldFilterForm -): +class PeeringFilterForm(NautobotFilterForm): """Form for filtering Peering records in combination with PeeringFilterSet.""" model = models.Peering @@ -481,21 +597,17 @@ class PeeringFilterForm( "status", "device", ] - role = utilities_forms.DynamicModelMultipleChoiceField( + role = DynamicModelMultipleChoiceField( queryset=models.PeeringRole.objects.all(), to_field_name="slug", required=False ) - device = utilities_forms.DynamicModelMultipleChoiceField( - queryset=Device.objects.all(), to_field_name="name", required=False - ) + device = DynamicModelMultipleChoiceField(queryset=Device.objects.all(), to_field_name="name", required=False) -class AddressFamilyForm( - utilities_forms.BootstrapMixin, extras_forms.CustomFieldModelForm, extras_forms.RelationshipModelForm -): +class AddressFamilyForm(NautobotModelForm): """Form for creating/updating AddressFamily records.""" - routing_instance = utilities_forms.DynamicModelChoiceField( + routing_instance = DynamicModelChoiceField( queryset=models.BGPRoutingInstance.objects.all(), required=True, label="BGP Routing Instance", @@ -509,7 +621,7 @@ class AddressFamilyForm( widget=utilities_forms.StaticSelect2(), ) - vrf = utilities_forms.DynamicModelChoiceField( + vrf = DynamicModelChoiceField( queryset=VRF.objects.all(), required=False, label="VRF", @@ -529,9 +641,7 @@ class Meta: ) -class AddressFamilyBulkEditForm( - utilities_forms.BootstrapMixin, extras_forms.AddRemoveTagsForm, extras_forms.CustomFieldBulkEditForm -): +class AddressFamilyBulkEditForm(NautobotBulkEditForm): """Form for bulk-editing multiple AddressFamily records.""" pk = forms.ModelMultipleChoiceField( @@ -542,14 +652,12 @@ class Meta: nullable_fields = [] -class AddressFamilyFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldFilterForm): +class AddressFamilyFilterForm(NautobotFilterForm): """Form for filtering AddressFamily records in combination with AddressFamilyFilterSet.""" model = models.AddressFamily - routing_instance = utilities_forms.DynamicModelMultipleChoiceField( - queryset=models.BGPRoutingInstance.objects.all(), required=False - ) + routing_instance = DynamicModelMultipleChoiceField(queryset=models.BGPRoutingInstance.objects.all(), required=False) afi_safi = forms.MultipleChoiceField( label="AFI-SAFI", @@ -558,4 +666,12 @@ class AddressFamilyFilterForm(utilities_forms.BootstrapMixin, extras_forms.Custo widget=utilities_forms.StaticSelect2Multiple(), ) - vrf = utilities_forms.DynamicModelMultipleChoiceField(queryset=VRF.objects.all(), required=False) + vrf = DynamicModelMultipleChoiceField(queryset=VRF.objects.all(), required=False) + + +class AddressFamilyCSVForm(CSVModelForm): + """Form for importing AddressFamily from CSV data.""" + + class Meta: + model = models.AddressFamily + fields = models.AddressFamily.csv_headers diff --git a/nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py b/nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py new file mode 100644 index 00000000..2d0742f5 --- /dev/null +++ b/nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.18 on 2023-03-15 21:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("nautobot_bgp_models", "0001_initial"), + ] + + operations = [ + migrations.RenameField( + model_name="peergroup", + old_name="template", + new_name="peergroup_template", + ), + ] diff --git a/nautobot_bgp_models/migrations/0003_bgproutinginstance_status.py b/nautobot_bgp_models/migrations/0003_bgproutinginstance_status.py new file mode 100644 index 00000000..c4f86433 --- /dev/null +++ b/nautobot_bgp_models/migrations/0003_bgproutinginstance_status.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.16 on 2023-05-25 08:42 + +from django.db import migrations +import django.db.models.deletion +import nautobot.extras.models.statuses + + +class Migration(migrations.Migration): + dependencies = [ + ("extras", "0053_relationship_required_on"), + ("nautobot_bgp_models", "0002_rename_template_peergroup_peergroup_template"), + ] + + operations = [ + migrations.AddField( + model_name="bgproutinginstance", + name="status", + field=nautobot.extras.models.statuses.StatusField( + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="nautobot_bgp_models_bgproutinginstance_related", + to="extras.status", + ), + ), + ] diff --git a/nautobot_bgp_models/models.py b/nautobot_bgp_models/models.py index e4befff6..91496fb8 100644 --- a/nautobot_bgp_models/models.py +++ b/nautobot_bgp_models/models.py @@ -138,7 +138,7 @@ class AutonomousSystem(PrimaryModel, StatusModel): description = models.CharField(max_length=200, blank=True) provider = models.ForeignKey(to=Provider, on_delete=models.PROTECT, blank=True, null=True) - csv_headers = ["asn", "description", "status"] + csv_headers = ["asn", "description", "status", "provider"] class Meta: ordering = ["asn"] @@ -154,7 +154,7 @@ def get_absolute_url(self): def to_csv(self): """Render an AutonomousSystem record to CSV fields.""" - return self.asn, self.description, self.get_status_display() + return self.asn, self.description, self.get_status_display(), self.provider @extras_features( @@ -189,7 +189,7 @@ def get_absolute_url(self): def to_csv(self): """Render a PeeringRole record to CSV fields.""" - return (self.name, self.slug, self.color, self.description) + return self.name, self.slug, self.color, self.description @extras_features( @@ -202,7 +202,7 @@ def to_csv(self): "statuses", "webhooks", ) -class BGPRoutingInstance(PrimaryModel, BGPExtraAttributesMixin): +class BGPRoutingInstance(PrimaryModel, StatusModel, BGPExtraAttributesMixin): """BGP instance definition.""" description = models.CharField(max_length=200, blank=True) @@ -227,6 +227,14 @@ class BGPRoutingInstance(PrimaryModel, BGPExtraAttributesMixin): on_delete=models.PROTECT, ) + csv_headers = [ + "device", + "autonomous_system", + "router_id", + "status", + "description", + ] + def get_absolute_url(self): """Get the URL for detailed view of a single BGPRoutingInstance.""" return reverse("plugins:nautobot_bgp_models:bgproutinginstance", args=[self.pk]) @@ -239,6 +247,16 @@ class Meta: verbose_name = "BGP Routing Instance" unique_together = [("device", "autonomous_system")] + def to_csv(self): + """Render an BGPRoutingInstance record to CSV fields.""" + return ( + self.device.identifier if self.device else None, + self.autonomous_system.asn if self.autonomous_system else None, + self.router_id.address if self.router_id else None, + self.get_status_display(), + self.description, + ) + @extras_features( "custom_fields", @@ -281,6 +299,18 @@ class PeerGroupTemplate(PrimaryModel, BGPExtraAttributesMixin): blank=True, null=True, ) + csv_headers = ["name", "import_policy", "export_policy", "autonomous_system", "enabled", "role"] + + def to_csv(self): + """Render a PeerGroupTemplate record to CSV fields.""" + return ( + self.name, + self.import_policy, + self.export_policy, + self.autonomous_system.asn if self.autonomous_system else None, + self.enabled, + self.role.name if self.role else None, + ) def __str__(self): """String.""" @@ -306,19 +336,20 @@ class Meta: class PeerGroup(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): """BGP peer group information.""" - extra_attributes_inheritance = ["template", "routing_instance"] + extra_attributes_inheritance = ["peergroup_template", "routing_instance"] property_inheritance = { - "autonomous_system": ["template", "routing_instance"], - "description": ["template"], - "enabled": ["template"], - "export_policy": ["template"], - "import_policy": ["template"], - "role": ["template"], + "autonomous_system": ["peergroup_template", "routing_instance"], + "description": ["peergroup_template"], + "enabled": ["peergroup_template"], + "export_policy": ["peergroup_template"], + "import_policy": ["peergroup_template"], + "role": ["peergroup_template"], } name = models.CharField(max_length=100) - template = models.ForeignKey( + # Rename to avoid clash with DRF renderer + peergroup_template = models.ForeignKey( to=PeerGroupTemplate, on_delete=models.PROTECT, related_name="peer_groups", blank=True, null=True ) @@ -375,6 +406,34 @@ class PeerGroup(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): null=True, ) + csv_headers = [ + "name", + "routing_instance", + "autonomous_system", + "import_policy", + "export_policy", + "source_interface", + "source_ip", + "peergroup_template", + "enabled", + "role", + ] + + def to_csv(self): + """Export data.""" + return ( + self.name, + self.routing_instance.pk, + self.autonomous_system.asn if self.autonomous_system else None, + self.import_policy, + self.export_policy, + self.source_interface.name if self.source_interface else None, + self.source_ip.address if self.source_ip else None, + self.peergroup_template.name if self.peergroup_template else None, + self.enabled, + self.role.name if self.role else None, + ) + def __str__(self): """String.""" return f"{self.name}" @@ -415,16 +474,16 @@ def clean(self): class PeerEndpoint(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): """BGP information about single endpoint of a peering.""" - extra_attributes_inheritance = ["peer_group", "peer_group.template", "routing_instance"] + extra_attributes_inheritance = ["peer_group", "peer_group.peergroup_template", "routing_instance"] property_inheritance = { - "autonomous_system": ["peer_group", "peer_group.template", "routing_instance"], - "description": ["peer_group", "peer_group.template"], - "enabled": ["peer_group", "peer_group.template"], - "export_policy": ["peer_group", "peer_group.template"], - "import_policy": ["peer_group", "peer_group.template"], + "autonomous_system": ["peer_group", "peer_group.peergroup_template", "routing_instance"], + "description": ["peer_group", "peer_group.peergroup_template"], + "enabled": ["peer_group", "peer_group.peergroup_template"], + "export_policy": ["peer_group", "peer_group.peergroup_template"], + "import_policy": ["peer_group", "peer_group.peergroup_template"], "source_ip": ["peer_group"], "source_interface": ["peer_group"], - "role": ["peer_group.role", "peer_group.template.role"], + "role": ["peer_group.role", "peer_group.peergroup_template.role"], } description = models.CharField(max_length=200, blank=True) @@ -489,6 +548,18 @@ class PeerEndpoint(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): verbose_name="Source Interface", ) + csv_headers = [ + "routing_instance", + "peer", + ] + + def to_csv(self): + """Export data.""" + return ( + self.routing_instance, + self.peer, + ) + @property def local_ip(self): """Compute effective peering endpoint IP address. @@ -669,6 +740,26 @@ class Meta: verbose_name = "BGP address family" verbose_name_plural = "BGP Address Families" + csv_headers = [ + "routing_instance", + "vrf", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + ] + + def to_csv(self): + """Export data.""" + return ( + self.routing_instance.pk, + self.vrf.name if self.vrf else None, + self.afi_safi, + self.import_policy, + self.export_policy, + self.multipath, + ) + def __str__(self): """String representation of a single AddressFamily.""" if self.vrf: diff --git a/nautobot_bgp_models/navigation.py b/nautobot_bgp_models/navigation.py index 339a374b..cc901a43 100644 --- a/nautobot_bgp_models/navigation.py +++ b/nautobot_bgp_models/navigation.py @@ -1,6 +1,6 @@ """Nautobot UI navigation elements for nautobot_bgp_models.""" -from nautobot.core.apps import NavMenuAddButton, NavMenuGroup, NavMenuItem, NavMenuTab +from nautobot.core.apps import NavMenuAddButton, NavMenuGroup, NavMenuItem, NavMenuTab, NavMenuImportButton menu_items = ( NavMenuTab( @@ -20,6 +20,10 @@ link="plugins:nautobot_bgp_models:autonomoussystem_add", permissions=["nautobot_bgp_models.add_autonomoussystem"], ), + NavMenuImportButton( + link="plugins:nautobot_bgp_models:autonomoussystem_import", + permissions=["nautobot_bgp_models.add_autonomoussystem"], + ), ), ), NavMenuItem( @@ -31,6 +35,10 @@ link="plugins:nautobot_bgp_models:peeringrole_add", permissions=["nautobot_bgp_models.add_peeringrole"], ), + NavMenuImportButton( + link="plugins:nautobot_bgp_models:peeringrole_import", + permissions=["nautobot_bgp_models.add_peeringrole"], + ), ), ), NavMenuItem( @@ -42,6 +50,10 @@ link="plugins:nautobot_bgp_models:peergrouptemplate_add", permissions=["nautobot_bgp_models.add_peergrouptemplate"], ), + NavMenuImportButton( + link="plugins:nautobot_bgp_models:peergrouptemplate_import", + permissions=["nautobot_bgp_models.add_peergrouptemplate"], + ), ), ), ), @@ -57,7 +69,11 @@ buttons=( NavMenuAddButton( link="plugins:nautobot_bgp_models:bgproutinginstance_add", - permissions=["nautobot_bgp_models.add_peeringrole"], + permissions=["nautobot_bgp_models.add_bgproutinginstance"], + ), + NavMenuImportButton( + link="plugins:nautobot_bgp_models:bgproutinginstance_import", + permissions=["nautobot_bgp_models.add_bgproutinginstance"], ), ), ), @@ -70,6 +86,10 @@ link="plugins:nautobot_bgp_models:peergroup_add", permissions=["nautobot_bgp_models.add_peergroup"], ), + NavMenuImportButton( + link="plugins:nautobot_bgp_models:peergroup_import", + permissions=["nautobot_bgp_models.add_peergroup"], + ), ), ), NavMenuItem( @@ -81,6 +101,10 @@ link="plugins:nautobot_bgp_models:addressfamily_add", permissions=["nautobot_bgp_models.add_addressfamily"], ), + NavMenuImportButton( + link="plugins:nautobot_bgp_models:addressfamily_import", + permissions=["nautobot_bgp_models.add_addressfamily"], + ), ), ), ), diff --git a/nautobot_bgp_models/tables.py b/nautobot_bgp_models/tables.py index 84f95e51..29d454a4 100644 --- a/nautobot_bgp_models/tables.py +++ b/nautobot_bgp_models/tables.py @@ -56,6 +56,7 @@ class Meta(BaseTable.Meta): "autonomous_system", "router_id", "actions", + "status", ) @@ -83,7 +84,7 @@ class PeerGroupTable(BaseTable): pk = ToggleColumn() name = tables.LinkColumn() - template = tables.LinkColumn() + peergroup_template = tables.LinkColumn() routing_instance = tables.LinkColumn() enabled = BooleanColumn() role = ColoredLabelColumn() @@ -99,7 +100,7 @@ class Meta(BaseTable.Meta): fields = ( "pk", "name", - "template", + "peergroup_template", "routing_instance", "enabled", "role", @@ -113,7 +114,7 @@ class Meta(BaseTable.Meta): default_columns = ( "pk", "name", - "template", + "peergroup_template", "routing_instance", "enabled", "role", @@ -156,7 +157,7 @@ class Meta(BaseTable.Meta): "import_policy", "export_policy", "secret", - "actions", + # "actions", ) diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily.html b/nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily_retrieve.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily_retrieve.html diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/autonomoussystem.html b/nautobot_bgp_models/templates/nautobot_bgp_models/autonomoussystem_retrieve.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/autonomoussystem.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/autonomoussystem_retrieve.html diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance.html b/nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance_retrieve.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance_retrieve.html diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peerendpoint.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peerendpoint_retrieve.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/peerendpoint.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/peerendpoint_retrieve.html diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup_retrieve.html similarity index 98% rename from nautobot_bgp_models/templates/nautobot_bgp_models/peergroup.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/peergroup_retrieve.html index 8d1f2ec4..0d1c5c9c 100644 --- a/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup.html +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup_retrieve.html @@ -34,7 +34,7 @@ Template - {% include "nautobot_bgp_models/inc/native_property.html" with property=object.template %} + {% include "nautobot_bgp_models/inc/native_property.html" with property=object.peergroup_template %} diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate_retrieve.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate_retrieve.html diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peering_add.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/peering_create.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/peering_add.html diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peering.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peering_retrieve.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/peering.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/peering_retrieve.html diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peeringrole.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peeringrole_retrieve.html similarity index 100% rename from nautobot_bgp_models/templates/nautobot_bgp_models/peeringrole.html rename to nautobot_bgp_models/templates/nautobot_bgp_models/peeringrole_retrieve.html diff --git a/nautobot_bgp_models/tests/test_api.py b/nautobot_bgp_models/tests/test_api.py index 1f903188..09f6427b 100644 --- a/nautobot_bgp_models/tests/test_api.py +++ b/nautobot_bgp_models/tests/test_api.py @@ -1,9 +1,11 @@ """Unit tests for nautobot_bgp_models.""" # pylint: disable=too-many-lines + from unittest import skip from rest_framework import status from django.test import override_settings from django.contrib.contenttypes.models import ContentType + from nautobot.circuits.models import Provider from nautobot.dcim.choices import InterfaceTypeChoices from nautobot.dcim.models import Device, DeviceRole, DeviceType, Interface, Manufacturer, Site @@ -52,10 +54,6 @@ def setUpTestData(cls): {"asn": 4294967294, "status": "active", "description": "Reserved for private use"}, ] - @skip("Not implemented") - def test_notes_url_on_object(self): - pass - class PeeringRoleAPITestCase(APIViewTestCases.APIViewTestCase): """Test the PeeringRole API.""" @@ -78,10 +76,6 @@ def setUpTestData(cls): models.PeeringRole.objects.create(name="Beta", slug="beta", color="00ff00") models.PeeringRole.objects.create(name="Gamma", slug="gamma", color="0000ff") - @skip("Not implemented") - def test_notes_url_on_object(self): - pass - class PeerGroupTemplateAPITestCase(APIViewTestCases.APIViewTestCase): """Test the PeerGroupTemplate API.""" @@ -178,10 +172,6 @@ def test_peer_group_template_extra_attributes(self): # Ensure extra_attributes are as on the model self.assertEqual(extra_attrs, pgt1_ea) - @skip("Not implemented") - def test_notes_url_on_object(self): - pass - class BGPRoutingInstanceAPITestCase(APIViewTestCases.APIViewTestCase): """Test the BGPRoutingInstance API.""" @@ -193,6 +183,8 @@ class BGPRoutingInstanceAPITestCase(APIViewTestCases.APIViewTestCase): "description": "Glenn was here.", } + choices_fields = ["status"] + # Nautobot testing doesn't correctly handle the API representation of a Status as a slug instead of a PK yet. validation_excluded_fields = ["status"] @@ -200,6 +192,7 @@ class BGPRoutingInstanceAPITestCase(APIViewTestCases.APIViewTestCase): def setUpTestData(cls): # pylint: disable=too-many-locals status_active = Status.objects.get(slug="active") status_active.content_types.add(ContentType.objects.get_for_model(models.AutonomousSystem)) + status_active.content_types.add(ContentType.objects.get_for_model(models.BGPRoutingInstance)) manufacturer = Manufacturer.objects.create(name="Cisco", slug="cisco") devicetype = DeviceType.objects.create(manufacturer=manufacturer, model="CSR 1000V", slug="csr1000v") @@ -240,6 +233,7 @@ def setUpTestData(cls): # pylint: disable=too-many-locals "device": device_1.pk, "router_id": address.pk, "extra_attributes": {"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}}, + "status": "active", }, ] @@ -253,14 +247,17 @@ def setUpTestData(cls): # pylint: disable=too-many-locals device=device_2, autonomous_system=asn_5616, extra_attributes={"key1": 1, "key2": {"nested_key2": "nested_value2", "nk2": 2}}, + status=status_active, ) models.BGPRoutingInstance.objects.create( device=device_3, autonomous_system=asn_8545, + status=status_active, ) models.BGPRoutingInstance.objects.create( device=device_4, autonomous_system=asn_15521, + status=status_active, ) cls.maxDiff = None @@ -349,6 +346,7 @@ def setUpTestData(cls): # pylint: disable=too-many-locals autonomous_system=asn_8545, device=device, extra_attributes={"ri_key": "ri_value", "ri_nk": {"ri_nk": "ri_nv", "ri_nk2": "ri_nv2"}}, + status=status_active, ) cls.create_data = [ @@ -400,7 +398,7 @@ def setUpTestData(cls): # pylint: disable=too-many-locals role=peeringrole, routing_instance=bgp_routing_instance, extra_attributes={"pg_key": "pg_value", "ri_nk": {"pg_nk": "pg_nv", "ri_nk2": "pg_nv2"}}, - template=pgt1, + peergroup_template=pgt1, ) models.PeerGroup.objects.create(name="Group 2", role=peeringrole, routing_instance=bgp_routing_instance) @@ -622,6 +620,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=cls.asn, device=device, + status=cls.status_active, ) cls.pgt1 = models.PeerGroupTemplate.objects.create( @@ -633,7 +632,7 @@ def setUpTestData(cls): name="Group 1", role=cls.peeringrole, routing_instance=cls.bgp_routing_instance, - template=cls.pgt1, + peergroup_template=cls.pgt1, extra_attributes={"pg_key": "pg_value"}, # vrf=cls.vrf, # router_id=cls.addresses[3], @@ -689,10 +688,6 @@ def setUpTestData(cls): cls.maxDiff = None - @skip("Not implemented") - def test_notes_url_on_object(self): - pass - @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) def test_peerendpoint_inherits_extra_attributes(self): """Test PeerEndpoint's inheritance path for extra attributes.""" @@ -904,10 +899,6 @@ def setUpTestData(cls): "status": "provisioning", } - @skip("Not implemented") - def test_notes_url_on_object(self): - pass - class AddressFamilyAPITestCase(APIViewTestCases.APIViewTestCase): """Test the AddressFamily API.""" @@ -945,6 +936,7 @@ def setUpTestData(cls): # pylint: disable=too-many-locals description="Hello World!", autonomous_system=asn_8545, device=device, + status=status_active, ) # interface_1 = Interface.objects.create(device=device, name="Loopback1", type=InterfaceTypeChoices.TYPE_VIRTUAL) @@ -1021,10 +1013,6 @@ def setUpTestData(cls): # pylint: disable=too-many-locals "export_policy": "EXPORT_V4", } - @skip("Not implemented") - def test_notes_url_on_object(self): - pass - # @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) # def test_get_object_include_inherited(self): diff --git a/nautobot_bgp_models/tests/test_filters.py b/nautobot_bgp_models/tests/test_filters.py index 4643bd8a..67f25501 100644 --- a/nautobot_bgp_models/tests/test_filters.py +++ b/nautobot_bgp_models/tests/test_filters.py @@ -129,6 +129,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=cls.asn_1, device=cls.device_1, + status=status_active, ) models.PeerGroup.objects.create( @@ -231,6 +232,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=asn, device=device, + status=status_active, ) cls.peergroup = models.PeerGroup.objects.create( @@ -331,6 +333,7 @@ def setUpTestData(cls): # pylint: disable=too-many-locals description="Hello World!", autonomous_system=asn1, device=device1, + status=status_active, ) interfaces_device1 = [ @@ -499,6 +502,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=asn1, device=device1, + status=status_active, ) cls.peergroup = models.PeerGroup.objects.create( diff --git a/nautobot_bgp_models/tests/test_forms.py b/nautobot_bgp_models/tests/test_forms.py index abf6e13c..dfef90e7 100644 --- a/nautobot_bgp_models/tests/test_forms.py +++ b/nautobot_bgp_models/tests/test_forms.py @@ -79,6 +79,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=asn_1, device=cls.device_1, + status=status_active, ) def test_valid_form(self): @@ -181,6 +182,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=asn_1, device=cls.device_1, + status=status_active, ) # clustertype = ClusterType.objects.create(name="Cluster Type A", slug="cluster-type-a") @@ -285,6 +287,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=cls.asn_1, device=cls.device_1, + status=status_active, ) def test_valid_form(self): diff --git a/nautobot_bgp_models/tests/test_models.py b/nautobot_bgp_models/tests/test_models.py index 5d44dd0e..8add834b 100644 --- a/nautobot_bgp_models/tests/test_models.py +++ b/nautobot_bgp_models/tests/test_models.py @@ -32,7 +32,7 @@ def test_str(self): def test_to_csv(self): """Test CSV representation of an AutonomousSystem.""" - self.assertEqual(self.autonomous_system.to_csv(), (15521, "Hi ex Premium Internet AS!", "Active")) + self.assertEqual(self.autonomous_system.to_csv(), (15521, "Hi ex Premium Internet AS!", "Active", None)) class PeeringRoleTestCase(TestCase): @@ -85,12 +85,17 @@ def setUp(self): description="Hello World!", autonomous_system=self.autonomous_system_8545, device=self.device_1, + status=self.status_active, ) def test_str(self): """Test string representation of a PeerGroup.""" self.assertEqual(str(self.bgp_routing_instance), f"{self.device_1} - {self.autonomous_system_8545}") + def test_to_csv(self): + """Test CSV representation of a BGPRoutingInstance.""" + self.assertEqual(self.bgp_routing_instance.to_csv(), ("Device 1", 8545, None, "Active", "Hello World!")) + class PeerGroupTestCase(TestCase): """Test the PeerGroup model.""" @@ -121,6 +126,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=autonomous_system_5616, device=device_1, + status=status_active, ) def setUp(self): @@ -133,6 +139,12 @@ def test_str(self): """Test string representation of a PeerGroup.""" self.assertEqual(str(self.peergroup), f"{self.peergroup.name}") + def test_to_csv(self): + """Test CSV representation of a PeerGroup.""" + self.assertEqual( + self.peergroup.to_csv(), ("Peer Group A", "Device 1", None, "", "", None, None, None, True, None) + ) + # def test_vrf_fixup_from_router_id(self): # """If VRF is None, but the router-id references a VRF, use that.""" # vrf = VRF.objects.create(name="red") @@ -187,6 +199,7 @@ def setUpTestData(cls): description="BGP Routing Instance for device 1", autonomous_system=autonomous_system_12345, device=device_1, + status=status_active, ) cls.bgp_routing_instance_1 = bgp_routing_instance_1 @@ -194,6 +207,7 @@ def setUpTestData(cls): description="BGP Routing Instance for device 2", autonomous_system=autonomous_system_12345, device=device_2, + status=status_active, ) cls.bgp_routing_instance_2 = bgp_routing_instance_2 @@ -400,6 +414,7 @@ def setUp(self): description="BGP Routing Instance for device 1", autonomous_system=self.autonomous_system_12345, device=self.device, + status=self.status_active, ) # interface = Interface.objects.create(device=self.device, name="Loopback1") @@ -433,6 +448,10 @@ def test_str(self): self.assertEqual("ipv4_unicast AF - Device 1", str(self.addressfamily_1)) self.assertEqual("ipv4_unicast AF (VRF global) Device 1", str(self.addressfamily_2)) + def test_to_csv(self): + """Test CSV representation of a AddressFamily.""" + self.assertEqual(self.addressfamily_1.to_csv(), ("Device 1", None, "ipv4_unicast", "", "", None)) + # def test_peer_group_peer_endpoint_mutual_exclusion(self): # addressfamily = models.AddressFamily( diff --git a/nautobot_bgp_models/tests/test_views.py b/nautobot_bgp_models/tests/test_views.py index d834ccec..b534dbe5 100644 --- a/nautobot_bgp_models/tests/test_views.py +++ b/nautobot_bgp_models/tests/test_views.py @@ -1,6 +1,6 @@ """Unit test automation for Model classes in nautobot_bgp_models.""" -from unittest import skip, skipIf +from unittest import skipIf from packaging import version from django.contrib.contenttypes.models import ContentType @@ -33,14 +33,6 @@ class AutonomousSystemTestCase(ViewTestCases.PrimaryObjectViewTestCase): test_bulk_import_objects_with_permission = None test_bulk_import_objects_with_constrained_permission = None - @skip("Route disabled in commit `c97f037f`") - def test_bulk_import_objects_with_permission_csv_file(self): - pass - - @skip("Route disabled in commit `c97f037f`") - def test_get_object_notes(self): - pass - @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") def test_list_objects_with_permission(self): super().test_list_objects_with_permission() @@ -75,12 +67,12 @@ def setUpTestData(cls): "tags": [tag.pk for tag in tags], } - # cls.csv_data = ( - # "asn,status", - # "4200000003,active", - # "4200000004,active", - # "4200000005,active", - # ) + cls.csv_data = ( + "asn,description,status", + "4200000003,asn3,active", + "4200000004,asn4,active", + "4200000005,asn5,active", + ) cls.bulk_edit_data = { "description": "New description", @@ -96,14 +88,6 @@ class PeeringRoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTe test_bulk_import_objects_with_permission = None test_bulk_import_objects_with_constrained_permission = None - @skip("Route disabled in commit `c97f037f`") - def test_bulk_import_objects_with_permission_csv_file(self): - pass - - @skip("Route disabled in commit `c97f037f`") - def test_get_object_notes(self): - pass - @skipIf(_NAUTOBOT_VERSION in _FAILING_OBJECT_LIST_NAUTOBOT_VERSIONS, f"Skip Nautobot version {_NAUTOBOT_VERSION}") def test_list_objects_with_permission(self): super().test_list_objects_with_permission() @@ -183,6 +167,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=asn_1, device=cls.device_1, + status=status_active, ) models.PeerGroup.objects.create(routing_instance=bgp_routing_instance, name="Group A", role=peeringrole) @@ -191,6 +176,13 @@ def setUpTestData(cls): cls.form_data = {"name": "Group D", "routing_instance": bgp_routing_instance.pk} + cls.csv_data = ( + "name,routing_instance", + f"Group E,{bgp_routing_instance.pk}", + f"Group F,{bgp_routing_instance.pk}", + f"Group G,{bgp_routing_instance.pk}", + ) + cls.bulk_edit_data = {"description": "Generic description"} @@ -239,6 +231,7 @@ def setUpTestData(cls): # pylint: disable=too-many-locals description="Hello World!", autonomous_system=asn_1, device=device, + status=status_active, ) interface = Interface.objects.create(name="Loopback1", device=device) @@ -388,6 +381,7 @@ def setUpTestData(cls): description="Hello World!", autonomous_system=asn_1, device=device, + status=status_active, ) models.AddressFamily.objects.create( diff --git a/nautobot_bgp_models/urls.py b/nautobot_bgp_models/urls.py index faa7500f..0ee6fb03 100644 --- a/nautobot_bgp_models/urls.py +++ b/nautobot_bgp_models/urls.py @@ -1,177 +1,54 @@ """Django urlpatterns declaration for nautobot_bgp_models plugin.""" from django.urls import path -from nautobot.extras.views import ObjectChangeLogView +from nautobot.core.views.routers import NautobotUIViewSetRouter from . import models, views +router = NautobotUIViewSetRouter() +router.register("autonomous-systems", views.AutonomousSystemUIViewSet) +router.register("routing-instances", views.BGPRoutingInstanceUIViewSet) +router.register("peering-roles", views.PeeringRoleUIViewSet) +router.register("peer-groups", views.PeerGroupUIViewSet) +router.register("peer-group-templates", views.PeerGroupTemplateUIViewSet) +router.register("peer-endpoints", views.PeerEndpointUIViewSet) +router.register("peerings", views.PeeringUIViewSet) +router.register("address-families", views.AddressFamilyUIViewSet) + urlpatterns = [ - path("autonomous-systems/", views.AutonomousSystemListView.as_view(), name="autonomoussystem_list"), - path("autonomous-systems/add/", views.AutonomousSystemEditView.as_view(), name="autonomoussystem_add"), - # path("autonomous-systems/import/", views.AutonomousSystemBulkImportView.as_view(), name="autonomoussystem_import"), - path("autonomous-systems/edit/", views.AutonomousSystemBulkEditView.as_view(), name="autonomoussystem_bulk_edit"), - path( - "autonomous-systems/delete/", - views.AutonomousSystemBulkDeleteView.as_view(), - name="autonomoussystem_bulk_delete", - ), - path("autonomous-systems//", views.AutonomousSystemView.as_view(), name="autonomoussystem"), - path("autonomous-systems//edit/", views.AutonomousSystemEditView.as_view(), name="autonomoussystem_edit"), - path( - "autonomous-systems//delete/", - views.AutonomousSystemDeleteView.as_view(), - name="autonomoussystem_delete", - ), - path( - "autonomous-systems//changelog/", - ObjectChangeLogView.as_view(), - name="autonomoussystem_changelog", - kwargs={"model": models.AutonomousSystem}, - ), - path("routing-instances/", views.BGPRoutingInstanceListView.as_view(), name="bgproutinginstance_list"), - path("routing-instances/add/", views.BGPRoutingInstanceEditView.as_view(), name="bgproutinginstance_add"), - path( - "routing-instances/edit/", views.BGPRoutingInstanceBulkEditView.as_view(), name="bgproutinginstance_bulk_edit" - ), - path( - "routing-instances/delete/", - views.BGPRoutingInstanceBulkDeleteView.as_view(), - name="bgproutinginstance_bulk_delete", - ), - path("routing-instances//", views.BGPRoutingInstanceView.as_view(), name="bgproutinginstance"), - path( - "routing-instances//edit/", views.BGPRoutingInstanceEditView.as_view(), name="bgproutinginstance_edit" - ), - path( - "routing-instances//delete/", - views.BGPRoutingInstanceDeleteView.as_view(), - name="bgproutinginstance_delete", - ), - path( - "routing-instances//changelog/", - ObjectChangeLogView.as_view(), - name="bgproutinginstance_changelog", - kwargs={"model": models.BGPRoutingInstance}, - ), + # Extra Attribute views. path( "routing-instances//extra-attributes/", views.BgpExtraAttributesView.as_view(), name="bgproutinginstance_extraattributes", kwargs={"model": models.BGPRoutingInstance}, ), - path("peering-roles/", views.PeeringRoleListView.as_view(), name="peeringrole_list"), - path("peering-roles/add/", views.PeeringRoleEditView.as_view(), name="peeringrole_add"), - # path("peering-roles/import/", views.PeeringRoleBulkImportView.as_view(), name="peeringrole_import"), - path("peering-roles/edit/", views.PeeringRoleBulkEditView.as_view(), name="peeringrole_bulk_edit"), - path("peering-roles/delete/", views.PeeringRoleBulkDeleteView.as_view(), name="peeringrole_bulk_delete"), - path("peering-roles//", views.PeeringRoleView.as_view(), name="peeringrole"), - path("peering-roles//edit/", views.PeeringRoleEditView.as_view(), name="peeringrole_edit"), - path("peering-roles//delete/", views.PeeringRoleDeleteView.as_view(), name="peeringrole_delete"), - path( - "peering-roles//changelog/", - ObjectChangeLogView.as_view(), - name="peeringrole_changelog", - kwargs={"model": models.PeeringRole}, - ), - path("peer-groups/", views.PeerGroupListView.as_view(), name="peergroup_list"), - path("peer-groups/add/", views.PeerGroupEditView.as_view(), name="peergroup_add"), - path("peer-group/edit/", views.PeerGroupBulkEditView.as_view(), name="peergroup_bulk_edit"), - path( - "peer-group/delete/", - views.PeerGroupBulkDeleteView.as_view(), - name="peergroup_bulk_delete", - ), - path("peer-groups//", views.PeerGroupView.as_view(), name="peergroup"), - path("peer-groups//edit/", views.PeerGroupEditView.as_view(), name="peergroup_edit"), - path("peer-groups//delete/", views.PeerGroupDeleteView.as_view(), name="peergroup_delete"), - path( - "peer-groups//changelog/", - ObjectChangeLogView.as_view(), - name="peergroup_changelog", - kwargs={"model": models.PeerGroup}, - ), path( "peer-groups//extra-attributes/", views.BgpExtraAttributesView.as_view(), name="peergroup_extraattributes", kwargs={"model": models.PeerGroup}, ), - path("peer-group-templates/", views.PeerGroupTemplateListView.as_view(), name="peergrouptemplate_list"), - path("peer-group-templates/add/", views.PeerGroupTemplateEditView.as_view(), name="peergrouptemplate_add"), - path( - "peer-group-templates/edit/", views.PeerGroupTemplateBulkEditView.as_view(), name="peergrouptemplate_bulk_edit" - ), - path( - "peer-group-templates/delete/", - views.PeerGroupTemplateBulkDeleteView.as_view(), - name="peergrouptemplate_bulk_delete", - ), - path("peer-group-templates//", views.PeerGroupTemplateView.as_view(), name="peergrouptemplate"), - path( - "peer-group-templates//edit/", views.PeerGroupTemplateEditView.as_view(), name="peergrouptemplate_edit" - ), - path( - "peer-group-templates//delete/", - views.PeerGroupTemplateDeleteView.as_view(), - name="peergrouptemplate_delete", - ), - path( - "peer-group-templates//changelog/", - ObjectChangeLogView.as_view(), - name="peergrouptemplate_changelog", - kwargs={"model": models.PeerGroupTemplate}, - ), path( "peer-group-templates//extra-attributes/", views.BgpExtraAttributesView.as_view(), name="peergrouptemplate_extraattributes", kwargs={"model": models.PeerGroupTemplate}, ), - path("peer-endpoints/", views.PeerEndpointListView.as_view(), name="peerendpoint_list"), - path("peer-endpoints/add/", views.PeerEndpointEditView.as_view(), name="peerendpoint_add"), - path("peer-endpoints//", views.PeerEndpointView.as_view(), name="peerendpoint"), - path("peer-endpoints//edit/", views.PeerEndpointEditView.as_view(), name="peerendpoint_edit"), - path("peer-endpoints//delete/", views.PeerEndpointDeleteView.as_view(), name="peerendpoint_delete"), - path( - "peer-endpoints//changelog/", - ObjectChangeLogView.as_view(), - name="peerendpoint_changelog", - kwargs={"model": models.PeerEndpoint}, - ), path( "peer-endpoints//extra-attributes/", views.BgpExtraAttributesView.as_view(), name="peerendpoint_extraattributes", kwargs={"model": models.PeerEndpoint}, ), - path("peerings/", views.PeeringListView.as_view(), name="peering_list"), path("peerings/add/", views.PeeringAddView.as_view(), name="peering_add"), - path("peerings/delete/", views.PeeringBulkDeleteView.as_view(), name="peering_bulk_delete"), - path("peerings//", views.PeeringView.as_view(), name="peering"), - path("peerings//edit/", views.PeeringEditView.as_view(), name="peering_edit"), - path("peerings//delete/", views.PeeringDeleteView.as_view(), name="peering_delete"), + # These three urls are to be removed once #3809 is fixed. + path("peer-groups/import/", views.PeerGroupImportView.as_view(), name="peergroup_import"), # Remove after #3809 path( - "peerings//changelog/", - ObjectChangeLogView.as_view(), - name="peering_changelog", - kwargs={"model": models.Peering}, - ), + "peer-groups-templates/import/", views.PeerGroupTemplateImportView.as_view(), name="peergroup_template_import" + ), # Remove after #3809 path( - "peerings//endpoint/add/", - views.PeerEndpointEditView.as_view(), - name="peerendpoint_add", - ), - path("address-families/", views.AddressFamilyListView.as_view(), name="addressfamily_list"), - path("address-families/add/", views.AddressFamilyEditView.as_view(), name="addressfamily_add"), - path("address-families/edit/", views.AddressFamilyBulkEditView.as_view(), name="addressfamily_bulk_edit"), - path("address-families/delete/", views.AddressFamilyBulkDeleteView.as_view(), name="addressfamily_bulk_delete"), - path("address-families//", views.AddressFamilyView.as_view(), name="addressfamily"), - path("address-families//edit/", views.AddressFamilyEditView.as_view(), name="addressfamily_edit"), - path("address-families//delete/", views.AddressFamilyDeleteView.as_view(), name="addressfamily_delete"), - path( - "address-families//changelog/", - ObjectChangeLogView.as_view(), - name="addressfamily_changelog", - kwargs={"model": models.AddressFamily}, - ), + "address-families/import/", views.AddressFamilyImportView.as_view(), name="addressfamily_import" + ), # Remove after #3809 ] +urlpatterns += router.urls diff --git a/nautobot_bgp_models/views.py b/nautobot_bgp_models/views.py index 2fb75b1f..7ffe7c3a 100644 --- a/nautobot_bgp_models/views.py +++ b/nautobot_bgp_models/views.py @@ -1,341 +1,144 @@ """View classes for nautobot_bgp_models.""" - -from django import template from django.core.exceptions import ValidationError from django.db import transaction from django.shortcuts import get_object_or_404, redirect, render from django.views.generic import View +from nautobot.apps.views import NautobotUIViewSet +from nautobot.core.views import mixins from nautobot.core.views import generic +from nautobot.extras.utils import get_base_template from . import filters, forms, models, tables +from .api import serializers -class AutonomousSystemListView(generic.ObjectListView): - """List/table view of AutonomousSystem records.""" - - queryset = models.AutonomousSystem.objects.all() - table = tables.AutonomousSystemTable - filterset = filters.AutonomousSystemFilterSet - filterset_form = forms.AutonomousSystemFilterForm - action_buttons = ("add",) - - -class AutonomousSystemView(generic.ObjectView): - """Detail view of a single AutonomousSystem.""" - - queryset = models.AutonomousSystem.objects.all() - - -class AutonomousSystemEditView(generic.ObjectEditView): - """Create/edit view for an AutonomousSystem.""" - - queryset = models.AutonomousSystem.objects.all() - model_form = forms.AutonomousSystemForm - - -class AutonomousSystemDeleteView(generic.ObjectDeleteView): - """Delete view for an AutonomousSystem.""" - - queryset = models.AutonomousSystem.objects.all() - - -# class AutonomousSystemBulkImportView(generic.BulkImportView): -# """Bulk-importing view for multiple AutonomousSystems.""" -# -# queryset = models.AutonomousSystem.objects.all() -# model_form = forms.AutonomousSystemCSVForm -# table = tables.AutonomousSystemTable - - -class AutonomousSystemBulkEditView(generic.BulkEditView): - """Bulk-editing view for multiple AutonomousSystems.""" +class AutonomousSystemUIViewSet(NautobotUIViewSet): + """UIViewset for AutonomousSystem model.""" + bulk_create_form_class = forms.AutonomousSystemCSVForm + bulk_update_form_class = forms.AutonomousSystemBulkEditForm + filterset_class = filters.AutonomousSystemFilterSet + filterset_form_class = forms.AutonomousSystemFilterForm + form_class = forms.AutonomousSystemForm + lookup_field = "pk" queryset = models.AutonomousSystem.objects.all() - filterset = filters.AutonomousSystemFilterSet - table = tables.AutonomousSystemTable - form = forms.AutonomousSystemBulkEditForm - - -class AutonomousSystemBulkDeleteView(generic.BulkDeleteView): - """Bulk-deleting view for multiple AutonomousSystems.""" - - queryset = models.AutonomousSystem.objects.all() - filterset = filters.AutonomousSystemFilterSet - table = tables.AutonomousSystemTable - - -class BGPRoutingInstanceListView(generic.ObjectListView): - """List/table view of BGPRoutingInstance records.""" - - queryset = models.BGPRoutingInstance.objects.all() - table = tables.BGPRoutingInstanceTable - filterset = filters.BGPRoutingInstanceFilterSet - filterset_form = forms.BGPRoutingInstanceFilterForm - action_buttons = ("add",) - - -class BGPRoutingInstanceView(generic.ObjectView): - """Detail view of a single BGPRoutingInstance.""" - - queryset = models.BGPRoutingInstance.objects.all() - - -class BGPRoutingInstanceEditView(generic.ObjectEditView): - """Create/edit view for an BGPRoutingInstance.""" - - queryset = models.BGPRoutingInstance.objects.all() - model_form = forms.BGPRoutingInstanceForm - - -class BGPRoutingInstanceDeleteView(generic.ObjectDeleteView): - """Delete view for an BGPRoutingInstance.""" - - queryset = models.BGPRoutingInstance.objects.all() - - -class BGPRoutingInstanceBulkEditView(generic.BulkEditView): - """Bulk-editing view for multiple BGPRoutingInstances.""" - - queryset = models.BGPRoutingInstance.objects.all() - filterset = filters.BGPRoutingInstanceFilterSet - table = tables.BGPRoutingInstanceTable - form = forms.BGPRoutingInstanceBulkEditForm + serializer_class = serializers.AutonomousSystemSerializer + table_class = tables.AutonomousSystemTable -class BGPRoutingInstanceBulkDeleteView(generic.BulkDeleteView): - """Bulk-deleting view for multiple BGPRoutingInstances.""" +class BGPRoutingInstanceUIViewSet(NautobotUIViewSet): + """UIViewset for BGPRoutingInstance model.""" + bulk_create_form_class = forms.BGPRoutingInstanceCSVForm + bulk_update_form_class = forms.BGPRoutingInstanceBulkEditForm + filterset_class = filters.BGPRoutingInstanceFilterSet + filterset_form_class = forms.BGPRoutingInstanceFilterForm + form_class = forms.BGPRoutingInstanceForm + lookup_field = "pk" queryset = models.BGPRoutingInstance.objects.all() - filterset = filters.BGPRoutingInstanceFilterSet - table = tables.BGPRoutingInstanceTable - - -class PeeringRoleListView(generic.ObjectListView): - """List/table view of PeeringRole records.""" - - queryset = models.PeeringRole.objects.all() - table = tables.PeeringRoleTable - filterset = filters.PeeringRoleFilterSet - filterset_form = forms.PeeringRoleFilterForm - action_buttons = ("add",) - - -class PeeringRoleView(generic.ObjectView): - """Detail view of a single PeeringRole.""" - - queryset = models.PeeringRole.objects.all() - - -class PeeringRoleEditView(generic.ObjectEditView): - """Create/edit view for a PeeringRole.""" - - queryset = models.PeeringRole.objects.all() - model_form = forms.PeeringRoleForm - - -class PeeringRoleDeleteView(generic.ObjectDeleteView): - """Delete view for a PeeringRole.""" + serializer_class = serializers.BGPRoutingInstanceSerializer + table_class = tables.BGPRoutingInstanceTable - queryset = models.PeeringRole.objects.all() - - -# class PeeringRoleBulkImportView(generic.BulkImportView): -# """Bulk-importing view for multiple PeeringRoles.""" -# -# queryset = models.PeeringRole.objects.all() -# model_form = forms.PeeringRoleCSVForm -# table = tables.PeeringRoleTable - - -class PeeringRoleBulkEditView(generic.BulkEditView): - """Bulk-editing view for multiple PeeringRoles.""" - queryset = models.PeeringRole.objects.all() - filterset = filters.PeeringRoleFilterSet - table = tables.PeeringRoleTable - form = forms.PeeringRoleBulkEditForm - - -class PeeringRoleBulkDeleteView(generic.BulkDeleteView): - """Bulk-deleting view for multiple PeeringRoles.""" +class PeeringRoleUIViewSet(NautobotUIViewSet): + """UIViewset for PeeringRole model.""" + bulk_create_form_class = forms.PeeringRoleCSVForm + bulk_update_form_class = forms.PeeringRoleBulkEditForm + filterset_class = filters.PeeringRoleFilterSet + filterset_form_class = forms.PeeringRoleFilterForm + form_class = forms.PeeringRoleForm queryset = models.PeeringRole.objects.all() - filterset = filters.PeeringRoleFilterSet - table = tables.PeeringRoleTable - - -class PeerGroupListView(generic.ObjectListView): - """List/table view of PeerGroup records.""" - - queryset = models.PeerGroup.objects.all() - table = tables.PeerGroupTable - filterset = filters.PeerGroupFilterSet - filterset_form = forms.PeerGroupFilterForm - action_buttons = ("add",) - - -class PeerGroupView(generic.ObjectView): - """Detail view of a single PeerGroup.""" - - queryset = models.PeerGroup.objects.all() - - def get_extra_context(self, request, instance): - """Return any additional context data for the template.""" - return {"object_fields": instance.get_fields(include_inherited=True)} - - -class PeerGroupEditView(generic.ObjectEditView): - """Create/edit view for a PeerGroup.""" - - queryset = models.PeerGroup.objects.all() - model_form = forms.PeerGroupForm - - -class PeerGroupDeleteView(generic.ObjectDeleteView): - """Delete view for a PeerGroup.""" - - queryset = models.PeerGroup.objects.all() - - -class PeerGroupBulkEditView(generic.BulkEditView): - """Bulk-editing view for multiple PeerGroup.""" - - queryset = models.PeerGroup.objects.all() - filterset = filters.PeerGroupFilterSet - table = tables.PeerGroupTable - form = forms.PeerGroupBulkEditForm + serializer_class = serializers.PeeringRoleSerializer + table_class = tables.PeeringRoleTable -class PeerGroupBulkDeleteView(generic.BulkDeleteView): - """Bulk-deleting view for multiple PeerGroup.""" +class PeerGroupUIViewSet(NautobotUIViewSet): + """UIViewset for PeerGroup model.""" + bulk_create_form_class = forms.PeerGroupCSVForm + bulk_update_form_class = forms.PeerGroupBulkEditForm + filterset_class = filters.PeerGroupFilterSet + filterset_form_class = forms.PeerGroupFilterForm + form_class = forms.PeerGroupForm + lookup_field = "pk" queryset = models.PeerGroup.objects.all() - filterset = filters.PeerGroupFilterSet - table = tables.PeerGroupTable - - -class PeerGroupTemplateView(generic.ObjectView): - """Detail view of a single PeerGroupTemplate.""" - - queryset = models.PeerGroupTemplate.objects.all() - - # def get_extra_context(self, request, instance): - # """Return any additional context data for the template.""" - # return {"object_fields": instance.get_fields(include_inherited=True)} - - -class PeerGroupTemplateListView(generic.ObjectListView): - """List/table view of PeerGroupTemplate records.""" - - queryset = models.PeerGroupTemplate.objects.all() - table = tables.PeerGroupTemplateTable - filterset = filters.PeerGroupTemplateFilterSet - filterset_form = forms.PeerGroupTemplateFilterForm - action_buttons = ("add",) + serializer_class = serializers.PeerGroupSerializer + table_class = tables.PeerGroupTable -class PeerGroupTemplateEditView(generic.ObjectEditView): - """Create/edit view for a PeerGroupTemplate.""" +class PeerGroupImportView(generic.BulkImportView): + """Workaround for #3809.""" - queryset = models.PeerGroupTemplate.objects.all() - model_form = forms.PeerGroupTemplateForm - - -class PeerGroupTemplateDeleteView(generic.ObjectDeleteView): - """Delete view for a PeerGroup.""" - - queryset = models.PeerGroupTemplate.objects.all() + queryset = PeerGroupUIViewSet.queryset + model_form = PeerGroupUIViewSet.bulk_create_form_class + table = PeerGroupUIViewSet.table_class -class PeerGroupTemplateBulkEditView(generic.BulkEditView): - """Bulk-editing view for multiple PeerGroupTemplate.""" +class PeerGroupTemplateUIViewSet(NautobotUIViewSet): + """UIViewset for PeerGroupTemplate model.""" + bulk_create_form_class = forms.PeerGroupTemplateCSVForm + bulk_update_form_class = forms.PeerGroupTemplateBulkEditForm + filterset_class = filters.PeerGroupTemplateFilterSet + filterset_form_class = forms.PeerGroupTemplateFilterForm + form_class = forms.PeerGroupTemplateForm + lookup_field = "pk" queryset = models.PeerGroupTemplate.objects.all() - filterset = filters.PeerGroupTemplateFilterSet - table = tables.PeerGroupTemplateTable - form = forms.PeerGroupTemplateBulkEditForm - - -class PeerGroupTemplateBulkDeleteView(generic.BulkDeleteView): - """Bulk-deleting view for multiple PeerGroupTemplate.""" - - queryset = models.PeerGroupTemplate.objects.all() - filterset = filters.PeerGroupTemplateFilterSet - table = tables.PeerGroupTemplateTable - - -class PeerEndpointListView(generic.ObjectListView): - """List/table view of PeerEndpoint records.""" - - queryset = models.PeerEndpoint.objects.all() - table = tables.PeerEndpointTable - filterset = filters.PeerEndpointFilterSet - action_buttons = ("add",) - - -class PeerEndpointView(generic.ObjectView): - """Detail view of a single PeerEndpoint.""" - - queryset = models.PeerEndpoint.objects.all() - - def get_extra_context(self, request, instance): - """Return any additional context data for the template.""" - return {"object_fields": instance.get_fields(include_inherited=True)} - + serializer_class = serializers.PeerGroupTemplateSerializer + table_class = tables.PeerGroupTemplateTable -class PeerEndpointEditView(generic.ObjectEditView): - """Create/edit view for a PeerEndpoint.""" - queryset = models.PeerEndpoint.objects.all() - model_form = forms.PeerEndpointForm - - def alter_obj(self, obj, request, url_args, url_kwargs): - """Inject peering object into form from url args.""" - if "peering" in url_kwargs: - obj.peering = get_object_or_404(models.Peering, pk=url_kwargs["peering"]) - return obj +class PeerGroupTemplateImportView(generic.BulkImportView): + """Workaround for #3809.""" - def get_return_url(self, request, obj, *args, **kwargs): - """Return to main Peering page after edit.""" - return obj.peering.get_absolute_url() + queryset = PeerGroupTemplateUIViewSet.queryset + model_form = PeerGroupTemplateUIViewSet.bulk_create_form_class + table = PeerGroupTemplateUIViewSet.table_class -class PeerEndpointDeleteView(generic.ObjectDeleteView): - """Delete view for a PeerEndpoint.""" +class PeerEndpointUIViewSet(NautobotUIViewSet): + """UIViewset for PeerEndpoint model.""" + bulk_create_form_class = forms.PeerEndpointCSVForm + bulk_update_form_class = forms.PeerEndpointBulkEditForm + filterset_class = filters.PeerEndpointFilterSet + filterset_form_class = forms.PeerEndpointFilterForm + form_class = forms.PeerEndpointForm + lookup_field = "pk" queryset = models.PeerEndpoint.objects.all() - - -class PeeringListView(generic.ObjectListView): - """List/table view of Peering records.""" - + serializer_class = serializers.PeerEndpointSerializer + table_class = tables.PeerEndpointTable + + +class PeeringUIViewSet( # pylint: disable=abstract-method + mixins.ObjectDestroyViewMixin, + mixins.ObjectBulkDestroyViewMixin, + mixins.ObjectEditViewMixin, + mixins.ObjectListViewMixin, + mixins.ObjectDetailViewMixin, + mixins.ObjectChangeLogViewMixin, + mixins.ObjectNotesViewMixin, +): + """UIViewset for Peering model.""" + + filterset_class = filters.PeeringFilterSet + filterset_form_class = forms.PeeringFilterForm + form_class = forms.PeeringForm + lookup_field = "pk" queryset = models.Peering.objects.all() - table = tables.PeeringTable - filterset = filters.PeeringFilterSet - filterset_form = forms.PeeringFilterForm - action_buttons = ("add",) - - -class PeeringView(generic.ObjectView): - """Detail view of a single Peering.""" - - queryset = models.Peering.objects.all() - - -class PeeringEditView(generic.ObjectEditView): - """Create/edit view for a Peering.""" - - queryset = models.Peering.objects.all() - model_form = forms.PeeringForm + serializer_class = serializers.PeeringSerializer + table_class = tables.PeeringTable +# TODO: This needs to be moved to the UIViewSet class PeeringAddView(generic.ObjectEditView): - """Create/edit view for a Peering.""" + """Create view for a Peering.""" queryset = models.Peering.objects.all() - template_name = "nautobot_bgp_models/peering_create.html" + template_name = "nautobot_bgp_models/peering_add.html" def post(self, request, *args, **kwargs): """Post Method.""" @@ -390,64 +193,26 @@ def get(self, request, *args, **kwargs): ) -class PeeringDeleteView(generic.ObjectDeleteView): - """Delete view for a Peering.""" - - queryset = models.Peering.objects.all() - - -class PeeringBulkDeleteView(generic.BulkDeleteView): - """Bulk-deleting view for multiple Peering.""" - - queryset = models.Peering.objects.all() - filterset = filters.PeeringFilterSet - table = tables.PeeringTable - - -class AddressFamilyListView(generic.ObjectListView): - """List/table view of AddressFamily records.""" - - queryset = models.AddressFamily.objects.all() - table = tables.AddressFamilyTable - filterset = filters.AddressFamilyFilterSet - filterset_form = forms.AddressFamilyFilterForm - action_buttons = ("add",) - - -class AddressFamilyView(generic.ObjectView): - """Detail view of a single AddressFamily.""" - - queryset = models.AddressFamily.objects.all() - - -class AddressFamilyEditView(generic.ObjectEditView): - """Create/edit view for an AddressFamily.""" +class AddressFamilyUIViewSet(NautobotUIViewSet): + """UIViewset for AddressFamily model.""" + bulk_create_form_class = forms.AddressFamilyCSVForm + bulk_update_form_class = forms.AddressFamilyBulkEditForm + filterset_class = filters.AddressFamilyFilterSet + filterset_form_class = forms.AddressFamilyFilterForm + form_class = forms.AddressFamilyForm + lookup_field = "pk" queryset = models.AddressFamily.objects.all() - model_form = forms.AddressFamilyForm + serializer_class = serializers.AddressFamilySerializer + table_class = tables.AddressFamilyTable -class AddressFamilyDeleteView(generic.ObjectDeleteView): - """Delete view for an AddressFamily.""" +class AddressFamilyImportView(generic.BulkImportView): + """Workaround for #3809.""" - queryset = models.AddressFamily.objects.all() - - -class AddressFamilyBulkEditView(generic.BulkEditView): - """Bulk-editing view for multiple AddressFamily.""" - - queryset = models.AddressFamily.objects.all() - filterset = filters.AddressFamilyFilterSet - table = tables.AddressFamilyTable - form = forms.AddressFamilyBulkEditForm - - -class AddressFamilyBulkDeleteView(generic.BulkDeleteView): - """Bulk-deleting view for multiple AddressFamily.""" - - queryset = models.AddressFamily.objects.all() - filterset = filters.AddressFamilyFilterSet - table = tables.AddressFamilyTable + queryset = AddressFamilyUIViewSet.queryset + model_form = AddressFamilyUIViewSet.bulk_create_form_class + table = AddressFamilyUIViewSet.table_class class BgpExtraAttributesView(View): @@ -463,15 +228,7 @@ def get(self, request, model, **kwargs): # pylint: disable=missing-function-doc else: obj = get_object_or_404(model, **kwargs) - # Default to using "/.html" as the template, if it exists. Otherwise, - # fall back to using base.html. - if self.base_template is None: - self.base_template = f"{model._meta.app_label}/{model._meta.model_name}.html" - # TODO: This can be removed once an object view has been established for every model. - try: - template.loader.get_template(self.base_template) - except template.TemplateDoesNotExist: - self.base_template = "base.html" + self.base_template = get_base_template(self.base_template, model) # Determine user's preferred output format if request.GET.get("format") in ["json", "yaml"]: From 2029f4a9ba307c051abd5518ad6135086417f77d Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Wed, 14 Jun 2023 12:29:04 +0200 Subject: [PATCH 42/61] unittest fix --- nautobot_bgp_models/tests/test_models.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nautobot_bgp_models/tests/test_models.py b/nautobot_bgp_models/tests/test_models.py index 8add834b..4fd30820 100644 --- a/nautobot_bgp_models/tests/test_models.py +++ b/nautobot_bgp_models/tests/test_models.py @@ -142,7 +142,8 @@ def test_str(self): def test_to_csv(self): """Test CSV representation of a PeerGroup.""" self.assertEqual( - self.peergroup.to_csv(), ("Peer Group A", "Device 1", None, "", "", None, None, None, True, None) + self.peergroup.to_csv(), + ("Peer Group A", self.bgp_routing_instance.pk, None, "", "", None, None, None, True, None), ) # def test_vrf_fixup_from_router_id(self): @@ -450,7 +451,10 @@ def test_str(self): def test_to_csv(self): """Test CSV representation of a AddressFamily.""" - self.assertEqual(self.addressfamily_1.to_csv(), ("Device 1", None, "ipv4_unicast", "", "", None)) + self.assertEqual( + self.addressfamily_1.to_csv(), + (self.bgp_routing_instance_1.pk, None, "ipv4_unicast", "", "", None), + ) # def test_peer_group_peer_endpoint_mutual_exclusion(self): From e1eb00dff7c9d905d4cef0982b37e262e305cd01 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 22 Jun 2023 14:34:48 +0200 Subject: [PATCH 43/61] Updating CSVModelForm to CustomFieldModelCSVForm in forms --- nautobot_bgp_models/forms.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nautobot_bgp_models/forms.py b/nautobot_bgp_models/forms.py index 436dee51..7dd9e087 100644 --- a/nautobot_bgp_models/forms.py +++ b/nautobot_bgp_models/forms.py @@ -4,7 +4,7 @@ import nautobot.utilities.forms as utilities_forms from nautobot.apps.forms import ( CSVModelChoiceField, - CSVModelForm, + CustomFieldModelCSVForm, DynamicModelMultipleChoiceField, DynamicModelChoiceField, NautobotModelForm, @@ -41,7 +41,7 @@ class AutonomousSystemFilterForm(NautobotFilterForm): tag = TagFilterField(model) -class AutonomousSystemCSVForm(StatusModelCSVFormMixin, CSVModelForm): +class AutonomousSystemCSVForm(StatusModelCSVFormMixin, CustomFieldModelCSVForm): """Form for importing AutonomousSystems from CSV data.""" provider = CSVModelChoiceField( @@ -179,7 +179,7 @@ class Meta: ] -class BGPRoutingInstanceCSVForm(StatusModelCSVFormMixin, CSVModelForm): +class BGPRoutingInstanceCSVForm(StatusModelCSVFormMixin, CustomFieldModelCSVForm): """Form for importing BGPRoutingInstance from CSV data.""" device = CSVModelChoiceField( @@ -224,7 +224,7 @@ class PeeringRoleFilterForm(NautobotFilterForm): color = forms.CharField(max_length=6, required=False, widget=utilities_forms.ColorSelect()) -class PeeringRoleCSVForm(CSVModelForm): +class PeeringRoleCSVForm(CustomFieldModelCSVForm): """Form for importing PeeringRole records from CSV data.""" class Meta: @@ -402,7 +402,7 @@ class PeerGroupTemplateFilterForm(NautobotFilterForm): ) -class PeerGroupTemplateCSVForm(CSVModelForm): +class PeerGroupTemplateCSVForm(CustomFieldModelCSVForm): """Form for importing PeerGroupTemplate from CSV data.""" role = CSVModelChoiceField( @@ -424,7 +424,7 @@ class Meta: fields = models.PeerGroupTemplate.csv_headers -class PeerGroupCSVForm(CSVModelForm): +class PeerGroupCSVForm(CustomFieldModelCSVForm): """Form for importing PeerGroup from CSV data.""" peergroup_template = CSVModelChoiceField( @@ -555,7 +555,7 @@ def save(self, commit=True): return endpoint -class PeerEndpointCSVForm(CSVModelForm): +class PeerEndpointCSVForm(CustomFieldModelCSVForm): """Form for importing PeerEndpoint from CSV data.""" class Meta: @@ -669,7 +669,7 @@ class AddressFamilyFilterForm(NautobotFilterForm): vrf = DynamicModelMultipleChoiceField(queryset=VRF.objects.all(), required=False) -class AddressFamilyCSVForm(CSVModelForm): +class AddressFamilyCSVForm(CustomFieldModelCSVForm): """Form for importing AddressFamily from CSV data.""" class Meta: From c6ad7c90dad3bed6be111bfad55ac3ed63694604 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 22 Jun 2023 14:37:30 +0200 Subject: [PATCH 44/61] #96 Migration cleanup --- ...ame_template_peergroup_peergroup_template.py | 17 ----------------- ...nce_status.py => 0002_viewsets_migration.py} | 10 +++++++--- 2 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py rename nautobot_bgp_models/migrations/{0003_bgproutinginstance_status.py => 0002_viewsets_migration.py} (70%) diff --git a/nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py b/nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py deleted file mode 100644 index 2d0742f5..00000000 --- a/nautobot_bgp_models/migrations/0002_rename_template_peergroup_peergroup_template.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.18 on 2023-03-15 21:03 - -from django.db import migrations - - -class Migration(migrations.Migration): - dependencies = [ - ("nautobot_bgp_models", "0001_initial"), - ] - - operations = [ - migrations.RenameField( - model_name="peergroup", - old_name="template", - new_name="peergroup_template", - ), - ] diff --git a/nautobot_bgp_models/migrations/0003_bgproutinginstance_status.py b/nautobot_bgp_models/migrations/0002_viewsets_migration.py similarity index 70% rename from nautobot_bgp_models/migrations/0003_bgproutinginstance_status.py rename to nautobot_bgp_models/migrations/0002_viewsets_migration.py index c4f86433..e4cc3b51 100644 --- a/nautobot_bgp_models/migrations/0003_bgproutinginstance_status.py +++ b/nautobot_bgp_models/migrations/0002_viewsets_migration.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.16 on 2023-05-25 08:42 +# Generated by Django 3.2.18 on 2023-03-15 21:03 from django.db import migrations import django.db.models.deletion @@ -7,11 +7,15 @@ class Migration(migrations.Migration): dependencies = [ - ("extras", "0053_relationship_required_on"), - ("nautobot_bgp_models", "0002_rename_template_peergroup_peergroup_template"), + ("nautobot_bgp_models", "0001_initial"), ] operations = [ + migrations.RenameField( + model_name="peergroup", + old_name="template", + new_name="peergroup_template", + ), migrations.AddField( model_name="bgproutinginstance", name="status", From c4dc1ddb58159c71a3d51e484fdf92793beda65d Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 22 Jun 2023 14:40:41 +0200 Subject: [PATCH 45/61] Adding status check for BGP Routing Instance --- nautobot_bgp_models/models.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nautobot_bgp_models/models.py b/nautobot_bgp_models/models.py index 91496fb8..319c3a85 100644 --- a/nautobot_bgp_models/models.py +++ b/nautobot_bgp_models/models.py @@ -257,6 +257,12 @@ def to_csv(self): self.description, ) + def clean(self): + """Clean.""" + # Ensure .status attribute: + if not self.status: + raise ValidationError("Status must be defined for the BGP Routing Instance.") + @extras_features( "custom_fields", From 902dd913e9b54e37bf60fb3e10c4ca6773e89e57 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Mon, 24 Jul 2023 13:40:20 +0200 Subject: [PATCH 46/61] Device Role and Peer Endpoint Role filters for Peering model --- nautobot_bgp_models/filters.py | 16 +++++++++++++++- nautobot_bgp_models/forms.py | 18 +++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/nautobot_bgp_models/filters.py b/nautobot_bgp_models/filters.py index cbfd746f..3a0c0485 100644 --- a/nautobot_bgp_models/filters.py +++ b/nautobot_bgp_models/filters.py @@ -4,7 +4,7 @@ from django.db.models import Q -from nautobot.dcim.models import Device +from nautobot.dcim.models import Device, DeviceRole from nautobot.extras.filters import StatusModelFilterSetMixin, CreatedUpdatedFilterSet, CustomFieldModelFilterSet from nautobot.ipam.models import VRF from nautobot.utilities.filters import BaseFilterSet, NameSlugSearchFilterSet, TagFilter @@ -224,6 +224,20 @@ class PeeringFilterSet(BaseFilterSet, CreatedUpdatedFilterSet, CustomFieldModelF label="Device (name)", ) + device_role = django_filters.ModelMultipleChoiceFilter( + field_name="endpoints__routing_instance__device__device_role__name", + queryset=DeviceRole.objects.all(), + to_field_name="name", + label="Device Role (name)", + ) + + peer_endpoint_role = django_filters.ModelMultipleChoiceFilter( + field_name="endpoints__role__name", + queryset=models.PeeringRole.objects.all(), + to_field_name="name", + label="Peer Endpoint Role (name)", + ) + class Meta: model = models.Peering fields = ["id"] diff --git a/nautobot_bgp_models/forms.py b/nautobot_bgp_models/forms.py index 7dd9e087..613342fc 100644 --- a/nautobot_bgp_models/forms.py +++ b/nautobot_bgp_models/forms.py @@ -14,7 +14,7 @@ TagsBulkEditFormMixin, ) from nautobot.circuits.models import Provider -from nautobot.dcim.models import Device, Interface +from nautobot.dcim.models import Device, DeviceRole, Interface from nautobot.extras.forms import NautobotFilterForm from nautobot.extras.models import Tag, Secret from nautobot.ipam.models import VRF, IPAddress @@ -593,16 +593,24 @@ class PeeringFilterForm(NautobotFilterForm): model = models.Peering field_order = [ "q", - "role", "status", "device", + "device_role", + "peer_endpoint_role", ] - role = DynamicModelMultipleChoiceField( - queryset=models.PeeringRole.objects.all(), to_field_name="slug", required=False - ) device = DynamicModelMultipleChoiceField(queryset=Device.objects.all(), to_field_name="name", required=False) + device_role = DynamicModelMultipleChoiceField( + queryset=DeviceRole.objects.all(), + to_field_name="name", + required=False, + ) + + peer_endpoint_role = DynamicModelMultipleChoiceField( + queryset=models.PeeringRole.objects.all(), to_field_name="name", required=False + ) + class AddressFamilyForm(NautobotModelForm): """Form for creating/updating AddressFamily records.""" From a8e39bcd4174451805ef20dbff188cb07fd84ef8 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Mon, 24 Jul 2023 13:54:30 +0200 Subject: [PATCH 47/61] Disable endpoint ordering in Peering table until fixed --- nautobot_bgp_models/tables.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nautobot_bgp_models/tables.py b/nautobot_bgp_models/tables.py index 29d454a4..af6f4c41 100644 --- a/nautobot_bgp_models/tables.py +++ b/nautobot_bgp_models/tables.py @@ -228,11 +228,12 @@ class PeeringTable(StatusTableMixin, BaseTable): ) endpoint_a = tables.LinkColumn( - verbose_name="Endpoint", text=lambda x: str(x.endpoint_a.local_ip) if x.endpoint_a else None + verbose_name="Endpoint", text=lambda x: str(x.endpoint_a.local_ip) if x.endpoint_a else None, orderable=False + ) endpoint_z = tables.LinkColumn( - verbose_name="Endpoint", text=lambda x: str(x.endpoint_z.local_ip) if x.endpoint_z else None + verbose_name="Endpoint", text=lambda x: str(x.endpoint_z.local_ip) if x.endpoint_z else None, orderable=False ) actions = ButtonsColumn(model=models.Peering) From 64383d15883b97fae690b1f936fcb4be52152a65 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Mon, 24 Jul 2023 14:16:30 +0200 Subject: [PATCH 48/61] Disable peering ordering in Peering table until fixed --- nautobot_bgp_models/tables.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nautobot_bgp_models/tables.py b/nautobot_bgp_models/tables.py index af6f4c41..dda314ad 100644 --- a/nautobot_bgp_models/tables.py +++ b/nautobot_bgp_models/tables.py @@ -225,6 +225,7 @@ class PeeringTable(StatusTableMixin, BaseTable): viewname="plugins:nautobot_bgp_models:peering", args=[A("pk")], text=str, + orderable=False, ) endpoint_a = tables.LinkColumn( From d6119b0b48699e60cc20ef6b98528712fde5acc4 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Mon, 24 Jul 2023 14:27:45 +0200 Subject: [PATCH 49/61] Fixing black. --- nautobot_bgp_models/tables.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nautobot_bgp_models/tables.py b/nautobot_bgp_models/tables.py index dda314ad..c2c4a8b8 100644 --- a/nautobot_bgp_models/tables.py +++ b/nautobot_bgp_models/tables.py @@ -230,7 +230,6 @@ class PeeringTable(StatusTableMixin, BaseTable): endpoint_a = tables.LinkColumn( verbose_name="Endpoint", text=lambda x: str(x.endpoint_a.local_ip) if x.endpoint_a else None, orderable=False - ) endpoint_z = tables.LinkColumn( From 318531281132526d55843b0b4f4af35f4f944de7 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Fri, 11 Aug 2023 16:47:18 +0200 Subject: [PATCH 50/61] Adding unit tests for Peering model filters --- nautobot_bgp_models/tests/test_filters.py | 144 ++++++++++++++++++---- 1 file changed, 118 insertions(+), 26 deletions(-) diff --git a/nautobot_bgp_models/tests/test_filters.py b/nautobot_bgp_models/tests/test_filters.py index 67f25501..72c4e861 100644 --- a/nautobot_bgp_models/tests/test_filters.py +++ b/nautobot_bgp_models/tests/test_filters.py @@ -314,38 +314,45 @@ def setUpTestData(cls): # pylint: disable=too-many-locals manufacturer = Manufacturer.objects.create(name="Cisco", slug="cisco") devicetype = DeviceType.objects.create(manufacturer=manufacturer, model="CSR 1000V", slug="csr1000v") site = Site.objects.create(name="Site 1", slug="site-1") - devicerole = DeviceRole.objects.create(name="Router", slug="router", color="ff0000") + devicerole_router = DeviceRole.objects.create(name="Router", slug="router", color="ff0000") + devicerole_switch = DeviceRole.objects.create(name="Switch", slug="switch", color="ff0000") device1 = Device.objects.create( device_type=devicetype, - device_role=devicerole, + device_role=devicerole_router, name="device1", site=site, status=status_active, ) - # device2 = Device.objects.create( - # device_type=devicetype, - # device_role=devicerole, - # name="device2", - # site=site, - # status=status_active - # ) + device2 = Device.objects.create( + device_type=devicetype, + device_role=devicerole_switch, + name="device2", + site=site, + status=status_active, + ) cls.bgp_routing_instance = models.BGPRoutingInstance.objects.create( - description="Hello World!", + description="Device 1 RI", autonomous_system=asn1, device=device1, status=status_active, ) + cls.bgp_routing_instance_device_2 = models.BGPRoutingInstance.objects.create( + description="Device 2 RI", + autonomous_system=asn1, + device=device2, + status=status_active, + ) + interfaces_device1 = [ Interface.objects.create(device=device1, name="Loopback0"), Interface.objects.create(device=device1, name="Loopback1"), Interface.objects.create(device=device1, name="Loopback2"), ] - # interfaces_device2 = [ - # Interface.objects.create(device=device2, name="Loopback0"), - # Interface.objects.create(device=device2, name="Loopback1"), - # Interface.objects.create(device=device2, name="Loopback2"), - # ] + interfaces_device2 = [ + Interface.objects.create(device=device2, name="Loopback0"), + Interface.objects.create(device=device2, name="Loopback1"), + ] addresses = [ IPAddress.objects.create( @@ -375,47 +382,115 @@ def setUpTestData(cls): # pylint: disable=too-many-locals address="10.1.1.6/24", status=status_reserved, ), + IPAddress.objects.create( + address="10.1.1.7/24", + status=status_reserved, + assigned_object=interfaces_device2[0], + ), + IPAddress.objects.create( + address="10.1.1.8/24", + status=status_reserved, + ), + IPAddress.objects.create( + address="10.1.1.9/24", + status=status_reserved, + assigned_object=interfaces_device2[1], + ), + IPAddress.objects.create( + address="10.1.1.10/24", + status=status_reserved, + ), ] - # peeringrole_internal = models.PeeringRole.objects.create(name="Internal", slug="internal", color="ffffff") - # peeringrole_external = models.PeeringRole.objects.create(name="External", slug="external", color="ffffff") + peeringrole_internal = models.PeeringRole.objects.create(name="Internal", slug="internal", color="ffffff") + peeringrole_external = models.PeeringRole.objects.create(name="External", slug="external", color="ffffff") peerings = [ + # Peering #0 models.Peering.objects.create(status=status_active), + # Peering #1 models.Peering.objects.create(status=status_active), + # Peering #2 models.Peering.objects.create(status=status_reserved), + # Peering #3 + models.Peering.objects.create(status=status_active), + # Peering #4 + models.Peering.objects.create(status=status_active), ] + # Peering #0 models.PeerEndpoint.objects.create( source_ip=addresses[0], peering=peerings[0], autonomous_system=asn1, + role=peeringrole_internal, + routing_instance=cls.bgp_routing_instance, ) models.PeerEndpoint.objects.create( source_ip=addresses[1], peering=peerings[0], autonomous_system=asn1, + role=peeringrole_external, ) + # Peering #1 models.PeerEndpoint.objects.create( source_ip=addresses[2], peering=peerings[1], autonomous_system=asn1, + role=peeringrole_internal, + routing_instance=cls.bgp_routing_instance, ) models.PeerEndpoint.objects.create( source_ip=addresses[3], peering=peerings[1], autonomous_system=asn2, + role=peeringrole_external, ) + + # Peering #2 models.PeerEndpoint.objects.create( source_ip=addresses[4], peering=peerings[2], autonomous_system=asn1, + role=peeringrole_internal, + routing_instance=cls.bgp_routing_instance, ) models.PeerEndpoint.objects.create( source_ip=addresses[5], peering=peerings[2], autonomous_system=asn3, + role=peeringrole_external, + ) + + # Peering #3 + models.PeerEndpoint.objects.create( + source_ip=addresses[6], + peering=peerings[3], + autonomous_system=asn1, + role=peeringrole_internal, + routing_instance=cls.bgp_routing_instance_device_2, + ) + models.PeerEndpoint.objects.create( + source_ip=addresses[7], + peering=peerings[3], + autonomous_system=asn3, + role=peeringrole_external, + ) + + # Peering #4 + models.PeerEndpoint.objects.create( + source_ip=addresses[8], + peering=peerings[4], + autonomous_system=asn1, + role=peeringrole_internal, + routing_instance=cls.bgp_routing_instance_device_2, + ) + models.PeerEndpoint.objects.create( + source_ip=addresses[9], + peering=peerings[4], + autonomous_system=asn3, + role=peeringrole_external, ) def test_id(self): @@ -423,27 +498,44 @@ def test_id(self): params = {"id": self.queryset.values_list("pk", flat=True)[:2]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - # def test_role(self): - # """Test filtering by role.""" - # params = {"role": ["external"]} - # self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_status(self): """Test filtering by status.""" params = {"status": ["active"]} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) def test_device(self): """Test filtering by device name.""" - params = {"device": "device1"} + params = {"device": ["device1"]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) - # params = {"device": "device2"} - # self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0) + params = {"device": ["device2"]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {"device": ["device1", "device2"]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + + def test_device_role(self): + """Test filtering by device role name.""" + params = {"device_role": ["Router"]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) + params = {"device_role": ["Switch"]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + params = {"device_role": ["Router", "Switch"]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + + def test_peer_endpoint_role(self): + """Test filtering by peer endpoint role name.""" + params = {"peer_endpoint_role": ["internal"]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + + params = {"peer_endpoint_role": ["external"]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + + params = {"peer_endpoint_role": ["router", "switch"]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + # def test_asn(self): # """Test filtering by asn name.""" # params = {"asn": [65000]} From a508c79bf48e58155fb51d70f39660a6592431bb Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Fri, 11 Aug 2023 17:29:14 +0200 Subject: [PATCH 51/61] Fix missing status field in BGP Routing Instance form Add unit tests for BGP Routing Instance form --- nautobot_bgp_models/forms.py | 1 + nautobot_bgp_models/tests/test_forms.py | 42 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/nautobot_bgp_models/forms.py b/nautobot_bgp_models/forms.py index 7dd9e087..b01711b4 100644 --- a/nautobot_bgp_models/forms.py +++ b/nautobot_bgp_models/forms.py @@ -127,6 +127,7 @@ class Meta: fields = ( "device", "autonomous_system", + "status", "description", "router_id", "peergroup_template", diff --git a/nautobot_bgp_models/tests/test_forms.py b/nautobot_bgp_models/tests/test_forms.py index dfef90e7..160b5469 100644 --- a/nautobot_bgp_models/tests/test_forms.py +++ b/nautobot_bgp_models/tests/test_forms.py @@ -46,6 +46,48 @@ def test_status_required(self): self.assertEqual("This field is required.", form.errors["status"][0]) +class BGPRoutingInstanceTestCase(TestCase): + """Test the BGPRoutingInstance create/edit form.""" + + form_class = forms.BGPRoutingInstanceForm + + @classmethod + def setUpTestData(cls): + """Set up class-wide data for the test.""" + cls.status_active = Status.objects.get(slug="active") + cls.status_active.content_types.add(ContentType.objects.get_for_model(models.BGPRoutingInstance)) + cls.status_active.content_types.add(ContentType.objects.get_for_model(models.AutonomousSystem)) + manufacturer = Manufacturer.objects.create(name="Cisco", slug="cisco") + devicetype = DeviceType.objects.create(manufacturer=manufacturer, model="CSR 1000V", slug="csr1000v") + site = Site.objects.create(name="Site 1", slug="site-1") + devicerole = DeviceRole.objects.create(name="Router", slug="router", color="ff0000") + cls.device = Device.objects.create( + device_type=devicetype, device_role=devicerole, name="Device 1", site=site, status=cls.status_active + ) + cls.asn = models.AutonomousSystem.objects.create(asn=4294967291, status=cls.status_active) + + def test_valid_form(self): + """Add a device through form.""" + data = { + "autonomous_system": self.asn, + "device": self.device, + "status": self.status_active, + "description": "RI for Device 1", + } + form = self.form_class(data) + self.assertTrue(form.is_valid(), form.errors) + self.assertTrue(form.save()) + + routing_instance = models.BGPRoutingInstance.objects.get(device=self.device) + self.assertEqual(routing_instance.device, self.device) + + def test_status_required(self): + data = {"autonomous_system": self.asn, "device": self.device} + form = self.form_class(data) + self.assertFalse(form.is_valid()) + self.assertEqual("This field is required.", form.errors["status"][0]) + + class PeerGroupFormTestCase(TestCase): """Test the PeerGroup create/edit form.""" From 7024de15b801da978cc1958d26557cb79549aebf Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Fri, 18 Aug 2023 11:56:38 +0200 Subject: [PATCH 52/61] Remove enforcement for ASN's provider --- nautobot_bgp_models/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nautobot_bgp_models/models.py b/nautobot_bgp_models/models.py index 319c3a85..260adaf0 100644 --- a/nautobot_bgp_models/models.py +++ b/nautobot_bgp_models/models.py @@ -642,9 +642,9 @@ def clean(self): if self.routing_instance: if local_ip_value not in IPAddress.objects.filter(interface__device_id=self.routing_instance.device.id): raise ValidationError("Peer IP not associated with Routing Instance") - else: - if not asn_value.provider: - raise ValidationError("ASN requires a specified Provider") + # Enforce Routing Instance if local IP belongs to the Device + elif not self.routing_instance and local_ip_value.interface.exists(): + raise ValidationError("Must specify Routing Instance for this IP Address") @extras_features( From b923c544291efb47b87ddc78fe6c1274133f4de0 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Fri, 18 Aug 2023 12:51:37 +0200 Subject: [PATCH 53/61] Fix unit test for API Peer Endpoint model --- nautobot_bgp_models/tests/test_api.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/nautobot_bgp_models/tests/test_api.py b/nautobot_bgp_models/tests/test_api.py index 09f6427b..4e419b86 100644 --- a/nautobot_bgp_models/tests/test_api.py +++ b/nautobot_bgp_models/tests/test_api.py @@ -652,18 +652,19 @@ def setUpTestData(cls): autonomous_system=cls.provider_asn, peering=cls.peering[0], ) + + # Peering #3 models.PeerEndpoint.objects.create( + routing_instance=cls.bgp_routing_instance, source_ip=cls.addresses[2], autonomous_system=cls.provider_asn, peering=cls.peering[3], ) - # models.PeerEndpoint.objects.create( - # source_ip=cls.addresses[3], - # autonomous_system=cls.provider_asn, - # peering=cls.peering[3] - # ) - - # models.PeerEndpoint.objects.create(local_ip=cls.addresses[2], peer_group=peergroup, peering=cls.peering[1]) + models.PeerEndpoint.objects.create( + source_ip=cls.addresses[3], + autonomous_system=cls.provider_asn, + peering=cls.peering[3], + ) cls.create_data = [ # Peering #1 @@ -678,12 +679,6 @@ def setUpTestData(cls): "autonomous_system": cls.provider_asn.pk, "peering": cls.peering[1].pk, }, - { - "source_ip": cls.addresses[2].pk, - "routing_instance": cls.bgp_routing_instance.pk, - "peer_group": peergroup.pk, - "peering": cls.peering[1].pk, - }, ] cls.maxDiff = None From 9d4175f51233ee538fe33cf028473a57d8b57ea8 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 24 Aug 2023 09:53:35 +0200 Subject: [PATCH 54/61] Dropping Python 3.7 --- .github/workflows/ci.yml | 4 +- nautobot_bgp_models/__init__.py | 12 +- nautobot_bgp_models/tests/test_views.py | 8 +- poetry.lock | 1340 +++++++++-------------- pyproject.toml | 2 +- 5 files changed, 537 insertions(+), 829 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ac8ee38..774d96a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,14 +119,14 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10"] db-backend: ["postgresql"] nautobot-version: ["stable"] include: - python-version: "3.10" db-backend: "postgresql" nautobot-version: "1.5.4" - - python-version: "3.7" + - python-version: "3.8" db-backend: "mysql" nautobot-version: "1.5.4" - python-version: "3.10" diff --git a/nautobot_bgp_models/__init__.py b/nautobot_bgp_models/__init__.py index 13e854fa..57c550e8 100644 --- a/nautobot_bgp_models/__init__.py +++ b/nautobot_bgp_models/__init__.py @@ -1,17 +1,11 @@ """Plugin declaration for nautobot_bgp_models.""" -try: - from importlib import metadata -except ImportError: - # Running on pre-3.8 Python; use importlib-metadata package - import importlib_metadata as metadata - -__version__ = metadata.version(__name__) - +from importlib import metadata from django.db.models.signals import post_migrate - from nautobot.extras.plugins import PluginConfig +__version__ = metadata.version(__name__) + class NautobotBGPModelsConfig(PluginConfig): """Plugin configuration for the nautobot_bgp_models plugin.""" diff --git a/nautobot_bgp_models/tests/test_views.py b/nautobot_bgp_models/tests/test_views.py index b534dbe5..a10b69a7 100644 --- a/nautobot_bgp_models/tests/test_views.py +++ b/nautobot_bgp_models/tests/test_views.py @@ -1,7 +1,8 @@ """Unit test automation for Model classes in nautobot_bgp_models.""" -from unittest import skipIf +from importlib import metadata from packaging import version +from unittest import skipIf from django.contrib.contenttypes.models import ContentType from nautobot.circuits.models import Provider @@ -13,11 +14,6 @@ from nautobot_bgp_models import models from nautobot_bgp_models.choices import AFISAFIChoices -try: - from importlib import metadata -except ImportError: - # Running on pre-3.8 Python; use importlib-metadata package - import importlib_metadata as metadata _NAUTOBOT_VERSION = version.parse(metadata.version("nautobot")) # Related to this issue: https://github.com/nautobot/nautobot/issues/2948 diff --git a/poetry.lock b/poetry.lock index 84890f65..847f41fd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "amqp" version = "5.1.1" description = "Low-level AMQP client for Python (fork of amqplib)." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -19,7 +18,6 @@ vine = ">=5.0.0" name = "aniso8601" version = "7.0.0" description = "A library for parsing ISO 8601 strings." -category = "main" optional = false python-versions = "*" files = [ @@ -29,61 +27,55 @@ files = [ [[package]] name = "asgiref" -version = "3.6.0" +version = "3.7.2" description = "ASGI specs, helper code, and adapters" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "asgiref-3.6.0-py3-none-any.whl", hash = "sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac"}, - {file = "asgiref-3.6.0.tar.gz", hash = "sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506"}, + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, ] [package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} [package.extras] tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "astroid" -version = "2.11.7" +version = "2.15.6" description = "An abstract syntax tree for Python with inference support." -category = "dev" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.2" files = [ - {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, - {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, + {file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"}, + {file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"}, ] [package.dependencies] lazy-object-proxy = ">=1.4.0" -setuptools = ">=20.0" -typed-ast = {version = ">=1.4.0,<2.0", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} -typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} -wrapt = ">=1.11,<2" +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} +wrapt = [ + {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, +] [[package]] name = "async-timeout" -version = "4.0.2" +version = "4.0.3" description = "Timeout context manager for asyncio programs" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, ] -[package.dependencies] -typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} - [[package]] name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -91,9 +83,6 @@ files = [ {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] dev = ["attrs[docs,tests]", "pre-commit"] @@ -101,11 +90,41 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +[[package]] +name = "backports-zoneinfo" +version = "0.2.1" +description = "Backport of the standard library zoneinfo module" +optional = false +python-versions = ">=3.6" +files = [ + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, + {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, +] + +[package.dependencies] +tzdata = {version = "*", optional = true, markers = "extra == \"tzdata\""} + +[package.extras] +tzdata = ["tzdata"] + [[package]] name = "bandit" version = "1.7.5" description = "Security oriented static analyser for python code." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -129,7 +148,6 @@ yaml = ["PyYAML"] name = "billiard" version = "3.6.4.0" description = "Python multiprocessing fork with improvements and bugfixes" -category = "main" optional = false python-versions = "*" files = [ @@ -139,37 +157,33 @@ files = [ [[package]] name = "black" -version = "23.3.0" +version = "23.7.0" description = "The uncompromising code formatter." -category = "dev" optional = false -python-versions = ">=3.7" -files = [ - {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, - {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, - {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, - {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, - {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, - {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, - {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, - {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, - {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, - {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, - {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, - {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, - {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, - {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, +python-versions = ">=3.8" +files = [ + {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, + {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, + {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, + {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, + {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, + {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, + {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, + {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, + {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, + {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, + {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, ] [package.dependencies] @@ -179,7 +193,6 @@ packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] @@ -188,23 +201,10 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] -[[package]] -name = "cached-property" -version = "1.5.2" -description = "A decorator for caching properties in classes." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, - {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, -] - [[package]] name = "celery" version = "5.2.7" description = "Distributed Task Queue." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -218,7 +218,6 @@ click = ">=8.0.3,<9.0" click-didyoumean = ">=0.0.3" click-plugins = ">=1.1.1" click-repl = ">=0.2.0" -importlib-metadata = {version = ">=1.4.0", markers = "python_version < \"3.8\""} kombu = ">=5.2.3,<6.0" pytz = ">=2021.3" vine = ">=5.0.0,<6.0" @@ -258,21 +257,19 @@ zstd = ["zstandard"] [[package]] name = "certifi" -version = "2023.5.7" +version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, - {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, ] [[package]] name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -347,110 +344,106 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.1.0" +version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, - {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] [[package]] name = "click" -version = "8.1.3" +version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, + {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\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "click-didyoumean" version = "0.3.0" description = "Enables git-like *did-you-mean* feature in click" -category = "main" optional = false python-versions = ">=3.6.2,<4.0.0" files = [ @@ -465,7 +458,6 @@ click = ">=7" name = "click-plugins" version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." -category = "main" optional = false python-versions = "*" files = [ @@ -481,26 +473,26 @@ dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] [[package]] name = "click-repl" -version = "0.2.0" +version = "0.3.0" description = "REPL plugin for Click" -category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "click-repl-0.2.0.tar.gz", hash = "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8"}, - {file = "click_repl-0.2.0-py3-none-any.whl", hash = "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b"}, + {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, + {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, ] [package.dependencies] -click = "*" -prompt-toolkit = "*" -six = "*" +click = ">=7.0" +prompt-toolkit = ">=3.0.36" + +[package.extras] +testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -508,44 +500,10 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "coreapi" -version = "2.3.3" -description = "Python client library for Core API." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "coreapi-2.3.3-py2.py3-none-any.whl", hash = "sha256:bf39d118d6d3e171f10df9ede5666f63ad80bba9a29a8ec17726a66cf52ee6f3"}, - {file = "coreapi-2.3.3.tar.gz", hash = "sha256:46145fcc1f7017c076a2ef684969b641d18a2991051fddec9458ad3f78ffc1cb"}, -] - -[package.dependencies] -coreschema = "*" -itypes = "*" -requests = "*" -uritemplate = "*" - -[[package]] -name = "coreschema" -version = "0.0.4" -description = "Core Schema." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "coreschema-0.0.4-py2-none-any.whl", hash = "sha256:5e6ef7bf38c1525d5e55a895934ab4273548629f16aed5c0a6caa74ebf45551f"}, - {file = "coreschema-0.0.4.tar.gz", hash = "sha256:9503506007d482ab0867ba14724b93c18a33b22b6d19fb419ef2d239dd4a1607"}, -] - -[package.dependencies] -jinja2 = "*" - [[package]] name = "coverage" version = "5.5" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" files = [ @@ -608,31 +566,34 @@ toml = ["toml"] [[package]] name = "cryptography" -version = "40.0.2" +version = "41.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, - {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, - {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, - {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, + {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507"}, + {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922"}, + {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81"}, + {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd"}, + {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47"}, + {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116"}, + {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c"}, + {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae"}, + {file = "cryptography-41.0.3-cp37-abi3-win32.whl", hash = "sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306"}, + {file = "cryptography-41.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574"}, + {file = "cryptography-41.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087"}, + {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858"}, + {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906"}, + {file = "cryptography-41.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e"}, + {file = "cryptography-41.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd"}, + {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207"}, + {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84"}, + {file = "cryptography-41.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7"}, + {file = "cryptography-41.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d"}, + {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de"}, + {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1"}, + {file = "cryptography-41.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4"}, + {file = "cryptography-41.0.3.tar.gz", hash = "sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34"}, ] [package.dependencies] @@ -641,18 +602,17 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "check-manifest", "mypy", "ruff"] -sdist = ["setuptools-rust (>=0.11.4)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -tox = ["tox"] [[package]] name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -662,14 +622,13 @@ files = [ [[package]] name = "dill" -version = "0.3.6" -description = "serialize all of python" -category = "dev" +version = "0.3.7" +description = "serialize all of Python" optional = false python-versions = ">=3.7" files = [ - {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, - {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, + {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, + {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, ] [package.extras] @@ -677,14 +636,13 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "django" -version = "3.2.19" +version = "3.2.20" description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "Django-3.2.19-py3-none-any.whl", hash = "sha256:21cc991466245d659ab79cb01204f9515690f8dae00e5eabde307f14d24d4d7d"}, - {file = "Django-3.2.19.tar.gz", hash = "sha256:031365bae96814da19c10706218c44dff3b654cc4de20a98bd2d29b9bde469f0"}, + {file = "Django-3.2.20-py3-none-any.whl", hash = "sha256:a477ab326ae7d8807dc25c186b951ab8c7648a3a23f9497763c37307a2b5ef87"}, + {file = "Django-3.2.20.tar.gz", hash = "sha256:dec2a116787b8e14962014bf78e120bba454135108e1af9e9b91ade7b2964c40"}, ] [package.dependencies] @@ -700,7 +658,6 @@ bcrypt = ["bcrypt"] name = "django-ajax-tables" version = "1.1.1" description = "Django tag for ajax-enabled tables" -category = "main" optional = false python-versions = "*" files = [ @@ -712,7 +669,6 @@ files = [ name = "django-appconf" version = "1.0.5" description = "A helper class for handling configuration defaults of packaged apps gracefully." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -727,7 +683,6 @@ django = "*" name = "django-cacheops" version = "6.0" description = "A slick ORM cache with automatic granular event-driven invalidation for Django." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -745,7 +700,6 @@ six = ">=1.4.0" name = "django-celery-beat" version = "2.2.1" description = "Database-backed Periodic Tasks." -category = "main" optional = false python-versions = "*" files = [ @@ -763,7 +717,6 @@ python-crontab = ">=2.3.4" name = "django-constance" version = "2.9.1" description = "Django live settings with pluggable backends, including Redis." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -782,7 +735,6 @@ redis = ["redis"] name = "django-cors-headers" version = "3.13.0" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -797,7 +749,6 @@ Django = ">=3.2" name = "django-cryptography" version = "1.0" description = "Easily encrypt data in Django" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -813,7 +764,6 @@ django-appconf = "*" name = "django-db-file-storage" version = "0.5.5" description = "Custom FILE_STORAGE for Django. Saves files in your database instead of your file system." -category = "main" optional = false python-versions = "*" files = [ @@ -825,14 +775,13 @@ Django = "*" [[package]] name = "django-debug-toolbar" -version = "3.8.1" +version = "4.2.0" description = "A configurable set of panels that display various debug information about the current request/response." -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "django_debug_toolbar-3.8.1-py3-none-any.whl", hash = "sha256:879f8a4672d41621c06a4d322dcffa630fc4df056cada6e417ed01db0e5e0478"}, - {file = "django_debug_toolbar-3.8.1.tar.gz", hash = "sha256:24ef1a7d44d25e60d7951e378454c6509bf536dce7e7d9d36e7c387db499bc27"}, + {file = "django_debug_toolbar-4.2.0-py3-none-any.whl", hash = "sha256:af99128c06e8e794479e65ab62cc6c7d1e74e1c19beb44dcbf9bad7a9c017327"}, + {file = "django_debug_toolbar-4.2.0.tar.gz", hash = "sha256:bc7fdaafafcdedefcc67a4a5ad9dac96efd6e41db15bc74d402a54a2ba4854dc"}, ] [package.dependencies] @@ -841,14 +790,13 @@ sqlparse = ">=0.2" [[package]] name = "django-extensions" -version = "3.2.1" +version = "3.2.3" description = "Extensions for Django" -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "django-extensions-3.2.1.tar.gz", hash = "sha256:2a4f4d757be2563cd1ff7cfdf2e57468f5f931cc88b23cf82ca75717aae504a4"}, - {file = "django_extensions-3.2.1-py3-none-any.whl", hash = "sha256:421464be390289513f86cb5e18eb43e5dc1de8b4c27ba9faa3b91261b0d67e09"}, + {file = "django-extensions-3.2.3.tar.gz", hash = "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a"}, + {file = "django_extensions-3.2.3-py3-none-any.whl", hash = "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401"}, ] [package.dependencies] @@ -858,7 +806,6 @@ Django = ">=3.2" name = "django-filter" version = "21.1" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -871,24 +818,26 @@ Django = ">=2.2" [[package]] name = "django-health-check" -version = "3.16.5" +version = "3.16.7" description = "Run checks on services like databases, queue servers, celery processes, etc." -category = "main" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "django-health-check-3.16.5.tar.gz", hash = "sha256:1edfd49293ccebbce29f9da609c407f307aee240ab799ab4201031341ae78c0f"}, - {file = "django_health_check-3.16.5-py2.py3-none-any.whl", hash = "sha256:8d66781a0ea82b1a8b44878187b38a27370e94f18287312e39be0593e72d8983"}, + {file = "django-health-check-3.16.7.tar.gz", hash = "sha256:85b8e4ffa6ebbee3a7214c91ea4a67ce0e918bc8ed9679d054afd9cc9fa17c4f"}, + {file = "django_health_check-3.16.7-py2.py3-none-any.whl", hash = "sha256:4f4fe32838eb367b9dda51669f128b97f8416eaa66b80b58c50db6fc2cc42356"}, ] [package.dependencies] django = ">=2.2" +[package.extras] +docs = ["sphinx"] +test = ["celery", "pytest", "pytest-cov", "pytest-django", "redis"] + [[package]] name = "django-jinja" version = "2.10.2" description = "Jinja2 templating language integrated in Django." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -902,18 +851,17 @@ jinja2 = ">=3" [[package]] name = "django-js-asset" -version = "2.0.0" +version = "2.1.0" description = "script tag with additional attributes for django.forms.Media" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "django_js_asset-2.0.0-py3-none-any.whl", hash = "sha256:86f9f300d682537ddaf0487dc2ab356581b8f50c069bdba91d334a46e449f923"}, - {file = "django_js_asset-2.0.0.tar.gz", hash = "sha256:adc1ee1efa853fad42054b540c02205344bb406c9bddf87c9e5377a41b7db90f"}, + {file = "django_js_asset-2.1.0-py3-none-any.whl", hash = "sha256:36a3a4dd6e9efc895fb127d13126020f6ec1ec9469ad42878d42143f22495d90"}, + {file = "django_js_asset-2.1.0.tar.gz", hash = "sha256:be6f69ae5c4865617aa7726c48eddb64089a1e7d4ea7d22a35a3beb8282020f6"}, ] [package.dependencies] -Django = ">=2.2" +django = ">=3.2" [package.extras] tests = ["coverage"] @@ -922,7 +870,6 @@ tests = ["coverage"] name = "django-mptt" version = "0.14.0" description = "Utilities for implementing Modified Preorder Tree Traversal with your Django Models and working with trees of Model instances." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -940,7 +887,6 @@ tests = ["coverage", "mock-django"] name = "django-picklefield" version = "3.1" description = "Pickled object field for Django" -category = "main" optional = false python-versions = ">=3" files = [ @@ -958,7 +904,6 @@ tests = ["tox"] name = "django-prometheus" version = "2.2.0" description = "Django middlewares to monitor your application with Prometheus.io." -category = "main" optional = false python-versions = "*" files = [ @@ -973,7 +918,6 @@ prometheus-client = ">=0.7" name = "django-redis" version = "5.2.0" description = "Full featured redis cache backend for Django." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -992,7 +936,6 @@ hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] name = "django-rq" version = "2.5.1" description = "An app that provides django integration for RQ (Redis Queue)" -category = "main" optional = false python-versions = "*" files = [ @@ -1013,7 +956,6 @@ testing = ["mock (>=2.0.0)"] name = "django-tables2" version = "2.4.1" description = "Table/data-grid framework for Django" -category = "main" optional = false python-versions = "*" files = [ @@ -1031,7 +973,6 @@ tablib = ["tablib"] name = "django-taggit" version = "3.0.0" description = "django-taggit is a reusable Django application for simple tagging." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1046,7 +987,6 @@ Django = ">=3.2" name = "django-timezone-field" version = "4.1.2" description = "A Django app providing database and form fields for pytz timezone objects." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1065,7 +1005,6 @@ rest-framework = ["djangorestframework (>=3.0.0)"] name = "django-tree-queries" version = "0.11.0" description = "Tree queries with explicit opt-in, without configurability" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1080,7 +1019,6 @@ tests = ["coverage"] name = "django-webserver" version = "1.2.0" description = "Django management commands for production webservers" -category = "main" optional = false python-versions = "*" files = [ @@ -1102,7 +1040,6 @@ waitress = ["waitress"] name = "djangorestframework" version = "3.14.0" description = "Web APIs for Django, made easy." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1118,7 +1055,6 @@ pytz = "*" name = "drf-spectacular" version = "0.24.2" description = "Sane and flexible OpenAPI 3 schema generation for Django REST framework" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1133,7 +1069,6 @@ drf-spectacular-sidecar = {version = "*", optional = true, markers = "extra == \ inflection = ">=0.3.1" jsonschema = ">=2.6.0" PyYAML = ">=5.1" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} uritemplate = ">=2.0.0" [package.extras] @@ -1142,14 +1077,13 @@ sidecar = ["drf-spectacular-sidecar"] [[package]] name = "drf-spectacular-sidecar" -version = "2023.5.1" +version = "2023.8.1" description = "Serve self-contained distribution builds of Swagger UI and Redoc with Django" -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "drf-spectacular-sidecar-2023.5.1.tar.gz", hash = "sha256:58358215fee6c4634d77335d4c341b8132dc0847b282fb2fe4b22530dc2a56ca"}, - {file = "drf_spectacular_sidecar-2023.5.1-py3-none-any.whl", hash = "sha256:10ab069a3475f763acbae76414ee80fc67a42c00394918777996bbfa9239f155"}, + {file = "drf-spectacular-sidecar-2023.8.1.tar.gz", hash = "sha256:79b928d75b8f7c07d2188dda33ea10ca90d4f7234af5788dda58dc4434cd27f8"}, + {file = "drf_spectacular_sidecar-2023.8.1-py3-none-any.whl", hash = "sha256:aa9027e8aadb907bb6be486a7219f1474ab678914cae8aebf34445f02e80bdca"}, ] [package.dependencies] @@ -1157,36 +1091,33 @@ Django = ">=2.2" [[package]] name = "drf-yasg" -version = "1.21.5" +version = "1.21.7" description = "Automated generation of real Swagger/OpenAPI 2.0 schemas from Django Rest Framework code." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "drf-yasg-1.21.5.tar.gz", hash = "sha256:ceef0c3b5dc4389781afd786e6dc3697af2a2fe0d8724ee1f637c23d75bbc5b2"}, - {file = "drf_yasg-1.21.5-py3-none-any.whl", hash = "sha256:ba9cf4bf79f259290daee9b400fa4fcdb0e78d2f043fa5e9f6589c939fd06d05"}, + {file = "drf-yasg-1.21.7.tar.gz", hash = "sha256:4c3b93068b3dfca6969ab111155e4dd6f7b2d680b98778de8fd460b7837bdb0d"}, + {file = "drf_yasg-1.21.7-py3-none-any.whl", hash = "sha256:f85642072c35e684356475781b7ecf5d218fff2c6185c040664dd49f0a4be181"}, ] [package.dependencies] -coreapi = ">=2.3.3" -coreschema = ">=0.0.4" django = ">=2.2.16" djangorestframework = ">=3.10.3" inflection = ">=0.3.1" packaging = ">=21.0" pytz = ">=2021.1" -"ruamel.yaml" = ">=0.16.13" +pyyaml = ">=5.1" swagger-spec-validator = {version = ">=2.1.0", optional = true, markers = "extra == \"validation\""} uritemplate = ">=3.0.0" [package.extras] +coreapi = ["coreapi (>=2.3.3)", "coreschema (>=0.0.4)"] validation = ["swagger-spec-validator (>=2.1.0)"] [[package]] name = "flake8" version = "3.9.2" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -1195,7 +1126,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.7.0,<2.8.0" pyflakes = ">=2.3.0,<2.4.0" @@ -1204,7 +1134,6 @@ pyflakes = ">=2.3.0,<2.4.0" name = "funcy" version = "1.18" description = "A fancy and practical functional tools" -category = "main" optional = false python-versions = "*" files = [ @@ -1216,7 +1145,6 @@ files = [ name = "ghp-import" version = "2.1.0" description = "Copy your docs directly to the gh-pages branch." -category = "dev" optional = false python-versions = "*" files = [ @@ -1234,7 +1162,6 @@ dev = ["flake8", "markdown", "twine", "wheel"] name = "gitdb" version = "4.0.10" description = "Git Object Database" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1247,25 +1174,22 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.31" +version = "3.1.32" description = "GitPython is a Python library used to interact with Git repositories" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "GitPython-3.1.31-py3-none-any.whl", hash = "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"}, - {file = "GitPython-3.1.31.tar.gz", hash = "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573"}, + {file = "GitPython-3.1.32-py3-none-any.whl", hash = "sha256:e3d59b1c2c6ebb9dfa7a184daf3b6dd4914237e7488a1730a6d8f6f5d0b4187f"}, + {file = "GitPython-3.1.32.tar.gz", hash = "sha256:8d9b8cb1e80b9735e8717c9362079d3ce4c6e5ddeebedd0361b228c3a67a62f6"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} [[package]] name = "graphene" version = "2.1.9" description = "GraphQL Framework for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1288,7 +1212,6 @@ test = ["coveralls", "fastdiff (==0.2.0)", "iso8601", "mock", "promise", "pytest name = "graphene-django" version = "2.15.0" description = "Graphene Django integration" -category = "main" optional = false python-versions = "*" files = [ @@ -1314,7 +1237,6 @@ test = ["coveralls", "django-filter (<2)", "django-filter (>=2)", "djangorestfra name = "graphene-django-optimizer" version = "0.8.0" description = "Optimize database access inside graphene queries." -category = "main" optional = false python-versions = "*" files = [ @@ -1325,7 +1247,6 @@ files = [ name = "graphql-core" version = "2.3.2" description = "GraphQL implementation for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1346,7 +1267,6 @@ test = ["coveralls (==1.11.1)", "cython (==0.29.17)", "gevent (==1.5.0)", "pyann name = "graphql-relay" version = "2.0.1" description = "Relay implementation for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1361,25 +1281,22 @@ six = ">=1.12" [[package]] name = "griffe" -version = "0.27.5" +version = "0.34.0" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "griffe-0.27.5-py3-none-any.whl", hash = "sha256:15b48fc3cebfc1c1a1a2f6e8177f6644a4a54517322e08e224fdf671454b34d7"}, - {file = "griffe-0.27.5.tar.gz", hash = "sha256:96fbc7a264bdb32b4da227bed6a16f2509e028a12d7471dbb48c2785bb01817f"}, + {file = "griffe-0.34.0-py3-none-any.whl", hash = "sha256:d8bca9bd4a0880e7f71dc152de4222171d941a32b5504d77450a71a7908dfc1d"}, + {file = "griffe-0.34.0.tar.gz", hash = "sha256:48c667ad51a7f756238f798866203aeb8f9fa02d4192e25970f57f813bb37f26"}, ] [package.dependencies] -cached-property = {version = "*", markers = "python_version < \"3.8\""} colorama = ">=0.4" [[package]] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1389,49 +1306,45 @@ files = [ [[package]] name = "importlib-metadata" -version = "4.13.0" +version = "6.8.0" description = "Read metadata from Python packages" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"}, - {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"}, + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, ] [package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "importlib-resources" -version = "5.12.0" +version = "6.0.1" description = "Read resources from Python packages" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, + {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"}, + {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [[package]] name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1441,51 +1354,36 @@ files = [ [[package]] name = "invoke" -version = "2.1.2" +version = "2.2.0" description = "Pythonic task execution" -category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "invoke-2.1.2-py3-none-any.whl", hash = "sha256:bfc904df1c9e9fe1a881933de661fe054b8db616ff2c4cf78e00407fe473ba5d"}, - {file = "invoke-2.1.2.tar.gz", hash = "sha256:a6cc1f06f75bacd0b1e11488fa3bf3e62f85e31f62e2c0172188613ba5b070e2"}, + {file = "invoke-2.2.0-py3-none-any.whl", hash = "sha256:6ea924cc53d4f78e3d98bc436b08069a03077e6f85ad1ddaa8a116d7dad15820"}, + {file = "invoke-2.2.0.tar.gz", hash = "sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5"}, ] [[package]] name = "isort" -version = "5.11.5" +version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" files = [ - {file = "isort-5.11.5-py3-none-any.whl", hash = "sha256:ba1d72fb2595a01c7895a5128f9585a5cc4b6d395f1c8d514989b9a7eb2a8746"}, - {file = "isort-5.11.5.tar.gz", hash = "sha256:6be1f76a507cb2ecf16c7cf14a37e41609ca082330be4e3436a18ef74add55db"}, + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, ] [package.extras] -colors = ["colorama (>=0.4.3,<0.5.0)"] +colors = ["colorama (>=0.4.3)"] pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] -[[package]] -name = "itypes" -version = "1.2.0" -description = "Simple immutable types for python." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "itypes-1.2.0-py2.py3-none-any.whl", hash = "sha256:03da6872ca89d29aef62773672b2d408f490f80db48b23079a4b194c86dd04c6"}, - {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, -] - [[package]] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1503,7 +1401,6 @@ i18n = ["Babel (>=2.7)"] name = "jsonschema" version = "4.7.2" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1513,10 +1410,8 @@ files = [ [package.dependencies] attrs = ">=17.4.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1524,43 +1419,42 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "kombu" -version = "5.2.4" +version = "5.3.1" description = "Messaging library for Python." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "kombu-5.2.4-py3-none-any.whl", hash = "sha256:8b213b24293d3417bcf0d2f5537b7f756079e3ea232a8386dcc89a59fd2361a4"}, - {file = "kombu-5.2.4.tar.gz", hash = "sha256:37cee3ee725f94ea8bb173eaab7c1760203ea53bbebae226328600f9d2799610"}, + {file = "kombu-5.3.1-py3-none-any.whl", hash = "sha256:48ee589e8833126fd01ceaa08f8a2041334e9f5894e5763c8486a550454551e9"}, + {file = "kombu-5.3.1.tar.gz", hash = "sha256:fbd7572d92c0bf71c112a6b45163153dea5a7b6a701ec16b568c27d0fd2370f2"}, ] [package.dependencies] -amqp = ">=5.0.9,<6.0.0" -cached-property = {version = "*", markers = "python_version < \"3.8\""} -importlib-metadata = {version = ">=0.18", markers = "python_version < \"3.8\""} +amqp = ">=5.1.1,<6.0.0" +"backports.zoneinfo" = {version = ">=0.2.1", extras = ["tzdata"], markers = "python_version < \"3.9\""} +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} vine = "*" [package.extras] -azureservicebus = ["azure-servicebus (>=7.0.0)"] -azurestoragequeues = ["azure-storage-queue"] -consul = ["python-consul (>=0.6.0)"] +azureservicebus = ["azure-servicebus (>=7.10.0)"] +azurestoragequeues = ["azure-identity (>=1.12.0)", "azure-storage-queue (>=12.6.0)"] +confluentkafka = ["confluent-kafka (==2.1.1)"] +consul = ["python-consul2"] librabbitmq = ["librabbitmq (>=2.0.0)"] -mongodb = ["pymongo (>=3.3.0,<3.12.1)"] +mongodb = ["pymongo (>=4.1.1)"] msgpack = ["msgpack"] pyro = ["pyro4"] qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] -redis = ["redis (>=3.4.1,!=4.0.0,!=4.0.1)"] +redis = ["redis (>=4.5.2)"] slmq = ["softlayer-messaging (>=1.0.3)"] -sqlalchemy = ["sqlalchemy"] -sqs = ["boto3 (>=1.9.12)", "pycurl (>=7.44.1,<7.45.0)", "urllib3 (>=1.26.7)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] yaml = ["PyYAML (>=3.10)"] -zookeeper = ["kazoo (>=1.3.1)"] +zookeeper = ["kazoo (>=2.8.0)"] [[package]] name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1606,7 +1500,6 @@ files = [ name = "markdown" version = "3.3.7" description = "Python implementation of Markdown." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1622,19 +1515,17 @@ testing = ["coverage", "pyyaml"] [[package]] name = "markdown-it-py" -version = "2.2.0" +version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" 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"}, + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [package.dependencies] mdurl = ">=0.1,<1.0" -typing_extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] @@ -1643,74 +1534,72 @@ compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.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"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.2" +version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, - {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] [[package]] name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = "*" files = [ @@ -1722,7 +1611,6 @@ files = [ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1734,7 +1622,6 @@ files = [ name = "mergedeep" version = "1.3.4" description = "A deep merge function for 🐍." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1746,7 +1633,6 @@ files = [ name = "mkdocs" version = "1.3.1" description = "Project documentation with Markdown." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1771,14 +1657,13 @@ i18n = ["babel (>=2.9.0)"] [[package]] name = "mkdocs-autorefs" -version = "0.4.1" +version = "0.5.0" description = "Automatically link across pages in MkDocs." -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs-autorefs-0.4.1.tar.gz", hash = "sha256:70748a7bd025f9ecd6d6feeba8ba63f8e891a1af55f48e366d6d6e78493aba84"}, - {file = "mkdocs_autorefs-0.4.1-py3-none-any.whl", hash = "sha256:a2248a9501b29dc0cc8ba4c09f4f47ff121945f6ce33d760f145d6f89d313f5b"}, + {file = "mkdocs_autorefs-0.5.0-py3-none-any.whl", hash = "sha256:7930fcb8ac1249f10e683967aeaddc0af49d90702af111a5e390e8b20b3d97ff"}, + {file = "mkdocs_autorefs-0.5.0.tar.gz", hash = "sha256:9a5054a94c08d28855cfab967ada10ed5be76e2bfad642302a610b252c3274c0"}, ] [package.dependencies] @@ -1789,7 +1674,6 @@ mkdocs = ">=1.1" name = "mkdocs-material" version = "8.4.2" description = "Documentation that simply works" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1809,7 +1693,6 @@ pymdown-extensions = ">=9.4" name = "mkdocs-material-extensions" version = "1.1.1" description = "Extension pack for Python Markdown and MkDocs Material." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1821,7 +1704,6 @@ files = [ name = "mkdocs-version-annotations" version = "1.0.0" description = "MkDocs plugin to add custom admonitions for documenting version differences" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -1833,7 +1715,6 @@ files = [ name = "mkdocstrings" version = "0.19.0" description = "Automatic documentation from sources, for MkDocs." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1858,7 +1739,6 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] name = "mkdocstrings-python" version = "0.7.1" description = "A Python handler for mkdocstrings." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1874,7 +1754,6 @@ mkdocstrings = ">=0.19" name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1886,7 +1765,6 @@ files = [ name = "nautobot" version = "1.5.16" description = "Source of truth and network automation platform." -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -1923,7 +1801,6 @@ drf-yasg = {version = ">=1.20.0,<2.0.0", extras = ["validation"]} GitPython = ">=3.1.31,<3.2.0" graphene-django = ">=2.15.0,<2.16.0" graphene-django-optimizer = ">=0.8.0,<0.9.0" -importlib-metadata = {version = ">=4.4,<5.0", markers = "python_version < \"3.8\""} Jinja2 = ">=3.1.0,<3.2.0" jsonschema = ">=4.7.0,<4.8.0" Markdown = ">=3.3.7,<3.4.0" @@ -1951,7 +1828,6 @@ sso = ["social-auth-core[openidconnect,saml] (>=4.3.0,<4.4.0)"] name = "netaddr" version = "0.8.0" description = "A network address manipulation library for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1961,14 +1837,13 @@ files = [ [[package]] name = "netutils" -version = "1.4.1" +version = "1.5.0" description = "Common helper functions useful in network automation." -category = "main" optional = false -python-versions = ">=3.7,<4.0" +python-versions = ">=3.8,<4.0" files = [ - {file = "netutils-1.4.1-py3-none-any.whl", hash = "sha256:41002e42b205149fbe6739b7fdbc778ed843e87fabba9691d3d06a35f7876fd4"}, - {file = "netutils-1.4.1.tar.gz", hash = "sha256:4f7501478d810bcd3c64edfe064fa8962a1572636f4fceee2538fc9d3616fbe2"}, + {file = "netutils-1.5.0-py3-none-any.whl", hash = "sha256:39654c367f291ed071477a2e5b4cda880eca9b8d5a1229ba3e39eec5f584cb67"}, + {file = "netutils-1.5.0.tar.gz", hash = "sha256:c0d3a8836a030eca456a2e9291d02be1326e6d7fe4e88cb63b1155512001bb14"}, ] [package.extras] @@ -1978,7 +1853,6 @@ optionals = ["napalm (>=4.0.0,<5.0.0)"] name = "oauthlib" version = "3.2.2" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1995,7 +1869,6 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2005,21 +1878,19 @@ files = [ [[package]] name = "pathspec" -version = "0.11.1" +version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, - {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, ] [[package]] name = "pbr" version = "5.11.1" description = "Python Build Reasonableness" -category = "dev" optional = false python-versions = ">=2.6" files = [ @@ -2031,7 +1902,6 @@ files = [ name = "pillow" version = "9.3.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2104,28 +1974,23 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa [[package]] name = "platformdirs" -version = "3.5.1" +version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, - {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, + {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, + {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""} - [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] name = "prometheus-client" version = "0.14.1" description = "Python client for the Prometheus monitoring system." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2140,7 +2005,6 @@ twisted = ["twisted"] name = "promise" version = "2.3" description = "Promises/A+ implementation for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -2155,14 +2019,13 @@ test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", [[package]] name = "prompt-toolkit" -version = "3.0.38" +version = "3.0.39" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, - {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, + {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, + {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, ] [package.dependencies] @@ -2170,81 +2033,77 @@ wcwidth = "*" [[package]] name = "psycopg2-binary" -version = "2.9.6" +version = "2.9.7" description = "psycopg2 - Python-PostgreSQL Database Adapter" -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "psycopg2-binary-2.9.6.tar.gz", hash = "sha256:1f64dcfb8f6e0c014c7f55e51c9759f024f70ea572fbdef123f85318c297947c"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d26e0342183c762de3276cca7a530d574d4e25121ca7d6e4a98e4f05cb8e4df7"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c48d8f2db17f27d41fb0e2ecd703ea41984ee19362cbce52c097963b3a1b4365"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe9dc0a884a8848075e576c1de0290d85a533a9f6e9c4e564f19adf8f6e54a7"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a76e027f87753f9bd1ab5f7c9cb8c7628d1077ef927f5e2446477153a602f2c"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6460c7a99fc939b849431f1e73e013d54aa54293f30f1109019c56a0b2b2ec2f"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae102a98c547ee2288637af07393dd33f440c25e5cd79556b04e3fca13325e5f"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9972aad21f965599ed0106f65334230ce826e5ae69fda7cbd688d24fa922415e"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a40c00dbe17c0af5bdd55aafd6ff6679f94a9be9513a4c7e071baf3d7d22a70"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:cacbdc5839bdff804dfebc058fe25684cae322987f7a38b0168bc1b2df703fb1"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f0438fa20fb6c7e202863e0d5ab02c246d35efb1d164e052f2f3bfe2b152bd0"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-win32.whl", hash = "sha256:b6c8288bb8a84b47e07013bb4850f50538aa913d487579e1921724631d02ea1b"}, - {file = "psycopg2_binary-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:61b047a0537bbc3afae10f134dc6393823882eb263088c271331602b672e52e9"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:964b4dfb7c1c1965ac4c1978b0f755cc4bd698e8aa2b7667c575fb5f04ebe06b"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afe64e9b8ea66866a771996f6ff14447e8082ea26e675a295ad3bdbffdd72afb"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15e2ee79e7cf29582ef770de7dab3d286431b01c3bb598f8e05e09601b890081"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa74c903a3c1f0d9b1c7e7b53ed2d929a4910e272add6700c38f365a6002820"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b83456c2d4979e08ff56180a76429263ea254c3f6552cd14ada95cff1dec9bb8"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0645376d399bfd64da57148694d78e1f431b1e1ee1054872a5713125681cf1be"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e99e34c82309dd78959ba3c1590975b5d3c862d6f279f843d47d26ff89d7d7e1"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ea29fc3ad9d91162c52b578f211ff1c931d8a38e1f58e684c45aa470adf19e2"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4ac30da8b4f57187dbf449294d23b808f8f53cad6b1fc3623fa8a6c11d176dd0"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e78e6e2a00c223e164c417628572a90093c031ed724492c763721c2e0bc2a8df"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-win32.whl", hash = "sha256:1876843d8e31c89c399e31b97d4b9725a3575bb9c2af92038464231ec40f9edb"}, - {file = "psycopg2_binary-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b4b24f75d16a89cc6b4cdff0eb6a910a966ecd476d1e73f7ce5985ff1328e9a6"}, - {file = "psycopg2_binary-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:498807b927ca2510baea1b05cc91d7da4718a0f53cb766c154c417a39f1820a0"}, - {file = "psycopg2_binary-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0d236c2825fa656a2d98bbb0e52370a2e852e5a0ec45fc4f402977313329174d"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:34b9ccdf210cbbb1303c7c4db2905fa0319391bd5904d32689e6dd5c963d2ea8"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d2222e61f313c4848ff05353653bf5f5cf6ce34df540e4274516880d9c3763"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30637a20623e2a2eacc420059be11527f4458ef54352d870b8181a4c3020ae6b"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8122cfc7cae0da9a3077216528b8bb3629c43b25053284cc868744bfe71eb141"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38601cbbfe600362c43714482f43b7c110b20cb0f8172422c616b09b85a750c5"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c7e62ab8b332147a7593a385d4f368874d5fe4ad4e341770d4983442d89603e3"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2ab652e729ff4ad76d400df2624d223d6e265ef81bb8aa17fbd63607878ecbee"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c83a74b68270028dc8ee74d38ecfaf9c90eed23c8959fca95bd703d25b82c88e"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d4e6036decf4b72d6425d5b29bbd3e8f0ff1059cda7ac7b96d6ac5ed34ffbacd"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:a8c28fd40a4226b4a84bdf2d2b5b37d2c7bd49486b5adcc200e8c7ec991dfa7e"}, - {file = "psycopg2_binary-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:51537e3d299be0db9137b321dfb6a5022caaab275775680e0c3d281feefaca6b"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4499e0a83b7b7edcb8dabecbd8501d0d3a5ef66457200f77bde3d210d5debb"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e13a5a2c01151f1208d5207e42f33ba86d561b7a89fca67c700b9486a06d0e2"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e0f754d27fddcfd74006455b6e04e6705d6c31a612ec69ddc040a5468e44b4e"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d57c3fd55d9058645d26ae37d76e61156a27722097229d32a9e73ed54819982a"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71f14375d6f73b62800530b581aed3ada394039877818b2d5f7fc77e3bb6894d"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:441cc2f8869a4f0f4bb408475e5ae0ee1f3b55b33f350406150277f7f35384fc"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:65bee1e49fa6f9cf327ce0e01c4c10f39165ee76d35c846ade7cb0ec6683e303"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:af335bac6b666cc6aea16f11d486c3b794029d9df029967f9938a4bed59b6a19"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cfec476887aa231b8548ece2e06d28edc87c1397ebd83922299af2e051cf2827"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65c07febd1936d63bfde78948b76cd4c2a411572a44ac50719ead41947d0f26b"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-win32.whl", hash = "sha256:4dfb4be774c4436a4526d0c554af0cc2e02082c38303852a36f6456ece7b3503"}, - {file = "psycopg2_binary-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:02c6e3cf3439e213e4ee930308dc122d6fb4d4bea9aef4a12535fbd605d1a2fe"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9182eb20f41417ea1dd8e8f7888c4d7c6e805f8a7c98c1081778a3da2bee3e4"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a6979cf527e2603d349a91060f428bcb135aea2be3201dff794813256c274f1"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8338a271cb71d8da40b023a35d9c1e919eba6cbd8fa20a54b748a332c355d896"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ed340d2b858d6e6fb5083f87c09996506af483227735de6964a6100b4e6a54"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f81e65376e52f03422e1fb475c9514185669943798ed019ac50410fb4c4df232"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb13af3c5dd3a9588000910178de17010ebcccd37b4f9794b00595e3a8ddad3"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4c727b597c6444a16e9119386b59388f8a424223302d0c06c676ec8b4bc1f963"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d67fbdaf177da06374473ef6f7ed8cc0a9dc640b01abfe9e8a2ccb1b1402c1f"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0892ef645c2fabb0c75ec32d79f4252542d0caec1d5d949630e7d242ca4681a3"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:02c0f3757a4300cf379eb49f543fb7ac527fb00144d39246ee40e1df684ab514"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-win32.whl", hash = "sha256:c3dba7dab16709a33a847e5cd756767271697041fbe3fe97c215b1fc1f5c9848"}, - {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"}, + {file = "psycopg2-binary-2.9.7.tar.gz", hash = "sha256:1b918f64a51ffe19cd2e230b3240ba481330ce1d4b7875ae67305bd1d37b041c"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ea5f8ee87f1eddc818fc04649d952c526db4426d26bab16efbe5a0c52b27d6ab"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2993ccb2b7e80844d534e55e0f12534c2871952f78e0da33c35e648bf002bbff"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbbc3c5d15ed76b0d9db7753c0db40899136ecfe97d50cbde918f630c5eb857a"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:692df8763b71d42eb8343f54091368f6f6c9cfc56dc391858cdb3c3ef1e3e584"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dcfd5d37e027ec393a303cc0a216be564b96c80ba532f3d1e0d2b5e5e4b1e6e"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17cc17a70dfb295a240db7f65b6d8153c3d81efb145d76da1e4a096e9c5c0e63"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e5666632ba2b0d9757b38fc17337d84bdf932d38563c5234f5f8c54fd01349c9"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7db7b9b701974c96a88997d458b38ccb110eba8f805d4b4f74944aac48639b42"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c82986635a16fb1fa15cd5436035c88bc65c3d5ced1cfaac7f357ee9e9deddd4"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4fe13712357d802080cfccbf8c6266a3121dc0e27e2144819029095ccf708372"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-win32.whl", hash = "sha256:122641b7fab18ef76b18860dd0c772290566b6fb30cc08e923ad73d17461dc63"}, + {file = "psycopg2_binary-2.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:f8651cf1f144f9ee0fa7d1a1df61a9184ab72962531ca99f077bbdcba3947c58"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4ecc15666f16f97709106d87284c136cdc82647e1c3f8392a672616aed3c7151"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fbb1184c7e9d28d67671992970718c05af5f77fc88e26fd7136613c4ece1f89"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a7968fd20bd550431837656872c19575b687f3f6f98120046228e451e4064df"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:094af2e77a1976efd4956a031028774b827029729725e136514aae3cdf49b87b"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26484e913d472ecb6b45937ea55ce29c57c662066d222fb0fbdc1fab457f18c5"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f309b77a7c716e6ed9891b9b42953c3ff7d533dc548c1e33fddc73d2f5e21f9"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6d92e139ca388ccfe8c04aacc163756e55ba4c623c6ba13d5d1595ed97523e4b"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2df562bb2e4e00ee064779902d721223cfa9f8f58e7e52318c97d139cf7f012d"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4eec5d36dbcfc076caab61a2114c12094c0b7027d57e9e4387b634e8ab36fd44"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1011eeb0c51e5b9ea1016f0f45fa23aca63966a4c0afcf0340ccabe85a9f65bd"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-win32.whl", hash = "sha256:ded8e15f7550db9e75c60b3d9fcbc7737fea258a0f10032cdb7edc26c2a671fd"}, + {file = "psycopg2_binary-2.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:8a136c8aaf6615653450817a7abe0fc01e4ea720ae41dfb2823eccae4b9062a3"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2dec5a75a3a5d42b120e88e6ed3e3b37b46459202bb8e36cd67591b6e5feebc1"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc10da7e7df3380426521e8c1ed975d22df678639da2ed0ec3244c3dc2ab54c8"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee919b676da28f78f91b464fb3e12238bd7474483352a59c8a16c39dfc59f0c5"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb1c0e682138f9067a58fc3c9a9bf1c83d8e08cfbee380d858e63196466d5c86"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00d8db270afb76f48a499f7bb8fa70297e66da67288471ca873db88382850bf4"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9b0c2b466b2f4d89ccc33784c4ebb1627989bd84a39b79092e560e937a11d4ac"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:51d1b42d44f4ffb93188f9b39e6d1c82aa758fdb8d9de65e1ddfe7a7d250d7ad"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:11abdbfc6f7f7dea4a524b5f4117369b0d757725798f1593796be6ece20266cb"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f02f4a72cc3ab2565c6d9720f0343cb840fb2dc01a2e9ecb8bc58ccf95dc5c06"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-win32.whl", hash = "sha256:81d5dd2dd9ab78d31a451e357315f201d976c131ca7d43870a0e8063b6b7a1ec"}, + {file = "psycopg2_binary-2.9.7-cp37-cp37m-win_amd64.whl", hash = "sha256:62cb6de84d7767164a87ca97e22e5e0a134856ebcb08f21b621c6125baf61f16"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:59f7e9109a59dfa31efa022e94a244736ae401526682de504e87bd11ce870c22"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:95a7a747bdc3b010bb6a980f053233e7610276d55f3ca506afff4ad7749ab58a"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c721ee464e45ecf609ff8c0a555018764974114f671815a0a7152aedb9f3343"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4f37bbc6588d402980ffbd1f3338c871368fb4b1cfa091debe13c68bb3852b3"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac83ab05e25354dad798401babaa6daa9577462136ba215694865394840e31f8"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:024eaeb2a08c9a65cd5f94b31ace1ee3bb3f978cd4d079406aef85169ba01f08"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1c31c2606ac500dbd26381145684d87730a2fac9a62ebcfbaa2b119f8d6c19f4"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:42a62ef0e5abb55bf6ffb050eb2b0fcd767261fa3faf943a4267539168807522"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7952807f95c8eba6a8ccb14e00bf170bb700cafcec3924d565235dffc7dc4ae8"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e02bc4f2966475a7393bd0f098e1165d470d3fa816264054359ed4f10f6914ea"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-win32.whl", hash = "sha256:fdca0511458d26cf39b827a663d7d87db6f32b93efc22442a742035728603d5f"}, + {file = "psycopg2_binary-2.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:d0b16e5bb0ab78583f0ed7ab16378a0f8a89a27256bb5560402749dbe8a164d7"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6822c9c63308d650db201ba22fe6648bd6786ca6d14fdaf273b17e15608d0852"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f94cb12150d57ea433e3e02aabd072205648e86f1d5a0a692d60242f7809b15"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5ee89587696d808c9a00876065d725d4ae606f5f7853b961cdbc348b0f7c9a1"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad5ec10b53cbb57e9a2e77b67e4e4368df56b54d6b00cc86398578f1c635f329"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:642df77484b2dcaf87d4237792246d8068653f9e0f5c025e2c692fc56b0dda70"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6a8b575ac45af1eaccbbcdcf710ab984fd50af048fe130672377f78aaff6fc1"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f955aa50d7d5220fcb6e38f69ea126eafecd812d96aeed5d5f3597f33fad43bb"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ad26d4eeaa0d722b25814cce97335ecf1b707630258f14ac4d2ed3d1d8415265"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ced63c054bdaf0298f62681d5dcae3afe60cbae332390bfb1acf0e23dcd25fc8"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2b04da24cbde33292ad34a40db9832a80ad12de26486ffeda883413c9e1b1d5e"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-win32.whl", hash = "sha256:18f12632ab516c47c1ac4841a78fddea6508a8284c7cf0f292cb1a523f2e2379"}, + {file = "psycopg2_binary-2.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb3b8d55924a6058a26db69fb1d3e7e32695ff8b491835ba9f479537e14dcf9f"}, ] [[package]] name = "pycodestyle" version = "2.7.0" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2256,7 +2115,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2268,7 +2126,6 @@ files = [ name = "pycryptodome" version = "3.13.0" description = "Cryptographic library for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -2308,7 +2165,6 @@ files = [ name = "pydocstyle" version = "6.3.0" description = "Python docstring style checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2317,7 +2173,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">=2.0.0,<5.0.0", markers = "python_version < \"3.8\""} snowballstemmer = ">=2.2.0" [package.extras] @@ -2327,7 +2182,6 @@ toml = ["tomli (>=1.2.3)"] name = "pyflakes" version = "2.3.1" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2337,14 +2191,13 @@ files = [ [[package]] name = "pygments" -version = "2.15.1" +version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, ] [package.extras] @@ -2352,19 +2205,15 @@ plugins = ["importlib-metadata"] [[package]] name = "pyjwt" -version = "2.7.0" +version = "2.8.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "PyJWT-2.7.0-py3-none-any.whl", hash = "sha256:ba2b425b15ad5ef12f200dc67dd56af4e26de2331f965c5439994dad075876e1"}, - {file = "PyJWT-2.7.0.tar.gz", hash = "sha256:bd6ca4a3c4285c1a2d4349e5a035fdf8fb94e04ccd0fcbe6ba289dae9cc3e074"}, + {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"}, + {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, ] -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version <= \"3.7\""} - [package.extras] crypto = ["cryptography (>=3.4.0)"] dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] @@ -2373,34 +2222,37 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pylint" -version = "2.13.9" +version = "2.17.5" description = "python code static checker" -category = "dev" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.2" files = [ - {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, - {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, + {file = "pylint-2.17.5-py3-none-any.whl", hash = "sha256:73995fb8216d3bed149c8d51bba25b2c52a8251a2c8ac846ec668ce38fab5413"}, + {file = "pylint-2.17.5.tar.gz", hash = "sha256:f7b601cbc06fef7e62a754e2b41294c2aa31f1cb659624b9a85bcba29eaf8252"}, ] [package.dependencies] -astroid = ">=2.11.5,<=2.12.0-dev0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -dill = ">=0.2" +astroid = ">=2.15.6,<=2.17.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, +] isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [package.extras] -testutil = ["gitpython (>3)"] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] [[package]] name = "pylint-django" version = "2.5.3" description = "A Pylint plugin to help Pylint understand the Django web framework" -category = "dev" optional = false python-versions = "*" files = [ @@ -2418,14 +2270,13 @@ with-django = ["Django"] [[package]] name = "pylint-plugin-utils" -version = "0.8.1" +version = "0.8.2" description = "Utilities and helpers for writing Pylint plugins" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "pylint_plugin_utils-0.8.1-py3-none-any.whl", hash = "sha256:8d753118eb4189b0f5d07483ab6bbc5770dcd52799ceb6456b0e96309218c80c"}, - {file = "pylint_plugin_utils-0.8.1.tar.gz", hash = "sha256:a595517d238d2ebe586fd867325cc656d4fac8d22b99421ff4cfb51b8c823a93"}, + {file = "pylint_plugin_utils-0.8.2-py3-none-any.whl", hash = "sha256:ae11664737aa2effbf26f973a9e0b6779ab7106ec0adc5fe104b0907ca04e507"}, + {file = "pylint_plugin_utils-0.8.2.tar.gz", hash = "sha256:d3cebf68a38ba3fba23a873809155562571386d4c1b03e5b4c4cc26c3eee93e4"}, ] [package.dependencies] @@ -2433,14 +2284,13 @@ pylint = ">=1.7" [[package]] name = "pymdown-extensions" -version = "10.0.1" +version = "10.1" description = "Extension pack for Python Markdown." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pymdown_extensions-10.0.1-py3-none-any.whl", hash = "sha256:ae66d84013c5d027ce055693e09a4628b67e9dec5bce05727e45b0918e36f274"}, - {file = "pymdown_extensions-10.0.1.tar.gz", hash = "sha256:b44e1093a43b8a975eae17b03c3a77aad4681b3b56fce60ce746dbef1944c8cb"}, + {file = "pymdown_extensions-10.1-py3-none-any.whl", hash = "sha256:ef25dbbae530e8f67575d222b75ff0649b1e841e22c2ae9a20bad9472c2207dc"}, + {file = "pymdown_extensions-10.1.tar.gz", hash = "sha256:508009b211373058debb8247e168de4cbcb91b1bff7b5e961b2c3e864e00b195"}, ] [package.dependencies] @@ -2451,7 +2301,6 @@ pyyaml = "*" name = "pyrsistent" version = "0.19.3" description = "Persistent/Functional/Immutable data structures" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2486,14 +2335,13 @@ files = [ [[package]] name = "python-crontab" -version = "2.7.1" +version = "3.0.0" description = "Python Crontab API" -category = "main" optional = false python-versions = "*" files = [ - {file = "python-crontab-2.7.1.tar.gz", hash = "sha256:b21af4647c7bbb848fef2f020616c6b0289dcb9f94b4f991a55310ff9bec5749"}, - {file = "python_crontab-2.7.1-py3-none-any.whl", hash = "sha256:9c374d1c9d401afdd8dd958f20077f74c158ab3fffb9604296802715e887fe48"}, + {file = "python-crontab-3.0.0.tar.gz", hash = "sha256:79fb7465039ddfd4fb93d072d6ee0d45c1ac8bf1597f0686ea14fd4361dba379"}, + {file = "python_crontab-3.0.0-py3-none-any.whl", hash = "sha256:6d5ba3c190ec76e4d252989a1644fcb233dbf53fbc8fceeb9febe1657b9fb1d4"}, ] [package.dependencies] @@ -2507,7 +2355,6 @@ cron-schedule = ["croniter"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -2522,7 +2369,6 @@ six = ">=1.5" name = "python3-openid" version = "3.2.0" description = "OpenID support for modern servers and consumers." -category = "main" optional = false python-versions = "*" files = [ @@ -2541,7 +2387,6 @@ postgresql = ["psycopg2"] name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -2553,7 +2398,6 @@ files = [ name = "pyuwsgi" version = "2.0.21" description = "The uWSGI server" -category = "main" optional = false python-versions = "*" files = [ @@ -2597,59 +2441,57 @@ files = [ [[package]] name = "pyyaml" -version = "6.0" +version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] name = "pyyaml-env-tag" version = "0.1" description = "A custom YAML tag for referencing environment variables in YAML files. " -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2662,20 +2504,17 @@ pyyaml = "*" [[package]] name = "redis" -version = "4.5.5" +version = "5.0.0" description = "Python client for Redis database and key-value store" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "redis-4.5.5-py3-none-any.whl", hash = "sha256:77929bc7f5dab9adf3acba2d3bb7d7658f1e0c2f1cafe7eb36434e751c471119"}, - {file = "redis-4.5.5.tar.gz", hash = "sha256:dc87a0bdef6c8bfe1ef1e1c40be7034390c2ae02d92dcd0c7ca1729443899880"}, + {file = "redis-5.0.0-py3-none-any.whl", hash = "sha256:06570d0b2d84d46c21defc550afbaada381af82f5b83e5b3777600e05d8e2ed0"}, + {file = "redis-5.0.0.tar.gz", hash = "sha256:5cea6c0d335c9a7332a460ed8729ceabb4d0c489c7285b0a86dbbf8a017bd120"}, ] [package.dependencies] async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} -importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] hiredis = ["hiredis (>=1.0.0)"] @@ -2683,14 +2522,13 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "requests" -version = "2.30.0" +version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"}, - {file = "requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"}, + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, ] [package.dependencies] @@ -2707,7 +2545,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-oauthlib" version = "1.3.1" description = "OAuthlib authentication support for Requests." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2724,18 +2561,17 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"] [[package]] name = "rich" -version = "13.3.5" +version = "13.5.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, - {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, + {file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"}, + {file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"}, ] [package.dependencies] -markdown-it-py = ">=2.2.0,<3.0.0" +markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} @@ -2744,118 +2580,33 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rq" -version = "1.14.1" +version = "1.15.1" description = "RQ is a simple, lightweight, library for creating background jobs, and processing them." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "rq-1.14.1-py2.py3-none-any.whl", hash = "sha256:37e003db1da205e08db6cc4653b7c6ccfd9292000954240308abfce2ebde43ba"}, - {file = "rq-1.14.1.tar.gz", hash = "sha256:5fb86038922ddd76eb2d9aa0adeec6dcf64f159dbbe730b26358b1417120dd44"}, + {file = "rq-1.15.1-py2.py3-none-any.whl", hash = "sha256:6e243d8d9c4af4686ded4b01b25ea1ff4bac4fc260b02638fbe9c8c17b004bd1"}, + {file = "rq-1.15.1.tar.gz", hash = "sha256:1f49f4ac1a084044bb8e95b3f305c0bf17e55618b08c18e0b60c080f12d6f008"}, ] [package.dependencies] click = ">=5.0.0" -redis = ">=3.5.0" - -[[package]] -name = "ruamel-yaml" -version = "0.17.26" -description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -category = "main" -optional = false -python-versions = ">=3" -files = [ - {file = "ruamel.yaml-0.17.26-py3-none-any.whl", hash = "sha256:25d0ee82a0a9a6f44683dcf8c282340def4074a4562f3a24f55695bb254c1693"}, - {file = "ruamel.yaml-0.17.26.tar.gz", hash = "sha256:baa2d0a5aad2034826c439ce61c142c07082b76f4791d54145e131206e998059"}, -] - -[package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.12\""} - -[package.extras] -docs = ["ryd"] -jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] - -[[package]] -name = "ruamel-yaml-clib" -version = "0.2.7" -description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -category = "main" -optional = false -python-versions = ">=3.5" -files = [ - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, - {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, -] +redis = ">=4.0.0" [[package]] name = "rx" version = "1.6.3" description = "Reactive Extensions (Rx) for Python" -category = "main" optional = false python-versions = "*" files = [ {file = "Rx-1.6.3.tar.gz", hash = "sha256:ca71b65d0fc0603a3b5cfaa9e33f5ba81e4aae10a58491133595088d7734b2da"}, ] -[[package]] -name = "setuptools" -version = "67.7.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, - {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - [[package]] name = "singledispatch" version = "4.0.0" description = "Backport functools.singledispatch to older Pythons." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2871,7 +2622,6 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2883,7 +2633,6 @@ files = [ name = "smmap" version = "5.0.0" description = "A pure Python implementation of a sliding window memory map manager" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2895,7 +2644,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -2907,7 +2655,6 @@ files = [ name = "social-auth-app-django" version = "5.0.0" description = "Python Social Authentication, Django integration." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2922,7 +2669,6 @@ social-auth-core = ">=4.1.0" name = "social-auth-core" version = "4.4.2" description = "Python social authentication made simple." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2950,7 +2696,6 @@ saml = ["python3-saml (>=1.5.0)"] name = "sqlparse" version = "0.4.4" description = "A non-validating SQL parser." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2965,25 +2710,22 @@ test = ["pytest", "pytest-cov"] [[package]] name = "stevedore" -version = "3.5.2" +version = "5.1.0" description = "Manage dynamic plugins for Python applications" -category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "stevedore-3.5.2-py3-none-any.whl", hash = "sha256:fa2630e3d0ad3e22d4914aff2501445815b9a4467a6edc49387c667a38faf5bf"}, - {file = "stevedore-3.5.2.tar.gz", hash = "sha256:cf99f41fc0d5a4f185ca4d3d42b03be9011b0a1ec1a4ea1a282be1b4b306dcc2"}, + {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, + {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, ] [package.dependencies] -importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] name = "svgwrite" version = "1.4.3" description = "A Python library to create SVG drawings." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2995,7 +2737,6 @@ files = [ name = "swagger-spec-validator" version = "3.0.3" description = "Validation of Swagger specifications" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3012,7 +2753,6 @@ typing-extensions = "*" name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" -category = "main" optional = false python-versions = "*" files = [ @@ -3024,7 +2764,6 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3033,56 +2772,42 @@ files = [ ] [[package]] -name = "typed-ast" -version = "1.5.4" -description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" +name = "tomlkit" +version = "0.12.1" +description = "Style preserving TOML library" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, + {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, + {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, ] [[package]] name = "typing-extensions" -version = "4.5.0" +version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, +] + +[[package]] +name = "tzdata" +version = "2023.3" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] [[package]] name = "uritemplate" version = "4.1.1" description = "Implementation of RFC 6570 URI Templates" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3092,14 +2817,13 @@ files = [ [[package]] name = "urllib3" -version = "2.0.2" +version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, - {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, + {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, + {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, ] [package.extras] @@ -3112,7 +2836,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "vine" version = "5.0.0" description = "Promises, promises, promises." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3124,7 +2847,6 @@ files = [ name = "watchdog" version = "3.0.0" description = "Filesystem events monitoring" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3164,7 +2886,6 @@ watchmedo = ["PyYAML (>=3.10)"] name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -3176,7 +2897,6 @@ files = [ name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -3259,14 +2979,13 @@ files = [ [[package]] name = "yamllint" -version = "1.31.0" +version = "1.32.0" description = "A linter for YAML files." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "yamllint-1.31.0-py3-none-any.whl", hash = "sha256:15f4bdb645e6a4a0a22fe5415bc38b4a934c51419b30104896d2f3f95e329185"}, - {file = "yamllint-1.31.0.tar.gz", hash = "sha256:2d83f1d12f733e162a87e06b176149d7bb9c5bae4a9e5fce1c771d7f703f7a65"}, + {file = "yamllint-1.32.0-py3-none-any.whl", hash = "sha256:d97a66e48da820829d96077d76b8dfbe6c6140f106e558dae87e81ac4e6b30b7"}, + {file = "yamllint-1.32.0.tar.gz", hash = "sha256:d01dde008c65de5b235188ab3110bebc59d18e5c65fc8a58267cd211cd9df34a"}, ] [package.dependencies] @@ -3278,21 +2997,20 @@ dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] [[package]] name = "zipp" -version = "3.15.0" +version = "3.16.2" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, + {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, + {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [metadata] lock-version = "2.0" -python-versions = "^3.7" -content-hash = "9bff4614f4789110d9842d9cef501144c1f46cb591b46b1bd185a75a7fabc2f5" +python-versions = "^3.8" +content-hash = "99e9f7e5251d14f95b86eb6b5b9adbfe0d2f2f9a427ad47cc07ad3212e13486f" diff --git a/pyproject.toml b/pyproject.toml index f6c1e3f2..6cf6a27a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ packages = [ ] [tool.poetry.dependencies] -python = "^3.7" +python = "^3.8" nautobot = "^1.5.4" [tool.poetry.dev-dependencies] From 62c05cd0f818fec6e953e9e0be102cefa304f3f0 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 24 Aug 2023 10:12:55 +0200 Subject: [PATCH 55/61] Fixing pylint issues after pylint upgrade --- nautobot_bgp_models/filters.py | 13 +++++++------ nautobot_bgp_models/migrations/0001_initial.py | 3 ++- .../migrations/0002_viewsets_migration.py | 1 + nautobot_bgp_models/tests/test_views.py | 2 +- pyproject.toml | 2 -- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/nautobot_bgp_models/filters.py b/nautobot_bgp_models/filters.py index 3a0c0485..dce24768 100644 --- a/nautobot_bgp_models/filters.py +++ b/nautobot_bgp_models/filters.py @@ -1,3 +1,4 @@ +# pylint: disable=unsupported-binary-operation """FilterSet definitions for nautobot_bgp_models.""" import django_filters @@ -24,7 +25,7 @@ class AutonomousSystemFilterSet( tag = TagFilter() - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Free-text search method implementation.""" if not value.strip(): return queryset @@ -70,7 +71,7 @@ class Meta: model = models.BGPRoutingInstance fields = ["id", "autonomous_system"] - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Free-text search method implementation.""" if not value.strip(): return queryset @@ -89,7 +90,7 @@ class Meta: model = models.PeeringRole fields = ["id", "name", "slug", "color", "description"] - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Free-text search method implementation.""" if not value.strip(): return queryset @@ -131,7 +132,7 @@ class Meta: model = models.PeerGroup fields = ["id", "name", "enabled"] - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Free-text search method implementation.""" if not value.strip(): return queryset @@ -164,7 +165,7 @@ class Meta: model = models.PeerGroupTemplate fields = ["id", "name", "enabled"] - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Free-text search method implementation.""" if not value.strip(): return queryset @@ -202,7 +203,7 @@ class Meta: model = models.PeerEndpoint fields = ["id", "enabled"] - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Free-text search method implementation.""" if not value.strip(): return queryset diff --git a/nautobot_bgp_models/migrations/0001_initial.py b/nautobot_bgp_models/migrations/0001_initial.py index 14f577c6..9ea615c2 100644 --- a/nautobot_bgp_models/migrations/0001_initial.py +++ b/nautobot_bgp_models/migrations/0001_initial.py @@ -1,5 +1,7 @@ +# pylint: disable=missing-module-docstring,missing-function-docstring,missing-class-docstring,invalid-name # Generated by Django 3.2.13 on 2022-06-22 08:16 +import uuid import django.core.serializers.json from django.db import migrations, models import django.db.models.deletion @@ -9,7 +11,6 @@ import nautobot.extras.models.statuses import nautobot.utilities.fields import taggit.managers -import uuid class Migration(migrations.Migration): diff --git a/nautobot_bgp_models/migrations/0002_viewsets_migration.py b/nautobot_bgp_models/migrations/0002_viewsets_migration.py index e4cc3b51..5578df18 100644 --- a/nautobot_bgp_models/migrations/0002_viewsets_migration.py +++ b/nautobot_bgp_models/migrations/0002_viewsets_migration.py @@ -1,3 +1,4 @@ +# pylint: disable=missing-module-docstring,missing-function-docstring,missing-class-docstring,invalid-name # Generated by Django 3.2.18 on 2023-03-15 21:03 from django.db import migrations diff --git a/nautobot_bgp_models/tests/test_views.py b/nautobot_bgp_models/tests/test_views.py index a10b69a7..2bcd7d64 100644 --- a/nautobot_bgp_models/tests/test_views.py +++ b/nautobot_bgp_models/tests/test_views.py @@ -1,8 +1,8 @@ """Unit test automation for Model classes in nautobot_bgp_models.""" +from unittest import skipIf from importlib import metadata from packaging import version -from unittest import skipIf from django.contrib.contenttypes.models import ContentType from nautobot.circuits.models import Provider diff --git a/pyproject.toml b/pyproject.toml index 6cf6a27a..b4f74782 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,12 +79,10 @@ no-docstring-rgx="^(_|test_|Meta$)" good-names = '''_,i,j,k,pk''' [tool.pylint.messages_control] -# bad-continuation: Pylint and Black disagree about how to format multi-line arrays; Black wins. # line-too-long: Line length is enforced by Black, so pylint doesn't need to check it. # too-few-public-methods: is just plain noise. # too-many-ancestors: is just a fact of life when dealing with Django and Nautobot inheritance hierarchies. disable = """, - bad-continuation, line-too-long, too-few-public-methods, too-many-ancestors, From 47ebdd0c86be5fcaf34dc5f4af59ffc88567b85c Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 24 Aug 2023 16:18:01 +0200 Subject: [PATCH 56/61] Adding python 3.11 into CI matrix --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 774d96a0..1c787099 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,7 +119,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11"] db-backend: ["postgresql"] nautobot-version: ["stable"] include: From 082a4b5f98bb8d44e15e390ed300dc43f71c5df7 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 24 Aug 2023 10:30:06 +0200 Subject: [PATCH 57/61] Release 0.8.0 --- docs/admin/compatibility_matrix.md | 1 + docs/admin/release_notes/version_0.8.md | 22 ++++++++++++++++++++++ mkdocs.yml | 1 + pyproject.toml | 2 +- 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 docs/admin/release_notes/version_0.8.md diff --git a/docs/admin/compatibility_matrix.md b/docs/admin/compatibility_matrix.md index ac35baa9..2e925287 100644 --- a/docs/admin/compatibility_matrix.md +++ b/docs/admin/compatibility_matrix.md @@ -4,3 +4,4 @@ |--------------------|--------------------------------|-------------------------------| | 0.7.0 | 1.3.0 | 1.99.99 | | 0.7.1 | 1.5.4 | 1.99.99 | +| 0.8.0 | 1.5.4 | 1.99.99 | diff --git a/docs/admin/release_notes/version_0.8.md b/docs/admin/release_notes/version_0.8.md new file mode 100644 index 00000000..8eb3101a --- /dev/null +++ b/docs/admin/release_notes/version_0.8.md @@ -0,0 +1,22 @@ +# v0.8 Release Notes + +## Release Overview + +- BGP Models v0.8 release + +## [v0.8.0] - 2023-08-24 + +### Added +- [#91](https://github.com/nautobot/nautobot-plugin-bgp-models/issues/91) - Implements Nautobot Viewsets for UI and API +- [#91](https://github.com/nautobot/nautobot-plugin-bgp-models/issues/91) - Adds Nautobot Notes support +- [#96](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/96) - Adds CSV Imports / Exports +- [#97](https://github.com/nautobot/nautobot-plugin-bgp-models/issues/97) - Adds `Status` field on `BGPRoutingInstance` model +- [#114](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/114) - Adds `Device Role` and `Peer Endpoint Role` filters on `Peering` model + +### Changed +- [#96](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/96) - Renames field `template` to `peergroup_template` on `PeerGroup` model +- [#116](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/116) - Disables endpoint ordering in `Peering` table +- [#122](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/122) - Removes mandatory `Provider` field for external `Peer Endpoints` + +### Removed +- [#124](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/124) - Removes support for Python 3.7 diff --git a/mkdocs.yml b/mkdocs.yml index 83bb0b6d..0595a805 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -109,6 +109,7 @@ nav: - Release Notes: - "admin/release_notes/index.md" - v0.7: "admin/release_notes/version_0.7.md" + - v0.8: "admin/release_notes/version_0.8.md" - Developer Guide: - BGP Data Models: "dev/models.md" - Extending the App: "dev/extending.md" diff --git a/pyproject.toml b/pyproject.toml index b4f74782..130189bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-bgp-models" -version = "0.7.1" +version = "0.8.0" description = "Nautobot BGP Models Plugin" authors = ["Network to Code, LLC "] From c56acb2e981cf397ad468828856fe37e8455ad50 Mon Sep 17 00:00:00 2001 From: Marek Zbroch Date: Thu, 24 Aug 2023 20:24:05 +0200 Subject: [PATCH 58/61] Pin mkdocstrings-python to 1.4.0 to have compatibility with griffe --- docs/requirements.txt | 4 ++-- poetry.lock | 28 +++++++++++++++------------- pyproject.toml | 4 ++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8cd16e3d..551c3fac 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ mkdocs==1.3.1 mkdocs-material==8.4.2 -mkdocstrings==0.19 -mkdocstrings-python==0.7.1 +mkdocstrings==0.22 +mkdocstrings-python==1.4.0 mkdocs-version-annotations==1.0.0 diff --git a/poetry.lock b/poetry.lock index 847f41fd..a3940de0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.12" [[package]] name = "griffe" -version = "0.34.0" +version = "0.35.0" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." optional = false python-versions = ">=3.8" files = [ - {file = "griffe-0.34.0-py3-none-any.whl", hash = "sha256:d8bca9bd4a0880e7f71dc152de4222171d941a32b5504d77450a71a7908dfc1d"}, - {file = "griffe-0.34.0.tar.gz", hash = "sha256:48c667ad51a7f756238f798866203aeb8f9fa02d4192e25970f57f813bb37f26"}, + {file = "griffe-0.35.0-py3-none-any.whl", hash = "sha256:52b1dc86dfca6db5877d65a07997f8363f61f14266064cf1cae41b70aac9f395"}, + {file = "griffe-0.35.0.tar.gz", hash = "sha256:d313f102da3d155fe0a3d284acb0fc93059ee6788903a2e983eb4f64a713fac1"}, ] [package.dependencies] @@ -1713,22 +1713,24 @@ files = [ [[package]] name = "mkdocstrings" -version = "0.19.0" +version = "0.22.0" description = "Automatic documentation from sources, for MkDocs." optional = false python-versions = ">=3.7" files = [ - {file = "mkdocstrings-0.19.0-py3-none-any.whl", hash = "sha256:3217d510d385c961f69385a670b2677e68e07b5fea4a504d86bf54c006c87c7d"}, - {file = "mkdocstrings-0.19.0.tar.gz", hash = "sha256:efa34a67bad11229d532d89f6836a8a215937548623b64f3698a1df62e01cc3e"}, + {file = "mkdocstrings-0.22.0-py3-none-any.whl", hash = "sha256:2d4095d461554ff6a778fdabdca3c00c468c2f1459d469f7a7f622a2b23212ba"}, + {file = "mkdocstrings-0.22.0.tar.gz", hash = "sha256:82a33b94150ebb3d4b5c73bab4598c3e21468c79ec072eff6931c8f3bfc38256"}, ] [package.dependencies] +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} Jinja2 = ">=2.11.1" Markdown = ">=3.3" MarkupSafe = ">=1.1" mkdocs = ">=1.2" mkdocs-autorefs = ">=0.3.1" pymdown-extensions = ">=6.3" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.10\""} [package.extras] crystal = ["mkdocstrings-crystal (>=0.3.4)"] @@ -1737,18 +1739,18 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] [[package]] name = "mkdocstrings-python" -version = "0.7.1" +version = "1.4.0" description = "A Python handler for mkdocstrings." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocstrings-python-0.7.1.tar.gz", hash = "sha256:c334b382dca202dfa37071c182418a6df5818356a95d54362a2b24822ca3af71"}, - {file = "mkdocstrings_python-0.7.1-py3-none-any.whl", hash = "sha256:a22060bfa374697678e9af4e62b020d990dad2711c98f7a9fac5c0345bef93c7"}, + {file = "mkdocstrings_python-1.4.0-py3-none-any.whl", hash = "sha256:46f4b0ed8540c6bfd0c3f50471831a7bdb9a1bf35f24400525721d7555aa355c"}, + {file = "mkdocstrings_python-1.4.0.tar.gz", hash = "sha256:c92304c402928a05c793203dadee7a1a51b5ae56404fd594d0b2db49a7b3957a"}, ] [package.dependencies] -griffe = ">=0.11.1" -mkdocstrings = ">=0.19" +griffe = ">=0.33" +mkdocstrings = ">=0.20" [[package]] name = "mypy-extensions" @@ -3013,4 +3015,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "99e9f7e5251d14f95b86eb6b5b9adbfe0d2f2f9a427ad47cc07ad3212e13486f" +content-hash = "821f74c4db6d4c6a90cd08a248d1f29b8d835ed6603678ad21cb3b31e213ff04" diff --git a/pyproject.toml b/pyproject.toml index 130189bf..2f5ab178 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,8 +42,8 @@ mkdocs-material = "8.4.2" # Render custom markdown for version added/changed/remove notes mkdocs-version-annotations = "1.0.0" # Automatic documentation from sources, for MkDocs -mkdocstrings = "0.19" -mkdocstrings-python = "0.7.1" +mkdocstrings = "0.22" +mkdocstrings-python = "1.4.0" [tool.black] line-length = 120 From 50a033be4d42544f56d314e66513c577e17185fe Mon Sep 17 00:00:00 2001 From: Glenn Matthews Date: Wed, 27 Sep 2023 14:05:01 -0400 Subject: [PATCH 59/61] PeerGroupAddressFamily and PeerEndpointAddressFamily (#132) * Add PeerGroupAddressFamily and PeerEndpointAddressFamily models and associated functionality * Add test coverage * Update docs * Pylint * Flake8 * Fix test failures * Make PeerGroup VRF-aware * pydocstyle * Address review feedback * Add release-note entry * Pylint fix * Remove deleted fields from template --- docs/admin/release_notes/version_0.9.md | 17 ++ docs/dev/models.md | 72 +++-- docs/user/app_overview.md | 18 +- docs/user/cisco_use_case.md | 55 ++-- docs/user/juniper_use_case.md | 53 ++-- mkdocs.yml | 1 + nautobot_bgp_models/api/nested_serializers.py | 34 ++- nautobot_bgp_models/api/serializers.py | 70 ++++- nautobot_bgp_models/api/urls.py | 2 + nautobot_bgp_models/api/views.py | 16 + nautobot_bgp_models/choices.py | 4 + nautobot_bgp_models/dolt_compat.py | 2 + nautobot_bgp_models/filters.py | 75 +++++ nautobot_bgp_models/forms.py | 177 +++++++++-- ...addressfamily_peerendpointaddressfamily.py | 173 +++++++++++ nautobot_bgp_models/models.py | 278 ++++++++++++++--- nautobot_bgp_models/navigation.py | 40 ++- nautobot_bgp_models/tables.py | 87 +++++- .../addressfamily_retrieve.html | 31 +- .../bgproutinginstance_retrieve.html | 38 +++ .../peerendpoint_retrieve.html | 45 ++- .../peerendpointaddressfamily_retrieve.html | 74 +++++ .../peergroup_retrieve.html | 49 ++- .../peergroupaddressfamily_retrieve.html | 68 +++++ .../peergrouptemplate_retrieve.html | 21 -- nautobot_bgp_models/tests/test_api.py | 287 ++++++++++++++++-- nautobot_bgp_models/tests/test_filters.py | 196 ++++++++++++ nautobot_bgp_models/tests/test_models.py | 14 +- nautobot_bgp_models/tests/test_views.py | 178 ++++++++++- nautobot_bgp_models/urls.py | 20 ++ nautobot_bgp_models/views.py | 32 ++ 31 files changed, 1941 insertions(+), 286 deletions(-) create mode 100644 docs/admin/release_notes/version_0.9.md create mode 100644 nautobot_bgp_models/migrations/0003_peergroupaddressfamily_peerendpointaddressfamily.py create mode 100644 nautobot_bgp_models/templates/nautobot_bgp_models/peerendpointaddressfamily_retrieve.html create mode 100644 nautobot_bgp_models/templates/nautobot_bgp_models/peergroupaddressfamily_retrieve.html diff --git a/docs/admin/release_notes/version_0.9.md b/docs/admin/release_notes/version_0.9.md new file mode 100644 index 00000000..9c175a68 --- /dev/null +++ b/docs/admin/release_notes/version_0.9.md @@ -0,0 +1,17 @@ +# v0.9 Release Notes + +## Release Overview + +This version introduces `PeerGroupAddressFamily` and `PeerEndpointAddressFamily` data models to provide for more granular configuration modeling. + +!!! warning + This version **removes** the `import_policy`, `export_policy`, and `multipath` attributes from the `PeerGroupTemplate`, `PeerGroup`, and `PeerEndpoint` models, as these are generally address-family-specific configuration attributes and are modeled as such now. No data migration is provided at this time (as there is no way to identify **which** AFI-SAFI any existing policy/multipath configs should be migrated to), and upgrading to this version will therefore necessarily result in data loss if you had previously populated these model fields. Back up your configuration or record this data in some other format before upgrading if appropriate. + +### Added + +- [#26](https://github.com/nautobot/nautobot-plugin-bgp-models/issues/26) - Adds `PeerGroupAddressFamily` and `PeerEndpointAddressFamily` data models. +- [#132](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/132) - Adds `extra_attributes` support to the `AddressFamily` model. + +### Removed + +- [#132](https://github.com/nautobot/nautobot-plugin-bgp-models/pull/132) - Removes `import_policy`, `export_policy`, and `multipath` attributes from `PeerGroupTemplate`, `PeerGroup`, and `PeerEndpoint` models. Use the equivalent fields on `PeerGroupAddressFamily` and `PeerEndpointAddressFamily` instead. diff --git a/docs/dev/models.md b/docs/dev/models.md index 2d9d79a0..c1ede3e4 100644 --- a/docs/dev/models.md +++ b/docs/dev/models.md @@ -3,13 +3,15 @@ This plugin adds the following data models to Nautobot: - AutonomousSystem +- PeeringRole - BGPRoutingInstance -- PeerEndpoint -- PeerGroup -- PeerGroupTemplate - AddressFamily +- PeerGroupTemplate +- PeerGroup +- PeerGroupAddressFamily +- PeerEndpoint +- PeerEndpointAddressFamily - Peering -- PeeringRole A key motivation behind this design is the idea that the Source of Truth should take a network-wide view of the BGP configuration rather than a per-device view. This especially applies to the data models for autonomous systems (ASNs), BGP peerings, and network-wide templates (Peer Groups). @@ -31,6 +33,10 @@ The data models introduced by the BGP plugin support the following Nautobot feat This model represents a network-wide description of a BGP autonomous system (AS). It has fields including the actual AS number (ASN), a description field, foreign key (FK) to a Nautobot `Provider` object, and a FK to a Nautobot `Status` object. +### PeeringRole + +This model operates similarly to Nautobot’s `Status` and `Tag` models, in that instances of this model describe various valid values for the `Role` field used by `PeerGroup` and `Peering` records. Similar to those models, this model has fields including a unique name, unique slug, and HTML color code. + ### BGPRoutingInstance This model represents a device specific BGP process. It has a mandatory FK to a Nautobot `Device`, mandatory FK to a `AutonomousSystem` and following fields: @@ -53,14 +59,24 @@ Example of the extra attributes: Extra Attributes are available for following models: -- `PeerEndpoint` -- `PeerGroup` -- `PeerGroupTemplate` - `BGPRoutingInstance` +- `AddressFamily` +- `PeerGroupTemplate` +- `PeerGroup` +- `PeerGroupAddressFamily` +- `PeerEndpoint` +- `PeerEndpointAddressFamily` -### PeeringRole +### AddressFamily -This model operates similarly to Nautobot’s `Status` and `Tag` models, in that instances of this model describe various valid values for the `Role` field used by `PeerGroup` and `Peering` records. Similar to those models, this model has fields including a unique name, unique slug, and HTML color code. +This model represents configuration of a BGP address-family (AFI-SAFI). AddressFamily aims to represent a device specific Address Family instance. + +It has a locally unique AFI (address family identifier) field, optional VRF field (FK to Nautobot `VRF`) and following fields: + +- Import Policy (optional, string) +- Export Policy (optional, string) + +(*) The network-wide modeling of AddressFamilies will be implemented in the future with `AddressFamilyTemplate` model similar to the `PeerGroupTemplate`. ### PeerGroupTemplate @@ -70,8 +86,6 @@ This model represents a network-wide configuration for `PeerGroups`. `PeerGroupT - Role (optional, FK to `PeeringRole`) - Description (string) - Enabled (bool) -- Import Policy (optional, string) -- Export Policy (optional, string) - Secret (optional, FK to Nautobot `Secret`) - Extra Attributes (optional, JSON) @@ -85,9 +99,15 @@ This model represents a common configuration for a group of functionally related - Role (optional, FK to `PeeringRole`) - Description (string) - Enabled (bool) +- Secret (optional, FK to Nautobot `Secret`) +- Extra Attributes (optional, JSON) + +### PeerGroupAddressFamily + +This model represents address-family-specific configuration of a PeerGroup. It has a mandatory FK to a `PeerGroup` and a mandatory `afi_safi` field, and additional fields including + - Import Policy (optional, string) - Export Policy (optional, string) -- Secret (optional, FK to Nautobot `Secret`) - Extra Attributes (optional, JSON) ### PeerEndpoint @@ -107,13 +127,9 @@ Note that in the case of an external peering (connection with an ISP or Transit - Role (optional, FK to `PeeringRole`) - Description (string) - Enabled (bool) -- Import Policy (optional, string) -- Export Policy (optional, string) - Secret (optional, FK to Nautobot `Secret`) - Extra Attributes (optional, JSON) -The device-specific `PeerEndpoint` custom modeling will be implemented in the future with `PeerEndpointContext` and `PeerGroupContext` models. - #### PeerEndpoint Local-IP To ease the data presentation and consumption, `PeerEndpoint` provides a property named `local_ip`. @@ -127,16 +143,13 @@ As Source-IP and Source-Interface could be defined at multiple inheritance level 3. `PeerEndpoint`'s `source_interface` attribute (if exists) 4. `PeerGroup`'s `source_interface` attribute (if exists) -### AddressFamily - -This model represents configuration of a BGP address-family (AFI-SAFI). AddressFamily aims to represent a device specific Address Family instance. +### PeerEndpointAddressFamily -It has a locally unique AFI (address family identifier) field, optional VRF field (FK to Nautobot `VRF`) and following fields: +This model represents address-family-specific configuration of a device's PeerEndpoint. It has a mandatory FK to a `PeerEndpoint` and a mandatory `afi_safi` field, and additional keys including: - Import Policy (optional, string) - Export Policy (optional, string) - -(*) The network-wide modeling of AddressFamilies will be implemented in the future with `AddressFamilyTemplate` model similar to the `PeerGroupTemplate`. +- Extra Attributes (optional, JSON) ### Peering @@ -201,3 +214,18 @@ Following is the complete documentation of the field inheritance hierarchy. Mode | export_policy | PeerGroupTemplate | | import_policy | PeerGroupTemplate | | role | PeerGroupTemplate | + +**PeerGroupAddressFamily**: + +| **Attribute** | **Inheritance from model** | +| ------------- | -------------------------- | +| extra_attributes | AddressFamily (same `afi_safi` only) | + +**PeerEndpointAddressFamily**: + +| **Attribute** | **Inheritance from model** | +| ------------- | -------------------------- | +| extra_attributes | PeerGroupAddressFamily (same `afi_safi` only) → AddressFamily (same `afi_safi` only) | +| import_policy | PeerGroupAddressFamily (same `afi_safi` only) | +| export_policy | PeerGroupAddressFamily (same `afi_safi` only) | +| multipath | PeerGroupAddressFamily (same `afi_safi` only) | diff --git a/docs/user/app_overview.md b/docs/user/app_overview.md index a7647732..6f883cc6 100644 --- a/docs/user/app_overview.md +++ b/docs/user/app_overview.md @@ -11,13 +11,15 @@ An app for [Nautobot](https://github.com/nautobot/nautobot), extending the core This application adds the following new data models into Nautobot: -- **BGP Routing Instance**: device-specific BGP process - **Autonomous System**: network-wide description of a BGP autonomous system (AS) +- **Peering Role**: describes the valid options for PeerGroup, PeerGroupTemplate, and/or Peering roles +- **BGP Routing Instance**: device-specific BGP process +- **Address Family**: device-specific configuration of a BGP address family (AFI-SAFI) with an optional VRF - **Peer Group Template**: network-wide template for Peer Group objects - **Peer Group**: device-specific configuration for a group of functionally related BGP peers -- **Address Family**: device-specific configuration of a BGP address family (AFI-SAFI) +- **Peer Group Address Family**: peer-group-specific configuration of a BGP address-family (AFI-SAFI) - **Peering and Peer Endpoints**: A BGP Peering is represented by a Peering object and two endpoints, each representing the configuration of one side of the BGP peering. A Peer Endpoint must be associated with a BGP Routing Instance. -- **Peering Role**: describes the valid options for PeerGroup, PeerGroupTemplate, and/or Peering roles +- **Peer Endpoint Address Family**: peer-specific configuration of a BGP address-family (AFI-SAFI) With these new models, it's now possible to populate the Source of Truth (SoT) with any BGP peerings, internal or external, regardless of whether both endpoints are fully defined in the Source of Truth. @@ -37,13 +39,15 @@ Network Admins who need to model their BGP internal and external peerings inside This plugin adds the following data models to Nautobot: - AutonomousSystem +- PeeringRole - BGPRoutingInstance -- PeerEndpoint -- PeerGroup -- PeerGroupTemplate - AddressFamily +- PeerGroupTemplate +- PeerGroup +- PeerGroupAddressFamily +- PeerEndpoint +- PeerEndpointAddressFamily - Peering -- PeeringRole The data models introduced by the BGP plugin support the following Nautobot features: diff --git a/docs/user/cisco_use_case.md b/docs/user/cisco_use_case.md index 40e2c1c5..3a4ab4e4 100644 --- a/docs/user/cisco_use_case.md +++ b/docs/user/cisco_use_case.md @@ -22,13 +22,16 @@ query ($device_id: ID!) { peer_groups { name extra_attributes - template { + peergroup_template { autonomous_system { asn } + extra_attributes + } + address_families { + afi_safi import_policy export_policy - extra_attributes } } endpoints { @@ -85,23 +88,29 @@ An example data returned from Nautobot is presented below. { "name": "EDGE-to-LEAF", "extra_attributes": null, - "template": { + "peergroup_template": { "autonomous_system": null, - "import_policy": "BGP-LEAF-IN", - "export_policy": "BGP-LEAF-OUT", - "extra_attributes": { - "next-hop-self": true, - "send-community": true - }, + "extra_attributes": {}, "role": { "slug": "peer" } - } + }, + "address_families": [ + { + "afi_safi": "IPV4_UNICAST", + "import_policy": "BGP-LEAF-IN", + "export_policy": "BGP-LEAF-OUT", + "extra_attributes": { + "next-hop-self": true, + "send-community": true, + } + } + ] }, { "name": "EDGE-to-TRANSIT", "extra_attributes": null, - "template": { + "peergroup_template": { "autonomous_system": null, "import_policy": "BGP-TRANSIT-IN", "export_policy": "BGP-TRANSIT-OUT", @@ -111,7 +120,15 @@ An example data returned from Nautobot is presented below. "role": { "slug": "customer" } - } + }, + "address_families": [ + { + "afi_safi": "IPV4_UNICAST", + "import_policy": "BGP-TRANSIT-IN", + "export_policy": "BGP-TRANSIT-OUT", + "extra_attributes": {} + } + ] } ], "endpoints": [ @@ -318,16 +335,16 @@ Following snippet represents an example Cisco BGP Configuration Template: router bgp {{ data.device.bgp_routing_instances.0.autonomous_system.asn }} {%- for peer_group in data.device.bgp_routing_instances.0.peer_groups %} neighbor {{ peer_group.name }} peer-group - neighbor {{ peer_group.name }} route-map {{ peer_group.template.import_policy }} in - neighbor {{ peer_group.name }} route-map {{ peer_group.template.export_policy }} out -{%- if "next-hop-self" in peer_group.template.extra_attributes %} + neighbor {{ peer_group.name }} route-map {{ peer_group.address_families.0.import_policy }} in + neighbor {{ peer_group.name }} route-map {{ peer_group.address_families.0.export_policy }} out +{%- if "next-hop-self" in peer_group.address_families.0.extra_attributes %} neighbor {{ peer_group.name }} next-hop-self {%- endif %} -{%- if "send-community" in peer_group.template.extra_attributes %} +{%- if "send-community" in peer_group.address_families.0.extra_attributes %} neighbor {{ peer_group.name }} send-community {%- endif %} -{%- if "ttl_security_hops" in peer_group.template.extra_attributes %} - neighbor {{ peer_group.name }} ttl-security hops {{ peer_group.template.extra_attributes.ttl_security_hops }} +{%- if "ttl_security_hops" in peer_group.peergroup_template.extra_attributes %} + neighbor {{ peer_group.name }} ttl-security hops {{ peer_group.peergroup_template.extra_attributes.ttl_security_hops }} {%- endif %} {%- endfor %} ! @@ -352,7 +369,7 @@ router bgp {{ data.device.bgp_routing_instances.0.autonomous_system.asn }} ## Rendering Cisco Jinja2 BGP Configuration Template with the data retrieved from GraphQL -Following snippet represents an example Cisco BGP Renderer Configuration: +Following snippet represents an example Cisco BGP rendered configuration: ```text ! diff --git a/docs/user/juniper_use_case.md b/docs/user/juniper_use_case.md index b3e67e53..dffd6bcc 100644 --- a/docs/user/juniper_use_case.md +++ b/docs/user/juniper_use_case.md @@ -22,10 +22,17 @@ query ($device_id: ID!) { peer_groups { name extra_attributes - template { + peergroup_template { autonomous_system { asn } + role { + slug + } + extra_attributes + } + address_families { + afi_safi import_policy export_policy extra_attributes @@ -85,33 +92,45 @@ An example data returned from Nautobot is presented below. { "name": "EDGE-to-LEAF", "extra_attributes": null, - "template": { + "peergroup_template": { "autonomous_system": null, - "import_policy": "BGP-LEAF-IN", - "export_policy": "BGP-LEAF-OUT", - "extra_attributes": { - "next-hop-self": true, - "send-community": true - }, "role": { "slug": "peer" } - } + "extra_attributes": {} + }, + "address_families": [ + { + "afi_safi": "IPV4_UNICAST", + "import_policy": "BGP-LEAF-IN", + "export_policy": "BGP-LEAF-OUT", + "extra_attributes": { + "next-hop-self": true, + "send-community": true + } + } + ] }, { "name": "EDGE-to-TRANSIT", "extra_attributes": null, - "template": { + "peergroup_template": { "autonomous_system": null, - "import_policy": "BGP-TRANSIT-IN", - "export_policy": "BGP-TRANSIT-OUT", "extra_attributes": { "ttl_security_hops": 1 }, "role": { "slug": "customer" } - } + }, + "address_families": [ + { + "afi_safi": "IPV4_UNICAST", + "import_policy": "BGP-TRANSIT-IN", + "export_policy": "BGP-TRANSIT-OUT", + "extra_attributes": {} + } + ] } ], "endpoints": [ @@ -319,14 +338,14 @@ set routing-options autonomous-system {{ data.device.bgp_routing_instances.0.aut # Configure Groups {%- for peer_group in data.device.bgp_routing_instances.0.peer_groups %} -{%- if peer_group.template.role.slug == "peer" %} +{%- if peer_group.peergroup_template.role.slug == "peer" %} set protocols bgp group {{ peer_group.name }} type internal {%- endif %} -{%- if peer_group.template.role.slug == "customer" %} +{%- if peer_group.peergroup_template.role.slug == "customer" %} set protocols bgp group {{ peer_group.name }} type external {%- endif %} -set protocols bgp group {{ peer_group.name }} import {{ peer_group.template.import_policy }} -set protocols bgp group {{ peer_group.name }} export {{ peer_group.template.export_policy }} +set protocols bgp group {{ peer_group.name }} import {{ peer_group.address_families.0.import_policy }} +set protocols bgp group {{ peer_group.name }} export {{ peer_group.address_families.0.export_policy }} {%- endfor %} # Configure Peers diff --git a/mkdocs.yml b/mkdocs.yml index 0595a805..95007b13 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -110,6 +110,7 @@ nav: - "admin/release_notes/index.md" - v0.7: "admin/release_notes/version_0.7.md" - v0.8: "admin/release_notes/version_0.8.md" + - v0.9: "admin/release_notes/version_0.9.md" - Developer Guide: - BGP Data Models: "dev/models.md" - Extending the App: "dev/extending.md" diff --git a/nautobot_bgp_models/api/nested_serializers.py b/nautobot_bgp_models/api/nested_serializers.py index ed628c3c..048adac5 100644 --- a/nautobot_bgp_models/api/nested_serializers.py +++ b/nautobot_bgp_models/api/nested_serializers.py @@ -7,14 +7,16 @@ from nautobot_bgp_models import models __all__ = ( + "NestedAddressFamilySerializer", "NestedAutonomousSystemSerializer", + "NestedBGPRoutingInstanceSerializer", + "NestedPeerEndpointAddressFamilySerializer", + "NestedPeerEndpointSerializer", "NestedPeeringRoleSerializer", + "NestedPeeringSerializer", + "NestedPeerGroupAddressFamilySerializer", "NestedPeerGroupSerializer", "NestedPeerGroupTemplateSerializer", - "NestedPeerEndpointSerializer", - "NestedPeeringSerializer", - "NestedAddressFamilySerializer", - "NestedBGPRoutingInstanceSerializer", ) @@ -98,3 +100,27 @@ class NestedAddressFamilySerializer(WritableNestedSerializer): class Meta: model = models.AddressFamily fields = ["id", "url", "afi_safi"] + + +class NestedPeerGroupAddressFamilySerializer(WritableNestedSerializer): + """Nested/brief serializer for PeerGroupAddressFamily.""" + + url = serializers.HyperlinkedIdentityField( + view_name="plugins-api:nautobot_bgp_models-api:peergroupaddressfamily-detail" + ) + + class Meta: + model = models.PeerGroupAddressFamily + fields = ["id", "url"] + + +class NestedPeerEndpointAddressFamilySerializer(WritableNestedSerializer): + """Nested/brief serializer for PeerEndpointAddressFamily.""" + + url = serializers.HyperlinkedIdentityField( + view_name="plugins-api:nautobot_bgp_models-api:peerendpointaddressfamily-detail" + ) + + class Meta: + model = models.PeerEndpointAddressFamily + fields = ["id", "url"] diff --git a/nautobot_bgp_models/api/serializers.py b/nautobot_bgp_models/api/serializers.py index e8cc2099..c3b997c3 100644 --- a/nautobot_bgp_models/api/serializers.py +++ b/nautobot_bgp_models/api/serializers.py @@ -1,6 +1,6 @@ """REST API serializers for nautobot_bgp_models models.""" -from rest_framework import serializers +from rest_framework import serializers, validators from nautobot.dcim.api.serializers import NestedDeviceSerializer, NestedInterfaceSerializer from nautobot.ipam.api.serializers import NestedVRFSerializer, NestedIPAddressSerializer @@ -95,8 +95,6 @@ class Meta: "description", "enabled", "autonomous_system", - "import_policy", - "export_policy", "extra_attributes", "secret", ] @@ -117,6 +115,8 @@ class PeerGroupSerializer( autonomous_system = NestedAutonomousSystemSerializer(required=False, allow_null=True) # noqa: F405 + vrf = NestedVRFSerializer(required=False, allow_null=True) + peergroup_template = NestedPeerGroupTemplateSerializer(required=False, allow_null=True) # noqa: F405 secret = NestedSecretSerializer(required=False, allow_null=True) @@ -133,13 +133,24 @@ class Meta: "enabled", "autonomous_system", "routing_instance", + "vrf", "peergroup_template", "secret", "extra_attributes", "role", - "import_policy", - "export_policy", ] + validators = [] + + def validate(self, data): + """Custom validation logic to handle unique-together with a nullable field.""" + if data.get("vrf"): + validator = validators.UniqueTogetherValidator( + queryset=models.PeerGroup.objects.all(), fields=("routing_instance", "name", "vrf") + ) + validator(data, self) + + super().validate(data) + return data class PeerEndpointSerializer( @@ -171,8 +182,6 @@ class Meta: "autonomous_system", "peer_group", "peer", - "import_policy", - "export_policy", "peering", "secret", "tags", @@ -247,7 +256,7 @@ class Meta: ] -class AddressFamilySerializer(NautobotModelSerializer): +class AddressFamilySerializer(NautobotModelSerializer, ExtraAttributesSerializerMixin): """REST API serializer for AddressFamily records.""" url = serializers.HyperlinkedIdentityField(view_name="plugins-api:nautobot_bgp_models-api:addressfamily-detail") @@ -264,6 +273,51 @@ class Meta: "afi_safi", "routing_instance", "vrf", + "extra_attributes", + ] + + +class PeerGroupAddressFamilySerializer(NautobotModelSerializer, ExtraAttributesSerializerMixin): + """REST API serializer for PeerGroupAddressFamily records.""" + + url = serializers.HyperlinkedIdentityField( + view_name="plugins-api:nautobot_bgp_models-api:peergroupaddressfamily-detail" + ) + + peer_group = NestedPeerGroupSerializer(required=True) # noqa: F405 + + class Meta: + model = models.PeerGroupAddressFamily + fields = [ + "id", + "url", + "afi_safi", + "peer_group", + "import_policy", "export_policy", + "multipath", + "extra_attributes", + ] + + +class PeerEndpointAddressFamilySerializer(NautobotModelSerializer, ExtraAttributesSerializerMixin): + """REST API serializer for PeerEndpointAddressFamily records.""" + + url = serializers.HyperlinkedIdentityField( + view_name="plugins-api:nautobot_bgp_models-api:peerendpointaddressfamily-detail" + ) + + peer_endpoint = NestedPeerEndpointSerializer(required=True) # noqa: F405 + + class Meta: + model = models.PeerEndpointAddressFamily + fields = [ + "id", + "url", + "afi_safi", + "peer_endpoint", "import_policy", + "export_policy", + "multipath", + "extra_attributes", ] diff --git a/nautobot_bgp_models/api/urls.py b/nautobot_bgp_models/api/urls.py index f645bafe..19b8ac56 100644 --- a/nautobot_bgp_models/api/urls.py +++ b/nautobot_bgp_models/api/urls.py @@ -14,6 +14,8 @@ router.register("peer-endpoints", views.PeerEndpointViewSet) router.register("peerings", views.PeeringViewSet) router.register("address-families", views.AddressFamilyViewSet) +router.register("peer-group-address-families", views.PeerGroupAddressFamilyViewSet) +router.register("peer-endpoint-address-families", views.PeerEndpointAddressFamilyViewSet) router.register("routing-instances", views.BGPRoutingInstanceViewSet) urlpatterns = router.urls diff --git a/nautobot_bgp_models/api/views.py b/nautobot_bgp_models/api/views.py index 77b0523e..01316a3b 100644 --- a/nautobot_bgp_models/api/views.py +++ b/nautobot_bgp_models/api/views.py @@ -113,3 +113,19 @@ class AddressFamilyViewSet(InheritableFieldsViewSetMixin, PluginModelViewSet): queryset = models.AddressFamily.objects.all() serializer_class = serializers.AddressFamilySerializer filterset_class = filters.AddressFamilyFilterSet + + +class PeerGroupAddressFamilyViewSet(InheritableFieldsViewSetMixin, PluginModelViewSet): + """REST API viewset for PeerGroupAddressFamily records.""" + + queryset = models.PeerGroupAddressFamily.objects.all() + serializer_class = serializers.PeerGroupAddressFamilySerializer + filterset_class = filters.PeerGroupAddressFamilyFilterSet + + +class PeerEndpointAddressFamilyViewSet(InheritableFieldsViewSetMixin, PluginModelViewSet): + """REST API viewset for PeerEndpointAddressFamily records.""" + + queryset = models.PeerEndpointAddressFamily.objects.all() + serializer_class = serializers.PeerEndpointAddressFamilySerializer + filterset_class = filters.PeerEndpointAddressFamilyFilterSet diff --git a/nautobot_bgp_models/choices.py b/nautobot_bgp_models/choices.py index e4ba9f32..ddfbb481 100644 --- a/nautobot_bgp_models/choices.py +++ b/nautobot_bgp_models/choices.py @@ -7,9 +7,11 @@ class AFISAFIChoices(ChoiceSet): """Choices for the "afi_safi" field on the AddressFamily model.""" AFI_IPV4_UNICAST = "ipv4_unicast" + AFI_IPV4_LABELED_UNICAST = "ipv4_labeled_unicast" AFI_IPV4_MULTICAST = "ipv4_multicast" AFI_IPV6_UNICAST = "ipv6_unicast" + AFI_IPV6_LABELED_UNICAST = "ipv6_labeled_unicast" AFI_IPV6_MULTICAST = "ipv6_multicast" AFI_IPV4_FLOWSPEC = "ipv4_flowspec" @@ -26,9 +28,11 @@ class AFISAFIChoices(ChoiceSet): CHOICES = ( (AFI_IPV4_UNICAST, "IPv4 Unicast"), + (AFI_IPV4_LABELED_UNICAST, "IPv4 Labeled Unicast"), (AFI_IPV4_MULTICAST, "IPv4 Multicast"), (AFI_IPV4_FLOWSPEC, "IPv4 Flowspec"), (AFI_IPV6_UNICAST, "IPv6 Unicast"), + (AFI_IPV6_LABELED_UNICAST, "IPv6 Labeled Unicast"), (AFI_IPV6_MULTICAST, "IPv6 Multicast"), (AFI_IPV6_FLOWSPEC, "IPv6 Flowspec"), (AFI_VPNV4_UNICAST, "VPNv4 Unicast"), diff --git a/nautobot_bgp_models/dolt_compat.py b/nautobot_bgp_models/dolt_compat.py index 6d9a7466..03361303 100644 --- a/nautobot_bgp_models/dolt_compat.py +++ b/nautobot_bgp_models/dolt_compat.py @@ -20,8 +20,10 @@ "autonomoussystem": tables.AutonomousSystemTable, "peeringrole": tables.PeeringRoleTable, "peergroup": tables.PeerGroupTable, + "peergroupaddressfamily": tables.PeerGroupAddressFamilyTable, "peergrouptemplate": tables.PeerGroupTemplateTable, "peerendpoint": tables.PeerEndpointTable, + "peerendpointaddressfamily": tables.PeerEndpointAddressFamilyTable, "peering": tables.PeeringTable, "addressfamily": tables.AddressFamilyTable, } diff --git a/nautobot_bgp_models/filters.py b/nautobot_bgp_models/filters.py index dce24768..99af6e27 100644 --- a/nautobot_bgp_models/filters.py +++ b/nautobot_bgp_models/filters.py @@ -121,6 +121,13 @@ class PeerGroupFilterSet(BaseFilterSet): label="BGP Routing Instance ID", ) + vrf = django_filters.ModelMultipleChoiceFilter( + field_name="vrf__name", + queryset=VRF.objects.all(), + to_field_name="name", + label="VRF (name)", + ) + role = django_filters.ModelMultipleChoiceFilter( field_name="role__slug", queryset=models.PeeringRole.objects.all(), @@ -271,3 +278,71 @@ class Meta: "afi_safi", "vrf", ] + + +class PeerGroupAddressFamilyFilterSet(BaseFilterSet, CreatedUpdatedFilterSet, CustomFieldModelFilterSet): + """Filtering of PeerGroupAddressFamily records.""" + + q = django_filters.CharFilter( + method="search", + label="Search", + ) + + afi_safi = django_filters.MultipleChoiceFilter(choices=choices.AFISAFIChoices) + + peer_group = django_filters.ModelMultipleChoiceFilter( + label="Peer Group (ID)", + queryset=models.PeerGroup.objects.all(), + ) + + class Meta: + model = models.PeerGroupAddressFamily + fields = [ + "id", + "afi_safi", + "peer_group", + ] + + def search(self, queryset, name, value): # pylint: disable=unused-argument + """Free-text search method implementation.""" + if not value.strip(): + return queryset + return queryset.filter( + Q(afi_safi__icontains=value) + | Q(peer_group__name__icontains=value) + | Q(peer_group__description__icontains=value) + ).distinct() + + +class PeerEndpointAddressFamilyFilterSet(BaseFilterSet, CreatedUpdatedFilterSet, CustomFieldModelFilterSet): + """Filtering of PeerEndpointAddressFamily records.""" + + q = django_filters.CharFilter( + method="search", + label="Search", + ) + + afi_safi = django_filters.MultipleChoiceFilter(choices=choices.AFISAFIChoices) + + peer_endpoint = django_filters.ModelMultipleChoiceFilter( + label="Peer Endpoint (ID)", + queryset=models.PeerEndpoint.objects.all(), + ) + + class Meta: + model = models.PeerEndpointAddressFamily + fields = [ + "id", + "afi_safi", + "peer_endpoint", + ] + + def search(self, queryset, name, value): # pylint: disable=unused-argument + """Free-text search method implementation.""" + if not value.strip(): + return queryset + return queryset.filter( + Q(afi_safi__icontains=value) + | Q(peer_endpoint__routing_instance__device__name__iexact=value) + | Q(peer_endpoint__description__icontains=value) + ).distinct() diff --git a/nautobot_bgp_models/forms.py b/nautobot_bgp_models/forms.py index 63b62b32..8e497e76 100644 --- a/nautobot_bgp_models/forms.py +++ b/nautobot_bgp_models/forms.py @@ -249,13 +249,6 @@ class Meta: class PeerGroupForm(NautobotModelForm): """Form for creating/updating PeerGroup records.""" - def __init__(self, *args, **kwargs): - """Init.""" - super().__init__(*args, **kwargs) - - if self.initial.get("routing_instance"): - self.fields["routing_instance"].disabled = True - routing_instance = DynamicModelChoiceField( queryset=models.BGPRoutingInstance.objects.all(), required=True, @@ -263,11 +256,20 @@ def __init__(self, *args, **kwargs): help_text="Specify related Routing Instance (Device)", ) + vrf = DynamicModelChoiceField( + queryset=VRF.objects.all(), + required=False, + label="VRF", + ) + source_ip = DynamicModelChoiceField( queryset=IPAddress.objects.all(), required=False, label="Source IP Address", - query_params={"nautobot_bgp_models_ips_bgp_routing_instance": "$routing_instance"}, + query_params={ + "nautobot_bgp_models_ips_bgp_routing_instance": "$routing_instance", + "vrf": "$vrf", + }, ) source_interface = DynamicModelChoiceField( @@ -294,6 +296,7 @@ class Meta: fields = ( "routing_instance", "name", + "vrf", "peergroup_template", "description", "enabled", @@ -301,8 +304,6 @@ class Meta: "source_ip", "source_interface", "autonomous_system", - "import_policy", - "export_policy", "secret", "extra_attributes", ) @@ -343,8 +344,6 @@ class Meta: "enabled", "role", "autonomous_system", - "import_policy", - "export_policy", "extra_attributes", ) @@ -382,6 +381,8 @@ class PeerGroupFilterForm(NautobotFilterForm): queryset=models.AutonomousSystem.objects.all(), to_field_name="asn", required=False ) + vrf = DynamicModelMultipleChoiceField(queryset=VRF.objects.all(), required=False) + class PeerGroupTemplateFilterForm(NautobotFilterForm): """Form for filtering PeerGroupTemplate records in combination with PeerGroupTemplateFilterSet.""" @@ -435,6 +436,12 @@ class PeerGroupCSVForm(CustomFieldModelCSVForm): required=False, ) + vrf = CSVModelChoiceField( + queryset=VRF.objects.all(), + to_field_name="name", + required=False, + ) + autonomous_system = CSVModelChoiceField( queryset=models.AutonomousSystem.objects.all(), to_field_name="asn", @@ -540,8 +547,6 @@ class Meta: "source_interface", "autonomous_system", "peer_group", - "import_policy", - "export_policy", "secret", "extra_attributes", ) @@ -636,26 +641,20 @@ class AddressFamilyForm(NautobotModelForm): label="VRF", ) - multipath = forms.NullBooleanField(required=False, widget=utilities_forms.BulkEditNullBooleanSelect()) - class Meta: model = models.AddressFamily fields = ( "routing_instance", "afi_safi", "vrf", - "import_policy", - "export_policy", - "multipath", + "extra_attributes", ) class AddressFamilyBulkEditForm(NautobotBulkEditForm): """Form for bulk-editing multiple AddressFamily records.""" - pk = forms.ModelMultipleChoiceField( - queryset=models.AutonomousSystem.objects.all(), widget=forms.MultipleHiddenInput() - ) + pk = forms.ModelMultipleChoiceField(queryset=models.AddressFamily.objects.all(), widget=forms.MultipleHiddenInput()) class Meta: nullable_fields = [] @@ -684,3 +683,137 @@ class AddressFamilyCSVForm(CustomFieldModelCSVForm): class Meta: model = models.AddressFamily fields = models.AddressFamily.csv_headers + + +class PeerGroupAddressFamilyForm(NautobotModelForm): + """Form for creating/updating PeerGroupAddressFamily records.""" + + peer_group = DynamicModelChoiceField( + queryset=models.PeerGroup.objects.all(), + required=True, + label="BGP Peer Group", + ) + + afi_safi = forms.ChoiceField( + label="AFI-SAFI", + choices=choices.AFISAFIChoices, + required=False, + widget=utilities_forms.StaticSelect2(), + ) + + multipath = forms.NullBooleanField(required=False, widget=utilities_forms.BulkEditNullBooleanSelect()) + + class Meta: + model = models.PeerGroupAddressFamily + fields = ( + "peer_group", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + "extra_attributes", + ) + + +class PeerGroupAddressFamilyBulkEditForm(NautobotBulkEditForm): + """Form for bulk-editing multiple PeerGroupAddressFamily records.""" + + pk = forms.ModelMultipleChoiceField( + queryset=models.PeerGroupAddressFamily.objects.all(), widget=forms.MultipleHiddenInput() + ) + import_policy = forms.CharField(max_length=100, required=False) + export_policy = forms.CharField(max_length=100, required=False) + multipath = forms.NullBooleanField(required=False, widget=utilities_forms.BulkEditNullBooleanSelect()) + + class Meta: + nullable_fields = ["import_policy", "export_policy", "multipath"] + + +class PeerGroupAddressFamilyFilterForm(NautobotFilterForm): + """Form for filtering PeerGroupAddressFamily records in combination with PeerGroupAddressFamilyFilterSet.""" + + model = models.PeerGroupAddressFamily + + peer_group = DynamicModelMultipleChoiceField(queryset=models.PeerGroup.objects.all(), required=False) + + afi_safi = forms.MultipleChoiceField( + label="AFI-SAFI", + choices=choices.AFISAFIChoices, + required=False, + widget=utilities_forms.StaticSelect2Multiple(), + ) + + +class PeerGroupAddressFamilyCSVForm(CustomFieldModelCSVForm): + """Form for importing PeerGroupAddressFamily from CSV data.""" + + class Meta: + model = models.PeerGroupAddressFamily + fields = models.PeerGroupAddressFamily.csv_headers + + +class PeerEndpointAddressFamilyForm(NautobotModelForm): + """Form for creating/updating PeerEndpointAddressFamily records.""" + + peer_endpoint = DynamicModelChoiceField( + queryset=models.PeerEndpoint.objects.all(), + required=True, + label="BGP Peer Endpoint", + ) + + afi_safi = forms.ChoiceField( + label="AFI-SAFI", + choices=choices.AFISAFIChoices, + required=False, + widget=utilities_forms.StaticSelect2(), + ) + + multipath = forms.NullBooleanField(required=False, widget=utilities_forms.BulkEditNullBooleanSelect()) + + class Meta: + model = models.PeerGroupAddressFamily + fields = ( + "peer_endpoint", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + "extra_attributes", + ) + + +class PeerEndpointAddressFamilyBulkEditForm(NautobotBulkEditForm): + """Form for bulk-editing multiple PeerEndpointAddressFamily records.""" + + pk = forms.ModelMultipleChoiceField( + queryset=models.PeerEndpointAddressFamily.objects.all(), widget=forms.MultipleHiddenInput() + ) + import_policy = forms.CharField(max_length=100, required=False) + export_policy = forms.CharField(max_length=100, required=False) + multipath = forms.NullBooleanField(required=False, widget=utilities_forms.BulkEditNullBooleanSelect()) + + class Meta: + nullable_fields = ["import_policy", "export_policy", "multipath"] + + +class PeerEndpointAddressFamilyFilterForm(NautobotFilterForm): + """Form for filtering PeerEndpointAddressFamily records in combination with PeerEndpointAddressFamilyFilterSet.""" + + model = models.PeerEndpointAddressFamily + + peer_endpoint = DynamicModelMultipleChoiceField(queryset=models.PeerEndpoint.objects.all(), required=False) + + afi_safi = forms.MultipleChoiceField( + label="AFI-SAFI", + choices=choices.AFISAFIChoices, + required=False, + widget=utilities_forms.StaticSelect2Multiple(), + ) + + +class PeerEndpointAddressFamilyCSVForm(CustomFieldModelCSVForm): + """Form for importing PeerEndpointAddressFamily from CSV data.""" + + class Meta: + model = models.PeerEndpointAddressFamily + fields = models.PeerEndpointAddressFamily.csv_headers diff --git a/nautobot_bgp_models/migrations/0003_peergroupaddressfamily_peerendpointaddressfamily.py b/nautobot_bgp_models/migrations/0003_peergroupaddressfamily_peerendpointaddressfamily.py new file mode 100644 index 00000000..1f65b366 --- /dev/null +++ b/nautobot_bgp_models/migrations/0003_peergroupaddressfamily_peerendpointaddressfamily.py @@ -0,0 +1,173 @@ +# pylint: disable=missing-module-docstring,missing-function-docstring,missing-class-docstring,invalid-name +# Generated by Django 3.2.16 on 2023-09-18 19:03 +import uuid + +import django.core.serializers.json +from django.db import migrations, models +import django.db.models.deletion +import nautobot.extras.models.mixins + + +class Migration(migrations.Migration): + dependencies = [ + ("ipam", "0008_prefix_vlan_vlangroup_location"), + ("nautobot_bgp_models", "0002_viewsets_migration"), + ] + + operations = [ + migrations.RemoveField( + model_name="addressfamily", + name="export_policy", + ), + migrations.RemoveField( + model_name="addressfamily", + name="import_policy", + ), + migrations.RemoveField( + model_name="addressfamily", + name="multipath", + ), + migrations.RemoveField( + model_name="peerendpoint", + name="export_policy", + ), + migrations.RemoveField( + model_name="peerendpoint", + name="import_policy", + ), + migrations.RemoveField( + model_name="peergroup", + name="export_policy", + ), + migrations.RemoveField( + model_name="peergroup", + name="import_policy", + ), + migrations.RemoveField( + model_name="peergrouptemplate", + name="export_policy", + ), + migrations.RemoveField( + model_name="peergrouptemplate", + name="import_policy", + ), + migrations.AddField( + model_name="addressfamily", + name="extra_attributes", + field=models.JSONField(blank=True, encoder=django.core.serializers.json.DjangoJSONEncoder, null=True), + ), + migrations.AddField( + model_name="peergroup", + name="vrf", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="peer_groups", + to="ipam.vrf", + ), + ), + migrations.AlterField( + model_name="addressfamily", + name="vrf", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="address_families", + to="ipam.vrf", + ), + ), + migrations.AlterUniqueTogether( + name="peergroup", + unique_together={("name", "routing_instance", "vrf")}, + ), + migrations.CreateModel( + name="PeerGroupAddressFamily", + fields=[ + ( + "id", + models.UUIDField( + default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True + ), + ), + ("created", models.DateField(auto_now_add=True, null=True)), + ("last_updated", models.DateTimeField(auto_now=True, null=True)), + ( + "_custom_field_data", + models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder), + ), + ( + "extra_attributes", + models.JSONField(blank=True, encoder=django.core.serializers.json.DjangoJSONEncoder, null=True), + ), + ("afi_safi", models.CharField(max_length=64)), + ("import_policy", models.CharField(blank=True, default="", max_length=100)), + ("export_policy", models.CharField(blank=True, default="", max_length=100)), + ("multipath", models.BooleanField(blank=True, null=True)), + ( + "peer_group", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="address_families", + to="nautobot_bgp_models.peergroup", + ), + ), + ], + options={ + "verbose_name": "BGP peer-group address family", + "verbose_name_plural": "BGP Peer-Group Address Families", + "ordering": ["-peer_group"], + "unique_together": {("peer_group", "afi_safi")}, + }, + bases=( + models.Model, + nautobot.extras.models.mixins.DynamicGroupMixin, + nautobot.extras.models.mixins.NotesMixin, + ), + ), + migrations.CreateModel( + name="PeerEndpointAddressFamily", + fields=[ + ( + "id", + models.UUIDField( + default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True + ), + ), + ("created", models.DateField(auto_now_add=True, null=True)), + ("last_updated", models.DateTimeField(auto_now=True, null=True)), + ( + "_custom_field_data", + models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder), + ), + ( + "extra_attributes", + models.JSONField(blank=True, encoder=django.core.serializers.json.DjangoJSONEncoder, null=True), + ), + ("afi_safi", models.CharField(max_length=64)), + ("import_policy", models.CharField(blank=True, default="", max_length=100)), + ("export_policy", models.CharField(blank=True, default="", max_length=100)), + ("multipath", models.BooleanField(blank=True, null=True)), + ( + "peer_endpoint", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="address_families", + to="nautobot_bgp_models.peerendpoint", + ), + ), + ], + options={ + "verbose_name": "BGP peer-endpoint address family", + "verbose_name_plural": "BGP Peer-Endpoint Address Families", + "ordering": ["-peer_endpoint"], + "unique_together": {("peer_endpoint", "afi_safi")}, + }, + bases=( + models.Model, + nautobot.extras.models.mixins.DynamicGroupMixin, + nautobot.extras.models.mixins.NotesMixin, + ), + ), + ] diff --git a/nautobot_bgp_models/models.py b/nautobot_bgp_models/models.py index 260adaf0..c44e30b4 100644 --- a/nautobot_bgp_models/models.py +++ b/nautobot_bgp_models/models.py @@ -1,5 +1,4 @@ -"""Django model definitions for nautobot_bgp_models.""" - +"""BGP data models.""" import functools from collections import OrderedDict @@ -294,10 +293,6 @@ class PeerGroupTemplate(PrimaryModel, BGPExtraAttributesMixin): on_delete=models.PROTECT, ) - import_policy = models.CharField(max_length=100, default="", blank=True) - - export_policy = models.CharField(max_length=100, default="", blank=True) - secret = models.ForeignKey( to="extras.Secret", on_delete=models.PROTECT, @@ -305,14 +300,12 @@ class PeerGroupTemplate(PrimaryModel, BGPExtraAttributesMixin): blank=True, null=True, ) - csv_headers = ["name", "import_policy", "export_policy", "autonomous_system", "enabled", "role"] + csv_headers = ["name", "autonomous_system", "enabled", "role"] def to_csv(self): """Render a PeerGroupTemplate record to CSV fields.""" return ( self.name, - self.import_policy, - self.export_policy, self.autonomous_system.asn if self.autonomous_system else None, self.enabled, self.role.name if self.role else None, @@ -347,8 +340,6 @@ class PeerGroup(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): "autonomous_system": ["peergroup_template", "routing_instance"], "description": ["peergroup_template"], "enabled": ["peergroup_template"], - "export_policy": ["peergroup_template"], - "import_policy": ["peergroup_template"], "role": ["peergroup_template"], } @@ -363,6 +354,15 @@ class PeerGroup(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): to=PeeringRole, on_delete=models.PROTECT, related_name="peer_groups", blank=True, null=True ) + vrf = models.ForeignKey( + to="ipam.VRF", + verbose_name="VRF", + related_name="peer_groups", + blank=True, + null=True, + on_delete=models.PROTECT, + ) + description = models.CharField(max_length=200, blank=True) enabled = models.BooleanField(default=True) @@ -400,10 +400,6 @@ class PeerGroup(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): verbose_name="Source Interface", ) - import_policy = models.CharField(max_length=100, default="", blank=True) - - export_policy = models.CharField(max_length=100, default="", blank=True) - secret = models.ForeignKey( to="extras.Secret", on_delete=models.PROTECT, @@ -416,8 +412,7 @@ class PeerGroup(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): "name", "routing_instance", "autonomous_system", - "import_policy", - "export_policy", + "vrf", "source_interface", "source_ip", "peergroup_template", @@ -431,8 +426,7 @@ def to_csv(self): self.name, self.routing_instance.pk, self.autonomous_system.asn if self.autonomous_system else None, - self.import_policy, - self.export_policy, + self.vrf.name if self.vrf else None, self.source_interface.name if self.source_interface else None, self.source_ip.address if self.source_ip else None, self.peergroup_template.name if self.peergroup_template else None, @@ -442,14 +436,16 @@ def to_csv(self): def __str__(self): """String.""" - return f"{self.name}" + if self.vrf: + return f"{self.name} (VRF {self.vrf}) - {self.routing_instance.device}" + return f"{self.name} - {self.routing_instance.device}" def get_absolute_url(self): """Get the URL for detailed view of a single PeerGroup.""" return reverse("plugins:nautobot_bgp_models:peergroup", args=[self.pk]) class Meta: - unique_together = [("name", "routing_instance")] + unique_together = [("name", "routing_instance", "vrf")] verbose_name = "BGP Peer Group" def clean(self): @@ -458,14 +454,43 @@ def clean(self): if self.source_ip and self.source_interface: raise ValidationError("Can not set both IP and Update source options") - # Ensure source_interface interface has 1 IP Address assigned - if self.source_interface and self.source_interface.ip_addresses.count() != 1: - raise ValidationError("Source Interface must have only 1 IP Address assigned.") - - # Ensure IP related to the routing instance - if self.routing_instance and self.source_ip: + if self.source_interface: + # Ensure source_interface interface has 1 IP Address assigned + if self.source_interface.ip_addresses.count() != 1: + raise ValidationError("Source Interface must have only 1 IP Address assigned.") + # Ensure VRF membership + if self.source_interface.ip_addresses.all().first().vrf != self.vrf: + raise ValidationError( + f"VRF mismatch between PeerGroup VRF ({self.vrf}) " + f"and selected source interface VRF ({self.source_interface.ip_addresses.all().first().vrf})" + ) + + if self.source_ip: + # Ensure IP related to the routing instance if self.source_ip not in IPAddress.objects.filter(interface__device_id=self.routing_instance.device.id): raise ValidationError("Group IP not associated with Routing Instance") + # Ensure VRF membership + if self.source_ip.vrf != self.vrf: + raise ValidationError( + f"VRF mismatch between PeerGroup VRF ({self.vrf}) and selected source IP VRF ({self.source_ip.vrf})" + ) + + if self.present_in_database: + original = self.__class__.objects.get(id=self.id) + if self.vrf != original.vrf and self.endpoints.exists(): + raise ValidationError("Cannot change VRF of PeerGroup that has existing PeerEndpoints in this VRF.") + + def validate_unique(self, exclude=None): + """Validate uniqueness, handling NULL != NULL for VRF foreign key.""" + if ( + self.vrf is None + and self.__class__.objects.exclude(id=self.id) + .filter(routing_instance=self.routing_instance, name=self.name, vrf__isnull=True) + .exists() + ): + raise ValidationError(f"Duplicate Peer Group name for {self.routing_instance}") + + super().validate_unique(exclude) @extras_features( @@ -485,8 +510,6 @@ class PeerEndpoint(PrimaryModel, InheritanceMixin, BGPExtraAttributesMixin): "autonomous_system": ["peer_group", "peer_group.peergroup_template", "routing_instance"], "description": ["peer_group", "peer_group.peergroup_template"], "enabled": ["peer_group", "peer_group.peergroup_template"], - "export_policy": ["peer_group", "peer_group.peergroup_template"], - "import_policy": ["peer_group", "peer_group.peergroup_template"], "source_ip": ["peer_group"], "source_interface": ["peer_group"], "role": ["peer_group.role", "peer_group.peergroup_template.role"], @@ -589,10 +612,6 @@ def local_ip(self): return None - import_policy = models.CharField(max_length=100, default="", blank=True) - - export_policy = models.CharField(max_length=100, default="", blank=True) - secret = models.ForeignKey( to="extras.Secret", on_delete=models.PROTECT, @@ -603,10 +622,11 @@ def local_ip(self): def __str__(self): """String.""" + asn, _, _ = self.get_inherited_field(field_name="autonomous_system") if self.routing_instance and self.routing_instance.device: - return f"{self.routing_instance.device}" + return f"{self.routing_instance.device} {self.local_ip} ({asn})" - return f"{self.local_ip} ({self.autonomous_system})" + return f"{self.local_ip} ({asn})" def get_absolute_url(self): """Get the URL for detailed view of a single PeerEndpoint.""" @@ -646,6 +666,14 @@ def clean(self): elif not self.routing_instance and local_ip_value.interface.exists(): raise ValidationError("Must specify Routing Instance for this IP Address") + # Enforce peer group VRF membership + if self.peer_group is not None: + if local_ip_value.vrf != self.peer_group.vrf: + raise ValidationError( + f"VRF mismatch between {local_ip_value} (VRF {local_ip_value.vrf}) " + f"and peer-group {self.peer_group.name} (VRF {self.peer_group.vrf})" + ) + @extras_features( "custom_fields", @@ -715,14 +743,17 @@ def validate_peers(self): "relationships", "webhooks", ) -class AddressFamily(OrganizationalModel): - """Address-family (AFI-SAFI) model.""" +class AddressFamily(OrganizationalModel, BGPExtraAttributesMixin): + """Address-family (AFI-SAFI) model for the RoutingInstance and VRF levels of configuration.""" + + extra_attributes_inheritance = [] afi_safi = models.CharField(max_length=64, choices=AFISAFIChoices, verbose_name="AFI-SAFI") vrf = models.ForeignKey( to="ipam.VRF", verbose_name="VRF", + related_name="address_families", blank=True, null=True, on_delete=models.PROTECT, @@ -735,12 +766,6 @@ class AddressFamily(OrganizationalModel): verbose_name="BGP Routing Instance", ) - import_policy = models.CharField(max_length=100, default="", blank=True) - - export_policy = models.CharField(max_length=100, default="", blank=True) - - multipath = models.BooleanField(blank=True, null=True) - class Meta: ordering = ["-routing_instance", "-vrf"] verbose_name = "BGP address family" @@ -750,9 +775,6 @@ class Meta: "routing_instance", "vrf", "afi_safi", - "import_policy", - "export_policy", - "multipath", ] def to_csv(self): @@ -761,9 +783,6 @@ def to_csv(self): self.routing_instance.pk, self.vrf.name if self.vrf else None, self.afi_safi, - self.import_policy, - self.export_policy, - self.multipath, ) def __str__(self): @@ -796,3 +815,164 @@ def validate_unique(self, exclude=None): raise ValidationError("Duplicate Address Family") super().validate_unique(exclude) + + +@extras_features( + "custom_fields", + "custom_links", + "custom_validators", + "export_templates", + "graphql", + "relationships", + "webhooks", +) +class PeerGroupAddressFamily(OrganizationalModel, InheritanceMixin, BGPExtraAttributesMixin): + """Address-family (AFI-SAFI) model for PeerGroup-specific configuration.""" + + @property + def parent_address_family(self): + """The routing-instance AddressFamily (if any) that this PeerGroupAddressFamily inherits from.""" + try: + return self.peer_group.routing_instance.address_families.get( + vrf=self.peer_group.vrf, afi_safi=self.afi_safi + ) + except AddressFamily.DoesNotExist: + return None + + extra_attributes_inheritance = ["parent_address_family"] + + property_inheritance = {} # no non-extra-attributes properties inherited from AddressFamily at this time + + afi_safi = models.CharField(max_length=64, choices=AFISAFIChoices, verbose_name="AFI-SAFI") + + peer_group = models.ForeignKey( + to=PeerGroup, + on_delete=models.CASCADE, + related_name="address_families", + ) + + import_policy = models.CharField(max_length=100, default="", blank=True) + + export_policy = models.CharField(max_length=100, default="", blank=True) + + multipath = models.BooleanField(blank=True, null=True) + + class Meta: + ordering = ["-peer_group"] + unique_together = ["peer_group", "afi_safi"] + verbose_name = "BGP peer-group address family" + verbose_name_plural = "BGP Peer-Group Address Families" + + csv_headers = [ + "peer_group", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + ] + + def to_csv(self): + """Return a list of values for use in CSV export.""" + return ( + str(self.peer_group), + self.afi_safi, + self.import_policy, + self.export_policy, + str(self.multipath), + ) + + def __str__(self): + """String representation.""" + return f"{self.afi_safi} AF - {self.peer_group}" + + def get_absolute_url(self): + """Absolute URL of a record.""" + return reverse("plugins:nautobot_bgp_models:peergroupaddressfamily", args=[self.pk]) + + +@extras_features( + "custom_fields", + "custom_links", + "custom_validators", + "export_templates", + "graphql", + "relationships", + "webhooks", +) +class PeerEndpointAddressFamily(OrganizationalModel, InheritanceMixin, BGPExtraAttributesMixin): + """Address-family (AFI-SAFI) model for PeerEndpoint-specific configuration.""" + + @property + def parent_peer_group_address_family(self): + """The PeerGroupAddressFamily (if any) that this PeerEndpointAddressFamily inherits from.""" + try: + parent_pg = self.peer_endpoint.peer_group + if parent_pg is not None: + return parent_pg.address_families.get(afi_safi=self.afi_safi) + except PeerGroupAddressFamily.DoesNotExist: + pass + return None + + @property + def parent_address_family(self): + """The routing-instance AddressFamily (if any) that this PeerEndpointAddressFamily inherits from.""" + try: + return self.peer_endpoint.routing_instance.address_families.get( + vrf=self.peer_endpoint.local_ip.vrf, afi_safi=self.afi_safi + ) + except AddressFamily.DoesNotExist: + return None + + extra_attributes_inheritance = ["parent_peer_group_address_family", "parent_address_family"] + + property_inheritance = { + "import_policy": ["parent_peer_group_address_family"], + "export_policy": ["parent_peer_group_address_family"], + "multipath": ["parent_peer_group_address_family"], + } + + afi_safi = models.CharField(max_length=64, choices=AFISAFIChoices, verbose_name="AFI-SAFI") + + peer_endpoint = models.ForeignKey( + to=PeerEndpoint, + on_delete=models.CASCADE, + related_name="address_families", + ) + + import_policy = models.CharField(max_length=100, default="", blank=True) + + export_policy = models.CharField(max_length=100, default="", blank=True) + + multipath = models.BooleanField(blank=True, null=True) + + class Meta: + ordering = ["-peer_endpoint"] + unique_together = ["peer_endpoint", "afi_safi"] + verbose_name = "BGP peer-endpoint address family" + verbose_name_plural = "BGP Peer-Endpoint Address Families" + + csv_headers = [ + "peer_endpoint", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + ] + + def to_csv(self): + """Return a list of values for use in CSV export.""" + return ( + str(self.peer_endpoint), + self.afi_safi, + self.import_policy, + self.export_policy, + str(self.multipath), + ) + + def __str__(self): + """String representation.""" + return f"{self.afi_safi} AF - {self.peer_endpoint}" + + def get_absolute_url(self): + """Absolute URL of a record.""" + return reverse("plugins:nautobot_bgp_models:peerendpointaddressfamily", args=[self.pk]) diff --git a/nautobot_bgp_models/navigation.py b/nautobot_bgp_models/navigation.py index cc901a43..f83fdbd1 100644 --- a/nautobot_bgp_models/navigation.py +++ b/nautobot_bgp_models/navigation.py @@ -77,6 +77,21 @@ ), ), ), + NavMenuItem( + link="plugins:nautobot_bgp_models:addressfamily_list", + name="Address-families (AFI-SAFI)", + permissions=["nautobot_bgp_models.view_addressfamily"], + buttons=( + NavMenuAddButton( + link="plugins:nautobot_bgp_models:addressfamily_add", + permissions=["nautobot_bgp_models.add_addressfamily"], + ), + NavMenuImportButton( + link="plugins:nautobot_bgp_models:addressfamily_import", + permissions=["nautobot_bgp_models.add_addressfamily"], + ), + ), + ), NavMenuItem( link="plugins:nautobot_bgp_models:peergroup_list", name="Peer Groups", @@ -93,17 +108,17 @@ ), ), NavMenuItem( - link="plugins:nautobot_bgp_models:addressfamily_list", - name="Address-families (AFI-SAFI)", - permissions=["nautobot_bgp_models.view_addressfamily"], + link="plugins:nautobot_bgp_models:peergroupaddressfamily_list", + name="Peer Group Address-families (AFI-SAFI)", + permissions=["nautobot_bgp_models.view_peergroupaddressfamily"], buttons=( NavMenuAddButton( - link="plugins:nautobot_bgp_models:addressfamily_add", - permissions=["nautobot_bgp_models.add_addressfamily"], + link="plugins:nautobot_bgp_models:peergroupaddressfamily_add", + permissions=["nautobot_bgp_models.add_peergroupaddressfamily"], ), NavMenuImportButton( - link="plugins:nautobot_bgp_models:addressfamily_import", - permissions=["nautobot_bgp_models.add_addressfamily"], + link="plugins:nautobot_bgp_models:peergroupaddressfamily_import", + permissions=["nautobot_bgp_models.add_peergroupaddressfamily"], ), ), ), @@ -124,6 +139,17 @@ ), ), ), + NavMenuItem( + link="plugins:nautobot_bgp_models:peerendpointaddressfamily_list", + name="Peer Endpoint Address-families (AFI-SAFI)", + permissions=["nautobot_bgp_models.view_peerendpointaddressfamily"], + buttons=( + NavMenuAddButton( + link="plugins:nautobot_bgp_models:peerendpointaddressfamily_add", + permissions=["nautobot_bgp_models.add_peerendpointaddressfamily"], + ), + ), + ), ), ), ), diff --git a/nautobot_bgp_models/tables.py b/nautobot_bgp_models/tables.py index c2c4a8b8..e163df51 100644 --- a/nautobot_bgp_models/tables.py +++ b/nautobot_bgp_models/tables.py @@ -86,6 +86,7 @@ class PeerGroupTable(BaseTable): name = tables.LinkColumn() peergroup_template = tables.LinkColumn() routing_instance = tables.LinkColumn() + vrf = tables.LinkColumn() enabled = BooleanColumn() role = ColoredLabelColumn() autonomous_system = tables.LinkColumn() @@ -102,11 +103,10 @@ class Meta(BaseTable.Meta): "name", "peergroup_template", "routing_instance", + "vrf", "enabled", "role", "autonomous_system", - "import_policy", - "export_policy", "source_ip", "source_interface", "secret", @@ -116,11 +116,10 @@ class Meta(BaseTable.Meta): "name", "peergroup_template", "routing_instance", + "vrf", "enabled", "role", "autonomous_system", - "import_policy", - "export_policy", "actions", ) @@ -144,8 +143,6 @@ class Meta(BaseTable.Meta): "enabled", "role", "autonomous_system", - "import_policy", - "export_policy", "secret", ) default_columns = ( @@ -154,8 +151,6 @@ class Meta(BaseTable.Meta): "enabled", "role", "autonomous_system", - "import_policy", - "export_policy", "secret", # "actions", ) @@ -194,8 +189,6 @@ class Meta(BaseTable.Meta): "peering", "vrf", "peer_group", - "import_policy", - "export_policy", ) default_columns = ( "pk", @@ -210,8 +203,6 @@ class Meta(BaseTable.Meta): "peering", "vrf", "peer_group", - "import_policy", - "export_policy", ) @@ -270,9 +261,6 @@ class Meta(BaseTable.Meta): "routing_instance", "afi_safi", "vrf", - "import_policy", - "export_policy", - "multipath", ) default_columns = ( "pk", @@ -280,6 +268,75 @@ class Meta(BaseTable.Meta): "routing_instance", "afi_safi", "vrf", + "actions", + ) + + +class PeerGroupAddressFamilyTable(BaseTable): + """Table representation of PeerGroupAddressFamily records.""" + + pk = ToggleColumn() + peer_group_address_family = tables.LinkColumn( + viewname="plugins:nautobot_bgp_models:peergroupaddressfamily", + args=[A("pk")], + text=str, + ) + peer_group = tables.LinkColumn() + afi_safi = tables.Column() + actions = ButtonsColumn(model=models.PeerGroupAddressFamily) + + class Meta(BaseTable.Meta): + model = models.PeerGroupAddressFamily + fields = ( + "pk", + "peer_group_address_family", + "peer_group", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + ) + default_columns = ( + "pk", + "peer_group_address_family", + "peer_group", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + "actions", + ) + + +class PeerEndpointAddressFamilyTable(BaseTable): + """Table representation of PeerEndpointAddressFamily records.""" + + pk = ToggleColumn() + peer_endpoint_address_family = tables.LinkColumn( + viewname="plugins:nautobot_bgp_models:peerendpointaddressfamily", + args=[A("pk")], + text=str, + ) + peer_endpoint = tables.LinkColumn() + afi_safi = tables.Column() + actions = ButtonsColumn(model=models.PeerEndpointAddressFamily) + + class Meta(BaseTable.Meta): + model = models.PeerEndpointAddressFamily + fields = ( + "pk", + "peer_endpoint_address_family", + "peer_endpoint", + "afi_safi", + "import_policy", + "export_policy", + "multipath", + ) + default_columns = ( + "pk", + "peer_endpoint_address_family", + "peer_endpoint", + "afi_safi", "import_policy", "export_policy", "multipath", diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily_retrieve.html b/nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily_retrieve.html index 9d697fb8..b4527b56 100644 --- a/nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily_retrieve.html +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/addressfamily_retrieve.html @@ -38,31 +38,12 @@ None {% endif %} - - Multipath - - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.multipath %} - - {% endblock content_left_page %} -{% block content_right_page %} -
-
Policy
- - - - - - - - - -
Import Policy - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.import_policy %} -
Export Policy - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.export_policy %} -
-
-{% endblock content_right_page %} + +{% block extra_nav_tabs %} +
+{% endblock extra_nav_tabs %} diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance_retrieve.html b/nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance_retrieve.html index 2acae33e..6822f62d 100644 --- a/nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance_retrieve.html +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/bgproutinginstance_retrieve.html @@ -34,6 +34,44 @@ {% endblock content_left_page %} +{% block content_right_page %} +
+
+ Address-Families +
+ + {% for af in object.address_families.all %} + + + + {% endfor %} +
{{ af.afi_safi }}
+ +
+
+
+ Peer Groups +
+ + {% for pg in object.peer_groups.all %} + + + + {% endfor %} +
{{ pg.name }}
+ +
+{% endblock content_right_page %} {% block extra_nav_tabs %} +{% endblock extra_nav_tabs %} diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup_retrieve.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup_retrieve.html index 0d1c5c9c..c24b9803 100644 --- a/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup_retrieve.html +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/peergroup_retrieve.html @@ -24,6 +24,14 @@ Routing Instance {{ object.routing_instance }} + + VRF + {% if object.vrf %} + {{ object.vrf }} + {% else %} + None + {% endif %} +
@@ -39,8 +47,6 @@
-{% endblock content_left_page %} -{% block content_right_page %}
Authentication @@ -74,40 +80,55 @@ Description - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.description %} + {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object.fields_inherited.description %} Enabled - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.enabled %} + {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object.fields_inherited.enabled %} Autonomous System - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.autonomous_system %} + {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object.fields_inherited.autonomous_system %}
+{% endblock content_left_page %} +{% block content_right_page %}
- Policy + Peer Group Address-Families
+ {% for af in object.address_families.all %} - - + + {% endfor %} +
Import Policy - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.import_policy %} - {{ af.afi_safi }}
+ +
+
+
+ Peerings In This Group +
+ + {% for endpoint in object.endpoints.all %} - - + + + + {% endfor %}
Export Policy - {% include "nautobot_bgp_models/inc/inheritable_property.html" with property=object_fields.export_policy %} - {{ endpoint }}peered to{{ endpoint.peer }}
{% endblock content_right_page %} diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peergroupaddressfamily_retrieve.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peergroupaddressfamily_retrieve.html new file mode 100644 index 00000000..04c6873f --- /dev/null +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/peergroupaddressfamily_retrieve.html @@ -0,0 +1,68 @@ +{% extends 'generic/object_detail.html' %} +{% load helpers %} + +{% block content_left_page %} +
+
+ BGP Peer-Group Address-Family +
+ + + + {% if object.peer_group.routing_instance and object.peer_group.routing_instance.device %} + + {% else %} + + {% endif %} + + + + + + + + + +
Device{{ object.peer_group.routing_instance.device }}None
Routing Instance{{ object.peer_group.routing_instance }}
Peer Group + + {{ object.peer_group }} + +
+
+
+
+ Attributes +
+ + + + + + + + + +
AFI-SAFI{{ object.afi_safi }}
Multipath{{ object.multipath | placeholder }}
+
+{% endblock content_left_page %} +{% block content_right_page %} +
+
Policy
+ + + + + + + + + +
Import Policy{{ object.import_policy | placeholder }}
Export Policy{{ object.export_policy | placeholder }}
+
+{% endblock content_right_page %} + +{% block extra_nav_tabs %} + +{% endblock extra_nav_tabs %} diff --git a/nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate_retrieve.html b/nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate_retrieve.html index ab85212a..4819ea59 100644 --- a/nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate_retrieve.html +++ b/nautobot_bgp_models/templates/nautobot_bgp_models/peergrouptemplate_retrieve.html @@ -52,27 +52,6 @@
{% endblock content_left_page %} -{% block content_right_page %} -
-
- Policy -
- - - - - - - - - -
Import Policy - {% include "nautobot_bgp_models/inc/native_property.html" with property=object.import_policy %} -
Export Policy - {% include "nautobot_bgp_models/inc/native_property.html" with property=object.export_policy %} -
-
-{% endblock content_right_page %} {% block extra_nav_tabs %}