diff --git a/dev_requirements.txt b/dev_requirements.txt deleted file mode 100644 index 2343cd8..0000000 --- a/dev_requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -flake8 -pytest -setuptools -wheel -twine -virtualenv -rstcheck -sphinx \ No newline at end of file diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..da493b3 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1651 @@ +[[package]] +name = "absl-py" +version = "0.11.0" +description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +six = "*" + +[[package]] +name = "alabaster" +version = "0.7.12" +description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "arrow" +version = "0.17.0" +description = "Better dates & times for Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +python-dateutil = ">=2.7.0" + +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "20.3.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] + +[[package]] +name = "babel" +version = "2.8.0" +description = "Internationalization utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pytz = ">=2015.7" + +[[package]] +name = "binaryornot" +version = "0.4.4" +description = "Ultra-lightweight pure Python package to check if a file is binary or text." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +chardet = ">=3.0.2" + +[[package]] +name = "cachetools" +version = "4.1.1" +description = "Extensible memoizing collections and decorators" +category = "main" +optional = false +python-versions = "~=3.5" + +[[package]] +name = "certifi" +version = "2020.11.8" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "chardet" +version = "3.0.4" +description = "Universal encoding detector for Python 2 and 3" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "click" +version = "7.1.2" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "cookiecutter" +version = "1.7.2" +description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +binaryornot = ">=0.4.4" +click = ">=7.0" +Jinja2 = "<3.0.0" +jinja2-time = ">=0.2.0" +MarkupSafe = "<2.0.0" +poyo = ">=0.5.0" +python-slugify = ">=4.0.0" +requests = ">=2.23.0" +six = ">=1.10" + +[[package]] +name = "cycler" +version = "0.10.0" +description = "Composable style cycles" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +six = "*" + +[[package]] +name = "decorator" +version = "4.4.2" +description = "Decorators for Humans" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" + +[[package]] +name = "docutils" +version = "0.16" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "flake8" +version = "3.8.4" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" + +[[package]] +name = "future" +version = "0.18.2" +description = "Clean single-source support for Python 3 and 2" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "google-auth" +version = "1.23.0" +description = "Google Authentication Library" +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + +[package.dependencies] +cachetools = ">=2.0.0,<5.0" +pyasn1-modules = ">=0.2.1" +rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.5\""} +six = ">=1.9.0" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)"] + +[[package]] +name = "google-auth-oauthlib" +version = "0.4.2" +description = "Google Authentication Library" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +google-auth = "*" +requests-oauthlib = ">=0.7.0" + +[package.extras] +tool = ["click"] + +[[package]] +name = "grpcio" +version = "1.33.2" +description = "HTTP/2-based RPC framework" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +six = ">=1.5.2" + +[package.extras] +protobuf = ["grpcio-tools (>=1.33.2)"] + +[[package]] +name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "imageio" +version = "2.9.0" +description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +numpy = "*" +pillow = "*" + +[package.extras] +ffmpeg = ["imageio-ffmpeg"] +fits = ["astropy"] +full = ["astropy", "gdal", "imageio-ffmpeg", "itk"] +gdal = ["gdal"] +itk = ["itk"] + +[[package]] +name = "imagesize" +version = "1.2.0" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "imgaug" +version = "0.4.0" +description = "Image augmentation library for deep neural networks" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +imageio = "*" +matplotlib = "*" +numpy = ">=1.15" +opencv-python = "*" +Pillow = "*" +scikit-image = ">=0.14.2" +scipy = "*" +Shapely = "*" +six = "*" + +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "jinja2" +version = "2.11.2" +description = "A very fast and expressive template engine." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +MarkupSafe = ">=0.23" + +[package.extras] +i18n = ["Babel (>=0.8)"] + +[[package]] +name = "jinja2-time" +version = "0.2.0" +description = "Jinja2 Extension for Dates and Times" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +arrow = "*" +jinja2 = "*" + +[[package]] +name = "kiwisolver" +version = "1.3.1" +description = "A fast implementation of the Cassowary constraint solver" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "markdown" +version = "3.3.3" +description = "Python implementation of Markdown." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "1.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + +[[package]] +name = "matplotlib" +version = "3.3.2" +description = "Python plotting package" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +certifi = ">=2020.06.20" +cycler = ">=0.10" +kiwisolver = ">=1.0.1" +numpy = ">=1.15" +pillow = ">=6.2.0" +pyparsing = ">=2.0.3,<2.0.4 || >2.0.4,<2.1.2 || >2.1.2,<2.1.6 || >2.1.6" +python-dateutil = ">=2.1" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "networkx" +version = "2.5" +description = "Python package for creating and manipulating graphs and networks" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +decorator = ">=4.3.0" + +[package.extras] +all = ["numpy", "scipy", "pandas", "matplotlib", "pygraphviz", "pydot", "pyyaml", "lxml", "pytest"] +gdal = ["gdal"] +lxml = ["lxml"] +matplotlib = ["matplotlib"] +numpy = ["numpy"] +pandas = ["pandas"] +pydot = ["pydot"] +pygraphviz = ["pygraphviz"] +pytest = ["pytest"] +pyyaml = ["pyyaml"] +scipy = ["scipy"] + +[[package]] +name = "numpy" +version = "1.19.4" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "oauthlib" +version = "3.1.0" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +rsa = ["cryptography"] +signals = ["blinker"] +signedtoken = ["cryptography", "pyjwt (>=1.0.0)"] + +[[package]] +name = "opencv-python" +version = "4.4.0.46" +description = "Wrapper package for OpenCV python bindings." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +numpy = ">=1.17.3" + +[[package]] +name = "packaging" +version = "20.4" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" +six = "*" + +[[package]] +name = "pandas" +version = "1.1.4" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +numpy = ">=1.15.4" +python-dateutil = ">=2.7.3" +pytz = ">=2017.2" + +[package.extras] +test = ["pytest (>=4.0.2)", "pytest-xdist", "hypothesis (>=3.58)"] + +[[package]] +name = "pillow" +version = "8.0.1" +description = "Python Imaging Library (Fork)" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "poyo" +version = "0.5.0" +description = "A lightweight YAML Parser for Python. 🐓" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "protobuf" +version = "3.13.0" +description = "Protocol Buffers" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +six = ">=1.9" + +[[package]] +name = "py" +version = "1.9.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyasn1" +version = "0.4.8" +description = "ASN.1 types and codecs" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pyasn1-modules" +version = "0.2.8" +description = "A collection of ASN.1-based protocols modules." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pyasn1 = ">=0.4.6,<0.5.0" + +[[package]] +name = "pycodestyle" +version = "2.6.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pydantic" +version = "1.7.2" +description = "Data validation and settings management using python 3.6 type hinting" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] +typing_extensions = ["typing-extensions (>=3.7.2)"] + +[[package]] +name = "pyflakes" +version = "2.2.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pygments" +version = "2.7.2" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "pytest" +version = "6.1.2" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=17.4.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.8.2" +toml = "*" + +[package.extras] +checkqa_mypy = ["mypy (==0.780)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.8.1" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-slugify" +version = "4.0.1" +description = "A Python Slugify application that handles Unicode" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + +[[package]] +name = "pytorch-datastream" +version = "0.3.8" +description = "Simple dataset to dataloader library for pytorch" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +numpy = ">=1.17" +pandas = ">=0.25" +pydantic = ">=1.5" +torch = {version = ">=1.4", markers = "python_version > \"3.6\""} + +[[package]] +name = "pytz" +version = "2020.4" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pywavelets" +version = "1.1.1" +description = "PyWavelets, wavelet transform module" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +numpy = ">=1.13.3" + +[[package]] +name = "requests" +version = "2.24.0" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] + +[[package]] +name = "requests-oauthlib" +version = "1.3.0" +description = "OAuthlib authentication support for Requests." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib[signedtoken] (>=3.0.0)"] + +[[package]] +name = "rsa" +version = "4.6" +description = "Pure-Python RSA implementation" +category = "main" +optional = false +python-versions = ">=3.5, <4" + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "rstcheck" +version = "3.3.1" +description = "Checks syntax of reStructuredText and code blocks nested within it" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +docutils = ">=0.7" + +[[package]] +name = "scikit-image" +version = "0.17.2" +description = "Image processing in Python" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +imageio = ">=2.3.0" +matplotlib = ">=2.0.0,<3.0.0 || >3.0.0" +networkx = ">=2.0" +numpy = ">=1.15.1" +pillow = ">=4.3.0,<7.1.0 || >7.1.0,<7.1.1 || >7.1.1" +PyWavelets = ">=1.1.1" +scipy = ">=1.0.1" +tifffile = ">=2019.7.26" + +[package.extras] +docs = ["sphinx (>=1.8,<=2.4.4)", "numpydoc (>=0.9)", "sphinx-gallery (>=0.3.1)", "sphinx-copybutton", "pytest-runner", "scikit-learn", "matplotlib (>=3.0.1)", "dask[array] (>=0.15.0)", "cloudpickle (>=0.2.1)", "pandas (>=0.23.0)", "seaborn (>=0.7.1)", "pooch (>=0.5.2)"] +optional = ["simpleitk", "astropy (>=1.2.0)", "qtpy", "pyamg", "dask[array] (>=0.15.0)", "cloudpickle (>=0.2.1)", "pooch (>=0.5.2)"] +test = ["pytest (!=3.7.3)", "pytest-cov", "pytest-localserver", "flake8", "codecov"] + +[[package]] +name = "scipy" +version = "1.5.4" +description = "SciPy: Scientific Library for Python" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +numpy = ">=1.14.5" + +[[package]] +name = "shapely" +version = "1.7.1" +description = "Geometric objects, predicates, and operations" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +all = ["numpy", "pytest", "pytest-cov"] +test = ["pytest", "pytest-cov"] +vectorized = ["numpy"] + +[[package]] +name = "six" +version = "1.15.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "snowballstemmer" +version = "2.0.0" +description = "This package provides 26 stemmers for 25 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "sphinx" +version = "3.3.0" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.12" +imagesize = "*" +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = "*" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = "*" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.790)", "docutils-stubs"] +test = ["pytest", "pytest-cov", "html5lib", "typed-ast", "cython"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "1.0.3" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest", "html5lib"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest", "flake8", "mypy"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.4" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "tensorboard" +version = "2.3.0" +description = "TensorBoard lets you watch Tensors Flow" +category = "main" +optional = false +python-versions = ">= 2.7, != 3.0.*, != 3.1.*" + +[package.dependencies] +absl-py = ">=0.4" +google-auth = ">=1.6.3,<2" +google-auth-oauthlib = ">=0.4.1,<0.5" +grpcio = ">=1.24.3" +markdown = ">=2.6.8" +numpy = ">=1.12.0" +protobuf = ">=3.6.0" +requests = ">=2.21.0,<3" +six = ">=1.10.0" +tensorboard-plugin-wit = ">=1.6.0" +werkzeug = ">=0.11.15" + +[[package]] +name = "tensorboard-plugin-wit" +version = "1.7.0" +description = "What-If Tool TensorBoard plugin." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "tifffile" +version = "2020.10.1" +description = "Read and write TIFF(r) files" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +numpy = ">=1.15.1" + +[package.extras] +all = ["imagecodecs (>=2020.5.30)", "matplotlib (>=3.2)", "lxml"] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "torch" +version = "1.6.0" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +category = "main" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +future = "*" +numpy = "*" + +[[package]] +name = "tqdm" +version = "4.51.0" +description = "Fast, Extensible Progress Meter" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown"] + +[[package]] +name = "urllib3" +version = "1.25.11" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +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 = "werkzeug" +version = "1.0.1" +description = "The comprehensive WSGI web application library." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +dev = ["pytest", "pytest-timeout", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] +watchdog = ["watchdog"] + +[metadata] +lock-version = "1.1" +python-versions = "3.8" +content-hash = "6ef1bf98a869bd1bea5d1b3c8070d9d41a0600aea9c232abb6bfa646ea4624a1" + +[metadata.files] +absl-py = [ + {file = "absl-py-0.11.0.tar.gz", hash = "sha256:673cccb88d810e5627d0c1c818158485d106f65a583880e2f730c997399bcfa7"}, + {file = "absl_py-0.11.0-py3-none-any.whl", hash = "sha256:b3d9eb5119ff6e0a0125f6dabf2f9fae02f8acae7be70576002fac27235611c5"}, +] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] +arrow = [ + {file = "arrow-0.17.0-py2.py3-none-any.whl", hash = "sha256:e098abbd9af3665aea81bdd6c869e93af4feb078e98468dd351c383af187aac5"}, + {file = "arrow-0.17.0.tar.gz", hash = "sha256:ff08d10cda1d36c68657d6ad20d74fbea493d980f8b2d45344e00d6ed2bf6ed4"}, +] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, + {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, +] +babel = [ + {file = "Babel-2.8.0-py2.py3-none-any.whl", hash = "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4"}, + {file = "Babel-2.8.0.tar.gz", hash = "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38"}, +] +binaryornot = [ + {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, + {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, +] +cachetools = [ + {file = "cachetools-4.1.1-py3-none-any.whl", hash = "sha256:513d4ff98dd27f85743a8dc0e92f55ddb1b49e060c2d5961512855cda2c01a98"}, + {file = "cachetools-4.1.1.tar.gz", hash = "sha256:bbaa39c3dede00175df2dc2b03d0cf18dd2d32a7de7beb68072d13043c9edb20"}, +] +certifi = [ + {file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"}, + {file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] +click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +cookiecutter = [ + {file = "cookiecutter-1.7.2-py2.py3-none-any.whl", hash = "sha256:430eb882d028afb6102c084bab6cf41f6559a77ce9b18dc6802e3bc0cc5f4a30"}, + {file = "cookiecutter-1.7.2.tar.gz", hash = "sha256:efb6b2d4780feda8908a873e38f0e61778c23f6a2ea58215723bcceb5b515dac"}, +] +cycler = [ + {file = "cycler-0.10.0-py2.py3-none-any.whl", hash = "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d"}, + {file = "cycler-0.10.0.tar.gz", hash = "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8"}, +] +decorator = [ + {file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"}, + {file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"}, +] +docutils = [ + {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, + {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, +] +flake8 = [ + {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, + {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, +] +future = [ + {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, +] +google-auth = [ + {file = "google-auth-1.23.0.tar.gz", hash = "sha256:5176db85f1e7e837a646cd9cede72c3c404ccf2e3373d9ee14b2db88febad440"}, + {file = "google_auth-1.23.0-py2.py3-none-any.whl", hash = "sha256:b728625ff5dfce8f9e56a499c8a4eb51443a67f20f6d28b67d5774c310ec4b6b"}, +] +google-auth-oauthlib = [ + {file = "google-auth-oauthlib-0.4.2.tar.gz", hash = "sha256:65b65bc39ad8cab15039b35e5898455d3d66296d0584d96fe0e79d67d04c51d9"}, + {file = "google_auth_oauthlib-0.4.2-py2.py3-none-any.whl", hash = "sha256:d4d98c831ea21d574699978827490a41b94f05d565c617fe1b420e88f1fc8d8d"}, +] +grpcio = [ + {file = "grpcio-1.33.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c5030be8a60fb18de1fc8d93d130d57e4296c02f229200df814f6578da00429e"}, + {file = "grpcio-1.33.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5b21d3de520a699cb631cfd3a773a57debeb36b131be366bf832153405cc5404"}, + {file = "grpcio-1.33.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b412f43c99ca72769306293ba83811b241d41b62ca8f358e47e0fdaf7b6fbbd7"}, + {file = "grpcio-1.33.2-cp27-cp27m-win32.whl", hash = "sha256:703da25278ee7318acb766be1c6d3b67d392920d002b2d0304e7f3431b74f6c1"}, + {file = "grpcio-1.33.2-cp27-cp27m-win_amd64.whl", hash = "sha256:2f2eabfd514af8945ee415083a0f849eea6cb3af444999453bb6666fadc10f54"}, + {file = "grpcio-1.33.2-cp27-cp27mu-linux_armv7l.whl", hash = "sha256:d51ddfb3d481a6a3439db09d4b08447fb9f6b60d862ab301238f37bea8f60a6d"}, + {file = "grpcio-1.33.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:407b4d869ce5c6a20af5b96bb885e3ecaf383e3fb008375919eb26cf8f10d9cd"}, + {file = "grpcio-1.33.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:abaf30d18874310d4439a23a0afb6e4b5709c4266966401de7c4ae345cc810ee"}, + {file = "grpcio-1.33.2-cp35-cp35m-linux_armv7l.whl", hash = "sha256:f2673c51e8535401c68806d331faba614bcff3ee16373481158a2e74f510b7f6"}, + {file = "grpcio-1.33.2-cp35-cp35m-macosx_10_7_intel.whl", hash = "sha256:65b06fa2db2edd1b779f9b256e270f7a58d60e40121660d8b5fd6e8b88f122ed"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:514b4a6790d6597fc95608f49f2f13fe38329b2058538095f0502b734b98ffd2"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4cef3eb2df338abd9b6164427ede961d351c6bf39b4a01448a65f9e795f56575"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:3ac453387add933b6cfbc67cc8635f91ff9895299130fc612c3c4b904e91d82a"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:7d292dabf7ded9c062357f8207e20e94095a397d487ffd25aa213a2c3dff0ab4"}, + {file = "grpcio-1.33.2-cp35-cp35m-win32.whl", hash = "sha256:0aeed3558a0eec0b31700af6072f1c90e8fd5701427849e76bc469554a14b4f5"}, + {file = "grpcio-1.33.2-cp35-cp35m-win_amd64.whl", hash = "sha256:88f2a102cbc67e91f42b4323cec13348bf6255b25f80426088079872bd4f3c5c"}, + {file = "grpcio-1.33.2-cp36-cp36m-linux_armv7l.whl", hash = "sha256:affbb739fde390710190e3540acc9f3e65df25bd192cc0aa554f368288ee0ea2"}, + {file = "grpcio-1.33.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ffec0b854d2ed6ee98776c7168c778cdd18503642a68d36c00ba0f96d4ccff7c"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:7744468ee48be3265db798f27e66e118c324d7831a34fd39d5775bcd5a70a2c4"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:6a1b5b7e47600edcaeaa42983b1c19e7a5892c6b98bcde32ae2aa509a99e0436"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:289671cfe441069f617bf23c41b1fa07053a31ff64de918d1016ac73adda2f73"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:a8c84db387907e8d800c383e4c92f39996343adedf635ae5206a684f94df8311"}, + {file = "grpcio-1.33.2-cp36-cp36m-win32.whl", hash = "sha256:4bb771c4c2411196b778871b519c7e12e87f3fa72b0517b22f952c64ead07958"}, + {file = "grpcio-1.33.2-cp36-cp36m-win_amd64.whl", hash = "sha256:b581ddb8df619402c377c81f186ad7f5e2726ad9f8d57047144b352f83f37522"}, + {file = "grpcio-1.33.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:02a4a637a774382d6ac8e65c0a7af4f7f4b9704c980a0a9f4f7bbc1e97c5b733"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:592656b10528aa327058d2007f7ab175dc9eb3754b289e24cac36e09129a2f6b"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c89510381cbf8c8317e14e747a8b53988ad226f0ed240824064a9297b65f921d"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:7fda62846ef8d86caf06bd1ecfddcae2c7e59479a4ee28808120e170064d36cc"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:d386630af995fd4de225d550b6806507ca09f5a650f227fddb29299335cda55e"}, + {file = "grpcio-1.33.2-cp37-cp37m-win32.whl", hash = "sha256:bf7de9e847d2d14a0efcd48b290ee181fdbffb2ae54dfa2ec2a935a093730bac"}, + {file = "grpcio-1.33.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7c1ea6ea6daa82031af6eb5b7d1ab56b1193840389ea7cf46d80e98636f8aff5"}, + {file = "grpcio-1.33.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85e56ab125b35b1373205b3802f58119e70ffedfe0d7e2821999126058f7c44f"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0cebba3907441d5c620f7b491a780ed155140fbd590da0886ecfb1df6ad947b9"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:52143467237bfa77331ed1979dc3e203a1c12511ee37b3ddd9ff41b05804fb10"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:8cf67b8493bff50fa12b4bc30ab40ce1f1f216eb54145962b525852959b0ab3d"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:fa78bd55ec652d4a88ba254c8dae623c9992e2ce647bd17ba1a37ca2b7b42222"}, + {file = "grpcio-1.33.2-cp38-cp38-win32.whl", hash = "sha256:143b4fe72c01000fc0667bf62ace402a6518939b3511b3c2bec04d44b1d7591c"}, + {file = "grpcio-1.33.2-cp38-cp38-win_amd64.whl", hash = "sha256:08b6a58c8a83e71af5650f8f879fe14b7b84dce0c4969f3817b42c72989dacf0"}, + {file = "grpcio-1.33.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56e2a985efdba8e2282e856470b684e83a3cadd920f04fcd360b4b826ced0dd3"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:62ce7e86f11e8c4ff772e63c282fb5a7904274258be0034adf37aa679cf96ba0"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7f727b8b6d9f92fcab19dbc62ec956d8352c6767b97b8ab18754b2dfa84d784f"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2d5124284f9d29e4f06f674a12ebeb23fc16ce0f96f78a80a6036930642ae5ab"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:eff55d318a114742ed2a06972f5daacfe3d5ad0c0c0d9146bcaf10acb427e6be"}, + {file = "grpcio-1.33.2.tar.gz", hash = "sha256:21265511880056d19ce4f809ce3fbe2a3fa98ec1fc7167dbdf30a80d3276202e"}, +] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] +imageio = [ + {file = "imageio-2.9.0-py3-none-any.whl", hash = "sha256:3604d751f03002e8e0e7650aa71d8d9148144a87daf17cb1f3228e80747f2e6b"}, + {file = "imageio-2.9.0.tar.gz", hash = "sha256:52ddbaeca2dccf53ba2d6dec5676ca7bc3b2403ef8b37f7da78b7654bb3e10f0"}, +] +imagesize = [ + {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"}, + {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, +] +imgaug = [ + {file = "imgaug-0.4.0-py2.py3-none-any.whl", hash = "sha256:ce61e65b4eb7405fc62c1b0a79d2fa92fd47f763aaecb65152d29243592111f9"}, + {file = "imgaug-0.4.0.tar.gz", hash = "sha256:46bab63ed38f8980630ff721a09ca2281b7dbd4d8c11258818b6ebcc69ea46c7"}, +] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] +jinja2 = [ + {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, + {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, +] +jinja2-time = [ + {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"}, + {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, +] +kiwisolver = [ + {file = "kiwisolver-1.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd34fbbfbc40628200730bc1febe30631347103fc8d3d4fa012c21ab9c11eca9"}, + {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:d3155d828dec1d43283bd24d3d3e0d9c7c350cdfcc0bd06c0ad1209c1bbc36d0"}, + {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5a7a7dbff17e66fac9142ae2ecafb719393aaee6a3768c9de2fd425c63b53e21"}, + {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:f8d6f8db88049a699817fd9178782867bf22283e3813064302ac59f61d95be05"}, + {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:5f6ccd3dd0b9739edcf407514016108e2280769c73a85b9e59aa390046dbf08b"}, + {file = "kiwisolver-1.3.1-cp36-cp36m-win32.whl", hash = "sha256:225e2e18f271e0ed8157d7f4518ffbf99b9450fca398d561eb5c4a87d0986dd9"}, + {file = "kiwisolver-1.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cf8b574c7b9aa060c62116d4181f3a1a4e821b2ec5cbfe3775809474113748d4"}, + {file = "kiwisolver-1.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:232c9e11fd7ac3a470d65cd67e4359eee155ec57e822e5220322d7b2ac84fbf0"}, + {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:b38694dcdac990a743aa654037ff1188c7a9801ac3ccc548d3341014bc5ca278"}, + {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ca3820eb7f7faf7f0aa88de0e54681bddcb46e485beb844fcecbcd1c8bd01689"}, + {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:c8fd0f1ae9d92b42854b2979024d7597685ce4ada367172ed7c09edf2cef9cb8"}, + {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:1e1bc12fb773a7b2ffdeb8380609f4f8064777877b2225dec3da711b421fda31"}, + {file = "kiwisolver-1.3.1-cp37-cp37m-win32.whl", hash = "sha256:72c99e39d005b793fb7d3d4e660aed6b6281b502e8c1eaf8ee8346023c8e03bc"}, + {file = "kiwisolver-1.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:8be8d84b7d4f2ba4ffff3665bcd0211318aa632395a1a41553250484a871d454"}, + {file = "kiwisolver-1.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:31dfd2ac56edc0ff9ac295193eeaea1c0c923c0355bf948fbd99ed6018010b72"}, + {file = "kiwisolver-1.3.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:563c649cfdef27d081c84e72a03b48ea9408c16657500c312575ae9d9f7bc1c3"}, + {file = "kiwisolver-1.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:78751b33595f7f9511952e7e60ce858c6d64db2e062afb325985ddbd34b5c131"}, + {file = "kiwisolver-1.3.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:a357fd4f15ee49b4a98b44ec23a34a95f1e00292a139d6015c11f55774ef10de"}, + {file = "kiwisolver-1.3.1-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:5989db3b3b34b76c09253deeaf7fbc2707616f130e166996606c284395da3f18"}, + {file = "kiwisolver-1.3.1-cp38-cp38-win32.whl", hash = "sha256:c08e95114951dc2090c4a630c2385bef681cacf12636fb0241accdc6b303fd81"}, + {file = "kiwisolver-1.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:44a62e24d9b01ba94ae7a4a6c3fb215dc4af1dde817e7498d901e229aaf50e4e"}, + {file = "kiwisolver-1.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:50af681a36b2a1dee1d3c169ade9fdc59207d3c31e522519181e12f1b3ba7000"}, + {file = "kiwisolver-1.3.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a53d27d0c2a0ebd07e395e56a1fbdf75ffedc4a05943daf472af163413ce9598"}, + {file = "kiwisolver-1.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:834ee27348c4aefc20b479335fd422a2c69db55f7d9ab61721ac8cd83eb78882"}, + {file = "kiwisolver-1.3.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5c3e6455341008a054cccee8c5d24481bcfe1acdbc9add30aa95798e95c65621"}, + {file = "kiwisolver-1.3.1-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:acef3d59d47dd85ecf909c359d0fd2c81ed33bdff70216d3956b463e12c38a54"}, + {file = "kiwisolver-1.3.1-cp39-cp39-win32.whl", hash = "sha256:c5518d51a0735b1e6cee1fdce66359f8d2b59c3ca85dc2b0813a8aa86818a030"}, + {file = "kiwisolver-1.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:b9edd0110a77fc321ab090aaa1cfcaba1d8499850a12848b81be2222eab648f6"}, + {file = "kiwisolver-1.3.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0cd53f403202159b44528498de18f9285b04482bab2a6fc3f5dd8dbb9352e30d"}, + {file = "kiwisolver-1.3.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:33449715e0101e4d34f64990352bce4095c8bf13bed1b390773fc0a7295967b3"}, + {file = "kiwisolver-1.3.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:401a2e9afa8588589775fe34fc22d918ae839aaaf0c0e96441c0fdbce6d8ebe6"}, + {file = "kiwisolver-1.3.1.tar.gz", hash = "sha256:950a199911a8d94683a6b10321f9345d5a3a8433ec58b217ace979e18f16e248"}, +] +markdown = [ + {file = "Markdown-3.3.3-py3-none-any.whl", hash = "sha256:c109c15b7dc20a9ac454c9e6025927d44460b85bd039da028d85e2b6d0bcc328"}, + {file = "Markdown-3.3.3.tar.gz", hash = "sha256:5d9f2b5ca24bc4c7a390d22323ca4bad200368612b5aaa7796babf971d2b2f18"}, +] +markupsafe = [ + {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, + {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, +] +matplotlib = [ + {file = "matplotlib-3.3.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:27f9de4784ae6fb97679556c5542cf36c0751dccb4d6407f7c62517fa2078868"}, + {file = "matplotlib-3.3.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:06866c138d81a593b535d037b2727bec9b0818cadfe6a81f6ec5715b8dd38a89"}, + {file = "matplotlib-3.3.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5ccecb5f78b51b885f0028b646786889f49c54883e554fca41a2a05998063f23"}, + {file = "matplotlib-3.3.2-cp36-cp36m-win32.whl", hash = "sha256:69cf76d673682140f46c6cb5e073332c1f1b2853c748dc1cb04f7d00023567f7"}, + {file = "matplotlib-3.3.2-cp36-cp36m-win_amd64.whl", hash = "sha256:371518c769d84af8ec9b7dcb871ac44f7a67ef126dd3a15c88c25458e6b6d205"}, + {file = "matplotlib-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:793e061054662aa27acaff9201cdd510a698541c6e8659eeceb31d66c16facc6"}, + {file = "matplotlib-3.3.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:16b241c3d17be786966495229714de37de04472da472277869b8d5b456a8df00"}, + {file = "matplotlib-3.3.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3fb0409754b26f48045bacd6818e44e38ca9338089f8ba689e2f9344ff2847c7"}, + {file = "matplotlib-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:548cfe81476dbac44db96e9c0b074b6fb333b4d1f12b1ae68dbed47e45166384"}, + {file = "matplotlib-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:f0268613073df055bcc6a490de733012f2cf4fe191c1adb74e41cec8add1a165"}, + {file = "matplotlib-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:57be9e21073fc367237b03ecac0d9e4b8ddbe38e86ec4a316857d8d93ac9286c"}, + {file = "matplotlib-3.3.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:be2f0ec62e0939a9dcfd3638c140c5a74fc929ee3fd1f31408ab8633db6e1523"}, + {file = "matplotlib-3.3.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c5d0c2ae3e3ed4e9f46b7c03b40d443601012ffe8eb8dfbb2bd6b2d00509f797"}, + {file = "matplotlib-3.3.2-cp38-cp38-win32.whl", hash = "sha256:a522de31e07ed7d6f954cda3fbd5ca4b8edbfc592a821a7b00291be6f843292e"}, + {file = "matplotlib-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:8bc1d3284dee001f41ec98f59675f4d723683e1cc082830b440b5f081d8e0ade"}, + {file = "matplotlib-3.3.2-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:799c421bc245a0749c1515b6dea6dc02db0a8c1f42446a0f03b3b82a60a900dc"}, + {file = "matplotlib-3.3.2-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:2f5eefc17dc2a71318d5a3496313be5c351c0731e8c4c6182c9ac3782cfc4076"}, + {file = "matplotlib-3.3.2.tar.gz", hash = "sha256:3d2edbf59367f03cd9daf42939ca06383a7d7803e3993eb5ff1bee8e8a3fbb6b"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +networkx = [ + {file = "networkx-2.5-py3-none-any.whl", hash = "sha256:8c5812e9f798d37c50570d15c4a69d5710a18d77bafc903ee9c5fba7454c616c"}, + {file = "networkx-2.5.tar.gz", hash = "sha256:7978955423fbc9639c10498878be59caf99b44dc304c2286162fd24b458c1602"}, +] +numpy = [ + {file = "numpy-1.19.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9b30d4bd69498fc0c3fe9db5f62fffbb06b8eb9321f92cc970f2969be5e3949"}, + {file = "numpy-1.19.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:fedbd128668ead37f33917820b704784aff695e0019309ad446a6d0b065b57e4"}, + {file = "numpy-1.19.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8ece138c3a16db8c1ad38f52eb32be6086cc72f403150a79336eb2045723a1ad"}, + {file = "numpy-1.19.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:64324f64f90a9e4ef732be0928be853eee378fd6a01be21a0a8469c4f2682c83"}, + {file = "numpy-1.19.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ad6f2ff5b1989a4899bf89800a671d71b1612e5ff40866d1f4d8bcf48d4e5764"}, + {file = "numpy-1.19.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d6c7bb82883680e168b55b49c70af29b84b84abb161cbac2800e8fcb6f2109b6"}, + {file = "numpy-1.19.4-cp36-cp36m-win32.whl", hash = "sha256:13d166f77d6dc02c0a73c1101dd87fdf01339febec1030bd810dcd53fff3b0f1"}, + {file = "numpy-1.19.4-cp36-cp36m-win_amd64.whl", hash = "sha256:448ebb1b3bf64c0267d6b09a7cba26b5ae61b6d2dbabff7c91b660c7eccf2bdb"}, + {file = "numpy-1.19.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:27d3f3b9e3406579a8af3a9f262f5339005dd25e0ecf3cf1559ff8a49ed5cbf2"}, + {file = "numpy-1.19.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:16c1b388cc31a9baa06d91a19366fb99ddbe1c7b205293ed072211ee5bac1ed2"}, + {file = "numpy-1.19.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e5b6ed0f0b42317050c88022349d994fe72bfe35f5908617512cd8c8ef9da2a9"}, + {file = "numpy-1.19.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:18bed2bcb39e3f758296584337966e68d2d5ba6aab7e038688ad53c8f889f757"}, + {file = "numpy-1.19.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:fe45becb4c2f72a0907c1d0246ea6449fe7a9e2293bb0e11c4e9a32bb0930a15"}, + {file = "numpy-1.19.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:6d7593a705d662be5bfe24111af14763016765f43cb6923ed86223f965f52387"}, + {file = "numpy-1.19.4-cp37-cp37m-win32.whl", hash = "sha256:6ae6c680f3ebf1cf7ad1d7748868b39d9f900836df774c453c11c5440bc15b36"}, + {file = "numpy-1.19.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9eeb7d1d04b117ac0d38719915ae169aa6b61fca227b0b7d198d43728f0c879c"}, + {file = "numpy-1.19.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cb1017eec5257e9ac6209ac172058c430e834d5d2bc21961dceeb79d111e5909"}, + {file = "numpy-1.19.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:edb01671b3caae1ca00881686003d16c2209e07b7ef8b7639f1867852b948f7c"}, + {file = "numpy-1.19.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:f29454410db6ef8126c83bd3c968d143304633d45dc57b51252afbd79d700893"}, + {file = "numpy-1.19.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:ec149b90019852266fec2341ce1db513b843e496d5a8e8cdb5ced1923a92faab"}, + {file = "numpy-1.19.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1aeef46a13e51931c0b1cf8ae1168b4a55ecd282e6688fdb0a948cc5a1d5afb9"}, + {file = "numpy-1.19.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:08308c38e44cc926bdfce99498b21eec1f848d24c302519e64203a8da99a97db"}, + {file = "numpy-1.19.4-cp38-cp38-win32.whl", hash = "sha256:5734bdc0342aba9dfc6f04920988140fb41234db42381cf7ccba64169f9fe7ac"}, + {file = "numpy-1.19.4-cp38-cp38-win_amd64.whl", hash = "sha256:09c12096d843b90eafd01ea1b3307e78ddd47a55855ad402b157b6c4862197ce"}, + {file = "numpy-1.19.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e452dc66e08a4ce642a961f134814258a082832c78c90351b75c41ad16f79f63"}, + {file = "numpy-1.19.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a5d897c14513590a85774180be713f692df6fa8ecf6483e561a6d47309566f37"}, + {file = "numpy-1.19.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:a09f98011236a419ee3f49cedc9ef27d7a1651df07810ae430a6b06576e0b414"}, + {file = "numpy-1.19.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:50e86c076611212ca62e5a59f518edafe0c0730f7d9195fec718da1a5c2bb1fc"}, + {file = "numpy-1.19.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f0d3929fe88ee1c155129ecd82f981b8856c5d97bcb0d5f23e9b4242e79d1de3"}, + {file = "numpy-1.19.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c42c4b73121caf0ed6cd795512c9c09c52a7287b04d105d112068c1736d7c753"}, + {file = "numpy-1.19.4-cp39-cp39-win32.whl", hash = "sha256:8cac8790a6b1ddf88640a9267ee67b1aee7a57dfa2d2dd33999d080bc8ee3a0f"}, + {file = "numpy-1.19.4-cp39-cp39-win_amd64.whl", hash = "sha256:4377e10b874e653fe96985c05feed2225c912e328c8a26541f7fc600fb9c637b"}, + {file = "numpy-1.19.4-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:2a2740aa9733d2e5b2dfb33639d98a64c3b0f24765fed86b0fd2aec07f6a0a08"}, + {file = "numpy-1.19.4.zip", hash = "sha256:141ec3a3300ab89c7f2b0775289954d193cc8edb621ea05f99db9cb181530512"}, +] +oauthlib = [ + {file = "oauthlib-3.1.0-py2.py3-none-any.whl", hash = "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"}, + {file = "oauthlib-3.1.0.tar.gz", hash = "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889"}, +] +opencv-python = [ + {file = "opencv-python-4.4.0.46.tar.gz", hash = "sha256:d80db278a07f51811dbf0f9c31ff7cd5b2501822fb7a7587e71f9ff27d5c04bd"}, + {file = "opencv_python-4.4.0.46-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:14df77490c8aedceae74e660564d48c04761658aecc93895ac5e974006a89606"}, + {file = "opencv_python-4.4.0.46-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:6b6d23de6d5ddc55e865ac8532bf8062b26ba70305fa1c87c671717027dcd370"}, + {file = "opencv_python-4.4.0.46-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:6b1d85cbb64ce20ac5f79ad8e3e76a3dbff53d258c65f2fc0b9411321147a0be"}, + {file = "opencv_python-4.4.0.46-cp36-cp36m-win32.whl", hash = "sha256:4af0053c6a70f127a52c26b112341826d3dbfce6955beb9044d3eabd7e14d1cd"}, + {file = "opencv_python-4.4.0.46-cp36-cp36m-win_amd64.whl", hash = "sha256:135e05b69ab9665cbe2589f56e60895219bc2443a632bdc4bde72fb95eda1582"}, + {file = "opencv_python-4.4.0.46-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:51baebb0f8f3cae4cccd30daf018a5bb75cb759d5658aea29100d34cd5cac106"}, + {file = "opencv_python-4.4.0.46-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:9659e80059c9f39728c7dcc22032dff0d1d467f07b6cd8e036613393e4b7c71a"}, + {file = "opencv_python-4.4.0.46-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:f69a56e958ecb549ba84e0497a438080932b4d52ded441cec04d80afde71dc0a"}, + {file = "opencv_python-4.4.0.46-cp37-cp37m-win32.whl", hash = "sha256:68a9ec7e32f82cab267b6f757d9862a9a930371062739f9d00472e7c850c5854"}, + {file = "opencv_python-4.4.0.46-cp37-cp37m-win_amd64.whl", hash = "sha256:17581c68400f828700e5c6b3b082f50c781bf74cb9a7b972a04f05d26c8e894a"}, + {file = "opencv_python-4.4.0.46-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:db874c65654465ef71d6e8618bed8c725722bc90624132b9512bf061abb4eec0"}, + {file = "opencv_python-4.4.0.46-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:8aeda9b2c37bf91fa88d67f09b85f2250661eec43d72184ec544783de204e96a"}, + {file = "opencv_python-4.4.0.46-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:8a8ebd7ceebc0be9c14ca3e25a1c4ae086016b469848258e998247f2fc855314"}, + {file = "opencv_python-4.4.0.46-cp38-cp38-win32.whl", hash = "sha256:e4c072cf4260063ebadc70e34d622fa1127a88e364475ed757709e249ebe990f"}, + {file = "opencv_python-4.4.0.46-cp38-cp38-win_amd64.whl", hash = "sha256:6022609b67f9c0f14e6807e782660d1d1be94d4f0c7bc1794d7d8f600014acb2"}, + {file = "opencv_python-4.4.0.46-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:117dbb2fd184de28d831f14c1da17864efcee7bb7895e43adf40f5e1da9137fb"}, + {file = "opencv_python-4.4.0.46-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:c1382209a771ca8a25fe89d4a2377875538c6ed3cf8745280e65636cbd0988f2"}, + {file = "opencv_python-4.4.0.46-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:744e9ae2fb4c8574e6d4a762146b4d0984bdec60b98480fc54a363c03a07a1ac"}, + {file = "opencv_python-4.4.0.46-cp39-cp39-win32.whl", hash = "sha256:7fe81d08df4eb5dc4c6aa5f09888b6fd390fce5fa7d5624a98cac890b9aa6181"}, + {file = "opencv_python-4.4.0.46-cp39-cp39-win_amd64.whl", hash = "sha256:0548981fe189e0d57b9cc65066b66fd70d4bc84ea906f349a63d9098e1b911c6"}, +] +packaging = [ + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, +] +pandas = [ + {file = "pandas-1.1.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e2b8557fe6d0a18db4d61c028c6af61bfed44ef90e419ed6fadbdc079eba141e"}, + {file = "pandas-1.1.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3aa8e10768c730cc1b610aca688f588831fa70b65a26cb549fbb9f35049a05e0"}, + {file = "pandas-1.1.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:185cf8c8f38b169dbf7001e1a88c511f653fbb9dfa3e048f5e19c38049e991dc"}, + {file = "pandas-1.1.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:0d9a38a59242a2f6298fff45d09768b78b6eb0c52af5919ea9e45965d7ba56d9"}, + {file = "pandas-1.1.4-cp36-cp36m-win32.whl", hash = "sha256:8b4c2055ebd6e497e5ecc06efa5b8aa76f59d15233356eb10dad22a03b757805"}, + {file = "pandas-1.1.4-cp36-cp36m-win_amd64.whl", hash = "sha256:5dac3aeaac5feb1016e94bde851eb2012d1733a222b8afa788202b836c97dad5"}, + {file = "pandas-1.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6d2b5b58e7df46b2c010ec78d7fb9ab20abf1d306d0614d3432e7478993fbdb0"}, + {file = "pandas-1.1.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c681e8fcc47a767bf868341d8f0d76923733cbdcabd6ec3a3560695c69f14a1e"}, + {file = "pandas-1.1.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c5a3597880a7a29a31ebd39b73b2c824316ae63a05c3c8a5ce2aea3fc68afe35"}, + {file = "pandas-1.1.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:6613c7815ee0b20222178ad32ec144061cb07e6a746970c9160af1ebe3ad43b4"}, + {file = "pandas-1.1.4-cp37-cp37m-win32.whl", hash = "sha256:43cea38cbcadb900829858884f49745eb1f42f92609d368cabcc674b03e90efc"}, + {file = "pandas-1.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:5378f58172bd63d8c16dd5d008d7dcdd55bf803fcdbe7da2dcb65dbbf322f05b"}, + {file = "pandas-1.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a7d2547b601ecc9a53fd41561de49a43d2231728ad65c7713d6b616cd02ddbed"}, + {file = "pandas-1.1.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:41746d520f2b50409dffdba29a15c42caa7babae15616bcf80800d8cfcae3d3e"}, + {file = "pandas-1.1.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a15653480e5b92ee376f8458197a58cca89a6e95d12cccb4c2d933df5cecc63f"}, + {file = "pandas-1.1.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:5fdb2a61e477ce58d3f1fdf2470ee142d9f0dde4969032edaf0b8f1a9dafeaa2"}, + {file = "pandas-1.1.4-cp38-cp38-win32.whl", hash = "sha256:8a5d7e57b9df2c0a9a202840b2881bb1f7a648eba12dd2d919ac07a33a36a97f"}, + {file = "pandas-1.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:54404abb1cd3f89d01f1fb5350607815326790efb4789be60508f458cdd5ccbf"}, + {file = "pandas-1.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:112c5ba0f9ea0f60b2cc38c25f87ca1d5ca10f71efbee8e0f1bee9cf584ed5d5"}, + {file = "pandas-1.1.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:cf135a08f306ebbcfea6da8bf775217613917be23e5074c69215b91e180caab4"}, + {file = "pandas-1.1.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b1f8111635700de7ac350b639e7e452b06fc541a328cf6193cf8fc638804bab8"}, + {file = "pandas-1.1.4-cp39-cp39-win32.whl", hash = "sha256:09e0503758ad61afe81c9069505f8cb8c1e36ea8cc1e6826a95823ef5b327daf"}, + {file = "pandas-1.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:0a11a6290ef3667575cbd4785a1b62d658c25a2fd70a5adedba32e156a8f1773"}, + {file = "pandas-1.1.4.tar.gz", hash = "sha256:a979d0404b135c63954dea79e6246c45dd45371a88631cdbb4877d844e6de3b6"}, +] +pillow = [ + {file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11"}, + {file = "Pillow-8.0.1-cp36-cp36m-win32.whl", hash = "sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e"}, + {file = "Pillow-8.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3"}, + {file = "Pillow-8.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8"}, + {file = "Pillow-8.0.1-cp37-cp37m-win32.whl", hash = "sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0"}, + {file = "Pillow-8.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039"}, + {file = "Pillow-8.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015"}, + {file = "Pillow-8.0.1-cp38-cp38-win32.whl", hash = "sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271"}, + {file = "Pillow-8.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7"}, + {file = "Pillow-8.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544"}, + {file = "Pillow-8.0.1-cp39-cp39-win32.whl", hash = "sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140"}, + {file = "Pillow-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021"}, + {file = "Pillow-8.0.1-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6"}, + {file = "Pillow-8.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb"}, + {file = "Pillow-8.0.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8"}, + {file = "Pillow-8.0.1.tar.gz", hash = "sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +poyo = [ + {file = "poyo-0.5.0-py2.py3-none-any.whl", hash = "sha256:3e2ca8e33fdc3c411cd101ca395668395dd5dc7ac775b8e809e3def9f9fe041a"}, + {file = "poyo-0.5.0.tar.gz", hash = "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd"}, +] +protobuf = [ + {file = "protobuf-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9c2e63c1743cba12737169c447374fab3dfeb18111a460a8c1a000e35836b18c"}, + {file = "protobuf-3.13.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1e834076dfef9e585815757a2c7e4560c7ccc5962b9d09f831214c693a91b463"}, + {file = "protobuf-3.13.0-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:df3932e1834a64b46ebc262e951cd82c3cf0fa936a154f0a42231140d8237060"}, + {file = "protobuf-3.13.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8c35bcbed1c0d29b127c886790e9d37e845ffc2725cc1db4bd06d70f4e8359f4"}, + {file = "protobuf-3.13.0-cp35-cp35m-win32.whl", hash = "sha256:339c3a003e3c797bc84499fa32e0aac83c768e67b3de4a5d7a5a9aa3b0da634c"}, + {file = "protobuf-3.13.0-cp35-cp35m-win_amd64.whl", hash = "sha256:361acd76f0ad38c6e38f14d08775514fbd241316cce08deb2ce914c7dfa1184a"}, + {file = "protobuf-3.13.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9edfdc679a3669988ec55a989ff62449f670dfa7018df6ad7f04e8dbacb10630"}, + {file = "protobuf-3.13.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5db9d3e12b6ede5e601b8d8684a7f9d90581882925c96acf8495957b4f1b204b"}, + {file = "protobuf-3.13.0-cp36-cp36m-win32.whl", hash = "sha256:c8abd7605185836f6f11f97b21200f8a864f9cb078a193fe3c9e235711d3ff1e"}, + {file = "protobuf-3.13.0-cp36-cp36m-win_amd64.whl", hash = "sha256:4d1174c9ed303070ad59553f435846a2f877598f59f9afc1b89757bdf846f2a7"}, + {file = "protobuf-3.13.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0bba42f439bf45c0f600c3c5993666fcb88e8441d011fad80a11df6f324eef33"}, + {file = "protobuf-3.13.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c0c5ab9c4b1eac0a9b838f1e46038c3175a95b0f2d944385884af72876bd6bc7"}, + {file = "protobuf-3.13.0-cp37-cp37m-win32.whl", hash = "sha256:f68eb9d03c7d84bd01c790948320b768de8559761897763731294e3bc316decb"}, + {file = "protobuf-3.13.0-cp37-cp37m-win_amd64.whl", hash = "sha256:91c2d897da84c62816e2f473ece60ebfeab024a16c1751aaf31100127ccd93ec"}, + {file = "protobuf-3.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3dee442884a18c16d023e52e32dd34a8930a889e511af493f6dc7d4d9bf12e4f"}, + {file = "protobuf-3.13.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:e7662437ca1e0c51b93cadb988f9b353fa6b8013c0385d63a70c8a77d84da5f9"}, + {file = "protobuf-3.13.0-py2.py3-none-any.whl", hash = "sha256:d69697acac76d9f250ab745b46c725edf3e98ac24763990b24d58c16c642947a"}, + {file = "protobuf-3.13.0.tar.gz", hash = "sha256:6a82e0c8bb2bf58f606040cc5814e07715b2094caeba281e2e7d0b0e2e397db5"}, +] +py = [ + {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, + {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, +] +pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, + {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, + {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, +] +pyasn1-modules = [ + {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"}, + {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"}, + {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"}, + {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"}, + {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"}, + {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, + {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"}, + {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"}, + {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"}, + {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"}, + {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"}, + {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"}, + {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"}, +] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +] +pydantic = [ + {file = "pydantic-1.7.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:dfaa6ed1d509b5aef4142084206584280bb6e9014f01df931ec6febdad5b200a"}, + {file = "pydantic-1.7.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:2182ba2a9290964b278bcc07a8d24207de709125d520efec9ad6fa6f92ee058d"}, + {file = "pydantic-1.7.2-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:0fe8b45d31ae53d74a6aa0bf801587bd49970070eac6a6326f9fa2a302703b8a"}, + {file = "pydantic-1.7.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:01f0291f4951580f320f7ae3f2ecaf0044cdebcc9b45c5f882a7e84453362420"}, + {file = "pydantic-1.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:4ba6b903e1b7bd3eb5df0e78d7364b7e831ed8b4cd781ebc3c4f1077fbcb72a4"}, + {file = "pydantic-1.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b11fc9530bf0698c8014b2bdb3bbc50243e82a7fa2577c8cfba660bcc819e768"}, + {file = "pydantic-1.7.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a3c274c49930dc047a75ecc865e435f3df89715c775db75ddb0186804d9b04d0"}, + {file = "pydantic-1.7.2-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:c68b5edf4da53c98bb1ccb556ae8f655575cb2e676aef066c12b08c724a3f1a1"}, + {file = "pydantic-1.7.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:95d4410c4e429480c736bba0db6cce5aaa311304aea685ebcf9ee47571bfd7c8"}, + {file = "pydantic-1.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a2fc7bf77ed4a7a961d7684afe177ff59971828141e608f142e4af858e07dddc"}, + {file = "pydantic-1.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b9572c0db13c8658b4a4cb705dcaae6983aeb9842248b36761b3fbc9010b740f"}, + {file = "pydantic-1.7.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:f83f679e727742b0c465e7ef992d6da4a7e5268b8edd8fdaf5303276374bef52"}, + {file = "pydantic-1.7.2-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:e5fece30e80087d9b7986104e2ac150647ec1658c4789c89893b03b100ca3164"}, + {file = "pydantic-1.7.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ce2d452961352ba229fe1e0b925b41c0c37128f08dddb788d0fd73fd87ea0f66"}, + {file = "pydantic-1.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:fc21a37ff3f545de80b166e1735c4172b41b017948a3fb2d5e2f03c219eac50a"}, + {file = "pydantic-1.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c9760d1556ec59ff745f88269a8f357e2b7afc75c556b3a87b8dda5bc62da8ba"}, + {file = "pydantic-1.7.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c1673633ad1eea78b1c5c420a47cd48717d2ef214c8230d96ca2591e9e00958"}, + {file = "pydantic-1.7.2-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:388c0c26c574ff49bad7d0fd6ed82fbccd86a0473fa3900397d3354c533d6ebb"}, + {file = "pydantic-1.7.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ab1d5e4d8de00575957e1c982b951bffaedd3204ddd24694e3baca3332e53a23"}, + {file = "pydantic-1.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:f045cf7afb3352a03bc6cb993578a34560ac24c5d004fa33c76efec6ada1361a"}, + {file = "pydantic-1.7.2-py3-none-any.whl", hash = "sha256:6665f7ab7fbbf4d3c1040925ff4d42d7549a8c15fe041164adfe4fc2134d4cce"}, + {file = "pydantic-1.7.2.tar.gz", hash = "sha256:c8200aecbd1fb914e1bd061d71a4d1d79ecb553165296af0c14989b89e90d09b"}, +] +pyflakes = [ + {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, + {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, +] +pygments = [ + {file = "Pygments-2.7.2-py3-none-any.whl", hash = "sha256:88a0bbcd659fcb9573703957c6b9cff9fab7295e6e76db54c9d00ae42df32773"}, + {file = "Pygments-2.7.2.tar.gz", hash = "sha256:381985fcc551eb9d37c52088a32914e00517e57f4a21609f48141ba08e193fa0"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +pytest = [ + {file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"}, + {file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"}, +] +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"}, +] +python-slugify = [ + {file = "python-slugify-4.0.1.tar.gz", hash = "sha256:69a517766e00c1268e5bbfc0d010a0a8508de0b18d30ad5a1ff357f8ae724270"}, +] +pytorch-datastream = [ + {file = "pytorch_datastream-0.3.8-py36-none-any.whl", hash = "sha256:7484925a78c6cd49e608f4363293cb66fdb13ecd5ce04665f21756a7519fb6f6"}, + {file = "pytorch_datastream-0.3.8-py37-none-any.whl", hash = "sha256:cecef8a9a44f846888dbeb6e2f58e1c9ef0f9b3a7029ff6815c2063c0baa3ce2"}, + {file = "pytorch_datastream-0.3.8-py38-none-any.whl", hash = "sha256:9491a4d6dc2a7f45e3ab45e35c842b2233d2d0e6c736d14ceb0263f498336013"}, +] +pytz = [ + {file = "pytz-2020.4-py2.py3-none-any.whl", hash = "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd"}, + {file = "pytz-2020.4.tar.gz", hash = "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268"}, +] +pywavelets = [ + {file = "PyWavelets-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:35959c041ec014648575085a97b498eafbbaa824f86f6e4a59bfdef8a3fe6308"}, + {file = "PyWavelets-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:55e39ec848ceec13c9fa1598253ae9dd5c31d09dfd48059462860d2b908fb224"}, + {file = "PyWavelets-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c06d2e340c7bf8b9ec71da2284beab8519a3908eab031f4ea126e8ccfc3fd567"}, + {file = "PyWavelets-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:be105382961745f88d8196bba5a69ee2c4455d87ad2a2e5d1eed6bd7fda4d3fd"}, + {file = "PyWavelets-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:076ca8907001fdfe4205484f719d12b4a0262dfe6652fa1cfc3c5c362d14dc84"}, + {file = "PyWavelets-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7947e51ca05489b85928af52a34fe67022ab5b81d4ae32a4109a99e883a0635e"}, + {file = "PyWavelets-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:9e2528823ccf5a0a1d23262dfefe5034dce89cd84e4e124dc553dfcdf63ebb92"}, + {file = "PyWavelets-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:80b924edbc012ded8aa8b91cb2fd6207fb1a9a3a377beb4049b8a07445cec6f0"}, + {file = "PyWavelets-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c2a799e79cee81a862216c47e5623c97b95f1abee8dd1f9eed736df23fb653fb"}, + {file = "PyWavelets-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:d510aef84d9852653d079c84f2f81a82d5d09815e625f35c95714e7364570ad4"}, + {file = "PyWavelets-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:889d4c5c5205a9c90118c1980df526857929841df33e4cd1ff1eff77c6817a65"}, + {file = "PyWavelets-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:68b5c33741d26c827074b3d8f0251de1c3019bb9567b8d303eb093c822ce28f1"}, + {file = "PyWavelets-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18a51b3f9416a2ae6e9a35c4af32cf520dd7895f2b69714f4aa2f4342fca47f9"}, + {file = "PyWavelets-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cfe79844526dd92e3ecc9490b5031fca5f8ab607e1e858feba232b1b788ff0ea"}, + {file = "PyWavelets-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:2f7429eeb5bf9c7068002d0d7f094ed654c77a70ce5e6198737fd68ab85f8311"}, + {file = "PyWavelets-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:720dbcdd3d91c6dfead79c80bf8b00a1d8aa4e5d551dc528c6d5151e4efc3403"}, + {file = "PyWavelets-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:bc5e87b72371da87c9bebc68e54882aada9c3114e640de180f62d5da95749cd3"}, + {file = "PyWavelets-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:98b2669c5af842a70cfab33a7043fcb5e7535a690a00cd251b44c9be0be418e5"}, + {file = "PyWavelets-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e02a0558e0c2ac8b8bbe6a6ac18c136767ec56b96a321e0dfde2173adfa5a504"}, + {file = "PyWavelets-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6162dc0ae04669ea04b4b51420777b9ea2d30b0a9d02901b2a3b4d61d159c2e9"}, + {file = "PyWavelets-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:39c74740718e420d38c78ca4498568fa57976d78d5096277358e0fa9629a7aea"}, + {file = "PyWavelets-1.1.1-cp38-cp38-win32.whl", hash = "sha256:79f5b54f9dc353e5ee47f0c3f02bebd2c899d49780633aa771fed43fa20b3149"}, + {file = "PyWavelets-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:935ff247b8b78bdf77647fee962b1cc208c51a7b229db30b9ba5f6da3e675178"}, + {file = "PyWavelets-1.1.1.tar.gz", hash = "sha256:1a64b40f6acb4ffbaccce0545d7fc641744f95351f62e4c6aaa40549326008c9"}, +] +requests = [ + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, +] +requests-oauthlib = [ + {file = "requests-oauthlib-1.3.0.tar.gz", hash = "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"}, + {file = "requests_oauthlib-1.3.0-py2.py3-none-any.whl", hash = "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d"}, + {file = "requests_oauthlib-1.3.0-py3.7.egg", hash = "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc"}, +] +rsa = [ + {file = "rsa-4.6-py3-none-any.whl", hash = "sha256:6166864e23d6b5195a5cfed6cd9fed0fe774e226d8f854fcb23b7bbef0350233"}, + {file = "rsa-4.6.tar.gz", hash = "sha256:109ea5a66744dd859bf16fe904b8d8b627adafb9408753161e766a92e7d681fa"}, +] +rstcheck = [ + {file = "rstcheck-3.3.1.tar.gz", hash = "sha256:92c4f79256a54270e0402ba16a2f92d0b3c15c8f4410cb9c57127067c215741f"}, +] +scikit-image = [ + {file = "scikit-image-0.17.2.tar.gz", hash = "sha256:bd954c0588f0f7e81d9763dc95e06950e68247d540476e06cb77bcbcd8c2d8b3"}, + {file = "scikit_image-0.17.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:11eec2e65cd4cd6487fe1089aa3538dbe25525aec7a36f5a0f14145df0163ce7"}, + {file = "scikit_image-0.17.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c5c277704b12e702e34d1f7b7a04d5ee8418735f535d269c74c02c6c9f8abee2"}, + {file = "scikit_image-0.17.2-cp36-cp36m-win32.whl", hash = "sha256:1fda9109a19dc9d7a4ac152d1fc226fed7282ad186a099f14c0aa9151f0c758e"}, + {file = "scikit_image-0.17.2-cp36-cp36m-win_amd64.whl", hash = "sha256:86a834f9a4d30201c0803a48a25364fe8f93f9feb3c58f2c483d3ce0a3e5fe4a"}, + {file = "scikit_image-0.17.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:87ca5168c6fc36b7a298a1db2d185a8298f549854342020f282f747a4e4ddce9"}, + {file = "scikit_image-0.17.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e99fa7514320011b250a21ab855fdd61ddcc05d3c77ec9e8f13edcc15d3296b5"}, + {file = "scikit_image-0.17.2-cp37-cp37m-win32.whl", hash = "sha256:ee3db438b5b9f8716a91ab26a61377a8a63356b186706f5b979822cc7241006d"}, + {file = "scikit_image-0.17.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6b65a103edbc34b22640daf3b084dc9e470c358d3298c10aa9e3b424dcc02db6"}, + {file = "scikit_image-0.17.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c0876e562991b0babff989ff4d00f35067a2ddef82e5fdd895862555ffbaec25"}, + {file = "scikit_image-0.17.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:178210582cc62a5b25c633966658f1f2598615f9c3f27f36cf45055d2a74b401"}, + {file = "scikit_image-0.17.2-cp38-cp38-win32.whl", hash = "sha256:7bedd3881ca4fea657a894815bcd5e5bf80944c26274f6b6417bb770c3f4f8e6"}, + {file = "scikit_image-0.17.2-cp38-cp38-win_amd64.whl", hash = "sha256:113bcacdfc839854f527a166a71768708328208e7b66e491050d6a57fa6727c7"}, +] +scipy = [ + {file = "scipy-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4f12d13ffbc16e988fa40809cbbd7a8b45bc05ff6ea0ba8e3e41f6f4db3a9e47"}, + {file = "scipy-1.5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a254b98dbcc744c723a838c03b74a8a34c0558c9ac5c86d5561703362231107d"}, + {file = "scipy-1.5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:368c0f69f93186309e1b4beb8e26d51dd6f5010b79264c0f1e9ca00cd92ea8c9"}, + {file = "scipy-1.5.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:4598cf03136067000855d6b44d7a1f4f46994164bcd450fb2c3d481afc25dd06"}, + {file = "scipy-1.5.4-cp36-cp36m-win32.whl", hash = "sha256:e98d49a5717369d8241d6cf33ecb0ca72deee392414118198a8e5b4c35c56340"}, + {file = "scipy-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:65923bc3809524e46fb7eb4d6346552cbb6a1ffc41be748535aa502a2e3d3389"}, + {file = "scipy-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9ad4fcddcbf5dc67619379782e6aeef41218a79e17979aaed01ed099876c0e62"}, + {file = "scipy-1.5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f87b39f4d69cf7d7529d7b1098cb712033b17ea7714aed831b95628f483fd012"}, + {file = "scipy-1.5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:25b241034215247481f53355e05f9e25462682b13bd9191359075682adcd9554"}, + {file = "scipy-1.5.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:fa789583fc94a7689b45834453fec095245c7e69c58561dc159b5d5277057e4c"}, + {file = "scipy-1.5.4-cp37-cp37m-win32.whl", hash = "sha256:d6d25c41a009e3c6b7e757338948d0076ee1dd1770d1c09ec131f11946883c54"}, + {file = "scipy-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:2c872de0c69ed20fb1a9b9cf6f77298b04a26f0b8720a5457be08be254366c6e"}, + {file = "scipy-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e360cb2299028d0b0d0f65a5c5e51fc16a335f1603aa2357c25766c8dab56938"}, + {file = "scipy-1.5.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3397c129b479846d7eaa18f999369a24322d008fac0782e7828fa567358c36ce"}, + {file = "scipy-1.5.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:168c45c0c32e23f613db7c9e4e780bc61982d71dcd406ead746c7c7c2f2004ce"}, + {file = "scipy-1.5.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:213bc59191da2f479984ad4ec39406bf949a99aba70e9237b916ce7547b6ef42"}, + {file = "scipy-1.5.4-cp38-cp38-win32.whl", hash = "sha256:634568a3018bc16a83cda28d4f7aed0d803dd5618facb36e977e53b2df868443"}, + {file = "scipy-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:b03c4338d6d3d299e8ca494194c0ae4f611548da59e3c038813f1a43976cb437"}, + {file = "scipy-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3d5db5d815370c28d938cf9b0809dade4acf7aba57eaf7ef733bfedc9b2474c4"}, + {file = "scipy-1.5.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6b0ceb23560f46dd236a8ad4378fc40bad1783e997604ba845e131d6c680963e"}, + {file = "scipy-1.5.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:ed572470af2438b526ea574ff8f05e7f39b44ac37f712105e57fc4d53a6fb660"}, + {file = "scipy-1.5.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:8c8d6ca19c8497344b810b0b0344f8375af5f6bb9c98bd42e33f747417ab3f57"}, + {file = "scipy-1.5.4-cp39-cp39-win32.whl", hash = "sha256:d84cadd7d7998433334c99fa55bcba0d8b4aeff0edb123b2a1dfcface538e474"}, + {file = "scipy-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:cc1f78ebc982cd0602c9a7615d878396bec94908db67d4ecddca864d049112f2"}, + {file = "scipy-1.5.4.tar.gz", hash = "sha256:4a453d5e5689de62e5d38edf40af3f17560bfd63c9c5bd228c18c1f99afa155b"}, +] +shapely = [ + {file = "Shapely-1.7.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4c10f317e379cc404f8fc510cd9982d5d3e7ba13a9cfd39aa251d894c6366798"}, + {file = "Shapely-1.7.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:17df66e87d0fe0193910aeaa938c99f0b04f67b430edb8adae01e7be557b141b"}, + {file = "Shapely-1.7.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:da38ed3d65b8091447dc3717e5218cc336d20303b77b0634b261bc5c1aa2bae8"}, + {file = "Shapely-1.7.1-cp35-cp35m-win32.whl", hash = "sha256:8e7659dd994792a0aad8fb80439f59055a21163e236faf2f9823beb63a380e19"}, + {file = "Shapely-1.7.1-cp35-cp35m-win_amd64.whl", hash = "sha256:791477edb422692e7dc351c5ed6530eb0e949a31b45569946619a0d9cd5f53cb"}, + {file = "Shapely-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e3afccf0437edc108eef1e2bb9cc4c7073e7705924eb4cd0bf7715cd1ef0ce1b"}, + {file = "Shapely-1.7.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8f15b6ce67dcc05b61f19c689b60f3fe58550ba994290ff8332f711f5aaa9840"}, + {file = "Shapely-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:60e5b2282619249dbe8dc5266d781cc7d7fb1b27fa49f8241f2167672ad26719"}, + {file = "Shapely-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:de618e67b64a51a0768d26a9963ecd7d338a2cf6e9e7582d2385f88ad005b3d1"}, + {file = "Shapely-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:182716ffb500d114b5d1b75d7fd9d14b7d3414cef3c38c0490534cc9ce20981a"}, + {file = "Shapely-1.7.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4f3c59f6dbf86a9fc293546de492f5e07344e045f9333f3a753f2dda903c45d1"}, + {file = "Shapely-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:6871acba8fbe744efa4f9f34e726d070bfbf9bffb356a8f6d64557846324232b"}, + {file = "Shapely-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:35be1c5d869966569d3dfd4ec31832d7c780e9df760e1fe52131105685941891"}, + {file = "Shapely-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:052eb5b9ba756808a7825e8a8020fb146ec489dd5c919e7d139014775411e688"}, + {file = "Shapely-1.7.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:90a3e2ae0d6d7d50ff2370ba168fbd416a53e7d8448410758c5d6a5920646c1d"}, + {file = "Shapely-1.7.1-cp38-cp38-win32.whl", hash = "sha256:a3774516c8a83abfd1ddffb8b6ec1b0935d7fe6ea0ff5c31a18bfdae567b4eba"}, + {file = "Shapely-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:6593026cd3f5daaea12bcc51ae5c979318070fefee210e7990cb8ac2364e79a1"}, + {file = "Shapely-1.7.1.tar.gz", hash = "sha256:1641724c1055459a7e2b8bbe47ba25bdc89554582e62aec23cb3f3ca25f9b129"}, +] +six = [ + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +snowballstemmer = [ + {file = "snowballstemmer-2.0.0-py2.py3-none-any.whl", hash = "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0"}, + {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, +] +sphinx = [ + {file = "Sphinx-3.3.0-py3-none-any.whl", hash = "sha256:3abdb2c57a65afaaa4f8573cbabd5465078eb6fd282c1e4f87f006875a7ec0c7"}, + {file = "Sphinx-3.3.0.tar.gz", hash = "sha256:1c21e7c5481a31b531e6cbf59c3292852ccde175b504b00ce2ff0b8f4adc3649"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-1.0.3.tar.gz", hash = "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"}, + {file = "sphinxcontrib_htmlhelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.4.tar.gz", hash = "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc"}, + {file = "sphinxcontrib_serializinghtml-1.1.4-py2.py3-none-any.whl", hash = "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"}, +] +tensorboard = [ + {file = "tensorboard-2.3.0-py3-none-any.whl", hash = "sha256:d34609ed83ff01dd5b49ef81031cfc9c166bba0dabd60197024f14df5e8eae5e"}, +] +tensorboard-plugin-wit = [ + {file = "tensorboard_plugin_wit-1.7.0-py3-none-any.whl", hash = "sha256:ee775f04821185c90d9a0e9c56970ee43d7c41403beb6629385b39517129685b"}, +] +text-unidecode = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] +tifffile = [ + {file = "tifffile-2020.10.1-py3-none-any.whl", hash = "sha256:9611ac348b4db6844b6555db2b5f8f2be1715728a0011352acb55e0171ee2949"}, + {file = "tifffile-2020.10.1.tar.gz", hash = "sha256:799feeccc91965b69e1288c51a1d1118faec7f40b2eb89ad2979591b85324830"}, +] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] +torch = [ + {file = "torch-1.6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:7669f4d923b5758e28b521ea749c795ed67ff24b45ba20296bc8cff706d08df8"}, + {file = "torch-1.6.0-cp36-none-macosx_10_9_x86_64.whl", hash = "sha256:728facb972a5952323c6d790c2c5922b2b35c44b0bc7bdfa02f8639727671a0c"}, + {file = "torch-1.6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:87d65c01d1b70bb46070824f28bfd93c86d3c5c56b90cbbe836a3f2491d91c76"}, + {file = "torch-1.6.0-cp37-none-macosx_10_9_x86_64.whl", hash = "sha256:3838bd01af7dfb1f78573973f6842ce75b17e8e4f22be99c891dcb7c94bc13f5"}, + {file = "torch-1.6.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5357873e243bcfa804c32dc341f564e9a4c12addfc9baae4ee857fcc09a0a216"}, + {file = "torch-1.6.0-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:4f9a4ad7947cef566afb0a323d99009fe8524f0b0f2ca1fb7ad5de0400381a5b"}, +] +tqdm = [ + {file = "tqdm-4.51.0-py2.py3-none-any.whl", hash = "sha256:9ad44aaf0fc3697c06f6e05c7cf025dd66bc7bcb7613c66d85f4464c47ac8fad"}, + {file = "tqdm-4.51.0.tar.gz", hash = "sha256:ef54779f1c09f346b2b5a8e5c61f96fbcb639929e640e59f8cf810794f406432"}, +] +urllib3 = [ + {file = "urllib3-1.25.11-py2.py3-none-any.whl", hash = "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"}, + {file = "urllib3-1.25.11.tar.gz", hash = "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2"}, +] +werkzeug = [ + {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, + {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2e48184 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,28 @@ +[tool.poetry] +name = "workflow" +version = "0.0.0" +description = "Pytorch project template and related tools" +authors = ["Aiwizo"] +license = "Apache 2" +include = ["workflow/template/*"] + +[tool.poetry.dependencies] +python = "^3.8" +numpy = "^1.19.4" +opencv-python = "^4.4.0" +pytorch-datastream = "^0.3.8" +torch = "1.6.0" +tqdm = "^4.51.0" +cookiecutter = "^1.7.2" +tensorboard = "^2.3.0" +imgaug = "^0.4.0" + +[tool.poetry.dev-dependencies] +flake8 = "^3.8.4" +pytest = "^6.1.2" +rstcheck = "^3.3.1" +Sphinx = "^3.3.0" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 906cf76..0000000 --- a/requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -numpy>=1.18.1 -opencv-python>=4.1.2.30 -pandas>=0.25.3 -pytorch-ignite>=0.4.0,<0.5 -scikit-learn>=0.20.4 -tensorboard>=2.1.0 -torch>=1.2.0 -tqdm>=4.41.1 -cookiecutter==1.7.2 -imgaug>=0.4.0 -pytorch-datastream>=0.3.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 9232771..0000000 --- a/setup.cfg +++ /dev/null @@ -1,44 +0,0 @@ -[metadata] -name = ml-workflow -author = "Aiwizo" -author-email = richard@aiwizo.com -summary = Pytorch project template and required tools -description-file = - README.rst -description-content-type = text/x-rst; charset=UTF-8 -project_urls = - Source Code = https://github.com/aiwizo/ml-workflow/ -license = Apache-2 -classifier = - Development Status :: 3 - Alpha - Environment :: Other Environment - License :: OSI Approved :: Apache Software License - Operating System :: OS Independent - Programming Language :: Python :: 3 -keywords = - pytorch - ignite - workflow - utilities - -[files] -packages = - workflow -data_files = workflow/template = template/* - -[entry_points] -pbr.config.drivers = - plain = pbr.cfg.driver:Plain - -[options] -python_requires = >=3.7 -setup_requires = - setuptools - -[bdist_wheel] - -[build_sphinx] -builders = html -source-dir = docs/source -build-dir = docs/build -all-files = 1 diff --git a/setup_template.sh b/setup_template.sh index d3c6863..f6c9b13 100755 --- a/setup_template.sh +++ b/setup_template.sh @@ -3,11 +3,12 @@ set -o errexit -o nounset -o pipefail -o xtrace VERSION=${1:-"3.8"} +poetry build rm -rf test_template mkdir test_template cd test_template -poetry init -poetry run pip install -e ../. +poetry init --name test --description test --author none --python ${VERSION} -n +poetry add ../dist/workflow-0.0.0-py3-none-any.whl echo "test test 0.1.0 diff --git a/template/{{cookiecutter.repository_name}}/pyproject.toml b/template/{{cookiecutter.repository_name}}/pyproject.toml deleted file mode 100644 index c26102b..0000000 --- a/template/{{cookiecutter.repository_name}}/pyproject.toml +++ /dev/null @@ -1,24 +0,0 @@ -[tool.poetry] -name = "{{cookiecutter.repository_name}}" -version = "{{cookiecutter.package_version}}" -description = "{{cookiecutter.package_description}}" -authors = ["Aiwizo AB"] - -[tool.poetry.dependencies] -python = "^3.8" -torch = ">=1.6.0" -numpy = ">=1.19.2" -torchvision = ">=0.7.0" -opencv-python = ">=4.4.0" -ml-workflow = ">=0.8.1" -pytorch-datastream = ">=0.3.6" - -[tool.poetry.dev-dependencies] -guildai = ">=0.7.1.dev6" -data-kale = ">=0.1.3" -pylint = ">=2.6.0" -flake8 = ">=3.8.4" - -[build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" diff --git a/template/{{cookiecutter.repository_name}}/setup.py b/template/{{cookiecutter.repository_name}}/setup.py deleted file mode 100644 index 028b859..0000000 --- a/template/{{cookiecutter.repository_name}}/setup.py +++ /dev/null @@ -1,8 +0,0 @@ -from setuptools import setup - - -setup( - setup_requires=['pbr', 'setuptools_scm'], - pbr=True, - use_scm_version=True, -) diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/train.py b/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/train.py deleted file mode 100644 index 2f4f019..0000000 --- a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/train.py +++ /dev/null @@ -1,159 +0,0 @@ -from functools import partial -from pathlib import Path -import numpy as np -import random -import argparse -import torch -import torch.nn.functional as F -import ignite -import logging -import workflow -from workflow.functional import starcompose -from workflow.torch import set_seeds -from workflow.ignite import worker_init -from workflow.ignite.handlers.learning_rate import ( - LearningRateScheduler, warmup, cyclical -) -from datastream import Datastream - -from {{cookiecutter.package_name}} import ( - datastream, architecture, metrics, log_examples -) - - -def train(config): - - set_seeds(config['seed']) - - device = torch.device('cuda' if config['use_cuda'] else 'cpu') - - model = architecture.Model().to(device) - optimizer = torch.optim.Adam( - model.parameters(), lr=config['learning_rate'] - ) - - train_state = dict(model=model, optimizer=optimizer) - - if Path('model').exists(): - print('Loading model checkpoint') - workflow.ignite.handlers.ModelCheckpoint.load( - train_state, 'model/checkpoints', device - ) - - workflow.torch.set_learning_rate(optimizer, config['learning_rate']) - - n_parameters = sum([ - p.shape.numel() for p in model.parameters() if p.requires_grad - ]) - print(f'n_parameters: {n_parameters:,}') - - def process_batch(examples): - predictions = model.predictions( - architecture.FeatureBatch.from_examples(examples) - ) - loss = predictions.loss(examples) - return predictions, loss - - @workflow.ignite.decorators.train(model, optimizer) - def train_batch(engine, examples): - predictions, loss = process_batch(examples) - loss.backward() - return dict( - examples=examples, - predictions=predictions.cpu().detach(), - loss=loss, - ) - - @workflow.ignite.decorators.evaluate(model) - def evaluate_batch(engine, examples): - predictions, loss = process_batch(examples) - return dict( - examples=examples, - predictions=predictions.cpu().detach(), - loss=loss, - ) - - evaluate_data_loaders = { - f'evaluate_{name}': datastream.data_loader( - batch_size=config['eval_batch_size'], - num_workers=config['n_workers'], - collate_fn=tuple, - ) - for name, datastream in datastream.evaluate_datastreams().items() - } - - trainer, evaluators, tensorboard_logger = workflow.ignite.trainer( - train_batch, - evaluate_batch, - evaluate_data_loaders, - metrics=dict( - progress=metrics.progress_metrics(), - train=metrics.train_metrics(), - **{ - name: metrics.evaluate_metrics() - for name in evaluate_data_loaders.keys() - } - ), - optimizers=optimizer, - ) - - workflow.ignite.handlers.ModelScore( - lambda: -evaluators['evaluate_early_stopping'].state.metrics['loss'], - train_state, - { - name: metrics.evaluate_metrics() - for name in evaluate_data_loaders.keys() - }, - tensorboard_logger, - config, - ).attach(trainer, evaluators) - - tensorboard_logger.attach( - trainer, - log_examples('train', trainer), - ignite.engine.Events.EPOCH_COMPLETED, - ) - tensorboard_logger.attach( - evaluators['evaluate_compare'], - log_examples('evaluate_compare', trainer), - ignite.engine.Events.EPOCH_COMPLETED, - ) - - if config.get('search_learning_rate', False): - - def search(config): - def search_(step, multiplier): - return ( - step, - (1 / config['minimum_learning_rate']) - ** (step / config['n_batches']) - ) - return search_ - - LearningRateScheduler( - optimizer, - search(config), - ).attach(trainer) - - else: - LearningRateScheduler( - optimizer, - starcompose( - warmup(150), - cyclical(length=500), - ), - ).attach(trainer) - - trainer.run( - data=( - datastream.GradientDatastream() - .data_loader( - batch_size=config['batch_size'], - num_workers=config['n_workers'], - n_batches_per_epoch=config['n_batches_per_epoch'], - worker_init_fn=partial(worker_init, config['seed'], trainer), - collate_fn=tuple, - ) - ), - max_epochs=config['max_epochs'], - ) diff --git a/test_template.sh b/test_template.sh index df6b3f7..ad9c9f6 100755 --- a/test_template.sh +++ b/test_template.sh @@ -1,19 +1,22 @@ #!/usr/bin/env bash set -o errexit -o nounset -o pipefail -o xtrace +rm dist/workflow-0.0.0-py3-none-any.whl +poetry build cd test_template +poetry remove workflow +poetry install --remove-untracked +poetry add ../dist/workflow-0.0.0-py3-none-any.whl shopt -s extglob rm -rf .github -rm -rf !(venv) -source venv/bin/activate +rm -rf !(pyproject.toml) echo "repository package 0.1.0 project description -y" | python -m workflow.setup_project -guild run prepare -y -guild run search_lr n_batches=10 -y -guild run train max_epochs=2 n_batches_per_epoch=2 -y -guild run retrain max_epochs=1 n_batches_per_epoch=1 -y -guild run evaluate -y -deactivate +y" | poetry run python -m workflow.setup_project +poetry run guild run prepare -y +poetry run guild run search_lr n_batches=10 -y +poetry run guild run train max_epochs=2 n_batches_per_epoch=2 -y +poetry run guild run retrain max_epochs=1 n_batches_per_epoch=1 -y +poetry run guild run evaluate -y diff --git a/workflow/__init__.py b/workflow/__init__.py index caa481d..1b477d6 100644 --- a/workflow/__init__.py +++ b/workflow/__init__.py @@ -1,8 +1,10 @@ +from workflow import functional + from workflow.figure_to_numpy import figure_to_numpy from workflow.numpy_seed import numpy_seed +from workflow.progress_bar import ProgressBar +from workflow.early_stopping import EarlyStopping -from workflow import functional -from workflow import ignite from workflow import torch from pkg_resources import get_distribution, DistributionNotFound diff --git a/workflow/early_stopping.py b/workflow/early_stopping.py new file mode 100644 index 0000000..5d0a983 --- /dev/null +++ b/workflow/early_stopping.py @@ -0,0 +1,8 @@ + + +# TODO +class EarlyStopping: + scores_since_improvement = 0 + + def score(self, tensorboard_logger): + return self diff --git a/workflow/functional/__init__.py b/workflow/functional/__init__.py index 17d7cbf..d0e4ceb 100644 --- a/workflow/functional/__init__.py +++ b/workflow/functional/__init__.py @@ -1,5 +1,3 @@ -from .interleaved import interleaved -from .repeat_map_chain import repeat_map_chain -from .star import star -from .starcompose import starcompose -from .structure_map import structure_map +from workflow.functional.star import star +from workflow.functional.starcompose import starcompose +from workflow.functional.structure_map import structure_map diff --git a/workflow/functional/interleaved.py b/workflow/functional/interleaved.py deleted file mode 100644 index 6187634..0000000 --- a/workflow/functional/interleaved.py +++ /dev/null @@ -1,29 +0,0 @@ -from itertools import chain - -from workflow.functional.starcompose import starcompose - - -interleaved = starcompose( - tuple, - zip, - chain.from_iterable, -) - - -def test_interleaved(): - from itertools import repeat - - test = interleaved([range(3)]) - if list(test) != [0, 1, 2]: - raise Exception('Interleave with single iterator failed') - - test = interleaved([ - range(3), - range(5) - ]) - - if list(test) != [0, 0, 1, 1, 2, 2]: - raise Exception('Interleave with different lengths failed') - - if list(test) != []: - raise Exception('Expected generator to be exhausted') diff --git a/workflow/functional/repeat_map_chain.py b/workflow/functional/repeat_map_chain.py deleted file mode 100644 index f10cc2f..0000000 --- a/workflow/functional/repeat_map_chain.py +++ /dev/null @@ -1,16 +0,0 @@ -from itertools import repeat, chain -from functools import partial - -from workflow.functional.starcompose import starcompose - - -def mk_repeat_map_chain(fn): - return starcompose( - repeat, - partial(map, fn), - chain.from_iterable, - ) - - -def repeat_map_chain(fn, iterable): - return mk_repeat_map_chain(fn)(iterable) diff --git a/workflow/ignite/__init__.py b/workflow/ignite/__init__.py deleted file mode 100644 index 9bbfc95..0000000 --- a/workflow/ignite/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from workflow.ignite import handlers -from workflow.ignite import decorators - -from workflow.ignite.worker_init import worker_init -from workflow.ignite.trainer import trainer -from workflow.ignite.evaluator import evaluator diff --git a/workflow/ignite/evaluator.py b/workflow/ignite/evaluator.py deleted file mode 100644 index 5540c4f..0000000 --- a/workflow/ignite/evaluator.py +++ /dev/null @@ -1,31 +0,0 @@ -from ignite.engine import Engine, Events -from ignite.contrib.handlers.tensorboard_logger import ( - TensorboardLogger, OutputHandler -) - -from workflow.ignite.handlers import ( - MetricsLogger, - ProgressBar, -) - - -def evaluator(evaluate_batch, description, metrics, tensorboard_logger): - engine = Engine(evaluate_batch) - - for metric_name, metric in metrics.items(): - metric.attach(engine, metric_name) - - metric_names = list(metrics.keys()) - - ProgressBar(desc=description).attach(engine) - MetricsLogger(description).attach(engine, metric_names) - tensorboard_logger.attach( - engine, - OutputHandler( - tag=description, - metric_names=metric_names, - ), - Events.EPOCH_COMPLETED, - ) - - return engine diff --git a/workflow/ignite/handlers/__init__.py b/workflow/ignite/handlers/__init__.py deleted file mode 100644 index 83b8ece..0000000 --- a/workflow/ignite/handlers/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from workflow.ignite.handlers import learning_rate - -from workflow.ignite.handlers.early_stopping import EarlyStopping -from workflow.ignite.handlers.epoch_logger import EpochLogger -from workflow.ignite.handlers.model_checkpoint import ModelCheckpoint -from workflow.ignite.handlers.metrics_logger import MetricsLogger -from workflow.ignite.handlers.progress_bar import ProgressBar -from workflow.ignite.handlers.model_score import ModelScore -from workflow.ignite.handlers.best_model_trigger import BestModelTrigger diff --git a/workflow/ignite/handlers/best_model_trigger.py b/workflow/ignite/handlers/best_model_trigger.py deleted file mode 100644 index b13731b..0000000 --- a/workflow/ignite/handlers/best_model_trigger.py +++ /dev/null @@ -1,46 +0,0 @@ -from enum import Enum -from ignite.engine import ( - Events, - EventEnum, -) -import numpy as np - - -class CustomEvents(EventEnum): - NEW_BEST_MODEL = 'new_best_model' - - -class BestModelTrigger: - Event = CustomEvents.NEW_BEST_MODEL - - def __init__(self, metric_name, extra_triggered_engines=[]): - self.best_score = -np.inf - self.extra_triggered_engines = extra_triggered_engines - self.metric_name = metric_name - - for engine in extra_triggered_engines: - engine.register_events( - CustomEvents.NEW_BEST_MODEL, - event_to_attr={CustomEvents.NEW_BEST_MODEL: 'new_best_model'} - ) - - def _check_new_best_model(self, engine): - score = engine.state.metrics[self.metric_name] - if score > self.best_score: - self.best_score = score - - engine.fire_event(CustomEvents.NEW_BEST_MODEL) - - for trigger_engine in self.extra_triggered_engines: - trigger_engine.fire_event(CustomEvents.NEW_BEST_MODEL) - - def attach(self, engine): - engine.register_events( - CustomEvents.NEW_BEST_MODEL, - event_to_attr={CustomEvents.NEW_BEST_MODEL: 'new_best_model'} - ) - - engine.add_event_handler( - Events.EPOCH_COMPLETED, - lambda engine: self._check_new_best_model(engine) - ) diff --git a/workflow/ignite/handlers/early_stopping.py b/workflow/ignite/handlers/early_stopping.py deleted file mode 100644 index 4866d10..0000000 --- a/workflow/ignite/handlers/early_stopping.py +++ /dev/null @@ -1,31 +0,0 @@ -from tqdm import tqdm -import ignite -from ignite.engine import Events - - -class EarlyStopping: - def __init__(self, model_score_function, trainer, config): - self.early_stopping_handler = ignite.handlers.EarlyStopping( - patience=config['patience'], - score_function=model_score_function, - trainer=trainer, - ) - - def attach(self, engine): - engine.add_event_handler( - Events.EPOCH_COMPLETED, self.early_stopping_handler - ) - - engine.add_event_handler( - Events.EPOCH_COMPLETED, - self._print_status, - ) - - def _print_status(self, engine): - epochs_until_stop = ( - self.early_stopping_handler.patience - self.early_stopping_handler.counter - ) - tqdm.write( - f'best score so far: {self.early_stopping_handler.best_score:.4f}' - f' (stopping in {epochs_until_stop:.0f} epochs)\n' - ) diff --git a/workflow/ignite/handlers/epoch_logger.py b/workflow/ignite/handlers/epoch_logger.py deleted file mode 100644 index 26f5608..0000000 --- a/workflow/ignite/handlers/epoch_logger.py +++ /dev/null @@ -1,16 +0,0 @@ -from tqdm import tqdm -from ignite.engine import Events - - -def get_epoch_text(epoch, max_epochs): - return f'------ epoch: {epoch} / {max_epochs} ------' - - -class EpochLogger: - def attach(self, engine): - engine.add_event_handler( - Events.EPOCH_STARTED, - lambda engine: tqdm.write( - get_epoch_text(engine.state.epoch, engine.state.max_epochs) - ) - ) diff --git a/workflow/ignite/handlers/learning_rate/__init__.py b/workflow/ignite/handlers/learning_rate/__init__.py deleted file mode 100644 index 952ccb6..0000000 --- a/workflow/ignite/handlers/learning_rate/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .cyclical import cyclical -from .decay import decay -from .learning_rate_scheduler import LearningRateScheduler -from .warmup import warmup -from .zero_warmup import zero_warmup diff --git a/workflow/ignite/handlers/learning_rate/cyclical.py b/workflow/ignite/handlers/learning_rate/cyclical.py deleted file mode 100644 index 301951a..0000000 --- a/workflow/ignite/handlers/learning_rate/cyclical.py +++ /dev/null @@ -1,17 +0,0 @@ - - -def cyclical(length=100, relative_min=0.1): - '''Also known as triangular, https://arxiv.org/pdf/1506.01186.pdf''' - - half = length / 2 - def _cyclical(step, multiplier): - return ( - step, - multiplier * ( - relative_min + (1 - relative_min) * abs( - ((step - 1) % length - half) - / (half - 1) - ) - ) - ) - return _cyclical diff --git a/workflow/ignite/handlers/learning_rate/decay.py b/workflow/ignite/handlers/learning_rate/decay.py deleted file mode 100644 index e4b1674..0000000 --- a/workflow/ignite/handlers/learning_rate/decay.py +++ /dev/null @@ -1,9 +0,0 @@ - - -def decay(base): - def _decay(step, multiplier): - return ( - step, - multiplier * base ** (step - 1) - ) - return _decay diff --git a/workflow/ignite/handlers/learning_rate/learning_rate_scheduler.py b/workflow/ignite/handlers/learning_rate/learning_rate_scheduler.py deleted file mode 100644 index f107201..0000000 --- a/workflow/ignite/handlers/learning_rate/learning_rate_scheduler.py +++ /dev/null @@ -1,30 +0,0 @@ -from ignite.engine import Events -from ignite.contrib.handlers.param_scheduler import LRScheduler -from torch.optim.lr_scheduler import LambdaLR - - -class LearningRateScheduler(LRScheduler): - def __init__(self, optimizer, multiplicative_fn): - ''' - Usage: - - LearningRateScheduler( - optimizer, - starcompose( - warmup(n_steps=100), - cyclical(length=50, relative_minimum=0.1), - decay(0.97), - ) - ).attach(trainer) - ''' - self.multiplicative_fn = multiplicative_fn - super().__init__( - LambdaLR(optimizer, self.learning_rate) - ) - - def learning_rate(self, step): - _, learning_rate = self.multiplicative_fn(step, 1) - return learning_rate - - def attach(self, trainer): - trainer.add_event_handler(Events.ITERATION_STARTED, self.__call__) diff --git a/workflow/ignite/handlers/learning_rate/warmup.py b/workflow/ignite/handlers/learning_rate/warmup.py deleted file mode 100644 index 0d7fa33..0000000 --- a/workflow/ignite/handlers/learning_rate/warmup.py +++ /dev/null @@ -1,11 +0,0 @@ - - -def warmup(n_steps): - def _warmup(step, multiplier): - if step == 0: - return (0, 0.) - elif step <= n_steps: - return (1, (step - 1) / n_steps) - else: - return (step - n_steps, multiplier) - return _warmup diff --git a/workflow/ignite/handlers/learning_rate/zero_warmup.py b/workflow/ignite/handlers/learning_rate/zero_warmup.py deleted file mode 100644 index 9b44a9a..0000000 --- a/workflow/ignite/handlers/learning_rate/zero_warmup.py +++ /dev/null @@ -1,9 +0,0 @@ - - -def zero_warmup(n_steps): - def _zero_warmup(step, multiplier): - if step <= n_steps: - return (1, 0.) - else: - return (step - n_steps, multiplier) - return _zero_warmup diff --git a/workflow/ignite/handlers/metrics_logger.py b/workflow/ignite/handlers/metrics_logger.py deleted file mode 100644 index d15a998..0000000 --- a/workflow/ignite/handlers/metrics_logger.py +++ /dev/null @@ -1,41 +0,0 @@ -from tqdm import tqdm -from ignite.engine import Events - -from workflow.torch.is_float import is_float - - -class MetricsLogger: - def __init__(self, name): - self.name = name - - def attach(self, engine, metric_names): - engine.add_event_handler( - Events.EPOCH_COMPLETED, - lambda engine: self._print(engine, metric_names) - ) - - def _print(self, engine, metric_names): - if len(engine.state.metrics) >= 1: - tqdm.write(f'{self.name}:') - - target_len = max(map(len, metric_names)) - for metric_name in metric_names: - value = engine.state.metrics.get(metric_name, None) - - if value is not None: - - padding = ' ' * (target_len - len(metric_name)) - if hasattr(value, '__len__'): - tqdm.write(f' {metric_name}:') - tqdm.write(str(value)) - elif is_float(value): - if abs(value) > 1e-4 or value == 0: - tqdm.write( - f' {metric_name}:{padding} {value:.4f}' - ) - else: - tqdm.write( - f' {metric_name}:{padding} {value:.4e}' - ) - else: - tqdm.write(f' {metric_name}:{padding} {value}') diff --git a/workflow/ignite/handlers/model_checkpoint.py b/workflow/ignite/handlers/model_checkpoint.py deleted file mode 100644 index 9bc0de8..0000000 --- a/workflow/ignite/handlers/model_checkpoint.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import torch -import numpy as np -import ignite -from ignite.engine import Events - - -class ModelCheckpoint: - dirname = 'checkpoints' - filename_prefix = 'model' - - def __init__(self, model_score_function=None): - self.model_checkpoint = ignite.handlers.ModelCheckpoint( - dirname=self.dirname, - filename_prefix=self.filename_prefix, - score_function=model_score_function, - n_saved=1, - require_empty=False, - ) - - def attach(self, engine, *args, **kwargs): - engine.add_event_handler( - Events.EPOCH_COMPLETED, - self.model_checkpoint, - *args, - **kwargs, - ) - - @staticmethod - def load( - to_load, - dirname=None, - device=None, - suffix=None, - ): - if dirname is None: - dirname = ModelCheckpoint.dirname - - models = os.listdir(dirname) - if suffix is None: - suffixes = [ - '_'.join( - os.path.splitext(name)[0] - .lstrip(ModelCheckpoint.filename_prefix) - .split('_')[2:] - ) - for name in models - ] - suffix = suffixes[np.argmax([float(s.split('_')[-1]) for s in suffixes])] - - saved_checkpoint_state = torch.load( - f'{dirname}/{ModelCheckpoint.filename_prefix}_checkpoint_{suffix}.pt', - map_location=device, - ) - - for name, module_or_optimizer in to_load.items(): - module_or_optimizer.load_state_dict( - saved_checkpoint_state[name] - ) - - return suffix diff --git a/workflow/ignite/handlers/model_score.py b/workflow/ignite/handlers/model_score.py deleted file mode 100644 index 71f9f6d..0000000 --- a/workflow/ignite/handlers/model_score.py +++ /dev/null @@ -1,73 +0,0 @@ -import ignite -from ignite.engine import Events -from ignite.contrib.handlers.tensorboard_logger import OutputHandler - -from workflow.ignite.metrics import ReduceMetricsLambda -from workflow.ignite.handlers.early_stopping import EarlyStopping -from workflow.ignite.handlers.model_checkpoint import ModelCheckpoint -from workflow.ignite.handlers.best_model_trigger import BestModelTrigger - - -class ModelScore: - def __init__( - self, - model_score_function, - checkpoint_state, - evaluator_metrics, - tensorboard_logger, - config, - ): - ''' - Model score brings together several handlers related to model score. - - model checkpoint - - early stopping - - tensorboard logging - - best model event - ''' - - self.model_score_function = model_score_function - self.checkpoint_state = checkpoint_state - self.evaluator_metrics = evaluator_metrics - self.tensorboard_logger = tensorboard_logger - self.config = config - - def attach(self, trainer, evaluators): - def _model_score_function(*args, **kwargs): - return self.model_score_function() - - ignite.metrics.MetricsLambda(_model_score_function).attach(trainer, 'model_score') - ReduceMetricsLambda(max, _model_score_function).attach(trainer, 'best_model_score') - - training_desc = 'train' - self.tensorboard_logger.attach( - trainer, - OutputHandler( - tag=training_desc, - metric_names=['model_score', 'best_model_score'], - ), - Events.EPOCH_COMPLETED, - ) - - BestModelTrigger('model_score', evaluators.values()).attach(trainer) - - for evaluator_desc, evaluator in evaluators.items(): - evaluator_metric_names = list( - self.evaluator_metrics[evaluator_desc].keys() - ) - self.tensorboard_logger.attach( - evaluator, - OutputHandler( - tag=f'best-{evaluator_desc}', - metric_names=evaluator_metric_names, - global_step_transform=lambda *args: trainer.state.epoch, - ), - BestModelTrigger.Event, - ) - - ModelCheckpoint(_model_score_function).attach( - trainer, self.checkpoint_state - ) - - EarlyStopping( - _model_score_function, trainer, self.config - ).attach(trainer) diff --git a/workflow/ignite/handlers/progress_bar.py b/workflow/ignite/handlers/progress_bar.py deleted file mode 100644 index ed1a5b4..0000000 --- a/workflow/ignite/handlers/progress_bar.py +++ /dev/null @@ -1,15 +0,0 @@ -import ignite - - -class ProgressBar(ignite.contrib.handlers.tqdm_logger.ProgressBar): - def __init__(self, desc, *args, **kwargs): - kwargs['smoothing'] = kwargs.get('smoothing', .0) - super().__init__( - *args, - **kwargs, - desc=desc, - bar_format=( - '{desc} {percentage:3.0f}%|{bar} {n_fmt}/{total}{postfix} ' - '[{elapsed}<{remaining} {rate_fmt}]' - ), - ) diff --git a/workflow/ignite/metrics/__init__.py b/workflow/ignite/metrics/__init__.py deleted file mode 100644 index 1613d6e..0000000 --- a/workflow/ignite/metrics/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .matthews_correlation_coefficient import MatthewsCorrelationCoefficient -from .reduce_metrics_lambda import ReduceMetricsLambda diff --git a/workflow/ignite/metrics/matthews_correlation_coefficient.py b/workflow/ignite/metrics/matthews_correlation_coefficient.py deleted file mode 100644 index 0b4eca7..0000000 --- a/workflow/ignite/metrics/matthews_correlation_coefficient.py +++ /dev/null @@ -1,29 +0,0 @@ -import torch - -from ignite.metrics import ( - ConfusionMatrix, - MetricsLambda, -) - - -def _matthews_correlation_coefficient(confusion_matrix): - [[tp, fp], [fn, tn]] = confusion_matrix.float() - - if all([ - 0 < tp + fp, - 0 < tp + fn, - 0 < tn + fp, - 0 < tn + fn, - ]): - return ( - (tp * tn - fp * fn) - / torch.sqrt((tp + fp) * (tp + fn) * (tn + fp) * (tn + fn)) - ) - else: - return torch.tensor(0.) - -def MatthewsCorrelationCoefficient(output_transform): - return MetricsLambda( - _matthews_correlation_coefficient, - ConfusionMatrix(num_classes=2, output_transform=output_transform) - ) diff --git a/workflow/ignite/metrics/reduce_metrics_lambda.py b/workflow/ignite/metrics/reduce_metrics_lambda.py deleted file mode 100644 index 9e771f0..0000000 --- a/workflow/ignite/metrics/reduce_metrics_lambda.py +++ /dev/null @@ -1,18 +0,0 @@ -import numpy as np -from ignite.metrics import MetricsLambda - - -class ReduceMetricsLambda(MetricsLambda): - def __init__(self, reduce_fn, f, *args, **kwargs): - super().__init__(f, *args, **kwargs) - self.reduce_fn = reduce_fn - self.reduced_value = None - - def compute(self): - value = super().compute() - if self.reduced_value is None: - self.reduced_value = value - else: - self.reduced_value = self.reduce_fn(self.reduced_value, value) - - return self.reduced_value diff --git a/workflow/ignite/trainer.py b/workflow/ignite/trainer.py deleted file mode 100644 index e023e64..0000000 --- a/workflow/ignite/trainer.py +++ /dev/null @@ -1,134 +0,0 @@ -import ignite -from ignite.engine import Events -from ignite.contrib.handlers.tensorboard_logger import ( - TensorboardLogger, OutputHandler, OptimizerParamsHandler, global_step_from_engine -) - -from workflow.ignite.handlers.epoch_logger import EpochLogger -from workflow.ignite.handlers.metrics_logger import MetricsLogger -from workflow.ignite.handlers.progress_bar import ProgressBar - - -PROGRESS_DESC = 'progress' -TRAIN_DESC = 'train' - - -def trainer( - train_batch, - evaluate_batch, - evaluate_data_loaders, - metrics, - optimizers, -): - ''' - Create standard trainer with evaluators. - - Parameters - ---------- - train_batch : function - function that trains on given batch - evaluate_batch : function - function that evaluates a given batch - evaluate_data_loaders: list - data loaders that yield batches to evaluate on - metrics : dict - dict with one dict each for 'train' and evaluate data loader. Wrap a - metric with trainer.Progress to show in progress bar. - optimizers : dict - dict with optimizers for logging - - Returns - ------- - tuple - trainer engine - list of evaluator engines - tensorboard logger - ''' - - trainer = ignite.engine.Engine(train_batch) - - for name, metric in metrics.get(PROGRESS_DESC, dict()).items(): - metric.attach(trainer, name) - - for name, metric in metrics.get(TRAIN_DESC, dict()).items(): - metric.attach(trainer, name) - - evaluators = { - evaluator_name: ignite.engine.Engine(evaluate_batch) - for evaluator_name in evaluate_data_loaders.keys() - } - - for evaluator_name, evaluator in evaluators.items(): - for metric_name, metric in metrics[evaluator_name].items(): - metric.attach(evaluator, metric_name) - - tensorboard_logger = TensorboardLogger(log_dir='tb') - - EpochLogger().attach(trainer) - - # Order of attaching progress bars is important for vscode / atom - ProgressBar(desc=TRAIN_DESC).attach( - trainer, metric_names=list(metrics.get(PROGRESS_DESC, dict()).keys()) - ) - tensorboard_logger.attach( - trainer, - OutputHandler( - tag=PROGRESS_DESC, - metric_names=list(metrics.get(PROGRESS_DESC, dict()).keys()), - ), - Events.ITERATION_COMPLETED, - ) - - MetricsLogger(TRAIN_DESC).attach( - trainer, metrics.get(TRAIN_DESC, dict()).keys() - ) - tensorboard_logger.attach( - trainer, - OutputHandler( - tag=TRAIN_DESC, - metric_names=list(metrics.get(TRAIN_DESC, dict()).keys()), - ), - Events.ITERATION_COMPLETED, - ) - - - def run_evaluator(evaluator_desc): - return lambda engine: evaluators[evaluator_desc].run( - evaluate_data_loaders[evaluator_desc] - ) - - - for evaluator_desc, evaluator in evaluators.items(): - evaluator_metric_names = list(metrics[evaluator_desc].keys()) - - trainer.add_event_handler( - Events.EPOCH_COMPLETED, run_evaluator(evaluator_desc), - ) - - ProgressBar(desc=evaluator_desc).attach(evaluator) - MetricsLogger(evaluator_desc).attach(evaluator, evaluator_metric_names) - tensorboard_logger.attach( - evaluator, - OutputHandler( - tag=evaluator_desc, - metric_names=evaluator_metric_names, - global_step_transform=global_step_from_engine(trainer), - ), - Events.EPOCH_COMPLETED, - ) - - if type(optimizers) is not dict: - optimizers = dict(optimizer=optimizers) - - for name, optimizer in optimizers.items(): - tensorboard_logger.attach( - trainer, - log_handler=OptimizerParamsHandler( - tag=f'{TRAIN_DESC}/{name}', - param_name='lr', - optimizer=optimizer, - ), - event_name=Events.ITERATION_COMPLETED, - ) - - return trainer, evaluators, tensorboard_logger diff --git a/workflow/json.py b/workflow/json.py deleted file mode 100644 index 4b10ea5..0000000 --- a/workflow/json.py +++ /dev/null @@ -1,11 +0,0 @@ -import json - - -def read(filepath): - with open(filepath, 'r') as file: - return json.load(file) - - -def write(obj, filepath): - with open(filepath, 'w') as file: - return json.dump(obj, file, indent=4) diff --git a/workflow/progress_bar.py b/workflow/progress_bar.py new file mode 100644 index 0000000..7cc7dca --- /dev/null +++ b/workflow/progress_bar.py @@ -0,0 +1,6 @@ +from tqdm import tqdm + + +# TODO +def ProgressBar(data_loader, metrics=None): + return tqdm(data_loader) diff --git a/workflow/setup_project.py b/workflow/setup_project.py index 882dc71..7bb5a17 100644 --- a/workflow/setup_project.py +++ b/workflow/setup_project.py @@ -6,15 +6,14 @@ if __name__ == '__main__': + print(__file__ + '/template') try: repository_path = cookiecutter( - '/'.join(__file__.split('/')[:-5]) + '/workflow/template', - ) - except RepositoryNotFound: - # Probably installed with the -e flag - repository_path = cookiecutter( - '/'.join(__file__.split('/')[:-2]) + '/template', + str(Path(__file__).parent / 'template') ) + except RepositoryNotFound as exception: + print('__file__:', __file__) + raise exception repository_path = Path(repository_path) diff --git a/template/cookiecutter.json b/workflow/template/cookiecutter.json similarity index 100% rename from template/cookiecutter.json rename to workflow/template/cookiecutter.json diff --git a/template/{{cookiecutter.repository_name}}/.github/workflows/publish.yml b/workflow/template/{{cookiecutter.repository_name}}/.github/workflows/publish.yml similarity index 100% rename from template/{{cookiecutter.repository_name}}/.github/workflows/publish.yml rename to workflow/template/{{cookiecutter.repository_name}}/.github/workflows/publish.yml diff --git a/template/{{cookiecutter.repository_name}}/.github/workflows/test.yml b/workflow/template/{{cookiecutter.repository_name}}/.github/workflows/test.yml similarity index 100% rename from template/{{cookiecutter.repository_name}}/.github/workflows/test.yml rename to workflow/template/{{cookiecutter.repository_name}}/.github/workflows/test.yml diff --git a/template/{{cookiecutter.repository_name}}/.gitignore b/workflow/template/{{cookiecutter.repository_name}}/.gitignore similarity index 100% rename from template/{{cookiecutter.repository_name}}/.gitignore rename to workflow/template/{{cookiecutter.repository_name}}/.gitignore diff --git a/template/{{cookiecutter.repository_name}}/README.rst b/workflow/template/{{cookiecutter.repository_name}}/README.rst similarity index 100% rename from template/{{cookiecutter.repository_name}}/README.rst rename to workflow/template/{{cookiecutter.repository_name}}/README.rst diff --git a/template/{{cookiecutter.repository_name}}/guild.yml b/workflow/template/{{cookiecutter.repository_name}}/guild.yml similarity index 100% rename from template/{{cookiecutter.repository_name}}/guild.yml rename to workflow/template/{{cookiecutter.repository_name}}/guild.yml diff --git a/template/{{cookiecutter.repository_name}}/operations/evaluate.py b/workflow/template/{{cookiecutter.repository_name}}/operations/evaluate.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/operations/evaluate.py rename to workflow/template/{{cookiecutter.repository_name}}/operations/evaluate.py diff --git a/template/{{cookiecutter.repository_name}}/operations/prepare.py b/workflow/template/{{cookiecutter.repository_name}}/operations/prepare.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/operations/prepare.py rename to workflow/template/{{cookiecutter.repository_name}}/operations/prepare.py diff --git a/template/{{cookiecutter.repository_name}}/operations/search_lr.py b/workflow/template/{{cookiecutter.repository_name}}/operations/search_lr.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/operations/search_lr.py rename to workflow/template/{{cookiecutter.repository_name}}/operations/search_lr.py diff --git a/template/{{cookiecutter.repository_name}}/operations/train.py b/workflow/template/{{cookiecutter.repository_name}}/operations/train.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/operations/train.py rename to workflow/template/{{cookiecutter.repository_name}}/operations/train.py diff --git a/workflow/template/{{cookiecutter.repository_name}}/pyproject.toml b/workflow/template/{{cookiecutter.repository_name}}/pyproject.toml new file mode 100644 index 0000000..beaa2d1 --- /dev/null +++ b/workflow/template/{{cookiecutter.repository_name}}/pyproject.toml @@ -0,0 +1,24 @@ +[tool.poetry] +name = "{{cookiecutter.repository_name}}" +version = "{{cookiecutter.package_version}}" +description = "{{cookiecutter.package_description}}" +authors = ["Aiwizo AB"] + +[tool.poetry.dependencies] +python = "^3.8" +torch = "^1.6.0" +numpy = "^1.19.2" +torchvision = "^0.8.1" +opencv-python = "^4.4.0" +ml-workflow = "^0.8.2" +pytorch-datastream = "^0.3.8" + +[tool.poetry.dev-dependencies] +guildai = "0.7.1.dev6" +data-kale = "^0.1.3" +pylint = "^2.6.0" +flake8 = "^3.8.4" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/template/{{cookiecutter.repository_name}}/pytest.ini b/workflow/template/{{cookiecutter.repository_name}}/pytest.ini similarity index 100% rename from template/{{cookiecutter.repository_name}}/pytest.ini rename to workflow/template/{{cookiecutter.repository_name}}/pytest.ini diff --git a/template/{{cookiecutter.repository_name}}/setup.cfg b/workflow/template/{{cookiecutter.repository_name}}/setup.cfg similarity index 100% rename from template/{{cookiecutter.repository_name}}/setup.cfg rename to workflow/template/{{cookiecutter.repository_name}}/setup.cfg diff --git a/setup.py b/workflow/template/{{cookiecutter.repository_name}}/setup.py similarity index 100% rename from setup.py rename to workflow/template/{{cookiecutter.repository_name}}/setup.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/__init__.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/__init__.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/__init__.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/__init__.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/__init__.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/__init__.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/__init__.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/__init__.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/feature.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/feature.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/feature.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/feature.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/model.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/model.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/model.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/model.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/prediction.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/prediction.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/prediction.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/architecture/prediction.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/__init__.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/__init__.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/__init__.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/__init__.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/augmenter.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/augmenter.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/augmenter.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/augmenter.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/datasets.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/datasets.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/datasets.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/datasets.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/evaluate_datastreams.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/evaluate_datastreams.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/evaluate_datastreams.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/evaluate_datastreams.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/gradient_datastream.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/gradient_datastream.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/gradient_datastream.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/datastream/gradient_datastream.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/log_examples.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/log_examples.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/log_examples.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/log_examples.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/metrics.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/metrics.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/metrics.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/metrics.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/__init__.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/__init__.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/__init__.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/__init__.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/datasets.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/datasets.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/datasets.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/datasets.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/example.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/example.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/example.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/example.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/settings.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/settings.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/settings.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/problem/settings.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/splits/.gitignore b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/splits/.gitignore similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/splits/.gitignore rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/splits/.gitignore diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/__init__.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/__init__.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/__init__.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/__init__.py diff --git a/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/text_.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/text_.py similarity index 100% rename from template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/text_.py rename to workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/tools/text_.py diff --git a/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/train.py b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/train.py new file mode 100644 index 0000000..6bca6ab --- /dev/null +++ b/workflow/template/{{cookiecutter.repository_name}}/{{cookiecutter.package_name}}/train.py @@ -0,0 +1,107 @@ +from functools import partial +from pathlib import Path +import numpy as np +import random +import argparse +import torch +import torch.nn.functional as F +import ignite +import logging +import workflow +from workflow.functional import starcompose +from workflow.torch import set_seeds +from workflow.ignite import worker_init +from workflow.ignite.handlers.learning_rate import ( + LearningRateScheduler, warmup, cyclical +) +from datastream import Datastream + +from {{cookiecutter.package_name}} import ( + datastream, architecture, metrics, log_examples +) + + +def train(config): + set_seeds(config['seed']) + device = torch.device('cuda' if config['use_cuda'] else 'cpu') + + model = architecture.Model().to(device) + optimizer = torch.optim.Adam( + model.parameters(), lr=config['learning_rate'] + ) + + train_state = dict(model=model, optimizer=optimizer) + + if Path('model').exists(): + print('Loading model checkpoint') + workflow.ignite.handlers.ModelCheckpoint.load( + train_state, 'model/checkpoints', device + ) + workflow.torch.set_learning_rate(optimizer, config['learning_rate']) + + evaluate_data_loaders = { + f'evaluate_{name}': datastream.data_loader( + batch_size=config['eval_batch_size'], + num_workers=config['n_workers'], + collate_fn=tuple, + ) + for name, datastream in datastream.evaluate_datastreams().items() + } + + gradient_data_loader = ( + datastream.GradientDatastream() + .data_loader( + batch_size=config['batch_size'], + num_workers=config['n_workers'], + n_batches_per_epoch=config['n_batches_per_epoch'], + worker_init_fn=partial(worker_init, config['seed'], trainer), + collate_fn=tuple, + ) + ) + + tensorboard_logger = torch.utils.tensorboard.SummaryWriter() + early_stopping = workflow.EarlyStopping() + # gradient_metrics = metrics.gradient_metrics() + + for epoch in tqdm(range(config['max_epochs'])): + + with workflow.torch.module_train(model): + for examples in workflow.ProgressBar( + gradient_data_loader + # gradient_data_loader, metrics=gradient_metrics[['loss']] + ): + predictions = model.predictions( + architecture.FeatureBatch.from_examples(examples) + ) + loss = predictions.loss(examples) + loss.backward() + optimizer.step() + optimizer.zero_grad() + + # gradient_metrics = gradient_metrics.update( + # examples, predictions, loss + # ) + # gradient_metrics.log_() + + # optional: schedule learning rate + + with workflow.torch.module_eval(model), torch.no_grad: + for name, data_loader in evaluate_data_loaders: + # evaluate_metrics = metrics.evaluate_metrics() + + for examples in tqdm(data_loader): + predictions = model.predictions( + architecture.FeatureBatch.from_examples(examples) + ) + loss = predictions.loss(examples) + + # evaluate_metrics = evaluate_metrics.update( + # examples, predictions, loss + # ) + # evaluate_metrics.log_() + + early_stopping = early_stopping.score(tensorboard_logger) + if early_stopping.scores_since_improvement == 0: + torch.save(train_state, 'model_checkpoint.pt') + elif early_stopping.scores_since_improvement > patience: + break diff --git a/workflow/torch/__init__.py b/workflow/torch/__init__.py index 5e5f271..073bb54 100644 --- a/workflow/torch/__init__.py +++ b/workflow/torch/__init__.py @@ -1,7 +1,3 @@ -from workflow.torch.is_float import is_float -from workflow.torch.get_conv_output_size import get_conv_output_size -from workflow.torch.get_model_summary import get_model_summary -from workflow.torch.initialize_weights import initialize_weights from workflow.torch.module_device import module_device from workflow.torch.module_compose import ModuleCompose from workflow.torch.to_device import to_device diff --git a/workflow/ignite/decorators/__init__.py b/workflow/torch/decorators/__init__.py similarity index 100% rename from workflow/ignite/decorators/__init__.py rename to workflow/torch/decorators/__init__.py diff --git a/workflow/ignite/decorators/evaluate.py b/workflow/torch/decorators/evaluate.py similarity index 100% rename from workflow/ignite/decorators/evaluate.py rename to workflow/torch/decorators/evaluate.py diff --git a/workflow/ignite/decorators/step.py b/workflow/torch/decorators/step.py similarity index 100% rename from workflow/ignite/decorators/step.py rename to workflow/torch/decorators/step.py diff --git a/workflow/ignite/decorators/to_device.py b/workflow/torch/decorators/to_device.py similarity index 100% rename from workflow/ignite/decorators/to_device.py rename to workflow/torch/decorators/to_device.py diff --git a/workflow/ignite/decorators/train.py b/workflow/torch/decorators/train.py similarity index 100% rename from workflow/ignite/decorators/train.py rename to workflow/torch/decorators/train.py diff --git a/workflow/ignite/decorators/update_cpu_model.py b/workflow/torch/decorators/update_cpu_model.py similarity index 100% rename from workflow/ignite/decorators/update_cpu_model.py rename to workflow/torch/decorators/update_cpu_model.py diff --git a/workflow/torch/get_conv_output_size.py b/workflow/torch/get_conv_output_size.py deleted file mode 100644 index 24ccd7b..0000000 --- a/workflow/torch/get_conv_output_size.py +++ /dev/null @@ -1,33 +0,0 @@ -import torch.nn as nn - - -def get_conv_output_size(input_size, layers): - size = input_size - for layer in layers: - if type(layer) in [nn.Conv2d, nn.MaxPool2d]: - size = get_layer_output_size( - size, layer.kernel_size, layer.padding, - layer.stride, layer.dilation - ) - return size - - -def get_layer_output_size(input_size, kernel_size, padding, stride, dilation): - if isinstance(kernel_size, int): - kernel_size = (kernel_size, kernel_size) - if isinstance(padding, int): - padding = (padding, padding) - if isinstance(stride, int): - stride = (stride, stride) - if isinstance(dilation, int): - dilation = (dilation, dilation) - return ( - ( - input_size[0] + 2 * padding[0] - - dilation[0] * (kernel_size[0] - 1) - 1 - ) // stride[0] + 1, - ( - input_size[1] + 2 * padding[1] - - dilation[1] * (kernel_size[1] - 1) - 1 - ) // stride[1] + 1, - ) diff --git a/workflow/torch/get_model_summary.py b/workflow/torch/get_model_summary.py deleted file mode 100644 index 283368e..0000000 --- a/workflow/torch/get_model_summary.py +++ /dev/null @@ -1,12 +0,0 @@ -import pandas as pd - - -def get_model_summary(model): - params_summary = pd.DataFrame( - [[n, p.numel()] for n, p in model.named_parameters()], - columns=['name', '# params'] - ) - num_params = params_summary['# params'].sum() - params_summary['# params'] = list(map('{:,}'.format, - params_summary['# params'])) - return params_summary, num_params diff --git a/workflow/torch/initialize_weights.py b/workflow/torch/initialize_weights.py deleted file mode 100644 index 84f2ccf..0000000 --- a/workflow/torch/initialize_weights.py +++ /dev/null @@ -1,14 +0,0 @@ -import torch - - -def initialize_weights(model, init='xavier', keywords=['']): - for name, param in model.named_parameters(): - if ( - 'weight' in name - and any(k in name for k in keywords) - and len(param.shape) > 1 - ): - if init == 'xavier': - torch.nn.init.xavier_normal_(param) - elif init == 'kaiming': - torch.nn.init.kaiming_normal_(param) diff --git a/workflow/torch/is_float.py b/workflow/torch/is_float.py deleted file mode 100644 index 600750a..0000000 --- a/workflow/torch/is_float.py +++ /dev/null @@ -1,9 +0,0 @@ -import numpy as np -import torch - - -def is_float(value): - return type(value) in [ - float, np.float16, np.float32, np.float64, torch.float16, - torch.float32, torch.float64 - ] diff --git a/workflow/ignite/worker_init.py b/workflow/torch/worker_init.py similarity index 100% rename from workflow/ignite/worker_init.py rename to workflow/torch/worker_init.py