From ac6411ffe35253d5b94f8a3af1a8fa6110c9fe1a Mon Sep 17 00:00:00 2001 From: Fredrik Nestvold Larsen <59914223+Nestvold@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:25:13 +0200 Subject: [PATCH] init --- .github/workflows/deploy.yaml | 29 + .gitignore | 278 +++++ cdf.toml | 14 + ice-cream-dataops/build_info.test.yaml | 435 ++++++++ ice-cream-dataops/config.test.yaml | 40 + .../auth/admin.readonly.group.yaml | 144 +++ .../auth/admin.readwrite.group.yaml | 128 +++ .../data_foundation/auth/data_developer.yaml | 131 +++ .../bootcamp/data_foundation/module.toml | 7 + .../ice_cream_api/auth/icapi_extractors.yaml | 63 ++ .../data_sets/icapi.DataSet.yaml | 3 + .../extraction_pipelines/ep_icapi_assets.yaml | 8 + .../ep_icapi_datapoints.yaml | 8 + .../ep_icapi_timeseries.yaml | 5 + .../ice_cream_api/functions/functions.yaml | 45 + .../icapi_assets_extractor/config.py | 18 + .../extractor_config.yaml | 26 + .../icapi_assets_extractor/handler.py | 45 + .../ice_cream_factory_api.py | 37 + .../icapi_assets_extractor/requirements.txt | 3 + .../icapi_datapoints_extractor/config.py | 22 + .../extractor_config.yaml | 35 + .../icapi_datapoints_extractor/handler.py | 108 ++ .../ice_cream_factory_api.py | 56 + .../requirements.txt | 2 + .../icapi_timeseries_extractor/config.py | 13 + .../extractor_config.yaml | 23 + .../icapi_timeseries_extractor/handler.py | 45 + .../ice_cream_factory_api.py | 43 + .../requirements.txt | 2 + .../ice_cream_api/functions/schedules.yaml | 15 + .../bootcamp/ice_cream_api/module.toml | 7 + .../raw/extraction_sources.Table.yaml | 4 + .../use_cases/oee/auth/data_pipeline_oee.yaml | 37 + .../use_cases/oee/data_sets/data_sets.yaml | 2 + .../use_cases/oee/functions/functions.yaml | 8 + .../oee/functions/oee_timeseries/handler.py | 128 +++ .../functions/oee_timeseries/requirements.txt | 5 + .../use_cases/oee/functions/schedules.yaml | 118 +++ .../bootcamp/use_cases/oee/module.toml | 7 + poetry.lock | 995 ++++++++++++++++++ pyproject.toml | 15 + temp.py | 1 + 43 files changed, 3158 insertions(+) create mode 100644 .github/workflows/deploy.yaml create mode 100644 .gitignore create mode 100644 cdf.toml create mode 100644 ice-cream-dataops/build_info.test.yaml create mode 100644 ice-cream-dataops/config.test.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readonly.group.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readwrite.group.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/data_foundation/auth/data_developer.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/data_foundation/module.toml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/auth/icapi_extractors.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/data_sets/icapi.DataSet.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_assets.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_datapoints.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_timeseries.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/functions.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/config.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/extractor_config.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/handler.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/ice_cream_factory_api.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/requirements.txt create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/config.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/extractor_config.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/handler.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/ice_cream_factory_api.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/requirements.txt create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/config.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/extractor_config.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/handler.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/ice_cream_factory_api.py create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/requirements.txt create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/schedules.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/module.toml create mode 100644 ice-cream-dataops/modules/bootcamp/ice_cream_api/raw/extraction_sources.Table.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/use_cases/oee/auth/data_pipeline_oee.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/use_cases/oee/data_sets/data_sets.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/functions.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/handler.py create mode 100644 ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/requirements.txt create mode 100644 ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml create mode 100644 ice-cream-dataops/modules/bootcamp/use_cases/oee/module.toml create mode 100644 poetry.lock create mode 100644 pyproject.toml create mode 100644 temp.py diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..feaa7f1 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,29 @@ +name: Toolkit Dry Run + +on: + push: + branches: + - main + +jobs: + build-modules: + runs-on: ubuntu-latest + # refers to the Environment concept in GitHub + environment: dev + name: Deploy + container: + image: cognite/toolkit:0.3.2 + env: + CDF_CLUSTER: ${{ vars.CDF_CLUSTER }} + CDF_PROJECT: ${{ vars.CDF_PROJECT }} + IDP_CLIENT_ID: ${{ vars.IDP_CLIENT_ID }} + IDP_CLIENT_SECRET: ${{ secrets.IDP_CLIENT_SECRET }} + IDP_TENANT_ID: ${{ vars.IDP_TENANT_ID }} + volumes: + - :/app + steps: + - uses: actions/checkout@v4 + - name: Build the modules + run: cdf build + - name: Deploy the modules + run: cdf deploy diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..845d7fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,278 @@ +# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig +# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,python,macos,git,windows +# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,python,macos,git,windows + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +.local/ +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,python,macos,git,windows + +# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) +*/.venv.* +.venv.* +build.* +build/ +function_local_venvs/ diff --git a/cdf.toml b/cdf.toml new file mode 100644 index 0000000..9715fae --- /dev/null +++ b/cdf.toml @@ -0,0 +1,14 @@ +[cdf] +default_organization_dir = "ice-cream-dataops" +default_env = "test" + +[modules] +# This is the version of the modules. It should not be changed manually. +# It will be updated by the 'cdf module upgrade' command. +version = "0.3.2" + + +[plugins] +run = true +pull = false +dump = false diff --git a/ice-cream-dataops/build_info.test.yaml b/ice-cream-dataops/build_info.test.yaml new file mode 100644 index 0000000..ea7b3ee --- /dev/null +++ b/ice-cream-dataops/build_info.test.yaml @@ -0,0 +1,435 @@ +# DO NOT MODIFY THIS FILE MANUALLY. IT IS AUTO-GENERATED BY THE COGNITE TOOLKIT. +modules: + version: 0.3.2 + modules: + - name: data_foundation + location: + path: modules/bootcamp/data_foundation + hash: f3f72fe1 + build_variables: + - key: CDF_PROJECT + value: ${CDF_PROJECT} + is_selected: true + location: modules/bootcamp + - key: IDP_CLIENT_ID + value: ${IDP_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: IDP_CLIENT_SECRET + value: ${IDP_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: IDP_TENANT_ID + value: ${IDP_TENANT_ID} + is_selected: true + location: modules/bootcamp + - key: CDF_URL + value: https://westeurope-1.cognitedata.com + is_selected: true + location: modules/bootcamp + - key: IDP_SCOPES + value: https://westeurope-1.cognitedata.com/.default + is_selected: true + location: modules/bootcamp + - key: IDP_TOKEN_URL + value: ${IDP_TOKEN_URL} + is_selected: true + location: modules/bootcamp + - key: data_developer_source_id + value: ${DATA_DEVELOPER_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_source_id + value: ${DATA_PIPELINE_OEE_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: readwrite_source_id + value: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + is_selected: true + location: modules/bootcamp + - key: readonly_source_id + value: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_source_id + value: ${ICAPI_EXTRACTORS_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_client_id + value: ${DATA_PIPELINE_OEE_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_client_secret + value: ${DATA_PIPELINE_OEE_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_client_id + value: ${ICAPI_EXTRACTORS_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_client_secret + value: ${ICAPI_EXTRACTORS_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: icapi_ds_external_id + value: ds_icapi + is_selected: true + location: modules/bootcamp + - key: uc_oee_ds_external_id + value: ds_uc_oee + is_selected: true + location: modules/bootcamp + resources: + auth: + - identifier: + name: gp_admin_readonly + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readonly.group.yaml + hash: e0b16472 + kind: Group + - identifier: + name: gp_admin_read_write + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readwrite.group.yaml + hash: 5d76eb9d + kind: Group + - identifier: + name: data_developer + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/data_foundation/auth/data_developer.yaml + hash: 4da5fb8a + kind: Group + warning_count: 0 + status: Success + - name: ice_cream_api + location: + path: modules/bootcamp/ice_cream_api + hash: b1381b08 + build_variables: + - key: CDF_PROJECT + value: ${CDF_PROJECT} + is_selected: true + location: modules/bootcamp + - key: IDP_CLIENT_ID + value: ${IDP_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: IDP_CLIENT_SECRET + value: ${IDP_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: IDP_TENANT_ID + value: ${IDP_TENANT_ID} + is_selected: true + location: modules/bootcamp + - key: CDF_URL + value: https://westeurope-1.cognitedata.com + is_selected: true + location: modules/bootcamp + - key: IDP_SCOPES + value: https://westeurope-1.cognitedata.com/.default + is_selected: true + location: modules/bootcamp + - key: IDP_TOKEN_URL + value: ${IDP_TOKEN_URL} + is_selected: true + location: modules/bootcamp + - key: data_developer_source_id + value: ${DATA_DEVELOPER_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_source_id + value: ${DATA_PIPELINE_OEE_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: readwrite_source_id + value: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + is_selected: true + location: modules/bootcamp + - key: readonly_source_id + value: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_source_id + value: ${ICAPI_EXTRACTORS_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_client_id + value: ${DATA_PIPELINE_OEE_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_client_secret + value: ${DATA_PIPELINE_OEE_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_client_id + value: ${ICAPI_EXTRACTORS_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_client_secret + value: ${ICAPI_EXTRACTORS_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: icapi_ds_external_id + value: ds_icapi + is_selected: true + location: modules/bootcamp + - key: uc_oee_ds_external_id + value: ds_uc_oee + is_selected: true + location: modules/bootcamp + resources: + extraction_pipelines: + - identifier: + externalId: ep_icapi_assets + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_assets.yaml + hash: 5f0dd030 + kind: ExtractionPipeline + - identifier: + externalId: ep_icapi_datapoints + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_datapoints.yaml + hash: 81abe813 + kind: ExtractionPipeline + - identifier: + externalId: ep_icapi_timeseries + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_timeseries.yaml + hash: 0dd35906 + kind: ExtractionPipeline + auth: + - identifier: + name: icapi_extractor + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/auth/icapi_extractors.yaml + hash: abe83767 + kind: Group + functions: + - identifier: + externalId: icapi_assets_extractor + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/functions.yaml + hash: 7a3f72cf + kind: Function + - identifier: + externalId: icapi_datapoints_extractor + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/functions.yaml + hash: 7a3f72cf + kind: Function + - identifier: + externalId: icapi_timeseries_extractor + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/functions.yaml + hash: 7a3f72cf + kind: Function + - identifier: + functionExternalId: icapi_datapoints_extractor + name: Frontfill every 10 minutes last hour of data (streamer) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/schedules.yaml + hash: a151e5eb + kind: Schedule + - identifier: + functionExternalId: icapi_datapoints_extractor + name: Backfill once a day for the last 30 days (gap filling) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/schedules.yaml + hash: a151e5eb + kind: Schedule + data_sets: + - identifier: + externalId: ds_icapi + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/data_sets/icapi.DataSet.yaml + hash: 252ee3a7 + kind: DataSet + raw: + - identifier: + dbName: State Store + tableName: icapi_datapoints_extractor + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/raw/extraction_sources.Table.yaml + hash: fe459b6c + kind: Table + - identifier: + dbName: ice_cream_api + tableName: icapi_assets_extractor + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/ice_cream_api/raw/extraction_sources.Table.yaml + hash: fe459b6c + kind: Table + warning_count: 0 + status: Success + - name: oee + location: + path: modules/bootcamp/use_cases/oee + hash: 06d09ad5 + build_variables: + - key: CDF_PROJECT + value: ${CDF_PROJECT} + is_selected: true + location: modules/bootcamp + - key: IDP_CLIENT_ID + value: ${IDP_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: IDP_CLIENT_SECRET + value: ${IDP_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: IDP_TENANT_ID + value: ${IDP_TENANT_ID} + is_selected: true + location: modules/bootcamp + - key: CDF_URL + value: https://westeurope-1.cognitedata.com + is_selected: true + location: modules/bootcamp + - key: IDP_SCOPES + value: https://westeurope-1.cognitedata.com/.default + is_selected: true + location: modules/bootcamp + - key: IDP_TOKEN_URL + value: ${IDP_TOKEN_URL} + is_selected: true + location: modules/bootcamp + - key: data_developer_source_id + value: ${DATA_DEVELOPER_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_source_id + value: ${DATA_PIPELINE_OEE_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: readwrite_source_id + value: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + is_selected: true + location: modules/bootcamp + - key: readonly_source_id + value: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_source_id + value: ${ICAPI_EXTRACTORS_OBJECT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_client_id + value: ${DATA_PIPELINE_OEE_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: data_pipeline_oee_client_secret + value: ${DATA_PIPELINE_OEE_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_client_id + value: ${ICAPI_EXTRACTORS_CLIENT_ID} + is_selected: true + location: modules/bootcamp + - key: icapi_extractors_client_secret + value: ${ICAPI_EXTRACTORS_CLIENT_SECRET} + is_selected: true + location: modules/bootcamp + - key: icapi_ds_external_id + value: ds_icapi + is_selected: true + location: modules/bootcamp + - key: uc_oee_ds_external_id + value: ds_uc_oee + is_selected: true + location: modules/bootcamp + resources: + auth: + - identifier: + name: oee_pipeline + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/auth/data_pipeline_oee.yaml + hash: 1b5b11c6 + kind: Group + functions: + - identifier: + externalId: oee_timeseries + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/functions.yaml + hash: 3579da40 + kind: Function + - identifier: + functionExternalId: oee_timeseries + name: Run calculations every 10 minutes for last hour of data + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Oslo) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Nuremberg) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Marseille) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Houston) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Sao Paulo) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Kuala Lumpur) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Chicago) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (Rotterdam) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + - identifier: + functionExternalId: oee_timeseries + name: Run calculations once a day for 30 days history (London) + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml + hash: 1dd72b15 + kind: Schedule + data_sets: + - identifier: + externalId: ds_uc_oee + source: + path: /Users/fredrik.larsen@cognitedata.com/Bootcamp/ice-cream-dataops/modules/bootcamp/use_cases/oee/data_sets/data_sets.yaml + hash: 3d953d35 + kind: DataSet + warning_count: 0 + status: Success diff --git a/ice-cream-dataops/config.test.yaml b/ice-cream-dataops/config.test.yaml new file mode 100644 index 0000000..f3cad24 --- /dev/null +++ b/ice-cream-dataops/config.test.yaml @@ -0,0 +1,40 @@ +environment: + name: IceCreamFactory + project: cdf-bootcamp-78-test + type: dev + selected: + - modules/bootcamp/data_foundation + - modules/bootcamp/ice_cream_api + - modules/bootcamp/use_cases/oee + +variables: + modules: + bootcamp: + CDF_PROJECT: ${CDF_PROJECT} + IDP_CLIENT_ID: ${IDP_CLIENT_ID} + IDP_CLIENT_SECRET: ${IDP_CLIENT_SECRET} + IDP_TENANT_ID: ${IDP_TENANT_ID} + # This is related to the cluster where the CDF project is hosted. + CDF_URL: https://westeurope-1.cognitedata.com + IDP_SCOPES: https://westeurope-1.cognitedata.com/.default + IDP_TOKEN_URL: ${IDP_TOKEN_URL} + # Groups + # OBJECT ID FOR TEST/PROD DATA DEVELOPER ENTRA GROUP + data_developer_source_id: ${DATA_DEVELOPER_OBJECT_ID} + # OBJECT ID FOR TEST/PROD DATA PIPELINE OEE ENTRA GROUP + data_pipeline_oee_source_id: ${DATA_PIPELINE_OEE_OBJECT_ID} + # OBJECT ID FOR TEST/PROD ADMIN TK ENTRA GROUP + readwrite_source_id: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + # OBJECT ID FOR TEST/PROD ADMIN TK ENTRA GROUP + readonly_source_id: a9bb9da4-5416-4390-8fd7-ccbf24af4b3d + # OBJECT ID FOR TEST/PROD ADMIN TK ENTRA GROUP + icapi_extractors_source_id: ${ICAPI_EXTRACTORS_OBJECT_ID} + # Client Ids + data_pipeline_oee_client_id: ${DATA_PIPELINE_OEE_CLIENT_ID} + data_pipeline_oee_client_secret: ${DATA_PIPELINE_OEE_CLIENT_SECRET} + icapi_extractors_client_id: ${ICAPI_EXTRACTORS_CLIENT_ID} + icapi_extractors_client_secret: ${ICAPI_EXTRACTORS_CLIENT_SECRET} + + # Custom + icapi_ds_external_id: 'ds_icapi' + uc_oee_ds_external_id: 'ds_uc_oee' diff --git a/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readonly.group.yaml b/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readonly.group.yaml new file mode 100644 index 0000000..f3c912b --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readonly.group.yaml @@ -0,0 +1,144 @@ +name: 'gp_admin_readonly' +sourceId: '{{readonly_source_id}}' +metadata: + origin: 'cdf-project-templates' +capabilities: + - projectsAcl: + actions: + - LIST + - READ + scope: + all: {} + - groupsAcl: + actions: + - LIST + - READ + scope: + all: {} + - assetsAcl: + actions: + - READ + scope: + all: {} + - filesAcl: + actions: + - READ + scope: + all: {} + - rawAcl: + actions: + - READ + - LIST + scope: + all: {} + - timeSeriesAcl: + actions: + - READ + scope: + all: {} + - dataModelsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - dataModelInstancesAcl: + actions: + - READ + scope: + all: {} + - datasetsAcl: + actions: + - READ + scope: + all: {} + - extractionPipelinesAcl: + actions: + - READ + scope: + all: {} + - extractionRunsAcl: + actions: + - READ + scope: + all: {} + - extractionConfigsAcl: + actions: + - READ + scope: + all: {} + - functionsAcl: + actions: + - READ + scope: + all: {} + - sessionsAcl: + actions: + - LIST + scope: + all: {} + - transformationsAcl: + actions: + - READ + scope: + all: {} + - filePipelinesAcl: + actions: + - READ + scope: + all: {} + - annotationsAcl: + actions: + - READ + scope: + all: {} + - documentFeedbackAcl: + actions: + - READ + scope: + all: {} + - securityCategoriesAcl: + actions: + - LIST + scope: + all: {} + - hostedExtractorsAcl: + actions: + - READ + scope: + all: {} + - visionModelAcl: + actions: + - READ + scope: + all: {} + - roboticsAcl: + actions: + - READ + scope: + all: {} + - geospatialAcl: + actions: + - READ + scope: + all: {} + - workflowOrchestrationAcl: + actions: + - READ + scope: + all: {} + - securityCategoriesAcl: + actions: + - LIST + scope: + all: {} + - timeSeriesSubscriptionsAcl: + actions: + - READ + scope: + all: {} + - labelsAcl: + actions: + - READ + scope: + all: {} diff --git a/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readwrite.group.yaml b/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readwrite.group.yaml new file mode 100644 index 0000000..8d7d21e --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/data_foundation/auth/admin.readwrite.group.yaml @@ -0,0 +1,128 @@ +name: 'gp_admin_read_write' +sourceId: '{{readwrite_source_id}}' +metadata: + origin: 'cdf-project-templates' +capabilities: + - projectsAcl: + actions: + - LIST + - READ + scope: + all: {} + - groupsAcl: + actions: + - LIST + - READ + - CREATE + - UPDATE + - DELETE + scope: + all: {} + - assetsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - filesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - rawAcl: + actions: + - READ + - WRITE + - LIST + scope: + all: {} + - timeSeriesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - dataModelsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - dataModelInstancesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - datasetsAcl: + actions: + - READ + - WRITE + - OWNER + scope: + all: {} + - extractionPipelinesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - extractionRunsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - extractionConfigsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - functionsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - sessionsAcl: + actions: + - LIST + - CREATE + - DELETE + scope: + all: {} + - transformationsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - workflowOrchestrationAcl: + actions: + - READ + - WRITE + scope: + all: {} + - securityCategoriesAcl: + actions: + - LIST + - MEMBEROF + - DELETE + - CREATE + - UPDATE + scope: + all: { } + - timeSeriesSubscriptionsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - labelsAcl: + actions: + - READ + - WRITE + scope: + all: {} diff --git a/ice-cream-dataops/modules/bootcamp/data_foundation/auth/data_developer.yaml b/ice-cream-dataops/modules/bootcamp/data_foundation/auth/data_developer.yaml new file mode 100644 index 0000000..8ee166e --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/data_foundation/auth/data_developer.yaml @@ -0,0 +1,131 @@ +name: 'data_developer' +sourceId: '{{data_developer_source_id}}' +metadata: + origin: 'cdf-project-custom' +capabilities: + - projectsAcl: + actions: + - LIST + - READ + scope: + all: {} + - assetsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - filesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - rawAcl: + actions: + - READ + - WRITE + - LIST + scope: + all: {} + - timeSeriesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - dataModelsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - dataModelInstancesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - datasetsAcl: + actions: + - READ + - WRITE + - OWNER + scope: + all: {} + - extractionPipelinesAcl: + actions: + - READ + - WRITE + scope: + all: {} + - extractionRunsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - extractionConfigsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - functionsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - sessionsAcl: + actions: + - LIST + - CREATE + - DELETE + scope: + all: {} + - transformationsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - workflowOrchestrationAcl: + actions: + - READ + - WRITE + scope: + all: {} + - securityCategoriesAcl: + actions: + - LIST + - MEMBEROF + - DELETE + - CREATE + - UPDATE + scope: + all: { } + - timeSeriesSubscriptionsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - labelsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - eventsAcl: + actions: + - READ + - WRITE + scope: + all: {} + - annotationsAcl: + actions: + - READ + - WRITE + scope: + all: {} \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/data_foundation/module.toml b/ice-cream-dataops/modules/bootcamp/data_foundation/module.toml new file mode 100644 index 0000000..73fe786 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/data_foundation/module.toml @@ -0,0 +1,7 @@ +[module] +title = "Data Foundation" + +[packages] +tags = [ + "bootcamp", +] \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/auth/icapi_extractors.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/auth/icapi_extractors.yaml new file mode 100644 index 0000000..4ae0a46 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/auth/icapi_extractors.yaml @@ -0,0 +1,63 @@ +name: 'icapi_extractor' +sourceId: '{{icapi_extractors_source_id}}' +metadata: + origin: 'cdf-project-custom' +capabilities: + - assetsAcl: + actions: [READ, WRITE] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] + - datasetsAcl: + actions: [READ] + scope: + idScope: + ids: [{{ icapi_ds_external_id }}] + - extractionPipelinesAcl: + actions: [READ] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] + - extractionRunsAcl: + actions: [READ, WRITE] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] + - filesAcl: + actions: [READ, WRITE] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] + - functionsAcl: + actions: [READ, WRITE] + scope: + all: {} + - groupsAcl: + actions: [LIST, READ] + scope: + currentuserscope: {} + - projectsAcl: + actions: [LIST, READ] + scope: + all: {} + - rawAcl: + actions: [LIST, READ, WRITE] + scope: + tableScope: + dbsToTables: + ice_cream_api: [icapi_assets_extractor] + State Store: [icapi_datapoints_extractor] + - sessionsAcl: + actions: [LIST, CREATE, DELETE] + scope: + all: {} + - timeSeriesAcl: + actions: [READ, WRITE] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] + - transformationsAcl: + actions: [READ, WRITE] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/data_sets/icapi.DataSet.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/data_sets/icapi.DataSet.yaml new file mode 100644 index 0000000..87b0580 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/data_sets/icapi.DataSet.yaml @@ -0,0 +1,3 @@ +externalId: {{ icapi_ds_external_id }} +name: Ice Cream API +description: Data set for the Ice Cream API diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_assets.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_assets.yaml new file mode 100644 index 0000000..2408171 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_assets.yaml @@ -0,0 +1,8 @@ +externalId: ep_icapi_assets +name: Ice Cream API Assets +description: Assets source extraction pipeline for the Ice Cream API +rawTables: + - dbName: ice_cream_api + tableName: icapi_assets_extractor +source: Ice Cream API +dataSetExternalId: {{ icapi_ds_external_id }} diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_datapoints.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_datapoints.yaml new file mode 100644 index 0000000..5f7515e --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_datapoints.yaml @@ -0,0 +1,8 @@ +externalId: ep_icapi_datapoints +name: Ice Cream API Data Points +description: Data Points source extraction pipeline for the Ice Cream API +rawTables: + - dbName: State Store + tableName: icapi_datapoints_extractor +source: Ice Cream API +dataSetExternalId: {{ icapi_ds_external_id }} diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_timeseries.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_timeseries.yaml new file mode 100644 index 0000000..12b5383 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/extraction_pipelines/ep_icapi_timeseries.yaml @@ -0,0 +1,5 @@ +externalId: ep_icapi_timeseries +name: Ice Cream API Time Series +description: Time Series source extraction pipeline for the Ice Cream API +source: Ice Cream API +dataSetExternalId: {{ icapi_ds_external_id }} diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/functions.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/functions.yaml new file mode 100644 index 0000000..e6fc762 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/functions.yaml @@ -0,0 +1,45 @@ +- name: Ice Cream API Assets Extractor + externalId: icapi_assets_extractor + owner: Bootcamp Team + description: Extracts Asset data from the Ice Cream API + metadata: + version: "1.0" + runtime: py311 + functionPath: ./handler.py + envVars: + CDF_PROJECT: {{ CDF_PROJECT }} + CDF_URL: {{ CDF_URL }} + IDP_TENANT_ID: {{ IDP_TENANT_ID }} + IDP_CLIENT_ID: {{ icapi_extractors_client_id }} + IDP_CLIENT_SECRET: {{ icapi_extractors_client_secret }} + IDP_SCOPES: {{ IDP_SCOPES }} +- name: Ice Cream API DataPoints Extractor + externalId: icapi_datapoints_extractor + owner: Bootcamp Team + description: Extracts DataPoints data from the Ice Cream API + metadata: + version: "1.0" + runtime: py311 + functionPath: ./handler.py + envVars: + CDF_PROJECT: {{ CDF_PROJECT }} + CDF_URL: {{ CDF_URL }} + IDP_TENANT_ID: {{ IDP_TENANT_ID }} + IDP_CLIENT_ID: {{ icapi_extractors_client_id }} + IDP_CLIENT_SECRET: {{ icapi_extractors_client_secret }} + IDP_SCOPES: {{ IDP_SCOPES }} +- name: Ice Cream API TimeSeries Extractor + externalId: icapi_timeseries_extractor + owner: Bootcamp Team + description: Extracts TimeSeries data from the Ice Cream API + metadata: + version: "1.0" + runtime: py311 + functionPath: ./handler.py + envVars: + CDF_PROJECT: {{ CDF_PROJECT }} + CDF_URL: {{ CDF_URL }} + IDP_TENANT_ID: {{ IDP_TENANT_ID }} + IDP_CLIENT_ID: {{ icapi_extractors_client_id }} + IDP_CLIENT_SECRET: {{ icapi_extractors_client_secret }} + IDP_SCOPES: {{ IDP_SCOPES }} diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/config.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/config.py new file mode 100644 index 0000000..cd2890b --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/config.py @@ -0,0 +1,18 @@ +from dataclasses import dataclass + +from cognite.extractorutils.configtools import BaseConfig + + +@dataclass +class DestConfig: + database: str + table: str + +@dataclass +class ExtractorConfig: + api_url: str + dest: DestConfig + +@dataclass +class Config(BaseConfig): + extractor: ExtractorConfig diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/extractor_config.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/extractor_config.yaml new file mode 100644 index 0000000..8d30f19 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/extractor_config.yaml @@ -0,0 +1,26 @@ +extractor: + dest: + database: ice_cream_api + table: icapi_assets_extractor + + api_url: https://ice-cream-factory.inso-internal.cognite.ai + +cognite: + host: ${CDF_URL} + project: ${CDF_PROJECT} + + idp-authentication: + tenant: ${IDP_TENANT_ID} + + client-id: ${IDP_CLIENT_ID} + secret: ${IDP_CLIENT_SECRET} + scopes: + - ${IDP_SCOPES} + + extraction_pipeline: + external-id: ep_icapi_assets + +logger: + console: + level: INFO +type: local \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/handler.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/handler.py new file mode 100644 index 0000000..14e7637 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/handler.py @@ -0,0 +1,45 @@ +from io import StringIO +from threading import Event + +import pandas +from cognite.client import CogniteClient +from cognite.extractorutils import Extractor +from cognite.extractorutils.statestore import AbstractStateStore +from config import Config +from ice_cream_factory_api import IceCreamFactoryAPI + + +def run_extractor( + client: CogniteClient, states: AbstractStateStore, config: Config, stop_event: Event +) -> None: + ice_cream_api = IceCreamFactoryAPI(base_url=config.extractor.api_url) + + sites_csv = ice_cream_api.get_sites_csv() + sites_df = pandas.read_csv( + StringIO(sites_csv), + sep=",", + usecols=["name", "external_id", "description", "metadata", "parent_external_id"] + ) + + client.raw.rows.insert_dataframe( + dataframe=sites_df, + db_name=config.extractor.dest.database, + table_name=config.extractor.dest.table, + ensure_parent=True + ) + +def handle(client: CogniteClient = None, data = None): + if data: + config_file_path = data.get("config_file_path", "extractor_config.yaml") + else: + config_file_path = "extractor_config.yaml" + + with Extractor( + name="icapi_assets_extractor", + description="An extractor that ingest Assets from the Ice Cream Factory API to CDF clean", + config_class=Config, + version="1.0", + config_file_path=config_file_path, + run_handle=run_extractor, + ) as extractor: + extractor.run() diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/ice_cream_factory_api.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/ice_cream_factory_api.py new file mode 100644 index 0000000..d8ee0e4 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/ice_cream_factory_api.py @@ -0,0 +1,37 @@ +from typing import Dict, Union + +from requests import Response, Session, adapters + + +class IceCreamFactoryAPI: + """Class for Ice Cream Factory API.""" + + def __init__(self, base_url: str): + self.base_url = base_url + self.adapter = adapters.HTTPAdapter(max_retries=3) + self.session = Session() + self.session.mount("https://", self.adapter) + + def get_response( + self, headers: Dict[str, str], url_suffix: str, params: Dict[str, Union[str, int, float]] = {} + ) -> Response: + """ + Get response from API. + + Args: + headers: request header + url_suffix: string to add to base url + params: query parameters + """ + + response = self.session.get(f"{self.base_url}/{url_suffix}", headers=headers, timeout=40, params=params) + response.raise_for_status() + return response + + def get_sites_csv(self): + """ + Get a dataframe for all sites from the Ice Cream API's site/{city}/csv endpoint + """ + response = self.get_response(headers={}, url_suffix="site/all/csv") + + return response.text diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/requirements.txt b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/requirements.txt new file mode 100644 index 0000000..310e888 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_assets_extractor/requirements.txt @@ -0,0 +1,3 @@ +cognite-extractor-utils >= 7.2.2 +orjson >= 3.10.5 +pandas \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/config.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/config.py new file mode 100644 index 0000000..6c3341c --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/config.py @@ -0,0 +1,22 @@ +from dataclasses import dataclass, field +from typing import List + +from cognite.extractorutils.configtools import BaseConfig, RawStateStoreConfig, StateStoreConfig + + +@dataclass +class ExtractorConfig: + api_url: str + backfill: bool + data_set_ext_id: str + hours: int + sites: List[str] + state_store: StateStoreConfig = field( + default_factory=StateStoreConfig( + raw=RawStateStoreConfig(database=None, table=None) + ) + ) + +@dataclass +class Config(BaseConfig): + extractor: ExtractorConfig diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/extractor_config.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/extractor_config.yaml new file mode 100644 index 0000000..c1ed28d --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/extractor_config.yaml @@ -0,0 +1,35 @@ +cognite: + extraction_pipeline: + external-id: ep_icapi_datapoints + host: ${CDF_URL} + idp-authentication: + client-id: ${IDP_CLIENT_ID} + scopes: + - ${IDP_SCOPES} + secret: ${IDP_CLIENT_SECRET} + tenant: ${IDP_TENANT_ID} + project: ${CDF_PROJECT} +extractor: + api_url: https://ice-cream-factory.inso-internal.cognite.ai + backfill: false + data_set_ext_id: ds_icapi + hours: 1 + sites: + - Houston + - Oslo + - Kuala Lumpur + - Hannover + - Nuremberg + - Marseille + - Sao Paulo + - Chicago + - Rotterdam + - London + state_store: + raw: + database: State Store + table: icapi_datapoints_extractor +logger: + console: + level: INFO +type: local diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/handler.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/handler.py new file mode 100644 index 0000000..2d20184 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/handler.py @@ -0,0 +1,108 @@ +import os +from ast import literal_eval +from datetime import datetime, timedelta, timezone +from threading import Event + +from cognite.client import CogniteClient +from cognite.extractorutils import Extractor +from cognite.extractorutils.statestore import AbstractStateStore +from cognite.extractorutils.uploader import TimeSeriesUploadQueue +from config import Config +from ice_cream_factory_api import IceCreamFactoryAPI + + +def get_timeseries_for_site(client: CogniteClient, site, config: Config): + this_site = site.lower() + ts = client.time_series.list( + data_set_external_ids=config.extractor.data_set_ext_id, + metadata={"site": this_site}, + limit=None + ) + + # filter returned list because the API returns connected timeseries. planned_status -> status, good -> count + ts = [item for item in ts if any(substring in item.external_id for substring in ["planned_status", "good"])] + return ts + +def run_extractor( + client: CogniteClient, states: AbstractStateStore, config: Config, stop_event: Event +) -> None: + + # The only way to pass variables to and Extractor's run function + if "SITES" in os.environ: + config.extractor.sites = literal_eval(os.environ["SITES"]) + if "BACKFILL" in os.environ: + config.extractor.backfill = True if os.environ["BACKFILL"] == "True" else False + if "HOURS" in os.environ: + config.extractor.hours = int(os.environ["HOURS"]) + + now = datetime.now(timezone.utc).timestamp() * 1000 + increment = timedelta(seconds=7200).total_seconds() * 1000 + + ice_cream_api = IceCreamFactoryAPI(base_url=config.extractor.api_url) + + upload_queue = TimeSeriesUploadQueue( + client, + post_upload_function=states.post_upload_handler(), + max_queue_size=500000, + trigger_log_level="INFO", + thread_name="Timeseries Upload Queue", + ) + + for site in config.extractor.sites: + print(f"Getting TimeSeries for {site}") + time_series = get_timeseries_for_site(client, site, config) + + if not config.extractor.backfill: + # Get all the latest datapoints in one API call + latest_dps = { + dp.external_id: dp.timestamp + for dp in client.time_series.data.retrieve_latest( + external_id=[ts.external_id for ts in time_series], + ignore_unknown_ids=True + ) + } + + for ts in time_series: + # figure out the window of datapoints to pull + if not config.extractor.backfill: + latest = latest_dps[ts.external_id][0] if latest_dps.get(ts.external_id) else None + start = latest if latest else now - increment + else: + start = now - timedelta(hours=config.extractor.hours).total_seconds() * 1000 + end = now + + dps = ice_cream_api.get_datapoints(timeseries_ext_id=ts.external_id, start=start, end=end) + for external_id, datapoints in dps.items(): + upload_queue.add_to_upload_queue(external_id=external_id, datapoints=datapoints) + + print(f"Queued {len(datapoints)} {ts.external_id} datapoints for upload") + + # trigger upload for this site + upload_queue.upload() + +def handle(client: CogniteClient = None, data = None): + config_file_path = "extractor_config.yaml" + + # Can't pass parameters to the Extractor, so create environment variables + if data: + sites = data.get("sites") + backfill = data.get("backfill") + hours = data.get("hours") + + if sites: + os.environ["SITES"] = f"{sites}" + if backfill: + os.environ["BACKFILL"] = f"{backfill}" + if hours: + os.environ["HOURS"] = f"{hours}" + + with Extractor( + name="icapi_datapoints_extractor", + description="An extractor that ingest Timeseries' Datapoints from the Ice Cream Factory API to CDF clean", + config_class=Config, + version="1.0", + config_file_path=config_file_path, + run_handle=run_extractor, + ) as extractor: + extractor.run() + diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/ice_cream_factory_api.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/ice_cream_factory_api.py new file mode 100644 index 0000000..3915b26 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/ice_cream_factory_api.py @@ -0,0 +1,56 @@ +from typing import Dict, Union + +import orjson +from requests import Response, Session, adapters + + +class IceCreamFactoryAPI: + """Class for Ice Cream Factory API.""" + + def __init__(self, base_url: str): + self.base_url = base_url + self.adapter = adapters.HTTPAdapter(max_retries=3) + self.session = Session() + self.session.mount("https://", self.adapter) + + def get_response( + self, headers: Dict[str, str], url_suffix: str, params: Dict[str, Union[str, int, float]] = {} + ) -> Response: + """ + Get response from API. + + Args: + headers: request header + url_suffix: string to add to base url + params: query parameters + """ + + response = self.session.get(f"{self.base_url}/{url_suffix}", headers=headers, timeout=40, params=params) + response.raise_for_status() + return response + + def get_datapoints( + self, timeseries_ext_id: str, start: Union[str, int, float], end: Union[str, int, float] + ): + """ + Get datapoints for a timeseries external id. This will also return datapoints for an associated timeseries + + (e.g. request for external id "HPM2C561:planned_status" will return datapoints for "HPM2C561:planned_status" AND + "HPM2C561:status". Similar, request for timeseries with external id "HPM2C561:count" will return datapoints for + "HPM2C561:count" AND ""HPM2C561:good"). + + Args: + timeseries_ext_id: external id of timeseries to get datapoints for + start: start for datapoints (UNIX timestamp (int, float) or string with format 'YYYY-MM-DD HH:MM') + end: end for datapoints (UNIX timestamp (int, float) or string with format 'YYYY-MM-DD HH:MM') + """ + params = {"start": start, "end": end, "external_id": timeseries_ext_id} + response = self.get_response(headers={}, url_suffix="datapoints/oee", params=params) + + datapoints_dict = orjson.loads(response.content) + + for ts, dps in datapoints_dict.items(): + # convert timestamp to ms (*1000) for CDF uploads + datapoints_dict[ts] = [(dp[0] * 1000, dp[1]) for dp in dps] + + return datapoints_dict diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/requirements.txt b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/requirements.txt new file mode 100644 index 0000000..e46cb23 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_datapoints_extractor/requirements.txt @@ -0,0 +1,2 @@ +cognite-extractor-utils >= 7.2.2 +orjson >= 3.10.5 \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/config.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/config.py new file mode 100644 index 0000000..8ae893e --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/config.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass + +from cognite.extractorutils.configtools import BaseConfig + + +@dataclass +class ExtractorConfig: + api_url: str + data_set_ext_id: str + +@dataclass +class Config(BaseConfig): + extractor: ExtractorConfig diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/extractor_config.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/extractor_config.yaml new file mode 100644 index 0000000..c809c01 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/extractor_config.yaml @@ -0,0 +1,23 @@ +extractor: + data_set_ext_id: ds_icapi + + api_url: https://ice-cream-factory.inso-internal.cognite.ai + +cognite: + host: ${CDF_URL} + project: ${CDF_PROJECT} + + idp-authentication: + tenant: ${IDP_TENANT_ID} + + client-id: ${IDP_CLIENT_ID} + secret: ${IDP_CLIENT_SECRET} + scopes: + - ${IDP_SCOPES} + + extraction_pipeline: + external-id: ep_icapi_timeseries + +logger: + console: + level: INFO diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/handler.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/handler.py new file mode 100644 index 0000000..60472db --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/handler.py @@ -0,0 +1,45 @@ +from threading import Event + +from cognite.client import CogniteClient +from cognite.extractorutils import Extractor +from cognite.extractorutils.statestore import AbstractStateStore +from config import Config +from ice_cream_factory_api import IceCreamFactoryAPI + + +def run_extractor( + client: CogniteClient, states: AbstractStateStore, config: Config, stop_event: Event +) -> None: + + ice_cream_api = IceCreamFactoryAPI(base_url=config.extractor.api_url) + time_series = ice_cream_api.get_timeseries() + + # add the dataset to all TimeSeries + data_set = client.data_sets.retrieve(external_id=config.extractor.data_set_ext_id) + if not data_set: + stop_event.set() + print(f"Data set {config.extractor.data_set_ext_id} not found") + + for ts in time_series: + ts.data_set_id = data_set.id + + client.time_series.upsert(item=time_series) + +def handle(client: CogniteClient = None, data = None): + if data: + config_file_path = data.get("config_file_path", "extractor_config.yaml") + else: + config_file_path = "extractor_config.yaml" + + with Extractor( + name="icapi_timeseries_extractor", + description="An extractor that ingests Time Series metadata from the Ice Cream Factory API to CDF clean", + config_class=Config, + version="1.0", + config_file_path=config_file_path, + run_handle=run_extractor, + ) as extractor: + extractor.run() + +if __name__ == "__main__": + handle() diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/ice_cream_factory_api.py b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/ice_cream_factory_api.py new file mode 100644 index 0000000..41811d6 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/ice_cream_factory_api.py @@ -0,0 +1,43 @@ +from typing import Dict, Union + +import orjson +from cognite.client.data_classes import TimeSeries +from requests import Response, Session, adapters + + +class IceCreamFactoryAPI: + """Class for Ice Cream Factory API.""" + + def __init__(self, base_url: str): + self.base_url = base_url + self.adapter = adapters.HTTPAdapter(max_retries=3) + self.session = Session() + self.session.mount("https://", self.adapter) + + def get_response( + self, headers: Dict[str, str], url_suffix: str, params: Dict[str, Union[str, int, float]] = {} + ) -> Response: + """ + Get response from API. + + Args: + headers: request header + url_suffix: string to add to base url + params: query parameters + """ + + response = self.session.get(f"{self.base_url}/{url_suffix}", headers=headers, timeout=40, params=params) + response.raise_for_status() + return response + + def get_timeseries(self): + """ + Get sites from the Ice Cream API and create a list Assets + """ + response = self.get_response(headers={}, url_suffix="timeseries/oee") + + timeseries = orjson.loads(response.content) + + timeseries = [TimeSeries(**ts) for ts in timeseries] + + return timeseries diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/requirements.txt b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/requirements.txt new file mode 100644 index 0000000..e46cb23 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/icapi_timeseries_extractor/requirements.txt @@ -0,0 +1,2 @@ +cognite-extractor-utils >= 7.2.2 +orjson >= 3.10.5 \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/schedules.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/schedules.yaml new file mode 100644 index 0000000..1bdac1e --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/functions/schedules.yaml @@ -0,0 +1,15 @@ +- name: Frontfill every 10 minutes last hour of data (streamer) + functionExternalId: icapi_datapoints_extractor + cronExpression: "*/10 * * * *" + authentication: + clientId: {{ icapi_extractors_client_id }} + clientSecret: {{ icapi_extractors_client_secret }} +- name: Backfill once a day for the last 30 days (gap filling) + functionExternalId: icapi_datapoints_extractor + cronExpression: "0 0 * * *" + data: + backfill: True + hours: 720 + authentication: + clientId: {{ icapi_extractors_client_id }} + clientSecret: {{ icapi_extractors_client_secret }} diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/module.toml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/module.toml new file mode 100644 index 0000000..2376460 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/module.toml @@ -0,0 +1,7 @@ +[module] +title = "Ice Cream API" + +[packages] +tags = [ + "bootcamp", +] \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/ice_cream_api/raw/extraction_sources.Table.yaml b/ice-cream-dataops/modules/bootcamp/ice_cream_api/raw/extraction_sources.Table.yaml new file mode 100644 index 0000000..1be5a92 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/ice_cream_api/raw/extraction_sources.Table.yaml @@ -0,0 +1,4 @@ +- dbName: State Store + tableName: icapi_datapoints_extractor +- dbName: ice_cream_api + tableName: icapi_assets_extractor diff --git a/ice-cream-dataops/modules/bootcamp/use_cases/oee/auth/data_pipeline_oee.yaml b/ice-cream-dataops/modules/bootcamp/use_cases/oee/auth/data_pipeline_oee.yaml new file mode 100644 index 0000000..a874d18 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/use_cases/oee/auth/data_pipeline_oee.yaml @@ -0,0 +1,37 @@ +name: 'oee_pipeline' +sourceId: '{{data_pipeline_oee_source_id}}' +metadata: + origin: 'cdf-project-custom' +capabilities: + - assetsAcl: + actions: [READ] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] + - datasetsAcl: + actions: [READ] + scope: + idScope: + ids: [{{ uc_oee_ds_external_id }}, {{ icapi_ds_external_id }}] + - groupsAcl: + actions: [LIST, READ] + scope: + currentuserscope: {} + - projectsAcl: + actions: [LIST, READ] + scope: + all: {} + - sessionsAcl: + actions: [LIST, CREATE, DELETE] + scope: + all: {} + - timeSeriesAcl: + actions: [READ] + scope: + datasetScope: + ids: [{{ icapi_ds_external_id }}] + - timeSeriesAcl: + actions: [READ, WRITE] + scope: + datasetScope: + ids: [{{ uc_oee_ds_external_id }}] \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/use_cases/oee/data_sets/data_sets.yaml b/ice-cream-dataops/modules/bootcamp/use_cases/oee/data_sets/data_sets.yaml new file mode 100644 index 0000000..3b53f61 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/use_cases/oee/data_sets/data_sets.yaml @@ -0,0 +1,2 @@ +- externalId: {{ uc_oee_ds_external_id }} + name: Overall Equipment Effectiveness Use Case \ No newline at end of file diff --git a/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/functions.yaml b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/functions.yaml new file mode 100644 index 0000000..31c674b --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/functions.yaml @@ -0,0 +1,8 @@ +- name: OEE TimeSeries + externalId: oee_timeseries + owner: CDF Bootcamp Team + description: Function to calculate OEE + metadata: + version: "1.0" + runtime: py311 + functionPath: ./handler.py diff --git a/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/handler.py b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/handler.py new file mode 100644 index 0000000..17dda34 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/handler.py @@ -0,0 +1,128 @@ +from concurrent.futures import ThreadPoolExecutor +from datetime import timedelta +from typing import Any, Dict + +import numpy as np +from cognite.client import CogniteClient +from cognite.client.data_classes import TimeSeries +from cognite.client.exceptions import CogniteNotFoundError +from retry import retry + + +def handle(client: CogniteClient, data: Dict[str, Any] = {}) -> None: + lookback_minutes = timedelta(minutes=data.get("lookback_minutes", 60)).total_seconds() * 1000 + data_set_external_id = data.get("data_set_external_id", "ds_uc_oee") + data_set_id = client.data_sets.retrieve(external_id=data_set_external_id).id + all_sites = ["Oslo", "Houston", "Kuala Lumpur", "Hannover", "Nuremberg", "Marseille", "Sao Paulo", "Chicago", "Rotterdam", "London"] + sites = data.get("sites", all_sites) + + print(f"Processing datapoints for these sites: {sites}") + with ThreadPoolExecutor(max_workers=10) as executor: + futures = [executor.submit(process_site, client, data_set_id, lookback_minutes, site) for site in sites] + for f in futures: + f.result() + +@retry(tries=5, delay=5) +def process_site(client, data_set_id, lookback_minutes, site): + assets = client.assets.list(asset_subtree_external_ids=site.lower(), limit=None) + timeseries = client.time_series.list(asset_subtree_external_ids=site.lower(), limit=None) + external_ids = [ts.external_id for ts in timeseries] + all_latest_dps = client.time_series.data.retrieve_latest(external_id=external_ids) + + # Organize latest datapoints by equipment for alignment + assets_dps = { + asset.external_id: [latest_dp for latest_dp in all_latest_dps if asset.external_id in latest_dp.external_id] + for asset in assets + } + + for asset, latest_dps in assets_dps.items(): + end = min([dp.timestamp[0] for dp in latest_dps if latest_dps and dp.timestamp], default=None) + if end: + dps_df = client.time_series.data.retrieve_dataframe( + external_id=[dp.external_id for dp in latest_dps], + start=end - lookback_minutes, + end=end, + aggregates=["sum"], + granularity="1m", + include_aggregate_name=False, + limit=None + ) + + # Frontfill because "planned_status" and "status" only have datapoints when the value changes + dps_df = dps_df.ffill() + + # Fill the rest with the opposite + try: + first_valid_value = dps_df[f"{asset}:planned_status"].loc[dps_df[f"{asset}:planned_status"].first_valid_index()] + except: + print(f"Failed to find datapoints for {asset}:planned_status") + continue + backfill_value = 1.0 if first_valid_value == 0.0 else 0.0 + dps_df[f"{asset}:planned_status"] = dps_df[f"{asset}:planned_status"].fillna(value=backfill_value) + + # Same for status + first_valid_value = dps_df[f"{asset}:status"].loc[dps_df[f"{asset}:status"].first_valid_index()] + backfill_value = 1.0 if first_valid_value == 0.0 else 0.0 + dps_df[f"{asset}:status"] = dps_df[f"{asset}:status"].fillna(value=backfill_value) + + count_dps = dps_df[f"{asset}:count"] + good_dps = dps_df[f"{asset}:good"] + status_dps = dps_df[f"{asset}:status"] + planned_status_dps = dps_df[f"{asset}:planned_status"] + + total_items = len(count_dps) + + if ( + total_items != len(good_dps) + or total_items != len(status_dps) + or total_items != len(planned_status_dps) + ): + # We expect ALL dependent timeseries to have the exact same number of datapoints + # for the specified time range for the calculation to execute. + print( + f"""{asset}: Unable to retrieve datapoints for all required OEE timeseries (count, good, status, planned_status) + between {end - lookback_minutes} and {end}. Ensure that data is available for the time range specified.""" + ) + + # Calculate the components of OEE + dps_df[f"{asset}:off_spec"] = count_dps - good_dps + dps_df[f"{asset}:quality"] = good_dps / count_dps + dps_df[f"{asset}:performance"] = (count_dps / status_dps) / (60.0 / 3.0) + dps_df[f"{asset}:availability"] = status_dps / planned_status_dps + + dps_df[f"{asset}:oee"] = dps_df[f"{asset}:quality"] * dps_df[f"{asset}:performance"] * dps_df[f"{asset}:availability"] + + # Fill in the divide by zeros + dps_df = dps_df.fillna(value=0.0) + dps_df = dps_df.replace([np.inf, -np.inf], 0.0) + + # Drop input timeseries + dps_df = dps_df.drop(columns=[f"{asset}:{postfix}" for postfix in ["good", "count", "status", "planned_status"]]) + + try: + client.time_series.data.insert_dataframe(dps_df) + except CogniteNotFoundError as e: + # Create the missing oee timeseries since they don't exist + ts_to_create = [] + for ext_id in e.failed: + external_id = ext_id["externalId"] + + # change external_id to a readable name + # Ex: "OSLPROFILTRASYS185:off_spec" to "OSLPROFILTRASYS185 Off Spec" + name = external_id.split(":") + typ = name[-1] + name[-1] = name[-1].replace("_", " ").title() + + ts_to_create.append( + TimeSeries( + external_id=external_id, + name=" ".join(name), + metadata={"type": typ}, + data_set_id=data_set_id + ) + ) + + client.time_series.create(ts_to_create) + client.time_series.data.insert_dataframe(dps_df) + + print(f" {asset} Finished") diff --git a/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/requirements.txt b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/requirements.txt new file mode 100644 index 0000000..ce92146 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/oee_timeseries/requirements.txt @@ -0,0 +1,5 @@ +arrow +pandas +pydantic +retry +cognite-sdk diff --git a/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml new file mode 100644 index 0000000..2eec301 --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/use_cases/oee/functions/schedules.yaml @@ -0,0 +1,118 @@ +- name: Run calculations every 10 minutes for last hour of data + cronExpression: "5-59/10 * * * *" + functionExternalId: oee_timeseries + data: + sites: + - Oslo + - Hannover + - Nuremberg + - Marseille + - Houston + - Sao Paulo + - Kuala Lumpur + - Chicago + - Rotterdam + - London + lookback_minutes: 60 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Oslo) + cronExpression: "0 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Oslo + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Nuremberg) + cronExpression: "1 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Nuremberg + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Marseille) + cronExpression: "2 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Marseille + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Houston) + cronExpression: "3 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Houston + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Sao Paulo) + cronExpression: "4 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Sao Paulo + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Kuala Lumpur) + cronExpression: "5 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Kuala Lumpur + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Chicago) + cronExpression: "6 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Chicago + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (Rotterdam) + cronExpression: "7 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - Rotterdam + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} + +- name: Run calculations once a day for 30 days history (London) + cronExpression: "8 1 * * *" + functionExternalId: oee_timeseries + data: + sites: + - London + lookback_minutes: 7200 + authentication: + clientId: {{ data_pipeline_oee_client_id }} + clientSecret: {{ data_pipeline_oee_client_secret }} diff --git a/ice-cream-dataops/modules/bootcamp/use_cases/oee/module.toml b/ice-cream-dataops/modules/bootcamp/use_cases/oee/module.toml new file mode 100644 index 0000000..4d1ed3b --- /dev/null +++ b/ice-cream-dataops/modules/bootcamp/use_cases/oee/module.toml @@ -0,0 +1,7 @@ +[module] +title = "OEE Use Case" + +[packages] +tags = [ + "bootcamp", +] \ No newline at end of file diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..39c3260 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,995 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "certifi" +version = "2024.8.30" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "cognite-sdk" +version = "7.63.3" +description = "Cognite Python SDK" +optional = false +python-versions = "<4.0,>=3.10" +files = [ + {file = "cognite_sdk-7.63.3-py3-none-any.whl", hash = "sha256:b0fb4910c37a79b9ecb3133103c810ddbaefa0c87e8b1f822e76f9228c863ca8"}, + {file = "cognite_sdk-7.63.3.tar.gz", hash = "sha256:4f66344b17f7f16f722cd17ec1b952cc9145eb5860e5637c5644f04193f9da0c"}, +] + +[package.dependencies] +msal = ">=1.31,<2.0" +pandas = {version = ">=2.1", optional = true, markers = "extra == \"pandas\" or extra == \"all\""} +protobuf = ">=4" +requests = ">=2.27,<3.0" +requests_oauthlib = ">=1,<2" +typing_extensions = ">=4" + +[package.extras] +all = ["PyYAML (>=6.0,<7.0)", "geopandas (>=0.14)", "numpy (>=1.25,<2.0)", "numpy (>=1.26,<2.0)", "pandas (>=2.1)", "pip (>=20.0.0)", "shapely (>=1.7.0)", "sympy"] +functions = ["pip (>=20.0.0)"] +geo = ["geopandas (>=0.14)", "shapely (>=1.7.0)"] +numpy = ["numpy (>=1.25,<2.0)", "numpy (>=1.26,<2.0)"] +pandas = ["pandas (>=2.1)"] +pyodide = ["pyodide-http (>=0.2.1,<0.3.0)", "tzdata (>=2024.1)"] +sympy = ["sympy"] +yaml = ["PyYAML (>=6.0,<7.0)"] + +[[package]] +name = "cognite-toolkit" +version = "0.3.2" +description = "Official Cognite Data Fusion tool for project templates and configuration deployment" +optional = false +python-versions = "<4.0,>=3.10" +files = [ + {file = "cognite_toolkit-0.3.2-py3-none-any.whl", hash = "sha256:a519514b369c9d9b66fbf1f77980cb1e585118997334093a480a13a329b1a296"}, + {file = "cognite_toolkit-0.3.2.tar.gz", hash = "sha256:05f195bf47bc2e2905b845d497fc5a65e20341d4a535d33ade229ddda1bf8319"}, +] + +[package.dependencies] +cognite-sdk = {version = ">=7.63.1,<8.0.0", extras = ["pandas"]} +mixpanel = ">=4.10.1,<5.0.0" +packaging = ">=22.0,<25.0" +pandas = ">=1.5.3,<3.0" +python-dotenv = ">=1.0.0,<2.0.0" +pyyaml = ">=6.0.1,<7.0.0" +questionary = ">=2.0.1,<3.0.0" +sentry-sdk = ">=2.1.0,<3.0.0" +toml = ">=0.10.2,<0.11.0" +typer = {version = ">=0.12.0,<1.0", extras = ["all"]} +typing-extensions = ">=4.0,<5.0" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "cryptography" +version = "43.0.1" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"}, + {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"}, + {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"}, + {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"}, + {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"}, + {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"}, + {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "mixpanel" +version = "4.10.1" +description = "Official Mixpanel library for Python" +optional = false +python-versions = ">=2.7, !=3.4.*" +files = [ + {file = "mixpanel-4.10.1-py2.py3-none-any.whl", hash = "sha256:a7a338b7197327e36356dbc1903086e7626db6d88367ccdd732b3f3c60d3b3ed"}, + {file = "mixpanel-4.10.1.tar.gz", hash = "sha256:29a6b5773dd34f05cf8e249f4e1d16e7b6280d6b58894551ce9a5aad7700a115"}, +] + +[package.dependencies] +requests = ">=2.4.2" +six = ">=1.9.0" +urllib3 = "*" + +[[package]] +name = "msal" +version = "1.31.0" +description = "The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of users with Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) using industry standard OAuth2 and OpenID Connect." +optional = false +python-versions = ">=3.7" +files = [ + {file = "msal-1.31.0-py3-none-any.whl", hash = "sha256:96bc37cff82ebe4b160d5fc0f1196f6ca8b50e274ecd0ec5bf69c438514086e7"}, + {file = "msal-1.31.0.tar.gz", hash = "sha256:2c4f189cf9cc8f00c80045f66d39b7c0f3ed45873fd3d1f2af9f22db2e12ff4b"}, +] + +[package.dependencies] +cryptography = ">=2.5,<46" +PyJWT = {version = ">=1.0.0,<3", extras = ["crypto"]} +requests = ">=2.0.0,<3" + +[package.extras] +broker = ["pymsalruntime (>=0.14,<0.18)", "pymsalruntime (>=0.17,<0.18)"] + +[[package]] +name = "numpy" +version = "2.1.2" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.10" +files = [ + {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, + {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, + {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, + {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, + {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, + {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, + {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, + {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, + {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, + {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, + {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, + {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, + {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, + {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, + {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, + {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, + {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, + {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, + {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, + {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, + {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, + {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, + {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, + {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, + {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, + {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, + {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, + {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, + {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, + {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, + {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, + {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, + {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, + {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, + {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, + {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, + {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, + {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, + {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, + {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, + {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, + {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, + {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, + {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, + {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, + {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, + {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, + {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, + {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, + {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, + {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, + {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, + {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, +] + +[[package]] +name = "oauthlib" +version = "3.2.2" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +optional = false +python-versions = ">=3.6" +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] + +[package.extras] +rsa = ["cryptography (>=3.0.0)"] +signals = ["blinker (>=1.4.0)"] +signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pandas" +version = "2.2.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, + {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, + {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, + {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, + {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, + {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, + {file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"}, + {file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"}, + {file = "pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c"}, + {file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"}, + {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea"}, + {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"}, + {file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"}, + {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, +] + +[package.dependencies] +numpy = {version = ">=1.26.0", markers = "python_version >= \"3.12\""} +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.36" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.6.2" +files = [ + {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"}, + {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "protobuf" +version = "5.28.2" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-5.28.2-cp310-abi3-win32.whl", hash = "sha256:eeea10f3dc0ac7e6b4933d32db20662902b4ab81bf28df12218aa389e9c2102d"}, + {file = "protobuf-5.28.2-cp310-abi3-win_amd64.whl", hash = "sha256:2c69461a7fcc8e24be697624c09a839976d82ae75062b11a0972e41fd2cd9132"}, + {file = "protobuf-5.28.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a8b9403fc70764b08d2f593ce44f1d2920c5077bf7d311fefec999f8c40f78b7"}, + {file = "protobuf-5.28.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:35cfcb15f213449af7ff6198d6eb5f739c37d7e4f1c09b5d0641babf2cc0c68f"}, + {file = "protobuf-5.28.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:5e8a95246d581eef20471b5d5ba010d55f66740942b95ba9b872d918c459452f"}, + {file = "protobuf-5.28.2-cp38-cp38-win32.whl", hash = "sha256:87317e9bcda04a32f2ee82089a204d3a2f0d3c8aeed16568c7daf4756e4f1fe0"}, + {file = "protobuf-5.28.2-cp38-cp38-win_amd64.whl", hash = "sha256:c0ea0123dac3399a2eeb1a1443d82b7afc9ff40241433296769f7da42d142ec3"}, + {file = "protobuf-5.28.2-cp39-cp39-win32.whl", hash = "sha256:ca53faf29896c526863366a52a8f4d88e69cd04ec9571ed6082fa117fac3ab36"}, + {file = "protobuf-5.28.2-cp39-cp39-win_amd64.whl", hash = "sha256:8ddc60bf374785fb7cb12510b267f59067fa10087325b8e1855b898a0d81d276"}, + {file = "protobuf-5.28.2-py3-none-any.whl", hash = "sha256:52235802093bd8a2811abbe8bf0ab9c5f54cca0a751fdd3f6ac2a21438bffece"}, + {file = "protobuf-5.28.2.tar.gz", hash = "sha256:59379674ff119717404f7454647913787034f03fe7049cbef1d74a97bb4593f0"}, +] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyjwt" +version = "2.9.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, + {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, +] + +[package.dependencies] +cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "pytz" +version = "2024.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "questionary" +version = "2.0.1" +description = "Python library to build pretty command line user prompts ⭐️" +optional = false +python-versions = ">=3.8" +files = [ + {file = "questionary-2.0.1-py3-none-any.whl", hash = "sha256:8ab9a01d0b91b68444dff7f6652c1e754105533f083cbe27597c8110ecc230a2"}, + {file = "questionary-2.0.1.tar.gz", hash = "sha256:bcce898bf3dbb446ff62830c86c5c6fb9a22a54146f0f5597d3da43b10d8fc8b"}, +] + +[package.dependencies] +prompt_toolkit = ">=2.0,<=3.0.36" + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-oauthlib" +version = "1.3.1" +description = "OAuthlib authentication support for Requests." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, + {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, +] + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib[signedtoken] (>=3.0.0)"] + +[[package]] +name = "rich" +version = "13.9.2" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"}, + {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "sentry-sdk" +version = "2.16.0" +description = "Python client for Sentry (https://sentry.io)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "sentry_sdk-2.16.0-py2.py3-none-any.whl", hash = "sha256:49139c31ebcd398f4f6396b18910610a0c1602f6e67083240c33019d1f6aa30c"}, + {file = "sentry_sdk-2.16.0.tar.gz", hash = "sha256:90f733b32e15dfc1999e6b7aca67a38688a567329de4d6e184154a73f96c6892"}, +] + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.26.11" + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +anthropic = ["anthropic (>=0.16)"] +arq = ["arq (>=0.23)"] +asyncpg = ["asyncpg (>=0.23)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +celery-redbeat = ["celery-redbeat (>=2)"] +chalice = ["chalice (>=1.16.0)"] +clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +fastapi = ["fastapi (>=0.79.0)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] +grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] +http2 = ["httpcore[http2] (==1.*)"] +httpx = ["httpx (>=0.16.0)"] +huey = ["huey (>=2)"] +huggingface-hub = ["huggingface-hub (>=0.22)"] +langchain = ["langchain (>=0.0.210)"] +litestar = ["litestar (>=2.0.0)"] +loguru = ["loguru (>=0.5)"] +openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] +opentelemetry = ["opentelemetry-distro (>=0.35b0)"] +opentelemetry-experimental = ["opentelemetry-distro"] +pure-eval = ["asttokens", "executing", "pure-eval"] +pymongo = ["pymongo (>=3.1)"] +pyspark = ["pyspark (>=2.4.4)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +starlette = ["starlette (>=0.19.1)"] +starlite = ["starlite (>=1.48)"] +tornado = ["tornado (>=6)"] + +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + +[[package]] +name = "typer" +version = "0.12.5" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +files = [ + {file = "typer-0.12.5-py3-none-any.whl", hash = "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b"}, + {file = "typer-0.12.5.tar.gz", hash = "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.12" +content-hash = "74952a922fe11499f497617411a59d834fd3ba35ee6219368c6074beb374ccf9" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..83f461a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "bootcamp" +version = "0.1.0" +description = "" +authors = ["Fredrik Nestvold Larsen <59914223+Nestvold@users.noreply.github.com>"] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.12" +cognite-toolkit = "^0.3.2" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/temp.py b/temp.py new file mode 100644 index 0000000..1730309 --- /dev/null +++ b/temp.py @@ -0,0 +1 @@ +# %% \ No newline at end of file