├── .gitignore ├── LICENSE ├── README.md └── kfp ├── .gitignore ├── DEPLOYMENT.md ├── README.md ├── components ├── data_generator │ ├── Dockerfile │ ├── README.md │ ├── data_generator.yaml │ ├── poetry.lock │ ├── pyproject.toml │ ├── setup.cfg │ ├── src │ │ ├── __init__.py │ │ └── data_generator.py │ └── tests │ │ ├── __init__.py │ │ └── test_main.py ├── evaluator │ ├── Dockerfile │ ├── README.md │ ├── evaluator.yaml │ ├── poetry.lock │ ├── pyproject.toml │ ├── setup.cfg │ ├── src │ │ ├── __init__.py │ │ └── evaluator.py │ └── tests │ │ ├── __init__.py │ │ └── test_main.py ├── trainer │ ├── Dockerfile │ ├── README.md │ ├── poetry.lock │ ├── pyproject.toml │ ├── setup.cfg │ ├── src │ │ ├── __init__.py │ │ └── trainer.py │ ├── tests │ │ ├── __init__.py │ │ └── test_main.py │ └── trainer.yaml └── transform │ ├── Dockerfile │ ├── README.md │ ├── poetry.lock │ ├── pyproject.toml │ ├── setup.cfg │ ├── src │ ├── __init__.py │ └── transform.py │ ├── tests │ ├── __init__.py │ └── test_main.py │ └── transform.yaml ├── dataflow.png ├── deploy_all_component.sh ├── pipeline.py ├── poetry.lock ├── pyproject.toml └── setup.cfg /.gitignore: -------------------------------------------------------------------------------- 1 | ### https://raw.github.com/github/gitignore/218a941be92679ce67d0484547e3e142b2f5f6f0/Python.gitignore 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | share/python-wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | cover/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | .pybuilder/ 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | # For a library or package, you might want to ignore these files since the code is 89 | # intended to run in multiple environments; otherwise, check them in: 90 | # .python-version 91 | 92 | # pipenv 93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 96 | # install all needed dependencies. 97 | #Pipfile.lock 98 | 99 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 100 | __pypackages__/ 101 | 102 | # Celery stuff 103 | celerybeat-schedule 104 | celerybeat.pid 105 | 106 | # SageMath parsed files 107 | *.sage.py 108 | 109 | # Environments 110 | .env 111 | .venv 112 | env/ 113 | venv/ 114 | ENV/ 115 | env.bak/ 116 | venv.bak/ 117 | 118 | # Spyder project settings 119 | .spyderproject 120 | .spyproject 121 | 122 | # Rope project settings 123 | .ropeproject 124 | 125 | # mkdocs documentation 126 | /site 127 | 128 | # mypy 129 | .mypy_cache/ 130 | .dmypy.json 131 | dmypy.json 132 | 133 | # Pyre type checker 134 | .pyre/ 135 | 136 | # pytype static type analyzer 137 | .pytype/ 138 | 139 | # Cython debug symbols 140 | cython_debug/ 141 | 142 | 143 | ### https://raw.github.com/github/gitignore/218a941be92679ce67d0484547e3e142b2f5f6f0/Global/VisualStudioCode.gitignore 144 | 145 | .vscode/* 146 | !.vscode/settings.json 147 | !.vscode/tasks.json 148 | !.vscode/launch.json 149 | !.vscode/extensions.json 150 | *.code-workspace 151 | 152 | # Local History for Visual Studio Code 153 | .history/ 154 | 155 | 156 | ### https://raw.github.com/github/gitignore/218a941be92679ce67d0484547e3e142b2f5f6f0/Global/macOS.gitignore 157 | 158 | # General 159 | .DS_Store 160 | .AppleDouble 161 | .LSOverride 162 | 163 | # Icon must end with two \r 164 | Icon 165 | 166 | # Thumbnails 167 | ._* 168 | 169 | # Files that might appear in the root of a volume 170 | .DocumentRevisions-V100 171 | .fseventsd 172 | .Spotlight-V100 173 | .TemporaryItems 174 | .Trashes 175 | .VolumeIcon.icns 176 | .com.apple.timemachine.donotpresent 177 | 178 | # Directories potentially created on remote AFP share 179 | .AppleDB 180 | .AppleDesktop 181 | Network Trash Folder 182 | Temporary Items 183 | .apdisk 184 | 185 | 186 | ### https://raw.github.com/github/gitignore/218a941be92679ce67d0484547e3e142b2f5f6f0/Global/Windows.gitignore 187 | 188 | # Windows thumbnail cache files 189 | Thumbs.db 190 | Thumbs.db:encryptable 191 | ehthumbs.db 192 | ehthumbs_vista.db 193 | 194 | # Dump file 195 | *.stackdump 196 | 197 | # Folder config file 198 | [Dd]esktop.ini 199 | 200 | # Recycle Bin used on file shares 201 | $RECYCLE.BIN/ 202 | 203 | # Windows Installer files 204 | *.cab 205 | *.msi 206 | *.msix 207 | *.msm 208 | *.msp 209 | 210 | # Windows shortcuts 211 | *.lnk 212 | 213 | 214 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Repro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Repro Lab Sample Pipelines 2 | 3 | Two simple sample pipelines are introduced on this repo with both KFP SDK and TFX SDK. 4 | 5 | ## KFP SDK 6 | 7 | 8 | 9 | Penguin classification pipeline with KFP SDK. To try to run this pipeline, check [this document](kfp/). 10 | 11 | ## TFX SDK 12 | 13 | - TBD 14 | 15 | ## Future Work 16 | 17 | ### KFP SDK 18 | 19 | - [ ] Add unit test 20 | - [ ] Migrate from `GCSPath` into `Artifact` 21 | - [ ] Pipeline E2E test 22 | - [ ] Add Pusher component 23 | 24 | ### TFX SDK 25 | 26 | - [ ] Add sample example pipeline 😃 27 | -------------------------------------------------------------------------------- /kfp/.gitignore: -------------------------------------------------------------------------------- 1 | /*.json 2 | /*.yaml -------------------------------------------------------------------------------- /kfp/DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | # How to deploy 2 | 3 | ## Pre-requirements 4 | 5 | Followings are required to deploy kfp sample pipeline. 6 | 7 | - Python ^3.8 8 | - poetry 9 | - docker 10 | 11 | It is also required to make a GCP project and enable billing for your project. 12 | 13 | ## Server-side setups 14 | 15 | ### GCS Bucket 16 | 17 | Create GCS Bucket to save kfp sample pipeline's artifacts. For more detail, check [Creating storage buckets](https://cloud.google.com/storage/docs/creating-buckets). 18 | 19 | ### Container Registry 20 | 21 | It is required to setup some container registry to run this kfp sample pipeline. To setup registory, check [GCR documentation](https://cloud.google.com/container-registry/docs/quickstart) or [Artifact Registry documentation](https://cloud.google.com/artifact-registry/docs/quickstarts). 22 | 23 | ### Pipelines 24 | 25 | Before deploy this pipeline to Kubeflow Pipelines or Managed Services such as Vertex AI, we need to setup the pipeline runtime environment. 26 | 27 | To setup Vertex Pipelines, check [Google Cloud configuration guide for Vertex Pipelines](https://cloud.google.com/vertex-ai/docs/pipelines/configure-project). 28 | 29 | To setup Kubeflow Pipelines via AI Platform Pipelines, check [Google Cloud setting up AI Platform Pipelines guide](https://cloud.google.com/ai-platform/pipelines/docs/setting-up). 30 | 31 | To setup Kubeflow Pipelines for your Kubernetes cluster, check [Kubeflow Pipelines install guide](https://www.kubeflow.org/docs/components/pipelines/installation/). 32 | 33 | Note: We need to make some change to IAM permission during the settings. 34 | 35 | ## Client-side setups 36 | 37 | ### Kubeflow Pipelines SDK 38 | 39 | We need to install Kubeflow pipelines SDK to compile pipeline Python dsl into pipeline spec yaml (v1) and json (v2). To install the sdk, `poetry install` at same directory of `pipeline.py`. 40 | 41 | ### Docker Authentication 42 | 43 | To deploy our component container image, it is required to authenticate our local docker. For more detail, check [Authentication methods](https://cloud.google.com/container-registry/docs/advanced-authentication). 44 | 45 | ### Push image to GCR 46 | 47 | All component container image are required to push the container registry. `deploy_all_component.sh` can help to push images. 48 | 49 | First, fill the two variables at first two lines of `deploy_all_component.sh`. 50 | 51 | ```shell 52 | GCP_PROJECT_ID=your-sample-pipeline-project # Enter your GCP Project ID 53 | GCP_GCR_ENDPOINT=us.gcr.io # Enter your GCR endpoint like `asia.gcr.io` 54 | ``` 55 | 56 | Then, we can deploy components as following command. 57 | 58 | ```shell 59 | # chmod +x deploy_all_component.sh 60 | deploy_all_component.sh 61 | ``` 62 | ## Compile 63 | 64 | ### Fill the pipeline DSL 65 | 66 | Kubeflow Pipelines SDK require to GCS bucket as `pipeline_root` parameter of `@kfp.dsl.pipeline` decorator. It is also required to GCP project ID and container registry endpoint to pull the images of components. 67 | 68 | Enter the GCP project ID, container registry endpoint, and GCS bucket in `pipeline.py` 69 | 70 | ```python 71 | GCP_PROJECT_ID = "your-sample-pipeline-project" # Enter your GCP project ID 72 | GCP_GCR_ENDPOINT = "us.gcr.io" # Enter your GCR endpoint 73 | GCP_GCS_PIPELINE_ROOT = "your-bucket-name" # Enter your GCS bucket without gs:// 74 | ``` 75 | 76 | ### Compile pipeline Python dsl 77 | 78 | Run `dsl-compile` to compile the kfp sample pipeline. 79 | 80 | ```shell 81 | dsl-compile --py pipeline.py --output kfp_sample_pipeline.yaml 82 | ``` 83 | 84 | The `dsl-compile` command will execute the pipeline.py to build `kfp_sample_pipeline.yaml` as v1 pipeline spec. In the same time, `kfp.v2.compiler.Compile` compiles same pipeline and generate `kfp_sample_pipeline.json` as v2 pipeline spec. 85 | -------------------------------------------------------------------------------- /kfp/README.md: -------------------------------------------------------------------------------- 1 | # Penguin Classification Pipeline on Kubeflow Pipelines 2 | 3 | Penguin classification pipeline introduces the basics of the KFP SDK v2 programming. It uses almost all of the Kubeflow Pipelines. 4 | 5 | ## How to deploy. 6 | 7 | To deploy kfp sample pipeline, check [this document](DEPLOYMENT.md). 8 | ## Requirements 9 | 10 | Setup followings; 11 | 12 | - Python 3.x (Tested on Python 3.8.10) 13 | - poetry 14 | - Docker (Tested on Docker for mac 3.2.2) 15 | 16 | ## Dataflow 17 | 18 | 19 | 20 | ## Pipeline Parameters 21 | 22 | - Suffix : `str` 23 | - Suffix for preprocessed features. This is used for pseudo "preprocessing". Default value is `_xf`. 24 | 25 | ## Components 26 | 27 | ### Data Generator 28 | 29 | The Data Generator downloads the [processed Palmer Penguins dataset](https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins_processed.csv) and split it into train/eval data. 30 | 31 | #### Input / Output 32 | 33 | Consumes: 34 | 35 | - Nothing 36 | 37 | Emits: 38 | 39 | - Train data 40 | - Eval data 41 | 42 | ### Transform 43 | 44 | The Transform pre processes train/eval data. Because this pipelines consumes already preprocessed data, this component simply add suffix for each column name. Default suffix is `_xf`. 45 | 46 | #### Input / Output 47 | 48 | Consumes: 49 | 50 | - Train data 51 | - Eval data 52 | - Suffix 53 | 54 | Emits: 55 | 56 | - Preprocessed train data 57 | - Preprocessed eval data 58 | 59 | ### Trainer 60 | 61 | The Trainer trains the ML model using the dataset from the Transform. ML model is based on scikit-learn model. 62 | 63 | Consumes: 64 | 65 | - Preprocessed train data 66 | - Suffix 67 | 68 | Emits: 69 | 70 | - Trained model 71 | 72 | ### Evaluator 73 | 74 | Evaluator evaluates the trained model by eval dataset. Evaluator use accuracy for the metric of the trained model and confusion matrix for visualization. 75 | 76 | Consumes: 77 | 78 | - Trained model 79 | - Preprocessed eval dataset 80 | - Suffix 81 | 82 | Emits: 83 | 84 | - Accuracy 85 | - Confusion matrix 86 | -------------------------------------------------------------------------------- /kfp/components/data_generator/Dockerfile: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # KUBEFLOW PIPELINE COMPONENT CONTAINER BUILD SCRIPT v1.1 3 | # (c) Repro Inc. 4 | # ------------------------------------------------------------------------------ 5 | 6 | # 7 | # BUILD BASE IMAGE (USED IN BOTH OF TEST/PROD) 8 | # ------------------------------------------------------------------------------ 9 | FROM amd64/python:3.9.12-slim-bullseye AS build_base 10 | 11 | # install dependent packages 12 | RUN apt-get -y update && apt-get install -y --no-install-recommends \ 13 | # for install 14 | curl \ 15 | && apt-get clean \ 16 | && rm -rf /var/lib/apt/lists/* 17 | 18 | # install poetry 19 | WORKDIR /home 20 | ENV HOME /home 21 | RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python 22 | ENV PATH $PATH:/home/.poetry/bin 23 | RUN poetry config virtualenvs.create false 24 | 25 | # specify working directory and install dependency files 26 | # without dev dependencies (they are required only on testing.) 27 | WORKDIR /component 28 | COPY pyproject.toml poetry.lock* ./ 29 | RUN poetry install --no-dev 30 | 31 | # copy base source code and add path into PYTHONPATH 32 | ENV PYTHONPATH $PYTHONPATH:/component/src 33 | 34 | # to utilize the cache system in docker, copying srcs has been moved to 35 | # subsequent stages instead of do it in here. 36 | 37 | # 38 | # BUILD AND EXECUTE UNIT TEST 39 | # ------------------------------------------------------------------------------ 40 | FROM build_base AS test_runner 41 | 42 | # install full dependencies (includes dev-dependencies) 43 | RUN poetry install 44 | 45 | # copy test directory and run test 46 | COPY src/ src/ 47 | COPY tests/ tests/ 48 | 49 | # run unit tests 50 | RUN poetry run pytest 51 | 52 | # 53 | # BUILD PRODUCTION IMAGE 54 | # ------------------------------------------------------------------------------ 55 | FROM build_base AS production 56 | 57 | # apply the cache system, copy codes 58 | COPY src/ src/ 59 | -------------------------------------------------------------------------------- /kfp/components/data_generator/README.md: -------------------------------------------------------------------------------- 1 | # Data Generator 2 | 3 | The Data Generator component downloads [processed Palmer Penguins dataset](https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins_processed.csv) and save it for other components. Downloaded data is managed by MLMD (ML Metadata) for each run of pipeline. 4 | 5 | ## Runtime Inputs and Returns 6 | 7 | - Inputs: 8 | - N/A 9 | - Outputs: 10 | - train_data_path [str]: Path to saved train data. 11 | - eval_data_path [str]: Path to saved eval data. 12 | - Metrics 13 | - N/A 14 | 15 | ## Files 16 | 17 | ```console 18 | $ tree . 19 | . 20 | ├── Dockerfile -- to generate the container image of the component 21 | ├── README.md -- this file 22 | ├── pyproject.toml -- describing project properies and dependencies used by poetry 23 | ├── src -- component source code 24 | └── tests -- test code 25 | ``` 26 | 27 | ## Pre-requirements 28 | 29 | - Python ^3.9 30 | - poetry 31 | - Docker 32 | 33 | We also use GCR as a docker registry. It is required to set up GCR and it's registration. See [documentation of GCR](https://cloud.google.com/container-registry/docs/quickstart). 34 | 35 | ## Install 36 | 37 | We can start to develop components by `poetry install`. 38 | 39 | ## Test 40 | 41 | For testing framework, we hire [pytest](https://docs.pytest.org/en/6.2.x/). We can test this component by `poetry run pytest`. 42 | 43 | ## Run locally 44 | 45 | ``` 46 | poetry run python src/data_generator.py ./tmp/train.csv ./tmp/eval.csv 47 | ``` 48 | 49 | ## Build dockerfile 50 | 51 | To build a container image with same version described in `pyproject.toml`, use following; 52 | 53 | ```shell 54 | docker build --platform amd64 --target production -t $(awk -F'[ ="]+' '$1 == "name" { print $2 }' pyproject.toml | sed 's/_/-/g'):latest . 55 | ``` 56 | 57 | ## Run docker 58 | 59 | ```shell 60 | docker run kfp-sample-data-generator poetry run python src/data_generator.py ./tmp/train.csv ./tmp/eval.csv 61 | ``` 62 | 63 | ## Deploy to GCR 64 | 65 | First set your GCP project ID and GCR endpoint. 66 | 67 | ```shell 68 | GCP_PROJECT_ID= # Enter your GCP Project ID 69 | GCP_GCR_ENDPOINT= # Enter your GCR endpoint like `asia.gcr.io` 70 | ``` 71 | 72 | Then run the following commands. 73 | 74 | ```shell 75 | IMAGE_NAME=$(awk -F'[ ="]+' '$1 == "name" { print $2 }' pyproject.toml | sed 's/_/-/g') 76 | IMAGE_VERSION_TAG=v$(awk -F'[ ="]+' '$1 == "version" { print $2 }' pyproject.toml) 77 | GCR_IMAGE_NAME_VERSIONED=${GCP_GCR_ENDPOINT}/${GCP_PROJECT_ID}/${IMAGE_NAME}:${IMAGE_VERSION_TAG} 78 | docker tag ${IMAGE_NAME}:latest ${GCR_IMAGE_NAME_VERSIONED} 79 | docker push ${GCR_IMAGE_NAME_VERSIONED} 80 | ``` 81 | 82 | If fails, check followings; 83 | 84 | - Check your default project with `gcloud project list` 85 | - Ensure `gcloud auth configure-docker` has been executed 86 | -------------------------------------------------------------------------------- /kfp/components/data_generator/data_generator.yaml: -------------------------------------------------------------------------------- 1 | name: data_generator 2 | outputs: 3 | - {name: train_data_path, type: {GCSPath: {data_type: CSV}}} 4 | - {name: eval_data_path, type: {GCSPath: {data_type: CSV}}} 5 | implementation: 6 | container: 7 | image: ${tagged_name} 8 | command: 9 | - poetry 10 | - run 11 | - python 12 | - /component/src/data_generator.py 13 | args: 14 | - { outputPath: train_data_path } 15 | - { outputPath: eval_data_path } 16 | -------------------------------------------------------------------------------- /kfp/components/data_generator/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "kfp_sample_data_generator" 3 | version = "0.0.2" 4 | description = "data-generator component of kfp sample pipeline" 5 | authors = ["Repro AI Lab Team "] 6 | license = "MIT" 7 | 8 | [tool.poetry.dependencies] 9 | python = "~3.9.0" 10 | pip = "*" 11 | numpy = "^1.22.3" 12 | scikit-learn = "^1.0.0" 13 | 14 | [tool.poetry.dev-dependencies] 15 | pydocstyle = "*" 16 | bandit = "*" 17 | prospector = "*" 18 | mypy = "*" 19 | pytest = "*" 20 | black = { version = "*", allow-prereleases = true } 21 | 22 | [build-system] 23 | requires = ["poetry>=0.12"] 24 | build-backend = "poetry.masonry.api" -------------------------------------------------------------------------------- /kfp/components/data_generator/setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501 3 | 4 | [mypy] 5 | ignore_missing_imports = true 6 | -------------------------------------------------------------------------------- /kfp/components/data_generator/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AseiSugiyama/lab_sample_pipelines/bff27728c15cbd29351b4970da312278409220de/kfp/components/data_generator/src/__init__.py -------------------------------------------------------------------------------- /kfp/components/data_generator/src/data_generator.py: -------------------------------------------------------------------------------- 1 | """Data Generator implementation.""" 2 | 3 | import argparse 4 | from dataclasses import dataclass 5 | from typing import IO, Tuple, get_type_hints 6 | from urllib import request 7 | from pathlib import Path 8 | 9 | import numpy as np 10 | from sklearn.model_selection import train_test_split 11 | 12 | PENGUIN_DATASET_URI = "https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins_processed.csv" 13 | TARGET = "species" 14 | 15 | 16 | # 17 | # COMPONENT ARGUMENTS 18 | # ------------------------------------------------------------------------------ 19 | 20 | 21 | @dataclass 22 | class ComponentArguments: 23 | """Argument of the component. Note: Data Generator has no inputs.""" 24 | 25 | 26 | @dataclass 27 | class OutputDestinations: 28 | """Outputs of the component.""" 29 | 30 | train_data_path: str 31 | eval_data_path: str 32 | 33 | 34 | @dataclass 35 | class Artifacts: 36 | component_arguments: ComponentArguments 37 | output_destinations: OutputDestinations 38 | 39 | @classmethod 40 | def arg_parser(cls) -> argparse.ArgumentParser: 41 | """Parse component argument and return as ComponentArguments.""" 42 | parser = argparse.ArgumentParser() 43 | # generate argument parser based on ComponentArgument's definition 44 | for artifact in get_type_hints(cls).values(): 45 | for arg_name, arg_type in get_type_hints(artifact).items(): 46 | parser.add_argument(arg_name, type=arg_type) 47 | 48 | return parser 49 | 50 | @classmethod 51 | def from_args(cls) -> "Artifacts": 52 | args = vars(cls.arg_parser().parse_args()) 53 | 54 | artifacts = {} 55 | for key, artifact_cls in get_type_hints(cls).items(): 56 | existed_keys = get_type_hints(artifact_cls).keys() 57 | filtered_vars = {k: v for k, v in args.items() if k in existed_keys} 58 | 59 | artifacts[key] = artifact_cls(**filtered_vars) 60 | # parse args and convert into PipelineArguments 61 | return cls(**artifacts) 62 | 63 | 64 | # 65 | # MAIN FUNCTION 66 | # ------------------------------------------------------------------------------ 67 | 68 | 69 | def fetch_dataset(source: IO) -> np.ndarray: 70 | data = np.genfromtxt(source, names=True, delimiter=",") 71 | 72 | if TARGET not in data.dtype.names: 73 | raise IndexError(f"{TARGET} is not in column names as {data.dtype.names}") 74 | 75 | types = [ 76 | (name, " Tuple[np.ndarray, np.ndarray]: 83 | with request.urlopen(PENGUIN_DATASET_URI) as f: 84 | data = fetch_dataset(f) 85 | # train-test split 86 | train_data, eval_data = train_test_split(data, test_size=0.2, random_state=42) 87 | return train_data, eval_data 88 | 89 | 90 | # 91 | # SUB FUNCTIONS 92 | # ------------------------------------------------------------------------------ 93 | 94 | 95 | def write_csv(destination: str, data: np.ndarray): 96 | if data.dtype.names: 97 | header = ",".join((name for name in data.dtype.names)) 98 | else: 99 | raise ValueError("Column names are missing") 100 | path = Path(destination) 101 | path.parent.mkdir(exist_ok=True, parents=True) 102 | np.savetxt(path, data, delimiter=",", header=header, comments="") 103 | 104 | 105 | # 106 | # ENTRY POINT 107 | # ------------------------------------------------------------------------------ 108 | 109 | if __name__ == "__main__": 110 | artifacts = Artifacts.from_args() 111 | 112 | train_data, eval_data = main(artifacts.component_arguments) 113 | 114 | # Write output. 115 | # When pipeline runs, runtime gives path to save dir for each outputPath 116 | # placeholder. For more detail, see 117 | # https://cloud.google.com/vertex-ai/docs/pipelines/build-pipeline#compare 118 | write_csv(artifacts.output_destinations.train_data_path, train_data) 119 | write_csv(artifacts.output_destinations.eval_data_path, eval_data) 120 | -------------------------------------------------------------------------------- /kfp/components/data_generator/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AseiSugiyama/lab_sample_pipelines/bff27728c15cbd29351b4970da312278409220de/kfp/components/data_generator/tests/__init__.py -------------------------------------------------------------------------------- /kfp/components/data_generator/tests/test_main.py: -------------------------------------------------------------------------------- 1 | from src import data_generator 2 | from io import StringIO 3 | 4 | import numpy as np 5 | import pytest 6 | 7 | 8 | class TestFetchDataset: 9 | def test_fetch_dataset_from_right_formatted_data(self): 10 | source = StringIO( 11 | "species,culmen_length_mm,culmen_depth_mm,flipper_length_mm,body_mass_g\n" 12 | "0,0.2545454545454545,0.6666666666666666,0.15254237288135594,0.2916666666666667" 13 | ) 14 | actual = data_generator.fetch_dataset(source) 15 | assert actual.dtype.names == ( 16 | "species", 17 | "culmen_length_mm", 18 | "culmen_depth_mm", 19 | "flipper_length_mm", 20 | "body_mass_g", 21 | ) 22 | assert actual["species"].dtype == np.int64 23 | assert actual["culmen_length_mm"].dtype == np.float64 24 | 25 | def test_fetch_dataset_fails_file_without_header(self): 26 | source = StringIO( 27 | "0,1\n" 28 | "0,1" 29 | ) 30 | with pytest.raises(IndexError): 31 | data_generator.fetch_dataset(source) 32 | -------------------------------------------------------------------------------- /kfp/components/evaluator/Dockerfile: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # KUBEFLOW PIPELINE COMPONENT CONTAINER BUILD SCRIPT v1.1 3 | # (c) Repro Inc. 4 | # ------------------------------------------------------------------------------ 5 | 6 | # 7 | # BUILD BASE IMAGE (USED IN BOTH OF TEST/PROD) 8 | # ------------------------------------------------------------------------------ 9 | FROM amd64/python:3.9.12-slim-bullseye AS build_base 10 | 11 | # install dependent packages 12 | RUN apt-get -y update && apt-get install -y --no-install-recommends \ 13 | # for install 14 | curl \ 15 | && apt-get clean \ 16 | && rm -rf /var/lib/apt/lists/* 17 | 18 | # install poetry 19 | WORKDIR /home 20 | ENV HOME /home 21 | RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python 22 | ENV PATH $PATH:/home/.poetry/bin 23 | RUN poetry config virtualenvs.create false 24 | 25 | # specify working directory and install dependency files 26 | # without dev dependencies (they are required only on testing.) 27 | WORKDIR /component 28 | COPY pyproject.toml poetry.lock* ./ 29 | RUN poetry install --no-dev 30 | 31 | # copy base source code and add path into PYTHONPATH 32 | ENV PYTHONPATH $PYTHONPATH:/component/src 33 | 34 | # to utilize the cache system in docker, copying srcs has been moved to 35 | # subsequent stages instead of do it in here. 36 | 37 | # 38 | # BUILD AND EXECUTE UNIT TEST 39 | # ------------------------------------------------------------------------------ 40 | FROM build_base AS test_runner 41 | 42 | # install full dependencies (includes dev-dependencies) 43 | RUN poetry install 44 | 45 | # copy test directory and run test 46 | COPY src/ src/ 47 | COPY tests/ tests/ 48 | 49 | # run unit tests 50 | RUN poetry run pytest 51 | 52 | # 53 | # BUILD PRODUCTION IMAGE 54 | # ------------------------------------------------------------------------------ 55 | FROM build_base AS production 56 | 57 | # apply the cache system, copy codes 58 | COPY src/ src/ 59 | -------------------------------------------------------------------------------- /kfp/components/evaluator/README.md: -------------------------------------------------------------------------------- 1 | # Evaluator 2 | 3 | The Evaluator component calculates accuracy as a score of the trained model and make a confusion matrix for visualization. 4 | 5 | ## Runtime Inputs and Returns 6 | 7 | - Inputs: 8 | - transformed_eval_data_path [str]: Path to saved train data. 9 | - trained_model_path [str]: Path to trained model. 10 | - suffix [str]: Suffix to add each column name. 11 | - Outputs: 12 | - confusion_matrix_path [str]: Path to save a confusion matrix (PNG). 13 | - Metrics 14 | - mlpipeline_metrics [float]: Accuracy score. 15 | 16 | ## Files 17 | 18 | ```console 19 | $ tree . 20 | . 21 | ├── Dockerfile -- to generate the container image of the component 22 | ├── README.md -- this file 23 | ├── pyproject.toml -- describing project properies and dependencies used by poetry 24 | ├── src -- component source code 25 | └── tests -- test code 26 | ``` 27 | 28 | ## Pre-requirements 29 | 30 | - Python ^3.9 31 | - poetry 32 | - Docker 33 | 34 | We also use GCR as a docker registry. It is required to set up GCR and it's registration. See [documentation of GCR](https://cloud.google.com/container-registry/docs/quickstart). 35 | 36 | ## Install 37 | 38 | We can start to develop components by `poetry install`. 39 | 40 | ## Test 41 | 42 | For testing framework, we hire [pytest](https://docs.pytest.org/en/6.2.x/). We can test this component by `poetry run pytest`. 43 | 44 | ## Run locally 45 | 46 | ```shell 47 | poetry run python src/evaluator.py \ 48 | ./tmp/model.pkl \ 49 | ./tmp/eval_xf.csv \ 50 | "_xf" \ 51 | ./tmp/confusion_matrix.png \ 52 | ./tmp/mlpipeline-metrics.json 53 | ``` 54 | 55 | ## Build dockerfile 56 | 57 | To build a container image with same version described in `pyproject.toml`, use following; 58 | 59 | ```shell 60 | docker build --platform amd64 --target production -t $(awk -F'[ ="]+' '$1 == "name" { print $2 }' pyproject.toml | sed 's/_/-/g'):latest . 61 | ``` 62 | 63 | ## Run docker 64 | 65 | ```shell 66 | docker run \ 67 | --mount type=bind,source="$(pwd)"/tmp,target=/component/tmp \ 68 | kfp-sample-evaluator \ 69 | poetry run python src/evaluator.py \ 70 | ./tmp/model.pkl \ 71 | ./tmp/eval_xf.csv \ 72 | "_xf" \ 73 | ./tmp/confusion_matrix.png \ 74 | ./tmp/mlpipeline-metrics.json 75 | ``` 76 | 77 | ## Deploy to GCR 78 | 79 | First set your GCP project ID and GCR endpoint. 80 | 81 | ```shell 82 | GCP_PROJECT_ID= # Enter your GCP Project ID 83 | GCP_GCR_ENDPOINT= # Enter your GCR endpoint like `asia.gcr.io` 84 | ``` 85 | 86 | Then run the following commands. 87 | 88 | ```shell 89 | IMAGE_NAME=$(awk -F'[ ="]+' '$1 == "name" { print $2 }' pyproject.toml | sed 's/_/-/g') 90 | IMAGE_VERSION_TAG=v$(awk -F'[ ="]+' '$1 == "version" { print $2 }' pyproject.toml) 91 | GCR_IMAGE_NAME_VERSIONED=${GCP_GCR_ENDPOINT}/${GCP_PROJECT_ID}/${IMAGE_NAME}:${IMAGE_VERSION_TAG} 92 | docker tag ${IMAGE_NAME}:latest ${GCR_IMAGE_NAME_VERSIONED} 93 | docker push ${GCR_IMAGE_NAME_VERSIONED} 94 | ``` 95 | 96 | If fails, check followings; 97 | 98 | - Check your default project with `gcloud project list` 99 | - Ensure `gcloud auth configure-docker` has been executed 100 | -------------------------------------------------------------------------------- /kfp/components/evaluator/evaluator.yaml: -------------------------------------------------------------------------------- 1 | name: evaluator 2 | inputs: 3 | - {name: trained_model_path, type: {GCSPath: {data_type: PKL}}} 4 | - {name: transformed_eval_data_path, type: {GCSPath: {data_type: CSV}}} 5 | - {name: suffix, type: String} 6 | outputs: 7 | - {name: confusion_matrix_path, type: {GCSPath: {data_type: PNG}}} 8 | - {name: mlpipeline_metrics, type: Metrics} 9 | implementation: 10 | container: 11 | image: ${tagged_name} 12 | command: 13 | - poetry 14 | - run 15 | - python 16 | - /component/src/evaluator.py 17 | args: 18 | - {inputPath: trained_model_path} 19 | - {inputPath: transformed_eval_data_path} 20 | - {inputValue: suffix} 21 | - {outputPath: confusion_matrix_path} 22 | - {outputPath: mlpipeline_metrics} 23 | -------------------------------------------------------------------------------- /kfp/components/evaluator/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "kfp_sample_evaluator" 3 | version = "0.0.2" 4 | description = "evaluator component of kfp sample pipeline" 5 | authors = ["Repro AI Lab Team "] 6 | license = "MIT" 7 | 8 | [tool.poetry.dependencies] 9 | python = "~3.9.0" 10 | pip = "*" 11 | numpy = "^1.22.3" 12 | scikit-learn = "^1.0.0" 13 | matplotlib = "^3.4.2" 14 | 15 | [tool.poetry.dev-dependencies] 16 | pydocstyle = "*" 17 | bandit = "*" 18 | prospector = "*" 19 | mypy = "*" 20 | pytest = "*" 21 | black = { version = "*", allow-prereleases = true } 22 | 23 | [build-system] 24 | requires = ["poetry>=0.12"] 25 | build-backend = "poetry.masonry.api" -------------------------------------------------------------------------------- /kfp/components/evaluator/setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501 3 | 4 | [mypy] 5 | ignore_missing_imports = true 6 | -------------------------------------------------------------------------------- /kfp/components/evaluator/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AseiSugiyama/lab_sample_pipelines/bff27728c15cbd29351b4970da312278409220de/kfp/components/evaluator/src/__init__.py -------------------------------------------------------------------------------- /kfp/components/evaluator/src/evaluator.py: -------------------------------------------------------------------------------- 1 | """Data Generator implementation.""" 2 | 3 | import argparse 4 | import json 5 | import pickle 6 | from dataclasses import dataclass 7 | from pathlib import Path 8 | from typing import IO, Optional, Protocol, Tuple, get_type_hints 9 | from matplotlib import pyplot as plt 10 | 11 | import numpy as np 12 | from sklearn.base import BaseEstimator 13 | from sklearn.metrics import ConfusionMatrixDisplay 14 | 15 | 16 | TARGET = "species" 17 | 18 | 19 | class Scorable(Protocol): 20 | def score( 21 | self: BaseEstimator, 22 | X: np.ndarray, 23 | y: np.ndarray, 24 | sample_weight: Optional[np.ndarray] = None, 25 | ) -> float: 26 | ... 27 | 28 | 29 | # 30 | # COMPONENT ARGUMENTS 31 | # ------------------------------------------------------------------------------ 32 | 33 | 34 | @dataclass 35 | class ComponentArguments: 36 | """Argument of the component. Note: Data Generator has no inputs.""" 37 | 38 | trained_model_path: str 39 | transformed_eval_data_path: str 40 | suffix: str 41 | 42 | 43 | @dataclass 44 | class OutputDestinations: 45 | """Outputs of the component.""" 46 | 47 | confusion_matrix_path: str 48 | mlpipeline_metrics: str 49 | 50 | 51 | @dataclass 52 | class Artifacts: 53 | component_arguments: ComponentArguments 54 | output_destinations: OutputDestinations 55 | 56 | @classmethod 57 | def arg_parser(cls) -> argparse.ArgumentParser: 58 | """Parse component argument and return as ComponentArguments.""" 59 | parser = argparse.ArgumentParser() 60 | # generate argument parser based on ComponentArgument's definition 61 | for artifact in get_type_hints(cls).values(): 62 | for arg_name, arg_type in get_type_hints(artifact).items(): 63 | parser.add_argument(arg_name, type=arg_type) 64 | 65 | return parser 66 | 67 | @classmethod 68 | def from_args(cls) -> "Artifacts": 69 | args = vars(cls.arg_parser().parse_args()) 70 | 71 | artifacts = {} 72 | for key, artifact_cls in get_type_hints(cls).items(): 73 | existed_keys = get_type_hints(artifact_cls).keys() 74 | filtered_vars = {k: v for k, v in args.items() if k in existed_keys} 75 | 76 | artifacts[key] = artifact_cls(**filtered_vars) 77 | # parse args and convert into PipelineArguments 78 | return cls(**artifacts) 79 | 80 | 81 | # 82 | # MAIN FUNCTION 83 | # ------------------------------------------------------------------------------ 84 | 85 | 86 | def main(args: ComponentArguments) -> Tuple[ConfusionMatrixDisplay, float]: 87 | label_key = TARGET + args.suffix 88 | model = load_model(args.trained_model_path) 89 | 90 | with Path(args.transformed_eval_data_path).open() as f: 91 | data = load_dataset(f, label_key) 92 | 93 | if data.dtype.names is None: 94 | raise ValueError("Column names are missing") 95 | else: 96 | keys = data.dtype.names 97 | 98 | feature_keys = [key for key in keys if key != label_key] 99 | x_eval = data[feature_keys].tolist() 100 | y_eval = data[label_key] 101 | 102 | score = model.score(x_eval, y_eval) 103 | matrix = ConfusionMatrixDisplay.from_estimator( 104 | model, x_eval, y_eval, cmap=plt.cm.Blues, normalize="true" 105 | ) 106 | 107 | return matrix, score 108 | 109 | 110 | # 111 | # SUB FUNCTIONS 112 | # ------------------------------------------------------------------------------ 113 | 114 | 115 | def load_model(model_path: str) -> Scorable: 116 | with Path(model_path).open("rb") as f: 117 | model = pickle.load(f) 118 | return model 119 | 120 | 121 | def load_dataset(source: IO, label_key: str) -> np.ndarray: 122 | data = np.genfromtxt(source, names=True, delimiter=",") 123 | 124 | if label_key not in data.dtype.names: 125 | raise IndexError(f"{label_key} is not in column names as {data.dtype.names}") 126 | 127 | types = [ 128 | (name, "=3.10", markers = "python_version < \"3.10\""} 12 | wrapt = ">=1.11,<2" 13 | 14 | [[package]] 15 | name = "atomicwrites" 16 | version = "1.4.0" 17 | description = "Atomic file writes." 18 | category = "dev" 19 | optional = false 20 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 21 | 22 | [[package]] 23 | name = "attrs" 24 | version = "21.4.0" 25 | description = "Classes Without Boilerplate" 26 | category = "dev" 27 | optional = false 28 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 29 | 30 | [package.extras] 31 | dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] 32 | docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] 33 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] 34 | tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] 35 | 36 | [[package]] 37 | name = "bandit" 38 | version = "1.7.4" 39 | description = "Security oriented static analyser for python code." 40 | category = "dev" 41 | optional = false 42 | python-versions = ">=3.7" 43 | 44 | [package.dependencies] 45 | colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} 46 | GitPython = ">=1.0.1" 47 | PyYAML = ">=5.3.1" 48 | stevedore = ">=1.20.0" 49 | 50 | [package.extras] 51 | test = ["coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml", "beautifulsoup4 (>=4.8.0)", "pylint (==1.9.4)"] 52 | toml = ["toml"] 53 | yaml = ["pyyaml"] 54 | 55 | [[package]] 56 | name = "black" 57 | version = "22.3.0" 58 | description = "The uncompromising code formatter." 59 | category = "dev" 60 | optional = false 61 | python-versions = ">=3.6.2" 62 | 63 | [package.dependencies] 64 | click = ">=8.0.0" 65 | mypy-extensions = ">=0.4.3" 66 | pathspec = ">=0.9.0" 67 | platformdirs = ">=2" 68 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 69 | typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} 70 | 71 | [package.extras] 72 | colorama = ["colorama (>=0.4.3)"] 73 | d = ["aiohttp (>=3.7.4)"] 74 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] 75 | uvloop = ["uvloop (>=0.15.2)"] 76 | 77 | [[package]] 78 | name = "click" 79 | version = "8.1.2" 80 | description = "Composable command line interface toolkit" 81 | category = "dev" 82 | optional = false 83 | python-versions = ">=3.7" 84 | 85 | [package.dependencies] 86 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 87 | 88 | [[package]] 89 | name = "colorama" 90 | version = "0.4.4" 91 | description = "Cross-platform colored terminal text." 92 | category = "dev" 93 | optional = false 94 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 95 | 96 | [[package]] 97 | name = "dill" 98 | version = "0.3.4" 99 | description = "serialize all of python" 100 | category = "dev" 101 | optional = false 102 | python-versions = ">=2.7, !=3.0.*" 103 | 104 | [package.extras] 105 | graph = ["objgraph (>=1.7.2)"] 106 | 107 | [[package]] 108 | name = "dodgy" 109 | version = "0.2.1" 110 | description = "Dodgy: Searches for dodgy looking lines in Python code" 111 | category = "dev" 112 | optional = false 113 | python-versions = "*" 114 | 115 | [[package]] 116 | name = "flake8" 117 | version = "4.0.1" 118 | description = "the modular source code checker: pep8 pyflakes and co" 119 | category = "dev" 120 | optional = false 121 | python-versions = ">=3.6" 122 | 123 | [package.dependencies] 124 | mccabe = ">=0.6.0,<0.7.0" 125 | pycodestyle = ">=2.8.0,<2.9.0" 126 | pyflakes = ">=2.4.0,<2.5.0" 127 | 128 | [[package]] 129 | name = "flake8-polyfill" 130 | version = "1.0.2" 131 | description = "Polyfill package for Flake8 plugins" 132 | category = "dev" 133 | optional = false 134 | python-versions = "*" 135 | 136 | [package.dependencies] 137 | flake8 = "*" 138 | 139 | [[package]] 140 | name = "gitdb" 141 | version = "4.0.9" 142 | description = "Git Object Database" 143 | category = "dev" 144 | optional = false 145 | python-versions = ">=3.6" 146 | 147 | [package.dependencies] 148 | smmap = ">=3.0.1,<6" 149 | 150 | [[package]] 151 | name = "gitpython" 152 | version = "3.1.27" 153 | description = "GitPython is a python library used to interact with Git repositories" 154 | category = "dev" 155 | optional = false 156 | python-versions = ">=3.7" 157 | 158 | [package.dependencies] 159 | gitdb = ">=4.0.1,<5" 160 | 161 | [[package]] 162 | name = "iniconfig" 163 | version = "1.1.1" 164 | description = "iniconfig: brain-dead simple config-ini parsing" 165 | category = "dev" 166 | optional = false 167 | python-versions = "*" 168 | 169 | [[package]] 170 | name = "isort" 171 | version = "5.10.1" 172 | description = "A Python utility / library to sort Python imports." 173 | category = "dev" 174 | optional = false 175 | python-versions = ">=3.6.1,<4.0" 176 | 177 | [package.extras] 178 | pipfile_deprecated_finder = ["pipreqs", "requirementslib"] 179 | requirements_deprecated_finder = ["pipreqs", "pip-api"] 180 | colors = ["colorama (>=0.4.3,<0.5.0)"] 181 | plugins = ["setuptools"] 182 | 183 | [[package]] 184 | name = "joblib" 185 | version = "1.1.0" 186 | description = "Lightweight pipelining with Python functions" 187 | category = "main" 188 | optional = false 189 | python-versions = ">=3.6" 190 | 191 | [[package]] 192 | name = "lazy-object-proxy" 193 | version = "1.7.1" 194 | description = "A fast and thorough lazy object proxy." 195 | category = "dev" 196 | optional = false 197 | python-versions = ">=3.6" 198 | 199 | [[package]] 200 | name = "mccabe" 201 | version = "0.6.1" 202 | description = "McCabe checker, plugin for flake8" 203 | category = "dev" 204 | optional = false 205 | python-versions = "*" 206 | 207 | [[package]] 208 | name = "mypy" 209 | version = "0.942" 210 | description = "Optional static typing for Python" 211 | category = "dev" 212 | optional = false 213 | python-versions = ">=3.6" 214 | 215 | [package.dependencies] 216 | mypy-extensions = ">=0.4.3" 217 | tomli = ">=1.1.0" 218 | typing-extensions = ">=3.10" 219 | 220 | [package.extras] 221 | dmypy = ["psutil (>=4.0)"] 222 | python2 = ["typed-ast (>=1.4.0,<2)"] 223 | reports = ["lxml"] 224 | 225 | [[package]] 226 | name = "mypy-extensions" 227 | version = "0.4.3" 228 | description = "Experimental type system extensions for programs checked with the mypy typechecker." 229 | category = "dev" 230 | optional = false 231 | python-versions = "*" 232 | 233 | [[package]] 234 | name = "numpy" 235 | version = "1.22.3" 236 | description = "NumPy is the fundamental package for array computing with Python." 237 | category = "main" 238 | optional = false 239 | python-versions = ">=3.8" 240 | 241 | [[package]] 242 | name = "packaging" 243 | version = "21.3" 244 | description = "Core utilities for Python packages" 245 | category = "dev" 246 | optional = false 247 | python-versions = ">=3.6" 248 | 249 | [package.dependencies] 250 | pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" 251 | 252 | [[package]] 253 | name = "pathspec" 254 | version = "0.9.0" 255 | description = "Utility library for gitignore style pattern matching of file paths." 256 | category = "dev" 257 | optional = false 258 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 259 | 260 | [[package]] 261 | name = "pbr" 262 | version = "5.8.1" 263 | description = "Python Build Reasonableness" 264 | category = "dev" 265 | optional = false 266 | python-versions = ">=2.6" 267 | 268 | [[package]] 269 | name = "pep8-naming" 270 | version = "0.10.0" 271 | description = "Check PEP-8 naming conventions, plugin for flake8" 272 | category = "dev" 273 | optional = false 274 | python-versions = "*" 275 | 276 | [package.dependencies] 277 | flake8-polyfill = ">=1.0.2,<2" 278 | 279 | [[package]] 280 | name = "platformdirs" 281 | version = "2.5.1" 282 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 283 | category = "dev" 284 | optional = false 285 | python-versions = ">=3.7" 286 | 287 | [package.extras] 288 | docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] 289 | test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] 290 | 291 | [[package]] 292 | name = "pluggy" 293 | version = "1.0.0" 294 | description = "plugin and hook calling mechanisms for python" 295 | category = "dev" 296 | optional = false 297 | python-versions = ">=3.6" 298 | 299 | [package.extras] 300 | dev = ["pre-commit", "tox"] 301 | testing = ["pytest", "pytest-benchmark"] 302 | 303 | [[package]] 304 | name = "prospector" 305 | version = "1.7.7" 306 | description = "" 307 | category = "dev" 308 | optional = false 309 | python-versions = ">=3.6.2,<4.0" 310 | 311 | [package.dependencies] 312 | dodgy = ">=0.2.1,<0.3.0" 313 | mccabe = ">=0.6.0,<0.7.0" 314 | pep8-naming = ">=0.3.3,<=0.10.0" 315 | pycodestyle = ">=2.6.0,<2.9.0" 316 | pydocstyle = ">=2.0.0" 317 | pyflakes = ">=2.2.0,<3" 318 | pylint = ">=2.8.3" 319 | pylint-celery = "0.3" 320 | pylint-django = ">=2.5,<2.6" 321 | pylint-flask = "0.6" 322 | pylint-plugin-utils = ">=0.7,<0.8" 323 | PyYAML = "*" 324 | requirements-detector = ">=0.7,<0.8" 325 | setoptconf-tmp = ">=0.3.1,<0.4.0" 326 | toml = ">=0.10.2,<0.11.0" 327 | 328 | [package.extras] 329 | with_bandit = ["bandit (>=1.5.1)"] 330 | with_everything = ["bandit (>=1.5.1)", "frosted (>=1.4.1)", "mypy (>=0.600)", "pyroma (>=2.4)", "vulture (>=1.5)"] 331 | with_frosted = ["frosted (>=1.4.1)"] 332 | with_mypy = ["mypy (>=0.600)"] 333 | with_pyroma = ["pyroma (>=2.4)"] 334 | with_vulture = ["vulture (>=1.5)"] 335 | 336 | [[package]] 337 | name = "py" 338 | version = "1.11.0" 339 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 340 | category = "dev" 341 | optional = false 342 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 343 | 344 | [[package]] 345 | name = "pycodestyle" 346 | version = "2.8.0" 347 | description = "Python style guide checker" 348 | category = "dev" 349 | optional = false 350 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 351 | 352 | [[package]] 353 | name = "pydocstyle" 354 | version = "6.1.1" 355 | description = "Python docstring style checker" 356 | category = "dev" 357 | optional = false 358 | python-versions = ">=3.6" 359 | 360 | [package.dependencies] 361 | snowballstemmer = "*" 362 | 363 | [package.extras] 364 | toml = ["toml"] 365 | 366 | [[package]] 367 | name = "pyflakes" 368 | version = "2.4.0" 369 | description = "passive checker of Python programs" 370 | category = "dev" 371 | optional = false 372 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 373 | 374 | [[package]] 375 | name = "pylint" 376 | version = "2.13.5" 377 | description = "python code static checker" 378 | category = "dev" 379 | optional = false 380 | python-versions = ">=3.6.2" 381 | 382 | [package.dependencies] 383 | astroid = ">=2.11.2,<=2.12.0-dev0" 384 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 385 | dill = ">=0.2" 386 | isort = ">=4.2.5,<6" 387 | mccabe = ">=0.6,<0.8" 388 | platformdirs = ">=2.2.0" 389 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 390 | typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} 391 | 392 | [package.extras] 393 | testutil = ["gitpython (>3)"] 394 | 395 | [[package]] 396 | name = "pylint-celery" 397 | version = "0.3" 398 | description = "pylint-celery is a Pylint plugin to aid Pylint in recognising and understandingerrors caused when using the Celery library" 399 | category = "dev" 400 | optional = false 401 | python-versions = "*" 402 | 403 | [package.dependencies] 404 | astroid = ">=1.0" 405 | pylint = ">=1.0" 406 | pylint-plugin-utils = ">=0.2.1" 407 | 408 | [[package]] 409 | name = "pylint-django" 410 | version = "2.5.3" 411 | description = "A Pylint plugin to help Pylint understand the Django web framework" 412 | category = "dev" 413 | optional = false 414 | python-versions = "*" 415 | 416 | [package.dependencies] 417 | pylint = ">=2.0,<3" 418 | pylint-plugin-utils = ">=0.7" 419 | 420 | [package.extras] 421 | for_tests = ["django-tables2", "factory-boy", "coverage", "pytest", "wheel", "django-tastypie", "pylint (>=2.13)"] 422 | with_django = ["django"] 423 | 424 | [[package]] 425 | name = "pylint-flask" 426 | version = "0.6" 427 | description = "pylint-flask is a Pylint plugin to aid Pylint in recognizing and understanding errors caused when using Flask" 428 | category = "dev" 429 | optional = false 430 | python-versions = "*" 431 | 432 | [package.dependencies] 433 | pylint-plugin-utils = ">=0.2.1" 434 | 435 | [[package]] 436 | name = "pylint-plugin-utils" 437 | version = "0.7" 438 | description = "Utilities and helpers for writing Pylint plugins" 439 | category = "dev" 440 | optional = false 441 | python-versions = ">=3.6.2" 442 | 443 | [package.dependencies] 444 | pylint = ">=1.7" 445 | 446 | [[package]] 447 | name = "pyparsing" 448 | version = "3.0.7" 449 | description = "Python parsing module" 450 | category = "dev" 451 | optional = false 452 | python-versions = ">=3.6" 453 | 454 | [package.extras] 455 | diagrams = ["jinja2", "railroad-diagrams"] 456 | 457 | [[package]] 458 | name = "pytest" 459 | version = "7.1.1" 460 | description = "pytest: simple powerful testing with Python" 461 | category = "dev" 462 | optional = false 463 | python-versions = ">=3.7" 464 | 465 | [package.dependencies] 466 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} 467 | attrs = ">=19.2.0" 468 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 469 | iniconfig = "*" 470 | packaging = "*" 471 | pluggy = ">=0.12,<2.0" 472 | py = ">=1.8.2" 473 | tomli = ">=1.0.0" 474 | 475 | [package.extras] 476 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] 477 | 478 | [[package]] 479 | name = "pyyaml" 480 | version = "6.0" 481 | description = "YAML parser and emitter for Python" 482 | category = "dev" 483 | optional = false 484 | python-versions = ">=3.6" 485 | 486 | [[package]] 487 | name = "requirements-detector" 488 | version = "0.7" 489 | description = "Python tool to find and list requirements of a Python project" 490 | category = "dev" 491 | optional = false 492 | python-versions = "*" 493 | 494 | [package.dependencies] 495 | astroid = ">=1.4" 496 | 497 | [[package]] 498 | name = "scikit-learn" 499 | version = "1.0.2" 500 | description = "A set of python modules for machine learning and data mining" 501 | category = "main" 502 | optional = false 503 | python-versions = ">=3.7" 504 | 505 | [package.dependencies] 506 | joblib = ">=0.11" 507 | numpy = ">=1.14.6" 508 | scipy = ">=1.1.0" 509 | threadpoolctl = ">=2.0.0" 510 | 511 | [package.extras] 512 | benchmark = ["matplotlib (>=2.2.3)", "pandas (>=0.25.0)", "memory-profiler (>=0.57.0)"] 513 | docs = ["matplotlib (>=2.2.3)", "scikit-image (>=0.14.5)", "pandas (>=0.25.0)", "seaborn (>=0.9.0)", "memory-profiler (>=0.57.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "numpydoc (>=1.0.0)", "Pillow (>=7.1.2)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] 514 | examples = ["matplotlib (>=2.2.3)", "scikit-image (>=0.14.5)", "pandas (>=0.25.0)", "seaborn (>=0.9.0)"] 515 | tests = ["matplotlib (>=2.2.3)", "scikit-image (>=0.14.5)", "pandas (>=0.25.0)", "pytest (>=5.0.1)", "pytest-cov (>=2.9.0)", "flake8 (>=3.8.2)", "black (>=21.6b0)", "mypy (>=0.770)", "pyamg (>=4.0.0)"] 516 | 517 | [[package]] 518 | name = "scipy" 519 | version = "1.8.0" 520 | description = "SciPy: Scientific Library for Python" 521 | category = "main" 522 | optional = false 523 | python-versions = ">=3.8,<3.11" 524 | 525 | [package.dependencies] 526 | numpy = ">=1.17.3,<1.25.0" 527 | 528 | [[package]] 529 | name = "setoptconf-tmp" 530 | version = "0.3.1" 531 | description = "A module for retrieving program settings from various sources in a consistant method." 532 | category = "dev" 533 | optional = false 534 | python-versions = "*" 535 | 536 | [package.extras] 537 | yaml = ["pyyaml"] 538 | 539 | [[package]] 540 | name = "smmap" 541 | version = "5.0.0" 542 | description = "A pure Python implementation of a sliding window memory map manager" 543 | category = "dev" 544 | optional = false 545 | python-versions = ">=3.6" 546 | 547 | [[package]] 548 | name = "snowballstemmer" 549 | version = "2.2.0" 550 | description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." 551 | category = "dev" 552 | optional = false 553 | python-versions = "*" 554 | 555 | [[package]] 556 | name = "stevedore" 557 | version = "3.5.0" 558 | description = "Manage dynamic plugins for Python applications" 559 | category = "dev" 560 | optional = false 561 | python-versions = ">=3.6" 562 | 563 | [package.dependencies] 564 | pbr = ">=2.0.0,<2.1.0 || >2.1.0" 565 | 566 | [[package]] 567 | name = "threadpoolctl" 568 | version = "3.1.0" 569 | description = "threadpoolctl" 570 | category = "main" 571 | optional = false 572 | python-versions = ">=3.6" 573 | 574 | [[package]] 575 | name = "toml" 576 | version = "0.10.2" 577 | description = "Python Library for Tom's Obvious, Minimal Language" 578 | category = "dev" 579 | optional = false 580 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 581 | 582 | [[package]] 583 | name = "tomli" 584 | version = "2.0.1" 585 | description = "A lil' TOML parser" 586 | category = "dev" 587 | optional = false 588 | python-versions = ">=3.7" 589 | 590 | [[package]] 591 | name = "typing-extensions" 592 | version = "4.1.1" 593 | description = "Backported and Experimental Type Hints for Python 3.6+" 594 | category = "dev" 595 | optional = false 596 | python-versions = ">=3.6" 597 | 598 | [[package]] 599 | name = "wrapt" 600 | version = "1.14.0" 601 | description = "Module for decorators, wrappers and monkey patching." 602 | category = "dev" 603 | optional = false 604 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 605 | 606 | [metadata] 607 | lock-version = "1.1" 608 | python-versions = "~3.9.0" 609 | content-hash = "96e271d7776314a1e8855e05a13061b8538aff7674657a56680d2871cf77a619" 610 | 611 | [metadata.files] 612 | astroid = [ 613 | {file = "astroid-2.11.2-py3-none-any.whl", hash = "sha256:cc8cc0d2d916c42d0a7c476c57550a4557a083081976bf42a73414322a6411d9"}, 614 | {file = "astroid-2.11.2.tar.gz", hash = "sha256:8d0a30fe6481ce919f56690076eafbb2fb649142a89dc874f1ec0e7a011492d0"}, 615 | ] 616 | atomicwrites = [ 617 | {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, 618 | {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, 619 | ] 620 | attrs = [ 621 | {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, 622 | {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, 623 | ] 624 | bandit = [ 625 | {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, 626 | {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, 627 | ] 628 | black = [ 629 | {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, 630 | {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, 631 | {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, 632 | {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, 633 | {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, 634 | {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, 635 | {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, 636 | {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, 637 | {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, 638 | {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, 639 | {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, 640 | {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, 641 | {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, 642 | {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, 643 | {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, 644 | {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, 645 | {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, 646 | {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, 647 | {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, 648 | {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, 649 | {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, 650 | {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, 651 | {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, 652 | ] 653 | click = [ 654 | {file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"}, 655 | {file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"}, 656 | ] 657 | colorama = [ 658 | {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, 659 | {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, 660 | ] 661 | dill = [ 662 | {file = "dill-0.3.4-py2.py3-none-any.whl", hash = "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f"}, 663 | {file = "dill-0.3.4.zip", hash = "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"}, 664 | ] 665 | dodgy = [ 666 | {file = "dodgy-0.2.1-py3-none-any.whl", hash = "sha256:51f54c0fd886fa3854387f354b19f429d38c04f984f38bc572558b703c0542a6"}, 667 | {file = "dodgy-0.2.1.tar.gz", hash = "sha256:28323cbfc9352139fdd3d316fa17f325cc0e9ac74438cbba51d70f9b48f86c3a"}, 668 | ] 669 | flake8 = [ 670 | {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, 671 | {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, 672 | ] 673 | flake8-polyfill = [ 674 | {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, 675 | {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, 676 | ] 677 | gitdb = [ 678 | {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, 679 | {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, 680 | ] 681 | gitpython = [ 682 | {file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"}, 683 | {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"}, 684 | ] 685 | iniconfig = [ 686 | {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, 687 | {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, 688 | ] 689 | isort = [ 690 | {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, 691 | {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, 692 | ] 693 | joblib = [ 694 | {file = "joblib-1.1.0-py2.py3-none-any.whl", hash = "sha256:f21f109b3c7ff9d95f8387f752d0d9c34a02aa2f7060c2135f465da0e5160ff6"}, 695 | {file = "joblib-1.1.0.tar.gz", hash = "sha256:4158fcecd13733f8be669be0683b96ebdbbd38d23559f54dca7205aea1bf1e35"}, 696 | ] 697 | lazy-object-proxy = [ 698 | {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, 699 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, 700 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, 701 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, 702 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, 703 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, 704 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, 705 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, 706 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, 707 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, 708 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, 709 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, 710 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, 711 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, 712 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, 713 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, 714 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, 715 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, 716 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, 717 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, 718 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, 719 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, 720 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, 721 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, 722 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, 723 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, 724 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, 725 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, 726 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, 727 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, 728 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, 729 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, 730 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, 731 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, 732 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, 733 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, 734 | {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, 735 | ] 736 | mccabe = [ 737 | {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, 738 | {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, 739 | ] 740 | mypy = [ 741 | {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, 742 | {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, 743 | {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, 744 | {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, 745 | {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, 746 | {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, 747 | {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, 748 | {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, 749 | {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, 750 | {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, 751 | {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, 752 | {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, 753 | {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, 754 | {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, 755 | {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, 756 | {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, 757 | {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, 758 | {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, 759 | {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, 760 | {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, 761 | {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, 762 | {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, 763 | {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, 764 | ] 765 | mypy-extensions = [ 766 | {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, 767 | {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, 768 | ] 769 | numpy = [ 770 | {file = "numpy-1.22.3-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75"}, 771 | {file = "numpy-1.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab"}, 772 | {file = "numpy-1.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e"}, 773 | {file = "numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4"}, 774 | {file = "numpy-1.22.3-cp310-cp310-win32.whl", hash = "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430"}, 775 | {file = "numpy-1.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4"}, 776 | {file = "numpy-1.22.3-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce"}, 777 | {file = "numpy-1.22.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe"}, 778 | {file = "numpy-1.22.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5"}, 779 | {file = "numpy-1.22.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1"}, 780 | {file = "numpy-1.22.3-cp38-cp38-win32.whl", hash = "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62"}, 781 | {file = "numpy-1.22.3-cp38-cp38-win_amd64.whl", hash = "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676"}, 782 | {file = "numpy-1.22.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123"}, 783 | {file = "numpy-1.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802"}, 784 | {file = "numpy-1.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d"}, 785 | {file = "numpy-1.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168"}, 786 | {file = "numpy-1.22.3-cp39-cp39-win32.whl", hash = "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa"}, 787 | {file = "numpy-1.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a"}, 788 | {file = "numpy-1.22.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f"}, 789 | {file = "numpy-1.22.3.zip", hash = "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18"}, 790 | ] 791 | packaging = [ 792 | {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, 793 | {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, 794 | ] 795 | pathspec = [ 796 | {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, 797 | {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, 798 | ] 799 | pbr = [ 800 | {file = "pbr-5.8.1-py2.py3-none-any.whl", hash = "sha256:27108648368782d07bbf1cb468ad2e2eeef29086affd14087a6d04b7de8af4ec"}, 801 | {file = "pbr-5.8.1.tar.gz", hash = "sha256:66bc5a34912f408bb3925bf21231cb6f59206267b7f63f3503ef865c1a292e25"}, 802 | ] 803 | pep8-naming = [ 804 | {file = "pep8-naming-0.10.0.tar.gz", hash = "sha256:f3b4a5f9dd72b991bf7d8e2a341d2e1aa3a884a769b5aaac4f56825c1763bf3a"}, 805 | {file = "pep8_naming-0.10.0-py2.py3-none-any.whl", hash = "sha256:5d9f1056cb9427ce344e98d1a7f5665710e2f20f748438e308995852cfa24164"}, 806 | ] 807 | platformdirs = [ 808 | {file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"}, 809 | {file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"}, 810 | ] 811 | pluggy = [ 812 | {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, 813 | {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, 814 | ] 815 | prospector = [ 816 | {file = "prospector-1.7.7-py3-none-any.whl", hash = "sha256:2dec5dac06f136880a3710996c0886dcc99e739007bbc05afc32884973f5c058"}, 817 | {file = "prospector-1.7.7.tar.gz", hash = "sha256:c04b3d593e7c525cf9a742fed62afbe02e2874f0e42f2f56a49378fd94037360"}, 818 | ] 819 | py = [ 820 | {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, 821 | {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, 822 | ] 823 | pycodestyle = [ 824 | {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, 825 | {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, 826 | ] 827 | pydocstyle = [ 828 | {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, 829 | {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, 830 | ] 831 | pyflakes = [ 832 | {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, 833 | {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, 834 | ] 835 | pylint = [ 836 | {file = "pylint-2.13.5-py3-none-any.whl", hash = "sha256:c149694cfdeaee1aa2465e6eaab84c87a881a7d55e6e93e09466be7164764d1e"}, 837 | {file = "pylint-2.13.5.tar.gz", hash = "sha256:dab221658368c7a05242e673c275c488670144123f4bd262b2777249c1c0de9b"}, 838 | ] 839 | pylint-celery = [ 840 | {file = "pylint-celery-0.3.tar.gz", hash = "sha256:41e32094e7408d15c044178ea828dd524beedbdbe6f83f712c5e35bde1de4beb"}, 841 | ] 842 | pylint-django = [ 843 | {file = "pylint-django-2.5.3.tar.gz", hash = "sha256:0ac090d106c62fe33782a1d01bda1610b761bb1c9bf5035ced9d5f23a13d8591"}, 844 | {file = "pylint_django-2.5.3-py3-none-any.whl", hash = "sha256:56b12b6adf56d548412445bd35483034394a1a94901c3f8571980a13882299d5"}, 845 | ] 846 | pylint-flask = [ 847 | {file = "pylint-flask-0.6.tar.gz", hash = "sha256:f4d97de2216bf7bfce07c9c08b166e978fe9f2725de2a50a9845a97de7e31517"}, 848 | ] 849 | pylint-plugin-utils = [ 850 | {file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"}, 851 | {file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"}, 852 | ] 853 | pyparsing = [ 854 | {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, 855 | {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, 856 | ] 857 | pytest = [ 858 | {file = "pytest-7.1.1-py3-none-any.whl", hash = "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea"}, 859 | {file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"}, 860 | ] 861 | pyyaml = [ 862 | {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, 863 | {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, 864 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, 865 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, 866 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, 867 | {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, 868 | {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, 869 | {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, 870 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, 871 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, 872 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, 873 | {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, 874 | {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, 875 | {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, 876 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, 877 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, 878 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, 879 | {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, 880 | {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, 881 | {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, 882 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, 883 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, 884 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, 885 | {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, 886 | {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, 887 | {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, 888 | {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, 889 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, 890 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, 891 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, 892 | {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, 893 | {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, 894 | {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, 895 | ] 896 | requirements-detector = [ 897 | {file = "requirements-detector-0.7.tar.gz", hash = "sha256:0d1e13e61ed243f9c3c86e6cbb19980bcb3a0e0619cde2ec1f3af70fdbee6f7b"}, 898 | ] 899 | scikit-learn = [ 900 | {file = "scikit-learn-1.0.2.tar.gz", hash = "sha256:b5870959a5484b614f26d31ca4c17524b1b0317522199dc985c3b4256e030767"}, 901 | {file = "scikit_learn-1.0.2-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:da3c84694ff693b5b3194d8752ccf935a665b8b5edc33a283122f4273ca3e687"}, 902 | {file = "scikit_learn-1.0.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:75307d9ea39236cad7eea87143155eea24d48f93f3a2f9389c817f7019f00705"}, 903 | {file = "scikit_learn-1.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f14517e174bd7332f1cca2c959e704696a5e0ba246eb8763e6c24876d8710049"}, 904 | {file = "scikit_learn-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9aac97e57c196206179f674f09bc6bffcd0284e2ba95b7fe0b402ac3f986023"}, 905 | {file = "scikit_learn-1.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:d93d4c28370aea8a7cbf6015e8a669cd5d69f856cc2aa44e7a590fb805bb5583"}, 906 | {file = "scikit_learn-1.0.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:85260fb430b795d806251dd3bb05e6f48cdc777ac31f2bcf2bc8bbed3270a8f5"}, 907 | {file = "scikit_learn-1.0.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a053a6a527c87c5c4fa7bf1ab2556fa16d8345cf99b6c5a19030a4a7cd8fd2c0"}, 908 | {file = "scikit_learn-1.0.2-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:245c9b5a67445f6f044411e16a93a554edc1efdcce94d3fc0bc6a4b9ac30b752"}, 909 | {file = "scikit_learn-1.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:158faf30684c92a78e12da19c73feff9641a928a8024b4fa5ec11d583f3d8a87"}, 910 | {file = "scikit_learn-1.0.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:08ef968f6b72033c16c479c966bf37ccd49b06ea91b765e1cc27afefe723920b"}, 911 | {file = "scikit_learn-1.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16455ace947d8d9e5391435c2977178d0ff03a261571e67f627c8fee0f9d431a"}, 912 | {file = "scikit_learn-1.0.2-cp37-cp37m-win32.whl", hash = "sha256:2f3b453e0b149898577e301d27e098dfe1a36943f7bb0ad704d1e548efc3b448"}, 913 | {file = "scikit_learn-1.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:46f431ec59dead665e1370314dbebc99ead05e1c0a9df42f22d6a0e00044820f"}, 914 | {file = "scikit_learn-1.0.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:ff3fa8ea0e09e38677762afc6e14cad77b5e125b0ea70c9bba1992f02c93b028"}, 915 | {file = "scikit_learn-1.0.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:9369b030e155f8188743eb4893ac17a27f81d28a884af460870c7c072f114243"}, 916 | {file = "scikit_learn-1.0.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7d6b2475f1c23a698b48515217eb26b45a6598c7b1840ba23b3c5acece658dbb"}, 917 | {file = "scikit_learn-1.0.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:285db0352e635b9e3392b0b426bc48c3b485512d3b4ac3c7a44ec2a2ba061e66"}, 918 | {file = "scikit_learn-1.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cb33fe1dc6f73dc19e67b264dbb5dde2a0539b986435fdd78ed978c14654830"}, 919 | {file = "scikit_learn-1.0.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1391d1a6e2268485a63c3073111fe3ba6ec5145fc957481cfd0652be571226d"}, 920 | {file = "scikit_learn-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc3744dabc56b50bec73624aeca02e0def06b03cb287de26836e730659c5d29c"}, 921 | {file = "scikit_learn-1.0.2-cp38-cp38-win32.whl", hash = "sha256:a999c9f02ff9570c783069f1074f06fe7386ec65b84c983db5aeb8144356a355"}, 922 | {file = "scikit_learn-1.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:7626a34eabbf370a638f32d1a3ad50526844ba58d63e3ab81ba91e2a7c6d037e"}, 923 | {file = "scikit_learn-1.0.2-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:a90b60048f9ffdd962d2ad2fb16367a87ac34d76e02550968719eb7b5716fd10"}, 924 | {file = "scikit_learn-1.0.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:7a93c1292799620df90348800d5ac06f3794c1316ca247525fa31169f6d25855"}, 925 | {file = "scikit_learn-1.0.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:eabceab574f471de0b0eb3f2ecf2eee9f10b3106570481d007ed1c84ebf6d6a1"}, 926 | {file = "scikit_learn-1.0.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:55f2f3a8414e14fbee03782f9fe16cca0f141d639d2b1c1a36779fa069e1db57"}, 927 | {file = "scikit_learn-1.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80095a1e4b93bd33261ef03b9bc86d6db649f988ea4dbcf7110d0cded8d7213d"}, 928 | {file = "scikit_learn-1.0.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa38a1b9b38ae1fad2863eff5e0d69608567453fdfc850c992e6e47eb764e846"}, 929 | {file = "scikit_learn-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff746a69ff2ef25f62b36338c615dd15954ddc3ab8e73530237dd73235e76d62"}, 930 | {file = "scikit_learn-1.0.2-cp39-cp39-win32.whl", hash = "sha256:e174242caecb11e4abf169342641778f68e1bfaba80cd18acd6bc84286b9a534"}, 931 | {file = "scikit_learn-1.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:b54a62c6e318ddbfa7d22c383466d38d2ee770ebdb5ddb668d56a099f6eaf75f"}, 932 | ] 933 | scipy = [ 934 | {file = "scipy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:87b01c7d5761e8a266a0fbdb9d88dcba0910d63c1c671bdb4d99d29f469e9e03"}, 935 | {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ae3e327da323d82e918e593460e23babdce40d7ab21490ddf9fc06dec6b91a18"}, 936 | {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:16e09ef68b352d73befa8bcaf3ebe25d3941fe1a58c82909d5589856e6bc8174"}, 937 | {file = "scipy-1.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c17a1878d00a5dd2797ccd73623ceca9d02375328f6218ee6d921e1325e61aff"}, 938 | {file = "scipy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937d28722f13302febde29847bbe554b89073fbb924a30475e5ed7b028898b5f"}, 939 | {file = "scipy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:8f4d059a97b29c91afad46b1737274cb282357a305a80bdd9e8adf3b0ca6a3f0"}, 940 | {file = "scipy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:38aa39b6724cb65271e469013aeb6f2ce66fd44f093e241c28a9c6bc64fd79ed"}, 941 | {file = "scipy-1.8.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:559a8a4c03a5ba9fe3232f39ed24f86457e4f3f6c0abbeae1fb945029f092720"}, 942 | {file = "scipy-1.8.0-cp38-cp38-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:f4a6d3b9f9797eb2d43938ac2c5d96d02aed17ef170c8b38f11798717523ddba"}, 943 | {file = "scipy-1.8.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b2c2af4183ed09afb595709a8ef5783b2baf7f41e26ece24e1329c109691a7"}, 944 | {file = "scipy-1.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a279e27c7f4566ef18bab1b1e2c37d168e365080974758d107e7d237d3f0f484"}, 945 | {file = "scipy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad5be4039147c808e64f99c0e8a9641eb5d2fa079ff5894dcd8240e94e347af4"}, 946 | {file = "scipy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:3d9dd6c8b93a22bf9a3a52d1327aca7e092b1299fb3afc4f89e8eba381be7b59"}, 947 | {file = "scipy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:5e73343c5e0d413c1f937302b2e04fb07872f5843041bcfd50699aef6e95e399"}, 948 | {file = "scipy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:de2e80ee1d925984c2504812a310841c241791c5279352be4707cdcd7c255039"}, 949 | {file = "scipy-1.8.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:c2bae431d127bf0b1da81fc24e4bba0a84d058e3a96b9dd6475dfcb3c5e8761e"}, 950 | {file = "scipy-1.8.0-cp39-cp39-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:723b9f878095ed994756fa4ee3060c450e2db0139c5ba248ee3f9628bd64e735"}, 951 | {file = "scipy-1.8.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:011d4386b53b933142f58a652aa0f149c9b9242abd4f900b9f4ea5fbafc86b89"}, 952 | {file = "scipy-1.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6f0cd9c0bd374ef834ee1e0f0999678d49dcc400ea6209113d81528958f97c7"}, 953 | {file = "scipy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3720d0124aced49f6f2198a6900304411dbbeed12f56951d7c66ebef05e3df6"}, 954 | {file = "scipy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:3d573228c10a3a8c32b9037be982e6440e411b443a6267b067cac72f690b8d56"}, 955 | {file = "scipy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb7088e89cd751acf66195d2f00cf009a1ea113f3019664032d9075b1e727b6c"}, 956 | {file = "scipy-1.8.0.tar.gz", hash = "sha256:31d4f2d6b724bc9a98e527b5849b8a7e589bf1ea630c33aa563eda912c9ff0bd"}, 957 | ] 958 | setoptconf-tmp = [ 959 | {file = "setoptconf-tmp-0.3.1.tar.gz", hash = "sha256:e0480addd11347ba52f762f3c4d8afa3e10ad0affbc53e3ffddc0ca5f27d5778"}, 960 | {file = "setoptconf_tmp-0.3.1-py3-none-any.whl", hash = "sha256:76035d5cd1593d38b9056ae12d460eca3aaa34ad05c315b69145e138ba80a745"}, 961 | ] 962 | smmap = [ 963 | {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, 964 | {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, 965 | ] 966 | snowballstemmer = [ 967 | {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, 968 | {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, 969 | ] 970 | stevedore = [ 971 | {file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"}, 972 | {file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"}, 973 | ] 974 | threadpoolctl = [ 975 | {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, 976 | {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, 977 | ] 978 | toml = [ 979 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 980 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 981 | ] 982 | tomli = [ 983 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, 984 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, 985 | ] 986 | typing-extensions = [ 987 | {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, 988 | {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, 989 | ] 990 | wrapt = [ 991 | {file = "wrapt-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:5a9a1889cc01ed2ed5f34574c90745fab1dd06ec2eee663e8ebeefe363e8efd7"}, 992 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:9a3ff5fb015f6feb78340143584d9f8a0b91b6293d6b5cf4295b3e95d179b88c"}, 993 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4b847029e2d5e11fd536c9ac3136ddc3f54bc9488a75ef7d040a3900406a91eb"}, 994 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9a5a544861b21e0e7575b6023adebe7a8c6321127bb1d238eb40d99803a0e8bd"}, 995 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:88236b90dda77f0394f878324cfbae05ae6fde8a84d548cfe73a75278d760291"}, 996 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f0408e2dbad9e82b4c960274214af533f856a199c9274bd4aff55d4634dedc33"}, 997 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9d8c68c4145041b4eeae96239802cfdfd9ef927754a5be3f50505f09f309d8c6"}, 998 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:22626dca56fd7f55a0733e604f1027277eb0f4f3d95ff28f15d27ac25a45f71b"}, 999 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:65bf3eb34721bf18b5a021a1ad7aa05947a1767d1aa272b725728014475ea7d5"}, 1000 | {file = "wrapt-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09d16ae7a13cff43660155383a2372b4aa09109c7127aa3f24c3cf99b891c330"}, 1001 | {file = "wrapt-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:debaf04f813ada978d7d16c7dfa16f3c9c2ec9adf4656efdc4defdf841fc2f0c"}, 1002 | {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748df39ed634851350efa87690c2237a678ed794fe9ede3f0d79f071ee042561"}, 1003 | {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1807054aa7b61ad8d8103b3b30c9764de2e9d0c0978e9d3fc337e4e74bf25faa"}, 1004 | {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763a73ab377390e2af26042f685a26787c402390f682443727b847e9496e4a2a"}, 1005 | {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8529b07b49b2d89d6917cfa157d3ea1dfb4d319d51e23030664a827fe5fd2131"}, 1006 | {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:68aeefac31c1f73949662ba8affaf9950b9938b712fb9d428fa2a07e40ee57f8"}, 1007 | {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59d7d92cee84a547d91267f0fea381c363121d70fe90b12cd88241bd9b0e1763"}, 1008 | {file = "wrapt-1.14.0-cp310-cp310-win32.whl", hash = "sha256:3a88254881e8a8c4784ecc9cb2249ff757fd94b911d5df9a5984961b96113fff"}, 1009 | {file = "wrapt-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:9a242871b3d8eecc56d350e5e03ea1854de47b17f040446da0e47dc3e0b9ad4d"}, 1010 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a65bffd24409454b889af33b6c49d0d9bcd1a219b972fba975ac935f17bdf627"}, 1011 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9d9fcd06c952efa4b6b95f3d788a819b7f33d11bea377be6b8980c95e7d10775"}, 1012 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:db6a0ddc1282ceb9032e41853e659c9b638789be38e5b8ad7498caac00231c23"}, 1013 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:14e7e2c5f5fca67e9a6d5f753d21f138398cad2b1159913ec9e9a67745f09ba3"}, 1014 | {file = "wrapt-1.14.0-cp35-cp35m-win32.whl", hash = "sha256:6d9810d4f697d58fd66039ab959e6d37e63ab377008ef1d63904df25956c7db0"}, 1015 | {file = "wrapt-1.14.0-cp35-cp35m-win_amd64.whl", hash = "sha256:d808a5a5411982a09fef6b49aac62986274ab050e9d3e9817ad65b2791ed1425"}, 1016 | {file = "wrapt-1.14.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b77159d9862374da213f741af0c361720200ab7ad21b9f12556e0eb95912cd48"}, 1017 | {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36a76a7527df8583112b24adc01748cd51a2d14e905b337a6fefa8b96fc708fb"}, 1018 | {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0057b5435a65b933cbf5d859cd4956624df37b8bf0917c71756e4b3d9958b9e"}, 1019 | {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0a4ca02752ced5f37498827e49c414d694ad7cf451ee850e3ff160f2bee9d3"}, 1020 | {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8c6be72eac3c14baa473620e04f74186c5d8f45d80f8f2b4eda6e1d18af808e8"}, 1021 | {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:21b1106bff6ece8cb203ef45b4f5778d7226c941c83aaaa1e1f0f4f32cc148cd"}, 1022 | {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:493da1f8b1bb8a623c16552fb4a1e164c0200447eb83d3f68b44315ead3f9036"}, 1023 | {file = "wrapt-1.14.0-cp36-cp36m-win32.whl", hash = "sha256:89ba3d548ee1e6291a20f3c7380c92f71e358ce8b9e48161401e087e0bc740f8"}, 1024 | {file = "wrapt-1.14.0-cp36-cp36m-win_amd64.whl", hash = "sha256:729d5e96566f44fccac6c4447ec2332636b4fe273f03da128fff8d5559782b06"}, 1025 | {file = "wrapt-1.14.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:891c353e95bb11abb548ca95c8b98050f3620a7378332eb90d6acdef35b401d4"}, 1026 | {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23f96134a3aa24cc50614920cc087e22f87439053d886e474638c68c8d15dc80"}, 1027 | {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6807bcee549a8cb2f38f73f469703a1d8d5d990815c3004f21ddb68a567385ce"}, 1028 | {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6915682f9a9bc4cf2908e83caf5895a685da1fbd20b6d485dafb8e218a338279"}, 1029 | {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f2f3bc7cd9c9fcd39143f11342eb5963317bd54ecc98e3650ca22704b69d9653"}, 1030 | {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3a71dbd792cc7a3d772ef8cd08d3048593f13d6f40a11f3427c000cf0a5b36a0"}, 1031 | {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5a0898a640559dec00f3614ffb11d97a2666ee9a2a6bad1259c9facd01a1d4d9"}, 1032 | {file = "wrapt-1.14.0-cp37-cp37m-win32.whl", hash = "sha256:167e4793dc987f77fd476862d32fa404d42b71f6a85d3b38cbce711dba5e6b68"}, 1033 | {file = "wrapt-1.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d066ffc5ed0be00cd0352c95800a519cf9e4b5dd34a028d301bdc7177c72daf3"}, 1034 | {file = "wrapt-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d9bdfa74d369256e4218000a629978590fd7cb6cf6893251dad13d051090436d"}, 1035 | {file = "wrapt-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2498762814dd7dd2a1d0248eda2afbc3dd9c11537bc8200a4b21789b6df6cd38"}, 1036 | {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f24ca7953f2643d59a9c87d6e272d8adddd4a53bb62b9208f36db408d7aafc7"}, 1037 | {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b835b86bd5a1bdbe257d610eecab07bf685b1af2a7563093e0e69180c1d4af1"}, 1038 | {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b21650fa6907e523869e0396c5bd591cc326e5c1dd594dcdccac089561cacfb8"}, 1039 | {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:354d9fc6b1e44750e2a67b4b108841f5f5ea08853453ecbf44c81fdc2e0d50bd"}, 1040 | {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f83e9c21cd5275991076b2ba1cd35418af3504667affb4745b48937e214bafe"}, 1041 | {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61e1a064906ccba038aa3c4a5a82f6199749efbbb3cef0804ae5c37f550eded0"}, 1042 | {file = "wrapt-1.14.0-cp38-cp38-win32.whl", hash = "sha256:28c659878f684365d53cf59dc9a1929ea2eecd7ac65da762be8b1ba193f7e84f"}, 1043 | {file = "wrapt-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:b0ed6ad6c9640671689c2dbe6244680fe8b897c08fd1fab2228429b66c518e5e"}, 1044 | {file = "wrapt-1.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3f7e671fb19734c872566e57ce7fc235fa953d7c181bb4ef138e17d607dc8a1"}, 1045 | {file = "wrapt-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87fa943e8bbe40c8c1ba4086971a6fefbf75e9991217c55ed1bcb2f1985bd3d4"}, 1046 | {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4775a574e9d84e0212f5b18886cace049a42e13e12009bb0491562a48bb2b758"}, 1047 | {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d57677238a0c5411c76097b8b93bdebb02eb845814c90f0b01727527a179e4d"}, 1048 | {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00108411e0f34c52ce16f81f1d308a571df7784932cc7491d1e94be2ee93374b"}, 1049 | {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d332eecf307fca852d02b63f35a7872de32d5ba8b4ec32da82f45df986b39ff6"}, 1050 | {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:01f799def9b96a8ec1ef6b9c1bbaf2bbc859b87545efbecc4a78faea13d0e3a0"}, 1051 | {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47045ed35481e857918ae78b54891fac0c1d197f22c95778e66302668309336c"}, 1052 | {file = "wrapt-1.14.0-cp39-cp39-win32.whl", hash = "sha256:2eca15d6b947cfff51ed76b2d60fd172c6ecd418ddab1c5126032d27f74bc350"}, 1053 | {file = "wrapt-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb36fbb48b22985d13a6b496ea5fb9bb2a076fea943831643836c9f6febbcfdc"}, 1054 | {file = "wrapt-1.14.0.tar.gz", hash = "sha256:8323a43bd9c91f62bb7d4be74cc9ff10090e7ef820e27bfe8815c57e68261311"}, 1055 | ] 1056 | -------------------------------------------------------------------------------- /kfp/components/trainer/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "kfp_sample_trainer" 3 | version = "0.0.2" 4 | description = "trainer component of kfp sample pipeline" 5 | authors = ["Repro AI Lab Team "] 6 | license = "MIT" 7 | 8 | [tool.poetry.dependencies] 9 | python = "~3.9.0" 10 | pip = "*" 11 | numpy = "^1.22.3" 12 | scikit-learn = "^1.0.0" 13 | 14 | [tool.poetry.dev-dependencies] 15 | pydocstyle = "*" 16 | bandit = "*" 17 | prospector = "*" 18 | mypy = "*" 19 | pytest = "*" 20 | black = { version = "*", allow-prereleases = true } 21 | 22 | [build-system] 23 | requires = ["poetry>=0.12"] 24 | build-backend = "poetry.masonry.api" -------------------------------------------------------------------------------- /kfp/components/trainer/setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501 3 | 4 | [mypy] 5 | ignore_missing_imports = true 6 | -------------------------------------------------------------------------------- /kfp/components/trainer/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AseiSugiyama/lab_sample_pipelines/bff27728c15cbd29351b4970da312278409220de/kfp/components/trainer/src/__init__.py -------------------------------------------------------------------------------- /kfp/components/trainer/src/trainer.py: -------------------------------------------------------------------------------- 1 | """Data Generator implementation.""" 2 | 3 | import argparse 4 | import pickle 5 | from dataclasses import dataclass 6 | from pathlib import Path 7 | from typing import IO, get_type_hints 8 | 9 | import numpy as np 10 | from sklearn.base import BaseEstimator 11 | from sklearn.ensemble import RandomForestClassifier 12 | 13 | TARGET = "species" 14 | 15 | 16 | # 17 | # COMPONENT ARGUMENTS 18 | # ------------------------------------------------------------------------------ 19 | 20 | 21 | @dataclass 22 | class ComponentArguments: 23 | """Argument of the component. Note: Data Generator has no inputs.""" 24 | 25 | transformed_train_data_path: str 26 | suffix: str 27 | 28 | 29 | @dataclass 30 | class OutputDestinations: 31 | """Outputs of the component.""" 32 | 33 | trained_model_path: str 34 | 35 | 36 | @dataclass 37 | class Artifacts: 38 | component_arguments: ComponentArguments 39 | output_destinations: OutputDestinations 40 | 41 | @classmethod 42 | def arg_parser(cls) -> argparse.ArgumentParser: 43 | """Parse component argument and return as ComponentArguments.""" 44 | parser = argparse.ArgumentParser() 45 | # generate argument parser based on ComponentArgument's definition 46 | for artifact in get_type_hints(cls).values(): 47 | for arg_name, arg_type in get_type_hints(artifact).items(): 48 | parser.add_argument(arg_name, type=arg_type) 49 | 50 | return parser 51 | 52 | @classmethod 53 | def from_args(cls) -> "Artifacts": 54 | args = vars(cls.arg_parser().parse_args()) 55 | 56 | artifacts = {} 57 | for key, artifact_cls in get_type_hints(cls).items(): 58 | existed_keys = get_type_hints(artifact_cls).keys() 59 | filtered_vars = {k: v for k, v in args.items() if k in existed_keys} 60 | 61 | artifacts[key] = artifact_cls(**filtered_vars) 62 | # parse args and convert into PipelineArguments 63 | return cls(**artifacts) 64 | 65 | 66 | # 67 | # MAIN FUNCTION 68 | # ------------------------------------------------------------------------------ 69 | 70 | 71 | def main(args: ComponentArguments) -> BaseEstimator: 72 | label_key = TARGET + args.suffix 73 | with Path(args.transformed_train_data_path).open() as f: 74 | data = load_dataset(f, label_key) 75 | return train(data, label_key) 76 | 77 | 78 | # 79 | # SUB FUNCTIONS 80 | # ------------------------------------------------------------------------------ 81 | 82 | 83 | def train(data, label_key) -> BaseEstimator: 84 | 85 | if data.dtype.names is None: 86 | raise ValueError("Column names are missing") 87 | else: 88 | keys = data.dtype.names 89 | 90 | feature_keys = [key for key in keys if key != label_key] 91 | x_train = data[feature_keys].tolist() 92 | y_train = data[label_key] 93 | 94 | model = RandomForestClassifier(random_state=42) 95 | model.fit(x_train, y_train) 96 | 97 | return model 98 | 99 | 100 | def load_dataset(source: IO, label_key: str) -> np.ndarray: 101 | data = np.genfromtxt(source, names=True, delimiter=",") 102 | 103 | if label_key not in data.dtype.names: 104 | raise IndexError(f"{label_key} is not in column names as {data.dtype.names}") 105 | 106 | types = [ 107 | (name, "=3.10", markers = "python_version < \"3.10\""} 12 | wrapt = ">=1.11,<2" 13 | 14 | [[package]] 15 | name = "atomicwrites" 16 | version = "1.4.0" 17 | description = "Atomic file writes." 18 | category = "dev" 19 | optional = false 20 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 21 | 22 | [[package]] 23 | name = "attrs" 24 | version = "21.4.0" 25 | description = "Classes Without Boilerplate" 26 | category = "dev" 27 | optional = false 28 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 29 | 30 | [package.extras] 31 | dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] 32 | docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] 33 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] 34 | tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] 35 | 36 | [[package]] 37 | name = "bandit" 38 | version = "1.7.4" 39 | description = "Security oriented static analyser for python code." 40 | category = "dev" 41 | optional = false 42 | python-versions = ">=3.7" 43 | 44 | [package.dependencies] 45 | colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} 46 | GitPython = ">=1.0.1" 47 | PyYAML = ">=5.3.1" 48 | stevedore = ">=1.20.0" 49 | 50 | [package.extras] 51 | test = ["coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml", "beautifulsoup4 (>=4.8.0)", "pylint (==1.9.4)"] 52 | toml = ["toml"] 53 | yaml = ["pyyaml"] 54 | 55 | [[package]] 56 | name = "black" 57 | version = "22.3.0" 58 | description = "The uncompromising code formatter." 59 | category = "dev" 60 | optional = false 61 | python-versions = ">=3.6.2" 62 | 63 | [package.dependencies] 64 | click = ">=8.0.0" 65 | mypy-extensions = ">=0.4.3" 66 | pathspec = ">=0.9.0" 67 | platformdirs = ">=2" 68 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 69 | typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} 70 | 71 | [package.extras] 72 | colorama = ["colorama (>=0.4.3)"] 73 | d = ["aiohttp (>=3.7.4)"] 74 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] 75 | uvloop = ["uvloop (>=0.15.2)"] 76 | 77 | [[package]] 78 | name = "click" 79 | version = "8.1.2" 80 | description = "Composable command line interface toolkit" 81 | category = "dev" 82 | optional = false 83 | python-versions = ">=3.7" 84 | 85 | [package.dependencies] 86 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 87 | 88 | [[package]] 89 | name = "colorama" 90 | version = "0.4.4" 91 | description = "Cross-platform colored terminal text." 92 | category = "dev" 93 | optional = false 94 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 95 | 96 | [[package]] 97 | name = "dill" 98 | version = "0.3.4" 99 | description = "serialize all of python" 100 | category = "dev" 101 | optional = false 102 | python-versions = ">=2.7, !=3.0.*" 103 | 104 | [package.extras] 105 | graph = ["objgraph (>=1.7.2)"] 106 | 107 | [[package]] 108 | name = "dodgy" 109 | version = "0.2.1" 110 | description = "Dodgy: Searches for dodgy looking lines in Python code" 111 | category = "dev" 112 | optional = false 113 | python-versions = "*" 114 | 115 | [[package]] 116 | name = "flake8" 117 | version = "4.0.1" 118 | description = "the modular source code checker: pep8 pyflakes and co" 119 | category = "dev" 120 | optional = false 121 | python-versions = ">=3.6" 122 | 123 | [package.dependencies] 124 | mccabe = ">=0.6.0,<0.7.0" 125 | pycodestyle = ">=2.8.0,<2.9.0" 126 | pyflakes = ">=2.4.0,<2.5.0" 127 | 128 | [[package]] 129 | name = "flake8-polyfill" 130 | version = "1.0.2" 131 | description = "Polyfill package for Flake8 plugins" 132 | category = "dev" 133 | optional = false 134 | python-versions = "*" 135 | 136 | [package.dependencies] 137 | flake8 = "*" 138 | 139 | [[package]] 140 | name = "gitdb" 141 | version = "4.0.9" 142 | description = "Git Object Database" 143 | category = "dev" 144 | optional = false 145 | python-versions = ">=3.6" 146 | 147 | [package.dependencies] 148 | smmap = ">=3.0.1,<6" 149 | 150 | [[package]] 151 | name = "gitpython" 152 | version = "3.1.27" 153 | description = "GitPython is a python library used to interact with Git repositories" 154 | category = "dev" 155 | optional = false 156 | python-versions = ">=3.7" 157 | 158 | [package.dependencies] 159 | gitdb = ">=4.0.1,<5" 160 | 161 | [[package]] 162 | name = "iniconfig" 163 | version = "1.1.1" 164 | description = "iniconfig: brain-dead simple config-ini parsing" 165 | category = "dev" 166 | optional = false 167 | python-versions = "*" 168 | 169 | [[package]] 170 | name = "isort" 171 | version = "5.10.1" 172 | description = "A Python utility / library to sort Python imports." 173 | category = "dev" 174 | optional = false 175 | python-versions = ">=3.6.1,<4.0" 176 | 177 | [package.extras] 178 | pipfile_deprecated_finder = ["pipreqs", "requirementslib"] 179 | requirements_deprecated_finder = ["pipreqs", "pip-api"] 180 | colors = ["colorama (>=0.4.3,<0.5.0)"] 181 | plugins = ["setuptools"] 182 | 183 | [[package]] 184 | name = "lazy-object-proxy" 185 | version = "1.7.1" 186 | description = "A fast and thorough lazy object proxy." 187 | category = "dev" 188 | optional = false 189 | python-versions = ">=3.6" 190 | 191 | [[package]] 192 | name = "mccabe" 193 | version = "0.6.1" 194 | description = "McCabe checker, plugin for flake8" 195 | category = "dev" 196 | optional = false 197 | python-versions = "*" 198 | 199 | [[package]] 200 | name = "mypy" 201 | version = "0.942" 202 | description = "Optional static typing for Python" 203 | category = "dev" 204 | optional = false 205 | python-versions = ">=3.6" 206 | 207 | [package.dependencies] 208 | mypy-extensions = ">=0.4.3" 209 | tomli = ">=1.1.0" 210 | typing-extensions = ">=3.10" 211 | 212 | [package.extras] 213 | dmypy = ["psutil (>=4.0)"] 214 | python2 = ["typed-ast (>=1.4.0,<2)"] 215 | reports = ["lxml"] 216 | 217 | [[package]] 218 | name = "mypy-extensions" 219 | version = "0.4.3" 220 | description = "Experimental type system extensions for programs checked with the mypy typechecker." 221 | category = "dev" 222 | optional = false 223 | python-versions = "*" 224 | 225 | [[package]] 226 | name = "numpy" 227 | version = "1.22.3" 228 | description = "NumPy is the fundamental package for array computing with Python." 229 | category = "main" 230 | optional = false 231 | python-versions = ">=3.8" 232 | 233 | [[package]] 234 | name = "packaging" 235 | version = "21.3" 236 | description = "Core utilities for Python packages" 237 | category = "dev" 238 | optional = false 239 | python-versions = ">=3.6" 240 | 241 | [package.dependencies] 242 | pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" 243 | 244 | [[package]] 245 | name = "pathspec" 246 | version = "0.9.0" 247 | description = "Utility library for gitignore style pattern matching of file paths." 248 | category = "dev" 249 | optional = false 250 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 251 | 252 | [[package]] 253 | name = "pbr" 254 | version = "5.8.1" 255 | description = "Python Build Reasonableness" 256 | category = "dev" 257 | optional = false 258 | python-versions = ">=2.6" 259 | 260 | [[package]] 261 | name = "pep8-naming" 262 | version = "0.10.0" 263 | description = "Check PEP-8 naming conventions, plugin for flake8" 264 | category = "dev" 265 | optional = false 266 | python-versions = "*" 267 | 268 | [package.dependencies] 269 | flake8-polyfill = ">=1.0.2,<2" 270 | 271 | [[package]] 272 | name = "platformdirs" 273 | version = "2.5.1" 274 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 275 | category = "dev" 276 | optional = false 277 | python-versions = ">=3.7" 278 | 279 | [package.extras] 280 | docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] 281 | test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] 282 | 283 | [[package]] 284 | name = "pluggy" 285 | version = "1.0.0" 286 | description = "plugin and hook calling mechanisms for python" 287 | category = "dev" 288 | optional = false 289 | python-versions = ">=3.6" 290 | 291 | [package.extras] 292 | dev = ["pre-commit", "tox"] 293 | testing = ["pytest", "pytest-benchmark"] 294 | 295 | [[package]] 296 | name = "prospector" 297 | version = "1.7.7" 298 | description = "" 299 | category = "dev" 300 | optional = false 301 | python-versions = ">=3.6.2,<4.0" 302 | 303 | [package.dependencies] 304 | dodgy = ">=0.2.1,<0.3.0" 305 | mccabe = ">=0.6.0,<0.7.0" 306 | pep8-naming = ">=0.3.3,<=0.10.0" 307 | pycodestyle = ">=2.6.0,<2.9.0" 308 | pydocstyle = ">=2.0.0" 309 | pyflakes = ">=2.2.0,<3" 310 | pylint = ">=2.8.3" 311 | pylint-celery = "0.3" 312 | pylint-django = ">=2.5,<2.6" 313 | pylint-flask = "0.6" 314 | pylint-plugin-utils = ">=0.7,<0.8" 315 | PyYAML = "*" 316 | requirements-detector = ">=0.7,<0.8" 317 | setoptconf-tmp = ">=0.3.1,<0.4.0" 318 | toml = ">=0.10.2,<0.11.0" 319 | 320 | [package.extras] 321 | with_bandit = ["bandit (>=1.5.1)"] 322 | with_everything = ["bandit (>=1.5.1)", "frosted (>=1.4.1)", "mypy (>=0.600)", "pyroma (>=2.4)", "vulture (>=1.5)"] 323 | with_frosted = ["frosted (>=1.4.1)"] 324 | with_mypy = ["mypy (>=0.600)"] 325 | with_pyroma = ["pyroma (>=2.4)"] 326 | with_vulture = ["vulture (>=1.5)"] 327 | 328 | [[package]] 329 | name = "py" 330 | version = "1.11.0" 331 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 332 | category = "dev" 333 | optional = false 334 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 335 | 336 | [[package]] 337 | name = "pycodestyle" 338 | version = "2.8.0" 339 | description = "Python style guide checker" 340 | category = "dev" 341 | optional = false 342 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 343 | 344 | [[package]] 345 | name = "pydocstyle" 346 | version = "6.1.1" 347 | description = "Python docstring style checker" 348 | category = "dev" 349 | optional = false 350 | python-versions = ">=3.6" 351 | 352 | [package.dependencies] 353 | snowballstemmer = "*" 354 | 355 | [package.extras] 356 | toml = ["toml"] 357 | 358 | [[package]] 359 | name = "pyflakes" 360 | version = "2.4.0" 361 | description = "passive checker of Python programs" 362 | category = "dev" 363 | optional = false 364 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 365 | 366 | [[package]] 367 | name = "pylint" 368 | version = "2.13.5" 369 | description = "python code static checker" 370 | category = "dev" 371 | optional = false 372 | python-versions = ">=3.6.2" 373 | 374 | [package.dependencies] 375 | astroid = ">=2.11.2,<=2.12.0-dev0" 376 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 377 | dill = ">=0.2" 378 | isort = ">=4.2.5,<6" 379 | mccabe = ">=0.6,<0.8" 380 | platformdirs = ">=2.2.0" 381 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 382 | typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} 383 | 384 | [package.extras] 385 | testutil = ["gitpython (>3)"] 386 | 387 | [[package]] 388 | name = "pylint-celery" 389 | version = "0.3" 390 | description = "pylint-celery is a Pylint plugin to aid Pylint in recognising and understandingerrors caused when using the Celery library" 391 | category = "dev" 392 | optional = false 393 | python-versions = "*" 394 | 395 | [package.dependencies] 396 | astroid = ">=1.0" 397 | pylint = ">=1.0" 398 | pylint-plugin-utils = ">=0.2.1" 399 | 400 | [[package]] 401 | name = "pylint-django" 402 | version = "2.5.3" 403 | description = "A Pylint plugin to help Pylint understand the Django web framework" 404 | category = "dev" 405 | optional = false 406 | python-versions = "*" 407 | 408 | [package.dependencies] 409 | pylint = ">=2.0,<3" 410 | pylint-plugin-utils = ">=0.7" 411 | 412 | [package.extras] 413 | for_tests = ["django-tables2", "factory-boy", "coverage", "pytest", "wheel", "django-tastypie", "pylint (>=2.13)"] 414 | with_django = ["django"] 415 | 416 | [[package]] 417 | name = "pylint-flask" 418 | version = "0.6" 419 | description = "pylint-flask is a Pylint plugin to aid Pylint in recognizing and understanding errors caused when using Flask" 420 | category = "dev" 421 | optional = false 422 | python-versions = "*" 423 | 424 | [package.dependencies] 425 | pylint-plugin-utils = ">=0.2.1" 426 | 427 | [[package]] 428 | name = "pylint-plugin-utils" 429 | version = "0.7" 430 | description = "Utilities and helpers for writing Pylint plugins" 431 | category = "dev" 432 | optional = false 433 | python-versions = ">=3.6.2" 434 | 435 | [package.dependencies] 436 | pylint = ">=1.7" 437 | 438 | [[package]] 439 | name = "pyparsing" 440 | version = "3.0.7" 441 | description = "Python parsing module" 442 | category = "dev" 443 | optional = false 444 | python-versions = ">=3.6" 445 | 446 | [package.extras] 447 | diagrams = ["jinja2", "railroad-diagrams"] 448 | 449 | [[package]] 450 | name = "pytest" 451 | version = "7.1.1" 452 | description = "pytest: simple powerful testing with Python" 453 | category = "dev" 454 | optional = false 455 | python-versions = ">=3.7" 456 | 457 | [package.dependencies] 458 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} 459 | attrs = ">=19.2.0" 460 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 461 | iniconfig = "*" 462 | packaging = "*" 463 | pluggy = ">=0.12,<2.0" 464 | py = ">=1.8.2" 465 | tomli = ">=1.0.0" 466 | 467 | [package.extras] 468 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] 469 | 470 | [[package]] 471 | name = "pyyaml" 472 | version = "6.0" 473 | description = "YAML parser and emitter for Python" 474 | category = "dev" 475 | optional = false 476 | python-versions = ">=3.6" 477 | 478 | [[package]] 479 | name = "requirements-detector" 480 | version = "0.7" 481 | description = "Python tool to find and list requirements of a Python project" 482 | category = "dev" 483 | optional = false 484 | python-versions = "*" 485 | 486 | [package.dependencies] 487 | astroid = ">=1.4" 488 | 489 | [[package]] 490 | name = "setoptconf-tmp" 491 | version = "0.3.1" 492 | description = "A module for retrieving program settings from various sources in a consistant method." 493 | category = "dev" 494 | optional = false 495 | python-versions = "*" 496 | 497 | [package.extras] 498 | yaml = ["pyyaml"] 499 | 500 | [[package]] 501 | name = "smmap" 502 | version = "5.0.0" 503 | description = "A pure Python implementation of a sliding window memory map manager" 504 | category = "dev" 505 | optional = false 506 | python-versions = ">=3.6" 507 | 508 | [[package]] 509 | name = "snowballstemmer" 510 | version = "2.2.0" 511 | description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." 512 | category = "dev" 513 | optional = false 514 | python-versions = "*" 515 | 516 | [[package]] 517 | name = "stevedore" 518 | version = "3.5.0" 519 | description = "Manage dynamic plugins for Python applications" 520 | category = "dev" 521 | optional = false 522 | python-versions = ">=3.6" 523 | 524 | [package.dependencies] 525 | pbr = ">=2.0.0,<2.1.0 || >2.1.0" 526 | 527 | [[package]] 528 | name = "toml" 529 | version = "0.10.2" 530 | description = "Python Library for Tom's Obvious, Minimal Language" 531 | category = "dev" 532 | optional = false 533 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 534 | 535 | [[package]] 536 | name = "tomli" 537 | version = "2.0.1" 538 | description = "A lil' TOML parser" 539 | category = "dev" 540 | optional = false 541 | python-versions = ">=3.7" 542 | 543 | [[package]] 544 | name = "typing-extensions" 545 | version = "4.1.1" 546 | description = "Backported and Experimental Type Hints for Python 3.6+" 547 | category = "dev" 548 | optional = false 549 | python-versions = ">=3.6" 550 | 551 | [[package]] 552 | name = "wrapt" 553 | version = "1.14.0" 554 | description = "Module for decorators, wrappers and monkey patching." 555 | category = "dev" 556 | optional = false 557 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 558 | 559 | [metadata] 560 | lock-version = "1.1" 561 | python-versions = "~3.9.0" 562 | content-hash = "7d17bc657fd15e5ead83f7f02594209dbb87eb628c74a30e6bc6ca98ee3fbab2" 563 | 564 | [metadata.files] 565 | astroid = [ 566 | {file = "astroid-2.11.2-py3-none-any.whl", hash = "sha256:cc8cc0d2d916c42d0a7c476c57550a4557a083081976bf42a73414322a6411d9"}, 567 | {file = "astroid-2.11.2.tar.gz", hash = "sha256:8d0a30fe6481ce919f56690076eafbb2fb649142a89dc874f1ec0e7a011492d0"}, 568 | ] 569 | atomicwrites = [ 570 | {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, 571 | {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, 572 | ] 573 | attrs = [ 574 | {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, 575 | {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, 576 | ] 577 | bandit = [ 578 | {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, 579 | {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, 580 | ] 581 | black = [ 582 | {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, 583 | {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, 584 | {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, 585 | {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, 586 | {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, 587 | {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, 588 | {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, 589 | {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, 590 | {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, 591 | {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, 592 | {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, 593 | {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, 594 | {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, 595 | {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, 596 | {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, 597 | {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, 598 | {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, 599 | {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, 600 | {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, 601 | {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, 602 | {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, 603 | {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, 604 | {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, 605 | ] 606 | click = [ 607 | {file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"}, 608 | {file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"}, 609 | ] 610 | colorama = [ 611 | {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, 612 | {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, 613 | ] 614 | dill = [ 615 | {file = "dill-0.3.4-py2.py3-none-any.whl", hash = "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f"}, 616 | {file = "dill-0.3.4.zip", hash = "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"}, 617 | ] 618 | dodgy = [ 619 | {file = "dodgy-0.2.1-py3-none-any.whl", hash = "sha256:51f54c0fd886fa3854387f354b19f429d38c04f984f38bc572558b703c0542a6"}, 620 | {file = "dodgy-0.2.1.tar.gz", hash = "sha256:28323cbfc9352139fdd3d316fa17f325cc0e9ac74438cbba51d70f9b48f86c3a"}, 621 | ] 622 | flake8 = [ 623 | {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, 624 | {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, 625 | ] 626 | flake8-polyfill = [ 627 | {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, 628 | {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, 629 | ] 630 | gitdb = [ 631 | {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, 632 | {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, 633 | ] 634 | gitpython = [ 635 | {file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"}, 636 | {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"}, 637 | ] 638 | iniconfig = [ 639 | {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, 640 | {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, 641 | ] 642 | isort = [ 643 | {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, 644 | {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, 645 | ] 646 | lazy-object-proxy = [ 647 | {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, 648 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, 649 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, 650 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, 651 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, 652 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, 653 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, 654 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, 655 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, 656 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, 657 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, 658 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, 659 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, 660 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, 661 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, 662 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, 663 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, 664 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, 665 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, 666 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, 667 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, 668 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, 669 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, 670 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, 671 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, 672 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, 673 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, 674 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, 675 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, 676 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, 677 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, 678 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, 679 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, 680 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, 681 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, 682 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, 683 | {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, 684 | ] 685 | mccabe = [ 686 | {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, 687 | {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, 688 | ] 689 | mypy = [ 690 | {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, 691 | {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, 692 | {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, 693 | {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, 694 | {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, 695 | {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, 696 | {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, 697 | {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, 698 | {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, 699 | {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, 700 | {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, 701 | {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, 702 | {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, 703 | {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, 704 | {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, 705 | {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, 706 | {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, 707 | {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, 708 | {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, 709 | {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, 710 | {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, 711 | {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, 712 | {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, 713 | ] 714 | mypy-extensions = [ 715 | {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, 716 | {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, 717 | ] 718 | numpy = [ 719 | {file = "numpy-1.22.3-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75"}, 720 | {file = "numpy-1.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab"}, 721 | {file = "numpy-1.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e"}, 722 | {file = "numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4"}, 723 | {file = "numpy-1.22.3-cp310-cp310-win32.whl", hash = "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430"}, 724 | {file = "numpy-1.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4"}, 725 | {file = "numpy-1.22.3-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce"}, 726 | {file = "numpy-1.22.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe"}, 727 | {file = "numpy-1.22.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5"}, 728 | {file = "numpy-1.22.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1"}, 729 | {file = "numpy-1.22.3-cp38-cp38-win32.whl", hash = "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62"}, 730 | {file = "numpy-1.22.3-cp38-cp38-win_amd64.whl", hash = "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676"}, 731 | {file = "numpy-1.22.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123"}, 732 | {file = "numpy-1.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802"}, 733 | {file = "numpy-1.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d"}, 734 | {file = "numpy-1.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168"}, 735 | {file = "numpy-1.22.3-cp39-cp39-win32.whl", hash = "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa"}, 736 | {file = "numpy-1.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a"}, 737 | {file = "numpy-1.22.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f"}, 738 | {file = "numpy-1.22.3.zip", hash = "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18"}, 739 | ] 740 | packaging = [ 741 | {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, 742 | {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, 743 | ] 744 | pathspec = [ 745 | {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, 746 | {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, 747 | ] 748 | pbr = [ 749 | {file = "pbr-5.8.1-py2.py3-none-any.whl", hash = "sha256:27108648368782d07bbf1cb468ad2e2eeef29086affd14087a6d04b7de8af4ec"}, 750 | {file = "pbr-5.8.1.tar.gz", hash = "sha256:66bc5a34912f408bb3925bf21231cb6f59206267b7f63f3503ef865c1a292e25"}, 751 | ] 752 | pep8-naming = [ 753 | {file = "pep8-naming-0.10.0.tar.gz", hash = "sha256:f3b4a5f9dd72b991bf7d8e2a341d2e1aa3a884a769b5aaac4f56825c1763bf3a"}, 754 | {file = "pep8_naming-0.10.0-py2.py3-none-any.whl", hash = "sha256:5d9f1056cb9427ce344e98d1a7f5665710e2f20f748438e308995852cfa24164"}, 755 | ] 756 | platformdirs = [ 757 | {file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"}, 758 | {file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"}, 759 | ] 760 | pluggy = [ 761 | {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, 762 | {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, 763 | ] 764 | prospector = [ 765 | {file = "prospector-1.7.7-py3-none-any.whl", hash = "sha256:2dec5dac06f136880a3710996c0886dcc99e739007bbc05afc32884973f5c058"}, 766 | {file = "prospector-1.7.7.tar.gz", hash = "sha256:c04b3d593e7c525cf9a742fed62afbe02e2874f0e42f2f56a49378fd94037360"}, 767 | ] 768 | py = [ 769 | {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, 770 | {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, 771 | ] 772 | pycodestyle = [ 773 | {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, 774 | {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, 775 | ] 776 | pydocstyle = [ 777 | {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, 778 | {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, 779 | ] 780 | pyflakes = [ 781 | {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, 782 | {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, 783 | ] 784 | pylint = [ 785 | {file = "pylint-2.13.5-py3-none-any.whl", hash = "sha256:c149694cfdeaee1aa2465e6eaab84c87a881a7d55e6e93e09466be7164764d1e"}, 786 | {file = "pylint-2.13.5.tar.gz", hash = "sha256:dab221658368c7a05242e673c275c488670144123f4bd262b2777249c1c0de9b"}, 787 | ] 788 | pylint-celery = [ 789 | {file = "pylint-celery-0.3.tar.gz", hash = "sha256:41e32094e7408d15c044178ea828dd524beedbdbe6f83f712c5e35bde1de4beb"}, 790 | ] 791 | pylint-django = [ 792 | {file = "pylint-django-2.5.3.tar.gz", hash = "sha256:0ac090d106c62fe33782a1d01bda1610b761bb1c9bf5035ced9d5f23a13d8591"}, 793 | {file = "pylint_django-2.5.3-py3-none-any.whl", hash = "sha256:56b12b6adf56d548412445bd35483034394a1a94901c3f8571980a13882299d5"}, 794 | ] 795 | pylint-flask = [ 796 | {file = "pylint-flask-0.6.tar.gz", hash = "sha256:f4d97de2216bf7bfce07c9c08b166e978fe9f2725de2a50a9845a97de7e31517"}, 797 | ] 798 | pylint-plugin-utils = [ 799 | {file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"}, 800 | {file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"}, 801 | ] 802 | pyparsing = [ 803 | {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, 804 | {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, 805 | ] 806 | pytest = [ 807 | {file = "pytest-7.1.1-py3-none-any.whl", hash = "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea"}, 808 | {file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"}, 809 | ] 810 | pyyaml = [ 811 | {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, 812 | {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, 813 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, 814 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, 815 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, 816 | {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, 817 | {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, 818 | {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, 819 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, 820 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, 821 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, 822 | {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, 823 | {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, 824 | {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, 825 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, 826 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, 827 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, 828 | {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, 829 | {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, 830 | {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, 831 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, 832 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, 833 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, 834 | {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, 835 | {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, 836 | {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, 837 | {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, 838 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, 839 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, 840 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, 841 | {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, 842 | {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, 843 | {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, 844 | ] 845 | requirements-detector = [ 846 | {file = "requirements-detector-0.7.tar.gz", hash = "sha256:0d1e13e61ed243f9c3c86e6cbb19980bcb3a0e0619cde2ec1f3af70fdbee6f7b"}, 847 | ] 848 | setoptconf-tmp = [ 849 | {file = "setoptconf-tmp-0.3.1.tar.gz", hash = "sha256:e0480addd11347ba52f762f3c4d8afa3e10ad0affbc53e3ffddc0ca5f27d5778"}, 850 | {file = "setoptconf_tmp-0.3.1-py3-none-any.whl", hash = "sha256:76035d5cd1593d38b9056ae12d460eca3aaa34ad05c315b69145e138ba80a745"}, 851 | ] 852 | smmap = [ 853 | {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, 854 | {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, 855 | ] 856 | snowballstemmer = [ 857 | {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, 858 | {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, 859 | ] 860 | stevedore = [ 861 | {file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"}, 862 | {file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"}, 863 | ] 864 | toml = [ 865 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 866 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 867 | ] 868 | tomli = [ 869 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, 870 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, 871 | ] 872 | typing-extensions = [ 873 | {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, 874 | {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, 875 | ] 876 | wrapt = [ 877 | {file = "wrapt-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:5a9a1889cc01ed2ed5f34574c90745fab1dd06ec2eee663e8ebeefe363e8efd7"}, 878 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:9a3ff5fb015f6feb78340143584d9f8a0b91b6293d6b5cf4295b3e95d179b88c"}, 879 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4b847029e2d5e11fd536c9ac3136ddc3f54bc9488a75ef7d040a3900406a91eb"}, 880 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9a5a544861b21e0e7575b6023adebe7a8c6321127bb1d238eb40d99803a0e8bd"}, 881 | {file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:88236b90dda77f0394f878324cfbae05ae6fde8a84d548cfe73a75278d760291"}, 882 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f0408e2dbad9e82b4c960274214af533f856a199c9274bd4aff55d4634dedc33"}, 883 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9d8c68c4145041b4eeae96239802cfdfd9ef927754a5be3f50505f09f309d8c6"}, 884 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:22626dca56fd7f55a0733e604f1027277eb0f4f3d95ff28f15d27ac25a45f71b"}, 885 | {file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:65bf3eb34721bf18b5a021a1ad7aa05947a1767d1aa272b725728014475ea7d5"}, 886 | {file = "wrapt-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09d16ae7a13cff43660155383a2372b4aa09109c7127aa3f24c3cf99b891c330"}, 887 | {file = "wrapt-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:debaf04f813ada978d7d16c7dfa16f3c9c2ec9adf4656efdc4defdf841fc2f0c"}, 888 | {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748df39ed634851350efa87690c2237a678ed794fe9ede3f0d79f071ee042561"}, 889 | {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1807054aa7b61ad8d8103b3b30c9764de2e9d0c0978e9d3fc337e4e74bf25faa"}, 890 | {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763a73ab377390e2af26042f685a26787c402390f682443727b847e9496e4a2a"}, 891 | {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8529b07b49b2d89d6917cfa157d3ea1dfb4d319d51e23030664a827fe5fd2131"}, 892 | {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:68aeefac31c1f73949662ba8affaf9950b9938b712fb9d428fa2a07e40ee57f8"}, 893 | {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59d7d92cee84a547d91267f0fea381c363121d70fe90b12cd88241bd9b0e1763"}, 894 | {file = "wrapt-1.14.0-cp310-cp310-win32.whl", hash = "sha256:3a88254881e8a8c4784ecc9cb2249ff757fd94b911d5df9a5984961b96113fff"}, 895 | {file = "wrapt-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:9a242871b3d8eecc56d350e5e03ea1854de47b17f040446da0e47dc3e0b9ad4d"}, 896 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a65bffd24409454b889af33b6c49d0d9bcd1a219b972fba975ac935f17bdf627"}, 897 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9d9fcd06c952efa4b6b95f3d788a819b7f33d11bea377be6b8980c95e7d10775"}, 898 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:db6a0ddc1282ceb9032e41853e659c9b638789be38e5b8ad7498caac00231c23"}, 899 | {file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:14e7e2c5f5fca67e9a6d5f753d21f138398cad2b1159913ec9e9a67745f09ba3"}, 900 | {file = "wrapt-1.14.0-cp35-cp35m-win32.whl", hash = "sha256:6d9810d4f697d58fd66039ab959e6d37e63ab377008ef1d63904df25956c7db0"}, 901 | {file = "wrapt-1.14.0-cp35-cp35m-win_amd64.whl", hash = "sha256:d808a5a5411982a09fef6b49aac62986274ab050e9d3e9817ad65b2791ed1425"}, 902 | {file = "wrapt-1.14.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b77159d9862374da213f741af0c361720200ab7ad21b9f12556e0eb95912cd48"}, 903 | {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36a76a7527df8583112b24adc01748cd51a2d14e905b337a6fefa8b96fc708fb"}, 904 | {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0057b5435a65b933cbf5d859cd4956624df37b8bf0917c71756e4b3d9958b9e"}, 905 | {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0a4ca02752ced5f37498827e49c414d694ad7cf451ee850e3ff160f2bee9d3"}, 906 | {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8c6be72eac3c14baa473620e04f74186c5d8f45d80f8f2b4eda6e1d18af808e8"}, 907 | {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:21b1106bff6ece8cb203ef45b4f5778d7226c941c83aaaa1e1f0f4f32cc148cd"}, 908 | {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:493da1f8b1bb8a623c16552fb4a1e164c0200447eb83d3f68b44315ead3f9036"}, 909 | {file = "wrapt-1.14.0-cp36-cp36m-win32.whl", hash = "sha256:89ba3d548ee1e6291a20f3c7380c92f71e358ce8b9e48161401e087e0bc740f8"}, 910 | {file = "wrapt-1.14.0-cp36-cp36m-win_amd64.whl", hash = "sha256:729d5e96566f44fccac6c4447ec2332636b4fe273f03da128fff8d5559782b06"}, 911 | {file = "wrapt-1.14.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:891c353e95bb11abb548ca95c8b98050f3620a7378332eb90d6acdef35b401d4"}, 912 | {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23f96134a3aa24cc50614920cc087e22f87439053d886e474638c68c8d15dc80"}, 913 | {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6807bcee549a8cb2f38f73f469703a1d8d5d990815c3004f21ddb68a567385ce"}, 914 | {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6915682f9a9bc4cf2908e83caf5895a685da1fbd20b6d485dafb8e218a338279"}, 915 | {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f2f3bc7cd9c9fcd39143f11342eb5963317bd54ecc98e3650ca22704b69d9653"}, 916 | {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3a71dbd792cc7a3d772ef8cd08d3048593f13d6f40a11f3427c000cf0a5b36a0"}, 917 | {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5a0898a640559dec00f3614ffb11d97a2666ee9a2a6bad1259c9facd01a1d4d9"}, 918 | {file = "wrapt-1.14.0-cp37-cp37m-win32.whl", hash = "sha256:167e4793dc987f77fd476862d32fa404d42b71f6a85d3b38cbce711dba5e6b68"}, 919 | {file = "wrapt-1.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d066ffc5ed0be00cd0352c95800a519cf9e4b5dd34a028d301bdc7177c72daf3"}, 920 | {file = "wrapt-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d9bdfa74d369256e4218000a629978590fd7cb6cf6893251dad13d051090436d"}, 921 | {file = "wrapt-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2498762814dd7dd2a1d0248eda2afbc3dd9c11537bc8200a4b21789b6df6cd38"}, 922 | {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f24ca7953f2643d59a9c87d6e272d8adddd4a53bb62b9208f36db408d7aafc7"}, 923 | {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b835b86bd5a1bdbe257d610eecab07bf685b1af2a7563093e0e69180c1d4af1"}, 924 | {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b21650fa6907e523869e0396c5bd591cc326e5c1dd594dcdccac089561cacfb8"}, 925 | {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:354d9fc6b1e44750e2a67b4b108841f5f5ea08853453ecbf44c81fdc2e0d50bd"}, 926 | {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f83e9c21cd5275991076b2ba1cd35418af3504667affb4745b48937e214bafe"}, 927 | {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61e1a064906ccba038aa3c4a5a82f6199749efbbb3cef0804ae5c37f550eded0"}, 928 | {file = "wrapt-1.14.0-cp38-cp38-win32.whl", hash = "sha256:28c659878f684365d53cf59dc9a1929ea2eecd7ac65da762be8b1ba193f7e84f"}, 929 | {file = "wrapt-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:b0ed6ad6c9640671689c2dbe6244680fe8b897c08fd1fab2228429b66c518e5e"}, 930 | {file = "wrapt-1.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3f7e671fb19734c872566e57ce7fc235fa953d7c181bb4ef138e17d607dc8a1"}, 931 | {file = "wrapt-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87fa943e8bbe40c8c1ba4086971a6fefbf75e9991217c55ed1bcb2f1985bd3d4"}, 932 | {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4775a574e9d84e0212f5b18886cace049a42e13e12009bb0491562a48bb2b758"}, 933 | {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d57677238a0c5411c76097b8b93bdebb02eb845814c90f0b01727527a179e4d"}, 934 | {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00108411e0f34c52ce16f81f1d308a571df7784932cc7491d1e94be2ee93374b"}, 935 | {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d332eecf307fca852d02b63f35a7872de32d5ba8b4ec32da82f45df986b39ff6"}, 936 | {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:01f799def9b96a8ec1ef6b9c1bbaf2bbc859b87545efbecc4a78faea13d0e3a0"}, 937 | {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47045ed35481e857918ae78b54891fac0c1d197f22c95778e66302668309336c"}, 938 | {file = "wrapt-1.14.0-cp39-cp39-win32.whl", hash = "sha256:2eca15d6b947cfff51ed76b2d60fd172c6ecd418ddab1c5126032d27f74bc350"}, 939 | {file = "wrapt-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb36fbb48b22985d13a6b496ea5fb9bb2a076fea943831643836c9f6febbcfdc"}, 940 | {file = "wrapt-1.14.0.tar.gz", hash = "sha256:8323a43bd9c91f62bb7d4be74cc9ff10090e7ef820e27bfe8815c57e68261311"}, 941 | ] 942 | -------------------------------------------------------------------------------- /kfp/components/transform/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "kfp_sample_transform" 3 | version = "0.0.1" 4 | description = "transform component of kfp sample pipeline" 5 | authors = ["Repro AI Lab Team "] 6 | license = "MIT" 7 | 8 | [tool.poetry.dependencies] 9 | python = "~3.9.0" 10 | pip = "*" 11 | numpy = "^1.22.3" 12 | 13 | [tool.poetry.dev-dependencies] 14 | pydocstyle = "*" 15 | bandit = "*" 16 | prospector = "*" 17 | mypy = "*" 18 | pytest = "*" 19 | black = { version = "*", allow-prereleases = true } 20 | 21 | [build-system] 22 | requires = ["poetry>=0.12"] 23 | build-backend = "poetry.masonry.api" -------------------------------------------------------------------------------- /kfp/components/transform/setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501 3 | 4 | [mypy] 5 | ignore_missing_imports = true 6 | -------------------------------------------------------------------------------- /kfp/components/transform/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AseiSugiyama/lab_sample_pipelines/bff27728c15cbd29351b4970da312278409220de/kfp/components/transform/src/__init__.py -------------------------------------------------------------------------------- /kfp/components/transform/src/transform.py: -------------------------------------------------------------------------------- 1 | """Data Generator implementation.""" 2 | 3 | import argparse 4 | from dataclasses import dataclass 5 | from typing import IO, Tuple, get_type_hints 6 | from pathlib import Path 7 | 8 | import numpy as np 9 | 10 | TARGET = "species" 11 | 12 | 13 | # 14 | # COMPONENT ARGUMENTS 15 | # ------------------------------------------------------------------------------ 16 | 17 | 18 | @dataclass 19 | class ComponentArguments: 20 | """Argument of the component. Note: Data Generator has no inputs.""" 21 | 22 | train_data_path: str 23 | eval_data_path: str 24 | suffix: str 25 | 26 | 27 | @dataclass 28 | class OutputDestinations: 29 | """Outputs of the component.""" 30 | 31 | transformed_train_data_path: str 32 | transformed_eval_data_path: str 33 | 34 | 35 | @dataclass 36 | class Artifacts: 37 | component_arguments: ComponentArguments 38 | output_destinations: OutputDestinations 39 | 40 | @classmethod 41 | def arg_parser(cls) -> argparse.ArgumentParser: 42 | """Parse component argument and return as ComponentArguments.""" 43 | parser = argparse.ArgumentParser() 44 | # generate argument parser based on ComponentArgument's definition 45 | for artifact in get_type_hints(cls).values(): 46 | for arg_name, arg_type in get_type_hints(artifact).items(): 47 | parser.add_argument(arg_name, type=arg_type) 48 | 49 | return parser 50 | 51 | @classmethod 52 | def from_args(cls) -> "Artifacts": 53 | args = vars(cls.arg_parser().parse_args()) 54 | 55 | artifacts = {} 56 | for key, artifact_cls in get_type_hints(cls).items(): 57 | existed_keys = get_type_hints(artifact_cls).keys() 58 | filtered_vars = {k: v for k, v in args.items() if k in existed_keys} 59 | 60 | artifacts[key] = artifact_cls(**filtered_vars) 61 | # parse args and convert into PipelineArguments 62 | return cls(**artifacts) 63 | 64 | 65 | # 66 | # MAIN FUNCTION 67 | # ------------------------------------------------------------------------------ 68 | 69 | 70 | def main(args: ComponentArguments) -> Tuple[np.ndarray, np.ndarray]: 71 | def download(data: str): 72 | with Path(data).open() as f: 73 | return fetch_dataset(f) 74 | 75 | datasets = map(download, [args.train_data_path, args.eval_data_path]) 76 | 77 | def _transform(data): 78 | return transform(data, args.suffix) 79 | 80 | train_data, eval_data = map(_transform, datasets) 81 | 82 | return train_data, eval_data 83 | 84 | 85 | # 86 | # SUB FUNCTIONS 87 | # ------------------------------------------------------------------------------ 88 | 89 | 90 | def transform(data: np.ndarray, suffix: str) -> np.ndarray: 91 | if data.dtype.names: 92 | names = (name + suffix for name in data.dtype.names) 93 | formats = (data[name].dtype for name in data.dtype.names) 94 | else: 95 | raise ValueError("Column names are missing") 96 | 97 | dtypes = list(zip(names, formats)) 98 | 99 | return np.array(data, dtype=dtypes) 100 | 101 | 102 | def fetch_dataset(source: IO) -> np.ndarray: 103 | data = np.genfromtxt(source, names=True, delimiter=",") 104 | 105 | if TARGET not in data.dtype.names: 106 | raise IndexError(f"{TARGET} is not in column names as {data.dtype.names}") 107 | 108 | types = [ 109 | (name, " Union[str, None]: 36 | path = Path(toml_path) 37 | lines = path.read_text().split("\n") 38 | for line in lines: 39 | if line.startswith("version = "): 40 | _, right = line.split("=") 41 | return right.replace('"', "").strip() 42 | return "latest" 43 | 44 | 45 | def get_component_spec(name: str) -> str: 46 | base_dir = f"components/{name.replace('-', '_')}" 47 | version = get_version_from_toml(f"{base_dir}/pyproject.toml") 48 | tag = f"v{version}" 49 | image = f"{GCP_GCR_ENDPOINT}/{GCP_PROJECT_ID}/{COMPONENT_PREFIX}-{name}:{tag}" 50 | path = Path(f"{base_dir}/{name.replace('-', '_')}.yaml") 51 | template = Template(path.read_text()) 52 | return template.substitute(tagged_name=image) 53 | 54 | 55 | # 56 | # COMPONENTS 57 | # ------------------------------------------------------------------------------ 58 | 59 | 60 | def _data_generator_op() -> kfp.dsl.ContainerOp: 61 | name = "data-generator" 62 | component_spec = get_component_spec(name) 63 | data_generator_op = kfp.components.load_component_from_text(component_spec) 64 | return data_generator_op() 65 | 66 | 67 | def _transform_op( 68 | train_data_path: str, eval_data_path: str, suffix: str 69 | ) -> kfp.dsl.ContainerOp: 70 | name = "transform" 71 | component_spec = get_component_spec(name) 72 | data_generator_op = kfp.components.load_component_from_text(component_spec) 73 | return data_generator_op( 74 | train_data_path=train_data_path, eval_data_path=eval_data_path, suffix=suffix 75 | ) 76 | 77 | 78 | def _trainer_op(transformed_train_data_path: str, suffix: str) -> kfp.dsl.ContainerOp: 79 | name = "trainer" 80 | component_spec = get_component_spec(name) 81 | trainer_op = kfp.components.load_component_from_text(component_spec) 82 | return trainer_op( 83 | transformed_train_data_path=transformed_train_data_path, suffix=suffix 84 | ) 85 | 86 | 87 | def _evaluator_op( 88 | trained_model_path: str, transformed_eval_data_path: str, suffix: str 89 | ) -> kfp.dsl.ContainerOp: 90 | name = "evaluator" 91 | component_spec = get_component_spec(name) 92 | evaluator_op = kfp.components.load_component_from_text(component_spec) 93 | return evaluator_op( 94 | trained_model_path=trained_model_path, 95 | transformed_eval_data_path=transformed_eval_data_path, 96 | suffix=suffix, 97 | ) 98 | 99 | 100 | # 101 | # PIPELINE 102 | # ------------------------------------------------------------------------------ 103 | 104 | 105 | @kfp.dsl.pipeline( 106 | name=PIPELINE_NAME, 107 | pipeline_root=f"gs://{GCP_GCS_PIPELINE_ROOT}/", 108 | ) 109 | def kfp_sample_pipeline(suffix: str = "_xf"): 110 | data_generator = _data_generator_op() 111 | transform = _transform_op( 112 | train_data_path=data_generator.outputs[GeneratedData.TrainData.value], 113 | eval_data_path=data_generator.outputs[GeneratedData.EvalData.value], 114 | suffix=suffix, 115 | ) 116 | trainer = _trainer_op( 117 | transformed_train_data_path=transform.outputs[ 118 | GeneratedData.TransformedTrainData.value 119 | ], 120 | suffix=suffix, 121 | ) 122 | _ = _evaluator_op( 123 | trained_model_path=trainer.outputs[GeneratedData.TrainedModel.value], 124 | transformed_eval_data_path=transform.outputs[ 125 | GeneratedData.TransformedEvalData.value 126 | ], 127 | suffix=suffix, 128 | ) 129 | 130 | 131 | # Compile the pipeline with V2 SDK to test the compatibility between V1 and V2 SDK 132 | compiler.Compiler().compile( 133 | pipeline_func=kfp_sample_pipeline, 134 | package_path="kfp_sample_pipeline.json", 135 | ) 136 | -------------------------------------------------------------------------------- /kfp/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "sample_pipeline" 3 | version = "0.0.2" 4 | description = "KFP Sample Pipeline." 5 | authors = ["Repro AI Lab Team "] 6 | license = "MIT" 7 | 8 | [tool.poetry.dependencies] 9 | python = "~3.9.0" 10 | kfp = "^1.8" 11 | pip = "*" 12 | google-cloud-aiplatform = "^1.12.0" 13 | 14 | [tool.poetry.dev-dependencies] 15 | black = { version = "*", allow-prereleases = true } 16 | flake8 = "*" 17 | isort = "*" 18 | mypy = "*" 19 | pydocstyle = "*" 20 | pytest = "*" 21 | 22 | [build-system] 23 | requires = ["poetry>=0.12"] 24 | build-backend = "poetry.masonry.api" -------------------------------------------------------------------------------- /kfp/setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501 3 | 4 | [mypy] 5 | ignore_missing_imports = true 6 | --------------------------------------------------------------------------------