From cad86363a25402103bd841b684fda08f7739e805 Mon Sep 17 00:00:00 2001 From: James Collier Date: Fri, 23 Jul 2021 16:40:24 +0200 Subject: [PATCH 1/2] Remove custom Result type and add returns library --- server/poetry.lock | 23 ++++- server/pyproject.toml | 1 + server/scopeserver/result.py | 194 ----------------------------------- server/test/test_result.py | 65 ------------ 4 files changed, 20 insertions(+), 263 deletions(-) delete mode 100644 server/scopeserver/result.py delete mode 100644 server/test/test_result.py diff --git a/server/poetry.lock b/server/poetry.lock index 90425a4fb..a4d8e8f2c 100644 --- a/server/poetry.lock +++ b/server/poetry.lock @@ -493,7 +493,7 @@ python-versions = ">=3.6.1" [[package]] name = "hypothesis" -version = "6.14.1" +version = "6.14.3" description = "A library for property-based testing" category = "dev" optional = false @@ -1173,6 +1173,17 @@ urllib3 = ">=1.21.1,<1.27" security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +[[package]] +name = "returns" +version = "0.16.0" +description = "Make your functions return something meaningful, typed, and safe!" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" + +[package.dependencies] +typing-extensions = ">=3.7,<4.0" + [[package]] name = "safety" version = "1.10.3" @@ -1499,7 +1510,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = ">=3.7,<3.10" -content-hash = "f54fba6f797071eebfb4c76b6784cae8f521aa423982f22a0d3cf6b316ecf823" +content-hash = "03182c7ea68e96b0405d8ad4cdc2cc2570678d9fb514b76cb73b93965be254db" [metadata.files] aiohttp = [ @@ -1905,8 +1916,8 @@ hyperframe = [ {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, ] hypothesis = [ - {file = "hypothesis-6.14.1-py3-none-any.whl", hash = "sha256:6dad44da8962cc7c13cdc28cf9b78c6779b5a0b0279a9baac427ae6d109f70e3"}, - {file = "hypothesis-6.14.1.tar.gz", hash = "sha256:88b0736a5691b68b8e16a4b7ee8e4c8596810c5a20989ea5b5f64870a7c25740"}, + {file = "hypothesis-6.14.3-py3-none-any.whl", hash = "sha256:6071ed0d25d90557f69e6a4d941b221f9b0beedde8ec8e4a136a40cad73d4886"}, + {file = "hypothesis-6.14.3.tar.gz", hash = "sha256:1c8776d9fc8c598cf1b93b99bd87976f9d9b589fc58843d85a30090700f14a8a"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, @@ -2570,6 +2581,10 @@ requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] +returns = [ + {file = "returns-0.16.0-py3-none-any.whl", hash = "sha256:3b7544f7b8c5aac8da3469b6ce34ed8878c993f0443d47f133cef2d38b08bc2a"}, + {file = "returns-0.16.0.tar.gz", hash = "sha256:ac717aaf1de89c87988c9c7cd57ce0bb06f726bd0f37c8915a53fa8ec8f800b7"}, +] safety = [ {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, diff --git a/server/pyproject.toml b/server/pyproject.toml index 42e3d99ce..5bd141a44 100644 --- a/server/pyproject.toml +++ b/server/pyproject.toml @@ -57,6 +57,7 @@ python-dotenv = "^0.18" python-multipart = "^0.0.5" h5py = ">=2.10,<3" scipy = "^1.6.3" +returns = "^0.16.0" [tool.poetry.dev-dependencies] pytest = "*" diff --git a/server/scopeserver/result.py b/server/scopeserver/result.py deleted file mode 100644 index c97f6decf..000000000 --- a/server/scopeserver/result.py +++ /dev/null @@ -1,194 +0,0 @@ -# -*- coding: utf-8 -*- -""" -A `Result` is used to indicate that a computation may fail -*with details* of the failure. This is closely realated to -`Optional` which is used to indicate the absence of a value. -A `Result` "wraps" one of **2** possibilities: - - `ok` - means the computation succeeded, or - `err` - means the computation failed. - -There are 3 ways to construct a Result: - 1. The `ok()` builder function to indicate success, - - 2. The `err()` builder function to indicate failure, - - 3. The `Result.from_optional()` method to build a result from an `Optional` - -When using a `Result` you do not have to perform explicit error checking. Instead -you should interact with a result using the provided methods. You should _never_ -access the wrapped values directly. -""" - -from __future__ import annotations -from typing import Generic, Optional, TypeVar, Callable - -# pylint: disable=invalid-name -T = TypeVar("T") -E = TypeVar("E") -U = TypeVar("U") -# pylint: enable=invalid-name - - -class Result(Generic[T, E]): - """ - The result of a computation that may fail. - This is a useful way to handle errors. - """ - - def __init__(self, value: Optional[T] = None, error: Optional[E] = None) -> None: - self._value: Optional[T] = value - self._error: Optional[E] = error - - def is_ok(self) -> bool: - """ - Check if the computation succeeded. - - >>> ok(1).is_ok() - True - - >>> err(1).is_ok() - False - """ - return self._value is not None - - def is_err(self) -> bool: - """ - Check if the computation failed. - - >>> err(1).is_err() - True - - >>> ok(1).is_err() - False - """ - return self._value is None - - def map(self, transform: Callable[[T], U]) -> Result[U, E]: - """ - Apply a function to a `Result`. If the result is `ok`, it will - be converted, otherwise the `err` will propogate. - - `map` gives you access to the value that `Result` wraps. If - it's `ok` then your function will operate on the value - "inside". Otherwise, your function does not execute. - - - >>> ok(10).map(lambda x: x * x).with_default(0) - 100 - - >>> err(-1).map(lambda x: x * x).with_default(0) - 0 - """ - if self._value is not None: - return Result(value=transform(self._value)) - - return Result(error=self._error) - - def and_then(self, transform: Callable[[T], Result[U, E]]) -> Result[U, E]: - """ - Compose, or chain together a sequence of computations that may fail. - If the result of a previous computation is `ok` then the value will - be passed to your function, otherwise the `err` will be propogated - and your function will not be executed. - - You can read this as "do this, *and then* do something else". The - number of "chained" functions is not limited. - - >>> ok(1).and_then(lambda x: ok(x * 2)).with_default(0) - 2 - - >>> ok(5).and_then(lambda x: ok(x + 25)).and_then(lambda x: ok(x // 2)).with_default(0) - 15 - - >>> err(1).and_then(lambda x: ok(x * 5)).with_default(0) - 0 - """ - if self._value is not None: - return transform(self._value) - - return Result(error=self._error) - - def or_else(self, transform: Callable[[E], Result[T, E]]) -> Result[T, E]: - """ - Gives you an alternative which is executed if an operation fails. - You can read it like, "do this, *or else*, do something else" or, - "do this and if it fails, do something else instead." - - >>> ok(9).or_else(lambda _: ok(6)).with_default(0) - 9 - - >>> err("something happened").or_else(lambda _: ok(6)).with_default(0) - 6 - """ - if self._error is not None: - return transform(self._error) - - return Result(value=self._value) - - def with_default(self, default: T) -> T: - """ - Extract a value. If `self` is `ok` the value is returned, - otherwise `default` is returned. - - If the result is a success (ok): - >>> ok(99).with_default(0) - 99 - - Otherwise, if the result is a failure, return the provided - default: - >>> err("failed").with_default(0) - 0 - """ - if self._value is not None: - return self._value - - return default - - def to_optional(self) -> Optional[T]: - """ - Convert to a simpler `Optional` if the `err` value is not needed. - If this `Result` is `ok`, `to_optional` unwraps the value, - otherwise returns `None`. - - >>> ok(10).to_optional() - 10 - - >>> err("wat!?").to_optional() == None - True - """ - if self._value is not None: - return self._value - - return None - - @staticmethod - def from_optional(value: Optional[T], error: E) -> Result[T, E]: - """ - Convert an `Optional` to a `Result`. If the `Optional` is `None` - returns `err(error)`, otherwise returns `ok(value)`. - - >>> Result.from_optional(5, "error").with_default(0) - 5 - - >>> Result.from_optional(None, "error").with_default(0) - 0 - """ - if value is None: - return Result(error=error) - - return Result(value=value) - - -# pylint: disable=invalid-name -def ok(val: T) -> Result[T, E]: - """Construct a successful `Result` containing `val`.""" - return Result(value=val) - - -# pylint: enable=invalid-name -def err(error: E) -> Result[T, E]: - """Construct a failing `Result` containing `error`.""" - return Result(error=error) diff --git a/server/test/test_result.py b/server/test/test_result.py deleted file mode 100644 index 00dffa476..000000000 --- a/server/test/test_result.py +++ /dev/null @@ -1,65 +0,0 @@ -import pytest - -from scopeserver.result import Result, ok, err - - -def test_ok(): - check = ok(1) - assert check.is_ok() == True - assert check.is_err() == False - - -def test_err(): - check = err("test") - assert check.is_err() == True - assert check.is_ok() == False - - -def test_from_optional_ok(): - check = Result.from_optional(1, "None").with_default(0) - assert check == 1 - - -def test_from_optional_err(): - check = Result.from_optional(None, "None").with_default(0) - assert check == 0 - - -def test_map_ok(): - check = ok(1).map(lambda x: x + 1).with_default(0) - assert check == 2 - - -def test_map_err(): - check = err(1).map(lambda x: x + 1).with_default(0) - assert check == 0 - - -def test_and_then_ok(): - check = ok(1).and_then(lambda x: ok(x + 1)).with_default(0) - assert check == 2 - - -def test_and_then_err(): - check = err(1).and_then(lambda x: ok(x + 1)).with_default(0) - assert check == 0 - - -def test_or_else_ok(): - check = ok(1).or_else(lambda x: ok("error")).with_default("no error") - assert check == 1 - - -def test_or_else_err(): - check = err("help").or_else(lambda x: ok("error")).with_default("no error") - assert check == "error" - - -def test_to_optional_ok(): - check = ok(1).to_optional() - assert check == 1 - - -def test_to_optional_err(): - check = err(1).to_optional() - assert check is None From b60b8bb3111ae04601aa7a7c02736008b4468100 Mon Sep 17 00:00:00 2001 From: James Collier Date: Mon, 26 Jul 2021 22:04:41 +0200 Subject: [PATCH 2/2] mark database functions as IO --- server/poetry.lock | 988 ++++++++++++++++++++------ server/pyproject.toml | 10 +- server/scopeserver/api/deps.py | 10 +- server/scopeserver/api/v1/projects.py | 35 +- server/scopeserver/api/v1/users.py | 3 +- server/scopeserver/crud.py | 52 +- 6 files changed, 831 insertions(+), 267 deletions(-) diff --git a/server/poetry.lock b/server/poetry.lock index a4d8e8f2c..34f69c7ab 100644 --- a/server/poetry.lock +++ b/server/poetry.lock @@ -55,9 +55,17 @@ pandas = "*" scikit-learn = "*" scipy = "*" +[[package]] +name = "astor" +version = "0.8.1" +description = "Read/rewrite/write Python ASTs" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + [[package]] name = "astroid" -version = "2.6.2" +version = "2.6.5" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false @@ -99,9 +107,24 @@ 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"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +[[package]] +name = "bandit" +version = "1.7.0" +description = "Security oriented static analyser for python code." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} +GitPython = ">=1.0.1" +PyYAML = ">=5.3.1" +six = ">=1.10.0" +stevedore = ">=1.20.0" + [[package]] name = "black" -version = "21.6b0" +version = "21.7b0" description = "The uncompromising code formatter." category = "dev" optional = false @@ -113,7 +136,7 @@ click = ">=7.1.2" mypy-extensions = ">=0.4.3" pathspec = ">=0.8.1,<1" regex = ">=2020.1.8" -toml = ">=0.10.1" +tomli = ">=0.2.6,<2.0.0" typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""} typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} @@ -165,6 +188,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "charset-normalizer" +version = "2.0.3" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + [[package]] name = "click" version = "8.0.1" @@ -247,9 +281,17 @@ toolz = ">=0.8.0" [package.extras] cython = ["cython"] +[[package]] +name = "darglint" +version = "1.8.0" +description = "A utility for ensuring Google-style docstrings stay up to date with the source code." +category = "main" +optional = false +python-versions = ">=3.6,<4.0" + [[package]] name = "dask" -version = "2021.6.2" +version = "2021.7.1" description = "Parallel PyData with Task Scheduling" category = "main" optional = false @@ -258,9 +300,10 @@ python-versions = ">=3.7" [package.dependencies] bokeh = {version = ">=1.0.0,<2.0.0 || >2.0.0", optional = true, markers = "extra == \"complete\""} cloudpickle = ">=1.1.1" -distributed = {version = "2021.06.2", optional = true, markers = "extra == \"complete\""} +distributed = {version = "2021.07.1", optional = true, markers = "extra == \"complete\""} fsspec = ">=0.6.0" numpy = {version = ">=1.16", optional = true, markers = "extra == \"complete\""} +packaging = ">=20.0" pandas = {version = ">=0.25.0", optional = true, markers = "extra == \"complete\""} partd = ">=0.3.10" pyyaml = "*" @@ -268,10 +311,10 @@ toolz = ">=0.8.2" [package.extras] array = ["numpy (>=1.16)"] -complete = ["bokeh (>=1.0.0,!=2.0.0)", "distributed (==2021.06.2)", "numpy (>=1.16)", "pandas (>=0.25.0)"] +complete = ["bokeh (>=1.0.0,!=2.0.0)", "distributed (==2021.07.1)", "numpy (>=1.16)", "pandas (>=0.25.0)"] dataframe = ["numpy (>=1.16)", "pandas (>=0.25.0)"] diagnostics = ["bokeh (>=1.0.0,!=2.0.0)"] -distributed = ["distributed (==2021.06.2)"] +distributed = ["distributed (==2021.07.1)"] test = ["pytest", "pytest-rerunfailures", "pytest-xdist"] [[package]] @@ -287,7 +330,7 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "distributed" -version = "2021.6.2" +version = "2021.7.1" description = "Distributed scheduler for Dask" category = "main" optional = false @@ -296,7 +339,7 @@ python-versions = ">=3.7" [package.dependencies] click = ">=6.6" cloudpickle = ">=1.5.0" -dask = "2021.06.2" +dask = "2021.07.1" msgpack = ">=0.6.0" psutil = ">=5.0" pyyaml = "*" @@ -309,6 +352,14 @@ tornado = [ ] zict = ">=0.1.3" +[[package]] +name = "docutils" +version = "0.17.1" +description = "Docutils -- Python Documentation Utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "dparse" version = "0.5.1" @@ -325,9 +376,17 @@ toml = "*" [package.extras] pipenv = ["pipenv"] +[[package]] +name = "eradicate" +version = "2.0.0" +description = "Removes commented-out code." +category = "main" +optional = false +python-versions = "*" + [[package]] name = "fastapi" -version = "0.66.0" +version = "0.66.1" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" category = "main" optional = false @@ -339,9 +398,186 @@ starlette = "0.14.2" [package.extras] all = ["requests (>=2.24.0,<3.0.0)", "aiofiles (>=0.5.0,<0.6.0)", "jinja2 (>=2.11.2,<3.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "itsdangerous (>=1.1.0,<2.0.0)", "pyyaml (>=5.3.1,<6.0.0)", "graphene (>=2.1.8,<3.0.0)", "ujson (>=4.0.1,<5.0.0)", "orjson (>=3.2.1,<4.0.0)", "email_validator (>=1.1.1,<2.0.0)", "uvicorn[standard] (>=0.12.0,<0.14.0)", "async_exit_stack (>=1.0.1,<2.0.0)", "async_generator (>=1.10,<2.0.0)"] -dev = ["python-jose[cryptography] (>=3.1.0,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "uvicorn[standard] (>=0.12.0,<0.14.0)", "graphene (>=2.1.8,<3.0.0)"] +dev = ["python-jose[cryptography] (>=3.3.0,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "uvicorn[standard] (>=0.12.0,<0.14.0)", "graphene (>=2.1.8,<3.0.0)"] doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=7.1.9,<8.0.0)", "markdown-include (>=0.6.0,<0.7.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.2.0)", "typer-cli (>=0.0.12,<0.0.13)", "pyyaml (>=5.3.1,<6.0.0)"] -test = ["pytest (==5.4.3)", "pytest-cov (==2.10.0)", "pytest-asyncio (>=0.14.0,<0.15.0)", "mypy (==0.812)", "flake8 (>=3.8.3,<4.0.0)", "black (==20.8b1)", "isort (>=5.0.6,<6.0.0)", "requests (>=2.24.0,<3.0.0)", "httpx (>=0.14.0,<0.15.0)", "email_validator (>=1.1.1,<2.0.0)", "sqlalchemy (>=1.3.18,<1.4.0)", "peewee (>=3.13.3,<4.0.0)", "databases[sqlite] (>=0.3.2,<0.4.0)", "orjson (>=3.2.1,<4.0.0)", "ujson (>=4.0.1,<5.0.0)", "async_exit_stack (>=1.0.1,<2.0.0)", "async_generator (>=1.10,<2.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "aiofiles (>=0.5.0,<0.6.0)", "flask (>=1.1.2,<2.0.0)"] +test = ["pytest (>=6.2.4,<7.0.0)", "pytest-cov (>=2.12.0,<3.0.0)", "pytest-asyncio (>=0.14.0,<0.15.0)", "mypy (==0.812)", "flake8 (>=3.8.3,<4.0.0)", "black (==20.8b1)", "isort (>=5.0.6,<6.0.0)", "requests (>=2.24.0,<3.0.0)", "httpx (>=0.14.0,<0.15.0)", "email_validator (>=1.1.1,<2.0.0)", "sqlalchemy (>=1.3.18,<1.4.0)", "peewee (>=3.13.3,<4.0.0)", "databases[sqlite] (>=0.3.2,<0.4.0)", "orjson (>=3.2.1,<4.0.0)", "ujson (>=4.0.1,<5.0.0)", "async_exit_stack (>=1.0.1,<2.0.0)", "async_generator (>=1.10,<2.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "aiofiles (>=0.5.0,<0.6.0)", "flask (>=1.1.2,<2.0.0)"] + +[[package]] +name = "flake8" +version = "3.9.2" +description = "the modular source code checker: pep8 pyflakes and co" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[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" + +[[package]] +name = "flake8-bandit" +version = "2.1.2" +description = "Automated security testing with bandit and flake8." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +bandit = "*" +flake8 = "*" +flake8-polyfill = "*" +pycodestyle = "*" + +[[package]] +name = "flake8-broken-line" +version = "0.3.0" +description = "Flake8 plugin to forbid backslashes for line breaks" +category = "main" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +flake8 = ">=3.5,<4.0" + +[[package]] +name = "flake8-bugbear" +version = "21.4.3" +description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +attrs = ">=19.2.0" +flake8 = ">=3.0.0" + +[package.extras] +dev = ["coverage", "black", "hypothesis", "hypothesmith"] + +[[package]] +name = "flake8-commas" +version = "2.0.0" +description = "Flake8 lint for trailing commas." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = ">=2,<4.0.0" + +[[package]] +name = "flake8-comprehensions" +version = "3.5.0" +description = "A flake8 plugin to help you write better list/set/dict comprehensions." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +flake8 = ">=3.0,<3.2.0 || >3.2.0,<4" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[[package]] +name = "flake8-debugger" +version = "4.0.0" +description = "ipdb/pdb statement checker plugin for flake8" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +flake8 = ">=3.0" +pycodestyle = "*" +six = "*" + +[[package]] +name = "flake8-docstrings" +version = "1.6.0" +description = "Extension for flake8 which uses pydocstyle to check docstrings" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = ">=3" +pydocstyle = ">=2.1" + +[[package]] +name = "flake8-eradicate" +version = "1.1.0" +description = "Flake8 plugin to find commented out code" +category = "main" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +attrs = "*" +eradicate = ">=2.0,<3.0" +flake8 = ">=3.5,<4.0" + +[[package]] +name = "flake8-isort" +version = "4.0.0" +description = "flake8 plugin that integrates isort ." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = ">=3.2.1,<4" +isort = ">=4.3.5,<6" +testfixtures = ">=6.8.0,<7" + +[package.extras] +test = ["pytest (>=4.0.2,<6)", "toml"] + +[[package]] +name = "flake8-polyfill" +version = "1.0.2" +description = "Polyfill package for Flake8 plugins" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "flake8-quotes" +version = "3.2.0" +description = "Flake8 lint for quotes." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "flake8-rst-docstrings" +version = "0.2.3" +description = "Python docstring reStructuredText (RST) validator" +category = "main" +optional = false +python-versions = ">=3.3" + +[package.dependencies] +flake8 = ">=3.0.0" +pygments = "*" +restructuredtext-lint = "*" + +[[package]] +name = "flake8-string-format" +version = "0.3.0" +description = "string format checker, plugin for flake8" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" [[package]] name = "frozendict" @@ -353,7 +589,7 @@ python-versions = ">=3.6" [[package]] name = "fsspec" -version = "2021.6.1" +version = "2021.7.0" description = "File-system specification" category = "main" optional = false @@ -376,6 +612,29 @@ sftp = ["paramiko"] smb = ["smbprotocol"] ssh = ["paramiko"] +[[package]] +name = "gitdb" +version = "4.0.7" +description = "Git Object Database" +category = "main" +optional = false +python-versions = ">=3.4" + +[package.dependencies] +smmap = ">=3.0.1,<5" + +[[package]] +name = "gitpython" +version = "3.1.19" +description = "Python Git Library" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +gitdb = ">=4.0.1,<5" +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} + [[package]] name = "greenlet" version = "1.1.0" @@ -389,7 +648,7 @@ docs = ["sphinx"] [[package]] name = "grpcio" -version = "1.38.1" +version = "1.39.0" description = "HTTP/2-based RPC framework" category = "main" optional = false @@ -399,18 +658,18 @@ python-versions = "*" six = ">=1.5.2" [package.extras] -protobuf = ["grpcio-tools (>=1.38.1)"] +protobuf = ["grpcio-tools (>=1.39.0)"] [[package]] name = "grpcio-tools" -version = "1.38.1" +version = "1.39.0" description = "Protobuf code generator for gRPC" category = "main" optional = false python-versions = "*" [package.dependencies] -grpcio = ">=1.38.1" +grpcio = ">=1.39.0" protobuf = ">=3.5.0.post1,<4.0dev" [[package]] @@ -493,7 +752,7 @@ python-versions = ">=3.6.1" [[package]] name = "hypothesis" -version = "6.14.3" +version = "6.14.4" description = "A library for property-based testing" category = "dev" optional = false @@ -522,11 +781,11 @@ zoneinfo = ["importlib-resources (>=3.3.0)", "backports.zoneinfo (>=0.2.1)", "tz [[package]] name = "idna" -version = "2.10" +version = "3.2" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.5" [[package]] name = "importlib-metadata" @@ -573,7 +832,7 @@ python-versions = "*" name = "isort" version = "5.9.2" description = "A Python utility / library to sort Python imports." -category = "dev" +category = "main" optional = false python-versions = ">=3.6.1,<4.0" @@ -696,7 +955,7 @@ python-dateutil = ">=2.7" name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -817,7 +1076,7 @@ numpy = ">=1.15" [[package]] name = "numpy" -version = "1.21.0" +version = "1.21.1" description = "NumPy is the fundamental package for array computing with Python." category = "main" optional = false @@ -875,11 +1134,30 @@ complete = ["numpy (>=1.9.0)", "pandas (>=0.19.0)", "pyzmq", "blosc"] [[package]] name = "pathspec" -version = "0.8.1" +version = "0.9.0" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" 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.*,>=2.7" + +[[package]] +name = "pbr" +version = "5.6.0" +description = "Python Build Reasonableness" +category = "main" +optional = false +python-versions = ">=2.6" + +[[package]] +name = "pep8-naming" +version = "0.11.1" +description = "Check PEP-8 naming conventions, plugin for flake8" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8-polyfill = ">=1.0.2,<2" [[package]] name = "pillow" @@ -953,6 +1231,14 @@ python-versions = "*" numpy = ">=1.14" six = ">=1.0.0" +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pydantic" version = "1.8.2" @@ -968,16 +1254,46 @@ typing-extensions = ">=3.7.4.3" dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] +[[package]] +name = "pydocstyle" +version = "6.1.1" +description = "Python docstring style checker" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +snowballstemmer = "*" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "pyflakes" +version = "2.3.1" +description = "passive checker of Python programs" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pygments" +version = "2.9.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "pylint" -version = "2.9.3" +version = "2.9.5" description = "python code static checker" category = "dev" optional = false python-versions = "~=3.6" [package.dependencies] -astroid = ">=2.6.2,<2.7" +astroid = ">=2.6.5,<2.7" colorama = {version = "*", markers = "sys_platform == \"win32\""} isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.7" @@ -1092,7 +1408,7 @@ testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtuale [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.8.2" description = "Extensions to the standard Python datetime module" category = "main" optional = false @@ -1157,21 +1473,32 @@ python-versions = "*" [[package]] name = "requests" -version = "2.25.1" +version = "2.26.0" description = "Python HTTP for Humans." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [package.dependencies] certifi = ">=2017.4.17" -chardet = ">=3.0.2,<5" -idna = ">=2.5,<3" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} urllib3 = ">=1.21.1,<1.27" [package.extras] -security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] + +[[package]] +name = "restructuredtext-lint" +version = "1.3.2" +description = "reStructuredText linter" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +docutils = ">=0.11,<1.0" [[package]] name = "returns" @@ -1252,6 +1579,22 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "smmap" +version = "4.0.0" +description = "A pure Python implementation of a sliding window memory map manager" +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "snowballstemmer" +version = "2.1.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "main" +optional = false +python-versions = "*" + [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1262,7 +1605,7 @@ python-versions = "*" [[package]] name = "sqlalchemy" -version = "1.4.20" +version = "1.4.22" description = "Database Abstraction Library" category = "main" optional = false @@ -1303,6 +1646,18 @@ python-versions = ">=3.6" [package.extras] full = ["aiofiles", "graphene", "itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests"] +[[package]] +name = "stevedore" +version = "3.3.0" +description = "Manage dynamic plugins for Python applications" +category = "main" +optional = false +python-versions = ">=3.6" + +[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 = "tblib" version = "1.7.0" @@ -1311,13 +1666,26 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "testfixtures" +version = "6.18.0" +description = "A collection of helpers and mock objects for unit tests and doc tests." +category = "main" +optional = false +python-versions = "*" + +[package.extras] +build = ["setuptools-git", "wheel", "twine"] +docs = ["sphinx", "zope.component", "sybil", "twisted", "mock", "django (<2)", "django"] +test = ["pytest (>=3.6)", "pytest-cov", "pytest-django", "zope.component", "sybil", "twisted", "mock", "django (<2)", "django"] + [[package]] name = "threadpoolctl" -version = "2.1.0" +version = "2.2.0" description = "threadpoolctl" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [[package]] name = "toml" @@ -1327,6 +1695,14 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "tomli" +version = "1.1.0" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "toolz" version = "0.11.1" @@ -1434,6 +1810,36 @@ brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[[package]] +name = "wemake-python-styleguide" +version = "0.15.3" +description = "The strictest and most opinionated python linter ever" +category = "main" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +astor = ">=0.8,<0.9" +attrs = "*" +darglint = ">=1.2,<2.0" +flake8 = ">=3.7,<4.0" +flake8-bandit = ">=2.1,<3.0" +flake8-broken-line = ">=0.3,<0.4" +flake8-bugbear = ">=20.1,<22.0" +flake8-commas = ">=2.0,<3.0" +flake8-comprehensions = ">=3.1,<4.0" +flake8-debugger = ">=4.0,<5.0" +flake8-docstrings = ">=1.3,<2.0" +flake8-eradicate = ">=1.0,<2.0" +flake8-isort = ">=4.0,<5.0" +flake8-quotes = ">=3.0,<4.0" +flake8-rst-docstrings = ">=0.2.3,<0.3.0" +flake8-string-format = ">=0.3,<0.4" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +pep8-naming = ">=0.11,<0.12" +pygments = ">=2.4,<3.0" +typing_extensions = ">=3.6,<4.0" + [[package]] name = "wirerope" version = "0.3.1" @@ -1510,7 +1916,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = ">=3.7,<3.10" -content-hash = "03182c7ea68e96b0405d8ad4cdc2cc2570678d9fb514b76cb73b93965be254db" +content-hash = "35c00dd426433c810013790be7a54d1beb0a3ae876544e3a6caaaa7c08cd5942" [metadata.files] aiohttp = [ @@ -1564,9 +1970,13 @@ arboreto = [ {file = "arboreto-0.1.6-py2.py3-none-any.whl", hash = "sha256:6c70074b9d7273efaed0f89dd508c886b83c22ef81ae07ca923b7d21e7bbd057"}, {file = "arboreto-0.1.6.tar.gz", hash = "sha256:32fdac5e8a3e0ef2e196b5827f067d815ac4e689d2fca0dc437f42abdeeb89ab"}, ] +astor = [ + {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, + {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, +] astroid = [ - {file = "astroid-2.6.2-py3-none-any.whl", hash = "sha256:606b2911d10c3dcf35e58d2ee5c97360e8477d7b9f3efc3f24811c93e6fc2cd9"}, - {file = "astroid-2.6.2.tar.gz", hash = "sha256:38b95085e9d92e2ca06cf8b35c12a74fa81da395a6f9e65803742e6509c05892"}, + {file = "astroid-2.6.5-py3-none-any.whl", hash = "sha256:7b963d1c590d490f60d2973e57437115978d3a2529843f160b5003b721e1e925"}, + {file = "astroid-2.6.5.tar.gz", hash = "sha256:83e494b02d75d07d4e347b27c066fd791c0c74fc96c613d1ea3de0c82c48168f"}, ] async-timeout = [ {file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"}, @@ -1580,9 +1990,13 @@ attrs = [ {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] +bandit = [ + {file = "bandit-1.7.0-py3-none-any.whl", hash = "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07"}, + {file = "bandit-1.7.0.tar.gz", hash = "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608"}, +] black = [ - {file = "black-21.6b0-py3-none-any.whl", hash = "sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7"}, - {file = "black-21.6b0.tar.gz", hash = "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04"}, + {file = "black-21.7b0-py3-none-any.whl", hash = "sha256:1c7aa6ada8ee864db745b22790a32f94b2795c253a75d6d9b5e439ff10d23116"}, + {file = "black-21.7b0.tar.gz", hash = "sha256:c8373c6491de9362e39271630b65b964607bc5c79c83783547d76c839b3aa219"}, ] bokeh = [ {file = "bokeh-2.3.3.tar.gz", hash = "sha256:a5fdcc181835561447fcc5a371300973fce4114692d5853addec284d1cdeb677"}, @@ -1599,6 +2013,10 @@ chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] +charset-normalizer = [ + {file = "charset-normalizer-2.0.3.tar.gz", hash = "sha256:c46c3ace2d744cfbdebceaa3c19ae691f53ae621b39fd7570f59d14fb7f2fd12"}, + {file = "charset_normalizer-2.0.3-py3-none-any.whl", hash = "sha256:88fce3fa5b1a84fdcb3f603d889f723d1dd89b26059d0123ca435570e848d5e1"}, +] click = [ {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, @@ -1675,33 +2093,106 @@ cycler = [ cytoolz = [ {file = "cytoolz-0.11.0.tar.gz", hash = "sha256:c64f3590c3eb40e1548f0d3c6b2ccde70493d0b8dc6cc7f9f3fec0bb3dcd4222"}, ] +darglint = [ + {file = "darglint-1.8.0-py3-none-any.whl", hash = "sha256:ac6797bcc918cd8d8f14c168a4a364f54e1aeb4ced59db58e7e4c6dfec2fe15c"}, + {file = "darglint-1.8.0.tar.gz", hash = "sha256:aa605ef47817a6d14797d32b390466edab621768ea4ca5cc0f3c54f6d8dcaec8"}, +] dask = [ - {file = "dask-2021.6.2-py3-none-any.whl", hash = "sha256:1f18d0815154b938a529ac3081c8952998d709319e57bbc484b42f0094217d43"}, - {file = "dask-2021.6.2.tar.gz", hash = "sha256:8588fcd1a42224b7cfcd2ebc8ad616734abb6b1a4517efd52d89c7dd66eb91f8"}, + {file = "dask-2021.7.1-py3-none-any.whl", hash = "sha256:b56572363cfda0e57771ef39c84cbd8103e0dea5c6fcbbd7a2224240bb3a0bd9"}, + {file = "dask-2021.7.1.tar.gz", hash = "sha256:e72f8773a14e2909a2105e628d981083859915373281fec8e5a78d14ee0a2c8c"}, ] dill = [ {file = "dill-0.3.4-py2.py3-none-any.whl", hash = "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f"}, {file = "dill-0.3.4.zip", hash = "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"}, ] distributed = [ - {file = "distributed-2021.6.2-py3-none-any.whl", hash = "sha256:68251734ec68254280d855db5a77cead2712df2580ec9d44fde14321e7f3806c"}, - {file = "distributed-2021.6.2.tar.gz", hash = "sha256:d7d112a86ab049dcefa3b21fd1baea4212a2c03d22c24bd55ad38d21a7f5d148"}, + {file = "distributed-2021.7.1-py3-none-any.whl", hash = "sha256:0b979c350315bdc85d75a17787b29b869ff88992f2573d503f3e28b256faae50"}, + {file = "distributed-2021.7.1.tar.gz", hash = "sha256:3a41ff1a1674d4ff0944dfdd8024e168ff451bcd72474d3f4d61d8a4ba019a78"}, +] +docutils = [ + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, ] dparse = [ {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, ] +eradicate = [ + {file = "eradicate-2.0.0.tar.gz", hash = "sha256:27434596f2c5314cc9b31410c93d8f7e8885747399773cd088d3adea647a60c8"}, +] fastapi = [ - {file = "fastapi-0.66.0-py3-none-any.whl", hash = "sha256:85d8aee8c3c46171f4cb7bb3651425a42c07cb9183345d100ef55d88ca2ce15f"}, - {file = "fastapi-0.66.0.tar.gz", hash = "sha256:6ea4225448786f3d6fae737713789f87631a7455f65580de0a4a2e50471060d9"}, + {file = "fastapi-0.66.1-py3-none-any.whl", hash = "sha256:958ed7341f97292e2fc3e6401830bbe203a917af93cd10bb6392be170ad3c15f"}, + {file = "fastapi-0.66.1.tar.gz", hash = "sha256:1ac66c0635301bbd99785fb825300064d54adb774e8a5562661901de14ce6560"}, +] +flake8 = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] +flake8-bandit = [ + {file = "flake8_bandit-2.1.2.tar.gz", hash = "sha256:687fc8da2e4a239b206af2e54a90093572a60d0954f3054e23690739b0b0de3b"}, +] +flake8-broken-line = [ + {file = "flake8-broken-line-0.3.0.tar.gz", hash = "sha256:f74e052833324a9e5f0055032f7ccc54b23faabafe5a26241c2f977e70b10b50"}, + {file = "flake8_broken_line-0.3.0-py3-none-any.whl", hash = "sha256:611f79c7f27118e7e5d3dc098ef7681c40aeadf23783700c5dbee840d2baf3af"}, +] +flake8-bugbear = [ + {file = "flake8-bugbear-21.4.3.tar.gz", hash = "sha256:2346c81f889955b39e4a368eb7d508de723d9de05716c287dc860a4073dc57e7"}, + {file = "flake8_bugbear-21.4.3-py36.py37.py38-none-any.whl", hash = "sha256:4f305dca96be62bf732a218fe6f1825472a621d3452c5b994d8f89dae21dbafa"}, +] +flake8-commas = [ + {file = "flake8-commas-2.0.0.tar.gz", hash = "sha256:d3005899466f51380387df7151fb59afec666a0f4f4a2c6a8995b975de0f44b7"}, + {file = "flake8_commas-2.0.0-py2.py3-none-any.whl", hash = "sha256:ee2141a3495ef9789a3894ed8802d03eff1eaaf98ce6d8653a7c573ef101935e"}, +] +flake8-comprehensions = [ + {file = "flake8-comprehensions-3.5.0.tar.gz", hash = "sha256:f24be9032587127f7a5bc6d066bf755b6e66834f694383adb8a673e229c1f559"}, + {file = "flake8_comprehensions-3.5.0-py3-none-any.whl", hash = "sha256:b07aef3277623db32310aa241a1cec67212b53c1d18e767d7e26d4d83aa05bf7"}, +] +flake8-debugger = [ + {file = "flake8-debugger-4.0.0.tar.gz", hash = "sha256:e43dc777f7db1481db473210101ec2df2bd39a45b149d7218a618e954177eda6"}, + {file = "flake8_debugger-4.0.0-py3-none-any.whl", hash = "sha256:82e64faa72e18d1bdd0000407502ebb8ecffa7bc027c62b9d4110ce27c091032"}, +] +flake8-docstrings = [ + {file = "flake8-docstrings-1.6.0.tar.gz", hash = "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b"}, + {file = "flake8_docstrings-1.6.0-py2.py3-none-any.whl", hash = "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde"}, +] +flake8-eradicate = [ + {file = "flake8-eradicate-1.1.0.tar.gz", hash = "sha256:f5917d6dbca352efcd10c15fdab9c55c48f0f26f6a8d47898b25d39101f170a8"}, + {file = "flake8_eradicate-1.1.0-py3-none-any.whl", hash = "sha256:d8e39b684a37c257a53cda817d86e2d96c9ba3450ddc292742623a5dfee04d9e"}, +] +flake8-isort = [ + {file = "flake8-isort-4.0.0.tar.gz", hash = "sha256:2b91300f4f1926b396c2c90185844eb1a3d5ec39ea6138832d119da0a208f4d9"}, + {file = "flake8_isort-4.0.0-py2.py3-none-any.whl", hash = "sha256:729cd6ef9ba3659512dee337687c05d79c78e1215fdf921ed67e5fe46cce2f3c"}, +] +flake8-polyfill = [ + {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, + {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, +] +flake8-quotes = [ + {file = "flake8-quotes-3.2.0.tar.gz", hash = "sha256:3f1116e985ef437c130431ac92f9b3155f8f652fda7405ac22ffdfd7a9d1055e"}, +] +flake8-rst-docstrings = [ + {file = "flake8-rst-docstrings-0.2.3.tar.gz", hash = "sha256:3045794e1c8467fba33aaea5c246b8369efc9c44ef8b0b20199bb6df7a4bd47b"}, + {file = "flake8_rst_docstrings-0.2.3-py3-none-any.whl", hash = "sha256:565bbb391d7e4d0042924102221e9857ad72929cdd305b26501736ec22c1451a"}, +] +flake8-string-format = [ + {file = "flake8-string-format-0.3.0.tar.gz", hash = "sha256:65f3da786a1461ef77fca3780b314edb2853c377f2e35069723348c8917deaa2"}, + {file = "flake8_string_format-0.3.0-py2.py3-none-any.whl", hash = "sha256:812ff431f10576a74c89be4e85b8e075a705be39bc40c4b4278b5b13e2afa9af"}, ] frozendict = [ {file = "frozendict-2.0.3-py3-none-any.whl", hash = "sha256:58143e2d3d11699bc295d9e7e05f10dde99a727e2295d7f43542ecdc42c5ec70"}, {file = "frozendict-2.0.3.tar.gz", hash = "sha256:163c616188beb97fdc8ef6e73ec2ebd70a844d4cf19d2e383aa94d1b8376653d"}, ] fsspec = [ - {file = "fsspec-2021.6.1-py3-none-any.whl", hash = "sha256:0ca23992f425c1ba61bf11d3cb3af8ad5363be8612e26732b520090556f173f2"}, - {file = "fsspec-2021.6.1.tar.gz", hash = "sha256:2cdaafb51dd71e062afffcabcbc4925acef95f9bdd8d822d2010e4bf92951bd7"}, + {file = "fsspec-2021.7.0-py3-none-any.whl", hash = "sha256:86822ccf367da99957f49db64f7d5fd3d8d21444fac4dfdc8ebc38ee93d478c6"}, + {file = "fsspec-2021.7.0.tar.gz", hash = "sha256:792ebd3b54de0b30f1ce73f0ba0a8bcc864724f2d9f248cb8d0ece47db0cbde8"}, +] +gitdb = [ + {file = "gitdb-4.0.7-py3-none-any.whl", hash = "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0"}, + {file = "gitdb-4.0.7.tar.gz", hash = "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005"}, +] +gitpython = [ + {file = "GitPython-3.1.19-py3-none-any.whl", hash = "sha256:17690588e36bd0cee21921ce621fad1e8be45a37afa486ff846fb8efcf53c34c"}, + {file = "GitPython-3.1.19.tar.gz", hash = "sha256:18f4039b96b5567bc4745eb851737ce456a2d499cecd71e84f5c0950e92d0e53"}, ] greenlet = [ {file = "greenlet-1.1.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:60848099b76467ef09b62b0f4512e7e6f0a2c977357a036de602b653667f5f4c"}, @@ -1755,110 +2246,110 @@ greenlet = [ {file = "greenlet-1.1.0.tar.gz", hash = "sha256:c87df8ae3f01ffb4483c796fe1b15232ce2b219f0b18126948616224d3f658ee"}, ] grpcio = [ - {file = "grpcio-1.38.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:118479436bda25b369e2dc1cd0921790fbfaea1ec663e4ee7095c4c325694495"}, - {file = "grpcio-1.38.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:7adfbd4e22647f880c9ed86b2be7f6d7a7dbbb8adc09395808cc7a4d021bc328"}, - {file = "grpcio-1.38.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:87b4b1977b52d5e0873a5e396340d2443640ba760f4fa23e93a38997ecfbcd5b"}, - {file = "grpcio-1.38.1-cp27-cp27m-win32.whl", hash = "sha256:3a25e1a46f51c80d06b66223f61938b9ffda37f2824ca65749c49b758137fac2"}, - {file = "grpcio-1.38.1-cp27-cp27m-win_amd64.whl", hash = "sha256:b5ea9902fc2990af993b74862282b49ae0b8de8a64ca3b4a8dda26a3163c3bb4"}, - {file = "grpcio-1.38.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:8ccde1df51eeaddf5515edc41bde2ea43a834a288914eae9ce4287399be108f5"}, - {file = "grpcio-1.38.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:0e193feaf4ebc72f6af57d7b8a08c0b8e43ebbd76f81c6f1e55d013557602dfd"}, - {file = "grpcio-1.38.1-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:b16e1967709392a0ec4b10b4374a72eb062c47c168a189606c9a7ea7b36593a8"}, - {file = "grpcio-1.38.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:4bc60f8372c3ab06f41279163c5d558bf95195bb3f68e35ed19f95d4fbd53d71"}, - {file = "grpcio-1.38.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a433d3740a9ef7bc34a18e2b12bf72b25e618facdfd09871167b30fd8e955fed"}, - {file = "grpcio-1.38.1-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:d49f250c3ffbe83ba2d03e3500e03505576a985f7c5f77172a9531058347aa68"}, - {file = "grpcio-1.38.1-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:6e137d014cf4162e5a796777012452516d92547717c1b4914fb71ce4e41817b5"}, - {file = "grpcio-1.38.1-cp35-cp35m-win32.whl", hash = "sha256:5ff4802d9b3704e680454289587e1cc146bb0d953cf3c9296e2d96441a6a8e88"}, - {file = "grpcio-1.38.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4c19578b35715e110c324b27c18ab54a56fccc4c41b8f651b1d1da5a64e0d605"}, - {file = "grpcio-1.38.1-cp36-cp36m-linux_armv7l.whl", hash = "sha256:6edf68d4305e08f6f8c45bfaa9dc04d527ab5a1562aaf0c452fa921fbe90eb23"}, - {file = "grpcio-1.38.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:ddd33c90b0c95eca737c9f6db7e969a48d23aed72cecb23f3b8aac009ca2cfb4"}, - {file = "grpcio-1.38.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c83481501533824fe341c17d297bbec1ec584ec46b352f98ce12bf16740615c4"}, - {file = "grpcio-1.38.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e85bba6f0e0c454a90b8fea16b59db9c6d19ddf9cc95052b2d4ca77b22d46d6"}, - {file = "grpcio-1.38.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:dcfcb147c18272a22a592251a49830b3c7abc82385ffff34916c2534175d885e"}, - {file = "grpcio-1.38.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:419af4f577a3d5d9f386aeacf4c4992f90016f84cbceb11ecd832101b1f7f9c9"}, - {file = "grpcio-1.38.1-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:cd7ddb5b6ffcbd3691990df20f260a888c8bd770d57480a97da1b756fb1be5c0"}, - {file = "grpcio-1.38.1-cp36-cp36m-win32.whl", hash = "sha256:d4179d96b0ce27602756185c1a00d088c9c1feb0cc17a36f8a66eec6ddddbc0c"}, - {file = "grpcio-1.38.1-cp36-cp36m-win_amd64.whl", hash = "sha256:96d78d9edf3070770cefd1822bc220d8cccad049b818a70a3c630052e9f15490"}, - {file = "grpcio-1.38.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:8ab27a6626c2038e13c1b250c5cd22da578f182364134620ec298b4ccfc85722"}, - {file = "grpcio-1.38.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:532ab738351aad2cdad80f4355123652e08b207281f3923ce51fb2b58692dd4c"}, - {file = "grpcio-1.38.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:e4a8a371ad02bf31576bcd99093cea3849e19ca1e9eb63fc0b2c0f1db1132f7d"}, - {file = "grpcio-1.38.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89af675d38bf490384dae85151768b8434e997cece98e5d1eb6fcb3c16d6af12"}, - {file = "grpcio-1.38.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:ff9ebc416e815161d89d2fd22d1a91acf3b810ef800dae38c402d19d203590bf"}, - {file = "grpcio-1.38.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:3db0680fee9e55022677abda186e73e3c019c59ed83e1550519250dc97cf6793"}, - {file = "grpcio-1.38.1-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:a77d1f47e5e82504c531bc9dd22c093ff093b6706ec8bcdad228464ef3a5dd54"}, - {file = "grpcio-1.38.1-cp37-cp37m-win32.whl", hash = "sha256:549beb5646137b78534a312a3b80b2b8b1ea01058b38a711d42d6b54b20b6c2b"}, - {file = "grpcio-1.38.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3eb960c2f9e031f0643b53bab67733a9544d82f42d0714338183d14993d2a23c"}, - {file = "grpcio-1.38.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:e90cda2ccd4bdb89a3cd5dc11771c3b8394817d5caaa1ae36042bc96a428c10e"}, - {file = "grpcio-1.38.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:26af85ae0a7ff8e8f8f550255bf85551df86a89883c11721c0756b71bc1019be"}, - {file = "grpcio-1.38.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:947bdba3ebcd93a7cef537d6405bc5667d1caf818fa8bbd2e2cc952ec8f97e09"}, - {file = "grpcio-1.38.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:6d898441ada374f76e0b5354d7e240e1c0e905a1ebcb1e95d9ffd99c88f63700"}, - {file = "grpcio-1.38.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:59f5fb4ba219a11fdc1c23e17c93ca3090480a8cde4370c980908546ffc091e6"}, - {file = "grpcio-1.38.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:cddd61bff66e42ef334f8cb9e719951e479b5ad2cb75c00338aac8de28e17484"}, - {file = "grpcio-1.38.1-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:c323265a4f18f586e8de84fda12b48eb3bd48395294aa2b8c05307ac1680299d"}, - {file = "grpcio-1.38.1-cp38-cp38-win32.whl", hash = "sha256:72e8358c751da9ab4f8653a3b67b2a3bb7e330ee57cb26439c6af358d6eac032"}, - {file = "grpcio-1.38.1-cp38-cp38-win_amd64.whl", hash = "sha256:278e131bfbc57bab112359b98930b0fdbf81aa0ba2cdfc6555c7a5119d7e2117"}, - {file = "grpcio-1.38.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:44efa41ac36f6bcbf4f64d6479b3031cceea28cf6892a77f15bd1c22611bff9d"}, - {file = "grpcio-1.38.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:cf6c3bfa403e055380fe90844beb4fe8e9448edab5d2bf40d37d208dbb2f768c"}, - {file = "grpcio-1.38.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:5efa68fc3fe0c439e2858215f2224bfb7242c35079538d58063f68a0d5d5ec33"}, - {file = "grpcio-1.38.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:2a179b2565fa85a134933acc7845f9d4c12e742c802b4f50bf2fd208bf8b741e"}, - {file = "grpcio-1.38.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:b1624123710fa701988a8a43994de78416e5010ac1508f64ed41e2577358604a"}, - {file = "grpcio-1.38.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:6a225440015db88ec4625a2a41c21582a50cce7ffbe38dcbbb416c7180352516"}, - {file = "grpcio-1.38.1-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:e891b0936aab73550d673dd3bbf89fa9577b3db1a61baecea480afd36fdb1852"}, - {file = "grpcio-1.38.1-cp39-cp39-win32.whl", hash = "sha256:889518ce7c2a0609a3cffb7b667669a39b3410e869ff38e087bf7eeadad62e5d"}, - {file = "grpcio-1.38.1-cp39-cp39-win_amd64.whl", hash = "sha256:77054f24d46498d9696c809da7810b67bccf6153f9848ea48331708841926d82"}, - {file = "grpcio-1.38.1.tar.gz", hash = "sha256:1f79d8a24261e3c12ec3a6c25945ff799ae09874fd24815bc17c2dc37715ef6c"}, + {file = "grpcio-1.39.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:4163e022f365406be2da78db890035463371effea172300ce5af8a768142baf3"}, + {file = "grpcio-1.39.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:02e8a8b41db8e13df53078355b439363e4ac46d0ac9a8a461a39e42829e2bcf8"}, + {file = "grpcio-1.39.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:050901a5baa6c4ca445e1781ef4c32d864f965ccec70c46cd5ad92d15e282c6a"}, + {file = "grpcio-1.39.0-cp27-cp27m-win32.whl", hash = "sha256:1ab44dde4e1b225d3fc873535ca6e642444433131dd2891a601b75fb46c87c11"}, + {file = "grpcio-1.39.0-cp27-cp27m-win_amd64.whl", hash = "sha256:25731b2c20a4ed51bea7e3952d5e83d408a5df32d03c7553457b2e6eb8bcb16c"}, + {file = "grpcio-1.39.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:a2733994b05ee5382da1d0378f6312b72c5cb202930c7fa20c794a24e96a1a34"}, + {file = "grpcio-1.39.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4039645b8b5d19064766f3a6fa535f1db52a61c4d4de97a6a8945331a354d527"}, + {file = "grpcio-1.39.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:7b95b3329446408e2fe6db9b310d263303fa1a94649d08ec1e1cc12506743d26"}, + {file = "grpcio-1.39.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:2a4308875b9b986000513c6b04c2e7424f436a127f15547036c42d3cf8289374"}, + {file = "grpcio-1.39.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4b3fcc1878a1a5b71e1ecdfe82c74f7cd9eadaa43e25be0d67676dcec0c9d39f"}, + {file = "grpcio-1.39.0-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:6d51be522b573cec14798d4742efaa69d234bedabce122fec2d5489abb3724d4"}, + {file = "grpcio-1.39.0-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:43c57987e526d1b893b85099424387b22de6e3eee4ea7188443de8d657d11cc0"}, + {file = "grpcio-1.39.0-cp35-cp35m-win32.whl", hash = "sha256:cd2e39a199bcbefb3f4b9fa6677c72b0e67332915550fed3bd7c28b454bf917d"}, + {file = "grpcio-1.39.0-cp35-cp35m-win_amd64.whl", hash = "sha256:5628e7cc69079159f9465388ff21fde1e1a780139f76dd99d319119d45156f45"}, + {file = "grpcio-1.39.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:3c14e2087f809973d5ee8ca64f772a089ead0167286f3f21fdda8b6029b50abb"}, + {file = "grpcio-1.39.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:d5a105f5a595b89a0e394e5b147430b115333d07c55efb0c0eddc96055f0d951"}, + {file = "grpcio-1.39.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:366b6b35b3719c5570588e21d866460c5666ae74e3509c2a5a73ca79997abdaf"}, + {file = "grpcio-1.39.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:544e1c1a133b43893e03e828c8325be5b82e20d3b0ef0ee3942d32553052a1b5"}, + {file = "grpcio-1.39.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:a659f7c634cacfcf14657687a9fa3265b0a1844b1c19d140f3b66aebfba1a66b"}, + {file = "grpcio-1.39.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:b0ff14dd872030e6b2fce8a6811642bd30d93833f794d3782c7e9eb2f01234cc"}, + {file = "grpcio-1.39.0-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:2a958ad794292e12d8738a06754ebaf71662e635a89098916c18715b27ca2b5b"}, + {file = "grpcio-1.39.0-cp36-cp36m-win32.whl", hash = "sha256:ed845ba6253c4032d5a01b7fb9db8fe80299e9a437e695a698751b0b191174be"}, + {file = "grpcio-1.39.0-cp36-cp36m-win_amd64.whl", hash = "sha256:b236eb4b50d83754184b248b8b1041bb1546287fff7618c4b7001b9f257bb903"}, + {file = "grpcio-1.39.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:27e2c6213fc04e71a862bacccb51f3c8e722255933f01736ace183e92d860ee6"}, + {file = "grpcio-1.39.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5127f4ba1f52fda28037ae465cf4b0e5fabe89d5ac1d64d15b073b46b7db5e16"}, + {file = "grpcio-1.39.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:a6211150765cc2343e69879dfb856718b0f7477a4618b5f9a8f6c3ee84c047c0"}, + {file = "grpcio-1.39.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:691f5b3a75f072dfb7b093f46303f493b885b7a42f25a831868ffaa22ee85f9d"}, + {file = "grpcio-1.39.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:c8fe430add656b92419f6cd0680b64fbe6347c831d89a7788324f5037dfb3359"}, + {file = "grpcio-1.39.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:3cccf470fcaab65a1b0a826ff34bd7c0861eb82ed957a83c6647a983459e4ecd"}, + {file = "grpcio-1.39.0-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:2bc7eebb405aac2d7eecfaa881fd73b489f99c01470d7193b4431a6ce199b9c3"}, + {file = "grpcio-1.39.0-cp37-cp37m-win32.whl", hash = "sha256:52100d800390d58492ed1093de6faccd957de6fc29b1a0e5948c84f275d9228f"}, + {file = "grpcio-1.39.0-cp37-cp37m-win_amd64.whl", hash = "sha256:20f57c5d09a36e0d0c8fe16ee1905f4307edb1d04f6034b56320f7fbc1a1071a"}, + {file = "grpcio-1.39.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:6ba6ad60009da2258cf15a72c51b7e0c2f58c8da517e97550881e488839e56c6"}, + {file = "grpcio-1.39.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a1fb9936b86b5efdea417fe159934bcad82a6f8c6ab7d1beec4bf3a78324d975"}, + {file = "grpcio-1.39.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:46cfb0f2b757673bfd36ab4b0e3d61988cc1a0d47e0597e91462dcbef7528f35"}, + {file = "grpcio-1.39.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:f2621c82fbbff1496993aa5fbf60e235583c7f970506e818671ad52000b6f310"}, + {file = "grpcio-1.39.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:e98aca5cfe05ca29950b3d99006b9ddb54fde6451cd12cb2db1443ae3b9fa076"}, + {file = "grpcio-1.39.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:8ed1e52ad507a54d20e6aaedf4b3edcab18cc12031eafe6de898f97513d8997b"}, + {file = "grpcio-1.39.0-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:3c57fa7fec932767bc553bfb956759f45026890255bd232b2f797c3bc4dfeba2"}, + {file = "grpcio-1.39.0-cp38-cp38-win32.whl", hash = "sha256:88dbef504b491b96e3238a6d5360b04508c34c62286080060c85fddd3caf7137"}, + {file = "grpcio-1.39.0-cp38-cp38-win_amd64.whl", hash = "sha256:cffdccc94e63710dd6ead01849443390632c8e0fec52dc26e4fddf9f28ac9280"}, + {file = "grpcio-1.39.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:43e0f5c49f985c94332794aa6c4f15f3a1ced336f0c6a6c8946c67b5ab111ae9"}, + {file = "grpcio-1.39.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:dc3a24022a90c1754e54315009da6f949b48862c1d06daa54f9a28f89a5efacb"}, + {file = "grpcio-1.39.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:476fa94ba8efb09213baabd757f6f93e839794d8ae0eaa371347d6899e8f57a0"}, + {file = "grpcio-1.39.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:46d510a7af777d2f38ef4c1d25491add37cad24143012f3eebe72dc5c6d0fc4c"}, + {file = "grpcio-1.39.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:5091b4a5ee8454a8f0c8ac45946ca25d6142c3be4b1fba141f1d62a6e0b5c696"}, + {file = "grpcio-1.39.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:de83a045005703e7b9e67b61c38bb72cd49f68d9d2780d2c675353a3a3f2816f"}, + {file = "grpcio-1.39.0-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:4258b778ce09ffa3b7c9a26971c216a34369e786771afbf4f98afe223f27d248"}, + {file = "grpcio-1.39.0-cp39-cp39-win32.whl", hash = "sha256:c44958a24559f875d902d5c1acb0ae43faa5a84f6120d1d0d800acb52f96516e"}, + {file = "grpcio-1.39.0-cp39-cp39-win_amd64.whl", hash = "sha256:2068a2b896ac67103c4a5453d5435fafcbb1a2f41eaf25148d08780096935cee"}, + {file = "grpcio-1.39.0.tar.gz", hash = "sha256:57974361a459d6fe04c9ae0af1845974606612249f467bbd2062d963cb90f407"}, ] grpcio-tools = [ - {file = "grpcio-tools-1.38.1.tar.gz", hash = "sha256:cd85f58038b92e1961f8127d79691e84e151390d35cae73c4c0cbe2042f76b77"}, - {file = "grpcio_tools-1.38.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:913f3dc262f28e2220bbb69aab4174c0a8b0fc94e7dec3a47c158bc2cc4fcdc7"}, - {file = "grpcio_tools-1.38.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:3e5a1485a4c18e1a35aae704682b2faac57f4f2122a8eaca576fd74f52e32cc0"}, - {file = "grpcio_tools-1.38.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:0df193c2ccdc93d343e5c789198f2c9196dcb2375538728c03cbf5b57f0d257a"}, - {file = "grpcio_tools-1.38.1-cp27-cp27m-win32.whl", hash = "sha256:72775c21fa5ff7e73a9ed9a26d32969ee5faf31e56ff8107b99c9d7914ea895f"}, - {file = "grpcio_tools-1.38.1-cp27-cp27m-win_amd64.whl", hash = "sha256:cf150b9b56ada5d78ad47e9d4c58da688788a9edfedd6b7586369311d40d6d51"}, - {file = "grpcio_tools-1.38.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:4ae9fb7d86f01915e0f640226a8eeb4063e2d1604e172596d52a06ac96c8fb11"}, - {file = "grpcio_tools-1.38.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:fa714aa29991328a4d51d1efd73ebd15f15b41ed0a84dd19af1654076b6f5ed2"}, - {file = "grpcio_tools-1.38.1-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:6c4e385f41d9c3e4a8f59af1b9c2b1d3d16840cc615f1f7f301012b3a7b53cab"}, - {file = "grpcio_tools-1.38.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:31c5ad318a47aefa451dd00cbbf3d0fba693df21d6382a52b8c3b7c67b0316af"}, - {file = "grpcio_tools-1.38.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:21efa933597d6c6133f5dd77dbfdb9c4bdb6b8c5d599c47ec96de264abf74157"}, - {file = "grpcio_tools-1.38.1-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:e2e97564aec7dded3a864f740ec5121ce7c574d2d1585d0fab1be8ab856ce312"}, - {file = "grpcio_tools-1.38.1-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:eebc25185c109dd584f3ab09146f8471dcbbdee23a6330753b30e732cf374fa1"}, - {file = "grpcio_tools-1.38.1-cp35-cp35m-win32.whl", hash = "sha256:728a9a96fcfdd32309ccc584664f3935c482951cc9340316235ec000683af1fa"}, - {file = "grpcio_tools-1.38.1-cp35-cp35m-win_amd64.whl", hash = "sha256:5b31142da2c74c02159eed352e39fe2d6b6ca8a6a25c53cb7efacb53d08055b2"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-linux_armv7l.whl", hash = "sha256:0ed1238044d908fe461e63a97c846a2420ec15103ed7bf8aa76372614e7216de"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:36a081086dc3646584cff59fb5675cded8226141adc1d160e1cd54466b6b728f"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:91c8de121d5a9ba8f76512e691c89c77f2bc93aa8924d3f891b76a183e1a3226"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:53f5cf971321c833d746258f656dba79b70f24129afef070e8a617b89e4a8281"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:69e0d7fcf788ecee123487d4f229010e65f77a267293a2c620b2930a65e9abbb"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:10e7343fdba4182951a0cd33757e1beca784b9b95098a61a38515edfcdf2129e"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:82f1a4d60f5b4371c4afee96f9f460d67fed17efae8ad152c2e6ce225f1fc1a6"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-win32.whl", hash = "sha256:5bf5c920c7b8b55b9f42ea270a032280a8ceb500d30a9894f83384f48c2cd5a0"}, - {file = "grpcio_tools-1.38.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ed99b84c9866f834f7c46e00095b16cf154b39c18944f1c138407b789d40da0"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:c9f6a3b5f546a57a1011e59a5b8588970adeba7c3567efc4f21a4bea7337192c"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:142357f786c862dc5dc4141b60f74ebae57b06ce3451c823b708d628dd403f19"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:baa1c225b361806bcad14de23f7cbf09f568a3550c1c97e6f22d414cd71b4c92"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d6445128492eec9a4d387dab8ef3811f889c674055139306ec5e055b1b8c92e9"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:315b72d38f954707e94497cb81efb450c7ac53a390c9b8e4b73f47758391d643"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:6a92e26cf42746228d668e9ef1fc66fe237fb2fd00e92a2eab56053d223149d7"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:6f19404a12778703030009e6e28a7fa243d58f5a7380c40f23786aae614b35a9"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-win32.whl", hash = "sha256:280772a6f43ed96b84521cd6187bce0a6d9ea1a07cce95074c21f8fd998dc95a"}, - {file = "grpcio_tools-1.38.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a3f04462d20bfc7ac197af12ea2a114436deb78306db33f555fae64b884f05ba"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:5889a5dd9490106736b29e14e1812755c02b2b2e8a1e70829b4631ba004dfe09"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:c6427583e598e77d72c518a930fe839def7d220ff18d9bd8f07f89263255fc2f"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:2ea397c2968dab3ebf81d957cf4654f5517bb57c8c9def2d4909d3c06bc1405e"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b148d44a70a4c14809380050f9cd5907f7edf17f6645df424bdb4302d7bf21b6"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:94a3c388c1f167aa4b17ce84e334a4c3f826ff3871beec888940f6082968ed23"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:c71126f5c55f8e7d822cd39038da1fbc52131d5ad1831565555a1f0148508c21"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:ed41f0146540f6b48ac8d9a3f45cab5f8b0721062f342cb006d1fefafae811e6"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-win32.whl", hash = "sha256:ce99acf886561ad704ea9f4f5c973f42389b3522a507baa5ad78624af92231ec"}, - {file = "grpcio_tools-1.38.1-cp38-cp38-win_amd64.whl", hash = "sha256:18c710f2be5ff7b819898af3b6821b6d1853e1b9abd8d133396483e201fcdece"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:2fc301ac4c8e39c741e31bdf8594448c5e05d84b37373c5c2308653da7f74d10"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48424b77cae16859e39e31b37d3b1cb54acf12b70a903a5494f8d352bcd5d733"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:58920d167a0414156b9c6b91816c5ce2de35fba25d068d076e3f5ed12cc535cc"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:fa4956ed0d72b3d9eb4d3a4b2180bf4cb368a6246b93b2ef6367e74cd32067ff"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:09487050dd3e297b4107821680da023f7db332e02cc9db03c7ced8873717fe4f"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:c0a93efe5fdb27618be78a34c8a2320175b2c5ccc53386cfe1799cb8fb1499ec"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:dd1edaee80cce4149b04c8090fd5a93534b7eaf83c0dec747be0d2b738210598"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-win32.whl", hash = "sha256:8226c1b44d7aa519e2ec09889fb4d39bd7b52b7fc768ce400cf9eb7aa101d419"}, - {file = "grpcio_tools-1.38.1-cp39-cp39-win_amd64.whl", hash = "sha256:156eb516564b7a3d1ca0877bd8edcc3f0b797815445c1192df1e7e8db2537601"}, + {file = "grpcio-tools-1.39.0.tar.gz", hash = "sha256:39dfe7415bc0d3860fdb8dd90607594b046b88b57dbe64284efa4820f951c805"}, + {file = "grpcio_tools-1.39.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:f980c998be1b071e0c7751c7d83758cbf1ceb3b8f2fb4b4babe72b6eca2a47b7"}, + {file = "grpcio_tools-1.39.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:365838a50fc09ebea91c13d4ac6a81038e390173b66f7f9e26a8844305b308a2"}, + {file = "grpcio_tools-1.39.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:1154756d2fdc69aebece508260c91016ce08fc33e97c9e3b1cecd453f50adb8e"}, + {file = "grpcio_tools-1.39.0-cp27-cp27m-win32.whl", hash = "sha256:9dcd72943a012ec5ff4adaf1c251d182f586980bb1a899d81007d7f51a90325f"}, + {file = "grpcio_tools-1.39.0-cp27-cp27m-win_amd64.whl", hash = "sha256:9378b52c2fab2410dcd0eecca079b69b746a122b603b4064d9d78e79e9ddbaab"}, + {file = "grpcio_tools-1.39.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:8356cc67111d0ecaa3ca92ddfae4f684b2284cea0057cf26520e17816aff7798"}, + {file = "grpcio_tools-1.39.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:0396bf48739f42c92e95024c205be222070776c627611a978b773d9bd550d911"}, + {file = "grpcio_tools-1.39.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:74348a08352a4c757cd257b7fd1357e8d69af926e422a79ec9cd1ae0943347fd"}, + {file = "grpcio_tools-1.39.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:ac91a0f6f9c4ecd26af295c30a9230cdddf10b1b479833a1583dba04a7a104d5"}, + {file = "grpcio_tools-1.39.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:c2e779910e047693067a6948427955ef0fd1999393a08d1d10fceab33f01a364"}, + {file = "grpcio_tools-1.39.0-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:1da33bc6716f2f9d729a6835709acb0130fface935ea5b8c937735e895134968"}, + {file = "grpcio_tools-1.39.0-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:1e21de2de46e4cb79b37bfe30acf53c617561b47835c40ab1cfa0c41ea448216"}, + {file = "grpcio_tools-1.39.0-cp35-cp35m-win32.whl", hash = "sha256:340bb3528e0e77c730aa916e8696d69319ef6646335d96c064676086c42cec21"}, + {file = "grpcio_tools-1.39.0-cp35-cp35m-win_amd64.whl", hash = "sha256:469de6903c742567ee74d25c486c499e14797783b35f2f637e511df898277afc"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:c429848062d8184c750b3d99fdf7dbf64d845ab02028429ea46d0bb9bf39dcc3"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:bca24354dbfffd9534a59de16e4a0e3e53834571a2a2854df3c232a05f765852"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:5f5ea81372af5ff9d32869c293d232ae4825fe6c2495e5b94fd3dab77521c6b7"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:d3a7e1dba6bddf731a37befbf42fa1c9de0e210818c3a3c414b5a08da515bd8c"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:fc478cab6836d518b55b78efb12dc10c52c28f22a9f6c41bfdb9df72d746a887"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:e1c9c5540c0b7b5f4cc98629db09dd6d8a24dc7afb535586355a1f6029c8c2f7"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:26420d765c502c3b3ee8fad1eea551c657bde4cc5e38341b3d9c8b340620b56c"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-win32.whl", hash = "sha256:d0a7524cf43adaad910d7727fbd330904471fa12ad74e2f0a71860f70154be18"}, + {file = "grpcio_tools-1.39.0-cp36-cp36m-win_amd64.whl", hash = "sha256:39a9da1dd8c8ac82b17e569a7395ece84aac27d407a574a1fd4100c6231b76be"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:7d1487c1b612b97585dee17991b65daa4e99b4a59872140207472f4b685033f7"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8edcaa57263c509fad2270fc59c3c8b8a5a8e57fbad968d83606f58b42306e03"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:a0dfe121a1df5e0000c07a358897fbadd674fd524417122cfb3ac342088ab4f1"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:241c3021970bd61b6a8447401634f565052ecf869a04d09c14408f5411168dd4"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:7373f800028dc96dbbfa22c6d026eeac1233e388816020e299ee967ba86f5a44"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:566805727215f8dd4b95de7089e5acce459f961a20cb59aa3d921444d5d967cb"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:4f09a9f661d9184033be48d1ed0b4d19ce9e10b0489f17de983e342505079901"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-win32.whl", hash = "sha256:f0f4fa0ae197d8cc7b776d63057d981d753b21b0559797d9082f2c8eae65b841"}, + {file = "grpcio_tools-1.39.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bc1cb415695027403e3bb6982c71180691f51047816e5589fe54b46b6220db92"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:cea1b630a991128938030fbc751674986ed7f53e3c69e5d897f77621bd0d0948"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:714df550ae7c93a3d7537c1c0939b5060cf481d2c1a8ff05df099c17e8e9405b"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:7d34e9ec08c5298eca07bc7e226f9f72b8067b7fba4fc22fbd84dd5214138c18"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:809f989370ce38c04b20e48b53628538bb3ab4c8d841708ec5dd6a1d511d8432"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:dfb442eb45becbac05c6de358d99acc771514bf85387b81663240e8772b07065"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:1c0ae4a3bfa45e198ddb767b6b4688532fdf808769862dd950221d4e73bde4c4"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:048ed87c3d1da06da42f5b79e21c23377678f7ef329b55beff3659e1631b0193"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-win32.whl", hash = "sha256:2daf0d52e30dd675531dabb92caaa1c551f9d169bf339168c1518a5b545948d9"}, + {file = "grpcio_tools-1.39.0-cp38-cp38-win_amd64.whl", hash = "sha256:d940b34183d2e756e843d2e7ff749e8ab8e0b505f253d7860583e8611bc0133c"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:463d722f10be7a682737eccb67055ad80cd51abc5c6400b02f212e90a4dad9cb"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:5acf9667d09c018563740a15b3b67958d9544e4417f2aeebba8529953f597c36"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:e3895622d38e8a075c14b746e21556a3755b0aeaf766a54a9cab2b8611305212"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:64e77664b29b5ee8f5dedcf186ba2a411c332929b34462b1ccd56531dea84240"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3003c61fae68fb86a9cfc3d36089ef3f50b89822a58810a552fc882b88868ea6"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:a688d344e454592375e52dc68269bde0cab266ab34b792c690217af1197d6ffd"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:e497ceb0da8578cf3d0270df0c9df209cdfe40adab72ffe88f7cf0444358fa21"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-win32.whl", hash = "sha256:4098b482ef1b085842d9376aed955ba07f9d7d84c40d41beab01df0d3ca5fa45"}, + {file = "grpcio_tools-1.39.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfa6229c5771c989bfc27f5640d8dc62a3572dcd43c00707e8176a247c48399b"}, ] h11 = [ {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, @@ -1916,12 +2407,12 @@ hyperframe = [ {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, ] hypothesis = [ - {file = "hypothesis-6.14.3-py3-none-any.whl", hash = "sha256:6071ed0d25d90557f69e6a4d941b221f9b0beedde8ec8e4a136a40cad73d4886"}, - {file = "hypothesis-6.14.3.tar.gz", hash = "sha256:1c8776d9fc8c598cf1b93b99bd87976f9d9b589fc58843d85a30090700f14a8a"}, + {file = "hypothesis-6.14.4-py3-none-any.whl", hash = "sha256:8ffb719d65f591782fee1b50899e52b291b3bcc2e4a0ffc9b783c86dc3dc6a03"}, + {file = "hypothesis-6.14.4.tar.gz", hash = "sha256:629decf31b54f8223a53fc4566057b62bf73ac43b87c4b7f3d71a34e71876998"}, ] idna = [ - {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, - {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, + {file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"}, + {file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"}, ] importlib-metadata = [ {file = "importlib_metadata-4.6.1-py3-none-any.whl", hash = "sha256:9f55f560e116f8643ecf2922d9cd3e1c7e8d52e683178fecd9d08f6aa357e11e"}, @@ -2239,34 +2730,34 @@ numba = [ {file = "numba-0.53.1.tar.gz", hash = "sha256:9cd4e5216acdc66c4e9dab2dfd22ddb5bef151185c070d4a3cd8e78638aff5b0"}, ] numpy = [ - {file = "numpy-1.21.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d5caa946a9f55511e76446e170bdad1d12d6b54e17a2afe7b189112ed4412bb8"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ac4fd578322842dbda8d968e3962e9f22e862b6ec6e3378e7415625915e2da4d"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:598fe100b2948465cf3ed64b1a326424b5e4be2670552066e17dfaa67246011d"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c55407f739f0bfcec67d0df49103f9333edc870061358ac8a8c9e37ea02fcd2"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:75579acbadbf74e3afd1153da6177f846212ea2a0cc77de53523ae02c9256513"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cc367c86eb87e5b7c9592935620f22d13b090c609f1b27e49600cd033b529f54"}, - {file = "numpy-1.21.0-cp37-cp37m-win32.whl", hash = "sha256:d89b0dc7f005090e32bb4f9bf796e1dcca6b52243caf1803fdd2b748d8561f63"}, - {file = "numpy-1.21.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eda2829af498946c59d8585a9fd74da3f810866e05f8df03a86f70079c7531dd"}, - {file = "numpy-1.21.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1a784e8ff7ea2a32e393cc53eb0003eca1597c7ca628227e34ce34eb11645a0e"}, - {file = "numpy-1.21.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bba474a87496d96e61461f7306fba2ebba127bed7836212c360f144d1e72ac54"}, - {file = "numpy-1.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fd0a359c1c17f00cb37de2969984a74320970e0ceef4808c32e00773b06649d9"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e4d5a86a5257843a18fb1220c5f1c199532bc5d24e849ed4b0289fb59fbd4d8f"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:620732f42259eb2c4642761bd324462a01cdd13dd111740ce3d344992dd8492f"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9205711e5440954f861ceeea8f1b415d7dd15214add2e878b4d1cf2bcb1a914"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ad09f55cc95ed8d80d8ab2052f78cc21cb231764de73e229140d81ff49d8145e"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a1f2fb2da242568af0271455b89aee0f71e4e032086ee2b4c5098945d0e11cf6"}, - {file = "numpy-1.21.0-cp38-cp38-win32.whl", hash = "sha256:e58ddb53a7b4959932f5582ac455ff90dcb05fac3f8dcc8079498d43afbbde6c"}, - {file = "numpy-1.21.0-cp38-cp38-win_amd64.whl", hash = "sha256:d2910d0a075caed95de1a605df00ee03b599de5419d0b95d55342e9a33ad1fb3"}, - {file = "numpy-1.21.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a290989cd671cd0605e9c91a70e6df660f73ae87484218e8285c6522d29f6e38"}, - {file = "numpy-1.21.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3537b967b350ad17633b35c2f4b1a1bbd258c018910b518c30b48c8e41272717"}, - {file = "numpy-1.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc6c650f8700ce1e3a77668bb7c43e45c20ac06ae00d22bdf6760b38958c883"}, - {file = "numpy-1.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:709884863def34d72b183d074d8ba5cfe042bc3ff8898f1ffad0209161caaa99"}, - {file = "numpy-1.21.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bebab3eaf0641bba26039fb0b2c5bf9b99407924b53b1ea86e03c32c64ef5aef"}, - {file = "numpy-1.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf680682ad0a3bef56dae200dbcbac2d57294a73e5b0f9864955e7dd7c2c2491"}, - {file = "numpy-1.21.0-cp39-cp39-win32.whl", hash = "sha256:d95d16204cd51ff1a1c8d5f9958ce90ae190be81d348b514f9be39f878b8044a"}, - {file = "numpy-1.21.0-cp39-cp39-win_amd64.whl", hash = "sha256:2ba579dde0563f47021dcd652253103d6fd66165b18011dce1a0609215b2791e"}, - {file = "numpy-1.21.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c40e6b860220ed862e8097b8f81c9af6d7405b723f4a7af24a267b46f90e461"}, - {file = "numpy-1.21.0.zip", hash = "sha256:e80fe25cba41c124d04c662f33f6364909b985f2eb5998aaa5ae4b9587242cce"}, + {file = "numpy-1.21.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a75b4498b1e93d8b700282dc8e655b8bd559c0904b3910b144646dbbbc03e062"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1412aa0aec3e00bc23fbb8664d76552b4efde98fb71f60737c83efbac24112f1"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e46ceaff65609b5399163de5893d8f2a82d3c77d5e56d976c8b5fb01faa6b671"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c6a2324085dd52f96498419ba95b5777e40b6bcbc20088fddb9e8cbb58885e8e"}, + {file = "numpy-1.21.1-cp37-cp37m-win32.whl", hash = "sha256:73101b2a1fef16602696d133db402a7e7586654682244344b8329cdcbbb82172"}, + {file = "numpy-1.21.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7a708a79c9a9d26904d1cca8d383bf869edf6f8e7650d85dbc77b041e8c5a0f8"}, + {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95b995d0c413f5d0428b3f880e8fe1660ff9396dcd1f9eedbc311f37b5652e16"}, + {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:635e6bd31c9fb3d475c8f44a089569070d10a9ef18ed13738b03049280281267"}, + {file = "numpy-1.21.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a3d5fb89bfe21be2ef47c0614b9c9c707b7362386c9a3ff1feae63e0267ccb6"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a326af80e86d0e9ce92bcc1e65c8ff88297de4fa14ee936cb2293d414c9ec63"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:791492091744b0fe390a6ce85cc1bf5149968ac7d5f0477288f78c89b385d9af"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0318c465786c1f63ac05d7c4dbcecd4d2d7e13f0959b01b534ea1e92202235c5"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a513bd9c1551894ee3d31369f9b07460ef223694098cf27d399513415855b68"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91c6f5fc58df1e0a3cc0c3a717bb3308ff850abdaa6d2d802573ee2b11f674a8"}, + {file = "numpy-1.21.1-cp38-cp38-win32.whl", hash = "sha256:978010b68e17150db8765355d1ccdd450f9fc916824e8c4e35ee620590e234cd"}, + {file = "numpy-1.21.1-cp38-cp38-win_amd64.whl", hash = "sha256:9749a40a5b22333467f02fe11edc98f022133ee1bfa8ab99bda5e5437b831214"}, + {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d7a4aeac3b94af92a9373d6e77b37691b86411f9745190d2c351f410ab3a791f"}, + {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9e7912a56108aba9b31df688a4c4f5cb0d9d3787386b87d504762b6754fbb1b"}, + {file = "numpy-1.21.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:25b40b98ebdd272bc3020935427a4530b7d60dfbe1ab9381a39147834e985eac"}, + {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a92c5aea763d14ba9d6475803fc7904bda7decc2a0a68153f587ad82941fec1"}, + {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05a0f648eb28bae4bcb204e6fd14603de2908de982e761a2fc78efe0f19e96e1"}, + {file = "numpy-1.21.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01f28075a92eede918b965e86e8f0ba7b7797a95aa8d35e1cc8821f5fc3ad6a"}, + {file = "numpy-1.21.1-cp39-cp39-win32.whl", hash = "sha256:88c0b89ad1cc24a5efbb99ff9ab5db0f9a86e9cc50240177a571fbe9c2860ac2"}, + {file = "numpy-1.21.1-cp39-cp39-win_amd64.whl", hash = "sha256:01721eefe70544d548425a07c80be8377096a54118070b8a62476866d5208e33"}, + {file = "numpy-1.21.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d4d1de6e6fb3d28781c73fbde702ac97f03d79e4ffd6598b880b2d95d62ead4"}, + {file = "numpy-1.21.1.zip", hash = "sha256:dff4af63638afcc57a3dfb9e4b26d434a7a602d225b42d746ea7fe2edf1342fd"}, ] numpy-groupies = [ {file = "numpy_groupies-0.9.13.tar.gz", hash = "sha256:7b17b291322353f07c51598512d077e3731da0a048cfa8f738f3460d1ef0658d"}, @@ -2306,8 +2797,16 @@ partd = [ {file = "partd-1.2.0.tar.gz", hash = "sha256:aa67897b84d522dcbc86a98b942afab8c6aa2f7f677d904a616b74ef5ddbc3eb"}, ] pathspec = [ - {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, - {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, + {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.6.0-py2.py3-none-any.whl", hash = "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4"}, + {file = "pbr-5.6.0.tar.gz", hash = "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd"}, +] +pep8-naming = [ + {file = "pep8-naming-0.11.1.tar.gz", hash = "sha256:a1dd47dd243adfe8a83616e27cf03164960b507530f155db94e10b36a6cd6724"}, + {file = "pep8_naming-0.11.1-py2.py3-none-any.whl", hash = "sha256:f43bfe3eea7e0d73e8b5d07d6407ab47f2476ccaeff6937c84275cd30b016738"}, ] pillow = [ {file = "Pillow-8.3.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:196560dba4da7a72c5e7085fccc5938ab4075fd37fe8b5468869724109812edd"}, @@ -2431,6 +2930,10 @@ pyarrow = [ {file = "pyarrow-0.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:2ff6e7b0411e3e163cc6465f1ed6a680f0c78b4ff6a4f507d29eb4ed65860557"}, {file = "pyarrow-0.16.0.tar.gz", hash = "sha256:bb6bb7ba1b6a1c3c94cc0d0068c96df9498c973ad0ae6ca398164d339b704c97"}, ] +pycodestyle = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] pydantic = [ {file = "pydantic-1.8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739"}, {file = "pydantic-1.8.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a7c6002203fe2c5a1b5cbb141bb85060cbff88c2d78eccbc72d97eb7022c43e4"}, @@ -2455,9 +2958,21 @@ pydantic = [ {file = "pydantic-1.8.2-py3-none-any.whl", hash = "sha256:fec866a0b59f372b7e776f2d7308511784dace622e0992a0b59ea3ccee0ae833"}, {file = "pydantic-1.8.2.tar.gz", hash = "sha256:26464e57ccaafe72b7ad156fdaa4e9b9ef051f69e175dbbb463283000c05ab7b"}, ] +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"}, +] +pygments = [ + {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"}, + {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"}, +] pylint = [ - {file = "pylint-2.9.3-py3-none-any.whl", hash = "sha256:5d46330e6b8886c31b5e3aba5ff48c10f4aa5e76cbf9002c6544306221e63fbc"}, - {file = "pylint-2.9.3.tar.gz", hash = "sha256:23a1dc8b30459d78e9ff25942c61bb936108ccbe29dd9e71c01dc8274961709a"}, + {file = "pylint-2.9.5-py3-none-any.whl", hash = "sha256:748f81e5776d6273a6619506e08f1b48ff9bcb8198366a56821cf11aac14fc87"}, + {file = "pylint-2.9.5.tar.gz", hash = "sha256:1f333dc72ef7f5ea166b3230936ebcfb1f3b722e76c980cb9fe6b9f95e8d3172"}, ] pylint-fail-under = [ {file = "pylint-fail-under-0.3.0.tar.gz", hash = "sha256:4584c0eb6bf2c3dcf9402c74734a49d3a7a86fbe3590276b517fbcbdcba1333a"}, @@ -2482,8 +2997,8 @@ pytest-cov = [ {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, ] python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, + {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"}, ] python-dotenv = [ {file = "python-dotenv-0.18.0.tar.gz", hash = "sha256:effaac3c1e58d89b3ccb4d04a40dc7ad6e0275fda25fd75ae9d323e2465e202d"}, @@ -2578,8 +3093,11 @@ regex = [ {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, ] requests = [ - {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, - {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, + {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, + {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, +] +restructuredtext-lint = [ + {file = "restructuredtext_lint-1.3.2.tar.gz", hash = "sha256:d3b10a1fe2ecac537e51ae6d151b223b78de9fafdd50e5eb6b08c243df173c80"}, ] returns = [ {file = "returns-0.16.0-py3-none-any.whl", hash = "sha256:3b7544f7b8c5aac8da3469b6ce34ed8878c993f0443d47f133cef2d38b08bc2a"}, @@ -2653,58 +3171,78 @@ 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-4.0.0-py2.py3-none-any.whl", hash = "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2"}, + {file = "smmap-4.0.0.tar.gz", hash = "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182"}, +] +snowballstemmer = [ + {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"}, + {file = "snowballstemmer-2.1.0.tar.gz", hash = "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"}, +] sortedcontainers = [ {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] sqlalchemy = [ - {file = "SQLAlchemy-1.4.20-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:525dd3c2205b11a2bc6d770bf1ec63bde0253fd754b4c19c399d27ddc9dad0d3"}, - {file = "SQLAlchemy-1.4.20-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4a67371752fd86d1d03a3b82d4e75404608f6f4d579b9676124079a22a40c79f"}, - {file = "SQLAlchemy-1.4.20-cp27-cp27m-win32.whl", hash = "sha256:7150e5b543b466f45f668b352f7abda27998cc8035f051d1b7e9524ca9eb2f5f"}, - {file = "SQLAlchemy-1.4.20-cp27-cp27m-win_amd64.whl", hash = "sha256:6da83225a23eaf7b3f48f3d5f53c91b2cf00fbfa48b24a7a758160112dd3e123"}, - {file = "SQLAlchemy-1.4.20-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9841762d114018c49483c089fa2d47f7e612e57666323f615913d7d7f46e9606"}, - {file = "SQLAlchemy-1.4.20-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:eaee5dd378f6f0d7c3ec49aeeb26564d55ac0ad73b9b4688bf29e66deabddf73"}, - {file = "SQLAlchemy-1.4.20-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eb25bcf9161e2fcbe9eebe8e829719b2334e849183f0e496bf4b83722bcccfa"}, - {file = "SQLAlchemy-1.4.20-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8d860c62e3f51623ccd528d8fac44580501df557d4b467cc5581587fcf057719"}, - {file = "SQLAlchemy-1.4.20-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f6d467b67a7e5048f1408e8ea60d6caa70be5b386d0eebbf1185ab49cb8c7e4"}, - {file = "SQLAlchemy-1.4.20-cp36-cp36m-win32.whl", hash = "sha256:ff8bebc7a9d297dff2003460e01db2c20c63818b45fb19170f388b1a72fe5a14"}, - {file = "SQLAlchemy-1.4.20-cp36-cp36m-win_amd64.whl", hash = "sha256:46361690f1e1c5385994a4caeb6e8126063ff593a5c635700bbc1245de793c1e"}, - {file = "SQLAlchemy-1.4.20-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:c0eb2cd3ad4967fcbdd9e066e8cd91fe2c23c671dbae9952f0b4d3d42832cc5f"}, - {file = "SQLAlchemy-1.4.20-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76fbc24311a3d039d6cd147d396719f606d96d1413f3816c028a48e29367f646"}, - {file = "SQLAlchemy-1.4.20-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f14acb0fd16d404fda9370f93aace682f284340c89c3442ac747c5466ac7e2b5"}, - {file = "SQLAlchemy-1.4.20-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcd84e4d46a86291495d131a7824ba38d2e8278bda9425c50661a04633174319"}, - {file = "SQLAlchemy-1.4.20-cp37-cp37m-win32.whl", hash = "sha256:2f60a2e599cf5cf5e5327ce60f2918b897e42ad9f405d10dd01e37869c0ce6fc"}, - {file = "SQLAlchemy-1.4.20-cp37-cp37m-win_amd64.whl", hash = "sha256:f6fc526bd70898489d02bf52c8f0632ab377592ae954d0c0a5bb38d618dddaa9"}, - {file = "SQLAlchemy-1.4.20-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:25c0e0f3a7e8c19350086b3c0fe93c4def045cec053d749ef15da710c4d54c81"}, - {file = "SQLAlchemy-1.4.20-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d48456e1aa4f0537f9c9af7be71e1f0659ff68bc1cd538ebc785f6b007bd0d"}, - {file = "SQLAlchemy-1.4.20-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9675d5bc7e4f96a7bb2b54d14e9b269a5fb6e5d36ecc7d01f0f65bb9af3185f9"}, - {file = "SQLAlchemy-1.4.20-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b502b5e2f08500cc4b8d29bfc4f51d805adcbc00f8d149e98fda8aae85ddb644"}, - {file = "SQLAlchemy-1.4.20-cp38-cp38-win32.whl", hash = "sha256:aad3234a41340e9cf6184e621694e2a7233ba3f8aef9b1e6de8cba431b45ebd2"}, - {file = "SQLAlchemy-1.4.20-cp38-cp38-win_amd64.whl", hash = "sha256:6c8406c3d8c1c7d15da454de15d77f7bb48d14ede5db994f74226c348cf1050e"}, - {file = "SQLAlchemy-1.4.20-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:238d78b3110b7f7cffdb70bf9cda686e0d876a849bc78ba4d471aa7b1461f306"}, - {file = "SQLAlchemy-1.4.20-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:854a7b15750e617e16f8d65dbc004f065a7963544b253b923f16109557648777"}, - {file = "SQLAlchemy-1.4.20-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ff38ecf89c69a531a7326c2dae71982edfe2f805f3c016cdc5bfd1a04ebf80cb"}, - {file = "SQLAlchemy-1.4.20-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86c079732328f1add097b0b8079cd532b5d28e207fac93e9d6ea5f487506deef"}, - {file = "SQLAlchemy-1.4.20-cp39-cp39-win32.whl", hash = "sha256:46b99eab618cdc1c871ea707b7c52edc23cfea6c750740cd242ba62b5c84de7f"}, - {file = "SQLAlchemy-1.4.20-cp39-cp39-win_amd64.whl", hash = "sha256:b86d83fefc8a8c394f3490c37e1953bc16c311a3d1d1cf91518793bfb9847fb4"}, - {file = "SQLAlchemy-1.4.20.tar.gz", hash = "sha256:38ee3a266afef2978e82824650457f70c5d74ec0cadec1b10fe5ed6f038eb5d0"}, + {file = "SQLAlchemy-1.4.22-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:488608953385d6c127d2dcbc4b11f8d7f2f30b89f6bd27c01b042253d985cc2f"}, + {file = "SQLAlchemy-1.4.22-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5d856cc50fd26fc8dd04892ed5a5a3d7eeb914fea2c2e484183e2d84c14926e0"}, + {file = "SQLAlchemy-1.4.22-cp27-cp27m-win32.whl", hash = "sha256:a00d9c6d3a8afe1d1681cd8a5266d2f0ed684b0b44bada2ca82403b9e8b25d39"}, + {file = "SQLAlchemy-1.4.22-cp27-cp27m-win_amd64.whl", hash = "sha256:5908ea6c652a050d768580d01219c98c071e71910ab8e7b42c02af4010608397"}, + {file = "SQLAlchemy-1.4.22-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b7fb937c720847879c7402fe300cfdb2aeff22349fa4ea3651bca4e2d6555939"}, + {file = "SQLAlchemy-1.4.22-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:9bfe882d5a1bbde0245dca0bd48da0976bd6634cf2041d2fdf0417c5463e40e5"}, + {file = "SQLAlchemy-1.4.22-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eedd76f135461cf237534a6dc0d1e0f6bb88a1dc193678fab48a11d223462da5"}, + {file = "SQLAlchemy-1.4.22-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6a16c7c4452293da5143afa3056680db2d187b380b3ef4d470d4e29885720de3"}, + {file = "SQLAlchemy-1.4.22-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d23ea797a5e0be71bc5454b9ae99158ea0edc79e2393c6e9a2354de88329c0"}, + {file = "SQLAlchemy-1.4.22-cp36-cp36m-win32.whl", hash = "sha256:a5e14cb0c0a4ac095395f24575a0e7ab5d1be27f5f9347f1762f21505e3ba9f1"}, + {file = "SQLAlchemy-1.4.22-cp36-cp36m-win_amd64.whl", hash = "sha256:bc34a007e604091ca3a4a057525efc4cefd2b7fe970f44d20b9cfa109ab1bddb"}, + {file = "SQLAlchemy-1.4.22-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:756f5d2f5b92d27450167247fb574b09c4cd192a3f8c2e493b3e518a204ee543"}, + {file = "SQLAlchemy-1.4.22-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fcbb4b4756b250ed19adc5e28c005b8ed56fdb5c21efa24c6822c0575b4964d"}, + {file = "SQLAlchemy-1.4.22-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:09dbb4bc01a734ccddbf188deb2a69aede4b3c153a72b6d5c6900be7fb2945b1"}, + {file = "SQLAlchemy-1.4.22-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f028ef6a1d828bc754852a022b2160e036202ac8658a6c7d34875aafd14a9a15"}, + {file = "SQLAlchemy-1.4.22-cp37-cp37m-win32.whl", hash = "sha256:68393d3fd31469845b6ba11f5b4209edbea0b58506be0e077aafbf9aa2e21e11"}, + {file = "SQLAlchemy-1.4.22-cp37-cp37m-win_amd64.whl", hash = "sha256:891927a49b2363a4199763a9d436d97b0b42c65922a4ea09025600b81a00d17e"}, + {file = "SQLAlchemy-1.4.22-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:fd2102a8f8a659522719ed73865dff3d3cc76eb0833039dc473e0ad3041d04be"}, + {file = "SQLAlchemy-1.4.22-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4014978de28163cd8027434916a92d0f5bb1a3a38dff5e8bf8bff4d9372a9117"}, + {file = "SQLAlchemy-1.4.22-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f814d80844969b0d22ea63663da4de5ca1c434cfbae226188901e5d368792c17"}, + {file = "SQLAlchemy-1.4.22-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d09a760b0a045b4d799102ae7965b5491ccf102123f14b2a8cc6c01d1021a2d9"}, + {file = "SQLAlchemy-1.4.22-cp38-cp38-win32.whl", hash = "sha256:26daa429f039e29b1e523bf763bfab17490556b974c77b5ca7acb545b9230e9a"}, + {file = "SQLAlchemy-1.4.22-cp38-cp38-win_amd64.whl", hash = "sha256:12bac5fa1a6ea870bdccb96fe01610641dd44ebe001ed91ef7fcd980e9702db5"}, + {file = "SQLAlchemy-1.4.22-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:39b5d36ab71f73c068cdcf70c38075511de73616e6c7fdd112d6268c2704d9f5"}, + {file = "SQLAlchemy-1.4.22-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5102b9face693e8b2db3b2539c7e1a5d9a5b4dc0d79967670626ffd2f710d6e6"}, + {file = "SQLAlchemy-1.4.22-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c9373ef67a127799027091fa53449125351a8c943ddaa97bec4e99271dbb21f4"}, + {file = "SQLAlchemy-1.4.22-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36a089dc604032d41343d86290ce85d4e6886012eea73faa88001260abf5ff81"}, + {file = "SQLAlchemy-1.4.22-cp39-cp39-win32.whl", hash = "sha256:b48148ceedfb55f764562e04c00539bb9ea72bf07820ca15a594a9a049ff6b0e"}, + {file = "SQLAlchemy-1.4.22-cp39-cp39-win_amd64.whl", hash = "sha256:1fdae7d980a2fa617d119d0dc13ecb5c23cc63a8b04ffcb5298f2c59d86851e9"}, + {file = "SQLAlchemy-1.4.22.tar.gz", hash = "sha256:ec1be26cdccd60d180359a527d5980d959a26269a2c7b1b327a1eea0cab37ed8"}, ] starlette = [ {file = "starlette-0.14.2-py3-none-any.whl", hash = "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed"}, {file = "starlette-0.14.2.tar.gz", hash = "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa"}, ] +stevedore = [ + {file = "stevedore-3.3.0-py3-none-any.whl", hash = "sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a"}, + {file = "stevedore-3.3.0.tar.gz", hash = "sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee"}, +] tblib = [ {file = "tblib-1.7.0-py2.py3-none-any.whl", hash = "sha256:289fa7359e580950e7d9743eab36b0691f0310fce64dee7d9c31065b8f723e23"}, {file = "tblib-1.7.0.tar.gz", hash = "sha256:059bd77306ea7b419d4f76016aef6d7027cc8a0785579b5aad198803435f882c"}, ] +testfixtures = [ + {file = "testfixtures-6.18.0-py2.py3-none-any.whl", hash = "sha256:9bddf79b2dddb36420a20c25a65c827a8e7398c6ed4e2c75c2697857cb006be9"}, + {file = "testfixtures-6.18.0.tar.gz", hash = "sha256:d4bd1c4f90eac90a73e1bdc59c31d03943f218d687f3c5a09e48478841a8af5f"}, +] threadpoolctl = [ - {file = "threadpoolctl-2.1.0-py3-none-any.whl", hash = "sha256:38b74ca20ff3bb42caca8b00055111d74159ee95c4370882bbff2b93d24da725"}, - {file = "threadpoolctl-2.1.0.tar.gz", hash = "sha256:ddc57c96a38beb63db45d6c159b5ab07b6bced12c45a1f07b2b92f272aebfa6b"}, + {file = "threadpoolctl-2.2.0-py3-none-any.whl", hash = "sha256:e5a995e3ffae202758fa8a90082e35783b9370699627ae2733cd1c3a73553616"}, + {file = "threadpoolctl-2.2.0.tar.gz", hash = "sha256:86d4b6801456d780e94681d155779058759eaef3c3564758b17b6c99db5f81cb"}, ] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomli = [ + {file = "tomli-1.1.0-py3-none-any.whl", hash = "sha256:f4a182048010e89cbec0ae4686b21f550a7f2903f665e34a6de58ec15424f919"}, + {file = "tomli-1.1.0.tar.gz", hash = "sha256:33d7984738f8bb699c9b0a816eb646a8178a69eaa792d258486776a5d21b8ca5"}, +] toolz = [ {file = "toolz-0.11.1-py3-none-any.whl", hash = "sha256:1bc473acbf1a1db4e72a1ce587be347450e8f08324908b8a266b486f408f04d5"}, {file = "toolz-0.11.1.tar.gz", hash = "sha256:c7a47921f07822fe534fb1c01c9931ab335a4390c782bd28c6bcc7c2f71f3fbf"}, @@ -2812,6 +3350,10 @@ urllib3 = [ {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"}, {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"}, ] +wemake-python-styleguide = [ + {file = "wemake-python-styleguide-0.15.3.tar.gz", hash = "sha256:8b89aedabae67b7b915908ed06c178b702068137c0d8afe1fb59cdc829cd2143"}, + {file = "wemake_python_styleguide-0.15.3-py3-none-any.whl", hash = "sha256:a382f6c9ec87d56daa08a11e47cab019c99b384f1393b32564ebc74c6da80441"}, +] wirerope = [ {file = "wirerope-0.3.1.tar.gz", hash = "sha256:0ca7c9af15b04b7c21e254d910d658eef908646ae74beb86cc4981b281df2a91"}, ] diff --git a/server/pyproject.toml b/server/pyproject.toml index 5bd141a44..41f13c52f 100644 --- a/server/pyproject.toml +++ b/server/pyproject.toml @@ -58,6 +58,7 @@ python-multipart = "^0.0.5" h5py = ">=2.10,<3" scipy = "^1.6.3" returns = "^0.16.0" +wemake-python-styleguide = "^0.15.3" [tool.poetry.dev-dependencies] pytest = "*" @@ -81,12 +82,15 @@ max-line-length = '120' line-length = 120 target-version = ['py38'] +[tool.mypy] +python_version = 3.8 +plugins = [ + 'returns.contrib.mypy.returns_plugin' +] + [build-system] requires = [ "poetry>=0.12", "setuptools>=45.2.0" ] build-backend = "poetry.masonry.api" - -[mypy] -python_version = 3.8 diff --git a/server/scopeserver/api/deps.py b/server/scopeserver/api/deps.py index 6f5a7f179..0140078e8 100644 --- a/server/scopeserver/api/deps.py +++ b/server/scopeserver/api/deps.py @@ -3,6 +3,8 @@ from typing import Generator, Optional from fastapi import Cookie, Depends, HTTPException, status +from returns.io import IOResult +from returns.unsafe import unsafe_perform_io from sqlalchemy.orm import Session from scopeserver import crud, models, schemas @@ -22,7 +24,7 @@ def get_current_user(database: Session = Depends(get_db), user_id: Optional[int] "Provide access to the User currently accessing the API." unknown_user = HTTPException( status_code=status.HTTP_404_NOT_FOUND, - detail="Unknown user ID", + detail=f"Unknown user ID: {user_id}", ) no_user_id = HTTPException( @@ -32,9 +34,9 @@ def get_current_user(database: Session = Depends(get_db), user_id: Optional[int] if user_id is not None: user = crud.get_user(database, user=schemas.User(id=user_id)) - if not user: - raise unknown_user + if isinstance(user, IOResult.success_type): + return unsafe_perform_io(user.unwrap()) - return user + raise unknown_user raise no_user_id diff --git a/server/scopeserver/api/v1/projects.py b/server/scopeserver/api/v1/projects.py index 6aed90d69..5851c7d9c 100644 --- a/server/scopeserver/api/v1/projects.py +++ b/server/scopeserver/api/v1/projects.py @@ -4,6 +4,8 @@ from pathlib import Path from fastapi import APIRouter, Depends, File, HTTPException, Response, UploadFile, status +from returns.io import IOResult +from returns.unsafe import unsafe_perform_io from sqlalchemy.orm import Session from scopeserver import crud, models, schemas @@ -21,7 +23,7 @@ async def my_projects( current_user: models.User = Depends(deps.get_current_user), ): """Retrieve all projects for the current user.""" - return crud.get_projects(db=db, user_id=current_user.id) + return unsafe_perform_io(crud.get_projects(db=db, user_id=current_user.id)) @router.get("/datasets", summary="Get all datasets in a project.", response_model=List[schemas.Dataset]) @@ -32,9 +34,9 @@ async def datasets( current_user: models.User = Depends(deps.get_current_user), ): """Retrieve all datasets in a given project.""" - found_project = crud.get_project(db, user_id=current_user.id, project_uuid=project) - if found_project: - return found_project.datasets + found_project: IOResult[models.Project, str] = crud.get_project(db, user_id=current_user.id, project_uuid=project) + if isinstance(found_project, IOResult.success_type): + return unsafe_perform_io(found_project.unwrap()).datasets raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"No project with id: {project} exists.") @@ -49,7 +51,7 @@ async def users( current_user: models.User = Depends(deps.get_current_user), ): """Retrieve all users on a given project.""" - all_users = crud.get_users_in_project(db, project_uuid=project) + all_users = unsafe_perform_io(crud.get_users_in_project(db, project_uuid=project)) if current_user.id in (u.user for u in all_users): return all_users @@ -64,7 +66,7 @@ async def new_project( current_user: models.User = Depends(deps.get_current_user), ): """Create a new project.""" - project = crud.create_project(db, current_user.id, name) + project = unsafe_perform_io(crud.create_project(db, current_user.id, name)) (settings.DATA_PATH / Path(project.uuid)).mkdir() return project @@ -81,10 +83,12 @@ async def add_user( user = crud.get_user(db, schemas.User(id=user_id)) found_project = crud.get_project(db, project_uuid=project, user_id=current_user.id) - if user is not None and found_project is not None: - project_existing_users = [existing_user.id for existing_user in found_project.users] - if user.id not in project_existing_users: - crud.add_user_to_project(db, user_id=user.id, project_id=found_project.id) + if isinstance(user, IOResult.success_type) and isinstance(found_project, IOResult.success_type): + _user = unsafe_perform_io(user.unwrap()) + _project = unsafe_perform_io(found_project.unwrap()) + project_existing_users = [existing_user.id for existing_user in _project.users] + if _user.id not in project_existing_users: + unsafe_perform_io(crud.add_user_to_project(db, user_id=_user.id, project_id=_project.id)) return Response(status_code=status.HTTP_200_OK) raise HTTPException( @@ -92,7 +96,9 @@ async def add_user( detail="User already in project", ) - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="User or project does not exist") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail="User or project does not exist or does not have permission" + ) @router.post("/dataset", summary="", response_model=schemas.Dataset) @@ -106,7 +112,8 @@ async def add_dataset( ): """Add a dataset to a project.""" found_project = crud.get_project(db, project_uuid=project, user_id=current_user.id) - if found_project: + if isinstance(found_project, IOResult.success_type): + _project = unsafe_perform_io(found_project.unwrap()) size = 0 with (settings.DATA_PATH / Path(project) / Path(uploadfile.filename)).open(mode="wb") as datafile: data = await uploadfile.read() @@ -115,7 +122,9 @@ async def add_dataset( size = len(data) datafile.write(data) - return crud.create_dataset(db, name=name, filename=uploadfile.filename, project=found_project, size=size) + return unsafe_perform_io( + crud.create_dataset(db, name=name, filename=uploadfile.filename, project=_project, size=size) + ) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="You are not in this project") diff --git a/server/scopeserver/api/v1/users.py b/server/scopeserver/api/v1/users.py index edc85bc89..b0ac4864b 100644 --- a/server/scopeserver/api/v1/users.py +++ b/server/scopeserver/api/v1/users.py @@ -1,6 +1,7 @@ " API endpoints related to managing users. " from fastapi import APIRouter, Depends +from returns.unsafe import unsafe_perform_io from sqlalchemy.orm import Session from scopeserver import crud, schemas @@ -14,4 +15,4 @@ @router.post("/new", summary="Create a new user.", response_model=schemas.UserResponse) async def new_user(db: Session = Depends(deps.get_db)): """Create a new user.""" - return crud.create_user(db=db) + return unsafe_perform_io(crud.create_user(db=db)) diff --git a/server/scopeserver/crud.py b/server/scopeserver/crud.py index 19d189dff..26a52c786 100644 --- a/server/scopeserver/crud.py +++ b/server/scopeserver/crud.py @@ -1,9 +1,10 @@ " Provides low-level Create, Read, Update, and Delete functions for API resources. " -from typing import List, Optional +from typing import List from datetime import datetime from uuid import uuid4 +from returns.io import IO, IOFailure, IOResult, IOSuccess from sqlalchemy.orm import Session from scopeserver import models, schemas @@ -13,33 +14,34 @@ # Projects -def get_projects(db: Session, user_id: int) -> List[models.Project]: +def get_projects(db: Session, user_id: int) -> IO[List[models.Project]]: "Read all projects for a given user." user = db.query(models.User).filter(models.User.id == user_id).first() - return user.projects if user else [] + return IO(user.projects) if user else IO([]) -def get_project(db: Session, project_uuid: str, user_id: int) -> Optional[models.Project]: +def get_project(db: Session, project_uuid: str, user_id: int) -> IOResult[models.Project, str]: "Get a specified project if it is accessible by a specified user." project = db.query(models.Project).filter(models.Project.uuid == project_uuid).first() - mapping = ( - db.query(models.ProjectMapping) - .filter(models.ProjectMapping.project == project.id, models.ProjectMapping.user == user_id) - .first() - ) - if mapping: - return project + if project: + mapping = ( + db.query(models.ProjectMapping) + .filter(models.ProjectMapping.project == project.id, models.ProjectMapping.user == user_id) + .first() + ) + if mapping: + return IOSuccess(project) - return None + return IOFailure("Not a project you can access") -def get_users_in_project(db: Session, project_uuid: str) -> List[models.User]: +def get_users_in_project(db: Session, project_uuid: str) -> IO[List[models.User]]: "Get all users in a given project." project = db.query(models.Project).filter(models.Project.uuid == project_uuid).first() - return db.query(models.ProjectMapping).filter(models.ProjectMapping.project == project.id).all() + return IO(db.query(models.ProjectMapping).filter(models.ProjectMapping.project == project.id).all()) -def create_project(db: Session, user_id: int, name: str) -> models.Project: +def create_project(db: Session, user_id: int, name: str) -> IO[models.Project]: "Create a new project." new_project = models.Project(name=name, uuid=str(uuid4()), created=datetime.now(), size=0) db.add(new_project) @@ -48,36 +50,40 @@ def create_project(db: Session, user_id: int, name: str) -> models.Project: db.add(models.ProjectMapping(project=new_project.id, user=user_id)) db.commit() - return new_project + return IO(new_project) -def add_user_to_project(db: Session, user_id: int, project_id: int): +def add_user_to_project(db: Session, user_id: int, project_id: int) -> IO[None]: "Give a specified user_id access to a given project." db.add(models.ProjectMapping(project=project_id, user=user_id)) db.commit() + return IO(None) # Users -def get_user(db: Session, user: schemas.User) -> Optional[models.User]: +def get_user(db: Session, user: schemas.User) -> IOResult[models.User, str]: "Read a user from the database." - return db.query(models.User).filter(models.User.id == user.id).first() + if (user := db.query(models.User).filter(models.User.id == user.id).first()) is not None: + return IOSuccess(user) + + return IOFailure("User not found") -def create_user(db: Session) -> models.User: +def create_user(db: Session) -> IO[models.User]: "Create a new user." new_user = models.User(created=datetime.now()) db.add(new_user) db.commit() db.refresh(new_user) - return new_user + return IO(new_user) # Datasets -def create_dataset(db: Session, name: str, filename: str, project: models.Project, size: int) -> models.Dataset: +def create_dataset(db: Session, name: str, filename: str, project: models.Project, size: int) -> IO[models.Dataset]: "Create a new dataset." new_dataset = models.Dataset( name=name, @@ -90,4 +96,4 @@ def create_dataset(db: Session, name: str, filename: str, project: models.Projec project.size += size db.commit() db.refresh(new_dataset) - return new_dataset + return IO(new_dataset)