├── .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 |
--------------------------------------------------------------------------------