From e8a6e2ac8962ea36c5b8b813e2702d09b449bc19 Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Sun, 30 Jun 2024 13:53:35 +0100 Subject: [PATCH 001/177] Initiated Clickup Integration directory --- integrations/clickup/.dockerignore | 94 +++++++++++ integrations/clickup/.gitignore | 153 ++++++++++++++++++ .../clickup/.port/resources/.gitignore | 1 + integrations/clickup/.port/spec.yaml | 15 ++ integrations/clickup/CHANGELOG.md | 8 + integrations/clickup/Dockerfile | 15 ++ integrations/clickup/Makefile | 74 +++++++++ integrations/clickup/README.md | 7 + integrations/clickup/changelog/.gitignore | 1 + integrations/clickup/debug.py | 4 + integrations/clickup/main.py | 41 +++++ integrations/clickup/poetry.toml | 3 + integrations/clickup/pyproject.toml | 102 ++++++++++++ integrations/clickup/tests/__init__.py | 0 14 files changed, 518 insertions(+) create mode 100644 integrations/clickup/.dockerignore create mode 100644 integrations/clickup/.gitignore create mode 100644 integrations/clickup/.port/resources/.gitignore create mode 100644 integrations/clickup/.port/spec.yaml create mode 100644 integrations/clickup/CHANGELOG.md create mode 100644 integrations/clickup/Dockerfile create mode 100644 integrations/clickup/Makefile create mode 100644 integrations/clickup/README.md create mode 100644 integrations/clickup/changelog/.gitignore create mode 100644 integrations/clickup/debug.py create mode 100644 integrations/clickup/main.py create mode 100644 integrations/clickup/poetry.toml create mode 100644 integrations/clickup/pyproject.toml create mode 100644 integrations/clickup/tests/__init__.py diff --git a/integrations/clickup/.dockerignore b/integrations/clickup/.dockerignore new file mode 100644 index 0000000000..dc28c4f316 --- /dev/null +++ b/integrations/clickup/.dockerignore @@ -0,0 +1,94 @@ +# Git +.git +.gitignore +.gitattributes + + +# CI +.codeclimate.yml +.travis.yml +.taskcluster.yml + +# Docker +docker-compose.yml +Dockerfile +.docker +.dockerignore + +# Byte-compiled / optimized / DLL files +**/__pycache__/ +**/*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# 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/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Virtual environment +.env +.venv/ +venv/ + +# PyCharm +.idea + +# Python mode for VIM +.ropeproject +**/.ropeproject + +# Vim swap files +**/*.swp + +# VS Code +.vscode/ + +*.md +**/.ruff_cache +**/cahangelog +**/tests \ No newline at end of file diff --git a/integrations/clickup/.gitignore b/integrations/clickup/.gitignore new file mode 100644 index 0000000000..d550eaaeaf --- /dev/null +++ b/integrations/clickup/.gitignore @@ -0,0 +1,153 @@ +# 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 +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/ \ No newline at end of file diff --git a/integrations/clickup/.port/resources/.gitignore b/integrations/clickup/.port/resources/.gitignore new file mode 100644 index 0000000000..f935021a8f --- /dev/null +++ b/integrations/clickup/.port/resources/.gitignore @@ -0,0 +1 @@ +!.gitignore diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml new file mode 100644 index 0000000000..9cf72fe4b3 --- /dev/null +++ b/integrations/clickup/.port/spec.yaml @@ -0,0 +1,15 @@ +description: ClickUp integration for Port Ocean +icon: Cookiecutter # Should be one of the available icons in Port +features: + - type: exporter + section: Git Providers # Should be one of the available sections in Port + resources: + - kind: + - kind: +configurations: + - name: myGitToken + required: true + type: string + sensitive: true + - name: someApplicationUrl + type: url diff --git a/integrations/clickup/CHANGELOG.md b/integrations/clickup/CHANGELOG.md new file mode 100644 index 0000000000..14e279d66d --- /dev/null +++ b/integrations/clickup/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + diff --git a/integrations/clickup/Dockerfile b/integrations/clickup/Dockerfile new file mode 100644 index 0000000000..86ddcc540f --- /dev/null +++ b/integrations/clickup/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3.11-slim-bookworm + +ENV LIBRDKAFKA_VERSION 1.9.2 + +WORKDIR /app + +RUN apt update && \ + apt install -y wget make g++ libssl-dev autoconf automake libtool curl librdkafka-dev && \ + apt-get clean + +COPY . /app + +RUN export POETRY_VIRTUALENVS_CREATE=false && make install/prod && pip cache purge + +ENTRYPOINT ocean sail \ No newline at end of file diff --git a/integrations/clickup/Makefile b/integrations/clickup/Makefile new file mode 100644 index 0000000000..9808e60140 --- /dev/null +++ b/integrations/clickup/Makefile @@ -0,0 +1,74 @@ +ACTIVATE := . .venv/bin/activate + +define run_checks + exit_code=0; \ + cd $1; \ + poetry check || exit_code=$$?;\ + mypy . || exit_code=$$?; \ + ruff check . || exit_code=$$?; \ + black --check . || exit_code=$$?; \ + if [ $$exit_code -eq 1 ]; then \ + echo "\033[0;31mOne or more checks failed with exit code $$exit_code\033[0m"; \ + else \ + echo "\033[0;32mAll checks executed successfully.\033[0m"; \ + fi; \ + exit $$exit_code +endef + +define install_poetry + if ! command -v poetry &> /dev/null; then \ + pip install --upgrade pip; \ + pip install poetry; \ + else \ + echo "Poetry is already installed."; \ + fi +endef + +define deactivate_virtualenv + if [ -n "$$VIRTUAL_ENV" ]; then \ + unset VIRTUAL_ENV; \ + unset PYTHONHOME; \ + unset -f pydoc >/dev/null 2>&1; \ + OLD_PATH="$$PATH"; \ + PATH=$$(echo -n "$$PATH" | awk -v RS=: -v ORS=: '/\/virtualenv\/bin$$/ {next} {print}'); \ + export PATH; \ + hash -r; \ + echo "Deactivated the virtual environment."; \ + fi +endef + +.SILENT: install install/prod lint run test clean + +install: + $(call deactivate_virtualenv) && \ + $(call install_poetry) && \ + poetry install --with dev + +install/prod: + $(call install_poetry) && \ + poetry install --without dev --no-root --no-interaction --no-ansi --no-cache + +lint: + $(ACTIVATE) && \ + $(call run_checks,.) + +run: + $(ACTIVATE) && ocean sail + +test: lint + $(ACTIVATE) && poetry run pytest + +clean: + @find . -name '.venv' -type d -exec rm -rf {} \; + @find . -name '*.pyc' -exec rm -rf {} \; + @find . -name '__pycache__' -exec rm -rf {} \; + @find . -name 'Thumbs.db' -exec rm -rf {} \; + @find . -name '*~' -exec rm -rf {} \; + rm -rf .cache + rm -rf build + rm -rf dist + rm -rf *.egg-info + rm -rf htmlcov + rm -rf .tox/ + rm -rf docs/_build + rm -rf dist/ \ No newline at end of file diff --git a/integrations/clickup/README.md b/integrations/clickup/README.md new file mode 100644 index 0000000000..438f4bac73 --- /dev/null +++ b/integrations/clickup/README.md @@ -0,0 +1,7 @@ +# ClickUp + +An integration used to import ClickUp resources into Port. + +#### Install & use the integration - [Integration documentation](https://docs.getport.io/build-your-software-catalog/sync-data-to-catalog/) *Replace this link with a link to this integration's documentation* + +#### Develop & improve the integration - [Ocean integration development documentation](https://ocean.getport.io/develop-an-integration/) \ No newline at end of file diff --git a/integrations/clickup/changelog/.gitignore b/integrations/clickup/changelog/.gitignore new file mode 100644 index 0000000000..f935021a8f --- /dev/null +++ b/integrations/clickup/changelog/.gitignore @@ -0,0 +1 @@ +!.gitignore diff --git a/integrations/clickup/debug.py b/integrations/clickup/debug.py new file mode 100644 index 0000000000..40b79f2d1c --- /dev/null +++ b/integrations/clickup/debug.py @@ -0,0 +1,4 @@ +from port_ocean import run + +if __name__ == "__main__": + run() diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py new file mode 100644 index 0000000000..48f98141e9 --- /dev/null +++ b/integrations/clickup/main.py @@ -0,0 +1,41 @@ +from typing import Any + +from port_ocean.context.ocean import ocean + + +# Required +# Listen to the resync event of all the kinds specified in the mapping inside port. +# Called each time with a different kind that should be returned from the source system. +@ocean.on_resync() +async def on_resync(kind: str) -> list[dict[Any, Any]]: + # 1. Get all data from the source system + # 2. Return a list of dictionaries with the raw data of the state to run the core logic of the framework for + # Example: + # if kind == "project": + # return [{"some_project_key": "someProjectValue", ...}] + # if kind == "issues": + # return [{"some_issue_key": "someIssueValue", ...}] + return [] + + +# The same sync logic can be registered for one of the kinds that are available in the mapping in port. +# @ocean.on_resync('project') +# async def resync_project(kind: str) -> list[dict[Any, Any]]: +# # 1. Get all projects from the source system +# # 2. Return a list of dictionaries with the raw data of the state +# return [{"some_project_key": "someProjectValue", ...}] +# +# @ocean.on_resync('issues') +# async def resync_issues(kind: str) -> list[dict[Any, Any]]: +# # 1. Get all issues from the source system +# # 2. Return a list of dictionaries with the raw data of the state +# return [{"some_issue_key": "someIssueValue", ...}] + + +# Optional +# Listen to the start event of the integration. Called once when the integration starts. +@ocean.on_start() +async def on_start() -> None: + # Something to do when the integration starts + # For example create a client to query 3rd party services - GitHub, Jira, etc... + print("Starting integration") diff --git a/integrations/clickup/poetry.toml b/integrations/clickup/poetry.toml new file mode 100644 index 0000000000..53b35d370d --- /dev/null +++ b/integrations/clickup/poetry.toml @@ -0,0 +1,3 @@ +[virtualenvs] +create = true +in-project = true diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml new file mode 100644 index 0000000000..949e530eeb --- /dev/null +++ b/integrations/clickup/pyproject.toml @@ -0,0 +1,102 @@ +[tool.poetry] +name = "clickup" +version = "0.1.0" +description = "Integration module for ClickUp" +authors = ["Iyanuoluwa Adebayo "] + +[tool.poetry.dependencies] +python = "^3.11" +port_ocean = { version = "^0.9.1", extras = ["cli"] } + +[tool.poetry.group.dev.dependencies] +pytest = "^7.2" +black = "^23.3.0" +mypy = "^1.3.0" +ruff = "^0.0.278" +pylint = "^2.17.4" +towncrier = "^23.6.0" + +[tool.towncrier] +directory = "changelog" +filename = "CHANGELOG.md" +package = "port_ocean" + + [[tool.towncrier.type]] + directory = "breaking" + name = "Breaking Changes" + showcontent = true + + [[tool.towncrier.type]] + directory = "deprecation" + name = "Deprecations" + showcontent = true + + [[tool.towncrier.type]] + directory = "feature" + name = "Features" + showcontent = true + + [[tool.towncrier.type]] + directory = "improvement" + name = "Improvements" + showcontent = true + + [[tool.towncrier.type]] + directory = "bugfix" + name = "Bug Fixes" + showcontent = true + + [[tool.towncrier.type]] + directory = "doc" + name = "Improved Documentation" + showcontent = true + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" + +[tool.mypy] +exclude = [ + 'venv', + '.venv', +] +plugins = [ + "pydantic.mypy" +] + +follow_imports = "silent" +warn_redundant_casts = true +warn_unused_ignores = true +disallow_any_generics = true +check_untyped_defs = true +no_implicit_reexport = true + +# for strict mypy: (this is the tricky one :-)) +disallow_untyped_defs = true + + +[tool.ruff] +# Never enforce `E501` (line length violations). +ignore = ["E501"] + +[tool.pydantic-mypy] +init_forbid_extra = true +init_typed = true +warn_required_dynamic_aliases = true +warn_untyped_fields = true + +[tool.black] +line-length = 88 +target-version = ['py311'] +include = '\.pyi?$' +exclude = ''' +/( + \scripts + \.toml + |\.sh + |\.git + |\.ini + |Dockerfile + |\.venv +)/ +''' diff --git a/integrations/clickup/tests/__init__.py b/integrations/clickup/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 91f3789ce47b2ffc36a02c9ecb3c6087f62036d4 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Wed, 3 Jul 2024 18:05:06 +0100 Subject: [PATCH 002/177] New Feature: ClickUp Integrations ClickUp Integration --- .../clickup/.port/resources/blueprints.json | 142 ++++++++++++++++++ .../.port/resources/port-app-config.yaml | 50 ++++++ integrations/clickup/.port/spec.yaml | 26 +++- integrations/clickup/clickup/client.py | 131 ++++++++++++++++ integrations/clickup/main.py | 112 +++++++++----- 5 files changed, 420 insertions(+), 41 deletions(-) create mode 100644 integrations/clickup/.port/resources/blueprints.json create mode 100644 integrations/clickup/.port/resources/port-app-config.yaml create mode 100644 integrations/clickup/clickup/client.py diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json new file mode 100644 index 0000000000..d5912db8d1 --- /dev/null +++ b/integrations/clickup/.port/resources/blueprints.json @@ -0,0 +1,142 @@ +[ + { + "identifier": "clickupTeam", + "description": "This blueprint represents a Clickup team", + "title": "Clickup Team", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "type": "string", + "title": "URL", + "format": "url" + }, + "members": { + "type": "array", + "title": "Members", + "items": { + "type": "string", + "format": "user" + } + } + }, + "required": [] + }, + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": {} +}, +{ + "identifier": "clickupProject", + "description": "This blueprint represents a ClickUp project", + "title": "ClickUp Project", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "title": "Project URL", + "type": "string", + "format": "url", + "description": "URL to the project in Clickup" + }, + "startDate": { + "title": "Project start date", + "type": "string", + "format": "date-time", + "description": "The start date of this project" + }, + "endDate": { + "title": "Project end date", + "type": "string", + "format": "date-time", + "description": "The end date of this project" + }, + "totalIssues": { + "title": "Total Issues", + "type": "number", + "description": "The total number of issues in the project" + } + }, + "required": [] + }, + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "team": { + "title": "Team", + "target": "clickupTeam", + "required": false, + "many": false + } + } +}, +{ + "identifier": "clickupIssue", + "title": "ClickUp Issue", + "icon": "Clickup", + "schema": { + "properties": { + "description": { + "title": "Issue Description", + "type": "string", + "description": "Detailed description of the issue" + }, + "url": { + "title": "Issue URL", + "type": "string", + "format": "url", + "description": "URL to the issue in Clickup" + }, + "status": { + "title": "Status", + "type": "string", + "description": "The status of the issue" + }, + "assignee": { + "title": "Assignee", + "type": "string", + "format": "user", + "description": "The user assigned to the issue" + }, + "creator": { + "title": "Creator", + "type": "string", + "description": "The user that created to the issue", + "format": "user" + }, + "priority": { + "title": "Priority", + "type": "string", + "description": "The priority of the issue" + }, + "created": { + "title": "Created At", + "type": "string", + "description": "The created datetime of the issue", + "format": "date-time" + }, + "updated": { + "title": "Updated At", + "type": "string", + "description": "The updated datetime of the issue", + "format": "date-time" + } + }, + "required": [] + }, + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "project": { + "title": "Project", + "description": "The Clickup project that manages this issue", + "target": "clickupProject", + "required": false, + "many": false + } + } +} +] \ No newline at end of file diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml new file mode 100644 index 0000000000..3e87745f69 --- /dev/null +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -0,0 +1,50 @@ +createMissingRelatedEntities: true +deleteDependentEntities: true +resources: + - kind: team + selector: + query: 'true' + port: + entity: + mappings: + blueprint: '"clickupTeam"' + identifier: .id + title: .name + properties: + url: "\"https://app.clickup.com/\" + .id + \"/home\"" + member: .members | map(.user.username) + - kind: project + selector: + query: 'true' + port: + entity: + mappings: + blueprint: '"clickupProject"' + identifier: .id + title: .name + properties: + url: "\"https://app.clickup.com/\" + .id + \"/list\"" + startDate: .start_date + endDate: .end_date + totalIssues: .task_count + - kind: issue + selector: + query: 'true' + port: + entity: + mappings: + blueprint: '"clickupIssue"' + identifier: .id | tostring + title: .name + properties: + tags: .tags + sloType: .type + description: .description + warningThreshold: .warning_threshold + targetThreshold: .target_threshold + createdBy: .creator.email + createdAt: .created_at | todate + updatedAt: .modified_at | todate + relations: + monitors: .monitor_ids | map(tostring) + services: '.monitor_tags + .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])' diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index 9cf72fe4b3..03ddd9dd29 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -1,15 +1,29 @@ +type: clickup description: ClickUp integration for Port Ocean -icon: Cookiecutter # Should be one of the available icons in Port +icon: Clickup features: - type: exporter - section: Git Providers # Should be one of the available sections in Port + section: Project Management resources: - - kind: - - kind: + - kind: issue + - kind: project + - kind: team configurations: - - name: myGitToken + - name: clickupPersonalToken + description: "Clickup personal token for authentication. Guide here - https://clickup.com/api/developer-portal/authentication#personal-token" required: true type: string sensitive: true - - name: someApplicationUrl + - name: clickupBaseUrl + description: "Clickup Base URL." type: url + required: true + default: "https://api.clickup.com" + - name: appHost + required: false + type: url + description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Jira" + - name: WorkspaceKey + description: "The ID of the workspace to integrate. Guide here - https://dev-doc.clickup.com/333/d/h/ad-455845/c464293970a6906" + required: true + type: string \ No newline at end of file diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py new file mode 100644 index 0000000000..9045c641f3 --- /dev/null +++ b/integrations/clickup/clickup/client.py @@ -0,0 +1,131 @@ +from typing import Any, AsyncGenerator, Optional, List +from httpx import Timeout +from loguru import logger +from port_ocean.utils import http_async_client + +PAGE_SIZE = 50 + +WEBHOOK_EVENTS = [ + "taskCreated", + "taskUpdated", + "taskDeleted", + "folderCreated", + "folderUpdated", + "folderDeleted", +] + + +class ClickupClient: + def __init__(self, clickup_url: str, clickup_token: str): + self.clickup_url = clickup_url + self.clickup_token = clickup_token + self.api_url = f"{self.clickup_url}/api/v2" + self.client = http_async_client + self.client.timeout = Timeout(30) + self.team_key = None + + async def initialize_team_key(self): + self.team_key = await self.get_team_key() + + @property + async def api_headers(self) -> dict[str, Any]: + return { + "Authorization": self.clickup_token, + "Content-Type": "application/json", + } + + async def get_team_key(self) -> List[str]: + url = f"{self.api_url}/team" + response = await self._send_api_request(url) + teams = response.get("teams", []) + team_ids = [] + for team in teams: + team_ids.append(team.get("id")) + return team_ids + + async def _send_api_request(self, url: str, params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, method: str = "GET") -> Any: + logger.debug(f"Sending request {method} to endpoint {url}") + response = await self.client.request(url=url, method=method, headers=await self.api_headers, params=params, + json=json_data) + response.raise_for_status() + return response.json() + + async def get_single_clickup_team(self, team_id: str) -> dict[str, Any]: + url = f"{self.api_url}/team/{team_id}" + response = await self._send_api_request(url) + team = response.get('team') + return team + + async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: + url = f"{self.api_url}/team" + response = await self._send_api_request(url) + teams = response.get("teams", []) + yield teams + + async def _get_spaces_in_team(self, team_id: str) -> List[dict[str, Any]]: + url = f"{self.api_url}/team/{team_id}/space" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + spaces = response.get("spaces") + return spaces + + async def get_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: + if self.team_key is None: + await self.initialize_team_key() + for team_id in self.team_key: + spaces = await self._get_spaces_in_team(team_id) + for space in spaces: + space_id = space.get("id") + url = f"{self.api_url}/space/{space_id}/folder" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + projects = response.get("folders") + yield projects + + async def get_single_project(self, folder_id: str) -> dict[str, Any]: + url = f"{self.api_url}/folder/{folder_id}" + response = await self._send_api_request(url) + return response + + async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: + if self.team_key is None: + await self.initialize_team_key() + for team_id in self.team_key: + url = f"{self.api_url}/team/{team_id}/task" + page = 0 + while True: + params = {"page": page} + response = await self._send_api_request(url, params) + yield response.get("tasks") + if response.get("last_page"): + break + page += 1 + + async def get_single_issue(self, task_id: str) -> dict[str, Any]: + url = f"{self.api_url}/task/{task_id}" + issue_response = await self._send_api_request(url) + return issue_response + + async def create_events_webhook(self, app_host: str) -> None: + if self.team_key is None: + await self.initialize_team_key() + for team_id in self.team_key: + webhook_target_app_host = f"{app_host}/integration/webhook" + clickup_get_webhook_url = f"{self.api_url}/team/{team_id}/webhook" + webhook_check_response = await self._send_api_request(clickup_get_webhook_url) + webhook_check = webhook_check_response.get("webhooks") + + for webhook in webhook_check: + if webhook["endpoint"] == webhook_target_app_host: + logger.info("Ocean real-time reporting webhook already exists on ClickUp") + return + + body = { + "endpoint": webhook_target_app_host, + "events": WEBHOOK_EVENTS, + } + logger.info("Subscribing to ClickUp webhooks...") + webhook_create_response = await self._send_api_request(clickup_get_webhook_url, json_data=body, + method="POST") + logger.info(f"Ocean real-time reporting webhook created on ClickUp - {webhook_create_response}") diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 48f98141e9..5dbc8a377d 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -1,41 +1,83 @@ +from enum import StrEnum from typing import Any - +from clickup.client import ClickupClient +from loguru import logger from port_ocean.context.ocean import ocean +from port_ocean.core.ocean_types import ASYNC_GENERATOR_RESYNC_TYPE + + +class ObjectKind(StrEnum): + TEAM = "team" + PROJECT = "project" + ISSUE = "issue" + + +async def init_client() -> ClickupClient: + client = ClickupClient( + ocean.integration_config["clickup_base_url"], + ocean.integration_config["clickup_personal_token"], + ) + await client.initialize_team_key() # Make sure team_key is initialized + return client + + +async def setup_application() -> None: + app_host = ocean.integration_config.get("app_host") + if not app_host: + logger.warning( + "App host was not provided, skipping webhook creation. " + "Without setting up the webhook, you will have to manually initiate resync to get updates from ClickUp." + ) + return + clickup_client = await init_client() # Await the initialization of the client + await clickup_client.create_events_webhook(app_host) + + +@ocean.on_resync(ObjectKind.TEAM) +async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: + clickup_client = await init_client() + async for team in clickup_client.get_clickup_teams(): + logger.info(f"Received team: {team}") + yield team + + +@ocean.on_resync(ObjectKind.PROJECT) +async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: + clickup_client = await init_client() + async for projects in clickup_client.get_projects(): + logger.info(f"Received project batch with {len(projects)} projects") + yield projects + + +@ocean.on_resync(ObjectKind.ISSUE) +async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: + clickup_client = await init_client() + async for issues in clickup_client.get_paginated_issues(): + logger.info(f"Received issue batch with {len(issues)} issues") + yield issues + + +@ocean.router.post("/webhook") +async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: + clickup_client = await init_client() + logger.info(f'Received webhook event of type: {data.get("event")}') + if "folderCreated" == data.get("event"): + logger.info(f'Received webhook event for project: {data["folder_id"]}') + project = await clickup_client.get_single_project(data["folder_id"]) + await ocean.register_raw(ObjectKind.PROJECT, [project]) + elif "taskCreated" == data.get("event"): + for task in data["history_items"]: + logger.info(f'Received webhook event for issue: {task["id"]}') + issue = await clickup_client.get_single_issue(task["id"]) + await ocean.register_raw(ObjectKind.ISSUE, [issue]) + logger.info("Webhook event processed") + return {"ok": True} -# Required -# Listen to the resync event of all the kinds specified in the mapping inside port. -# Called each time with a different kind that should be returned from the source system. -@ocean.on_resync() -async def on_resync(kind: str) -> list[dict[Any, Any]]: - # 1. Get all data from the source system - # 2. Return a list of dictionaries with the raw data of the state to run the core logic of the framework for - # Example: - # if kind == "project": - # return [{"some_project_key": "someProjectValue", ...}] - # if kind == "issues": - # return [{"some_issue_key": "someIssueValue", ...}] - return [] - - -# The same sync logic can be registered for one of the kinds that are available in the mapping in port. -# @ocean.on_resync('project') -# async def resync_project(kind: str) -> list[dict[Any, Any]]: -# # 1. Get all projects from the source system -# # 2. Return a list of dictionaries with the raw data of the state -# return [{"some_project_key": "someProjectValue", ...}] -# -# @ocean.on_resync('issues') -# async def resync_issues(kind: str) -> list[dict[Any, Any]]: -# # 1. Get all issues from the source system -# # 2. Return a list of dictionaries with the raw data of the state -# return [{"some_issue_key": "someIssueValue", ...}] - - -# Optional -# Listen to the start event of the integration. Called once when the integration starts. @ocean.on_start() async def on_start() -> None: - # Something to do when the integration starts - # For example create a client to query 3rd party services - GitHub, Jira, etc... - print("Starting integration") + logger.info("Starting Port Ocean ClickUp integration") + if ocean.event_listener_type == "ONCE": + logger.info("Skipping webhook creation because the event listener is ONCE") + return + await setup_application() From 845d38eba3de61289d3befac085fea54c32639d6 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Wed, 3 Jul 2024 22:26:21 +0100 Subject: [PATCH 003/177] Update: updated clickup integration - Added support for both folder less and folder based projects - Added custom properties of workspace id to each project --- .../.port/resources/port-app-config.yaml | 25 +++++------ integrations/clickup/.port/spec.yaml | 6 +-- integrations/clickup/clickup/client.py | 42 ++++++++++++++----- integrations/clickup/clickup/utils.py | 5 +++ integrations/clickup/main.py | 10 ++++- 5 files changed, 59 insertions(+), 29 deletions(-) create mode 100644 integrations/clickup/clickup/utils.py diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 3e87745f69..9cb39644a7 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -23,10 +23,12 @@ resources: identifier: .id title: .name properties: - url: "\"https://app.clickup.com/\" + .id + \"/list\"" + url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " startDate: .start_date - endDate: .end_date + endDate: .due_date totalIssues: .task_count + relations: + team: .__team_id - kind: issue selector: query: 'true' @@ -34,17 +36,16 @@ resources: entity: mappings: blueprint: '"clickupIssue"' - identifier: .id | tostring + identifier: .id title: .name properties: - tags: .tags - sloType: .type description: .description - warningThreshold: .warning_threshold - targetThreshold: .target_threshold - createdBy: .creator.email - createdAt: .created_at | todate - updatedAt: .modified_at | todate + url: .url + status: .status.status + assignee: .assignees | map(.username) + creator: .creator.username + priority: .priority + created: .date_created | todate + updated: .date_updated | todate relations: - monitors: .monitor_ids | map(tostring) - services: '.monitor_tags + .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])' + project: .list.id diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index 03ddd9dd29..247ea77365 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -22,8 +22,4 @@ configurations: - name: appHost required: false type: url - description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Jira" - - name: WorkspaceKey - description: "The ID of the workspace to integrate. Guide here - https://dev-doc.clickup.com/333/d/h/ad-455845/c464293970a6906" - required: true - type: string \ No newline at end of file + description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Jira" \ No newline at end of file diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 9045c641f3..75da175c1c 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -1,6 +1,8 @@ from typing import Any, AsyncGenerator, Optional, List from httpx import Timeout from loguru import logger + +from integrations.clickup.clickup.utils import CustomProperties from port_ocean.utils import http_async_client PAGE_SIZE = 50 @@ -63,26 +65,44 @@ async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: teams = response.get("teams", []) yield teams - async def _get_spaces_in_team(self, team_id: str) -> List[dict[str, Any]]: + async def _get_spaces_in_team(self, team_id: str) -> AsyncGenerator[str, None]: url = f"{self.api_url}/team/{team_id}/space" params = {"archived": "false"} response = await self._send_api_request(url, params) spaces = response.get("spaces") - return spaces - - async def get_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: - if self.team_key is None: - await self.initialize_team_key() + for space in spaces: + yield space.get("id") + + async def _get_folders_in_space(self, team_id: str) -> AsyncGenerator[str, None]: + async for space in self._get_spaces_in_team(team_id): + url = f"{self.api_url}/space/{space}/folders" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + folders = response.get("folders") + for folder in folders: + yield folder.get("id") + + async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: for team_id in self.team_key: - spaces = await self._get_spaces_in_team(team_id) - for space in spaces: - space_id = space.get("id") - url = f"{self.api_url}/space/{space_id}/folder" + async for folder_id in self._get_folders_in_space(team_id): + url = f"{self.api_url}/folder/{folder_id}/list" params = {"archived": "false"} response = await self._send_api_request(url, params) - projects = response.get("folders") + projects = response.get("lists") yield projects + async def get_folderless_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: + for team_id in self.team_key: + async for space_id in self._get_spaces_in_team(team_id): + url = f"{self.api_url}/space/{space_id}/list" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + projects = response.get("lists") + yield [ + {**project, CustomProperties.TEAM_ID: team_id} + for project in projects + ] + async def get_single_project(self, folder_id: str) -> dict[str, Any]: url = f"{self.api_url}/folder/{folder_id}" response = await self._send_api_request(url) diff --git a/integrations/clickup/clickup/utils.py b/integrations/clickup/clickup/utils.py new file mode 100644 index 0000000000..0d09e31ecb --- /dev/null +++ b/integrations/clickup/clickup/utils.py @@ -0,0 +1,5 @@ +import enum + + +class CustomProperties(enum.StrEnum): + TEAM_ID = "__team_id" diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 5dbc8a377d..220efcd121 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -44,7 +44,15 @@ async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: @ocean.on_resync(ObjectKind.PROJECT) async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() - async for projects in clickup_client.get_projects(): + async for projects in clickup_client.get_folderless_projects(): + logger.info(f"Received project batch with {len(projects)} projects") + yield projects + + +@ocean.on_resync(ObjectKind.PROJECT) +async def on_resync_folder_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: + clickup_client = await init_client() + async for projects in clickup_client.get_folder_projects(): logger.info(f"Received project batch with {len(projects)} projects") yield projects From a50a24a1b89a88e16f1b9936b1d29793312e2ebe Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 10:24:00 +0100 Subject: [PATCH 004/177] Update client.py Fixed import statement for custom properties --- integrations/clickup/clickup/client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 75da175c1c..889d53c387 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -1,8 +1,7 @@ from typing import Any, AsyncGenerator, Optional, List from httpx import Timeout from loguru import logger - -from integrations.clickup.clickup.utils import CustomProperties +from utils import CustomProperties from port_ocean.utils import http_async_client PAGE_SIZE = 50 From 0b3a96aa85d4bbed390cc6b038d20deaf418651d Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 10:25:44 +0100 Subject: [PATCH 005/177] Update client.py Fixed import statement for custom properties --- integrations/clickup/clickup/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 889d53c387..2bcc40320b 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -1,7 +1,7 @@ from typing import Any, AsyncGenerator, Optional, List from httpx import Timeout from loguru import logger -from utils import CustomProperties +from .utils import CustomProperties from port_ocean.utils import http_async_client PAGE_SIZE = 50 From 408941644475387cb923a9867940decacdbde91b Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 10:38:44 +0100 Subject: [PATCH 006/177] Update client.py added team_id to issues in folder --- integrations/clickup/clickup/client.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 2bcc40320b..0833e07304 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -88,7 +88,10 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None params = {"archived": "false"} response = await self._send_api_request(url, params) projects = response.get("lists") - yield projects + yield [ + {**project, CustomProperties.TEAM_ID: team_id} + for project in projects + ] async def get_folderless_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: for team_id in self.team_key: From 3701e3c97da57b0755edb9170074c300675eba18 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 11:16:06 +0100 Subject: [PATCH 007/177] Fixes: Config and Client - Fixed getting folders in space - Fixed username not string --- integrations/clickup/.port/resources/port-app-config.yaml | 6 +++--- integrations/clickup/clickup/client.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 9cb39644a7..c77f359902 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: .members | map(.user.username) + member: (.members | map(.user.username | tostring)) - kind: project selector: query: 'true' @@ -42,8 +42,8 @@ resources: description: .description url: .url status: .status.status - assignee: .assignees | map(.username) - creator: .creator.username + assignee: (.assignees | map(.username | tostring)) + creator: .creator.username | to priority: .priority created: .date_created | todate updated: .date_updated | todate diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 0833e07304..1a82674b90 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -74,7 +74,7 @@ async def _get_spaces_in_team(self, team_id: str) -> AsyncGenerator[str, None]: async def _get_folders_in_space(self, team_id: str) -> AsyncGenerator[str, None]: async for space in self._get_spaces_in_team(team_id): - url = f"{self.api_url}/space/{space}/folders" + url = f"{self.api_url}/space/{space}/folder" params = {"archived": "false"} response = await self._send_api_request(url, params) folders = response.get("folders") From a1c85404eacdc3f0403026a45b454ea33fc7308d Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 11:36:50 +0100 Subject: [PATCH 008/177] Update port-app-config.yaml Fixed data mapping problems --- integrations/clickup/.port/resources/port-app-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index c77f359902..36ca82a059 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -42,10 +42,10 @@ resources: description: .description url: .url status: .status.status - assignee: (.assignees | map(.username | tostring)) + assignee: (.assignees | map(.username | tostring) | first) creator: .creator.username | to priority: .priority - created: .date_created | todate - updated: .date_updated | todate + created: if .date_created == null then null else .date_created | todate end + updated: if .date_updated == null then null else .date_updated | todate end relations: project: .list.id From 9b29877daaa5d8959203f91541bc1335c6af588d Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 11:44:22 +0100 Subject: [PATCH 009/177] Update port-app-config.yaml Fixed data mapping --- integrations/clickup/.port/resources/port-app-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 36ca82a059..acbcf89ef9 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -42,10 +42,10 @@ resources: description: .description url: .url status: .status.status - assignee: (.assignees | map(.username | tostring) | first) + assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | to priority: .priority - created: if .date_created == null then null else .date_created | todate end - updated: if .date_updated == null then null else .date_updated | todate end + created: if .date_created == null then "" else .date_created | todate end + updated: if .date_created == null then "" else .date_updated | todate end relations: project: .list.id From 510028a2f05299986e790242a5b0098cacfef082 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 11:49:18 +0100 Subject: [PATCH 010/177] Update port-app-config.yaml Fixed assignees issues --- integrations/clickup/.port/resources/port-app-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index acbcf89ef9..f921609670 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: .start_date - endDate: .due_date + startDate: if .start_date == null then "" else .start_date | todate end + endDate: if .due_date == null then "" else .due_date | todate end totalIssues: .task_count relations: team: .__team_id @@ -44,7 +44,7 @@ resources: status: .status.status assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | to - priority: .priority + priority: if .priority == null then "" else .priority created: if .date_created == null then "" else .date_created | todate end updated: if .date_created == null then "" else .date_updated | todate end relations: From b06e724f82763a7c5b7b1175ea830f36fb797fa5 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 12:00:25 +0100 Subject: [PATCH 011/177] Update port-app-config.yaml Fixing date mapping --- integrations/clickup/.port/resources/port-app-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index f921609670..1c6f8ba390 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date == null then "" else .start_date | todate end - endDate: if .due_date == null then "" else .due_date | todate end + startDate: if .start_date == null then "0000-00-00" else (.start_date | todate | tostring) end + endDate: if .due_date == null then "0000-00-00" else (.due_date | todate | tostring) end totalIssues: .task_count relations: team: .__team_id @@ -45,7 +45,7 @@ resources: assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | to priority: if .priority == null then "" else .priority - created: if .date_created == null then "" else .date_created | todate end - updated: if .date_created == null then "" else .date_updated | todate end + created: if .date_created == null then "0000-00-00" else (.date_created | todate | tostring) end + updated: if .date_updated == null then "0000-00-00" else (.date_updated | todate | tostring) end relations: project: .list.id From 78ea4d5f211e2b9d053ff26bb2cca17fa6c268ae Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 12:41:34 +0100 Subject: [PATCH 012/177] Update port-app-config.yaml Made username string --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 1c6f8ba390..e1255f00be 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -43,7 +43,7 @@ resources: url: .url status: .status.status assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end - creator: .creator.username | to + creator: .creator.username | tostring priority: if .priority == null then "" else .priority created: if .date_created == null then "0000-00-00" else (.date_created | todate | tostring) end updated: if .date_updated == null then "0000-00-00" else (.date_updated | todate | tostring) end From 8f102b1fcc57340531cd4977ffdaf47818a7bac9 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 12:43:13 +0100 Subject: [PATCH 013/177] Update port-app-config.yaml Fixed unterminated if --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index e1255f00be..e0d933ffa1 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -44,7 +44,7 @@ resources: status: .status.status assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | tostring - priority: if .priority == null then "" else .priority + priority: if .priority == null then "" else .priority end created: if .date_created == null then "0000-00-00" else (.date_created | todate | tostring) end updated: if .date_updated == null then "0000-00-00" else (.date_updated | todate | tostring) end relations: From 6359e287e118b624fc5b11a08542b74272289823 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 12:49:15 +0100 Subject: [PATCH 014/177] Update port-app-config.yaml Correcting data mapping --- .../clickup/.port/resources/port-app-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index e0d933ffa1..39c6a22e9e 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date == null then "0000-00-00" else (.start_date | todate | tostring) end - endDate: if .due_date == null then "0000-00-00" else (.due_date | todate | tostring) end + startDate: if .start_date !== null then (.start_date | todate) end + endDate: if .due_date !== null then (.due_date | todate) end totalIssues: .task_count relations: team: .__team_id @@ -44,8 +44,8 @@ resources: status: .status.status assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | tostring - priority: if .priority == null then "" else .priority end - created: if .date_created == null then "0000-00-00" else (.date_created | todate | tostring) end - updated: if .date_updated == null then "0000-00-00" else (.date_updated | todate | tostring) end + priority: if .priority !== null and .priority is not None then .priority end + created: if .date_created !== null then (.date_created | todate) end + updated: if .date_updated !== null then (.date_updated | todate) end relations: project: .list.id From e01ddea7ee76b47430ea60405e2e9ac7d484c1f7 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 12:55:08 +0100 Subject: [PATCH 015/177] Update port-app-config.yaml --- .../clickup/.port/resources/port-app-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 39c6a22e9e..5cfd2e106e 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date !== null then (.start_date | todate) end - endDate: if .due_date !== null then (.due_date | todate) end + startDate: if .start_date != null then (.start_date | todate) end + endDate: if .due_date != null then (.due_date | todate) end totalIssues: .task_count relations: team: .__team_id @@ -44,8 +44,8 @@ resources: status: .status.status assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | tostring - priority: if .priority !== null and .priority is not None then .priority end - created: if .date_created !== null then (.date_created | todate) end - updated: if .date_updated !== null then (.date_updated | todate) end + priority: if .priority != null and .priority is not None then .priority end + created: if .date_created != null then (.date_created | todate) end + updated: if .date_updated != null then (.date_updated | todate) end relations: project: .list.id From 8ca4ba3872aa46d4e2e6169a8e2fa4120f4e91ad Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 12:56:49 +0100 Subject: [PATCH 016/177] Update port-app-config.yaml --- .../clickup/.port/resources/port-app-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 5cfd2e106e..3153da52fc 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date != null then (.start_date | todate) end - endDate: if .due_date != null then (.due_date | todate) end + startDate: if .start_date != null then (.start_date | todate) else end + endDate: if .due_date != null then (.due_date | todate) else end totalIssues: .task_count relations: team: .__team_id @@ -44,8 +44,8 @@ resources: status: .status.status assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | tostring - priority: if .priority != null and .priority is not None then .priority end - created: if .date_created != null then (.date_created | todate) end - updated: if .date_updated != null then (.date_updated | todate) end + priority: if .priority != null and .priority is not None then .priority else end + created: if .date_created != null then (.date_created | todate) else end + updated: if .date_updated != null then (.date_updated | todate) else end relations: project: .list.id From db5e94d43dac5a773154951386051f4a2df3e51f Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 13:00:40 +0100 Subject: [PATCH 017/177] Update port-app-config.yaml --- integrations/clickup/.port/resources/port-app-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 3153da52fc..db913b0d95 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date != null then (.start_date | todate) else end - endDate: if .due_date != null then (.due_date | todate) else end + startDate: if .start_date != null then (.start_date | todate) end + endDate: if .due_date != null then (.due_date | todate) end totalIssues: .task_count relations: team: .__team_id @@ -48,4 +48,4 @@ resources: created: if .date_created != null then (.date_created | todate) else end updated: if .date_updated != null then (.date_updated | todate) else end relations: - project: .list.id + project: .list.id \ No newline at end of file From f85d81a91e11c931b0257522e9e1e0861ebcf1d5 Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Thu, 4 Jul 2024 13:37:33 +0100 Subject: [PATCH 018/177] Fixed all data mapping issues --- .../.port/resources/port-app-config.yaml | 10 +- integrations/clickup/poetry.lock | 1429 +++++++++++++++++ 2 files changed, 1434 insertions(+), 5 deletions(-) create mode 100644 integrations/clickup/poetry.lock diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index db913b0d95..16d344d3db 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date != null then (.start_date | todate) end - endDate: if .due_date != null then (.due_date | todate) end + startDate: if .start_date != null then (.start_date | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 + endDate: if .due_date != null then (.due_date | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 totalIssues: .task_count relations: team: .__team_id @@ -44,8 +44,8 @@ resources: status: .status.status assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end creator: .creator.username | tostring - priority: if .priority != null and .priority is not None then .priority else end - created: if .date_created != null then (.date_created | todate) else end - updated: if .date_updated != null then (.date_updated | todate) else end + priority: if .priority != null then .priority | tostring else " " end + created: if .date_created != null then (.date_created | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 + updated: if .date_updated != null then (.date_updated | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 relations: project: .list.id \ No newline at end of file diff --git a/integrations/clickup/poetry.lock b/integrations/clickup/poetry.lock new file mode 100644 index 0000000000..51cbb54c47 --- /dev/null +++ b/integrations/clickup/poetry.lock @@ -0,0 +1,1429 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "aiostream" +version = "0.5.2" +description = "Generator-based operators for asynchronous iteration" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiostream-0.5.2-py3-none-any.whl", hash = "sha256:054660370be9d37f6fe3ece3851009240416bd082e469fd90cc8673d3818cf71"}, + {file = "aiostream-0.5.2.tar.gz", hash = "sha256:b71b519a2d66c38f0872403ab86417955b77352f08d9ad02ad46fc3926b389f4"}, +] + +[package.dependencies] +typing-extensions = "*" + +[[package]] +name = "anyio" +version = "4.4.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, +] + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "arrow" +version = "1.3.0" +description = "Better dates & times for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + +[[package]] +name = "astroid" +version = "2.15.8" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.7.2" +files = [ + {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"}, + {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"}, +] + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} + +[[package]] +name = "binaryornot" +version = "0.4.4" +description = "Ultra-lightweight pure Python package to check if a file is binary or text." +optional = false +python-versions = "*" +files = [ + {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, + {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, +] + +[package.dependencies] +chardet = ">=3.0.2" + +[[package]] +name = "black" +version = "23.12.1" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, + {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, + {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, + {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, + {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, + {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, + {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, + {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, + {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, + {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, + {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, + {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, + {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, + {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, + {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, + {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, + {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, + {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, + {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, + {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, + {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, + {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "certifi" +version = "2024.6.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, +] + +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +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.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[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 = "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 = "confluent-kafka" +version = "2.4.0" +description = "Confluent's Python client for Apache Kafka" +optional = false +python-versions = "*" +files = [ + {file = "confluent-kafka-2.4.0.tar.gz", hash = "sha256:201c6182304c5864c8a1b1aae2f99bf51fa332017abbec05a3a1fb2ff242c41d"}, + {file = "confluent_kafka-2.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:827820321e0ac6a7f75f119f7ab4dcbbbd59c95d7807f6eb79f03a4cb6b9ab25"}, + {file = "confluent_kafka-2.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c74a06a658f72dd0f6df9b0fbfc5b1b483b3263fde6abd925bba512879995cc"}, + {file = "confluent_kafka-2.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:108bc30e1153734cd36d88a299c7cf0c69fe6c95d67f4cce9f9180adaefef839"}, + {file = "confluent_kafka-2.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:cbe32df72b9d7fee198cf12eb3770270d99b122613b0e3abfb55a13294f6a54a"}, + {file = "confluent_kafka-2.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:c2e9e1dd2238e5b55cf541c9dbd3e665531418e0cc965e6143f593f64a3f79a5"}, + {file = "confluent_kafka-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a28bf5b59f28e3357d113cc8c50ba09389dcc3327ca13cc502e9c3228f2ab5dc"}, + {file = "confluent_kafka-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:506c867d987ab78494fc94ec6a966ddcb3ce3cb75809e098060d654d280281e0"}, + {file = "confluent_kafka-2.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b02cd0eb338a8dc5db0ea07243bbf457670655a3846732f81a091b8e3d5d456"}, + {file = "confluent_kafka-2.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:15d356dd1c7699ed332f262bf0aa825a177c50f7debca0f1ec14873531603b2d"}, + {file = "confluent_kafka-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:0c1b89e1bd790dd82b64a4dd746e7a0ce3ebed7f17b0642d488c1bb0056ba763"}, + {file = "confluent_kafka-2.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a11acfd79f0448095c6492d2ea34cd3df4864d78d72326bed0859d875eb7a62d"}, + {file = "confluent_kafka-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd53d58a6648e4d5e435ff5178248b91af050a4478ed51a95b2b0eaedddafdb1"}, + {file = "confluent_kafka-2.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a5e9cc9fff71c70f1520ab917f33cf66181b29c46cf9940da1af6a52cc086a6"}, + {file = "confluent_kafka-2.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b0d5a2d7563b9ca9bef09668d6aae6e360f1e9455672dc0886d78d76ced682c9"}, + {file = "confluent_kafka-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:d09aa0c67532c47ec6cd08c50feaa8338e77d18fc83181c46e5a5cb88a5b25ce"}, + {file = "confluent_kafka-2.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f2e39794270088157f65e5b2b5ba7e0217759412de20088f5873bdb176084ab3"}, + {file = "confluent_kafka-2.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0591645e709ea8392f8d41b9ff752f1cdb57c71730c9be2deae3184303d3efaf"}, + {file = "confluent_kafka-2.4.0-cp36-cp36m-manylinux_2_28_aarch64.whl", hash = "sha256:07f38339da116527d9516a0b1899b499ebfe5f906ef54c0780a309ebee585c12"}, + {file = "confluent_kafka-2.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c661f4c014f78ee478667a5018fb62ec2a4b61322410a9be314bdbf6ead481d7"}, + {file = "confluent_kafka-2.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a8b440684a22d9239b857d1be065ea2844537ff20bb675c75e7a9e2adbd5ce9a"}, + {file = "confluent_kafka-2.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac7120919a4189018120a40da8d9c05bd6e024f60638901483bb6a46c45a115"}, + {file = "confluent_kafka-2.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:6a2b81902b0c824549f85f49774535285242b1472e52ab0a18260526840a8ecf"}, + {file = "confluent_kafka-2.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:78f6776aca06c81308c8be66c754a3b8281a20dd9af697b2cfcb5c2272878df9"}, + {file = "confluent_kafka-2.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2858fb428f29086df2a50554d9093d176ec4b1f76240a62efe136acc493f7fb6"}, + {file = "confluent_kafka-2.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9608b8b1145a0b41e6c6949ac9ec974e74f1ed2d065b26eae73e208668fa20cf"}, + {file = "confluent_kafka-2.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baaf1022972bd213bf20cfccb1b13b613d7ab13ebcafacd65220bd5908f5e460"}, + {file = "confluent_kafka-2.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:16be3360f040b5d17dcb7e1b66a170b72f428c98d0978705b0a3081de756b2c7"}, + {file = "confluent_kafka-2.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:45e6f719f6bd95210e0451b50cd19f33a44d7b16be560217240caa71f165420d"}, + {file = "confluent_kafka-2.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3cf1b40ae59569e50ba15da1dc0030bac904b74d8aff82f02a16df3bb9b87e53"}, + {file = "confluent_kafka-2.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b5dd225596325159eee928caba47e0cf3f03ce3c8244371457a1823d7c66c22"}, + {file = "confluent_kafka-2.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d338e8189f5836b916c632e0f2db9a197352c199db7323ca3f2bd1785cb9a747"}, + {file = "confluent_kafka-2.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:40d18f1bd1bac6d2cf8dbf47da11cdb82d077b26a81ea551136515a1079ec532"}, + {file = "confluent_kafka-2.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:52f937ab1cde9aacb01288293d374bf09da728b79cf907504dec8f3c4f82030e"}, +] + +[package.extras] +avro = ["avro (>=1.11.1,<2)", "fastavro (>=0.23.0,<1.0)", "fastavro (>=1.0)", "requests"] +dev = ["avro (>=1.11.1,<2)", "fastavro (>=0.23.0,<1.0)", "fastavro (>=1.0)", "flake8", "pytest", "pytest (==4.6.4)", "pytest-timeout", "requests"] +doc = ["avro (>=1.11.1,<2)", "fastavro (>=0.23.0,<1.0)", "fastavro (>=1.0)", "requests", "sphinx", "sphinx-rtd-theme"] +json = ["jsonschema", "pyrsistent", "pyrsistent (==0.16.1)", "requests"] +protobuf = ["protobuf", "requests"] +schema-registry = ["requests"] + +[[package]] +name = "cookiecutter" +version = "2.6.0" +description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d"}, + {file = "cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c"}, +] + +[package.dependencies] +arrow = "*" +binaryornot = ">=0.4.4" +click = ">=7.0,<9.0.0" +Jinja2 = ">=2.7,<4.0.0" +python-slugify = ">=4.0.0" +pyyaml = ">=5.3.1" +requests = ">=2.23.0" +rich = "*" + +[[package]] +name = "dill" +version = "0.3.8" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + +[[package]] +name = "fastapi" +version = "0.110.3" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastapi-0.110.3-py3-none-any.whl", hash = "sha256:fd7600612f755e4050beb74001310b5a7e1796d149c2ee363124abdfa0289d32"}, + {file = "fastapi-0.110.3.tar.gz", hash = "sha256:555700b0159379e94fdbfc6bb66a0f1c43f4cf7060f25239af3d84b63a656626"}, +] + +[package.dependencies] +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +starlette = ">=0.37.2,<0.38.0" +typing-extensions = ">=4.8.0" + +[package.extras] +all = ["email_validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, + {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.26.0)"] + +[[package]] +name = "httpx" +version = "0.27.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "incremental" +version = "22.10.0" +description = "\"A small library that versions your Python projects.\"" +optional = false +python-versions = "*" +files = [ + {file = "incremental-22.10.0-py2.py3-none-any.whl", hash = "sha256:b864a1f30885ee72c5ac2835a761b8fe8aa9c28b9395cacf27286602688d3e51"}, + {file = "incremental-22.10.0.tar.gz", hash = "sha256:912feeb5e0f7e0188e6f42241d2f450002e11bbc0937c65865045854c24c0bd0"}, +] + +[package.extras] +mypy = ["click (>=6.0)", "mypy (==0.812)", "twisted (>=16.4.0)"] +scripts = ["click (>=6.0)", "twisted (>=16.4.0)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jinja2-time" +version = "0.2.0" +description = "Jinja2 Extension for Dates and Times" +optional = false +python-versions = "*" +files = [ + {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"}, + {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, +] + +[package.dependencies] +arrow = "*" +jinja2 = "*" + +[[package]] +name = "lazy-object-proxy" +version = "1.10.0" +description = "A fast and thorough lazy object proxy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, + {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, +] + +[[package]] +name = "loguru" +version = "0.7.2" +description = "Python logging made (stupidly) simple" +optional = false +python-versions = ">=3.5" +files = [ + {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, + {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, +] + +[package.dependencies] +colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} +win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} + +[package.extras] +dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] + +[[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 = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[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 = "mypy" +version = "1.10.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[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 = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "port-ocean" +version = "0.9.1" +description = "Port Ocean is a CLI tool for managing your Port projects." +optional = false +python-versions = "<4.0,>=3.11" +files = [ + {file = "port_ocean-0.9.1-py3-none-any.whl", hash = "sha256:ead27b47816355b52a2316d54ee190d2a4200a5c708befcd691ce69319268947"}, + {file = "port_ocean-0.9.1.tar.gz", hash = "sha256:12636b6214d69182aff3d3e1a4db2ae889d13a40d099fea816a1249b8b8fbebf"}, +] + +[package.dependencies] +aiostream = ">=0.5.2,<0.6.0" +click = {version = ">=8.1.3,<9.0.0", optional = true, markers = "extra == \"cli\""} +confluent-kafka = ">=2.1.1,<3.0.0" +cookiecutter = {version = ">=2.1.1,<3.0.0", optional = true, markers = "extra == \"cli\""} +fastapi = ">=0.100,<0.111" +httpx = ">=0.24.1,<0.28.0" +jinja2-time = {version = ">=0.2.0,<0.3.0", optional = true, markers = "extra == \"cli\""} +loguru = ">=0.7.0,<0.8.0" +pydantic = {version = ">=1.10.8,<2.0.0", extras = ["dotenv"]} +pydispatcher = ">=2.0.7,<3.0.0" +pyhumps = ">=3.8.0,<4.0.0" +pyjq = ">=2.6.0,<3.0.0" +pyyaml = ">=6.0,<7.0" +rich = {version = ">=13.4.1,<14.0.0", optional = true, markers = "extra == \"cli\""} +six = ">=1.16.0,<2.0.0" +tomli = ">=2.0.1,<3.0.0" +urllib3 = ">=1.26.16,<3.0.0" +uvicorn = ">=0.22,<0.30" +werkzeug = ">=2.3.4,<4.0.0" + +[package.extras] +cli = ["click (>=8.1.3,<9.0.0)", "cookiecutter (>=2.1.1,<3.0.0)", "jinja2-time (>=0.2.0,<0.3.0)", "rich (>=13.4.1,<14.0.0)"] + +[[package]] +name = "pydantic" +version = "1.10.17" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, + {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, + {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, + {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, + {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, + {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, + {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, + {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, + {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, + {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, + {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, + {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, + {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, + {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, + {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, + {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, + {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, + {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, + {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, + {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, + {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, + {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, + {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, + {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, + {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, + {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, + {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, + {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, + {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, + {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, + {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, + {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, + {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, + {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, + {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, + {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, + {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, + {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, + {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, + {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, + {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, + {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, + {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, +] + +[package.dependencies] +python-dotenv = {version = ">=0.10.4", optional = true, markers = "extra == \"dotenv\""} +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pydispatcher" +version = "2.0.7" +description = "Multi-producer multi-consumer in-memory signal dispatch system" +optional = false +python-versions = "*" +files = [ + {file = "PyDispatcher-2.0.7-py3-none-any.whl", hash = "sha256:96543bea04115ffde08f851e1d45cacbfd1ee866ac42127d9b476dc5aefa7de0"}, + {file = "PyDispatcher-2.0.7.tar.gz", hash = "sha256:b777c6ad080dc1bad74a4c29d6a46914fa6701ac70f94b0d66fbcfde62f5be31"}, +] + +[package.extras] +dev = ["tox"] + +[[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 = "pyhumps" +version = "3.8.0" +description = "🐫 Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node" +optional = false +python-versions = "*" +files = [ + {file = "pyhumps-3.8.0-py3-none-any.whl", hash = "sha256:060e1954d9069f428232a1adda165db0b9d8dfdce1d265d36df7fbff540acfd6"}, + {file = "pyhumps-3.8.0.tar.gz", hash = "sha256:498026258f7ee1a8e447c2e28526c0bea9407f9a59c03260aee4bd6c04d681a3"}, +] + +[[package]] +name = "pyjq" +version = "2.6.0" +description = "Binding for jq JSON processor." +optional = false +python-versions = "*" +files = [ + {file = "pyjq-2.6.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:6e0e4f398e81b1fb9794874d81fc9240d4a155adba5a1aecda77e717bcfae03e"}, + {file = "pyjq-2.6.0.tar.gz", hash = "sha256:e083f326f4af8b07b8ca6424d1f99afbdd7db9b727284da5f919b9816077f2e4"}, +] + +[[package]] +name = "pylint" +version = "2.17.7" +description = "python code static checker" +optional = false +python-versions = ">=3.7.2" +files = [ + {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"}, + {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"}, +] + +[package.dependencies] +astroid = ">=2.15.8,<=2.17.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = {version = ">=0.3.6", markers = "python_version >= \"3.11\""} +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomlkit = ">=0.10.1" + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + +[[package]] +name = "pytest" +version = "7.4.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[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 = "python-slugify" +version = "8.0.4" +description = "A Python slugify application that also handles Unicode" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, + {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[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 = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[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 = "ruff" +version = "0.0.278" +description = "An extremely fast Python linter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.0.278-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:1a90ebd8f2a554db1ee8d12b2f3aa575acbd310a02cd1a9295b3511a4874cf98"}, + {file = "ruff-0.0.278-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:38ca1c0c8c1221fe64c0a66784c91501d09a8ed02a4dbfdc117c0ce32a81eefc"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c62a0bde4d20d087cabce2fa8b012d74c2e985da86d00fb3359880469b90e31"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7545bb037823cd63dca19280f75a523a68bd3e78e003de74609320d6822b5a52"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb380d2d6fdb60656a0b5fa78305535db513fc72ce11f4532cc1641204ef380"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d11149c7b186f224f2055e437a030cd83b164a43cc0211314c33ad1553ed9c4c"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666e739fb2685277b879d493848afe6933e3be30d40f41fe0e571ad479d57d77"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ec8b0469b54315803aaf1fbf9a37162a3849424cab6182496f972ad56e0ea702"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c25b96602695a147d62a572865b753ef56aff1524abab13b9436724df30f9bd7"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a48621f5f372d5019662db5b3dbfc5f1450f927683d75f1153fe0ebf20eb9698"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1078125123a3c68e92463afacedb7e41b15ccafc09e510c6c755a23087afc8de"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3ce0d620e257b4cad16e2f0c103b2f43a07981668a3763380542e8a131d11537"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1cae4c07d334eb588f171f1363fa89a8911047eb93184276be11a24dbbc996c7"}, + {file = "ruff-0.0.278-py3-none-win32.whl", hash = "sha256:70d39f5599d8449082ab8ce542fa98e16413145eb411dd1dc16575b44565d52d"}, + {file = "ruff-0.0.278-py3-none-win_amd64.whl", hash = "sha256:e131595ab7f4ce61a1650463bd2fe304b49e7d0deb0dfa664b92817c97cdba5f"}, + {file = "ruff-0.0.278-py3-none-win_arm64.whl", hash = "sha256:737a0cfb6c36aaa92d97a46957dfd5e55329299074ad06ed12663b98e0c6fc82"}, + {file = "ruff-0.0.278.tar.gz", hash = "sha256:1a9f1d925204cfba81b18368b7ac943befcfccc3a41e170c91353b674c6b7a66"}, +] + +[[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 = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "starlette" +version = "0.37.2" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.8" +files = [ + {file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"}, + {file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"}, +] + +[package.dependencies] +anyio = ">=3.4.0,<5" + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] + +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tomlkit" +version = "0.12.5" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, +] + +[[package]] +name = "towncrier" +version = "23.11.0" +description = "Building newsfiles for your project." +optional = false +python-versions = ">=3.8" +files = [ + {file = "towncrier-23.11.0-py3-none-any.whl", hash = "sha256:2e519ca619426d189e3c98c99558fe8be50c9ced13ea1fc20a4a353a95d2ded7"}, + {file = "towncrier-23.11.0.tar.gz", hash = "sha256:13937c247e3f8ae20ac44d895cf5f96a60ad46cfdcc1671759530d7837d9ee5d"}, +] + +[package.dependencies] +click = "*" +incremental = "*" +jinja2 = "*" + +[package.extras] +dev = ["furo", "packaging", "sphinx (>=5)", "twisted"] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20240316" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, +] + +[[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 = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[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 = "uvicorn" +version = "0.29.0" +description = "The lightning-fast ASGI server." +optional = false +python-versions = ">=3.8" +files = [ + {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, + {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, +] + +[package.dependencies] +click = ">=7.0" +h11 = ">=0.8" + +[package.extras] +standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] + +[[package]] +name = "werkzeug" +version = "3.0.3" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"}, + {file = "werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "win32-setctime" +version = "1.1.0" +description = "A small Python utility to set file creation time on Windows" +optional = false +python-versions = ">=3.5" +files = [ + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, +] + +[package.extras] +dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "cf017d49bb23753d024aeea6c5132b5f121afb2cf02c8724fd32f4c7db18aa50" From 133a58b5f70ddc7c63201b2dbe23de6e07deab35 Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Thu, 4 Jul 2024 14:16:33 +0100 Subject: [PATCH 019/177] Changelog --- integrations/clickup/CHANGELOG.md | 6 ++++++ integrations/clickup/changelog/0.0.1.feature | 1 + 2 files changed, 7 insertions(+) create mode 100644 integrations/clickup/changelog/0.0.1.feature diff --git a/integrations/clickup/CHANGELOG.md b/integrations/clickup/CHANGELOG.md index 14e279d66d..b28e5d4e3a 100644 --- a/integrations/clickup/CHANGELOG.md +++ b/integrations/clickup/CHANGELOG.md @@ -6,3 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +# Port_Ocean 0.0.1 (2024-07-04) + +### Features + +- New Integration for Clickup (0.0.1) diff --git a/integrations/clickup/changelog/0.0.1.feature b/integrations/clickup/changelog/0.0.1.feature new file mode 100644 index 0000000000..1b7e866b04 --- /dev/null +++ b/integrations/clickup/changelog/0.0.1.feature @@ -0,0 +1 @@ +New Integration for Clickup \ No newline at end of file From 1ca3b3e04cb2335e97b93b1c34b1c349c9603704 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 14:44:29 +0100 Subject: [PATCH 020/177] Fixes Formatted and fixed webhook to listen for list instead of folders --- integrations/clickup/clickup/client.py | 67 +++++++++++++++++++------- integrations/clickup/clickup/utils.py | 2 + integrations/clickup/main.py | 6 +-- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 1a82674b90..c3fc35e612 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -1,8 +1,8 @@ from typing import Any, AsyncGenerator, Optional, List from httpx import Timeout from loguru import logger -from .utils import CustomProperties from port_ocean.utils import http_async_client +from .utils import CustomProperties PAGE_SIZE = 50 @@ -10,13 +10,15 @@ "taskCreated", "taskUpdated", "taskDeleted", - "folderCreated", - "folderUpdated", - "folderDeleted", + "listCreated", + "listUpdated", + "listDeleted", ] class ClickupClient: + """Clickup client to interact with Clickup API.""" + def __init__(self, clickup_url: str, clickup_token: str): self.clickup_url = clickup_url self.clickup_token = clickup_token @@ -36,6 +38,7 @@ async def api_headers(self) -> dict[str, Any]: } async def get_team_key(self) -> List[str]: + """Get the team key for the Clickup account.""" url = f"{self.api_url}/team" response = await self._send_api_request(url) teams = response.get("teams", []) @@ -44,27 +47,41 @@ async def get_team_key(self) -> List[str]: team_ids.append(team.get("id")) return team_ids - async def _send_api_request(self, url: str, params: Optional[dict[str, Any]] = None, - json_data: Optional[dict[str, Any]] = None, method: str = "GET") -> Any: + async def _send_api_request( + self, + url: str, + params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, + method: str = "GET", + ) -> Any: + """Send a request to the Clickup API.""" logger.debug(f"Sending request {method} to endpoint {url}") - response = await self.client.request(url=url, method=method, headers=await self.api_headers, params=params, - json=json_data) + response = await self.client.request( + url=url, + method=method, + headers=await self.api_headers, + params=params, + json=json_data, + ) response.raise_for_status() return response.json() async def get_single_clickup_team(self, team_id: str) -> dict[str, Any]: + """Get a single Clickup team by team_id.""" url = f"{self.api_url}/team/{team_id}" response = await self._send_api_request(url) - team = response.get('team') + team = response.get("team") return team async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: + """Get all Clickup teams.""" url = f"{self.api_url}/team" response = await self._send_api_request(url) teams = response.get("teams", []) yield teams async def _get_spaces_in_team(self, team_id: str) -> AsyncGenerator[str, None]: + """Get all spaces in a workspace.""" url = f"{self.api_url}/team/{team_id}/space" params = {"archived": "false"} response = await self._send_api_request(url, params) @@ -73,6 +90,7 @@ async def _get_spaces_in_team(self, team_id: str) -> AsyncGenerator[str, None]: yield space.get("id") async def _get_folders_in_space(self, team_id: str) -> AsyncGenerator[str, None]: + """Get all folders in a space.""" async for space in self._get_spaces_in_team(team_id): url = f"{self.api_url}/space/{space}/folder" params = {"archived": "false"} @@ -82,6 +100,7 @@ async def _get_folders_in_space(self, team_id: str) -> AsyncGenerator[str, None] yield folder.get("id") async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: + """Get all projects with a folder parent.""" for team_id in self.team_key: async for folder_id in self._get_folders_in_space(team_id): url = f"{self.api_url}/folder/{folder_id}/list" @@ -93,7 +112,10 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None for project in projects ] - async def get_folderless_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: + async def get_folderless_projects( + self, + ) -> AsyncGenerator[List[dict[str, Any]], None]: + """Get all projects without a folder parent.""" for team_id in self.team_key: async for space_id in self._get_spaces_in_team(team_id): url = f"{self.api_url}/space/{space_id}/list" @@ -105,12 +127,14 @@ async def get_folderless_projects(self) -> AsyncGenerator[List[dict[str, Any]], for project in projects ] - async def get_single_project(self, folder_id: str) -> dict[str, Any]: - url = f"{self.api_url}/folder/{folder_id}" + async def get_single_project(self, list_id: str) -> dict[str, Any]: + """Get a single project by folder_id.""" + url = f"{self.api_url}/list/{list_id}" response = await self._send_api_request(url) return response async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: + """Get all issues in a project.""" if self.team_key is None: await self.initialize_team_key() for team_id in self.team_key: @@ -125,22 +149,28 @@ async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], Non page += 1 async def get_single_issue(self, task_id: str) -> dict[str, Any]: + """Get a single issue by task_id.""" url = f"{self.api_url}/task/{task_id}" issue_response = await self._send_api_request(url) return issue_response async def create_events_webhook(self, app_host: str) -> None: + """Create a webhook for ClickUp events.""" if self.team_key is None: await self.initialize_team_key() for team_id in self.team_key: webhook_target_app_host = f"{app_host}/integration/webhook" clickup_get_webhook_url = f"{self.api_url}/team/{team_id}/webhook" - webhook_check_response = await self._send_api_request(clickup_get_webhook_url) + webhook_check_response = await self._send_api_request( + clickup_get_webhook_url + ) webhook_check = webhook_check_response.get("webhooks") for webhook in webhook_check: if webhook["endpoint"] == webhook_target_app_host: - logger.info("Ocean real-time reporting webhook already exists on ClickUp") + logger.info( + "Ocean real-time reporting webhook already exists on ClickUp" + ) return body = { @@ -148,6 +178,9 @@ async def create_events_webhook(self, app_host: str) -> None: "events": WEBHOOK_EVENTS, } logger.info("Subscribing to ClickUp webhooks...") - webhook_create_response = await self._send_api_request(clickup_get_webhook_url, json_data=body, - method="POST") - logger.info(f"Ocean real-time reporting webhook created on ClickUp - {webhook_create_response}") + webhook_create_response = await self._send_api_request( + clickup_get_webhook_url, json_data=body, method="POST" + ) + logger.info( + f"Ocean real-time reporting webhook created on ClickUp - {webhook_create_response}" + ) diff --git a/integrations/clickup/clickup/utils.py b/integrations/clickup/clickup/utils.py index 0d09e31ecb..3a396933a3 100644 --- a/integrations/clickup/clickup/utils.py +++ b/integrations/clickup/clickup/utils.py @@ -2,4 +2,6 @@ class CustomProperties(enum.StrEnum): + """Creating custom properties for the Clickup integration.""" + TEAM_ID = "__team_id" diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 220efcd121..129891710b 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -69,9 +69,9 @@ async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: clickup_client = await init_client() logger.info(f'Received webhook event of type: {data.get("event")}') - if "folderCreated" == data.get("event"): - logger.info(f'Received webhook event for project: {data["folder_id"]}') - project = await clickup_client.get_single_project(data["folder_id"]) + if "listCreated" == data.get("event"): + logger.info(f'Received webhook event for project: {data["list_id"]}') + project = await clickup_client.get_single_project(data["list_id"]) await ocean.register_raw(ObjectKind.PROJECT, [project]) elif "taskCreated" == data.get("event"): for task in data["history_items"]: From 7e2a39d5fa4fcc219be229215f55af671da92bb4 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 19:04:09 +0100 Subject: [PATCH 021/177] Deleting unnecessary files --- integrations/clickup/.dockerignore | 94 ------------------- .../clickup/.port/resources/.gitignore | 1 - integrations/clickup/changelog/.gitignore | 1 - integrations/clickup/changelog/0.0.1.feature | 1 - 4 files changed, 97 deletions(-) delete mode 100644 integrations/clickup/.dockerignore delete mode 100644 integrations/clickup/.port/resources/.gitignore delete mode 100644 integrations/clickup/changelog/.gitignore delete mode 100644 integrations/clickup/changelog/0.0.1.feature diff --git a/integrations/clickup/.dockerignore b/integrations/clickup/.dockerignore deleted file mode 100644 index dc28c4f316..0000000000 --- a/integrations/clickup/.dockerignore +++ /dev/null @@ -1,94 +0,0 @@ -# Git -.git -.gitignore -.gitattributes - - -# CI -.codeclimate.yml -.travis.yml -.taskcluster.yml - -# Docker -docker-compose.yml -Dockerfile -.docker -.dockerignore - -# Byte-compiled / optimized / DLL files -**/__pycache__/ -**/*.py[cod] - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# 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/ -.coverage -.cache -nosetests.xml -coverage.xml - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Virtual environment -.env -.venv/ -venv/ - -# PyCharm -.idea - -# Python mode for VIM -.ropeproject -**/.ropeproject - -# Vim swap files -**/*.swp - -# VS Code -.vscode/ - -*.md -**/.ruff_cache -**/cahangelog -**/tests \ No newline at end of file diff --git a/integrations/clickup/.port/resources/.gitignore b/integrations/clickup/.port/resources/.gitignore deleted file mode 100644 index f935021a8f..0000000000 --- a/integrations/clickup/.port/resources/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/integrations/clickup/changelog/.gitignore b/integrations/clickup/changelog/.gitignore deleted file mode 100644 index f935021a8f..0000000000 --- a/integrations/clickup/changelog/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/integrations/clickup/changelog/0.0.1.feature b/integrations/clickup/changelog/0.0.1.feature deleted file mode 100644 index 1b7e866b04..0000000000 --- a/integrations/clickup/changelog/0.0.1.feature +++ /dev/null @@ -1 +0,0 @@ -New Integration for Clickup \ No newline at end of file From 7639166b3e8ffd23be806d601e12b7381fb5ea5e Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 19:55:03 +0100 Subject: [PATCH 022/177] Update port-app-config.yaml - Removed unnecessary default - Replaced username with email --- .../clickup/.port/resources/port-app-config.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 16d344d3db..c89ec86f8c 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: (.members | map(.user.username | tostring)) + member: (.members | map(.user.email | tostring)) - kind: project selector: query: 'true' @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date != null then (.start_date | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 - endDate: if .due_date != null then (.due_date | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 + startDate: if .start_date != null then (.start_date | todate) else " " end + endDate: if .due_date != null then (.due_date | todate) else " " end totalIssues: .task_count relations: team: .__team_id @@ -42,10 +42,10 @@ resources: description: .description url: .url status: .status.status - assignee: if (.assignees | length) > 0 then .assignees[0].username else "" end - creator: .creator.username | tostring - priority: if .priority != null then .priority | tostring else " " end - created: if .date_created != null then (.date_created | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 - updated: if .date_updated != null then (.date_updated | todate) else "946684800" | todate end # Unix epoch for 01/01/2000 + assignee: if (.assignees | length) > 0 then .assignees[0].email else "" end + creator: .creator.email | tostring + priority: if .priority != null then .priority.priority else " " end + created: if .date_created != null then (.date_created | todate) else " " end + updated: if .date_updated != null then (.date_updated | todate) else " " end relations: project: .list.id \ No newline at end of file From 1e9be3a27e45db9b493026971a71e1b55fb120ef Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Thu, 4 Jul 2024 20:40:30 +0100 Subject: [PATCH 023/177] Update port-app-config.yaml Refixed date --- integrations/clickup/.port/resources/port-app-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index c89ec86f8c..f45dcb496c 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date != null then (.start_date | todate) else " " end - endDate: if .due_date != null then (.due_date | todate) else " " end + startDate: if .start_date==null then .start_date else .start_date | tonumber / 1000 | todate end + endDate: if .due_date==null then .due_date else .due_date | tonumber / 1000 | todate end totalIssues: .task_count relations: team: .__team_id @@ -45,7 +45,7 @@ resources: assignee: if (.assignees | length) > 0 then .assignees[0].email else "" end creator: .creator.email | tostring priority: if .priority != null then .priority.priority else " " end - created: if .date_created != null then (.date_created | todate) else " " end - updated: if .date_updated != null then (.date_updated | todate) else " " end + created: if .date_created==null then .date_created else .date_created | tonumber / 1000 | todate end + updated: if .date_updated==null then .date_updated else .date_updated | tonumber / 1000 | todate end relations: project: .list.id \ No newline at end of file From 3baf0fa9740411576b537bd9d31daa2a98272db6 Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Thu, 4 Jul 2024 23:24:32 +0100 Subject: [PATCH 024/177] Fixed date formats --- integrations/clickup/.port/resources/port-app-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index f45dcb496c..3d42aee3e3 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -24,8 +24,8 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " - startDate: if .start_date==null then .start_date else .start_date | tonumber / 1000 | todate end - endDate: if .due_date==null then .due_date else .due_date | tonumber / 1000 | todate end + startDate: if .start_date!=null then .start_date | tonumber / 1000 | todate else "" | todate end + endDate: if .due_date!=null then .due_date | tonumber / 1000 | todate else "" | todate end totalIssues: .task_count relations: team: .__team_id @@ -45,7 +45,7 @@ resources: assignee: if (.assignees | length) > 0 then .assignees[0].email else "" end creator: .creator.email | tostring priority: if .priority != null then .priority.priority else " " end - created: if .date_created==null then .date_created else .date_created | tonumber / 1000 | todate end - updated: if .date_updated==null then .date_updated else .date_updated | tonumber / 1000 | todate end + created: if .date_created!=null then .date_created | tonumber / 1000 | todate else "" | todate end + updated: if .date_updated!=null then .date_updated | tonumber / 1000 | todate else "" | todate end relations: project: .list.id \ No newline at end of file From e431398842a22a7c915bf2f4abdbe05c5fae5dad Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Fri, 5 Jul 2024 09:58:29 +0100 Subject: [PATCH 025/177] Fixed headers function --- integrations/clickup/clickup/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index c3fc35e612..994eb555af 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -31,7 +31,7 @@ async def initialize_team_key(self): self.team_key = await self.get_team_key() @property - async def api_headers(self) -> dict[str, Any]: + def api_headers(self) -> dict[str, Any]: return { "Authorization": self.clickup_token, "Content-Type": "application/json", @@ -59,7 +59,7 @@ async def _send_api_request( response = await self.client.request( url=url, method=method, - headers=await self.api_headers, + headers=self.api_headers, params=params, json=json_data, ) From 2b4cfe3b7ffee9f7492231792850b4825afa7123 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 11:39:56 +0100 Subject: [PATCH 026/177] Fixes - Corrected the tracking of Team ID and cached the response that are needed repeatedly in an event. --- integrations/clickup/.port/spec.yaml | 2 +- integrations/clickup/clickup/client.py | 169 +++++++++++-------------- integrations/clickup/clickup/utils.py | 7 - integrations/clickup/main.py | 3 +- 4 files changed, 75 insertions(+), 106 deletions(-) delete mode 100644 integrations/clickup/clickup/utils.py diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index 247ea77365..fcced72c6f 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -22,4 +22,4 @@ configurations: - name: appHost required: false type: url - description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Jira" \ No newline at end of file + description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Clickup" \ No newline at end of file diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 994eb555af..856e366dda 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -2,9 +2,7 @@ from httpx import Timeout from loguru import logger from port_ocean.utils import http_async_client -from .utils import CustomProperties - -PAGE_SIZE = 50 +from port_ocean.utils.cache import cache_iterator_result WEBHOOK_EVENTS = [ "taskCreated", @@ -25,10 +23,6 @@ def __init__(self, clickup_url: str, clickup_token: str): self.api_url = f"{self.clickup_url}/api/v2" self.client = http_async_client self.client.timeout = Timeout(30) - self.team_key = None - - async def initialize_team_key(self): - self.team_key = await self.get_team_key() @property def api_headers(self) -> dict[str, Any]: @@ -37,16 +31,6 @@ def api_headers(self) -> dict[str, Any]: "Content-Type": "application/json", } - async def get_team_key(self) -> List[str]: - """Get the team key for the Clickup account.""" - url = f"{self.api_url}/team" - response = await self._send_api_request(url) - teams = response.get("teams", []) - team_ids = [] - for team in teams: - team_ids.append(team.get("id")) - return team_ids - async def _send_api_request( self, url: str, @@ -66,13 +50,7 @@ async def _send_api_request( response.raise_for_status() return response.json() - async def get_single_clickup_team(self, team_id: str) -> dict[str, Any]: - """Get a single Clickup team by team_id.""" - url = f"{self.api_url}/team/{team_id}" - response = await self._send_api_request(url) - team = response.get("team") - return team - + @cache_iterator_result() async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all Clickup teams.""" url = f"{self.api_url}/team" @@ -80,52 +58,53 @@ async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: teams = response.get("teams", []) yield teams - async def _get_spaces_in_team(self, team_id: str) -> AsyncGenerator[str, None]: + @cache_iterator_result() + async def _get_spaces_in_team( + self, team_id: str + ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all spaces in a workspace.""" url = f"{self.api_url}/team/{team_id}/space" params = {"archived": "false"} response = await self._send_api_request(url, params) - spaces = response.get("spaces") - for space in spaces: - yield space.get("id") + yield response.get("spaces") - async def _get_folders_in_space(self, team_id: str) -> AsyncGenerator[str, None]: + async def _get_folders_in_space(self, team_id: str) -> List[dict[str, Any]]: """Get all folders in a space.""" - async for space in self._get_spaces_in_team(team_id): - url = f"{self.api_url}/space/{space}/folder" - params = {"archived": "false"} - response = await self._send_api_request(url, params) - folders = response.get("folders") - for folder in folders: - yield folder.get("id") + async for spaces in self._get_spaces_in_team(team_id): + for space in spaces: + url = f"{self.api_url}/space/{space.get('id')}/folder" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + return response.get("folders") async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects with a folder parent.""" - for team_id in self.team_key: - async for folder_id in self._get_folders_in_space(team_id): - url = f"{self.api_url}/folder/{folder_id}/list" - params = {"archived": "false"} - response = await self._send_api_request(url, params) - projects = response.get("lists") - yield [ - {**project, CustomProperties.TEAM_ID: team_id} - for project in projects - ] + async for teams in self.get_clickup_teams(): + for team in teams: + team_id = team.get("id") + for folder in await self._get_folders_in_space(team_id): + url = f"{self.api_url}/folder/{folder.get('id')}/list" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + projects = response.get("lists") + yield [{**project, "__team_id": team_id} for project in projects] async def get_folderless_projects( self, ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects without a folder parent.""" - for team_id in self.team_key: - async for space_id in self._get_spaces_in_team(team_id): - url = f"{self.api_url}/space/{space_id}/list" - params = {"archived": "false"} - response = await self._send_api_request(url, params) - projects = response.get("lists") - yield [ - {**project, CustomProperties.TEAM_ID: team_id} - for project in projects - ] + async for teams in self.get_clickup_teams(): + for team in teams: + team_id = team.get("id") + async for spaces in self._get_spaces_in_team(team_id): + for space in spaces: + url = f"{self.api_url}/space/{space.get('id')}/list" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + projects = response.get("lists") + yield [ + {**project, "__team_id": team_id} for project in projects + ] async def get_single_project(self, list_id: str) -> dict[str, Any]: """Get a single project by folder_id.""" @@ -135,18 +114,17 @@ async def get_single_project(self, list_id: str) -> dict[str, Any]: async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" - if self.team_key is None: - await self.initialize_team_key() - for team_id in self.team_key: - url = f"{self.api_url}/team/{team_id}/task" - page = 0 - while True: - params = {"page": page} - response = await self._send_api_request(url, params) - yield response.get("tasks") - if response.get("last_page"): - break - page += 1 + async for teams in self.get_clickup_teams(): + for team in teams: + url = f"{self.api_url}/team/{team.get('id')}/task" + page = 0 + while True: + params = {"page": page} + response = await self._send_api_request(url, params) + yield response.get("tasks") + if response.get("last_page"): + break + page += 1 async def get_single_issue(self, task_id: str) -> dict[str, Any]: """Get a single issue by task_id.""" @@ -156,31 +134,30 @@ async def get_single_issue(self, task_id: str) -> dict[str, Any]: async def create_events_webhook(self, app_host: str) -> None: """Create a webhook for ClickUp events.""" - if self.team_key is None: - await self.initialize_team_key() - for team_id in self.team_key: - webhook_target_app_host = f"{app_host}/integration/webhook" - clickup_get_webhook_url = f"{self.api_url}/team/{team_id}/webhook" - webhook_check_response = await self._send_api_request( - clickup_get_webhook_url - ) - webhook_check = webhook_check_response.get("webhooks") - - for webhook in webhook_check: - if webhook["endpoint"] == webhook_target_app_host: - logger.info( - "Ocean real-time reporting webhook already exists on ClickUp" - ) - return - - body = { - "endpoint": webhook_target_app_host, - "events": WEBHOOK_EVENTS, - } - logger.info("Subscribing to ClickUp webhooks...") - webhook_create_response = await self._send_api_request( - clickup_get_webhook_url, json_data=body, method="POST" - ) - logger.info( - f"Ocean real-time reporting webhook created on ClickUp - {webhook_create_response}" - ) + async for teams in self.get_clickup_teams(): + for team in teams: + team_id = team.get("id") + webhook_target_app_host = f"{app_host}/integration/webhook" + clickup_get_webhook_url = f"{self.api_url}/team/{team_id}/webhook" + webhook_check_response = await self._send_api_request( + clickup_get_webhook_url + ) + webhook_check = webhook_check_response.get("webhooks") + for webhook in webhook_check: + if webhook["endpoint"] == webhook_target_app_host: + logger.info( + "Ocean real-time reporting webhook already exists on ClickUp" + ) + return + + body = { + "endpoint": webhook_target_app_host, + "events": WEBHOOK_EVENTS, + } + logger.info("Subscribing to ClickUp webhooks...") + webhook_create_response = await self._send_api_request( + clickup_get_webhook_url, json_data=body, method="POST" + ) + logger.info( + f"Ocean real-time reporting webhook created on ClickUp - {webhook_create_response}" + ) diff --git a/integrations/clickup/clickup/utils.py b/integrations/clickup/clickup/utils.py deleted file mode 100644 index 3a396933a3..0000000000 --- a/integrations/clickup/clickup/utils.py +++ /dev/null @@ -1,7 +0,0 @@ -import enum - - -class CustomProperties(enum.StrEnum): - """Creating custom properties for the Clickup integration.""" - - TEAM_ID = "__team_id" diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 129891710b..9441a99731 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -17,7 +17,6 @@ async def init_client() -> ClickupClient: ocean.integration_config["clickup_base_url"], ocean.integration_config["clickup_personal_token"], ) - await client.initialize_team_key() # Make sure team_key is initialized return client @@ -37,7 +36,7 @@ async def setup_application() -> None: async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() async for team in clickup_client.get_clickup_teams(): - logger.info(f"Received team: {team}") + logger.info(f"Received team of length {len(team)}") yield team From 73adc6aa9d6b25982497d6bc0c840bc0341b0969 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 11:53:48 +0100 Subject: [PATCH 027/177] Update client.py Fixed folder export error --- integrations/clickup/clickup/client.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 856e366dda..bdfa63cf69 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -68,26 +68,31 @@ async def _get_spaces_in_team( response = await self._send_api_request(url, params) yield response.get("spaces") - async def _get_folders_in_space(self, team_id: str) -> List[dict[str, Any]]: + async def _get_folders_in_space( + self, team_id: str + ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all folders in a space.""" async for spaces in self._get_spaces_in_team(team_id): for space in spaces: url = f"{self.api_url}/space/{space.get('id')}/folder" params = {"archived": "false"} response = await self._send_api_request(url, params) - return response.get("folders") + yield response.get("folders") async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects with a folder parent.""" async for teams in self.get_clickup_teams(): for team in teams: team_id = team.get("id") - for folder in await self._get_folders_in_space(team_id): - url = f"{self.api_url}/folder/{folder.get('id')}/list" - params = {"archived": "false"} - response = await self._send_api_request(url, params) - projects = response.get("lists") - yield [{**project, "__team_id": team_id} for project in projects] + async for folders in self._get_folders_in_space(team_id): + for folder in folders: + url = f"{self.api_url}/folder/{folder.get('id')}/list" + params = {"archived": "false"} + response = await self._send_api_request(url, params) + projects = response.get("lists") + yield [ + {**project, "__team_id": team_id} for project in projects + ] async def get_folderless_projects( self, From 14e43f9f15a32afb4fd8e723d2cdf6d75e768d0c Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 12:01:48 +0100 Subject: [PATCH 028/177] Update port-app-config.yaml Remapped members --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 3d42aee3e3..527fe62c82 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: (.members | map(.user.email | tostring)) + member: [.members[].user.email] - kind: project selector: query: 'true' From a005aea586aea332a00c2086bad0e4c4cfca6662 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 12:03:41 +0100 Subject: [PATCH 029/177] Update port-app-config.yaml --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 527fe62c82..6d2c4f16d9 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: [.members[].user.email] + member: .members[].user.email - kind: project selector: query: 'true' From d46959336ef850d92d399237757529b20e3d8714 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 12:12:06 +0100 Subject: [PATCH 030/177] Update port-app-config.yaml --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 6d2c4f16d9..e09ffb99d9 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: .members[].user.email + member: "[members[*].user.email]" - kind: project selector: query: 'true' From 886fccde4c5075d2266d89596931e69713cd9d50 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 12:13:30 +0100 Subject: [PATCH 031/177] Update port-app-config.yaml --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index e09ffb99d9..645e2edbac 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: "[members[*].user.email]" + member: "[members[].user.email]" - kind: project selector: query: 'true' From 9bcabb130f4c752bf54689a0fe2b8371e26f7a13 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 12:15:07 +0100 Subject: [PATCH 032/177] Update port-app-config.yaml --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 645e2edbac..47070e8867 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: "[members[].user.email]" + member: "[.members[].user.email]" - kind: project selector: query: 'true' From 4366e213f5f24563f4a9f8262b350feb9b4ed8dd Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 12:26:19 +0100 Subject: [PATCH 033/177] Update client.py --- integrations/clickup/clickup/client.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index bdfa63cf69..a559987e82 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -54,9 +54,7 @@ async def _send_api_request( async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all Clickup teams.""" url = f"{self.api_url}/team" - response = await self._send_api_request(url) - teams = response.get("teams", []) - yield teams + yield (await self._send_api_request(url)).get("teams", []) @cache_iterator_result() async def _get_spaces_in_team( @@ -65,8 +63,7 @@ async def _get_spaces_in_team( """Get all spaces in a workspace.""" url = f"{self.api_url}/team/{team_id}/space" params = {"archived": "false"} - response = await self._send_api_request(url, params) - yield response.get("spaces") + yield (await self._send_api_request(url, params)).get("spaces", []) async def _get_folders_in_space( self, team_id: str @@ -76,8 +73,7 @@ async def _get_folders_in_space( for space in spaces: url = f"{self.api_url}/space/{space.get('id')}/folder" params = {"archived": "false"} - response = await self._send_api_request(url, params) - yield response.get("folders") + yield (await self._send_api_request(url, params)).get("folders") async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects with a folder parent.""" From e60ae29d241f8e696567671605ad14d8aed7ef1b Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 12:49:36 +0100 Subject: [PATCH 034/177] Update client.py --- integrations/clickup/clickup/client.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index a559987e82..8034ec355c 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -4,6 +4,7 @@ from port_ocean.utils import http_async_client from port_ocean.utils.cache import cache_iterator_result +TEAM_ID = "__team_id" WEBHOOK_EVENTS = [ "taskCreated", "taskUpdated", @@ -86,9 +87,7 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None params = {"archived": "false"} response = await self._send_api_request(url, params) projects = response.get("lists") - yield [ - {**project, "__team_id": team_id} for project in projects - ] + yield [{**project, TEAM_ID: team_id} for project in projects] async def get_folderless_projects( self, @@ -103,9 +102,7 @@ async def get_folderless_projects( params = {"archived": "false"} response = await self._send_api_request(url, params) projects = response.get("lists") - yield [ - {**project, "__team_id": team_id} for project in projects - ] + yield [{**project, TEAM_ID: team_id} for project in projects] async def get_single_project(self, list_id: str) -> dict[str, Any]: """Get a single project by folder_id.""" From 52d8390a763b89fcdf0fec28885a8e7c7388ee05 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 14:54:51 +0100 Subject: [PATCH 035/177] Update main.py Updated webhook single issue handling --- integrations/clickup/main.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 9441a99731..5883bcbdc3 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -73,10 +73,9 @@ async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: project = await clickup_client.get_single_project(data["list_id"]) await ocean.register_raw(ObjectKind.PROJECT, [project]) elif "taskCreated" == data.get("event"): - for task in data["history_items"]: - logger.info(f'Received webhook event for issue: {task["id"]}') - issue = await clickup_client.get_single_issue(task["id"]) - await ocean.register_raw(ObjectKind.ISSUE, [issue]) + logger.info(f'Received webhook event for issue: {data["task_id"]}') + issue = await clickup_client.get_single_issue(data["task_id"]) + await ocean.register_raw(ObjectKind.ISSUE, [issue]) logger.info("Webhook event processed") return {"ok": True} From 4559381519ad5609052bb52f85f9cc76b69f835a Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 17:50:58 +0100 Subject: [PATCH 036/177] Delete .gitignore --- integrations/clickup/.gitignore | 153 -------------------------------- 1 file changed, 153 deletions(-) delete mode 100644 integrations/clickup/.gitignore diff --git a/integrations/clickup/.gitignore b/integrations/clickup/.gitignore deleted file mode 100644 index d550eaaeaf..0000000000 --- a/integrations/clickup/.gitignore +++ /dev/null @@ -1,153 +0,0 @@ -# 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 -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/ \ No newline at end of file From 1abcca8c0656ff5e004c0ab60e69055f3c0bac13 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 18:50:19 +0100 Subject: [PATCH 037/177] Revert "Delete .gitignore" This reverts commit 4559381519ad5609052bb52f85f9cc76b69f835a. --- integrations/clickup/.gitignore | 153 ++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 integrations/clickup/.gitignore diff --git a/integrations/clickup/.gitignore b/integrations/clickup/.gitignore new file mode 100644 index 0000000000..d550eaaeaf --- /dev/null +++ b/integrations/clickup/.gitignore @@ -0,0 +1,153 @@ +# 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 +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/ \ No newline at end of file From 15a0e34947587b82628eeca4fb18d4e28f2ab66a Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 19:35:36 +0100 Subject: [PATCH 038/177] Update to Client and Main - deleted unnecessary variables - extend webhook to cover handle all webhook events tracked --- integrations/clickup/clickup/client.py | 19 +++++++++++-------- integrations/clickup/main.py | 22 ++++++++++++++++------ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 8034ec355c..c8ed011b50 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -80,14 +80,15 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None """Get all projects with a folder parent.""" async for teams in self.get_clickup_teams(): for team in teams: - team_id = team.get("id") - async for folders in self._get_folders_in_space(team_id): + async for folders in self._get_folders_in_space(team.get("id")): for folder in folders: url = f"{self.api_url}/folder/{folder.get('id')}/list" params = {"archived": "false"} response = await self._send_api_request(url, params) projects = response.get("lists") - yield [{**project, TEAM_ID: team_id} for project in projects] + yield [ + {**project, TEAM_ID: team.get("id")} for project in projects + ] async def get_folderless_projects( self, @@ -95,14 +96,15 @@ async def get_folderless_projects( """Get all projects without a folder parent.""" async for teams in self.get_clickup_teams(): for team in teams: - team_id = team.get("id") - async for spaces in self._get_spaces_in_team(team_id): + async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: url = f"{self.api_url}/space/{space.get('id')}/list" params = {"archived": "false"} response = await self._send_api_request(url, params) projects = response.get("lists") - yield [{**project, TEAM_ID: team_id} for project in projects] + yield [ + {**project, TEAM_ID: team.get("id")} for project in projects + ] async def get_single_project(self, list_id: str) -> dict[str, Any]: """Get a single project by folder_id.""" @@ -134,9 +136,10 @@ async def create_events_webhook(self, app_host: str) -> None: """Create a webhook for ClickUp events.""" async for teams in self.get_clickup_teams(): for team in teams: - team_id = team.get("id") webhook_target_app_host = f"{app_host}/integration/webhook" - clickup_get_webhook_url = f"{self.api_url}/team/{team_id}/webhook" + clickup_get_webhook_url = ( + f"{self.api_url}/team/{team.get('id')}/webhook" + ) webhook_check_response = await self._send_api_request( clickup_get_webhook_url ) diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 5883bcbdc3..fda0c36664 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -68,14 +68,24 @@ async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: clickup_client = await init_client() logger.info(f'Received webhook event of type: {data.get("event")}') - if "listCreated" == data.get("event"): + if data.get("event").startswith("list"): logger.info(f'Received webhook event for project: {data["list_id"]}') project = await clickup_client.get_single_project(data["list_id"]) - await ocean.register_raw(ObjectKind.PROJECT, [project]) - elif "taskCreated" == data.get("event"): - logger.info(f'Received webhook event for issue: {data["task_id"]}') - issue = await clickup_client.get_single_issue(data["task_id"]) - await ocean.register_raw(ObjectKind.ISSUE, [issue]) + if data.get("event") == "listCreated": + await ocean.register_raw(ObjectKind.PROJECT, [project]) + elif data.get("event") == "listDeleted": + await ocean.unregister_raw(ObjectKind.PROJECT, [project]) + elif data.get("event") == "listUpdated": + await ocean.update_raw_diff(ObjectKind.PROJECT, project) + elif data.get("event").startswith("task"): + logger.info(f'Received webhook event for project: {data["list_id"]}') + project = await clickup_client.get_single_project(data["list_id"]) + if data.get("event") == "taskCreated": + await ocean.register_raw(ObjectKind.PROJECT, [project]) + elif data.get("event") == "taskDeleted": + await ocean.unregister_raw(ObjectKind.PROJECT, [project]) + elif data.get("event") == "taskUpdated": + await ocean.update_raw_diff(ObjectKind.PROJECT, project) logger.info("Webhook event processed") return {"ok": True} From 22a4d5ce60b8afed96b7fadda908732fcc36d0b7 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Fri, 5 Jul 2024 21:15:04 +0100 Subject: [PATCH 039/177] Update main.py Updated webhook handling --- integrations/clickup/main.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index fda0c36664..acbb7c4b4a 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -71,21 +71,17 @@ async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: if data.get("event").startswith("list"): logger.info(f'Received webhook event for project: {data["list_id"]}') project = await clickup_client.get_single_project(data["list_id"]) - if data.get("event") == "listCreated": + if data.get("event") in ["listCreated", "listUpdated"]: await ocean.register_raw(ObjectKind.PROJECT, [project]) elif data.get("event") == "listDeleted": await ocean.unregister_raw(ObjectKind.PROJECT, [project]) - elif data.get("event") == "listUpdated": - await ocean.update_raw_diff(ObjectKind.PROJECT, project) elif data.get("event").startswith("task"): logger.info(f'Received webhook event for project: {data["list_id"]}') project = await clickup_client.get_single_project(data["list_id"]) - if data.get("event") == "taskCreated": + if data.get("event") in ["taskCreated", "taskUpdated"]: await ocean.register_raw(ObjectKind.PROJECT, [project]) elif data.get("event") == "taskDeleted": await ocean.unregister_raw(ObjectKind.PROJECT, [project]) - elif data.get("event") == "taskUpdated": - await ocean.update_raw_diff(ObjectKind.PROJECT, project) logger.info("Webhook event processed") return {"ok": True} From bad4f9761e598ca25da32db320066b90ceda50be Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Sat, 6 Jul 2024 21:46:15 +0100 Subject: [PATCH 040/177] Lint fix --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- integrations/clickup/.port/spec.yaml | 2 +- integrations/clickup/main.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 47070e8867..20d2e36acf 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -48,4 +48,4 @@ resources: created: if .date_created!=null then .date_created | tonumber / 1000 | todate else "" | todate end updated: if .date_updated!=null then .date_updated | tonumber / 1000 | todate else "" | todate end relations: - project: .list.id \ No newline at end of file + project: .list.id diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index fcced72c6f..fb09813e08 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -22,4 +22,4 @@ configurations: - name: appHost required: false type: url - description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Clickup" \ No newline at end of file + description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Clickup" diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 9441a99731..ded66afff9 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -1,9 +1,9 @@ from enum import StrEnum from typing import Any -from clickup.client import ClickupClient from loguru import logger from port_ocean.context.ocean import ocean from port_ocean.core.ocean_types import ASYNC_GENERATOR_RESYNC_TYPE +from clickup.client import ClickupClient class ObjectKind(StrEnum): From 593a1d689a446f2bb5aa2069f5778c340c63d86a Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Sat, 6 Jul 2024 22:08:51 +0100 Subject: [PATCH 041/177] Update blueprints.json --- integrations/clickup/.port/resources/blueprints.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json index d5912db8d1..b2e3030ac8 100644 --- a/integrations/clickup/.port/resources/blueprints.json +++ b/integrations/clickup/.port/resources/blueprints.json @@ -139,4 +139,4 @@ } } } -] \ No newline at end of file +] From 263c60eb235a13ec17ad47bc8d63f52c1a029b1e Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Sat, 6 Jul 2024 22:20:05 +0100 Subject: [PATCH 042/177] Lint Fix --- integrations/clickup/.gitignore | 2 +- integrations/clickup/Dockerfile | 2 +- integrations/clickup/Makefile | 2 +- integrations/clickup/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/integrations/clickup/.gitignore b/integrations/clickup/.gitignore index d550eaaeaf..06109db226 100644 --- a/integrations/clickup/.gitignore +++ b/integrations/clickup/.gitignore @@ -150,4 +150,4 @@ dmypy.json .pytype/ # Cython debug symbols -cython_debug/ \ No newline at end of file +cython_debug/ diff --git a/integrations/clickup/Dockerfile b/integrations/clickup/Dockerfile index 86ddcc540f..2c46a6fd0e 100644 --- a/integrations/clickup/Dockerfile +++ b/integrations/clickup/Dockerfile @@ -12,4 +12,4 @@ COPY . /app RUN export POETRY_VIRTUALENVS_CREATE=false && make install/prod && pip cache purge -ENTRYPOINT ocean sail \ No newline at end of file +ENTRYPOINT ocean sail diff --git a/integrations/clickup/Makefile b/integrations/clickup/Makefile index 9808e60140..b50d6a576e 100644 --- a/integrations/clickup/Makefile +++ b/integrations/clickup/Makefile @@ -71,4 +71,4 @@ clean: rm -rf htmlcov rm -rf .tox/ rm -rf docs/_build - rm -rf dist/ \ No newline at end of file + rm -rf dist/ diff --git a/integrations/clickup/README.md b/integrations/clickup/README.md index 438f4bac73..2229666cfe 100644 --- a/integrations/clickup/README.md +++ b/integrations/clickup/README.md @@ -4,4 +4,4 @@ An integration used to import ClickUp resources into Port. #### Install & use the integration - [Integration documentation](https://docs.getport.io/build-your-software-catalog/sync-data-to-catalog/) *Replace this link with a link to this integration's documentation* -#### Develop & improve the integration - [Ocean integration development documentation](https://ocean.getport.io/develop-an-integration/) \ No newline at end of file +#### Develop & improve the integration - [Ocean integration development documentation](https://ocean.getport.io/develop-an-integration/) From ae5e7f7f204006332a201d7919414037889ff962 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Sat, 6 Jul 2024 23:26:33 +0100 Subject: [PATCH 043/177] Delete Dockerfile --- integrations/clickup/Dockerfile | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 integrations/clickup/Dockerfile diff --git a/integrations/clickup/Dockerfile b/integrations/clickup/Dockerfile deleted file mode 100644 index 2c46a6fd0e..0000000000 --- a/integrations/clickup/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM python:3.11-slim-bookworm - -ENV LIBRDKAFKA_VERSION 1.9.2 - -WORKDIR /app - -RUN apt update && \ - apt install -y wget make g++ libssl-dev autoconf automake libtool curl librdkafka-dev && \ - apt-get clean - -COPY . /app - -RUN export POETRY_VIRTUALENVS_CREATE=false && make install/prod && pip cache purge - -ENTRYPOINT ocean sail From c1eb2e9de10edefe1913ff6775fdfad31c6baf25 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Sun, 14 Jul 2024 23:14:42 +0100 Subject: [PATCH 044/177] Performed Requested Changes --- .../.port/resources/port-app-config.yaml | 2 +- integrations/clickup/.port/spec.yaml | 5 ++ integrations/clickup/clickup/client.py | 50 ++++++++++--------- integrations/clickup/main.py | 41 +++++++++------ 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 20d2e36acf..859a28fae3 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -28,7 +28,7 @@ resources: endDate: if .due_date!=null then .due_date | tonumber / 1000 | todate else "" | todate end totalIssues: .task_count relations: - team: .__team_id + team: .__team.id - kind: issue selector: query: 'true' diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index fb09813e08..f25c4e37c3 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -19,6 +19,11 @@ configurations: type: url required: true default: "https://api.clickup.com" + - name: clickupArchivedParameter + description: "This is to filter archived projects. If set to true, archived projects will be included in the export. If set to false, archived projects will be excluded from the export. Default is false." + type: boolean + required: false + default: false - name: appHost required: false type: url diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index c8ed011b50..d905ba463e 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -4,7 +4,7 @@ from port_ocean.utils import http_async_client from port_ocean.utils.cache import cache_iterator_result -TEAM_ID = "__team_id" +TEAM_OBJ = "__team" WEBHOOK_EVENTS = [ "taskCreated", "taskUpdated", @@ -18,12 +18,13 @@ class ClickupClient: """Clickup client to interact with Clickup API.""" - def __init__(self, clickup_url: str, clickup_token: str): + def __init__(self, clickup_url: str, clickup_token: str, archived: bool): self.clickup_url = clickup_url self.clickup_token = clickup_token self.api_url = f"{self.clickup_url}/api/v2" self.client = http_async_client self.client.timeout = Timeout(30) + self.archived = archived @property def api_headers(self) -> dict[str, Any]: @@ -63,9 +64,11 @@ async def _get_spaces_in_team( ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all spaces in a workspace.""" url = f"{self.api_url}/team/{team_id}/space" - params = {"archived": "false"} - yield (await self._send_api_request(url, params)).get("spaces", []) + yield (await self._send_api_request(url, {"archived": self.archived})).get( + "spaces", [] + ) + @cache_iterator_result() async def _get_folders_in_space( self, team_id: str ) -> AsyncGenerator[List[dict[str, Any]], None]: @@ -73,8 +76,9 @@ async def _get_folders_in_space( async for spaces in self._get_spaces_in_team(team_id): for space in spaces: url = f"{self.api_url}/space/{space.get('id')}/folder" - params = {"archived": "false"} - yield (await self._send_api_request(url, params)).get("folders") + yield ( + await self._send_api_request(url, {"archived": self.archived}) + ).get("folders") async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects with a folder parent.""" @@ -82,13 +86,8 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None for team in teams: async for folders in self._get_folders_in_space(team.get("id")): for folder in folders: - url = f"{self.api_url}/folder/{folder.get('id')}/list" - params = {"archived": "false"} - response = await self._send_api_request(url, params) - projects = response.get("lists") - yield [ - {**project, TEAM_ID: team.get("id")} for project in projects - ] + projects = folder.get("lists") + yield [{**project, TEAM_OBJ: team} for project in projects] async def get_folderless_projects( self, @@ -99,18 +98,24 @@ async def get_folderless_projects( async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: url = f"{self.api_url}/space/{space.get('id')}/list" - params = {"archived": "false"} - response = await self._send_api_request(url, params) + response = await self._send_api_request( + url, {"archived": self.archived} + ) projects = response.get("lists") - yield [ - {**project, TEAM_ID: team.get("id")} for project in projects - ] + yield [{**project, TEAM_OBJ: team} for project in projects] - async def get_single_project(self, list_id: str) -> dict[str, Any]: - """Get a single project by folder_id.""" + async def get_single_project(self, list_id: str) -> Optional[dict[str, Any]]: + """Get a single project by list_id.""" url = f"{self.api_url}/list/{list_id}" response = await self._send_api_request(url) - return response + space_id = response.get("space").get("id") + async for teams in self.get_clickup_teams(): + for team in teams: + async for spaces in self._get_spaces_in_team(team.get("id")): + for space in spaces: + if space.get("id") == space_id: + response[TEAM_OBJ] = team + return response async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" @@ -119,8 +124,7 @@ async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], Non url = f"{self.api_url}/team/{team.get('id')}/task" page = 0 while True: - params = {"page": page} - response = await self._send_api_request(url, params) + response = await self._send_api_request(url, {"page": page}) yield response.get("tasks") if response.get("last_page"): break diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index fa5d0ae420..ec98dbc700 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -6,6 +6,16 @@ from clickup.client import ClickupClient +EVENT_ACTIONS = { + "listCreated": "register", + "listUpdated": "register", + "listDeleted": "unregister", + "taskCreated": "register", + "taskUpdated": "register", + "taskDeleted": "unregister", +} + + class ObjectKind(StrEnum): TEAM = "team" PROJECT = "project" @@ -16,6 +26,7 @@ async def init_client() -> ClickupClient: client = ClickupClient( ocean.integration_config["clickup_base_url"], ocean.integration_config["clickup_personal_token"], + ocean.integration_config["clickup_archived_parameter"], ) return client @@ -35,9 +46,9 @@ async def setup_application() -> None: @ocean.on_resync(ObjectKind.TEAM) async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() - async for team in clickup_client.get_clickup_teams(): - logger.info(f"Received team of length {len(team)}") - yield team + async for teams in clickup_client.get_clickup_teams(): + logger.info(f"Received team of length {len(teams)}") + yield teams @ocean.on_resync(ObjectKind.PROJECT) @@ -66,22 +77,24 @@ async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: @ocean.router.post("/webhook") async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: + """ + Handle the webhook request from ClickUp. + Events are mapped to the appropriate actions in EVENT_ACTIONS. + """ clickup_client = await init_client() logger.info(f'Received webhook event of type: {data.get("event")}') if data.get("event").startswith("list"): - logger.info(f'Received webhook event for project: {data["list_id"]}') - project = await clickup_client.get_single_project(data["list_id"]) - if data.get("event") in ["listCreated", "listUpdated"]: + if EVENT_ACTIONS.get(data.get("event")) == "register": + project = await clickup_client.get_single_project(data["list_id"]) await ocean.register_raw(ObjectKind.PROJECT, [project]) - elif data.get("event") == "listDeleted": - await ocean.unregister_raw(ObjectKind.PROJECT, [project]) + else: + await ocean.unregister_raw(ObjectKind.PROJECT, [{"id": data["list_id"]}]) elif data.get("event").startswith("task"): - logger.info(f'Received webhook event for project: {data["list_id"]}') - project = await clickup_client.get_single_project(data["list_id"]) - if data.get("event") in ["taskCreated", "taskUpdated"]: - await ocean.register_raw(ObjectKind.PROJECT, [project]) - elif data.get("event") == "taskDeleted": - await ocean.unregister_raw(ObjectKind.PROJECT, [project]) + if EVENT_ACTIONS.get(data.get("event")) == "register": + single_issue = await clickup_client.get_single_project(data["task_id"]) + await ocean.register_raw(ObjectKind.ISSUE, [single_issue]) + else: + await ocean.unregister_raw(ObjectKind.ISSUE, [{"id": data["task_id"]}]) logger.info("Webhook event processed") return {"ok": True} From f70e8bcd6a6b79f71a5b9e69d94c7ba24365156e Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Sun, 14 Jul 2024 23:52:41 +0100 Subject: [PATCH 045/177] Fix Changelog --- integrations/clickup/CHANGELOG.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/integrations/clickup/CHANGELOG.md b/integrations/clickup/CHANGELOG.md index b28e5d4e3a..4a66e33715 100644 --- a/integrations/clickup/CHANGELOG.md +++ b/integrations/clickup/CHANGELOG.md @@ -1,14 +1,10 @@ -# Changelog +# Port_Ocean 0.1.0 (2024-07-14) -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +### Features - +- New Integration Module to export data from Clickup. Exports teams, projects and issues (0.1.0) -# Port_Ocean 0.0.1 (2024-07-04) -### Features +# Port_Ocean 0.9.1 (2024-07-14) -- New Integration for Clickup (0.0.1) +No significant changes. From 15603f699b4ae0b5635da2480bc502b5d591e5cb Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Mon, 15 Jul 2024 00:15:19 +0100 Subject: [PATCH 046/177] Update port-app-config.yaml --- integrations/clickup/.port/resources/port-app-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 859a28fae3..4a5859d818 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -23,7 +23,7 @@ resources: identifier: .id title: .name properties: - url: "\"https://app.clickup.com/\" + .__team_id + \"/v/b/li/\" + .id " + url: "\"https://app.clickup.com/\" + .__team.id + \"/v/b/li/\" + .id " startDate: if .start_date!=null then .start_date | tonumber / 1000 | todate else "" | todate end endDate: if .due_date!=null then .due_date | tonumber / 1000 | todate else "" | todate end totalIssues: .task_count From ffea6ef82d066c84500df93b324c8803292497df Mon Sep 17 00:00:00 2001 From: Jaden Miles <154226440+jadenmyles@users.noreply.github.com> Date: Sat, 20 Jul 2024 23:13:25 +0000 Subject: [PATCH 047/177] changed create webhook event logic --- integrations/clickup/clickup/client.py | 63 +++++++++++++++----------- integrations/clickup/main.py | 2 +- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index d905ba463e..13bbaba47e 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -136,33 +136,42 @@ async def get_single_issue(self, task_id: str) -> dict[str, Any]: issue_response = await self._send_api_request(url) return issue_response - async def create_events_webhook(self, app_host: str) -> None: - """Create a webhook for ClickUp events.""" + async def create_clickup_webhook(self, team_id: str, app_host: str) -> None: + """ + Create a new webhook for a given team. + """ + await self._send_api_request( + f"{self.api_url}/team/{team_id}/webhook", + method="POST", + json_data={ + "endpoint": f"{app_host}/integration/webhook", + "events": WEBHOOK_EVENTS, + }, + ) + logger.info("Webhook created successfully") + + async def get_clickup_webhooks(self, team_id: str) -> list[dict[str, Any]]: + """ + Retrieve existing webhooks for a given team. + """ + return (await self._send_api_request(f"{self.api_url}/team/{team_id}/webhook"))["webhooks"] + + async def create_clickup_events_webhook(self, app_host: str) -> None: + async for teams in self.get_clickup_teams(): for team in teams: - webhook_target_app_host = f"{app_host}/integration/webhook" - clickup_get_webhook_url = ( - f"{self.api_url}/team/{team.get('id')}/webhook" - ) - webhook_check_response = await self._send_api_request( - clickup_get_webhook_url - ) - webhook_check = webhook_check_response.get("webhooks") - for webhook in webhook_check: - if webhook["endpoint"] == webhook_target_app_host: - logger.info( - "Ocean real-time reporting webhook already exists on ClickUp" - ) - return - - body = { - "endpoint": webhook_target_app_host, - "events": WEBHOOK_EVENTS, - } - logger.info("Subscribing to ClickUp webhooks...") - webhook_create_response = await self._send_api_request( - clickup_get_webhook_url, json_data=body, method="POST" - ) - logger.info( - f"Ocean real-time reporting webhook created on ClickUp - {webhook_create_response}" + team_id = team["id"] + + webhook_target_url = f"{app_host}/integration/webhook" + + webhooks = await self.get_clickup_webhooks(team_id) + + webhook_exits = any( + config["endpoint"] == webhook_target_url for config in webhooks ) + + if webhook_exits: + logger.info(f"Webhook already exists for team {team_id}") + else: + logger.info(f"Creating webhook for team {team_id}") + await self.create_clickup_webhook(team_id, app_host) diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index ec98dbc700..1a23c0e6c4 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -40,7 +40,7 @@ async def setup_application() -> None: ) return clickup_client = await init_client() # Await the initialization of the client - await clickup_client.create_events_webhook(app_host) + await clickup_client.create_clickup_events_webhook(app_host) @ocean.on_resync(ObjectKind.TEAM) From 6ce2bcae0de00aef7b41925a53aee6635ed12f3e Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Sun, 21 Jul 2024 01:16:54 +0100 Subject: [PATCH 048/177] Supported Rate limiting - Rate limiting - Improved event handler --- integrations/clickup/clickup/client.py | 71 ++++++++++++++++++++------ integrations/clickup/main.py | 31 ++++++----- 2 files changed, 74 insertions(+), 28 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 13bbaba47e..ce3ee17963 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -1,9 +1,12 @@ +import asyncio +import time from typing import Any, AsyncGenerator, Optional, List -from httpx import Timeout +from httpx import Timeout, HTTPStatusError from loguru import logger from port_ocean.utils import http_async_client from port_ocean.utils.cache import cache_iterator_result + TEAM_OBJ = "__team" WEBHOOK_EVENTS = [ "taskCreated", @@ -13,6 +16,8 @@ "listUpdated", "listDeleted", ] +MINIMUM_LIMIT_REMAINING = 90 +DEFAULT_SLEEP_TIME = 60 class ClickupClient: @@ -33,6 +38,51 @@ def api_headers(self) -> dict[str, Any]: "Content-Type": "application/json", } + async def _fetch_with_rate_limit_handling( + self, + url: str, + method: str, + params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, + ) -> Any: + """Rate limit handler.""" + while True: + response = await self.client.request( + url=url, + method=method, + headers=self.api_headers, + params=params, + json=json_data, + ) + try: + response.raise_for_status() + rate_limit_remaining = int( + response.headers.get("X-RateLimit-Remaining", 1) + ) + if rate_limit_remaining <= MINIMUM_LIMIT_REMAINING: + current_time = int(time.time()) + rate_limit_reset = int( + response.headers.get( + "X-RateLimit-Reset", current_time + DEFAULT_SLEEP_TIME + ) + ) + wait_time = max(rate_limit_reset - current_time, DEFAULT_SLEEP_TIME) + logger.debug( + f"Approaching rate limit. Waiting for {wait_time} seconds before retrying. " + f"URL: {url}, Remaining: {rate_limit_remaining} " + ) + await asyncio.sleep(wait_time) + except KeyError as e: + logger.warning( + f"Rate limit headers not found in response: {str(e)} for url {url}" + ) + except HTTPStatusError as e: + logger.error( + f"Got HTTP error to url: {url} with status code: {e.response.status_code} and response text: {e.response.text}" + ) + raise + return response + async def _send_api_request( self, url: str, @@ -40,16 +90,10 @@ async def _send_api_request( json_data: Optional[dict[str, Any]] = None, method: str = "GET", ) -> Any: - """Send a request to the Clickup API.""" - logger.debug(f"Sending request {method} to endpoint {url}") - response = await self.client.request( - url=url, - method=method, - headers=self.api_headers, - params=params, - json=json_data, + """Send a request to the Clickup API with rate limiting.""" + response = await self._fetch_with_rate_limit_handling( + url, method, params, json_data ) - response.raise_for_status() return response.json() @cache_iterator_result() @@ -114,8 +158,7 @@ async def get_single_project(self, list_id: str) -> Optional[dict[str, Any]]: async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: if space.get("id") == space_id: - response[TEAM_OBJ] = team - return response + return {**response, TEAM_OBJ: team} async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" @@ -132,9 +175,7 @@ async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], Non async def get_single_issue(self, task_id: str) -> dict[str, Any]: """Get a single issue by task_id.""" - url = f"{self.api_url}/task/{task_id}" - issue_response = await self._send_api_request(url) - return issue_response + return await self._send_api_request(f"{self.api_url}/task/{task_id}") async def create_clickup_webhook(self, team_id: str, app_host: str) -> None: """ diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 1a23c0e6c4..bf06b7514d 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -82,19 +82,24 @@ async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: Events are mapped to the appropriate actions in EVENT_ACTIONS. """ clickup_client = await init_client() - logger.info(f'Received webhook event of type: {data.get("event")}') - if data.get("event").startswith("list"): - if EVENT_ACTIONS.get(data.get("event")) == "register": - project = await clickup_client.get_single_project(data["list_id"]) - await ocean.register_raw(ObjectKind.PROJECT, [project]) - else: - await ocean.unregister_raw(ObjectKind.PROJECT, [{"id": data["list_id"]}]) - elif data.get("event").startswith("task"): - if EVENT_ACTIONS.get(data.get("event")) == "register": - single_issue = await clickup_client.get_single_project(data["task_id"]) - await ocean.register_raw(ObjectKind.ISSUE, [single_issue]) - else: - await ocean.unregister_raw(ObjectKind.ISSUE, [{"id": data["task_id"]}]) + logger.info(f"Received webhook event of type: {data.get('event')}") + event_handlers = { + "task": (ObjectKind.ISSUE, clickup_client.get_single_issue), + "list": (ObjectKind.PROJECT, clickup_client.get_single_project), + } + event_type = data["event"] + action = "unregister" if "Deleted" in event_type else "register" + for key, (kind, handler) in event_handlers.items(): + if key in event_type: + entity_id = data.get(f"{key}_id") + if action == "register": + entity = await handler(entity_id) + await ocean.register_raw(kind, [entity]) + logger.info(f"Registered {kind.value} for event {event_type}") + else: + await ocean.unregister_raw(kind, [{"id": entity_id}]) + logger.info(f"Unregistered {kind.value} for event {event_type}") + break logger.info("Webhook event processed") return {"ok": True} From adfe6a40a1b84c9be52fd20126fa5fef25a2774b Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Sun, 21 Jul 2024 14:24:27 +0100 Subject: [PATCH 049/177] Updated Rate limiting handling --- integrations/clickup/clickup/client.py | 149 +++++++++++++++---------- integrations/clickup/main.py | 9 +- 2 files changed, 95 insertions(+), 63 deletions(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index ce3ee17963..934e18bb4d 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -1,12 +1,11 @@ import asyncio import time from typing import Any, AsyncGenerator, Optional, List -from httpx import Timeout, HTTPStatusError +from httpx import HTTPStatusError, Timeout from loguru import logger from port_ocean.utils import http_async_client from port_ocean.utils.cache import cache_iterator_result - TEAM_OBJ = "__team" WEBHOOK_EVENTS = [ "taskCreated", @@ -16,8 +15,11 @@ "listUpdated", "listDeleted", ] -MINIMUM_LIMIT_REMAINING = 90 -DEFAULT_SLEEP_TIME = 60 +MINIMUM_LIMIT_REMAINING = 20 +DEFAULT_SLEEP_TIME = 30 + +# Adjust the concurrency level as needed +SEMAPHORE = asyncio.Semaphore(10) class ClickupClient: @@ -28,7 +30,7 @@ def __init__(self, clickup_url: str, clickup_token: str, archived: bool): self.clickup_token = clickup_token self.api_url = f"{self.clickup_url}/api/v2" self.client = http_async_client - self.client.timeout = Timeout(30) + self.client.timeout = Timeout(60) self.archived = archived @property @@ -39,56 +41,86 @@ def api_headers(self) -> dict[str, Any]: } async def _fetch_with_rate_limit_handling( - self, - url: str, - method: str, - params: Optional[dict[str, Any]] = None, - json_data: Optional[dict[str, Any]] = None, + self, + url: str, + method: str, + params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, ) -> Any: - """Rate limit handler.""" + """ + Sends an HTTP request to the ClickUp API with rate limit handling. + + This method ensures that requests to the ClickUp API do not exceed the + rate limits imposed by the API. If the rate limit is approached or exceeded, + the method will wait until the rate limit is reset before retrying the request. + + Parameters: + ----------- + url : str + The endpoint URL for the ClickUp API request. + method : str + The HTTP method to use for the request (e.g., 'GET', 'POST'). + params : Optional[dict[str, Any]], optional + Query parameters to include in the request, by default None. + json_data : Optional[dict[str, Any]], optional + JSON data to include in the body of the request, by default None. + + Returns: + -------- + Any + The JSON response from the ClickUp API. + + Raises: + ------- + httpx.HTTPStatusError + If the HTTP request returns an error status code. + + Notes: + ------ + - The method uses an asyncio semaphore to limit the number of concurrent + requests to the ClickUp API. + - The method logs detailed information about rate limits and waits if the + rate limit is approached. + """ while True: - response = await self.client.request( - url=url, - method=method, - headers=self.api_headers, - params=params, - json=json_data, - ) - try: - response.raise_for_status() - rate_limit_remaining = int( - response.headers.get("X-RateLimit-Remaining", 1) + async with SEMAPHORE: + response = await self.client.request( + url=url, + method=method, + headers=self.api_headers, + params=params, + json=json_data, ) - if rate_limit_remaining <= MINIMUM_LIMIT_REMAINING: - current_time = int(time.time()) - rate_limit_reset = int( - response.headers.get( - "X-RateLimit-Reset", current_time + DEFAULT_SLEEP_TIME + try: + response.raise_for_status() + rate_limit_remaining = int(response.headers.get("X-RateLimit-Remaining", 1)) + rate_limit_reset = int(response.headers.get("X-RateLimit-Reset")) + if rate_limit_remaining <= MINIMUM_LIMIT_REMAINING: + current_time = int(time.time()) + wait_time = max(rate_limit_reset - current_time, DEFAULT_SLEEP_TIME) + logger.info( + f"Approaching rate limit. Waiting for {wait_time} seconds to continue export. " + f"URL: {url}, Remaining: {rate_limit_remaining} " ) + await asyncio.sleep(wait_time) + logger.debug(f"{rate_limit_reset} - {rate_limit_remaining}") + except KeyError as e: + logger.error( + f"Rate limit headers not found in response: {str(e)} for url {url}" ) - wait_time = max(rate_limit_reset - current_time, DEFAULT_SLEEP_TIME) - logger.debug( - f"Approaching rate limit. Waiting for {wait_time} seconds before retrying. " - f"URL: {url}, Remaining: {rate_limit_remaining} " + except HTTPStatusError as e: + logger.error( + f"Got HTTP error to url: {url} with status code: {e.response.status_code} and response text: {e.response.text}" ) - await asyncio.sleep(wait_time) - except KeyError as e: - logger.warning( - f"Rate limit headers not found in response: {str(e)} for url {url}" - ) - except HTTPStatusError as e: - logger.error( - f"Got HTTP error to url: {url} with status code: {e.response.status_code} and response text: {e.response.text}" - ) - raise + raise return response async def _send_api_request( - self, - url: str, - params: Optional[dict[str, Any]] = None, - json_data: Optional[dict[str, Any]] = None, - method: str = "GET", + self, + url: str, + params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, + method: str = "GET", ) -> Any: """Send a request to the Clickup API with rate limiting.""" response = await self._fetch_with_rate_limit_handling( @@ -99,30 +131,26 @@ async def _send_api_request( @cache_iterator_result() async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all Clickup teams.""" - url = f"{self.api_url}/team" - yield (await self._send_api_request(url)).get("teams", []) + yield (await self._send_api_request(f"{self.api_url}/team")).get("teams", []) @cache_iterator_result() async def _get_spaces_in_team( - self, team_id: str + self, team_id: str ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all spaces in a workspace.""" - url = f"{self.api_url}/team/{team_id}/space" - yield (await self._send_api_request(url, {"archived": self.archived})).get( - "spaces", [] - ) + yield (await self._send_api_request(f"{self.api_url}/team/{team_id}/space", + {"archived": self.archived})).get("spaces", []) @cache_iterator_result() async def _get_folders_in_space( - self, team_id: str + self, team_id: str ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all folders in a space.""" async for spaces in self._get_spaces_in_team(team_id): for space in spaces: - url = f"{self.api_url}/space/{space.get('id')}/folder" yield ( - await self._send_api_request(url, {"archived": self.archived}) - ).get("folders") + await self._send_api_request(f"{self.api_url}/space/{space.get('id')}/folder", + {"archived": self.archived})).get("folders") async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects with a folder parent.""" @@ -134,16 +162,15 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None yield [{**project, TEAM_OBJ: team} for project in projects] async def get_folderless_projects( - self, + self, ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects without a folder parent.""" async for teams in self.get_clickup_teams(): for team in teams: async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: - url = f"{self.api_url}/space/{space.get('id')}/list" response = await self._send_api_request( - url, {"archived": self.archived} + f"{self.api_url}/space/{space.get('id')}/list", {"archived": self.archived} ) projects = response.get("lists") yield [{**project, TEAM_OBJ: team} for project in projects] @@ -153,10 +180,12 @@ async def get_single_project(self, list_id: str) -> Optional[dict[str, Any]]: url = f"{self.api_url}/list/{list_id}" response = await self._send_api_request(url) space_id = response.get("space").get("id") + logger.info(space_id) async for teams in self.get_clickup_teams(): for team in teams: async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: + logger.info(space.get("id")) if space.get("id") == space_id: return {**response, TEAM_OBJ: team} diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index bf06b7514d..e8ce84c38f 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -95,10 +95,13 @@ async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: if action == "register": entity = await handler(entity_id) await ocean.register_raw(kind, [entity]) - logger.info(f"Registered {kind.value} for event {event_type}") + logger.info(f"Registered {kind} for event {event_type}") else: - await ocean.unregister_raw(kind, [{"id": entity_id}]) - logger.info(f"Unregistered {kind.value} for event {event_type}") + try: + await ocean.unregister_raw(kind, [{"id": entity_id}]) + logger.info(f"Unregistered {kind} for event {event_type}") + except Exception as e: + logger.error(f"Exception {e} occurred while attempting to unregister raw") break logger.info("Webhook event processed") return {"ok": True} From 0ccf204ffe4efdba34a27d7f9641af82e24181bc Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Sun, 21 Jul 2024 14:30:38 +0100 Subject: [PATCH 050/177] Updated docstring --- integrations/clickup/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index e8ce84c38f..5db9785d1e 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -79,7 +79,7 @@ async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: """ Handle the webhook request from ClickUp. - Events are mapped to the appropriate actions in EVENT_ACTIONS. + Events are mapped to the appropriate actions in event_handlers. """ clickup_client = await init_client() logger.info(f"Received webhook event of type: {data.get('event')}") From ef1f18b2dd2bb161e789dc7b8d3999c42edf811e Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Sun, 21 Jul 2024 16:52:52 +0100 Subject: [PATCH 051/177] Updated bounded rate liimit logic --- integrations/clickup/clickup/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/clickup/client.py index 934e18bb4d..b98b65a65e 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/clickup/client.py @@ -19,7 +19,7 @@ DEFAULT_SLEEP_TIME = 30 # Adjust the concurrency level as needed -SEMAPHORE = asyncio.Semaphore(10) +SEMAPHORE = asyncio.BoundedSemaphore(10) class ClickupClient: From f1d0561b35aec36ee79a5e9fd6c1233a124d3411 Mon Sep 17 00:00:00 2001 From: Jaden Miles <154226440+jadenmyles@users.noreply.github.com> Date: Mon, 22 Jul 2024 02:17:15 +0000 Subject: [PATCH 052/177] - formatted blueprint to use spaces instead of tab to pass linting - modified handling webhook request to take care of type miss-match errors --- .../clickup/.port/resources/blueprints.json | 258 +++++++++--------- integrations/clickup/{clickup => }/client.py | 97 +++---- integrations/clickup/main.py | 54 +++- 3 files changed, 208 insertions(+), 201 deletions(-) rename integrations/clickup/{clickup => }/client.py (76%) diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json index b2e3030ac8..338473ce9b 100644 --- a/integrations/clickup/.port/resources/blueprints.json +++ b/integrations/clickup/.port/resources/blueprints.json @@ -1,142 +1,142 @@ [ - { - "identifier": "clickupTeam", - "description": "This blueprint represents a Clickup team", - "title": "Clickup Team", - "icon": "Clickup", - "schema": { - "properties": { - "url": { - "type": "string", - "title": "URL", - "format": "url" - }, - "members": { - "type": "array", - "title": "Members", - "items": { + { + "identifier": "clickupTeam", + "description": "This blueprint represents a Clickup team", + "title": "Clickup Team", + "icon": "Clickup", + "schema": { + "properties": { + "url": { "type": "string", - "format": "user" + "title": "URL", + "format": "url" + }, + "members": { + "type": "array", + "title": "Members", + "items": { + "type": "string", + "format": "user" + } } - } + }, + "required": [] }, - "required": [] + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": {} }, - "mirrorProperties": {}, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": {} -}, -{ - "identifier": "clickupProject", - "description": "This blueprint represents a ClickUp project", - "title": "ClickUp Project", - "icon": "Clickup", - "schema": { - "properties": { - "url": { - "title": "Project URL", - "type": "string", - "format": "url", - "description": "URL to the project in Clickup" - }, - "startDate": { - "title": "Project start date", - "type": "string", - "format": "date-time", - "description": "The start date of this project" - }, - "endDate": { - "title": "Project end date", - "type": "string", - "format": "date-time", - "description": "The end date of this project" + { + "identifier": "clickupProject", + "description": "This blueprint represents a ClickUp project", + "title": "ClickUp Project", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "title": "Project URL", + "type": "string", + "format": "url", + "description": "URL to the project in Clickup" + }, + "startDate": { + "title": "Project start date", + "type": "string", + "format": "date-time", + "description": "The start date of this project" + }, + "endDate": { + "title": "Project end date", + "type": "string", + "format": "date-time", + "description": "The end date of this project" + }, + "totalIssues": { + "title": "Total Issues", + "type": "number", + "description": "The total number of issues in the project" + } }, - "totalIssues": { - "title": "Total Issues", - "type": "number", - "description": "The total number of issues in the project" - } + "required": [] }, - "required": [] - }, - "mirrorProperties": {}, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": { - "team": { - "title": "Team", - "target": "clickupTeam", - "required": false, - "many": false + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "team": { + "title": "Team", + "target": "clickupTeam", + "required": false, + "many": false + } } - } -}, -{ - "identifier": "clickupIssue", - "title": "ClickUp Issue", - "icon": "Clickup", - "schema": { - "properties": { - "description": { - "title": "Issue Description", - "type": "string", - "description": "Detailed description of the issue" - }, - "url": { - "title": "Issue URL", - "type": "string", - "format": "url", - "description": "URL to the issue in Clickup" - }, - "status": { - "title": "Status", - "type": "string", - "description": "The status of the issue" - }, - "assignee": { - "title": "Assignee", - "type": "string", - "format": "user", - "description": "The user assigned to the issue" - }, - "creator": { - "title": "Creator", - "type": "string", - "description": "The user that created to the issue", - "format": "user" - }, - "priority": { - "title": "Priority", - "type": "string", - "description": "The priority of the issue" - }, - "created": { - "title": "Created At", - "type": "string", - "description": "The created datetime of the issue", - "format": "date-time" + }, + { + "identifier": "clickupIssue", + "title": "ClickUp Issue", + "icon": "Clickup", + "schema": { + "properties": { + "description": { + "title": "Issue Description", + "type": "string", + "description": "Detailed description of the issue" + }, + "url": { + "title": "Issue URL", + "type": "string", + "format": "url", + "description": "URL to the issue in Clickup" + }, + "status": { + "title": "Status", + "type": "string", + "description": "The status of the issue" + }, + "assignee": { + "title": "Assignee", + "type": "string", + "format": "user", + "description": "The user assigned to the issue" + }, + "creator": { + "title": "Creator", + "type": "string", + "description": "The user that created the issue", + "format": "user" + }, + "priority": { + "title": "Priority", + "type": "string", + "description": "The priority of the issue" + }, + "created": { + "title": "Created At", + "type": "string", + "description": "The created datetime of the issue", + "format": "date-time" + }, + "updated": { + "title": "Updated At", + "type": "string", + "description": "The updated datetime of the issue", + "format": "date-time" + } }, - "updated": { - "title": "Updated At", - "type": "string", - "description": "The updated datetime of the issue", - "format": "date-time" - } + "required": [] }, - "required": [] - }, - "mirrorProperties": {}, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": { - "project": { - "title": "Project", - "description": "The Clickup project that manages this issue", - "target": "clickupProject", - "required": false, - "many": false + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "project": { + "title": "Project", + "description": "The Clickup project that manages this issue", + "target": "clickupProject", + "required": false, + "many": false + } } } -} ] diff --git a/integrations/clickup/clickup/client.py b/integrations/clickup/client.py similarity index 76% rename from integrations/clickup/clickup/client.py rename to integrations/clickup/client.py index b98b65a65e..58ccc5c77c 100644 --- a/integrations/clickup/clickup/client.py +++ b/integrations/clickup/client.py @@ -1,6 +1,6 @@ import asyncio import time -from typing import Any, AsyncGenerator, Optional, List +from typing import Any, AsyncGenerator, Optional, List, Dict from httpx import HTTPStatusError, Timeout from loguru import logger from port_ocean.utils import http_async_client @@ -41,46 +41,14 @@ def api_headers(self) -> dict[str, Any]: } async def _fetch_with_rate_limit_handling( - self, - url: str, - method: str, - params: Optional[dict[str, Any]] = None, - json_data: Optional[dict[str, Any]] = None, + self, + url: str, + method: str, + params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, ) -> Any: """ Sends an HTTP request to the ClickUp API with rate limit handling. - - This method ensures that requests to the ClickUp API do not exceed the - rate limits imposed by the API. If the rate limit is approached or exceeded, - the method will wait until the rate limit is reset before retrying the request. - - Parameters: - ----------- - url : str - The endpoint URL for the ClickUp API request. - method : str - The HTTP method to use for the request (e.g., 'GET', 'POST'). - params : Optional[dict[str, Any]], optional - Query parameters to include in the request, by default None. - json_data : Optional[dict[str, Any]], optional - JSON data to include in the body of the request, by default None. - - Returns: - -------- - Any - The JSON response from the ClickUp API. - - Raises: - ------- - httpx.HTTPStatusError - If the HTTP request returns an error status code. - - Notes: - ------ - - The method uses an asyncio semaphore to limit the number of concurrent - requests to the ClickUp API. - - The method logs detailed information about rate limits and waits if the - rate limit is approached. """ while True: async with SEMAPHORE: @@ -93,11 +61,15 @@ async def _fetch_with_rate_limit_handling( ) try: response.raise_for_status() - rate_limit_remaining = int(response.headers.get("X-RateLimit-Remaining", 1)) + rate_limit_remaining = int( + response.headers.get("X-RateLimit-Remaining", 1) + ) rate_limit_reset = int(response.headers.get("X-RateLimit-Reset")) if rate_limit_remaining <= MINIMUM_LIMIT_REMAINING: current_time = int(time.time()) - wait_time = max(rate_limit_reset - current_time, DEFAULT_SLEEP_TIME) + wait_time = max( + rate_limit_reset - current_time, DEFAULT_SLEEP_TIME + ) logger.info( f"Approaching rate limit. Waiting for {wait_time} seconds to continue export. " f"URL: {url}, Remaining: {rate_limit_remaining} " @@ -116,11 +88,11 @@ async def _fetch_with_rate_limit_handling( return response async def _send_api_request( - self, - url: str, - params: Optional[dict[str, Any]] = None, - json_data: Optional[dict[str, Any]] = None, - method: str = "GET", + self, + url: str, + params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, + method: str = "GET", ) -> Any: """Send a request to the Clickup API with rate limiting.""" response = await self._fetch_with_rate_limit_handling( @@ -135,22 +107,28 @@ async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: @cache_iterator_result() async def _get_spaces_in_team( - self, team_id: str + self, team_id: str ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all spaces in a workspace.""" - yield (await self._send_api_request(f"{self.api_url}/team/{team_id}/space", - {"archived": self.archived})).get("spaces", []) + yield ( + await self._send_api_request( + f"{self.api_url}/team/{team_id}/space", {"archived": self.archived} + ) + ).get("spaces", []) @cache_iterator_result() async def _get_folders_in_space( - self, team_id: str + self, team_id: str ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all folders in a space.""" async for spaces in self._get_spaces_in_team(team_id): for space in spaces: yield ( - await self._send_api_request(f"{self.api_url}/space/{space.get('id')}/folder", - {"archived": self.archived})).get("folders") + await self._send_api_request( + f"{self.api_url}/space/{space.get('id')}/folder", + {"archived": self.archived}, + ) + ).get("folders") async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects with a folder parent.""" @@ -162,7 +140,7 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None yield [{**project, TEAM_OBJ: team} for project in projects] async def get_folderless_projects( - self, + self, ) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects without a folder parent.""" async for teams in self.get_clickup_teams(): @@ -170,17 +148,18 @@ async def get_folderless_projects( async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: response = await self._send_api_request( - f"{self.api_url}/space/{space.get('id')}/list", {"archived": self.archived} + f"{self.api_url}/space/{space.get('id')}/list", + {"archived": self.archived}, ) projects = response.get("lists") yield [{**project, TEAM_OBJ: team} for project in projects] - async def get_single_project(self, list_id: str) -> Optional[dict[str, Any]]: + async def get_single_project(self, list_id: str) -> Optional[Dict[str, Any]]: """Get a single project by list_id.""" url = f"{self.api_url}/list/{list_id}" response = await self._send_api_request(url) space_id = response.get("space").get("id") - logger.info(space_id) + async for teams in self.get_clickup_teams(): for team in teams: async for spaces in self._get_spaces_in_team(team.get("id")): @@ -189,6 +168,9 @@ async def get_single_project(self, list_id: str) -> Optional[dict[str, Any]]: if space.get("id") == space_id: return {**response, TEAM_OBJ: team} + logger.warning("No matching space found.") + return None + async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" async for teams in self.get_clickup_teams(): @@ -224,10 +206,11 @@ async def get_clickup_webhooks(self, team_id: str) -> list[dict[str, Any]]: """ Retrieve existing webhooks for a given team. """ - return (await self._send_api_request(f"{self.api_url}/team/{team_id}/webhook"))["webhooks"] + return (await self._send_api_request(f"{self.api_url}/team/{team_id}/webhook"))[ + "webhooks" + ] async def create_clickup_events_webhook(self, app_host: str) -> None: - async for teams in self.get_clickup_teams(): for team in teams: team_id = team["id"] diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 5db9785d1e..71c8fbee97 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -1,10 +1,9 @@ from enum import StrEnum -from typing import Any +from typing import Any, Dict from loguru import logger from port_ocean.context.ocean import ocean from port_ocean.core.ocean_types import ASYNC_GENERATOR_RESYNC_TYPE -from clickup.client import ClickupClient - +from client import ClickupClient EVENT_ACTIONS = { "listCreated": "register", @@ -75,34 +74,59 @@ async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: yield issues +async def _handle_register( + clickup_client: Any, entity_id: str, kind: ObjectKind, event_type: str +) -> None: + if kind == ObjectKind.ISSUE: + entity = await clickup_client.get_single_issue(entity_id) + else: + entity = await clickup_client.get_single_project(entity_id) + + if entity: + await ocean.register_raw(kind, [entity]) + logger.info(f"Registered {kind} for event {event_type}") + else: + logger.error(f"Handler returned None for entity_id {entity_id}") + + +async def _handle_unregister(entity_id: str, kind: ObjectKind, event_type: str) -> None: + try: + await ocean.unregister_raw(kind, [{"id": entity_id}]) + logger.info(f"Unregistered {kind} for event {event_type}") + except Exception as e: + logger.error(f"Exception {e} occurred while attempting to unregister raw") + + @ocean.router.post("/webhook") -async def handle_webhook_request(data: dict[str, Any]) -> dict[str, Any]: +async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: """ Handle the webhook request from ClickUp. Events are mapped to the appropriate actions in event_handlers. """ clickup_client = await init_client() logger.info(f"Received webhook event of type: {data.get('event')}") + event_handlers = { - "task": (ObjectKind.ISSUE, clickup_client.get_single_issue), - "list": (ObjectKind.PROJECT, clickup_client.get_single_project), + "task": ObjectKind.ISSUE, + "list": ObjectKind.PROJECT, } + event_type = data["event"] action = "unregister" if "Deleted" in event_type else "register" - for key, (kind, handler) in event_handlers.items(): + + for key, kind in event_handlers.items(): if key in event_type: entity_id = data.get(f"{key}_id") + if not entity_id: + logger.error(f"No {key}_id found in data for event {event_type}") + continue + if action == "register": - entity = await handler(entity_id) - await ocean.register_raw(kind, [entity]) - logger.info(f"Registered {kind} for event {event_type}") + await _handle_register(clickup_client, entity_id, kind, event_type) else: - try: - await ocean.unregister_raw(kind, [{"id": entity_id}]) - logger.info(f"Unregistered {kind} for event {event_type}") - except Exception as e: - logger.error(f"Exception {e} occurred while attempting to unregister raw") + await _handle_unregister(entity_id, kind, event_type) break + logger.info("Webhook event processed") return {"ok": True} From 1b3e9c1631b7ee11b2912aec4313a4926ff1df01 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:41:42 +0100 Subject: [PATCH 053/177] Update integrations/clickup/.port/spec.yaml Co-authored-by: PagesCoffy --- integrations/clickup/.port/spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index f25c4e37c3..2a76a5205a 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -10,7 +10,7 @@ features: - kind: team configurations: - name: clickupPersonalToken - description: "Clickup personal token for authentication. Guide here - https://clickup.com/api/developer-portal/authentication#personal-token" +The ClickUp personal token used for authentication. To create a personal token, see the ClickUp documentation required: true type: string sensitive: true From 2fc90b2316fab8b5de70a1a9f584d4d790cf686d Mon Sep 17 00:00:00 2001 From: Jaden Miles <154226440+jadenmyles@users.noreply.github.com> Date: Mon, 22 Jul 2024 11:37:48 +0000 Subject: [PATCH 054/177] -removed quotes from objects in spec.yaml - renamed TEAM_OBJ to TEAM_OBJECT --- integrations/clickup/.port/spec.yaml | 12 ++++++------ integrations/clickup/CHANGELOG.md | 4 ---- integrations/clickup/README.md | 3 +-- integrations/clickup/client.py | 8 ++++---- integrations/clickup/main.py | 2 +- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index 2a76a5205a..853edb1dc8 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -10,20 +10,20 @@ features: - kind: team configurations: - name: clickupPersonalToken -The ClickUp personal token used for authentication. To create a personal token, see the ClickUp documentation + description: The ClickUp personal token used for authentication. To create a personal token, see the ClickUp documentation required: true type: string sensitive: true - name: clickupBaseUrl - description: "Clickup Base URL." + description: The Clickup Base URL. Defaults to https://api.clickup.com when not specified type: url required: true - default: "https://api.clickup.com" - - name: clickupArchivedParameter - description: "This is to filter archived projects. If set to true, archived projects will be included in the export. If set to false, archived projects will be excluded from the export. Default is false." + default: https://api.clickup.com + - name: includeArchivedProjects + description: This is to filter archived projects. If set to true, archived projects will be included in the export. If set to false, archived projects will be excluded from the export. Default is false. type: boolean required: false - default: false + default: "false" - name: appHost required: false type: url diff --git a/integrations/clickup/CHANGELOG.md b/integrations/clickup/CHANGELOG.md index 4a66e33715..863f9b0668 100644 --- a/integrations/clickup/CHANGELOG.md +++ b/integrations/clickup/CHANGELOG.md @@ -4,7 +4,3 @@ - New Integration Module to export data from Clickup. Exports teams, projects and issues (0.1.0) - -# Port_Ocean 0.9.1 (2024-07-14) - -No significant changes. diff --git a/integrations/clickup/README.md b/integrations/clickup/README.md index 2229666cfe..03954d9bcb 100644 --- a/integrations/clickup/README.md +++ b/integrations/clickup/README.md @@ -2,6 +2,5 @@ An integration used to import ClickUp resources into Port. -#### Install & use the integration - [Integration documentation](https://docs.getport.io/build-your-software-catalog/sync-data-to-catalog/) *Replace this link with a link to this integration's documentation* - +#### Install & use the integration - [Integration documentation](https://docs.getport.io/build-your-software-catalog/sync-data-to-catalog/project-management/clickup/) #### Develop & improve the integration - [Ocean integration development documentation](https://ocean.getport.io/develop-an-integration/) diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 58ccc5c77c..9ab67b8769 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -6,7 +6,7 @@ from port_ocean.utils import http_async_client from port_ocean.utils.cache import cache_iterator_result -TEAM_OBJ = "__team" +TEAM_OBJECT = "__team" WEBHOOK_EVENTS = [ "taskCreated", "taskUpdated", @@ -137,7 +137,7 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None async for folders in self._get_folders_in_space(team.get("id")): for folder in folders: projects = folder.get("lists") - yield [{**project, TEAM_OBJ: team} for project in projects] + yield [{**project, TEAM_OBJECT: team} for project in projects] async def get_folderless_projects( self, @@ -152,7 +152,7 @@ async def get_folderless_projects( {"archived": self.archived}, ) projects = response.get("lists") - yield [{**project, TEAM_OBJ: team} for project in projects] + yield [{**project, TEAM_OBJECT: team} for project in projects] async def get_single_project(self, list_id: str) -> Optional[Dict[str, Any]]: """Get a single project by list_id.""" @@ -166,7 +166,7 @@ async def get_single_project(self, list_id: str) -> Optional[Dict[str, Any]]: for space in spaces: logger.info(space.get("id")) if space.get("id") == space_id: - return {**response, TEAM_OBJ: team} + return {**response, TEAM_OBJECT: team} logger.warning("No matching space found.") return None diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 71c8fbee97..83ae8c5cc1 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -25,7 +25,7 @@ async def init_client() -> ClickupClient: client = ClickupClient( ocean.integration_config["clickup_base_url"], ocean.integration_config["clickup_personal_token"], - ocean.integration_config["clickup_archived_parameter"], + ocean.integration_config["include_archived_projects"], ) return client From f031c50f31bcbf24e29bee6fb042c49e8fc85842 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Mon, 22 Jul 2024 14:59:29 +0100 Subject: [PATCH 055/177] Requested Changes - Removed unnecessary assignments - Added link to rate limit - Renamed archived to be reveal its type - Combined the two resync function for projects --- integrations/clickup/client.py | 17 +++++++++-------- integrations/clickup/main.py | 17 ++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 9ab67b8769..1be330a0c9 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -15,10 +15,9 @@ "listUpdated", "listDeleted", ] + MINIMUM_LIMIT_REMAINING = 20 DEFAULT_SLEEP_TIME = 30 - -# Adjust the concurrency level as needed SEMAPHORE = asyncio.BoundedSemaphore(10) @@ -26,12 +25,11 @@ class ClickupClient: """Clickup client to interact with Clickup API.""" def __init__(self, clickup_url: str, clickup_token: str, archived: bool): - self.clickup_url = clickup_url self.clickup_token = clickup_token - self.api_url = f"{self.clickup_url}/api/v2" + self.api_url = f"{clickup_url}/api/v2" self.client = http_async_client self.client.timeout = Timeout(60) - self.archived = archived + self.is_archived = archived @property def api_headers(self) -> dict[str, Any]: @@ -49,6 +47,8 @@ async def _fetch_with_rate_limit_handling( ) -> Any: """ Sends an HTTP request to the ClickUp API with rate limit handling. + The acceptable rate is described in the documentation provided by Clickup at + https://clickup.com/api/developer-portal/rate-limits/ """ while True: async with SEMAPHORE: @@ -112,7 +112,8 @@ async def _get_spaces_in_team( """Get all spaces in a workspace.""" yield ( await self._send_api_request( - f"{self.api_url}/team/{team_id}/space", {"archived": self.archived} + f"{self.api_url}/team/{team_id}/space", + {"is_archived": self.is_archived}, ) ).get("spaces", []) @@ -126,7 +127,7 @@ async def _get_folders_in_space( yield ( await self._send_api_request( f"{self.api_url}/space/{space.get('id')}/folder", - {"archived": self.archived}, + {"is_archived": self.is_archived}, ) ).get("folders") @@ -149,7 +150,7 @@ async def get_folderless_projects( for space in spaces: response = await self._send_api_request( f"{self.api_url}/space/{space.get('id')}/list", - {"archived": self.archived}, + {"is_archived": self.is_archived}, ) projects = response.get("lists") yield [{**project, TEAM_OBJECT: team} for project in projects] diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 83ae8c5cc1..b6f2365166 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -53,16 +53,15 @@ async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: @ocean.on_resync(ObjectKind.PROJECT) async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() - async for projects in clickup_client.get_folderless_projects(): - logger.info(f"Received project batch with {len(projects)} projects") - yield projects - - -@ocean.on_resync(ObjectKind.PROJECT) -async def on_resync_folder_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: - clickup_client = await init_client() + async for folderless_projects in clickup_client.get_folderless_projects(): + logger.info( + f"Received folderless project batch with {len(folderless_projects)} projects" + ) + yield folderless_projects async for projects in clickup_client.get_folder_projects(): - logger.info(f"Received project batch with {len(projects)} projects") + logger.info( + f"Received a batch of project in folders with {len(projects)} projects" + ) yield projects From 47383ad6a43c026a255d81de6d0c6c570849f23d Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Mon, 22 Jul 2024 15:43:44 +0100 Subject: [PATCH 056/177] Updating Ocean version --- integrations/clickup/poetry.lock | 338 +--------------------------- integrations/clickup/pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 332 deletions(-) diff --git a/integrations/clickup/poetry.lock b/integrations/clickup/poetry.lock index 51cbb54c47..5f7f5e55f5 100644 --- a/integrations/clickup/poetry.lock +++ b/integrations/clickup/poetry.lock @@ -34,25 +34,6 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (>=0.23)"] -[[package]] -name = "arrow" -version = "1.3.0" -description = "Better dates & times for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, - {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, -] - -[package.dependencies] -python-dateutil = ">=2.7.0" -types-python-dateutil = ">=2.8.10" - -[package.extras] -doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] -test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] - [[package]] name = "astroid" version = "2.15.8" @@ -68,20 +49,6 @@ files = [ lazy-object-proxy = ">=1.4.0" wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} -[[package]] -name = "binaryornot" -version = "0.4.4" -description = "Ultra-lightweight pure Python package to check if a file is binary or text." -optional = false -python-versions = "*" -files = [ - {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, - {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, -] - -[package.dependencies] -chardet = ">=3.0.2" - [[package]] name = "black" version = "23.12.1" @@ -137,116 +104,6 @@ files = [ {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] -[[package]] -name = "chardet" -version = "5.2.0" -description = "Universal encoding detector for Python 3" -optional = false -python-versions = ">=3.7" -files = [ - {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, - {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -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.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - [[package]] name = "click" version = "8.1.7" @@ -323,27 +180,6 @@ json = ["jsonschema", "pyrsistent", "pyrsistent (==0.16.1)", "requests"] protobuf = ["protobuf", "requests"] schema-registry = ["requests"] -[[package]] -name = "cookiecutter" -version = "2.6.0" -description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." -optional = false -python-versions = ">=3.7" -files = [ - {file = "cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d"}, - {file = "cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c"}, -] - -[package.dependencies] -arrow = "*" -binaryornot = ">=0.4.4" -click = ">=7.0,<9.0.0" -Jinja2 = ">=2.7,<4.0.0" -python-slugify = ">=4.0.0" -pyyaml = ">=5.3.1" -requests = ">=2.23.0" -rich = "*" - [[package]] name = "dill" version = "0.3.8" @@ -502,21 +338,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "jinja2-time" -version = "0.2.0" -description = "Jinja2 Extension for Dates and Times" -optional = false -python-versions = "*" -files = [ - {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"}, - {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, -] - -[package.dependencies] -arrow = "*" -jinja2 = "*" - [[package]] name = "lazy-object-proxy" version = "1.10.0" @@ -581,30 +402,6 @@ win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] -[[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 = "markupsafe" version = "2.1.5" @@ -685,17 +482,6 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] -[[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 = "mypy" version = "1.10.1" @@ -808,34 +594,30 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.1" +version = "0.9.4" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.1-py3-none-any.whl", hash = "sha256:ead27b47816355b52a2316d54ee190d2a4200a5c708befcd691ce69319268947"}, - {file = "port_ocean-0.9.1.tar.gz", hash = "sha256:12636b6214d69182aff3d3e1a4db2ae889d13a40d099fea816a1249b8b8fbebf"}, + {file = "port_ocean-0.9.4-py3-none-any.whl", hash = "sha256:afe4771b0044683941269b3a83b82b24ccd0968f3c2ace056e961fd6b0dd37a2"}, + {file = "port_ocean-0.9.4.tar.gz", hash = "sha256:26018da654867e8c1a49aed2003697595b9b4100892d2f750d79e6b8e166a36a"}, ] [package.dependencies] -aiostream = ">=0.5.2,<0.6.0" -click = {version = ">=8.1.3,<9.0.0", optional = true, markers = "extra == \"cli\""} +aiostream = ">=0.5.2,<0.7.0" confluent-kafka = ">=2.1.1,<3.0.0" -cookiecutter = {version = ">=2.1.1,<3.0.0", optional = true, markers = "extra == \"cli\""} -fastapi = ">=0.100,<0.111" +fastapi = ">=0.100,<0.112" httpx = ">=0.24.1,<0.28.0" -jinja2-time = {version = ">=0.2.0,<0.3.0", optional = true, markers = "extra == \"cli\""} loguru = ">=0.7.0,<0.8.0" pydantic = {version = ">=1.10.8,<2.0.0", extras = ["dotenv"]} pydispatcher = ">=2.0.7,<3.0.0" pyhumps = ">=3.8.0,<4.0.0" pyjq = ">=2.6.0,<3.0.0" pyyaml = ">=6.0,<7.0" -rich = {version = ">=13.4.1,<14.0.0", optional = true, markers = "extra == \"cli\""} six = ">=1.16.0,<2.0.0" tomli = ">=2.0.1,<3.0.0" urllib3 = ">=1.26.16,<3.0.0" -uvicorn = ">=0.22,<0.30" +uvicorn = ">=0.22,<0.31" werkzeug = ">=2.3.4,<4.0.0" [package.extras] @@ -915,20 +697,6 @@ files = [ [package.extras] dev = ["tox"] -[[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 = "pyhumps" version = "3.8.0" @@ -995,20 +763,6 @@ pluggy = ">=0.12,<2.0" [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] -[[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" @@ -1023,23 +777,6 @@ files = [ [package.extras] cli = ["click (>=5.0)"] -[[package]] -name = "python-slugify" -version = "8.0.4" -description = "A Python slugify application that also handles Unicode" -optional = false -python-versions = ">=3.7" -files = [ - {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, - {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, -] - -[package.dependencies] -text-unidecode = ">=1.3" - -[package.extras] -unidecode = ["Unidecode (>=1.1.1)"] - [[package]] name = "pyyaml" version = "6.0.1" @@ -1100,45 +837,6 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] -[[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 = "rich" -version = "13.7.1" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, -] - -[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 = "ruff" version = "0.0.278" @@ -1204,17 +902,6 @@ anyio = ">=3.4.0,<5" [package.extras] full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] -[[package]] -name = "text-unidecode" -version = "1.3" -description = "The most basic Text::Unidecode port" -optional = false -python-versions = "*" -files = [ - {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, - {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, -] - [[package]] name = "tomli" version = "2.0.1" @@ -1256,17 +943,6 @@ jinja2 = "*" [package.extras] dev = ["furo", "packaging", "sphinx (>=5)", "twisted"] -[[package]] -name = "types-python-dateutil" -version = "2.9.0.20240316" -description = "Typing stubs for python-dateutil" -optional = false -python-versions = ">=3.8" -files = [ - {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, - {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, -] - [[package]] name = "typing-extensions" version = "4.12.2" @@ -1426,4 +1102,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cf017d49bb23753d024aeea6c5132b5f121afb2cf02c8724fd32f4c7db18aa50" +content-hash = "bd9bd3e83390bca497930c01378d25e06ebdd2e14f975e046c3d1ad04ba7963c" diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml index 949e530eeb..66300d89de 100644 --- a/integrations/clickup/pyproject.toml +++ b/integrations/clickup/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Iyanuoluwa Adebayo "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = { version = "^0.9.1", extras = ["cli"] } +port_ocean = "^0.9.4" [tool.poetry.group.dev.dependencies] pytest = "^7.2" From 359ecba9fbdfdec6b6d1974d1870ee2f0a2e0917 Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Mon, 22 Jul 2024 15:46:26 +0100 Subject: [PATCH 057/177] Updating Ocean version --- integrations/clickup/poetry.lock | 326 +++++++++++++++++++++++++++- integrations/clickup/pyproject.toml | 2 +- 2 files changed, 326 insertions(+), 2 deletions(-) diff --git a/integrations/clickup/poetry.lock b/integrations/clickup/poetry.lock index 5f7f5e55f5..3ffc32da5c 100644 --- a/integrations/clickup/poetry.lock +++ b/integrations/clickup/poetry.lock @@ -34,6 +34,25 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (>=0.23)"] +[[package]] +name = "arrow" +version = "1.3.0" +description = "Better dates & times for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + [[package]] name = "astroid" version = "2.15.8" @@ -49,6 +68,20 @@ files = [ lazy-object-proxy = ">=1.4.0" wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} +[[package]] +name = "binaryornot" +version = "0.4.4" +description = "Ultra-lightweight pure Python package to check if a file is binary or text." +optional = false +python-versions = "*" +files = [ + {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, + {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, +] + +[package.dependencies] +chardet = ">=3.0.2" + [[package]] name = "black" version = "23.12.1" @@ -104,6 +137,116 @@ files = [ {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +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.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + [[package]] name = "click" version = "8.1.7" @@ -180,6 +323,27 @@ json = ["jsonschema", "pyrsistent", "pyrsistent (==0.16.1)", "requests"] protobuf = ["protobuf", "requests"] schema-registry = ["requests"] +[[package]] +name = "cookiecutter" +version = "2.6.0" +description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d"}, + {file = "cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c"}, +] + +[package.dependencies] +arrow = "*" +binaryornot = ">=0.4.4" +click = ">=7.0,<9.0.0" +Jinja2 = ">=2.7,<4.0.0" +python-slugify = ">=4.0.0" +pyyaml = ">=5.3.1" +requests = ">=2.23.0" +rich = "*" + [[package]] name = "dill" version = "0.3.8" @@ -338,6 +502,21 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jinja2-time" +version = "0.2.0" +description = "Jinja2 Extension for Dates and Times" +optional = false +python-versions = "*" +files = [ + {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"}, + {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, +] + +[package.dependencies] +arrow = "*" +jinja2 = "*" + [[package]] name = "lazy-object-proxy" version = "1.10.0" @@ -402,6 +581,30 @@ win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] +[[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 = "markupsafe" version = "2.1.5" @@ -482,6 +685,17 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[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 = "mypy" version = "1.10.1" @@ -605,15 +819,19 @@ files = [ [package.dependencies] aiostream = ">=0.5.2,<0.7.0" +click = {version = ">=8.1.3,<9.0.0", optional = true, markers = "extra == \"cli\""} confluent-kafka = ">=2.1.1,<3.0.0" +cookiecutter = {version = ">=2.1.1,<3.0.0", optional = true, markers = "extra == \"cli\""} fastapi = ">=0.100,<0.112" httpx = ">=0.24.1,<0.28.0" +jinja2-time = {version = ">=0.2.0,<0.3.0", optional = true, markers = "extra == \"cli\""} loguru = ">=0.7.0,<0.8.0" pydantic = {version = ">=1.10.8,<2.0.0", extras = ["dotenv"]} pydispatcher = ">=2.0.7,<3.0.0" pyhumps = ">=3.8.0,<4.0.0" pyjq = ">=2.6.0,<3.0.0" pyyaml = ">=6.0,<7.0" +rich = {version = ">=13.4.1,<14.0.0", optional = true, markers = "extra == \"cli\""} six = ">=1.16.0,<2.0.0" tomli = ">=2.0.1,<3.0.0" urllib3 = ">=1.26.16,<3.0.0" @@ -697,6 +915,20 @@ files = [ [package.extras] dev = ["tox"] +[[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 = "pyhumps" version = "3.8.0" @@ -763,6 +995,20 @@ pluggy = ">=0.12,<2.0" [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[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" @@ -777,6 +1023,23 @@ files = [ [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-slugify" +version = "8.0.4" +description = "A Python slugify application that also handles Unicode" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, + {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + [[package]] name = "pyyaml" version = "6.0.1" @@ -837,6 +1100,45 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[[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 = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[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 = "ruff" version = "0.0.278" @@ -902,6 +1204,17 @@ anyio = ">=3.4.0,<5" [package.extras] full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -943,6 +1256,17 @@ jinja2 = "*" [package.extras] dev = ["furo", "packaging", "sphinx (>=5)", "twisted"] +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20240316" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, +] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1102,4 +1426,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "bd9bd3e83390bca497930c01378d25e06ebdd2e14f975e046c3d1ad04ba7963c" +content-hash = "57ddc4413c2bd9293b32d2226198126b1ccafd59ca0b1af98c2ffb84b0ae18de" diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml index 66300d89de..f88541171b 100644 --- a/integrations/clickup/pyproject.toml +++ b/integrations/clickup/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Iyanuoluwa Adebayo "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = "^0.9.4" +port_ocean = {extras = ["cli"], version = "^0.9.4"} [tool.poetry.group.dev.dependencies] pytest = "^7.2" From 0d8c3084a8a64e6c1305289d78f0b5c3e6218921 Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Mon, 22 Jul 2024 16:06:50 +0100 Subject: [PATCH 058/177] renamed bool in client init parameter --- integrations/clickup/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 1be330a0c9..9e046d4a27 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -24,12 +24,12 @@ class ClickupClient: """Clickup client to interact with Clickup API.""" - def __init__(self, clickup_url: str, clickup_token: str, archived: bool): + def __init__(self, clickup_url: str, clickup_token: str, is_archived: bool): self.clickup_token = clickup_token self.api_url = f"{clickup_url}/api/v2" self.client = http_async_client self.client.timeout = Timeout(60) - self.is_archived = archived + self.is_archived = is_archived @property def api_headers(self) -> dict[str, Any]: From f10d46d5bc571ff7e99f8a7c442dbb81ace999be Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Mon, 22 Jul 2024 16:22:42 +0100 Subject: [PATCH 059/177] Added some comments in client --- integrations/clickup/client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 9e046d4a27..4187c2893a 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -16,9 +16,9 @@ "listDeleted", ] -MINIMUM_LIMIT_REMAINING = 20 -DEFAULT_SLEEP_TIME = 30 -SEMAPHORE = asyncio.BoundedSemaphore(10) +MINIMUM_LIMIT_REMAINING = 20 # This limit minus the Semaphore count will be the lower treshold for rate limit in the header +DEFAULT_SLEEP_TIME = 30 # The Default wait time when limit is hit +SEMAPHORE = asyncio.BoundedSemaphore(10) # The number of concurrent request allowed class ClickupClient: From a171221969984e05f90139e85a3c9446bbab52fe Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Mon, 22 Jul 2024 16:30:40 +0100 Subject: [PATCH 060/177] Corrected comments in client --- integrations/clickup/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 4187c2893a..9fed18bf1f 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -16,9 +16,9 @@ "listDeleted", ] -MINIMUM_LIMIT_REMAINING = 20 # This limit minus the Semaphore count will be the lower treshold for rate limit in the header +MINIMUM_LIMIT_REMAINING = 20 # This limit minus the Semaphore count will be the lower threshold for rate limit in the header DEFAULT_SLEEP_TIME = 30 # The Default wait time when limit is hit -SEMAPHORE = asyncio.BoundedSemaphore(10) # The number of concurrent request allowed +SEMAPHORE = asyncio.BoundedSemaphore(10) # The number of concurrent requests allowed class ClickupClient: From f9e2a41743860f03d65e35ee8287f5157e831183 Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Thu, 25 Jul 2024 14:17:54 +0100 Subject: [PATCH 061/177] Updated port-ocean --- integrations/clickup/poetry.lock | 8 ++++---- integrations/clickup/pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/integrations/clickup/poetry.lock b/integrations/clickup/poetry.lock index 3ffc32da5c..314cd466f4 100644 --- a/integrations/clickup/poetry.lock +++ b/integrations/clickup/poetry.lock @@ -808,13 +808,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.4" +version = "0.9.5" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.4-py3-none-any.whl", hash = "sha256:afe4771b0044683941269b3a83b82b24ccd0968f3c2ace056e961fd6b0dd37a2"}, - {file = "port_ocean-0.9.4.tar.gz", hash = "sha256:26018da654867e8c1a49aed2003697595b9b4100892d2f750d79e6b8e166a36a"}, + {file = "port_ocean-0.9.5-py3-none-any.whl", hash = "sha256:6d457dfddd0e4906d76ecff28498159acc948fc0cbe25f6e3553514cc237b066"}, + {file = "port_ocean-0.9.5.tar.gz", hash = "sha256:bd205f411feeb7524856bb3b8cbf0251f9d39d2d07fab361c3b90a8012759b71"}, ] [package.dependencies] @@ -1426,4 +1426,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "57ddc4413c2bd9293b32d2226198126b1ccafd59ca0b1af98c2ffb84b0ae18de" +content-hash = "059abbf8fb46ed08115d2698e79b929a77b0bc42ee0a0e31a6bbd32179f15860" diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml index f88541171b..9c30de0ace 100644 --- a/integrations/clickup/pyproject.toml +++ b/integrations/clickup/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Iyanuoluwa Adebayo "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {extras = ["cli"], version = "^0.9.4"} +port_ocean = {extras = ["cli"], version = "^0.9.5"} [tool.poetry.group.dev.dependencies] pytest = "^7.2" From f86bf1e9d67dc7efc3c61b464ff761d4236aeb3c Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Thu, 25 Jul 2024 16:29:33 +0100 Subject: [PATCH 062/177] Added sonar-project.properties --- integrations/clickup/sonar-project.properties | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 integrations/clickup/sonar-project.properties diff --git a/integrations/clickup/sonar-project.properties b/integrations/clickup/sonar-project.properties new file mode 100644 index 0000000000..bd117765e8 --- /dev/null +++ b/integrations/clickup/sonar-project.properties @@ -0,0 +1,2 @@ +sonar.projectKey=port-labs_ocean_clickup +sonar.organization=port-labs From ab5fcfa814eb8fe9fa20b4fb3cc8ae9464b9f1ba Mon Sep 17 00:00:00 2001 From: oiadebayo Date: Thu, 25 Jul 2024 16:30:21 +0100 Subject: [PATCH 063/177] Updated sonar-project.properties --- integrations/clickup/sonar-project.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/integrations/clickup/sonar-project.properties b/integrations/clickup/sonar-project.properties index bd117765e8..16063caded 100644 --- a/integrations/clickup/sonar-project.properties +++ b/integrations/clickup/sonar-project.properties @@ -1,2 +1,3 @@ sonar.projectKey=port-labs_ocean_clickup sonar.organization=port-labs + From 58df41458ab08432b8cac717fbbf287f7d45cc33 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa Date: Tue, 30 Jul 2024 12:58:40 +0100 Subject: [PATCH 064/177] Attending to PR comment Added support for ingesting space data Separated webhook creation logic from client Added webhook support for space --- .../clickup/.port/resources/blueprints.json | 159 +++++++++++++----- .../.port/resources/port-app-config.yaml | 22 ++- integrations/clickup/client.py | 77 ++++----- integrations/clickup/main.py | 30 +++- 4 files changed, 195 insertions(+), 93 deletions(-) diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json index 338473ce9b..447c45ccda 100644 --- a/integrations/clickup/.port/resources/blueprints.json +++ b/integrations/clickup/.port/resources/blueprints.json @@ -28,50 +28,120 @@ "relations": {} }, { - "identifier": "clickupProject", - "description": "This blueprint represents a ClickUp project", - "title": "ClickUp Project", - "icon": "Clickup", - "schema": { - "properties": { - "url": { - "title": "Project URL", - "type": "string", - "format": "url", - "description": "URL to the project in Clickup" - }, - "startDate": { - "title": "Project start date", - "type": "string", - "format": "date-time", - "description": "The start date of this project" - }, - "endDate": { - "title": "Project end date", - "type": "string", - "format": "date-time", - "description": "The end date of this project" - }, - "totalIssues": { - "title": "Total Issues", - "type": "number", - "description": "The total number of issues in the project" + "identifier": "clickupSpace", + "description": "This blueprint represents a ClickUp space", + "title": "ClickUp Space", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "title": "Space URL", + "type": "string", + "format": "url", + "description": "URL to the space in Clickup" + }, + "statuses": { + "title": "Statuses", + "type": "array", + "items": { + "type": "object", + "properties": { + "status": { + "title": "Status", + "type": "string" + }, + "type": { + "title": "Type", + "type": "string" + }, + "orderindex": { + "title": "Order Index", + "type": "integer" + }, + "color": { + "title": "Color", + "type": "string", + "format": "color" + } + } } }, - "required": [] + "archived": { + "title": "Archived", + "type": "boolean", + "description": "Indicates if the space is archived" + }, + "private": { + "title": "Private", + "type": "boolean", + "description": "Indicates if the space is private" + } }, - "mirrorProperties": {}, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": { - "team": { - "title": "Team", - "target": "clickupTeam", - "required": false, - "many": false + "required": [] + }, + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "team": { + "title": "Team", + "description": "The ClickUp team that this space belongs to", + "target": "clickupTeam", + "required": false, + "many": false + } + } +}, + { + "identifier": "clickupProject", + "description": "This blueprint represents a ClickUp project", + "title": "ClickUp Project", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "title": "Project URL", + "type": "string", + "format": "url", + "description": "URL to the project in Clickup" + }, + "startDate": { + "title": "Project start date", + "type": "string", + "format": "date-time", + "description": "The start date of this project" + }, + "endDate": { + "title": "Project end date", + "type": "string", + "format": "date-time", + "description": "The end date of this project" + }, + "totalIssues": { + "title": "Total Issues", + "type": "number", + "description": "The total number of issues in the project" } + }, + "required": [] + }, + "mirrorProperties": { + "team": { + "title": "Team", + "path": "space.team.$title" } }, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "space": { + "title": "Space", + "target": "clickupSpace", + "required": false, + "many": false + } + } +}, { "identifier": "clickupIssue", "title": "ClickUp Issue", @@ -94,11 +164,14 @@ "type": "string", "description": "The status of the issue" }, - "assignee": { - "title": "Assignee", - "type": "string", - "format": "user", - "description": "The user assigned to the issue" + "assignees": { + "title": "Assignees", + "type": "array", + "items": { + "type": "string", + "format": "email", + "description": "The users assigned to the issue" + } }, "creator": { "title": "Creator", diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 4a5859d818..5943359a3b 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,23 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - member: "[.members[].user.email]" + members: [.members[].user.email] + - kind: space + selector: + query: 'true' + port: + entity: + mappings: + blueprint: '"clickupSpace"' + identifier: .id + title: .name + properties: + url: "\"https://app.clickup.com/\" + .__team.id + \"/v/o/s/\" + .id" + statuses: .statuses + archived: .archived + private: .private + relations: + team: .__team.id - kind: project selector: query: 'true' @@ -28,7 +44,7 @@ resources: endDate: if .due_date!=null then .due_date | tonumber / 1000 | todate else "" | todate end totalIssues: .task_count relations: - team: .__team.id + space: .space.id - kind: issue selector: query: 'true' @@ -42,7 +58,7 @@ resources: description: .description url: .url status: .status.status - assignee: if (.assignees | length) > 0 then .assignees[0].email else "" end + assignees: [.assignees[].email] creator: .creator.email | tostring priority: if .priority != null then .priority.priority else " " end created: if .date_created!=null then .date_created | tonumber / 1000 | todate else "" | todate end diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 9fed18bf1f..5fa390c693 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -14,6 +14,9 @@ "listCreated", "listUpdated", "listDeleted", + "spaceCreated", + "spaceUpdated", + "spaceDeleted", ] MINIMUM_LIMIT_REMAINING = 20 # This limit minus the Semaphore count will be the lower threshold for rate limit in the header @@ -131,14 +134,19 @@ async def _get_folders_in_space( ) ).get("folders") + async def get_all_spaces(self) -> AsyncGenerator[List[dict[str, Any]], None]: + """Get all spaces across all teams.""" + async for teams in self.get_clickup_teams(): + for team in teams: + async for spaces in self._get_spaces_in_team(team.get("id")): + yield [{**space, TEAM_OBJECT: team} for space in spaces] + async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all projects with a folder parent.""" async for teams in self.get_clickup_teams(): for team in teams: async for folders in self._get_folders_in_space(team.get("id")): - for folder in folders: - projects = folder.get("lists") - yield [{**project, TEAM_OBJECT: team} for project in projects] + yield [folder.get("lists") for folder in folders] async def get_folderless_projects( self, @@ -148,30 +156,14 @@ async def get_folderless_projects( for team in teams: async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: - response = await self._send_api_request( - f"{self.api_url}/space/{space.get('id')}/list", - {"is_archived": self.is_archived}, - ) - projects = response.get("lists") + projects = ( + await self._send_api_request( + f"{self.api_url}/space/{space.get('id')}/list", + {"is_archived": self.is_archived}, + ) + ).get("lists") yield [{**project, TEAM_OBJECT: team} for project in projects] - async def get_single_project(self, list_id: str) -> Optional[Dict[str, Any]]: - """Get a single project by list_id.""" - url = f"{self.api_url}/list/{list_id}" - response = await self._send_api_request(url) - space_id = response.get("space").get("id") - - async for teams in self.get_clickup_teams(): - for team in teams: - async for spaces in self._get_spaces_in_team(team.get("id")): - for space in spaces: - logger.info(space.get("id")) - if space.get("id") == space_id: - return {**response, TEAM_OBJECT: team} - - logger.warning("No matching space found.") - return None - async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" async for teams in self.get_clickup_teams(): @@ -185,6 +177,22 @@ async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], Non break page += 1 + async def _get_all_teams(self) -> List[Dict[str, Any]]: + """Get all teams.""" + return (await self._send_api_request(f"{self.api_url}/team")).get("teams", []) + + async def get_single_space(self, space_id: str) -> Optional[Dict[str, Any]]: + """Get a single space by space_id.""" + async for spaces in self.get_all_spaces(): + for space in spaces: + if space["id"] == space_id: + return space + return None + + async def get_single_project(self, list_id: str) -> Optional[Dict[str, Any]]: + """Get a single project by list_id.""" + return await self._send_api_request(f"{self.api_url}/list/{list_id}") + async def get_single_issue(self, task_id: str) -> dict[str, Any]: """Get a single issue by task_id.""" return await self._send_api_request(f"{self.api_url}/task/{task_id}") @@ -210,22 +218,3 @@ async def get_clickup_webhooks(self, team_id: str) -> list[dict[str, Any]]: return (await self._send_api_request(f"{self.api_url}/team/{team_id}/webhook"))[ "webhooks" ] - - async def create_clickup_events_webhook(self, app_host: str) -> None: - async for teams in self.get_clickup_teams(): - for team in teams: - team_id = team["id"] - - webhook_target_url = f"{app_host}/integration/webhook" - - webhooks = await self.get_clickup_webhooks(team_id) - - webhook_exits = any( - config["endpoint"] == webhook_target_url for config in webhooks - ) - - if webhook_exits: - logger.info(f"Webhook already exists for team {team_id}") - else: - logger.info(f"Creating webhook for team {team_id}") - await self.create_clickup_webhook(team_id, app_host) diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index b6f2365166..e467e3081f 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -12,11 +12,15 @@ "taskCreated": "register", "taskUpdated": "register", "taskDeleted": "unregister", + "spaceCreated": "register", + "spaceUpdated": "register", + "spaceDeleted": "unregister", } class ObjectKind(StrEnum): TEAM = "team" + SPACE = "space" PROJECT = "project" ISSUE = "issue" @@ -39,7 +43,17 @@ async def setup_application() -> None: ) return clickup_client = await init_client() # Await the initialization of the client - await clickup_client.create_clickup_events_webhook(app_host) + async for teams in clickup_client.get_clickup_teams(): + for team in teams: + webhooks = await clickup_client.get_clickup_webhooks(team["id"]) + webhook_exists = any( + config["endpoint"] == f"{app_host}/integration/webhook" + for config in webhooks + ) + if webhook_exists: + logger.info(f"Webhook already exists for team {team['id']}") + else: + logger.info(f"Creating webhook for team {team['id']}") @ocean.on_resync(ObjectKind.TEAM) @@ -50,6 +64,14 @@ async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: yield teams +@ocean.on_resync(ObjectKind.SPACE) +async def on_resync_spaces(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: + clickup_client = await init_client() + async for spaces in clickup_client.get_all_spaces(): + logger.info(f"Received space batch with {len(spaces)} spaces") + yield spaces + + @ocean.on_resync(ObjectKind.PROJECT) async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() @@ -78,8 +100,10 @@ async def _handle_register( ) -> None: if kind == ObjectKind.ISSUE: entity = await clickup_client.get_single_issue(entity_id) - else: + elif kind == ObjectKind.PROJECT: entity = await clickup_client.get_single_project(entity_id) + else: + entity = await clickup_client.get_single_space(entity_id) if entity: await ocean.register_raw(kind, [entity]) @@ -108,6 +132,7 @@ async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: event_handlers = { "task": ObjectKind.ISSUE, "list": ObjectKind.PROJECT, + "space": ObjectKind.SPACE, } event_type = data["event"] @@ -119,7 +144,6 @@ async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: if not entity_id: logger.error(f"No {key}_id found in data for event {event_type}") continue - if action == "register": await _handle_register(clickup_client, entity_id, kind, event_type) else: From 2036db8ac5c34551a8d51045e8c7f8f4e45bb049 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Sun, 4 Aug 2024 16:16:00 +0100 Subject: [PATCH 065/177] Attended to review comments --- .../clickup/.port/resources/blueprints.json | 3 +- .../.port/resources/port-app-config.yaml | 8 ++-- integrations/clickup/client.py | 47 +++++++++++++------ integrations/clickup/main.py | 8 ++-- integrations/clickup/poetry.lock | 9 ++-- integrations/clickup/pyproject.toml | 2 +- 6 files changed, 48 insertions(+), 29 deletions(-) diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json index 447c45ccda..233c624469 100644 --- a/integrations/clickup/.port/resources/blueprints.json +++ b/integrations/clickup/.port/resources/blueprints.json @@ -60,8 +60,7 @@ }, "color": { "title": "Color", - "type": "string", - "format": "color" + "type": "string" } } } diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index 5943359a3b..cd7fcd6519 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -12,7 +12,7 @@ resources: title: .name properties: url: "\"https://app.clickup.com/\" + .id + \"/home\"" - members: [.members[].user.email] + members: '[.members[].user.email]' - kind: space selector: query: 'true' @@ -39,7 +39,9 @@ resources: identifier: .id title: .name properties: - url: "\"https://app.clickup.com/\" + .__team.id + \"/v/b/li/\" + .id " + url: >- + 'https://app.clickup.com/' + + .__team.id + '/v/b/li/' + .id startDate: if .start_date!=null then .start_date | tonumber / 1000 | todate else "" | todate end endDate: if .due_date!=null then .due_date | tonumber / 1000 | todate else "" | todate end totalIssues: .task_count @@ -58,7 +60,7 @@ resources: description: .description url: .url status: .status.status - assignees: [.assignees[].email] + assignees: '[.assignees[].email]' creator: .creator.email | tostring priority: if .priority != null then .priority.priority else " " end created: if .date_created!=null then .date_created | tonumber / 1000 | todate else "" | todate end diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 5fa390c693..deb6702348 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -6,6 +6,14 @@ from port_ocean.utils import http_async_client from port_ocean.utils.cache import cache_iterator_result +MINIMUM_LIMIT_REMAINING = ( + 1001 # The minimum limit returned in the headers before waiting +) +DEFAULT_SLEEP_TIME = 5 # The Default wait time when limit is hit +DEFAULT_SEMAPHORE_VALUE = 1000 # The default number of concurrent requests allowed +SEMAPHORE = asyncio.BoundedSemaphore(DEFAULT_SEMAPHORE_VALUE) +SEMAPHORE_UPDATED = False + TEAM_OBJECT = "__team" WEBHOOK_EVENTS = [ "taskCreated", @@ -19,10 +27,6 @@ "spaceDeleted", ] -MINIMUM_LIMIT_REMAINING = 20 # This limit minus the Semaphore count will be the lower threshold for rate limit in the header -DEFAULT_SLEEP_TIME = 30 # The Default wait time when limit is hit -SEMAPHORE = asyncio.BoundedSemaphore(10) # The number of concurrent requests allowed - class ClickupClient: """Clickup client to interact with Clickup API.""" @@ -51,8 +55,12 @@ async def _fetch_with_rate_limit_handling( """ Sends an HTTP request to the ClickUp API with rate limit handling. The acceptable rate is described in the documentation provided by Clickup at - https://clickup.com/api/developer-portal/rate-limits/ + https://clickup.com/api/developer-portal/rate-limits/ and the rate limit headers are described at + https://rdrr.io/github/psolymos/clickrup/src/R/cu-ratelimit.R """ + global SEMAPHORE_UPDATED + global SEMAPHORE + global MINIMUM_LIMIT_REMAINING while True: async with SEMAPHORE: response = await self.client.request( @@ -64,15 +72,28 @@ async def _fetch_with_rate_limit_handling( ) try: response.raise_for_status() + # Update semaphore based on the rate limit if not updated already + if not SEMAPHORE_UPDATED: + rate_limit = int( + response.headers.get( + "X-RateLimit-Limit", DEFAULT_SEMAPHORE_VALUE + ) + ) + SEMAPHORE = asyncio.BoundedSemaphore(int(rate_limit / 10)) + MINIMUM_LIMIT_REMAINING = int((rate_limit / 10) + 1) + SEMAPHORE_UPDATED = True + logger.info( + f"Number of concurrent requests allowed adjusted to {int(rate_limit/10)} based on X-RateLimit-Limit header" + ) rate_limit_remaining = int( response.headers.get("X-RateLimit-Remaining", 1) ) - rate_limit_reset = int(response.headers.get("X-RateLimit-Reset")) + rate_limit_reset = int( + response.headers.get("X-RateLimit-Reset", DEFAULT_SLEEP_TIME) + ) if rate_limit_remaining <= MINIMUM_LIMIT_REMAINING: current_time = int(time.time()) - wait_time = max( - rate_limit_reset - current_time, DEFAULT_SLEEP_TIME - ) + wait_time = rate_limit_reset - current_time logger.info( f"Approaching rate limit. Waiting for {wait_time} seconds to continue export. " f"URL: {url}, Remaining: {rate_limit_remaining} " @@ -156,13 +177,12 @@ async def get_folderless_projects( for team in teams: async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: - projects = ( + yield ( await self._send_api_request( f"{self.api_url}/space/{space.get('id')}/list", {"is_archived": self.is_archived}, ) ).get("lists") - yield [{**project, TEAM_OBJECT: team} for project in projects] async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" @@ -177,16 +197,13 @@ async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], Non break page += 1 - async def _get_all_teams(self) -> List[Dict[str, Any]]: - """Get all teams.""" - return (await self._send_api_request(f"{self.api_url}/team")).get("teams", []) - async def get_single_space(self, space_id: str) -> Optional[Dict[str, Any]]: """Get a single space by space_id.""" async for spaces in self.get_all_spaces(): for space in spaces: if space["id"] == space_id: return space + logger.warning(f"No matching space found for {space_id}.") return None async def get_single_project(self, list_id: str) -> Optional[Dict[str, Any]]: diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index e467e3081f..8d7416ae68 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -95,7 +95,7 @@ async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: yield issues -async def _handle_register( +async def handle_register( clickup_client: Any, entity_id: str, kind: ObjectKind, event_type: str ) -> None: if kind == ObjectKind.ISSUE: @@ -112,7 +112,7 @@ async def _handle_register( logger.error(f"Handler returned None for entity_id {entity_id}") -async def _handle_unregister(entity_id: str, kind: ObjectKind, event_type: str) -> None: +async def handle_unregister(entity_id: str, kind: ObjectKind, event_type: str) -> None: try: await ocean.unregister_raw(kind, [{"id": entity_id}]) logger.info(f"Unregistered {kind} for event {event_type}") @@ -145,9 +145,9 @@ async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: logger.error(f"No {key}_id found in data for event {event_type}") continue if action == "register": - await _handle_register(clickup_client, entity_id, kind, event_type) + await handle_register(clickup_client, entity_id, kind, event_type) else: - await _handle_unregister(entity_id, kind, event_type) + await handle_unregister(entity_id, kind, event_type) break logger.info("Webhook event processed") diff --git a/integrations/clickup/poetry.lock b/integrations/clickup/poetry.lock index 314cd466f4..a48341127e 100644 --- a/integrations/clickup/poetry.lock +++ b/integrations/clickup/poetry.lock @@ -808,13 +808,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.5" +version = "0.9.10" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.5-py3-none-any.whl", hash = "sha256:6d457dfddd0e4906d76ecff28498159acc948fc0cbe25f6e3553514cc237b066"}, - {file = "port_ocean-0.9.5.tar.gz", hash = "sha256:bd205f411feeb7524856bb3b8cbf0251f9d39d2d07fab361c3b90a8012759b71"}, + {file = "port_ocean-0.9.10-py3-none-any.whl", hash = "sha256:4b0ee8bbfda6fa21b214d843ece1ff3b3709680ab341bfe34bce8e06689b70e1"}, + {file = "port_ocean-0.9.10.tar.gz", hash = "sha256:a20773fc97f4662df2dadfd54cdc3a53a7ae2f7779f410bb655491e23d3cfe12"}, ] [package.dependencies] @@ -830,6 +830,7 @@ pydantic = {version = ">=1.10.8,<2.0.0", extras = ["dotenv"]} pydispatcher = ">=2.0.7,<3.0.0" pyhumps = ">=3.8.0,<4.0.0" pyjq = ">=2.6.0,<3.0.0" +python-dateutil = ">=2.9.0.post0,<3.0.0" pyyaml = ">=6.0,<7.0" rich = {version = ">=13.4.1,<14.0.0", optional = true, markers = "extra == \"cli\""} six = ">=1.16.0,<2.0.0" @@ -1426,4 +1427,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "059abbf8fb46ed08115d2698e79b929a77b0bc42ee0a0e31a6bbd32179f15860" +content-hash = "c30b03639636b9448f9ed4d76d0516e6ac612d1b4439e3cc8b3b70f98900603b" diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml index 9c30de0ace..2862512fbf 100644 --- a/integrations/clickup/pyproject.toml +++ b/integrations/clickup/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Iyanuoluwa Adebayo "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {extras = ["cli"], version = "^0.9.5"} +port_ocean = {extras = ["cli"], version = "^0.9.10"} [tool.poetry.group.dev.dependencies] pytest = "^7.2" From 918e919a2d80c47be3664d3c7913cd2dc9f92555 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Sun, 4 Aug 2024 17:45:22 +0100 Subject: [PATCH 066/177] Handled team inclusion --- .../clickup/.port/resources/port-app-config.yaml | 4 +--- integrations/clickup/client.py | 15 +++++++++++---- integrations/clickup/main.py | 1 + 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index cd7fcd6519..c06ba53c80 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -39,9 +39,7 @@ resources: identifier: .id title: .name properties: - url: >- - 'https://app.clickup.com/' + - .__team.id + '/v/b/li/' + .id + url: "\"https://app.clickup.com/\" + .__team.id + \"/v/b/li/\" + .id" startDate: if .start_date!=null then .start_date | tonumber / 1000 | todate else "" | todate end endDate: if .due_date!=null then .due_date | tonumber / 1000 | todate else "" | todate end totalIssues: .task_count diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index deb6702348..08da0459a9 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -94,12 +94,11 @@ async def _fetch_with_rate_limit_handling( if rate_limit_remaining <= MINIMUM_LIMIT_REMAINING: current_time = int(time.time()) wait_time = rate_limit_reset - current_time - logger.info( + logger.warning( f"Approaching rate limit. Waiting for {wait_time} seconds to continue export. " f"URL: {url}, Remaining: {rate_limit_remaining} " ) await asyncio.sleep(wait_time) - logger.debug(f"{rate_limit_reset} - {rate_limit_remaining}") except KeyError as e: logger.error( f"Rate limit headers not found in response: {str(e)} for url {url}" @@ -167,7 +166,14 @@ async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None async for teams in self.get_clickup_teams(): for team in teams: async for folders in self._get_folders_in_space(team.get("id")): - yield [folder.get("lists") for folder in folders] + for folder in folders: + projects = ( + await self._send_api_request( + f"{self.api_url}/folder/{folder.get('id')}/list", + {"is_archived": self.is_archived}, + ) + ).get("lists") + yield [{**project, TEAM_OBJECT: team} for project in projects] async def get_folderless_projects( self, @@ -177,12 +183,13 @@ async def get_folderless_projects( for team in teams: async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: - yield ( + projects = ( await self._send_api_request( f"{self.api_url}/space/{space.get('id')}/list", {"is_archived": self.is_archived}, ) ).get("lists") + yield [{**project, TEAM_OBJECT: team} for project in projects] async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 8d7416ae68..c6f85b0083 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -54,6 +54,7 @@ async def setup_application() -> None: logger.info(f"Webhook already exists for team {team['id']}") else: logger.info(f"Creating webhook for team {team['id']}") + await clickup_client.create_clickup_webhook(team["id"], app_host) @ocean.on_resync(ObjectKind.TEAM) From 87339728bfbee1fb0c3a55be0aa6295843bf9d4a Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Sun, 4 Aug 2024 17:51:11 +0100 Subject: [PATCH 067/177] Fixed indentation --- .../clickup/.port/resources/blueprints.json | 402 +++++++++--------- 1 file changed, 201 insertions(+), 201 deletions(-) diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json index 233c624469..f8730ca353 100644 --- a/integrations/clickup/.port/resources/blueprints.json +++ b/integrations/clickup/.port/resources/blueprints.json @@ -1,214 +1,214 @@ [ - { - "identifier": "clickupTeam", - "description": "This blueprint represents a Clickup team", - "title": "Clickup Team", - "icon": "Clickup", - "schema": { - "properties": { - "url": { - "type": "string", - "title": "URL", - "format": "url" + { + "identifier": "clickupTeam", + "description": "This blueprint represents a Clickup team", + "title": "Clickup Team", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "type": "string", + "title": "URL", + "format": "url" + }, + "members": { + "type": "array", + "title": "Members", + "items": { + "type": "string", + "format": "user" + } + } + }, + "required": [] }, - "members": { - "type": "array", - "title": "Members", - "items": { - "type": "string", - "format": "user" - } - } - }, - "required": [] + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": {} }, - "mirrorProperties": {}, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": {} - }, - { - "identifier": "clickupSpace", - "description": "This blueprint represents a ClickUp space", - "title": "ClickUp Space", - "icon": "Clickup", - "schema": { - "properties": { - "url": { - "title": "Space URL", - "type": "string", - "format": "url", - "description": "URL to the space in Clickup" - }, - "statuses": { - "title": "Statuses", - "type": "array", - "items": { - "type": "object", - "properties": { - "status": { - "title": "Status", - "type": "string" - }, - "type": { - "title": "Type", - "type": "string" + { + "identifier": "clickupSpace", + "description": "This blueprint represents a ClickUp space", + "title": "ClickUp Space", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "title": "Space URL", + "type": "string", + "format": "url", + "description": "URL to the space in Clickup" + }, + "statuses": { + "title": "Statuses", + "type": "array", + "items": { + "type": "object", + "properties": { + "status": { + "title": "Status", + "type": "string" + }, + "type": { + "title": "Type", + "type": "string" + }, + "orderindex": { + "title": "Order Index", + "type": "integer" + }, + "color": { + "title": "Color", + "type": "string" + } + } + } + }, + "archived": { + "title": "Archived", + "type": "boolean", + "description": "Indicates if the space is archived" + }, + "private": { + "title": "Private", + "type": "boolean", + "description": "Indicates if the space is private" + } }, - "orderindex": { - "title": "Order Index", - "type": "integer" - }, - "color": { - "title": "Color", - "type": "string" + "required": [] + }, + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "team": { + "title": "Team", + "description": "The ClickUp team that this space belongs to", + "target": "clickupTeam", + "required": false, + "many": false } - } } - }, - "archived": { - "title": "Archived", - "type": "boolean", - "description": "Indicates if the space is archived" - }, - "private": { - "title": "Private", - "type": "boolean", - "description": "Indicates if the space is private" - } }, - "required": [] - }, - "mirrorProperties": {}, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": { - "team": { - "title": "Team", - "description": "The ClickUp team that this space belongs to", - "target": "clickupTeam", - "required": false, - "many": false - } - } -}, - { - "identifier": "clickupProject", - "description": "This blueprint represents a ClickUp project", - "title": "ClickUp Project", - "icon": "Clickup", - "schema": { - "properties": { - "url": { - "title": "Project URL", - "type": "string", - "format": "url", - "description": "URL to the project in Clickup" - }, - "startDate": { - "title": "Project start date", - "type": "string", - "format": "date-time", - "description": "The start date of this project" - }, - "endDate": { - "title": "Project end date", - "type": "string", - "format": "date-time", - "description": "The end date of this project" - }, - "totalIssues": { - "title": "Total Issues", - "type": "number", - "description": "The total number of issues in the project" - } - }, - "required": [] - }, - "mirrorProperties": { - "team": { - "title": "Team", - "path": "space.team.$title" - } - }, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": { - "space": { - "title": "Space", - "target": "clickupSpace", - "required": false, - "many": false - } - } -}, - { - "identifier": "clickupIssue", - "title": "ClickUp Issue", - "icon": "Clickup", - "schema": { - "properties": { - "description": { - "title": "Issue Description", - "type": "string", - "description": "Detailed description of the issue" - }, - "url": { - "title": "Issue URL", - "type": "string", - "format": "url", - "description": "URL to the issue in Clickup" - }, - "status": { - "title": "Status", - "type": "string", - "description": "The status of the issue" - }, - "assignees": { - "title": "Assignees", - "type": "array", - "items": { - "type": "string", - "format": "email", - "description": "The users assigned to the issue" - } - }, - "creator": { - "title": "Creator", - "type": "string", - "description": "The user that created the issue", - "format": "user" - }, - "priority": { - "title": "Priority", - "type": "string", - "description": "The priority of the issue" + { + "identifier": "clickupProject", + "description": "This blueprint represents a ClickUp project", + "title": "ClickUp Project", + "icon": "Clickup", + "schema": { + "properties": { + "url": { + "title": "Project URL", + "type": "string", + "format": "url", + "description": "URL to the project in Clickup" + }, + "startDate": { + "title": "Project start date", + "type": "string", + "format": "date-time", + "description": "The start date of this project" + }, + "endDate": { + "title": "Project end date", + "type": "string", + "format": "date-time", + "description": "The end date of this project" + }, + "totalIssues": { + "title": "Total Issues", + "type": "number", + "description": "The total number of issues in the project" + } + }, + "required": [] }, - "created": { - "title": "Created At", - "type": "string", - "description": "The created datetime of the issue", - "format": "date-time" + "mirrorProperties": { + "team": { + "title": "Team", + "path": "space.team.$title" + } }, - "updated": { - "title": "Updated At", - "type": "string", - "description": "The updated datetime of the issue", - "format": "date-time" + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "space": { + "title": "Space", + "target": "clickupSpace", + "required": false, + "many": false + } } - }, - "required": [] }, - "mirrorProperties": {}, - "calculationProperties": {}, - "aggregationProperties": {}, - "relations": { - "project": { - "title": "Project", - "description": "The Clickup project that manages this issue", - "target": "clickupProject", - "required": false, - "many": false - } + { + "identifier": "clickupIssue", + "title": "ClickUp Issue", + "icon": "Clickup", + "schema": { + "properties": { + "description": { + "title": "Issue Description", + "type": "string", + "description": "Detailed description of the issue" + }, + "url": { + "title": "Issue URL", + "type": "string", + "format": "url", + "description": "URL to the issue in Clickup" + }, + "status": { + "title": "Status", + "type": "string", + "description": "The status of the issue" + }, + "assignees": { + "title": "Assignees", + "type": "array", + "items": { + "type": "string", + "format": "email", + "description": "The users assigned to the issue" + } + }, + "creator": { + "title": "Creator", + "type": "string", + "description": "The user that created the issue", + "format": "user" + }, + "priority": { + "title": "Priority", + "type": "string", + "description": "The priority of the issue" + }, + "created": { + "title": "Created At", + "type": "string", + "description": "The created datetime of the issue", + "format": "date-time" + }, + "updated": { + "title": "Updated At", + "type": "string", + "description": "The updated datetime of the issue", + "format": "date-time" + } + }, + "required": [] + }, + "mirrorProperties": {}, + "calculationProperties": {}, + "aggregationProperties": {}, + "relations": { + "project": { + "title": "Project", + "description": "The Clickup project that manages this issue", + "target": "clickupProject", + "required": false, + "many": false + } + } } - } ] From 26699bce4cdb627558a65a60a324d205265586cc Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:08:56 +0100 Subject: [PATCH 068/177] Fix: property issue on blueprint and bumped ocean version --- .../clickup/.port/resources/blueprints.json | 23 +++---------------- integrations/clickup/poetry.lock | 8 +++---- integrations/clickup/pyproject.toml | 2 +- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json index f8730ca353..0e677c27a9 100644 --- a/integrations/clickup/.port/resources/blueprints.json +++ b/integrations/clickup/.port/resources/blueprints.json @@ -44,26 +44,9 @@ "title": "Statuses", "type": "array", "items": { - "type": "object", - "properties": { - "status": { - "title": "Status", - "type": "string" - }, - "type": { - "title": "Type", - "type": "string" - }, - "orderindex": { - "title": "Order Index", - "type": "integer" - }, - "color": { - "title": "Color", - "type": "string" - } - } - } + "type": "object" + }, + "icon": "DefaultProperty" }, "archived": { "title": "Archived", diff --git a/integrations/clickup/poetry.lock b/integrations/clickup/poetry.lock index a48341127e..182e25c576 100644 --- a/integrations/clickup/poetry.lock +++ b/integrations/clickup/poetry.lock @@ -808,13 +808,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.10" +version = "0.9.11" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.10-py3-none-any.whl", hash = "sha256:4b0ee8bbfda6fa21b214d843ece1ff3b3709680ab341bfe34bce8e06689b70e1"}, - {file = "port_ocean-0.9.10.tar.gz", hash = "sha256:a20773fc97f4662df2dadfd54cdc3a53a7ae2f7779f410bb655491e23d3cfe12"}, + {file = "port_ocean-0.9.11-py3-none-any.whl", hash = "sha256:6bd8ec8e17a4ae3a4e9da5f283d93368e7ec4756461fe0abcdd1aba8aa5c9764"}, + {file = "port_ocean-0.9.11.tar.gz", hash = "sha256:3fbc0206b49e942be5a11cc891cf1f7f7c746bfbf0c5d3e19b13b05af6c901f5"}, ] [package.dependencies] @@ -1427,4 +1427,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "c30b03639636b9448f9ed4d76d0516e6ac612d1b4439e3cc8b3b70f98900603b" +content-hash = "8f6eb86d16ca414b19f7f7e37807328795e23f1d5c25a735cfa0474d5b599844" diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml index 2862512fbf..054f12696c 100644 --- a/integrations/clickup/pyproject.toml +++ b/integrations/clickup/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Iyanuoluwa Adebayo "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {extras = ["cli"], version = "^0.9.10"} +port_ocean = {extras = ["cli"], version = "^0.9.11"} [tool.poetry.group.dev.dependencies] pytest = "^7.2" From e944bf6ee623d1418daae93e49bdace2d7b095fc Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:45:50 +0100 Subject: [PATCH 069/177] Committed suggestion to integrations/clickup/.port/spec.yaml Co-authored-by: Tom Tankilevitch <59158507+Tankilevitch@users.noreply.github.com> --- integrations/clickup/.port/spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index 853edb1dc8..8815f7203f 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -17,7 +17,7 @@ configurations: - name: clickupBaseUrl description: The Clickup Base URL. Defaults to https://api.clickup.com when not specified type: url - required: true + required: false default: https://api.clickup.com - name: includeArchivedProjects description: This is to filter archived projects. If set to true, archived projects will be included in the export. If set to false, archived projects will be excluded from the export. Default is false. From 4a3f749e87a275c2644d7d102651d33678f57d15 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:46:36 +0100 Subject: [PATCH 070/177] Committed suggestion to integrations/clickup/.port/spec.yaml Co-authored-by: Tom Tankilevitch <59158507+Tankilevitch@users.noreply.github.com> --- integrations/clickup/.port/spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index 8815f7203f..f99fe4af98 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -23,7 +23,7 @@ configurations: description: This is to filter archived projects. If set to true, archived projects will be included in the export. If set to false, archived projects will be excluded from the export. Default is false. type: boolean required: false - default: "false" + default: false - name: appHost required: false type: url From 9dde50760f23cd58ce13de9ec79a07e3bc792e86 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:49:28 +0100 Subject: [PATCH 071/177] Committed suggestion to integrations/clickup/main.py Co-authored-by: Tom Tankilevitch <59158507+Tankilevitch@users.noreply.github.com> --- integrations/clickup/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index c6f85b0083..4341d451ef 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -61,7 +61,7 @@ async def setup_application() -> None: async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() async for teams in clickup_client.get_clickup_teams(): - logger.info(f"Received team of length {len(teams)}") + logger.info(f"Received batch of {len(teams)} teams") yield teams From e6d69ab65340ed6f24a3130e8e751343a7b35c4a Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:45:24 +0100 Subject: [PATCH 072/177] Applied suggestions in review comments --- integrations/clickup/.port/spec.yaml | 1 + integrations/clickup/CHANGELOG.md | 5 +- integrations/clickup/client.py | 101 +++++++++++++++------------ integrations/clickup/main.py | 56 ++++++++------- 4 files changed, 89 insertions(+), 74 deletions(-) diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index f99fe4af98..9dc25b4033 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -7,6 +7,7 @@ features: resources: - kind: issue - kind: project + - kind: space - kind: team configurations: - name: clickupPersonalToken diff --git a/integrations/clickup/CHANGELOG.md b/integrations/clickup/CHANGELOG.md index 863f9b0668..51f028c230 100644 --- a/integrations/clickup/CHANGELOG.md +++ b/integrations/clickup/CHANGELOG.md @@ -1,6 +1,5 @@ -# Port_Ocean 0.1.0 (2024-07-14) +# Port_Ocean 0.1.0 (2024-08-05) ### Features -- New Integration Module to export data from Clickup. Exports teams, projects and issues (0.1.0) - +- New Integration Module to export data from Clickup. Export teams, spaces, projects and issues diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index 08da0459a9..bde1c7b813 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -140,20 +140,6 @@ async def _get_spaces_in_team( ) ).get("spaces", []) - @cache_iterator_result() - async def _get_folders_in_space( - self, team_id: str - ) -> AsyncGenerator[List[dict[str, Any]], None]: - """Get all folders in a space.""" - async for spaces in self._get_spaces_in_team(team_id): - for space in spaces: - yield ( - await self._send_api_request( - f"{self.api_url}/space/{space.get('id')}/folder", - {"is_archived": self.is_archived}, - ) - ).get("folders") - async def get_all_spaces(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all spaces across all teams.""" async for teams in self.get_clickup_teams(): @@ -161,35 +147,50 @@ async def get_all_spaces(self) -> AsyncGenerator[List[dict[str, Any]], None]: async for spaces in self._get_spaces_in_team(team.get("id")): yield [{**space, TEAM_OBJECT: team} for space in spaces] - async def get_folder_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: - """Get all projects with a folder parent.""" - async for teams in self.get_clickup_teams(): - for team in teams: - async for folders in self._get_folders_in_space(team.get("id")): - for folder in folders: - projects = ( - await self._send_api_request( - f"{self.api_url}/folder/{folder.get('id')}/list", - {"is_archived": self.is_archived}, - ) - ).get("lists") - yield [{**project, TEAM_OBJECT: team} for project in projects] - - async def get_folderless_projects( - self, + @cache_iterator_result() + async def _get_folders_in_space( + self, space_id: str ) -> AsyncGenerator[List[dict[str, Any]], None]: - """Get all projects without a folder parent.""" + """Get all folders in a space.""" + yield ( + await self._send_api_request( + f"{self.api_url}/space/{space_id}/folder", + {"is_archived": self.is_archived}, + ) + ).get("folders") + + async def _fetch_projects( + self, parent_type: str, parent_id: str + ) -> List[dict[str, Any]]: + """Fetch projects based on the parent type and id.""" + url = f"{self.api_url}/{parent_type}/{parent_id}/list" + response = await self._send_api_request(url, {"is_archived": self.is_archived}) + return response.get("lists", []) + + async def get_all_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: + """Get all projects, both foldered and folderless.""" async for teams in self.get_clickup_teams(): for team in teams: async for spaces in self._get_spaces_in_team(team.get("id")): for space in spaces: - projects = ( - await self._send_api_request( - f"{self.api_url}/space/{space.get('id')}/list", - {"is_archived": self.is_archived}, - ) - ).get("lists") - yield [{**project, TEAM_OBJECT: team} for project in projects] + folderless_projects = await self._fetch_projects( + "space", space.get("id") + ) + yield [ + {**project, TEAM_OBJECT: team} + for project in folderless_projects + ] + async for folders in self._get_folders_in_space( + space.get("id") + ): + for folder in folders: + projects = await self._fetch_projects( + "folder", folder.get("id") + ) + yield [ + {**project, TEAM_OBJECT: team} + for project in projects + ] async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all issues in a project.""" @@ -204,28 +205,35 @@ async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], Non break page += 1 - async def get_single_space(self, space_id: str) -> Optional[Dict[str, Any]]: + async def get_single_space( + self, space_id: str, team_id: str + ) -> Optional[Dict[str, Any]]: """Get a single space by space_id.""" - async for spaces in self.get_all_spaces(): + async for spaces in self._get_spaces_in_team(team_id): for space in spaces: if space["id"] == space_id: - return space - logger.warning(f"No matching space found for {space_id}.") + return {**space, TEAM_OBJECT: {"id": team_id}} + logger.warning(f"No matching space found for {space_id}") return None - async def get_single_project(self, list_id: str) -> Optional[Dict[str, Any]]: + async def get_single_project( + self, list_id: str, team_id: str + ) -> Optional[Dict[str, Any]]: """Get a single project by list_id.""" - return await self._send_api_request(f"{self.api_url}/list/{list_id}") + response = await self._send_api_request(f"{self.api_url}/list/{list_id}") + return {**response, TEAM_OBJECT: {"id": team_id}} async def get_single_issue(self, task_id: str) -> dict[str, Any]: """Get a single issue by task_id.""" return await self._send_api_request(f"{self.api_url}/task/{task_id}") - async def create_clickup_webhook(self, team_id: str, app_host: str) -> None: + async def create_clickup_webhook( + self, team_id: str, app_host: str + ) -> Dict[str, Any]: """ Create a new webhook for a given team. """ - await self._send_api_request( + response = await self._send_api_request( f"{self.api_url}/team/{team_id}/webhook", method="POST", json_data={ @@ -234,6 +242,7 @@ async def create_clickup_webhook(self, team_id: str, app_host: str) -> None: }, ) logger.info("Webhook created successfully") + return response async def get_clickup_webhooks(self, team_id: str) -> list[dict[str, Any]]: """ diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 4341d451ef..777268e0c1 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -17,6 +17,8 @@ "spaceDeleted": "unregister", } +WEBHOOK_TEAM_MAP = {} + class ObjectKind(StrEnum): TEAM = "team" @@ -42,19 +44,22 @@ async def setup_application() -> None: "Without setting up the webhook, you will have to manually initiate resync to get updates from ClickUp." ) return - clickup_client = await init_client() # Await the initialization of the client + clickup_client = await init_client() async for teams in clickup_client.get_clickup_teams(): for team in teams: webhooks = await clickup_client.get_clickup_webhooks(team["id"]) - webhook_exists = any( - config["endpoint"] == f"{app_host}/integration/webhook" - for config in webhooks - ) - if webhook_exists: - logger.info(f"Webhook already exists for team {team['id']}") - else: - logger.info(f"Creating webhook for team {team['id']}") - await clickup_client.create_clickup_webhook(team["id"], app_host) + for webhook in webhooks: + if webhook["endpoint"] == f"{app_host}/integration/webhook": + logger.info(f"Webhook already exists for team {team['id']}") + WEBHOOK_TEAM_MAP[webhook["id"]] = team["id"] + break + else: + logger.info(f"Creating webhook for team {team['id']}") + webhook = await clickup_client.create_clickup_webhook( + team["id"], app_host + ) + WEBHOOK_TEAM_MAP[webhook["id"]] = team["id"] + logger.warning(f"Webhook team map: {WEBHOOK_TEAM_MAP}") @ocean.on_resync(ObjectKind.TEAM) @@ -69,22 +74,15 @@ async def on_resync_teams(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: async def on_resync_spaces(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() async for spaces in clickup_client.get_all_spaces(): - logger.info(f"Received space batch with {len(spaces)} spaces") + logger.info(f"Received batch of {len(spaces)} spaces") yield spaces @ocean.on_resync(ObjectKind.PROJECT) async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() - async for folderless_projects in clickup_client.get_folderless_projects(): - logger.info( - f"Received folderless project batch with {len(folderless_projects)} projects" - ) - yield folderless_projects - async for projects in clickup_client.get_folder_projects(): - logger.info( - f"Received a batch of project in folders with {len(projects)} projects" - ) + async for projects in clickup_client.get_all_projects(): + logger.info(f"Received batch of {len(projects)} projects") yield projects @@ -92,19 +90,24 @@ async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() async for issues in clickup_client.get_paginated_issues(): - logger.info(f"Received issue batch with {len(issues)} issues") + logger.info(f"Received batch of {len(issues)} issues") yield issues async def handle_register( - clickup_client: Any, entity_id: str, kind: ObjectKind, event_type: str + clickup_client: Any, + entity_id: str, + kind: ObjectKind, + event_type: str, + webhook_id: str, ) -> None: + team_id = WEBHOOK_TEAM_MAP.get(webhook_id) if kind == ObjectKind.ISSUE: entity = await clickup_client.get_single_issue(entity_id) elif kind == ObjectKind.PROJECT: - entity = await clickup_client.get_single_project(entity_id) + entity = await clickup_client.get_single_project(entity_id, team_id) else: - entity = await clickup_client.get_single_space(entity_id) + entity = await clickup_client.get_single_space(entity_id, team_id) if entity: await ocean.register_raw(kind, [entity]) @@ -137,6 +140,7 @@ async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: } event_type = data["event"] + webhook_id = data["webhook_id"] action = "unregister" if "Deleted" in event_type else "register" for key, kind in event_handlers.items(): @@ -146,7 +150,9 @@ async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: logger.error(f"No {key}_id found in data for event {event_type}") continue if action == "register": - await handle_register(clickup_client, entity_id, kind, event_type) + await handle_register( + clickup_client, entity_id, kind, event_type, webhook_id + ) else: await handle_unregister(entity_id, kind, event_type) break From 5138b5a07d65563d9f1aabb1a8f0e6d60adc1726 Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:21:08 +0100 Subject: [PATCH 073/177] Update integrations/clickup/pyproject.toml Co-authored-by: omby8888 <160610297+omby8888@users.noreply.github.com> --- integrations/clickup/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml index 054f12696c..01f8a63322 100644 --- a/integrations/clickup/pyproject.toml +++ b/integrations/clickup/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "clickup" -version = "0.1.0" +version = "0.1.0-beta" description = "Integration module for ClickUp" authors = ["Iyanuoluwa Adebayo "] From b1b3be0c8a9906b892ce6336fa623b3ed9d8cc1a Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:21:19 +0100 Subject: [PATCH 074/177] Update integrations/clickup/CHANGELOG.md Co-authored-by: omby8888 <160610297+omby8888@users.noreply.github.com> --- integrations/clickup/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/clickup/CHANGELOG.md b/integrations/clickup/CHANGELOG.md index 51f028c230..2ae8ebcc45 100644 --- a/integrations/clickup/CHANGELOG.md +++ b/integrations/clickup/CHANGELOG.md @@ -1,4 +1,4 @@ -# Port_Ocean 0.1.0 (2024-08-05) +# Port_Ocean 0.1.0-beta (2024-08-05) ### Features From 9f61ef06902fbb445dfd92a0b16ac8549214bb09 Mon Sep 17 00:00:00 2001 From: Iyanuoluwa Adebayo Date: Wed, 21 Aug 2024 08:03:29 +0100 Subject: [PATCH 075/177] Attended to reviewer's suggestions - Renamed issue to task to follow clickup naming - Made links in spec.yaml open in new tabs - Added support for filtering data by workspace id - Separated webhook logic into webhooks.py - Updated to latest port-ocean - Added sample unit test --- .../clickup/.port/resources/blueprints.json | 34 ++--- .../.port/resources/port-app-config.yaml | 6 +- integrations/clickup/.port/spec.yaml | 12 +- integrations/clickup/CHANGELOG.md | 2 +- integrations/clickup/client.py | 26 +++- integrations/clickup/main.py | 131 ++---------------- integrations/clickup/poetry.lock | 8 +- integrations/clickup/pyproject.toml | 2 +- integrations/clickup/tests/test_sample.py | 2 + integrations/clickup/webhook.py | 107 ++++++++++++++ 10 files changed, 178 insertions(+), 152 deletions(-) create mode 100644 integrations/clickup/tests/test_sample.py create mode 100644 integrations/clickup/webhook.py diff --git a/integrations/clickup/.port/resources/blueprints.json b/integrations/clickup/.port/resources/blueprints.json index 0e677c27a9..3caae81aa0 100644 --- a/integrations/clickup/.port/resources/blueprints.json +++ b/integrations/clickup/.port/resources/blueprints.json @@ -99,10 +99,10 @@ "format": "date-time", "description": "The end date of this project" }, - "totalIssues": { - "title": "Total Issues", + "totalTasks": { + "title": "Total Tasks", "type": "number", - "description": "The total number of issues in the project" + "description": "The total number of tasks in the project" } }, "required": [] @@ -125,57 +125,57 @@ } }, { - "identifier": "clickupIssue", - "title": "ClickUp Issue", + "identifier": "clickupTask", + "title": "ClickUp Task", "icon": "Clickup", "schema": { "properties": { "description": { - "title": "Issue Description", + "title": "Task Description", "type": "string", - "description": "Detailed description of the issue" + "description": "Detailed description of the task" }, "url": { - "title": "Issue URL", + "title": "Task URL", "type": "string", "format": "url", - "description": "URL to the issue in Clickup" + "description": "URL to the task in Clickup" }, "status": { "title": "Status", "type": "string", - "description": "The status of the issue" + "description": "The status of the task" }, "assignees": { "title": "Assignees", "type": "array", "items": { "type": "string", - "format": "email", - "description": "The users assigned to the issue" + "format": "user", + "description": "The users assigned to the task" } }, "creator": { "title": "Creator", "type": "string", - "description": "The user that created the issue", + "description": "The user that created the task", "format": "user" }, "priority": { "title": "Priority", "type": "string", - "description": "The priority of the issue" + "description": "The priority of the task" }, "created": { "title": "Created At", "type": "string", - "description": "The created datetime of the issue", + "description": "The created datetime of the task", "format": "date-time" }, "updated": { "title": "Updated At", "type": "string", - "description": "The updated datetime of the issue", + "description": "The updated datetime of the task", "format": "date-time" } }, @@ -187,7 +187,7 @@ "relations": { "project": { "title": "Project", - "description": "The Clickup project that manages this issue", + "description": "The Clickup project that manages this task", "target": "clickupProject", "required": false, "many": false diff --git a/integrations/clickup/.port/resources/port-app-config.yaml b/integrations/clickup/.port/resources/port-app-config.yaml index c06ba53c80..08664b5e50 100644 --- a/integrations/clickup/.port/resources/port-app-config.yaml +++ b/integrations/clickup/.port/resources/port-app-config.yaml @@ -42,16 +42,16 @@ resources: url: "\"https://app.clickup.com/\" + .__team.id + \"/v/b/li/\" + .id" startDate: if .start_date!=null then .start_date | tonumber / 1000 | todate else "" | todate end endDate: if .due_date!=null then .due_date | tonumber / 1000 | todate else "" | todate end - totalIssues: .task_count + totalTasks: .task_count relations: space: .space.id - - kind: issue + - kind: task selector: query: 'true' port: entity: mappings: - blueprint: '"clickupIssue"' + blueprint: '"clickupTask"' identifier: .id title: .name properties: diff --git a/integrations/clickup/.port/spec.yaml b/integrations/clickup/.port/spec.yaml index 9dc25b4033..7a69fb8cee 100644 --- a/integrations/clickup/.port/spec.yaml +++ b/integrations/clickup/.port/spec.yaml @@ -5,18 +5,18 @@ features: - type: exporter section: Project Management resources: - - kind: issue + - kind: task - kind: project - kind: space - kind: team configurations: - name: clickupPersonalToken - description: The ClickUp personal token used for authentication. To create a personal token, see the ClickUp documentation + description: The ClickUp personal token used for authentication. To create a personal token, see the ClickUp documentation required: true type: string sensitive: true - name: clickupBaseUrl - description: The Clickup Base URL. Defaults to https://api.clickup.com when not specified + description: The Clickup Base URL. Defaults to https://api.clickup.com when not specified type: url required: false default: https://api.clickup.com @@ -28,4 +28,8 @@ configurations: - name: appHost required: false type: url - description: "The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Clickup" + description: The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Clickup + - name: workspaceIds + description: A comma-separated list of workspace ids to filter. Integration will import all workspaces on the credentials if not provided. To find your workspace ids, see the ClickUp documentation + required: false + type: string diff --git a/integrations/clickup/CHANGELOG.md b/integrations/clickup/CHANGELOG.md index 2ae8ebcc45..39b37e36cb 100644 --- a/integrations/clickup/CHANGELOG.md +++ b/integrations/clickup/CHANGELOG.md @@ -2,4 +2,4 @@ ### Features -- New Integration Module to export data from Clickup. Export teams, spaces, projects and issues +- New Integration Module to export data from Clickup. Export teams, spaces, projects and tasks diff --git a/integrations/clickup/client.py b/integrations/clickup/client.py index bde1c7b813..1109ee4149 100644 --- a/integrations/clickup/client.py +++ b/integrations/clickup/client.py @@ -31,12 +31,23 @@ class ClickupClient: """Clickup client to interact with Clickup API.""" - def __init__(self, clickup_url: str, clickup_token: str, is_archived: bool): + def __init__( + self, + clickup_url: str, + clickup_token: str, + is_archived: bool, + workspace_ids: Optional[str] = None, + ) -> None: self.clickup_token = clickup_token self.api_url = f"{clickup_url}/api/v2" self.client = http_async_client self.client.timeout = Timeout(60) self.is_archived = is_archived + self.workspace_ids = ( + [ws_id.strip() for ws_id in workspace_ids.split(",")] + if workspace_ids + else [] + ) @property def api_headers(self) -> dict[str, Any]: @@ -126,7 +137,10 @@ async def _send_api_request( @cache_iterator_result() async def get_clickup_teams(self) -> AsyncGenerator[List[dict[str, Any]], None]: """Get all Clickup teams.""" - yield (await self._send_api_request(f"{self.api_url}/team")).get("teams", []) + teams = (await self._send_api_request(f"{self.api_url}/team")).get("teams", []) + if self.workspace_ids: + teams = [team for team in teams if team["id"] in self.workspace_ids] + yield teams @cache_iterator_result() async def _get_spaces_in_team( @@ -192,8 +206,8 @@ async def get_all_projects(self) -> AsyncGenerator[List[dict[str, Any]], None]: for project in projects ] - async def get_paginated_issues(self) -> AsyncGenerator[List[dict[str, Any]], None]: - """Get all issues in a project.""" + async def get_paginated_tasks(self) -> AsyncGenerator[List[dict[str, Any]], None]: + """Get all tasks in a project.""" async for teams in self.get_clickup_teams(): for team in teams: url = f"{self.api_url}/team/{team.get('id')}/task" @@ -223,8 +237,8 @@ async def get_single_project( response = await self._send_api_request(f"{self.api_url}/list/{list_id}") return {**response, TEAM_OBJECT: {"id": team_id}} - async def get_single_issue(self, task_id: str) -> dict[str, Any]: - """Get a single issue by task_id.""" + async def get_single_task(self, task_id: str) -> dict[str, Any]: + """Get a single task by task_id.""" return await self._send_api_request(f"{self.api_url}/task/{task_id}") async def create_clickup_webhook( diff --git a/integrations/clickup/main.py b/integrations/clickup/main.py index 777268e0c1..d6b888ca6a 100644 --- a/integrations/clickup/main.py +++ b/integrations/clickup/main.py @@ -1,39 +1,13 @@ -from enum import StrEnum from typing import Any, Dict from loguru import logger from port_ocean.context.ocean import ocean from port_ocean.core.ocean_types import ASYNC_GENERATOR_RESYNC_TYPE -from client import ClickupClient - -EVENT_ACTIONS = { - "listCreated": "register", - "listUpdated": "register", - "listDeleted": "unregister", - "taskCreated": "register", - "taskUpdated": "register", - "taskDeleted": "unregister", - "spaceCreated": "register", - "spaceUpdated": "register", - "spaceDeleted": "unregister", -} - -WEBHOOK_TEAM_MAP = {} - - -class ObjectKind(StrEnum): - TEAM = "team" - SPACE = "space" - PROJECT = "project" - ISSUE = "issue" - - -async def init_client() -> ClickupClient: - client = ClickupClient( - ocean.integration_config["clickup_base_url"], - ocean.integration_config["clickup_personal_token"], - ocean.integration_config["include_archived_projects"], - ) - return client +from webhook import ( + handle_webhook_creation, + process_webhook_request, + init_client, + ObjectKind, +) async def setup_application() -> None: @@ -44,22 +18,7 @@ async def setup_application() -> None: "Without setting up the webhook, you will have to manually initiate resync to get updates from ClickUp." ) return - clickup_client = await init_client() - async for teams in clickup_client.get_clickup_teams(): - for team in teams: - webhooks = await clickup_client.get_clickup_webhooks(team["id"]) - for webhook in webhooks: - if webhook["endpoint"] == f"{app_host}/integration/webhook": - logger.info(f"Webhook already exists for team {team['id']}") - WEBHOOK_TEAM_MAP[webhook["id"]] = team["id"] - break - else: - logger.info(f"Creating webhook for team {team['id']}") - webhook = await clickup_client.create_clickup_webhook( - team["id"], app_host - ) - WEBHOOK_TEAM_MAP[webhook["id"]] = team["id"] - logger.warning(f"Webhook team map: {WEBHOOK_TEAM_MAP}") + await handle_webhook_creation(app_host) @ocean.on_resync(ObjectKind.TEAM) @@ -86,79 +45,19 @@ async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: yield projects -@ocean.on_resync(ObjectKind.ISSUE) -async def on_resync_issues(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: +@ocean.on_resync(ObjectKind.TASK) +async def on_resync_tasks(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: clickup_client = await init_client() - async for issues in clickup_client.get_paginated_issues(): - logger.info(f"Received batch of {len(issues)} issues") - yield issues - - -async def handle_register( - clickup_client: Any, - entity_id: str, - kind: ObjectKind, - event_type: str, - webhook_id: str, -) -> None: - team_id = WEBHOOK_TEAM_MAP.get(webhook_id) - if kind == ObjectKind.ISSUE: - entity = await clickup_client.get_single_issue(entity_id) - elif kind == ObjectKind.PROJECT: - entity = await clickup_client.get_single_project(entity_id, team_id) - else: - entity = await clickup_client.get_single_space(entity_id, team_id) - - if entity: - await ocean.register_raw(kind, [entity]) - logger.info(f"Registered {kind} for event {event_type}") - else: - logger.error(f"Handler returned None for entity_id {entity_id}") - - -async def handle_unregister(entity_id: str, kind: ObjectKind, event_type: str) -> None: - try: - await ocean.unregister_raw(kind, [{"id": entity_id}]) - logger.info(f"Unregistered {kind} for event {event_type}") - except Exception as e: - logger.error(f"Exception {e} occurred while attempting to unregister raw") + async for tasks in clickup_client.get_paginated_tasks(): + logger.info(f"Received batch of {len(tasks)} tasks") + yield tasks @ocean.router.post("/webhook") async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: - """ - Handle the webhook request from ClickUp. - Events are mapped to the appropriate actions in event_handlers. - """ - clickup_client = await init_client() - logger.info(f"Received webhook event of type: {data.get('event')}") - - event_handlers = { - "task": ObjectKind.ISSUE, - "list": ObjectKind.PROJECT, - "space": ObjectKind.SPACE, - } - - event_type = data["event"] - webhook_id = data["webhook_id"] - action = "unregister" if "Deleted" in event_type else "register" - - for key, kind in event_handlers.items(): - if key in event_type: - entity_id = data.get(f"{key}_id") - if not entity_id: - logger.error(f"No {key}_id found in data for event {event_type}") - continue - if action == "register": - await handle_register( - clickup_client, entity_id, kind, event_type, webhook_id - ) - else: - await handle_unregister(entity_id, kind, event_type) - break - - logger.info("Webhook event processed") - return {"ok": True} + logger.info(f"Received webhook event of type: {data}") + response = await process_webhook_request(data) + return response @ocean.on_start() diff --git a/integrations/clickup/poetry.lock b/integrations/clickup/poetry.lock index 182e25c576..c6c761c427 100644 --- a/integrations/clickup/poetry.lock +++ b/integrations/clickup/poetry.lock @@ -808,13 +808,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.11" +version = "0.9.14" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.11-py3-none-any.whl", hash = "sha256:6bd8ec8e17a4ae3a4e9da5f283d93368e7ec4756461fe0abcdd1aba8aa5c9764"}, - {file = "port_ocean-0.9.11.tar.gz", hash = "sha256:3fbc0206b49e942be5a11cc891cf1f7f7c746bfbf0c5d3e19b13b05af6c901f5"}, + {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, + {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, ] [package.dependencies] @@ -1427,4 +1427,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "8f6eb86d16ca414b19f7f7e37807328795e23f1d5c25a735cfa0474d5b599844" +content-hash = "7d77d47b9595fd18794e44b7afe844dae3f076d44c80545894c11e649b214a0f" diff --git a/integrations/clickup/pyproject.toml b/integrations/clickup/pyproject.toml index 01f8a63322..51cb7b6243 100644 --- a/integrations/clickup/pyproject.toml +++ b/integrations/clickup/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Iyanuoluwa Adebayo "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {extras = ["cli"], version = "^0.9.11"} +port_ocean = {extras = ["cli"], version = "^0.9.14"} [tool.poetry.group.dev.dependencies] pytest = "^7.2" diff --git a/integrations/clickup/tests/test_sample.py b/integrations/clickup/tests/test_sample.py new file mode 100644 index 0000000000..dc80e299c8 --- /dev/null +++ b/integrations/clickup/tests/test_sample.py @@ -0,0 +1,2 @@ +def test_example() -> None: + assert 1 == 1 diff --git a/integrations/clickup/webhook.py b/integrations/clickup/webhook.py new file mode 100644 index 0000000000..fac791c87e --- /dev/null +++ b/integrations/clickup/webhook.py @@ -0,0 +1,107 @@ +from enum import StrEnum +from typing import Any, Dict +from loguru import logger +from port_ocean.context.ocean import ocean +from client import ClickupClient + + +class ObjectKind(StrEnum): + TEAM = "team" + SPACE = "space" + PROJECT = "project" + TASK = "task" + + +async def init_client() -> ClickupClient: + client = ClickupClient( + ocean.integration_config["clickup_base_url"], + ocean.integration_config["clickup_personal_token"], + ocean.integration_config["include_archived_projects"], + ocean.integration_config.get("workspace_ids"), + ) + return client + + +WEBHOOK_TEAM_MAP = {} + + +async def handle_webhook_creation(app_host: str) -> None: + clickup_client = await init_client() + async for teams in clickup_client.get_clickup_teams(): + for team in teams: + webhooks = await clickup_client.get_clickup_webhooks(team["id"]) + webhook_found = False + for webhook in webhooks: + if webhook["endpoint"] == f"{app_host}/integration/webhook": + logger.info(f"Webhook already exists for team {team['id']}") + WEBHOOK_TEAM_MAP[webhook["id"]] = team["id"] + webhook_found = True + break + if not webhook_found: + logger.info(f"Creating webhook for team {team['id']}") + webhook = await clickup_client.create_clickup_webhook( + team["id"], app_host + ) + WEBHOOK_TEAM_MAP[webhook["id"]] = team["id"] + + +async def handle_register( + clickup_client: Any, + entity_id: str, + kind: ObjectKind, + event_type: str, + webhook_id: str, +) -> None: + team_id = WEBHOOK_TEAM_MAP.get(webhook_id) + if kind == ObjectKind.TASK: + entity = await clickup_client.get_single_task(entity_id) + elif kind == ObjectKind.PROJECT: + entity = await clickup_client.get_single_project(entity_id, team_id) + else: + entity = await clickup_client.get_single_space(entity_id, team_id) + + if entity: + await ocean.register_raw(kind, [entity]) + logger.info(f"Registered {kind} for event {event_type}") + else: + logger.error(f"Handler returned None for entity_id {entity_id}") + + +async def handle_unregister(entity_id: str, kind: ObjectKind, event_type: str) -> None: + try: + await ocean.unregister_raw(kind, [{"id": entity_id}]) + logger.info(f"Unregistered {kind} for event {event_type}") + except Exception as e: + logger.error(f"Exception {e} occurred while attempting to unregister raw") + + +async def process_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: + """ + Handle the webhook request from ClickUp. + Events are mapped to the appropriate actions in event_handlers. + """ + clickup_client = await init_client() + event_handlers = { + "task": ObjectKind.TASK, + "list": ObjectKind.PROJECT, + "space": ObjectKind.SPACE, + } + event_type = data["event"] + webhook_id = data["webhook_id"] + + for key, kind in event_handlers.items(): + if key in event_type: + entity_id = data.get(f"{key}_id") + if not entity_id: + logger.error(f"No {key}_id found in data for event {event_type}") + continue + if "Deleted" in event_type: + await handle_unregister(entity_id, kind, event_type) + else: + await handle_register( + clickup_client, entity_id, kind, event_type, webhook_id + ) + break + + logger.info("Webhook event processed") + return {"ok": True} From 531c1035dc3f0c274ef8310d20045cd4eb62a939 Mon Sep 17 00:00:00 2001 From: Port Bot <110599342+portmachineuser@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:39:36 +0300 Subject: [PATCH 076/177] Apply Ocean version 0.10.0 to all integrations (#937) This PR was automatically created by a GitHub Action. ## What does this PR do? Apply Ocean version 0.10.0 to all integrations ## How should this be manually tested? ./scripts/bump-all.sh ^0.10.0 --------- Co-authored-by: GitHub Action --- integrations/argocd/CHANGELOG.md | 8 ++++++++ integrations/argocd/poetry.lock | 8 ++++---- integrations/argocd/pyproject.toml | 4 ++-- integrations/aws/CHANGELOG.md | 8 ++++++++ integrations/aws/poetry.lock | 8 ++++---- integrations/aws/pyproject.toml | 4 ++-- integrations/azure-devops/CHANGELOG.md | 9 +++++++++ integrations/azure-devops/poetry.lock | 8 ++++---- integrations/azure-devops/pyproject.toml | 4 ++-- integrations/azure/CHANGELOG.md | 7 +++++++ integrations/azure/poetry.lock | 8 ++++---- integrations/azure/pyproject.toml | 4 ++-- integrations/datadog/CHANGELOG.md | 8 ++++++++ integrations/datadog/poetry.lock | 8 ++++---- integrations/datadog/pyproject.toml | 4 ++-- integrations/dynatrace/CHANGELOG.md | 8 ++++++++ integrations/dynatrace/poetry.lock | 8 ++++---- integrations/dynatrace/pyproject.toml | 4 ++-- integrations/firehydrant/CHANGELOG.md | 8 ++++++++ integrations/firehydrant/poetry.lock | 8 ++++---- integrations/firehydrant/pyproject.toml | 4 ++-- integrations/gcp/CHANGELOG.md | 8 ++++++++ integrations/gcp/poetry.lock | 8 ++++---- integrations/gcp/pyproject.toml | 4 ++-- integrations/gitlab/CHANGELOG.md | 8 ++++++++ integrations/gitlab/poetry.lock | 10 +++++----- integrations/gitlab/pyproject.toml | 4 ++-- integrations/jenkins/CHANGELOG.md | 8 ++++++++ integrations/jenkins/poetry.lock | 8 ++++---- integrations/jenkins/pyproject.toml | 4 ++-- integrations/jira/CHANGELOG.md | 8 ++++++++ integrations/jira/poetry.lock | 8 ++++---- integrations/jira/pyproject.toml | 4 ++-- integrations/kafka/CHANGELOG.md | 8 ++++++++ integrations/kafka/poetry.lock | 8 ++++---- integrations/kafka/pyproject.toml | 4 ++-- integrations/kubecost/CHANGELOG.md | 8 ++++++++ integrations/kubecost/poetry.lock | 8 ++++---- integrations/kubecost/pyproject.toml | 4 ++-- integrations/launchdarkly/CHANGELOG.md | 8 ++++++++ integrations/launchdarkly/poetry.lock | 8 ++++---- integrations/launchdarkly/pyproject.toml | 4 ++-- integrations/linear/CHANGELOG.md | 8 ++++++++ integrations/linear/poetry.lock | 8 ++++---- integrations/linear/pyproject.toml | 4 ++-- integrations/newrelic/CHANGELOG.md | 8 ++++++++ integrations/newrelic/poetry.lock | 8 ++++---- integrations/newrelic/pyproject.toml | 4 ++-- integrations/opencost/CHANGELOG.md | 8 ++++++++ integrations/opencost/poetry.lock | 8 ++++---- integrations/opencost/pyproject.toml | 4 ++-- integrations/opsgenie/CHANGELOG.md | 8 ++++++++ integrations/opsgenie/poetry.lock | 8 ++++---- integrations/opsgenie/pyproject.toml | 4 ++-- integrations/pagerduty/CHANGELOG.md | 8 ++++++++ integrations/pagerduty/poetry.lock | 8 ++++---- integrations/pagerduty/pyproject.toml | 4 ++-- integrations/sentry/CHANGELOG.md | 8 ++++++++ integrations/sentry/poetry.lock | 8 ++++---- integrations/sentry/pyproject.toml | 4 ++-- integrations/servicenow/CHANGELOG.md | 8 ++++++++ integrations/servicenow/poetry.lock | 8 ++++---- integrations/servicenow/pyproject.toml | 4 ++-- integrations/snyk/CHANGELOG.md | 8 ++++++++ integrations/snyk/poetry.lock | 8 ++++---- integrations/snyk/pyproject.toml | 4 ++-- integrations/sonarqube/CHANGELOG.md | 8 ++++++++ integrations/sonarqube/poetry.lock | 8 ++++---- integrations/sonarqube/pyproject.toml | 4 ++-- integrations/statuspage/CHANGELOG.md | 8 ++++++++ integrations/statuspage/poetry.lock | 8 ++++---- integrations/statuspage/pyproject.toml | 4 ++-- integrations/terraform-cloud/CHANGELOG.md | 8 ++++++++ integrations/terraform-cloud/poetry.lock | 8 ++++---- integrations/terraform-cloud/pyproject.toml | 4 ++-- integrations/wiz/CHANGELOG.md | 8 ++++++++ integrations/wiz/poetry.lock | 8 ++++---- integrations/wiz/pyproject.toml | 4 ++-- 78 files changed, 365 insertions(+), 157 deletions(-) diff --git a/integrations/argocd/CHANGELOG.md b/integrations/argocd/CHANGELOG.md index 6cf3796bd3..e3606c481f 100644 --- a/integrations/argocd/CHANGELOG.md +++ b/integrations/argocd/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.77 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.76 (2024-08-20) diff --git a/integrations/argocd/poetry.lock b/integrations/argocd/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/argocd/poetry.lock +++ b/integrations/argocd/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/argocd/pyproject.toml b/integrations/argocd/pyproject.toml index 0c2e540c12..4833c58ace 100644 --- a/integrations/argocd/pyproject.toml +++ b/integrations/argocd/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "argocd" -version = "0.1.76" +version = "0.1.77" description = "Argo CD integration powered by Ocean" authors = ["Isaac Coffie "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # Uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/aws/CHANGELOG.md b/integrations/aws/CHANGELOG.md index 970e975a9d..f2754e8326 100644 --- a/integrations/aws/CHANGELOG.md +++ b/integrations/aws/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.2.29 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.2.28 (2024-08-20) diff --git a/integrations/aws/poetry.lock b/integrations/aws/poetry.lock index 14b20f7ed4..5b3965dd40 100644 --- a/integrations/aws/poetry.lock +++ b/integrations/aws/poetry.lock @@ -2213,13 +2213,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -4106,4 +4106,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "620e6037bd4dcd9a6baca4eea16b69de9b32cc48f1da5b31b999bb53fc95fc24" +content-hash = "cffe956e1196b3398ebe2c6462d60eec50a0508a992bd38fb96283a972a72dc8" diff --git a/integrations/aws/pyproject.toml b/integrations/aws/pyproject.toml index 77694f8f5f..3efba85e53 100644 --- a/integrations/aws/pyproject.toml +++ b/integrations/aws/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "aws" -version = "0.2.28" +version = "0.2.29" description = "This integration will map all your resources in all the available accounts to your Port entities" authors = ["Shalev Avhar ", "Erik Zaadi "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} python-dotenv = "^1.0.1" aioboto3 = "^12.4.0" boto3-stubs = {version = "1.34.76", extras = ["acm", "apigateway", "appconfig", "athena", "cloudcontrol", "cloudformation", "cloudwatch", "dynamodb", "ec2", "ec2-instance-connect", "ecr", "ecs", "elasticache", "elb", "elbv2", "events", "iam", "lambda", "logs", "organizations", "rds", "route53", "s3", "sagemaker", "secretsmanager", "sns", "sqs", "ssm", "sts"]} diff --git a/integrations/azure-devops/CHANGELOG.md b/integrations/azure-devops/CHANGELOG.md index 5ec9867a22..36b3dd5c22 100644 --- a/integrations/azure-devops/CHANGELOG.md +++ b/integrations/azure-devops/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.55 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.54 (2024-08-21) ### Features diff --git a/integrations/azure-devops/poetry.lock b/integrations/azure-devops/poetry.lock index 5df9b439d6..98babac290 100644 --- a/integrations/azure-devops/poetry.lock +++ b/integrations/azure-devops/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1875,4 +1875,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "080230c675b0dfff9b4b5fb4258ec3864828ad3154d31280e24237e73193eb78" +content-hash = "d0c53b7a34ef6bb1289e6da1a855ff86e54502cc27ac0be9db527909d835e678" diff --git a/integrations/azure-devops/pyproject.toml b/integrations/azure-devops/pyproject.toml index 3479388fba..f662022898 100644 --- a/integrations/azure-devops/pyproject.toml +++ b/integrations/azure-devops/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "azure-devops" -version = "0.1.54" +version = "0.1.55" description = "An Azure Devops Ocean integration" authors = ["Matan Geva "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # Uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/azure/CHANGELOG.md b/integrations/azure/CHANGELOG.md index 3d049a05c8..056fb42869 100644 --- a/integrations/azure/CHANGELOG.md +++ b/integrations/azure/CHANGELOG.md @@ -1,3 +1,10 @@ +0.1.81 (2024-08-22) + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + 0.1.80 (2024-08-20) ### Improvements diff --git a/integrations/azure/poetry.lock b/integrations/azure/poetry.lock index a3ff979787..95904ae21b 100644 --- a/integrations/azure/poetry.lock +++ b/integrations/azure/poetry.lock @@ -1594,13 +1594,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -2718,4 +2718,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "22b0842a786c8cd0570e6ffc0f14a2163912eb27c0578fb8269da3321a67197b" +content-hash = "7f3c0bad23f444312761996935dc5579d799fca7e05bae3f280a19f3da259f99" diff --git a/integrations/azure/pyproject.toml b/integrations/azure/pyproject.toml index cb7ca0e613..16375c396d 100644 --- a/integrations/azure/pyproject.toml +++ b/integrations/azure/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "azure" -version = "0.1.80" +version = "0.1.81" description = "Azure integration" authors = ["Tom Tankilevitch "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} # due to patching the azure-mgmt-resource package, we need to use a specific version azure-mgmt-resource = "23.0.1" azure-identity = "^1.13.0" diff --git a/integrations/datadog/CHANGELOG.md b/integrations/datadog/CHANGELOG.md index 5bfb106e45..a11c57159a 100644 --- a/integrations/datadog/CHANGELOG.md +++ b/integrations/datadog/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.30 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.29 (2024-08-20) diff --git a/integrations/datadog/poetry.lock b/integrations/datadog/poetry.lock index 322c0b146c..cea7c2b140 100644 --- a/integrations/datadog/poetry.lock +++ b/integrations/datadog/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "53e16cc569f00dd2f669f869b34c0ecc6d628e91865ee089f8972ea5a11e9736" +content-hash = "630bd136b54c544ee4c923ef785a20b45a43401a8084a56e911f667dd989da75" diff --git a/integrations/datadog/pyproject.toml b/integrations/datadog/pyproject.toml index c37721c99a..30352fc12e 100644 --- a/integrations/datadog/pyproject.toml +++ b/integrations/datadog/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "datadog" -version = "0.1.29" +version = "0.1.30" description = "Datadog Ocean Integration" authors = ["Albert Luganga "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} loguru = "^0.7.2" [tool.poetry.group.dev.dependencies] diff --git a/integrations/dynatrace/CHANGELOG.md b/integrations/dynatrace/CHANGELOG.md index d213b1098d..f7ab801bbe 100644 --- a/integrations/dynatrace/CHANGELOG.md +++ b/integrations/dynatrace/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.43 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.42 (2024-08-20) diff --git a/integrations/dynatrace/poetry.lock b/integrations/dynatrace/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/dynatrace/poetry.lock +++ b/integrations/dynatrace/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/dynatrace/pyproject.toml b/integrations/dynatrace/pyproject.toml index 65ca8fd253..288edb0414 100644 --- a/integrations/dynatrace/pyproject.toml +++ b/integrations/dynatrace/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "dynatrace" -version = "0.1.42" +version = "0.1.43" description = "An integration used to import Dynatrace resources into Port" authors = ["Ayodeji Adeoti <>"] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/firehydrant/CHANGELOG.md b/integrations/firehydrant/CHANGELOG.md index ffb32b461c..49b6590dd5 100644 --- a/integrations/firehydrant/CHANGELOG.md +++ b/integrations/firehydrant/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.66 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.65 (2024-08-20) diff --git a/integrations/firehydrant/poetry.lock b/integrations/firehydrant/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/firehydrant/poetry.lock +++ b/integrations/firehydrant/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/firehydrant/pyproject.toml b/integrations/firehydrant/pyproject.toml index d4103c0d8c..949e7f63b3 100644 --- a/integrations/firehydrant/pyproject.toml +++ b/integrations/firehydrant/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "firehydrant" -version = "0.1.65" +version = "0.1.66" description = "FireHydrant Integration Powered by Ocean" authors = ["Isaac Coffie "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/gcp/CHANGELOG.md b/integrations/gcp/CHANGELOG.md index 7cf68474b8..34bbe6e081 100644 --- a/integrations/gcp/CHANGELOG.md +++ b/integrations/gcp/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.42 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.41 (2024-08-20) diff --git a/integrations/gcp/poetry.lock b/integrations/gcp/poetry.lock index ff061fd65e..6616bb6b2a 100644 --- a/integrations/gcp/poetry.lock +++ b/integrations/gcp/poetry.lock @@ -1210,13 +1210,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -2216,4 +2216,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "c2cdf9d9b41c8086eb8afc227f1143a8c235431230e4a836914de07c10bc39dc" +content-hash = "9242b4feb645946defd2140907f65608d672eb3d043713ac63a3b1a649507fbe" diff --git a/integrations/gcp/pyproject.toml b/integrations/gcp/pyproject.toml index 240f13f11d..a1421bc9dc 100644 --- a/integrations/gcp/pyproject.toml +++ b/integrations/gcp/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "gcp" -version = "0.1.41" +version = "0.1.42" description = "A GCP ocean integration" authors = ["Matan Geva "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} google-cloud-asset = "^3.25.1" google-cloud-pubsub = "^2.21.1" google-cloud-resource-manager = "^1.12.3" diff --git a/integrations/gitlab/CHANGELOG.md b/integrations/gitlab/CHANGELOG.md index 99b4745940..a5132a0c78 100644 --- a/integrations/gitlab/CHANGELOG.md +++ b/integrations/gitlab/CHANGELOG.md @@ -7,6 +7,14 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm +0.1.109 (2024-08-22) +==================== + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + 0.1.108 (2024-08-20) ==================== diff --git a/integrations/gitlab/poetry.lock b/integrations/gitlab/poetry.lock index 977970416c..59d0d672ef 100644 --- a/integrations/gitlab/poetry.lock +++ b/integrations/gitlab/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiofiles" @@ -909,13 +909,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1896,4 +1896,4 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "fa19c4a66cf429f3e619f3a7d6ed395bfb76633ea02f75953a913e457bf7ac89" +content-hash = "f9a4d9f54dbc4a04c65e691cba4da48bb0063a94a7176d5521f7b1c43dff26b0" diff --git a/integrations/gitlab/pyproject.toml b/integrations/gitlab/pyproject.toml index 49fd607830..71796827c1 100644 --- a/integrations/gitlab/pyproject.toml +++ b/integrations/gitlab/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "gitlab" -version = "0.1.108" +version = "0.1.109" description = "Gitlab integration for Port using Port-Ocean Framework" authors = ["Yair Siman-Tov "] @@ -10,7 +10,7 @@ aiofiles = "^0.6.0" python-gitlab = "^3.14.0" pathlib = "^1.0.1" jsonschema = "^4.17.3" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/jenkins/CHANGELOG.md b/integrations/jenkins/CHANGELOG.md index 1d37b6843e..0d1c734001 100644 --- a/integrations/jenkins/CHANGELOG.md +++ b/integrations/jenkins/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.48 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.47 (2024-08-20) diff --git a/integrations/jenkins/poetry.lock b/integrations/jenkins/poetry.lock index b168b42e77..a091cdf71e 100644 --- a/integrations/jenkins/poetry.lock +++ b/integrations/jenkins/poetry.lock @@ -945,13 +945,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1875,4 +1875,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "527fac7a015fc10ac7556aa71a4822b71885d8cecc1dd0aef3a9e785dde1eae6" +content-hash = "704292c44144066f4f0a32185827e4d0d36a6300740fbb74124710387f3eef20" diff --git a/integrations/jenkins/pyproject.toml b/integrations/jenkins/pyproject.toml index e38ba27d56..6e365d52cf 100644 --- a/integrations/jenkins/pyproject.toml +++ b/integrations/jenkins/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "jenkins" -version = "0.1.47" +version = "0.1.48" description = "Jenkins Integration to Port Ocean" authors = ["Albert Luganga "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} pip = "^23.3.1" python-dotenv = "^1.0.0" loguru = "^0.7.2" diff --git a/integrations/jira/CHANGELOG.md b/integrations/jira/CHANGELOG.md index f9564e13e5..cfcf182c81 100644 --- a/integrations/jira/CHANGELOG.md +++ b/integrations/jira/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.77 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.76 (2024-08-20) diff --git a/integrations/jira/poetry.lock b/integrations/jira/poetry.lock index bffed97c39..ae5878294f 100644 --- a/integrations/jira/poetry.lock +++ b/integrations/jira/poetry.lock @@ -933,13 +933,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1863,4 +1863,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "1a8b416d58532d9e777df7f01cfa6e5f3941904deb568638e74d4c8bdd9aed88" +content-hash = "8d36d82dd63e18f67aa9a0665b0c0c534f2e6a5784fa553dffc92fa81f0ec58f" diff --git a/integrations/jira/pyproject.toml b/integrations/jira/pyproject.toml index 210b105bbc..482f732850 100644 --- a/integrations/jira/pyproject.toml +++ b/integrations/jira/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "jira" -version = "0.1.76" +version = "0.1.77" description = "Integration to bring information from Jira into Port" authors = ["Mor Paz "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} httpx = "^0.24.1" [tool.poetry.group.dev.dependencies] diff --git a/integrations/kafka/CHANGELOG.md b/integrations/kafka/CHANGELOG.md index 92420ae3bb..450077a51f 100644 --- a/integrations/kafka/CHANGELOG.md +++ b/integrations/kafka/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.65 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.64 (2024-08-20) diff --git a/integrations/kafka/poetry.lock b/integrations/kafka/poetry.lock index c663e4dd45..bf64a88494 100644 --- a/integrations/kafka/poetry.lock +++ b/integrations/kafka/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "022e2c489d1d812e5bdb5784b5bdae0317db5adf89704762e022ad691c64f3ce" +content-hash = "3f7994affc7cbf7e1f2de75e4c2c1dbcc6570547b9e0a087cf2ea6e93e0575f7" diff --git a/integrations/kafka/pyproject.toml b/integrations/kafka/pyproject.toml index 2f29334ff7..1f9fb63c4b 100644 --- a/integrations/kafka/pyproject.toml +++ b/integrations/kafka/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "kafka" -version = "0.1.64" +version = "0.1.65" description = "Integration to import information from a Kafka cluster into Port. The integration supports importing metadata regarding the Kafka cluster, brokers and topics." authors = ["Tal Sabag "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} confluent-kafka = "^2.2.0" [tool.poetry.group.dev.dependencies] diff --git a/integrations/kubecost/CHANGELOG.md b/integrations/kubecost/CHANGELOG.md index c1da959ed5..b234895b61 100644 --- a/integrations/kubecost/CHANGELOG.md +++ b/integrations/kubecost/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.70 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.69 (2024-08-20) diff --git a/integrations/kubecost/poetry.lock b/integrations/kubecost/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/kubecost/poetry.lock +++ b/integrations/kubecost/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/kubecost/pyproject.toml b/integrations/kubecost/pyproject.toml index 76ba219e41..3cfced355d 100644 --- a/integrations/kubecost/pyproject.toml +++ b/integrations/kubecost/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "kubecost" -version = "0.1.69" +version = "0.1.70" description = "Kubecost integration powered by Ocean" authors = ["Isaac Coffie "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/launchdarkly/CHANGELOG.md b/integrations/launchdarkly/CHANGELOG.md index 03e18eef0e..4696a22b4d 100644 --- a/integrations/launchdarkly/CHANGELOG.md +++ b/integrations/launchdarkly/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.42 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.41 (2024-08-20) diff --git a/integrations/launchdarkly/poetry.lock b/integrations/launchdarkly/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/launchdarkly/poetry.lock +++ b/integrations/launchdarkly/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/launchdarkly/pyproject.toml b/integrations/launchdarkly/pyproject.toml index d13a7163c8..725a98e158 100644 --- a/integrations/launchdarkly/pyproject.toml +++ b/integrations/launchdarkly/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "launchdarkly" -version = "0.1.41" +version = "0.1.42" description = "Launchdarkly integration for Port" authors = ["Michael Armah "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/linear/CHANGELOG.md b/integrations/linear/CHANGELOG.md index f96ca6f0ba..6e21119c51 100644 --- a/integrations/linear/CHANGELOG.md +++ b/integrations/linear/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.28 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.27 (2024-08-20) diff --git a/integrations/linear/poetry.lock b/integrations/linear/poetry.lock index d8db3831fc..3cd7ca4f62 100644 --- a/integrations/linear/poetry.lock +++ b/integrations/linear/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "6b68730ae6696f47bfcd1c031acea6b8f5820ae5f330bdba423bade3a2b35581" +content-hash = "5df855c1101897f1c09a15bd8d00abd9b0f83108371b9313408953340703c398" diff --git a/integrations/linear/pyproject.toml b/integrations/linear/pyproject.toml index 894b4a6684..8057595649 100644 --- a/integrations/linear/pyproject.toml +++ b/integrations/linear/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "linear" -version = "0.1.27" +version = "0.1.28" description = "Integration to bring information from Linear into Port" authors = ["Mor Paz "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/newrelic/CHANGELOG.md b/integrations/newrelic/CHANGELOG.md index 4ec10cbe48..6d363e7edc 100644 --- a/integrations/newrelic/CHANGELOG.md +++ b/integrations/newrelic/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.72 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.71 (2024-08-20) diff --git a/integrations/newrelic/poetry.lock b/integrations/newrelic/poetry.lock index bffed97c39..ae5878294f 100644 --- a/integrations/newrelic/poetry.lock +++ b/integrations/newrelic/poetry.lock @@ -933,13 +933,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1863,4 +1863,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "1a8b416d58532d9e777df7f01cfa6e5f3941904deb568638e74d4c8bdd9aed88" +content-hash = "8d36d82dd63e18f67aa9a0665b0c0c534f2e6a5784fa553dffc92fa81f0ec58f" diff --git a/integrations/newrelic/pyproject.toml b/integrations/newrelic/pyproject.toml index 6216d0960c..104640c5f7 100644 --- a/integrations/newrelic/pyproject.toml +++ b/integrations/newrelic/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "newrelic" -version = "0.1.71" +version = "0.1.72" description = "New Relic Integration" authors = ["Tom Tankilevitch "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} httpx = "^0.24.1" [tool.poetry.group.dev.dependencies] diff --git a/integrations/opencost/CHANGELOG.md b/integrations/opencost/CHANGELOG.md index 6b0546a464..50fc14c2d8 100644 --- a/integrations/opencost/CHANGELOG.md +++ b/integrations/opencost/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.68 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.67 (2024-08-20) diff --git a/integrations/opencost/poetry.lock b/integrations/opencost/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/opencost/poetry.lock +++ b/integrations/opencost/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/opencost/pyproject.toml b/integrations/opencost/pyproject.toml index 00e9e81584..d4c61ebd68 100644 --- a/integrations/opencost/pyproject.toml +++ b/integrations/opencost/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "opencost" -version = "0.1.67" +version = "0.1.68" description = "Ocean integration for OpenCost" authors = ["Isaac Coffie "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/opsgenie/CHANGELOG.md b/integrations/opsgenie/CHANGELOG.md index 58d45c71f7..7d0d3e000b 100644 --- a/integrations/opsgenie/CHANGELOG.md +++ b/integrations/opsgenie/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.69 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.68 (2024-08-20) diff --git a/integrations/opsgenie/poetry.lock b/integrations/opsgenie/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/opsgenie/poetry.lock +++ b/integrations/opsgenie/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/opsgenie/pyproject.toml b/integrations/opsgenie/pyproject.toml index dd994741df..19b1f37c1c 100644 --- a/integrations/opsgenie/pyproject.toml +++ b/integrations/opsgenie/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "opsgenie" -version = "0.1.68" +version = "0.1.69" description = "Ocean integration for OpsGenie" authors = ["Isaac Coffie "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/pagerduty/CHANGELOG.md b/integrations/pagerduty/CHANGELOG.md index dd3fea2bac..45bc4c8846 100644 --- a/integrations/pagerduty/CHANGELOG.md +++ b/integrations/pagerduty/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.92 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.91 (2024-08-20) diff --git a/integrations/pagerduty/poetry.lock b/integrations/pagerduty/poetry.lock index bffed97c39..ae5878294f 100644 --- a/integrations/pagerduty/poetry.lock +++ b/integrations/pagerduty/poetry.lock @@ -933,13 +933,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1863,4 +1863,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "1a8b416d58532d9e777df7f01cfa6e5f3941904deb568638e74d4c8bdd9aed88" +content-hash = "8d36d82dd63e18f67aa9a0665b0c0c534f2e6a5784fa553dffc92fa81f0ec58f" diff --git a/integrations/pagerduty/pyproject.toml b/integrations/pagerduty/pyproject.toml index b4e612ba46..b93afbc545 100644 --- a/integrations/pagerduty/pyproject.toml +++ b/integrations/pagerduty/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "pagerduty" -version = "0.1.91" +version = "0.1.92" description = "Pagerduty Integration" authors = ["Port Team "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} httpx = "^0.24.1" [tool.poetry.group.dev.dependencies] diff --git a/integrations/sentry/CHANGELOG.md b/integrations/sentry/CHANGELOG.md index 47621e3859..09e01067d6 100644 --- a/integrations/sentry/CHANGELOG.md +++ b/integrations/sentry/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.68 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.67 (2024-08-20) diff --git a/integrations/sentry/poetry.lock b/integrations/sentry/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/sentry/poetry.lock +++ b/integrations/sentry/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/sentry/pyproject.toml b/integrations/sentry/pyproject.toml index 0ba6f445b9..e0802d1b15 100644 --- a/integrations/sentry/pyproject.toml +++ b/integrations/sentry/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "sentry" -version = "0.1.67" +version = "0.1.68" description = "Sentry Integration" authors = ["Dvir Segev ","Matan Geva "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/servicenow/CHANGELOG.md b/integrations/servicenow/CHANGELOG.md index d7cee4f761..1c57635bb5 100644 --- a/integrations/servicenow/CHANGELOG.md +++ b/integrations/servicenow/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.58 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.57 (2024-08-20) diff --git a/integrations/servicenow/poetry.lock b/integrations/servicenow/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/servicenow/poetry.lock +++ b/integrations/servicenow/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/servicenow/pyproject.toml b/integrations/servicenow/pyproject.toml index 575c270249..20f43d749c 100644 --- a/integrations/servicenow/pyproject.toml +++ b/integrations/servicenow/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "servicenow" -version = "0.1.57" +version = "0.1.58" description = "Service Now Ocean Integration" authors = ["Isaac Coffie "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/snyk/CHANGELOG.md b/integrations/snyk/CHANGELOG.md index 27838c87b1..ec80c164f1 100644 --- a/integrations/snyk/CHANGELOG.md +++ b/integrations/snyk/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.77 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.76 (2024-08-20) diff --git a/integrations/snyk/poetry.lock b/integrations/snyk/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/snyk/poetry.lock +++ b/integrations/snyk/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/snyk/pyproject.toml b/integrations/snyk/pyproject.toml index aee3f5bb4b..919f3aa245 100644 --- a/integrations/snyk/pyproject.toml +++ b/integrations/snyk/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "snyk" -version = "0.1.76" +version = "0.1.77" description = "Snyk integration powered by Ocean" authors = ["Isaac Coffie "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/sonarqube/CHANGELOG.md b/integrations/sonarqube/CHANGELOG.md index 189597ee69..795fa16dee 100644 --- a/integrations/sonarqube/CHANGELOG.md +++ b/integrations/sonarqube/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.83 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.82 (2024-08-20) diff --git a/integrations/sonarqube/poetry.lock b/integrations/sonarqube/poetry.lock index 214e96cbd6..e54b9abcf2 100644 --- a/integrations/sonarqube/poetry.lock +++ b/integrations/sonarqube/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "db8201fa1ce69733983adfc9124c4bcf8eced7913d714bf50e13e226297e1f49" +content-hash = "c2493ccef44316a2a3a38a98dd4dd2b8c40501db507611f147c5f935ca54588d" diff --git a/integrations/sonarqube/pyproject.toml b/integrations/sonarqube/pyproject.toml index 7134b53863..a7e0bb0e46 100644 --- a/integrations/sonarqube/pyproject.toml +++ b/integrations/sonarqube/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "sonarqube" -version = "0.1.82" +version = "0.1.83" description = "SonarQube projects and code quality analysis integration" authors = ["Port Team "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} rich = "^13.5.2" cookiecutter = "^2.3.0" diff --git a/integrations/statuspage/CHANGELOG.md b/integrations/statuspage/CHANGELOG.md index 259a1b7431..eb30884176 100644 --- a/integrations/statuspage/CHANGELOG.md +++ b/integrations/statuspage/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.17 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.16 (2024-08-20) diff --git a/integrations/statuspage/poetry.lock b/integrations/statuspage/poetry.lock index d8db3831fc..3cd7ca4f62 100644 --- a/integrations/statuspage/poetry.lock +++ b/integrations/statuspage/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "6b68730ae6696f47bfcd1c031acea6b8f5820ae5f330bdba423bade3a2b35581" +content-hash = "5df855c1101897f1c09a15bd8d00abd9b0f83108371b9313408953340703c398" diff --git a/integrations/statuspage/pyproject.toml b/integrations/statuspage/pyproject.toml index eb080200fd..cbb1112acb 100644 --- a/integrations/statuspage/pyproject.toml +++ b/integrations/statuspage/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "statuspage" -version = "0.1.16" +version = "0.1.17" description = "Connect Statuspage to Ocean and automatically ingest incidents, updates, and impacted components for comprehensive monitoring" authors = ["Albert Luganga "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/terraform-cloud/CHANGELOG.md b/integrations/terraform-cloud/CHANGELOG.md index 4503f62a29..c4c935081e 100644 --- a/integrations/terraform-cloud/CHANGELOG.md +++ b/integrations/terraform-cloud/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.56 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.55 (2024-08-20) diff --git a/integrations/terraform-cloud/poetry.lock b/integrations/terraform-cloud/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/terraform-cloud/poetry.lock +++ b/integrations/terraform-cloud/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/terraform-cloud/pyproject.toml b/integrations/terraform-cloud/pyproject.toml index 3e1a6b9f15..b604774be4 100644 --- a/integrations/terraform-cloud/pyproject.toml +++ b/integrations/terraform-cloud/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "terraform-cloud" -version = "0.1.55" +version = "0.1.56" description = "Terraform Cloud Integration for Port" authors = ["Michael Armah "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration diff --git a/integrations/wiz/CHANGELOG.md b/integrations/wiz/CHANGELOG.md index afa02b2a51..45b7712b5b 100644 --- a/integrations/wiz/CHANGELOG.md +++ b/integrations/wiz/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.1.48 (2024-08-22) + + +### Improvements + +- Bumped ocean version to ^0.10.0 (#1) + + ## 0.1.47 (2024-08-20) diff --git a/integrations/wiz/poetry.lock b/integrations/wiz/poetry.lock index 1497f5bab2..d76bd9fc2e 100644 --- a/integrations/wiz/poetry.lock +++ b/integrations/wiz/poetry.lock @@ -934,13 +934,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "port-ocean" -version = "0.9.14" +version = "0.10.0" description = "Port Ocean is a CLI tool for managing your Port projects." optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "port_ocean-0.9.14-py3-none-any.whl", hash = "sha256:8ce0946e9b23c0ca7e5e6821efdaddadde2b2ccca39dd9e376132c38f27b9ec6"}, - {file = "port_ocean-0.9.14.tar.gz", hash = "sha256:f733ce2fcbc69a843d980e3d4182774dcfb1c7800f91372e52943f0d45808678"}, + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, ] [package.dependencies] @@ -1864,4 +1864,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "cc141c7f257a49b28a93d1293a6b7d8219b4ebd5d4280c03c1551037cb65358b" +content-hash = "c6218047de98f6ed47001d86e9041fa05c7d4b7eb327a2e958792b57a133204c" diff --git a/integrations/wiz/pyproject.toml b/integrations/wiz/pyproject.toml index 4415b8ac7b..019a52f81f 100644 --- a/integrations/wiz/pyproject.toml +++ b/integrations/wiz/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "wiz" -version = "0.1.47" +version = "0.1.48" description = "Wiz Port integration in Ocean" authors = ["Albert Luganga "] [tool.poetry.dependencies] python = "^3.11" -port_ocean = {version = "^0.9.14", extras = ["cli"]} +port_ocean = {version = "^0.10.0", extras = ["cli"]} [tool.poetry.group.dev.dependencies] # uncomment this if you want to debug the ocean core together with your integration From 63b6f27a0721aa68067b056515cd23d21edeafc0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:44:29 +0300 Subject: [PATCH 077/177] Update tj-actions/changed-files action to v44.5.7 (#930) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [tj-actions/changed-files](https://togithub.com/tj-actions/changed-files) | action | patch | `v44.5.2` -> `v44.5.7` | --- ### Release Notes
tj-actions/changed-files (tj-actions/changed-files) ### [`v44.5.7`](https://togithub.com/tj-actions/changed-files/releases/tag/v44.5.7) [Compare Source](https://togithub.com/tj-actions/changed-files/compare/v44.5.6...v44.5.7) #### What's Changed - Upgraded to v44.5.6 by [@​tj-actions-bot](https://togithub.com/tj-actions-bot) in [https://github.com/tj-actions/changed-files/pull/2204](https://togithub.com/tj-actions/changed-files/pull/2204) - chore(deps): update typescript-eslint monorepo to v7.17.0 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2205](https://togithub.com/tj-actions/changed-files/pull/2205) - chore(deps): update dependency [@​types/node](https://togithub.com/types/node) to v20.14.12 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2208](https://togithub.com/tj-actions/changed-files/pull/2208) - fix(deps): update dependency yaml to v2.5.0 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2209](https://togithub.com/tj-actions/changed-files/pull/2209) - fix: error with pull_request closed test by [@​jackton1](https://togithub.com/jackton1) in [https://github.com/tj-actions/changed-files/pull/2211](https://togithub.com/tj-actions/changed-files/pull/2211) - fix(deps): update dependency [@​stdlib/utils-convert-path](https://togithub.com/stdlib/utils-convert-path) to v0.2.2 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2212](https://togithub.com/tj-actions/changed-files/pull/2212) - chore(deps): update dependency [@​types/node](https://togithub.com/types/node) to v20.14.13 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2213](https://togithub.com/tj-actions/changed-files/pull/2213) - chore(deps): update typescript-eslint monorepo to v7.18.0 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2216](https://togithub.com/tj-actions/changed-files/pull/2216) - chore(deps-dev): bump [@​types/node](https://togithub.com/types/node) from 20.14.13 to 22.0.0 by [@​dependabot](https://togithub.com/dependabot) in [https://github.com/tj-actions/changed-files/pull/2215](https://togithub.com/tj-actions/changed-files/pull/2215) **Full Changelog**: https://github.com/tj-actions/changed-files/compare/v44...v44.5.7 ### [`v44.5.6`](https://togithub.com/tj-actions/changed-files/releases/tag/v44.5.6) [Compare Source](https://togithub.com/tj-actions/changed-files/compare/v44.5.5...v44.5.6) ##### What's Changed - chore(deps): update typescript-eslint monorepo to v7.14.1 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2169](https://togithub.com/tj-actions/changed-files/pull/2169) - Upgraded to v44.5.5 by [@​tj-actions-bot](https://togithub.com/tj-actions-bot) in [https://github.com/tj-actions/changed-files/pull/2168](https://togithub.com/tj-actions/changed-files/pull/2168) - chore(deps): update dependency [@​types/node](https://togithub.com/types/node) to v20.14.9 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2170](https://togithub.com/tj-actions/changed-files/pull/2170) - chore(deps): update dependency [@​types/micromatch](https://togithub.com/types/micromatch) to v4.0.8 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2171](https://togithub.com/tj-actions/changed-files/pull/2171) - chore(deps): update dependency [@​types/lodash](https://togithub.com/types/lodash) to v4.17.6 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2172](https://togithub.com/tj-actions/changed-files/pull/2172) - chore(deps): update actions/checkout action to v3 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2173](https://togithub.com/tj-actions/changed-files/pull/2173) - chore(deps): update actions/checkout action to v4 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2174](https://togithub.com/tj-actions/changed-files/pull/2174) - chore(deps): update dependency [@​types/micromatch](https://togithub.com/types/micromatch) to v4.0.9 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2175](https://togithub.com/tj-actions/changed-files/pull/2175) - chore(deps-dev): bump [@​typescript-eslint/parser](https://togithub.com/typescript-eslint/parser) from 7.14.1 to 7.15.0 by [@​dependabot](https://togithub.com/dependabot) in [https://github.com/tj-actions/changed-files/pull/2181](https://togithub.com/tj-actions/changed-files/pull/2181) - chore(deps): update dependency [@​typescript-eslint/eslint-plugin](https://togithub.com/typescript-eslint/eslint-plugin) to v7.15.0 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2178](https://togithub.com/tj-actions/changed-files/pull/2178) - chore(deps): update dependency [@​types/node](https://togithub.com/types/node) to v20.14.10 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2182](https://togithub.com/tj-actions/changed-files/pull/2182) - chore(deps): update dependency ts-jest to v29.2.0 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2184](https://togithub.com/tj-actions/changed-files/pull/2184) - chore(deps): update typescript-eslint monorepo to v7.16.0 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2185](https://togithub.com/tj-actions/changed-files/pull/2185) - chore(deps): update actions/setup-node action to v4.0.3 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2188](https://togithub.com/tj-actions/changed-files/pull/2188) - chore(deps): update dependency ts-jest to v29.2.1 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2189](https://togithub.com/tj-actions/changed-files/pull/2189) - chore(deps): update dependency ts-jest to v29.2.2 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2190](https://togithub.com/tj-actions/changed-files/pull/2190) - chore(deps): update codacy/codacy-analysis-cli-action action to v4.4.2 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2191](https://togithub.com/tj-actions/changed-files/pull/2191) - chore(deps): update codacy/codacy-analysis-cli-action action to v4.4.4 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2192](https://togithub.com/tj-actions/changed-files/pull/2192) - chore(deps): update codacy/codacy-analysis-cli-action action to v4.4.5 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2193](https://togithub.com/tj-actions/changed-files/pull/2193) - chore(deps): update dependency prettier to v3.3.3 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2194](https://togithub.com/tj-actions/changed-files/pull/2194) - chore(deps): update typescript-eslint monorepo to v7.16.1 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2196](https://togithub.com/tj-actions/changed-files/pull/2196) - chore(deps): update dependency [@​types/lodash](https://togithub.com/types/lodash) to v4.17.7 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2197](https://togithub.com/tj-actions/changed-files/pull/2197) - chore(deps): update dependency [@​types/node](https://togithub.com/types/node) to v20.14.11 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2198](https://togithub.com/tj-actions/changed-files/pull/2198) - fix(deps): update dependency [@​octokit/rest](https://togithub.com/octokit/rest) to v21.0.1 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2199](https://togithub.com/tj-actions/changed-files/pull/2199) - chore(deps): update dependency eslint-plugin-prettier to v5.2.1 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2200](https://togithub.com/tj-actions/changed-files/pull/2200) - chore(deps): update dependency ts-jest to v29.2.3 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2203](https://togithub.com/tj-actions/changed-files/pull/2203) - fix: remove unused code by [@​jackton1](https://togithub.com/jackton1) in [https://github.com/tj-actions/changed-files/pull/2202](https://togithub.com/tj-actions/changed-files/pull/2202) **Full Changelog**: https://github.com/tj-actions/changed-files/compare/v44...v44.5.6 ### [`v44.5.5`](https://togithub.com/tj-actions/changed-files/releases/tag/v44.5.5) [Compare Source](https://togithub.com/tj-actions/changed-files/compare/v44.5.4...v44.5.5) #### What's Changed - Upgraded to v44.5.4 by [@​tj-actions-bot](https://togithub.com/tj-actions-bot) in [https://github.com/tj-actions/changed-files/pull/2165](https://togithub.com/tj-actions/changed-files/pull/2165) - chore: remove debug lines by [@​jackton1](https://togithub.com/jackton1) in [https://github.com/tj-actions/changed-files/pull/2166](https://togithub.com/tj-actions/changed-files/pull/2166) **Full Changelog**: https://github.com/tj-actions/changed-files/compare/v44...v44.5.5 ### [`v44.5.4`](https://togithub.com/tj-actions/changed-files/releases/tag/v44.5.4) [Compare Source](https://togithub.com/tj-actions/changed-files/compare/v44.5.3...v44.5.4) ##### What's Changed - chore(deps): update dependency [@​types/node](https://togithub.com/types/node) to v20.14.7 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2156](https://togithub.com/tj-actions/changed-files/pull/2156) - fix(deps): update dependency [@​octokit/rest](https://togithub.com/octokit/rest) to v21 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2158](https://togithub.com/tj-actions/changed-files/pull/2158) - Upgraded to v44.5.3 by [@​tj-actions-bot](https://togithub.com/tj-actions-bot) in [https://github.com/tj-actions/changed-files/pull/2154](https://togithub.com/tj-actions/changed-files/pull/2154) - chore(deps-dev): bump [@​types/uuid](https://togithub.com/types/uuid) from 9.0.8 to 10.0.0 by [@​dependabot](https://togithub.com/dependabot) in [https://github.com/tj-actions/changed-files/pull/2160](https://togithub.com/tj-actions/changed-files/pull/2160) - chore(deps): update dependency [@​types/node](https://togithub.com/types/node) to v20.14.8 by [@​renovate](https://togithub.com/renovate) in [https://github.com/tj-actions/changed-files/pull/2162](https://togithub.com/tj-actions/changed-files/pull/2162) - fix: error using since_last_remote_commit with the first PR commit by [@​jackton1](https://togithub.com/jackton1) in [https://github.com/tj-actions/changed-files/pull/2163](https://togithub.com/tj-actions/changed-files/pull/2163) **Full Changelog**: https://github.com/tj-actions/changed-files/compare/v44...v44.5.4 ### [`v44.5.3`](https://togithub.com/tj-actions/changed-files/compare/v44.5.2...v44.5.3) [Compare Source](https://togithub.com/tj-actions/changed-files/compare/v44.5.2...v44.5.3)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/port-labs/ocean). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 711622e0c5..4faa6de8a0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,7 +16,7 @@ jobs: - name: Get list of changed files id: changed-files - uses: tj-actions/changed-files@v44.5.2 + uses: tj-actions/changed-files@v44.5.7 - name: Set matrix id: set-matrix run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 86316706d6..75aa773eb5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: - name: Get list of changed files id: changed-files - uses: tj-actions/changed-files@v44.5.2 + uses: tj-actions/changed-files@v44.5.7 - name: Set matrix id: set-matrix run: | From 00a0625253e0fdcf0a5f4e3b79abce0dd76d71ee Mon Sep 17 00:00:00 2001 From: Adebayo Oluwadunsin Iyanuoluwa <88881603+oiadebayo@users.noreply.github.com> Date: Sat, 24 Aug 2024 18:24:13 +0100 Subject: [PATCH 078/177] [Integration][Octopus] Added integration with support for Spaces Project, Release, Deployments and Machines (#880) --- integrations/octopus/.gitignore | 153 ++ .../octopus/.port/resources/.gitignore | 0 .../octopus/.port/resources/blueprints.json | 246 +++ .../.port/resources/port-app-config.yaml | 88 + integrations/octopus/.port/spec.yaml | 26 + integrations/octopus/CHANGELOG.md | 16 + integrations/octopus/Makefile | 74 + integrations/octopus/README.md | 7 + integrations/octopus/client.py | 124 ++ integrations/octopus/debug.py | 4 + integrations/octopus/main.py | 97 + integrations/octopus/poetry.lock | 1819 +++++++++++++++++ integrations/octopus/poetry.toml | 3 + integrations/octopus/pyproject.toml | 102 + integrations/octopus/sonar-project.properties | 3 + integrations/octopus/tests/__init__.py | 0 integrations/octopus/tests/test_sample.py | 2 + 17 files changed, 2764 insertions(+) create mode 100644 integrations/octopus/.gitignore create mode 100644 integrations/octopus/.port/resources/.gitignore create mode 100644 integrations/octopus/.port/resources/blueprints.json create mode 100644 integrations/octopus/.port/resources/port-app-config.yaml create mode 100644 integrations/octopus/.port/spec.yaml create mode 100644 integrations/octopus/CHANGELOG.md create mode 100644 integrations/octopus/Makefile create mode 100644 integrations/octopus/README.md create mode 100644 integrations/octopus/client.py create mode 100644 integrations/octopus/debug.py create mode 100644 integrations/octopus/main.py create mode 100644 integrations/octopus/poetry.lock create mode 100644 integrations/octopus/poetry.toml create mode 100644 integrations/octopus/pyproject.toml create mode 100644 integrations/octopus/sonar-project.properties create mode 100644 integrations/octopus/tests/__init__.py create mode 100644 integrations/octopus/tests/test_sample.py diff --git a/integrations/octopus/.gitignore b/integrations/octopus/.gitignore new file mode 100644 index 0000000000..437709ed59 --- /dev/null +++ b/integrations/octopus/.gitignore @@ -0,0 +1,153 @@ +# 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 +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/ \ No newline at end of file diff --git a/integrations/octopus/.port/resources/.gitignore b/integrations/octopus/.port/resources/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/integrations/octopus/.port/resources/blueprints.json b/integrations/octopus/.port/resources/blueprints.json new file mode 100644 index 0000000000..62fcee94f5 --- /dev/null +++ b/integrations/octopus/.port/resources/blueprints.json @@ -0,0 +1,246 @@ +[ + { + "identifier": "octopusSpace", + "title": "Octopus Space", + "icon": "Octopus", + "description": "A space in Octopus Deploy", + "schema": { + "properties": { + "url": { + "type": "string", + "title": "Space URL", + "format": "url", + "description": "The Link to the Space in Octopus Deploy" + }, + "description": { + "type": "string", + "title": "Description", + "description": "The description of the space" + } + } + }, + "calculationProperties": {}, + "relations": {} + }, + { + "identifier": "octopusProject", + "title": "Octopus Project", + "icon": "Octopus", + "description": "An Octopus project", + "schema": { + "properties": { + "slug": { + "type": "string", + "title": "Slug", + "description": "The slug identifier of the project" + }, + "url": { + "type": "string", + "title": "Project URL", + "format": "url", + "description": "The URL to access the project in Octopus Deploy" + }, + "description": { + "type": "string", + "title": "Description", + "description": "The project description" + }, + "isDisabled": { + "type": "boolean", + "title": "Is Disabled", + "description": "Indicates if the project is disabled" + }, + "tenantedDeploymentMode": { + "type": "string", + "title": "Tenanted Deployment Mode", + "description": "The deployment mode regarding tenants" + } + } + }, + "calculationProperties": {}, + "relations": { + "space": { + "target": "octopusSpace", + "title": "Space", + "description": "The space to which this project belongs", + "required": false, + "many": false + } + } + }, + { + "identifier": "octopusRelease", + "title": "Octopus Release", + "icon": "Octopus", + "description": "A release in Octopus Deploy", + "schema": { + "properties": { + "version": { + "type": "string", + "title": "Version", + "description": "The version of the release" + }, + "assembledDate": { + "type": "string", + "title": "Assembled Date", + "format": "date-time", + "description": "The datetime the release was assembled" + }, + "channelId": { + "type": "string", + "title": "Channel ID", + "description": "The ID of the channel associated with the release" + }, + "releaseNotes": { + "type": "string", + "title": "Release Notes", + "description": "Notes provided for the release" + }, + "url": { + "type": "string", + "title": "Release URL", + "format": "url", + "description": "The URL to access the release in Octopus Deploy" + } + } + }, + "calculationProperties": {}, + "relations": { + "project": { + "target": "octopusProject", + "title": "Project", + "description": "The project to which this release belongs", + "required": false, + "many": false + } + } + }, + { + "identifier": "octopusDeployment", + "title": "Octopus Deployment", + "icon": "Octopus", + "description": "A deployment in Octopus Deploy", + "schema": { + "properties": { + "createdAt": { + "type": "string", + "title": "Created At", + "format": "date-time", + "description": "The datetime when the deployment was created" + }, + "deployedBy": { + "type": "string", + "title": "Deployed By", + "description": "The user or system that performed the deployment" + }, + "taskId": { + "type": "string", + "title": "Task ID", + "description": "The ID of the task associated with the deployment" + }, + "failureEncountered": { + "type": "boolean", + "title": "Failure Encountered", + "description": "Indicates if any failure was encountered during the deployment" + }, + "comments": { + "type": "string", + "title": "Comments", + "description": "Comments regarding the deployment" + }, + "url": { + "type": "string", + "title": "Deployment URL", + "format": "url", + "description": "The URL to access the deployment in Octopus Deploy" + } + } + }, + "calculationProperties": {}, + "relations": { + "release": { + "target": "octopusRelease", + "title": "Release", + "description": "The release associated with this deployment", + "required": false, + "many": false + }, + "project": { + "target": "octopusProject", + "title": "Project", + "description": "The project associated with this deployment", + "required": false, + "many": false + } + } + }, + { + "identifier": "octopusMachine", + "title": "Octopus Machine", + "icon": "Octopus", + "description": "A deployment target in Octopus Deploy", + "schema": { + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Roles", + "description": "Roles assigned to the target" + }, + "status": { + "type": "string", + "title": "Status", + "description": "The health status of the target" + }, + "url": { + "type": "string", + "title": "Machine URL", + "format": "url", + "description": "The URL of the target" + }, + "isDisabled": { + "type": "boolean", + "title": "Is Disabled", + "description": "Indicates if the target is disabled" + }, + "operatingSystem": { + "type": "string", + "title": "Operating System", + "description": "The operating system of the target" + }, + "architecture": { + "type": "string", + "title": "Architecture", + "description": "The architecture of the target" + }, + "statusSummary": { + "type": "string", + "title": "Status Summary", + "description": "Summary of the target's status" + }, + "endpointType": { + "type": "string", + "title": "Endpoint Type", + "description": "The type of deployment target endpoint" + }, + "communicationStyle": { + "type": "string", + "title": "Communication Style", + "description": "The communication style of the target" + } + } + }, + "calculationProperties": {}, + "relations": { + "space": { + "target": "octopusSpace", + "title": "Space", + "description": "The space associated with this target", + "required": false, + "many": false + } + } + } +] diff --git a/integrations/octopus/.port/resources/port-app-config.yaml b/integrations/octopus/.port/resources/port-app-config.yaml new file mode 100644 index 0000000000..e490be2866 --- /dev/null +++ b/integrations/octopus/.port/resources/port-app-config.yaml @@ -0,0 +1,88 @@ +createMissingRelatedEntities: true +deleteDependentEntities: true +resources: + - kind: space + selector: + query: "true" + port: + entity: + mappings: + identifier: .Id + title: .Name + blueprint: '"octopusSpace"' + properties: + url: env.OCEAN__INTEGRATION__CONFIG__SERVER_URL + "/app#/" + .Id + description: .Description + - kind: project + selector: + query: "true" + port: + entity: + mappings: + identifier: .Id + title: .Name + blueprint: '"octopusProject"' + properties: + url: env.OCEAN__INTEGRATION__CONFIG__SERVER_URL + "/app#/" + .SpaceId + "/projects/" + .Id + description: .Description + isDisabled: .IsDisabled + tenantedDeploymentMode: .TenantedDeploymentMode + relations: + space: .SpaceId + - kind: release + selector: + query: "true" + port: + entity: + mappings: + identifier: .Id + title: ".ProjectId + \"(\" + .Version + \")\"" + blueprint: '"octopusRelease"' + properties: + version: .Version + assembledDate: .Assembled + channelId: .ChannelId + releaseNotes: .ReleaseNotes + url: env.OCEAN__INTEGRATION__CONFIG__SERVER_URL + "/app#/" + .SpaceId + "/releases/" + .Id + relations: + project: .ProjectId + - kind: deployment + selector: + query: "true" + port: + entity: + mappings: + identifier: .Id + title: .Name + blueprint: '"octopusDeployment"' + properties: + createdAt: .Created + deployedBy: .DeployedBy + taskId: .TaskId + failureEncountered: .FailureEncountered + comments: .Comments + url: env.OCEAN__INTEGRATION__CONFIG__SERVER_URL + "/app#/" + .SpaceId + "/deployments/" + .Id + relations: + release: .ReleaseId + project: .ProjectId + - kind: machine + selector: + query: "true" + port: + entity: + mappings: + identifier: .Id + title: .Name + blueprint: '"octopusMachine"' + properties: + roles: .Roles + status: .HealthStatus + url: env.OCEAN__INTEGRATION__CONFIG__SERVER_URL + "/app#/" + .SpaceId + "/infrastructure/machines/" + .Id + "/settings" + isDisabled: .IsDisabled + operatingSystem: .OperatingSystem + architecture: .Architecture + statusSummary: .StatusSummary + endpointType: .Endpoint.DeploymentTargetTypeId + communicationStyle: .Endpoint.CommunicationStyle + relations: + space: .SpaceId diff --git a/integrations/octopus/.port/spec.yaml b/integrations/octopus/.port/spec.yaml new file mode 100644 index 0000000000..0bf2c4c44c --- /dev/null +++ b/integrations/octopus/.port/spec.yaml @@ -0,0 +1,26 @@ +description: Octopus Deploy integration for Port Ocean +icon: Octopus +docs: https://docs.getport.io/build-your-software-catalog/sync-data-to-catalog/octopus +features: + - type: exporter + section: CICD + resources: + - kind: space + - kind: project + - kind: release + - kind: deployment + - kind: machine +configurations: + - name: octopusApiKey + required: true + type: string + description: Octopus Deploy API key. For more information on creating an API key, refer to the Octopus API documentation. + sensitive: true + - name: serverUrl + required: true + type: url + description: The base URL of your Octopus Deploy instance. It should include the protocol (e.g., https://). + - name: appHost + required: false + type: url + description: The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Octopus Deploy. diff --git a/integrations/octopus/CHANGELOG.md b/integrations/octopus/CHANGELOG.md new file mode 100644 index 0000000000..79012defb8 --- /dev/null +++ b/integrations/octopus/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + +## 0.1.0-beta (2024-08-24) + +### Features + +- Added Octopus integration with support for Space, Project, Release, Deployment and Machine (PORT-9398) + + diff --git a/integrations/octopus/Makefile b/integrations/octopus/Makefile new file mode 100644 index 0000000000..f2d20457b8 --- /dev/null +++ b/integrations/octopus/Makefile @@ -0,0 +1,74 @@ +ACTIVATE := . .venv/bin/activate + +define run_checks + exit_code=0; \ + cd $1; \ + poetry check || exit_code=$$?;\ + mypy . || exit_code=$$?; \ + ruff check . || exit_code=$$?; \ + black --check . || exit_code=$$?; \ + if [ $$exit_code -eq 1 ]; then \ + echo "\033[0;31mOne or more checks failed with exit code $$exit_code\033[0m"; \ + else \ + echo "\033[0;32mAll checks executed successfully.\033[0m"; \ + fi; \ + exit $$exit_code +endef + +define install_poetry + if ! command -v poetry &> /dev/null; then \ + pip install --upgrade pip; \ + pip install poetry; \ + else \ + echo "Poetry is already installed."; \ + fi +endef + +define deactivate_virtualenv + if [ -n "$$VIRTUAL_ENV" ]; then \ + unset VIRTUAL_ENV; \ + unset PYTHONHOME; \ + unset -f pydoc >/dev/null 2>&1; \ + OLD_PATH="$$PATH"; \ + PATH=$$(echo -n "$$PATH" | awk -v RS=: -v ORS=: '/\/virtualenv\/bin$$/ {next} {print}'); \ + export PATH; \ + hash -r; \ + echo "Deactivated the virtual environment."; \ + fi +endef + +.SILENT: install install/prod lint run test clean + +install: + $(call deactivate_virtualenv) && \ + $(call install_poetry) && \ + poetry install --with dev + +install/prod: + $(call install_poetry) && \ + poetry install --without dev --no-root --no-interaction --no-ansi --no-cache + +lint: + $(ACTIVATE) && \ + $(call run_checks,.) + +run: + $(ACTIVATE) && ocean sail + +test: lint + $(ACTIVATE) && poetry run pytest + +clean: + @find . -name '.venv' -type d -exec rm -rf {} \; + @find . -name '*.pyc' -exec rm -rf {} \; + @find . -name '__pycache__' -exec rm -rf {} \; + @find . -name 'Thumbs.db' -exec rm -rf {} \; + @find . -name '*~' -exec rm -rf {} \; + rm -rf .cache + rm -rf build + rm -rf dist + rm -rf *.egg-info + rm -rf htmlcov + rm -rf .tox/ + rm -rf docs/_build + rm -rf dist/ \ No newline at end of file diff --git a/integrations/octopus/README.md b/integrations/octopus/README.md new file mode 100644 index 0000000000..2e159eda06 --- /dev/null +++ b/integrations/octopus/README.md @@ -0,0 +1,7 @@ +# octopus + +An integration used to import octopus resources into Port. + +#### Install & use the integration - [Integration documentation](https://docs.getport.io/build-your-software-catalog/sync-data-to-catalog/octopus) + +#### Develop & improve the integration - [Ocean integration development documentation](https://ocean.getport.io/develop-an-integration/) \ No newline at end of file diff --git a/integrations/octopus/client.py b/integrations/octopus/client.py new file mode 100644 index 0000000000..badfee182f --- /dev/null +++ b/integrations/octopus/client.py @@ -0,0 +1,124 @@ +from typing import Any, AsyncGenerator, Optional +from loguru import logger +from port_ocean.utils import http_async_client +from httpx import HTTPStatusError, Timeout + +PAGE_SIZE = 50 +WEBHOOK_TIMEOUT = "00:00:50" +CLIENT_TIMEOUT = 60 +KINDS_WITH_LIMITATION = ["deployment"] +MAX_ITEMS_LIMITATION = 100 + + +class OctopusClient: + def __init__(self, server_url: str, octopus_api_key: str) -> None: + self.octopus_url = f"{server_url.rstrip('/')}/api/" + self.api_auth_header = {"X-Octopus-ApiKey": octopus_api_key} + self.client = http_async_client + self.client.timeout = Timeout(CLIENT_TIMEOUT) + self.client.headers.update(self.api_auth_header) + + async def _send_api_request( + self, + endpoint: str, + params: Optional[dict[str, Any]] = None, + json_data: Optional[dict[str, Any]] = None, + method: str = "GET", + ) -> Any: + """Send a request to the Octopus Deploy API.""" + url = f"{self.octopus_url}{endpoint}" + response = await self.client.request( + url=url, + method=method, + headers=self.api_auth_header, + params=params, + json=json_data, + ) + try: + response.raise_for_status() + except HTTPStatusError as e: + logger.error( + f"Got HTTP error to url: {url} with status code: {e.response.status_code} and response text: {e.response.text}" + ) + raise + return response.json() + + async def get_paginated_resources( + self, + kind: str, + params: Optional[dict[str, Any]] = None, + ) -> AsyncGenerator[list[dict[str, Any]], None]: + """Fetch paginated data from the Octopus Deploy API.""" + if params is None: + params = {} + params["skip"] = 0 + params["take"] = PAGE_SIZE + page = 0 + while True: + response = await self._send_api_request(f"{kind}s", params=params) + items = response.get("Items", []) + last_page = response.get("LastPageNumber", 0) + yield items + if page >= last_page: + break + if kind in KINDS_WITH_LIMITATION and params["skip"] >= MAX_ITEMS_LIMITATION: + logger.warning( + f"Reached the limit of {MAX_ITEMS_LIMITATION} {kind}s. Skipping the rest of the {kind}s." + ) + break + params["skip"] += PAGE_SIZE + page += 1 + + async def get_single_resource( + self, resource_kind: str, resource_id: str + ) -> dict[str, Any]: + """Get a single resource by kind and ID.""" + return await self._send_api_request(f"{resource_kind}/{resource_id}") + + async def _get_all_spaces(self) -> list[dict[str, Any]]: + """Get all spaces in the Octopus instance.""" + return await self._send_api_request("spaces/all") + + async def _create_subscription( + self, space_id: str, app_host: str + ) -> dict[str, Any]: + """Create a new subscription for a space.""" + endpoint = "subscriptions" + subscription_data = { + "EventNotificationSubscription": { + "WebhookURI": f"{app_host}/integration/webhook", + "WebhookTimeout": WEBHOOK_TIMEOUT, + }, + "IsDisabled": False, + "Name": f"Port Subscription - {space_id}", + "SpaceId": space_id, + } + logger.info( + f"Creating Webhook Subscription - '{subscription_data['Name']}' in '{space_id}'" + ) + return await self._send_api_request( + endpoint, json_data=subscription_data, method="POST" + ) + + async def create_webhook_subscription(self, app_host: str) -> dict[str, Any]: + """Create a new subscription for all spaces.""" + for space in await self._get_all_spaces(): + try: + response = await self._create_subscription(space["Id"], app_host) + if response.get("Id"): + logger.info( + f"Subscription created for space '{space['Id']}' with ID {response['Id']}" + ) + else: + logger.error( + f"Failed to create subscription for space '{space['Id']}'" + ) + except Exception as e: + logger.error(f"Unexpected error for space '{space['Id']}': {str(e)}") + return {"ok": True} + + async def get_webhook_subscriptions(self) -> list[dict[str, Any]]: + """Get existing subscriptions.""" + response = await self._send_api_request("subscriptions/all") + logger.info(f"Retrieved {len(response)} subscriptions.") + return response diff --git a/integrations/octopus/debug.py b/integrations/octopus/debug.py new file mode 100644 index 0000000000..b49924b4db --- /dev/null +++ b/integrations/octopus/debug.py @@ -0,0 +1,4 @@ +from port_ocean import run + +if __name__ == "__main__": + run() diff --git a/integrations/octopus/main.py b/integrations/octopus/main.py new file mode 100644 index 0000000000..68ba8ddc36 --- /dev/null +++ b/integrations/octopus/main.py @@ -0,0 +1,97 @@ +from enum import StrEnum +from typing import Any, Dict +from loguru import logger +from port_ocean.context.ocean import ocean +from port_ocean.core.ocean_types import ASYNC_GENERATOR_RESYNC_TYPE +from client import OctopusClient + +TRACKED_EVENTS = [ + "spaces", + "projects", + "deployments", + "releases", + "machines", +] + + +class ObjectKind(StrEnum): + SPACE = "space" + PROJECT = "project" + DEPLOYMENT = "deployment" + RELEASE = "release" + MACHINE = "machine" + + +@ocean.on_start() +async def on_start() -> None: + logger.info("Starting Port Ocean Octopus integration") + if ocean.event_listener_type == "ONCE": + logger.info("Skipping webhook creation because the event listener is ONCE") + return + await setup_application() + + +async def init_client() -> OctopusClient: + client = OctopusClient( + ocean.integration_config["server_url"], + ocean.integration_config["octopus_api_key"], + ) + return client + + +async def setup_application() -> None: + app_host = ocean.integration_config.get("app_host") + if not app_host: + logger.warning( + "App host was not provided, skipping webhook creation. " + "Without setting up the webhook, you will have to manually initiate resync to get updates from Octopus." + ) + return + octopus_client = await init_client() + existing_subscriptions = await octopus_client.get_webhook_subscriptions() + existing_webhook_uris = { + subscription.get("EventNotificationSubscription", {}).get("WebhookURI") + for subscription in existing_subscriptions + } + webhook_uri = f"{app_host}/integration/webhook" + if webhook_uri in existing_webhook_uris: + logger.info(f"Webhook already exists with URI: {webhook_uri}") + else: + await octopus_client.create_webhook_subscription(app_host) + logger.info(f"Webhook created with URI: {webhook_uri}") + + +@ocean.on_resync() +async def resync_resources(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: + octopus_client = await init_client() + async for resource_batch in octopus_client.get_paginated_resources(kind): + logger.info(f"Received length {len(resource_batch)} of {kind} ") + yield resource_batch + + +@ocean.router.post("/webhook") +async def handle_webhook_request(data: Dict[str, Any]) -> Dict[str, Any]: + """ + Handle the webhook request from Octopus Deploy. + """ + payload = data.get("Payload", {}).get("Event", {}) + related_document_ids = payload.get("RelatedDocumentIds", []) + event_category = payload.get("Category", "") + client = await init_client() + for resource_id in related_document_ids: + logger.info(f"Received webhook event with ID: {resource_id}") + resource_prefix = resource_id.split("-")[0].lower() + if resource_prefix in TRACKED_EVENTS: + kind = ObjectKind(resource_prefix.rstrip("s")) + try: + if event_category == "Deleted": + await ocean.unregister_raw(kind, [{"Id": resource_id}]) + else: + resource_data = await client.get_single_resource( + resource_prefix, resource_id + ) + await ocean.register_raw(kind, [resource_data]) + except Exception as e: + logger.error(f"Failed to process resource {resource_id}: {e}") + logger.info("Webhook event processed") + return {"ok": True} diff --git a/integrations/octopus/poetry.lock b/integrations/octopus/poetry.lock new file mode 100644 index 0000000000..67181aeac9 --- /dev/null +++ b/integrations/octopus/poetry.lock @@ -0,0 +1,1819 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "aiostream" +version = "0.6.2" +description = "Generator-based operators for asynchronous iteration" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiostream-0.6.2-py3-none-any.whl", hash = "sha256:e771bfb0a8d6f5e04359992025315fa4cc3b908ddb02822f73bb57d6ed7e9125"}, + {file = "aiostream-0.6.2.tar.gz", hash = "sha256:481e58c7f94b98f37a81384411ee39336dffb933784753b1cfa0a26f3681cc2c"}, +] + +[package.dependencies] +typing-extensions = "*" + +[package.extras] +dev = ["pytest", "pytest-asyncio", "pytest-cov"] + +[[package]] +name = "anyio" +version = "4.4.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, +] + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "arrow" +version = "1.3.0" +description = "Better dates & times for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + +[[package]] +name = "astroid" +version = "2.15.8" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.7.2" +files = [ + {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"}, + {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"}, +] + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} + +[[package]] +name = "binaryornot" +version = "0.4.4" +description = "Ultra-lightweight pure Python package to check if a file is binary or text." +optional = false +python-versions = "*" +files = [ + {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, + {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, +] + +[package.dependencies] +chardet = ">=3.0.2" + +[[package]] +name = "black" +version = "23.12.1" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, + {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, + {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, + {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, + {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, + {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, + {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, + {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, + {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, + {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, + {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, + {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, + {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, + {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, + {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, + {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, + {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, + {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, + {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, + {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, + {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, + {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "certifi" +version = "2024.7.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, +] + +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +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.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[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 = "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 = "confluent-kafka" +version = "2.5.0" +description = "Confluent's Python client for Apache Kafka" +optional = false +python-versions = "*" +files = [ + {file = "confluent-kafka-2.5.0.tar.gz", hash = "sha256:551cabaade717bb56ec13eb860ce439bedbcf1c97f4a4aa26957572ed1bfa74f"}, + {file = "confluent_kafka-2.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5509a219128fb177fa4186a8669071cc52acd52eba436f339edb9063aabb486d"}, + {file = "confluent_kafka-2.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ff98d8fbe7d3671cac3e1b692c13f160cf508b525c110a89906ffabd1cc140fe"}, + {file = "confluent_kafka-2.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:72ffae4387d283cb5657b6381a893c7231c26a9b4248557e7f030de76156290a"}, + {file = "confluent_kafka-2.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:75873087fd1bd753e082f74ab97f68cc3a0765d6b600c2ac3d3a0beffbdc569d"}, + {file = "confluent_kafka-2.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:2af917f93ac3a0aa88e6bee9b2056c1c176621e4a9c8f7051cc8646b81f91327"}, + {file = "confluent_kafka-2.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:efc8c48d5dbbcd1b56afe737df8156a74e62b50481ccffe581b9926eaa16c014"}, + {file = "confluent_kafka-2.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7b9f867c7e955a48ed60dee0da9c157b0f84e67724f7e42591bbcf6867e3865f"}, + {file = "confluent_kafka-2.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b064baf6a93ab58199e63bddf73d9f2c855b89cc376d5313c2f89c633aa3254a"}, + {file = "confluent_kafka-2.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a55f3d761c8463c504012ad9b06be33ef07f301f246e61d656cc927d35763f82"}, + {file = "confluent_kafka-2.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:c05a677b1dbdcf2a4532e2cf41e78d2e2ffb3a6829347caf2825f472cda59e69"}, + {file = "confluent_kafka-2.5.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:db987d8953d0d58a28a455e43a1da74a0e9dec7a12a74f5abd85a7cb308aefd4"}, + {file = "confluent_kafka-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d828ebb45db153cd462e72c575f8683c2c56ddba62b282aa36d9c365847e212"}, + {file = "confluent_kafka-2.5.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fb863f76605e9bbbb1d7f02abf05899cf1435421aa721a5be212c600bd054aa3"}, + {file = "confluent_kafka-2.5.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:92efb98908e29f597c77ab97faa064f670b681f4540c3eabc415b8a6e58df9bf"}, + {file = "confluent_kafka-2.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:d668b5c426af595271bf6fce2917a6c3a15453656077a59db85f440958b5ccc2"}, + {file = "confluent_kafka-2.5.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:797250f1a66024dd8b1c94764cc75e1d7bd1b7224a0b982678eafbb39714874e"}, + {file = "confluent_kafka-2.5.0-cp36-cp36m-manylinux_2_28_aarch64.whl", hash = "sha256:e81dc0a2980e597848b73983ce6e0b4ae7d129c01370cd9f31599c15c5d02a5d"}, + {file = "confluent_kafka-2.5.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:ffda33c86f5fee6ae678cca039915a0c4c1863bbc592b6f2f82abfddc173b0d3"}, + {file = "confluent_kafka-2.5.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7410bd5b0d6f54df5fa3313c75801a6ebcfab7cbfb947c3f56149e38b0fe924c"}, + {file = "confluent_kafka-2.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9a29dc4b7d4a754037d7d8e3ad1873a27b16e7de8c0a06755456b20803a70b16"}, + {file = "confluent_kafka-2.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:089b68a43c3b911356a4ff08fa862245f1333387b79221ac7f60d99e5b4e24d6"}, + {file = "confluent_kafka-2.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:c3a17ebdd97c803cf369c8615a474ca0bea39b5f5944e51f1c320aee8d6d5da9"}, + {file = "confluent_kafka-2.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:151656afaeb623b46c042a752091d8b17fd05ff7d309be6d8b4953b8dc0783bc"}, + {file = "confluent_kafka-2.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:570fc091cdcf9d1baf90c5f4965322cea8185ba8698d0f02cd1c8bd38bf6664a"}, + {file = "confluent_kafka-2.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bd57edf51434d6ec289339a0c9b627ca1f1e7c1130e348c0b411407183db53c6"}, + {file = "confluent_kafka-2.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:8975fea2ccd6927aad188e198e1688ef16589dc36b42f7a33ad07b1ca1341901"}, + {file = "confluent_kafka-2.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7c0b1a7774905c9e3c24d09d9b8463d771685e4105150c2503185537a6a590f9"}, + {file = "confluent_kafka-2.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:eaf01cd79b4d2cdbdf1e7b6ace9c846ae9ad9f4cf573617bbb5735a5c48cbd20"}, + {file = "confluent_kafka-2.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa789332fd40a9e99b9388f87f28db8fc7dd8ca54a1d24d0bcd0ad33f50f3528"}, + {file = "confluent_kafka-2.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e917db155dc3a64e1496b293a3ceb0a8edf23e0bd6f93d43576c40f0c59d3067"}, + {file = "confluent_kafka-2.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:a8bb3af6d1f109aaac5514c65a46cac933d78b3935f6fea52fe1f2ea6a9951bf"}, + {file = "confluent_kafka-2.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a1fb72461dcf7aa7e1834133eb733f824331aafda87ef48ec917d9b09c805a99"}, + {file = "confluent_kafka-2.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:4bda1b5fa87cb993bcd964d271a76cc11cafa2455de02ab5eff6efd9e688d55e"}, +] + +[package.extras] +avro = ["avro (>=1.11.1,<2)", "fastavro (>=0.23.0,<1.0)", "fastavro (>=1.0)", "requests"] +dev = ["avro (>=1.11.1,<2)", "fastavro (>=0.23.0,<1.0)", "fastavro (>=1.0)", "flake8", "pytest", "pytest (==4.6.4)", "pytest-timeout", "requests"] +doc = ["avro (>=1.11.1,<2)", "fastavro (>=0.23.0,<1.0)", "fastavro (>=1.0)", "requests", "sphinx", "sphinx-rtd-theme"] +json = ["jsonschema", "pyrsistent", "pyrsistent (==0.16.1)", "requests"] +protobuf = ["protobuf", "requests"] +schema-registry = ["requests"] + +[[package]] +name = "cookiecutter" +version = "2.6.0" +description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d"}, + {file = "cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c"}, +] + +[package.dependencies] +arrow = "*" +binaryornot = ">=0.4.4" +click = ">=7.0,<9.0.0" +Jinja2 = ">=2.7,<4.0.0" +python-slugify = ">=4.0.0" +pyyaml = ">=5.3.1" +requests = ">=2.23.0" +rich = "*" + +[[package]] +name = "dill" +version = "0.3.8" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + +[[package]] +name = "dnspython" +version = "2.6.1" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"}, + {file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"}, +] + +[package.extras] +dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "sphinx (>=7.2.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"] +dnssec = ["cryptography (>=41)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"] +doq = ["aioquic (>=0.9.25)"] +idna = ["idna (>=3.6)"] +trio = ["trio (>=0.23)"] +wmi = ["wmi (>=1.5.1)"] + +[[package]] +name = "email-validator" +version = "2.2.0" +description = "A robust email address syntax and deliverability validation library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"}, + {file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"}, +] + +[package.dependencies] +dnspython = ">=2.0.0" +idna = ">=2.0.0" + +[[package]] +name = "fastapi" +version = "0.111.1" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastapi-0.111.1-py3-none-any.whl", hash = "sha256:4f51cfa25d72f9fbc3280832e84b32494cf186f50158d364a8765aabf22587bf"}, + {file = "fastapi-0.111.1.tar.gz", hash = "sha256:ddd1ac34cb1f76c2e2d7f8545a4bcb5463bce4834e81abf0b189e0c359ab2413"}, +] + +[package.dependencies] +email_validator = ">=2.0.0" +fastapi-cli = ">=0.0.2" +httpx = ">=0.23.0" +jinja2 = ">=2.11.2" +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +python-multipart = ">=0.0.7" +starlette = ">=0.37.2,<0.38.0" +typing-extensions = ">=4.8.0" +uvicorn = {version = ">=0.12.0", extras = ["standard"]} + +[package.extras] +all = ["email_validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] + +[[package]] +name = "fastapi-cli" +version = "0.0.5" +description = "Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastapi_cli-0.0.5-py3-none-any.whl", hash = "sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46"}, + {file = "fastapi_cli-0.0.5.tar.gz", hash = "sha256:d30e1239c6f46fcb95e606f02cdda59a1e2fa778a54b64686b3ff27f6211ff9f"}, +] + +[package.dependencies] +typer = ">=0.12.3" +uvicorn = {version = ">=0.15.0", extras = ["standard"]} + +[package.extras] +standard = ["uvicorn[standard] (>=0.15.0)"] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, + {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.26.0)"] + +[[package]] +name = "httptools" +version = "0.6.1" +description = "A collection of framework independent HTTP protocol utils." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"}, + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"}, + {file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"}, + {file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"}, + {file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"}, + {file = "httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"}, + {file = "httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"}, + {file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"}, +] + +[package.extras] +test = ["Cython (>=0.29.24,<0.30.0)"] + +[[package]] +name = "httpx" +version = "0.27.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "incremental" +version = "24.7.2" +description = "A small library that versions your Python projects." +optional = false +python-versions = ">=3.8" +files = [ + {file = "incremental-24.7.2-py3-none-any.whl", hash = "sha256:8cb2c3431530bec48ad70513931a760f446ad6c25e8333ca5d95e24b0ed7b8fe"}, + {file = "incremental-24.7.2.tar.gz", hash = "sha256:fb4f1d47ee60efe87d4f6f0ebb5f70b9760db2b2574c59c8e8912be4ebd464c9"}, +] + +[package.dependencies] +setuptools = ">=61.0" + +[package.extras] +scripts = ["click (>=6.0)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jinja2-time" +version = "0.2.0" +description = "Jinja2 Extension for Dates and Times" +optional = false +python-versions = "*" +files = [ + {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"}, + {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, +] + +[package.dependencies] +arrow = "*" +jinja2 = "*" + +[[package]] +name = "lazy-object-proxy" +version = "1.10.0" +description = "A fast and thorough lazy object proxy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, + {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, +] + +[[package]] +name = "loguru" +version = "0.7.2" +description = "Python logging made (stupidly) simple" +optional = false +python-versions = ">=3.5" +files = [ + {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, + {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, +] + +[package.dependencies] +colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} +win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} + +[package.extras] +dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] + +[[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 = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[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 = "mypy" +version = "1.11.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, + {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, + {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, + {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, + {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, + {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, + {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, + {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, + {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, + {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, + {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, + {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, + {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, + {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, + {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, + {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, + {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, + {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +typing-extensions = ">=4.6.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[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 = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "port-ocean" +version = "0.10.0" +description = "Port Ocean is a CLI tool for managing your Port projects." +optional = false +python-versions = "<4.0,>=3.11" +files = [ + {file = "port_ocean-0.10.0-py3-none-any.whl", hash = "sha256:1bb21cca26cd680e3dea78da44bf3b14d6a3822979dd7326555e1b02ca055a6a"}, + {file = "port_ocean-0.10.0.tar.gz", hash = "sha256:54c44af4a41a9eb48c7cf83ca16064f09a38dc4098b95c240581e0159b4dd72a"}, +] + +[package.dependencies] +aiostream = ">=0.5.2,<0.7.0" +click = {version = ">=8.1.3,<9.0.0", optional = true, markers = "extra == \"cli\""} +confluent-kafka = ">=2.1.1,<3.0.0" +cookiecutter = {version = ">=2.1.1,<3.0.0", optional = true, markers = "extra == \"cli\""} +fastapi = ">=0.100,<0.112" +httpx = ">=0.24.1,<0.28.0" +jinja2-time = {version = ">=0.2.0,<0.3.0", optional = true, markers = "extra == \"cli\""} +loguru = ">=0.7.0,<0.8.0" +pydantic = {version = ">=1.10.8,<2.0.0", extras = ["dotenv"]} +pydispatcher = ">=2.0.7,<3.0.0" +pyhumps = ">=3.8.0,<4.0.0" +pyjq = ">=2.6.0,<3.0.0" +python-dateutil = ">=2.9.0.post0,<3.0.0" +pyyaml = ">=6.0,<7.0" +rich = {version = ">=13.4.1,<14.0.0", optional = true, markers = "extra == \"cli\""} +six = ">=1.16.0,<2.0.0" +tomli = ">=2.0.1,<3.0.0" +urllib3 = ">=1.26.16,<3.0.0" +uvicorn = ">=0.22,<0.31" +werkzeug = ">=2.3.4,<4.0.0" + +[package.extras] +cli = ["click (>=8.1.3,<9.0.0)", "cookiecutter (>=2.1.1,<3.0.0)", "jinja2-time (>=0.2.0,<0.3.0)", "rich (>=13.4.1,<14.0.0)"] + +[[package]] +name = "pydantic" +version = "1.10.17" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, + {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, + {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, + {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, + {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, + {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, + {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, + {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, + {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, + {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, + {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, + {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, + {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, + {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, + {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, + {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, + {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, + {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, + {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, + {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, + {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, + {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, + {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, + {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, + {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, + {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, + {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, + {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, + {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, + {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, + {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, + {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, + {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, + {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, + {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, + {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, + {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, + {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, + {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, + {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, + {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, + {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, + {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, +] + +[package.dependencies] +python-dotenv = {version = ">=0.10.4", optional = true, markers = "extra == \"dotenv\""} +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pydispatcher" +version = "2.0.7" +description = "Multi-producer multi-consumer in-memory signal dispatch system" +optional = false +python-versions = "*" +files = [ + {file = "PyDispatcher-2.0.7-py3-none-any.whl", hash = "sha256:96543bea04115ffde08f851e1d45cacbfd1ee866ac42127d9b476dc5aefa7de0"}, + {file = "PyDispatcher-2.0.7.tar.gz", hash = "sha256:b777c6ad080dc1bad74a4c29d6a46914fa6701ac70f94b0d66fbcfde62f5be31"}, +] + +[package.extras] +dev = ["tox"] + +[[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 = "pyhumps" +version = "3.8.0" +description = "🐫 Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node" +optional = false +python-versions = "*" +files = [ + {file = "pyhumps-3.8.0-py3-none-any.whl", hash = "sha256:060e1954d9069f428232a1adda165db0b9d8dfdce1d265d36df7fbff540acfd6"}, + {file = "pyhumps-3.8.0.tar.gz", hash = "sha256:498026258f7ee1a8e447c2e28526c0bea9407f9a59c03260aee4bd6c04d681a3"}, +] + +[[package]] +name = "pyjq" +version = "2.6.0" +description = "Binding for jq JSON processor." +optional = false +python-versions = "*" +files = [ + {file = "pyjq-2.6.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:6e0e4f398e81b1fb9794874d81fc9240d4a155adba5a1aecda77e717bcfae03e"}, + {file = "pyjq-2.6.0.tar.gz", hash = "sha256:e083f326f4af8b07b8ca6424d1f99afbdd7db9b727284da5f919b9816077f2e4"}, +] + +[[package]] +name = "pylint" +version = "2.17.7" +description = "python code static checker" +optional = false +python-versions = ">=3.7.2" +files = [ + {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"}, + {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"}, +] + +[package.dependencies] +astroid = ">=2.15.8,<=2.17.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = {version = ">=0.3.6", markers = "python_version >= \"3.11\""} +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomlkit = ">=0.10.1" + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + +[[package]] +name = "pytest" +version = "7.4.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[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 = "python-multipart" +version = "0.0.9" +description = "A streaming multipart parser for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"}, + {file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"}, +] + +[package.extras] +dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatch", "invoke (==2.2.0)", "more-itertools (==10.2.0)", "pbr (==6.0.0)", "pluggy (==1.4.0)", "py (==1.11.0)", "pytest (==8.0.0)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.2.0)", "pyyaml (==6.0.1)", "ruff (==0.2.1)"] + +[[package]] +name = "python-slugify" +version = "8.0.4" +description = "A Python slugify application that also handles Unicode" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, + {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[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 = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[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 = "ruff" +version = "0.0.278" +description = "An extremely fast Python linter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.0.278-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:1a90ebd8f2a554db1ee8d12b2f3aa575acbd310a02cd1a9295b3511a4874cf98"}, + {file = "ruff-0.0.278-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:38ca1c0c8c1221fe64c0a66784c91501d09a8ed02a4dbfdc117c0ce32a81eefc"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c62a0bde4d20d087cabce2fa8b012d74c2e985da86d00fb3359880469b90e31"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7545bb037823cd63dca19280f75a523a68bd3e78e003de74609320d6822b5a52"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb380d2d6fdb60656a0b5fa78305535db513fc72ce11f4532cc1641204ef380"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d11149c7b186f224f2055e437a030cd83b164a43cc0211314c33ad1553ed9c4c"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666e739fb2685277b879d493848afe6933e3be30d40f41fe0e571ad479d57d77"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ec8b0469b54315803aaf1fbf9a37162a3849424cab6182496f972ad56e0ea702"}, + {file = "ruff-0.0.278-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c25b96602695a147d62a572865b753ef56aff1524abab13b9436724df30f9bd7"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a48621f5f372d5019662db5b3dbfc5f1450f927683d75f1153fe0ebf20eb9698"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1078125123a3c68e92463afacedb7e41b15ccafc09e510c6c755a23087afc8de"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3ce0d620e257b4cad16e2f0c103b2f43a07981668a3763380542e8a131d11537"}, + {file = "ruff-0.0.278-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1cae4c07d334eb588f171f1363fa89a8911047eb93184276be11a24dbbc996c7"}, + {file = "ruff-0.0.278-py3-none-win32.whl", hash = "sha256:70d39f5599d8449082ab8ce542fa98e16413145eb411dd1dc16575b44565d52d"}, + {file = "ruff-0.0.278-py3-none-win_amd64.whl", hash = "sha256:e131595ab7f4ce61a1650463bd2fe304b49e7d0deb0dfa664b92817c97cdba5f"}, + {file = "ruff-0.0.278-py3-none-win_arm64.whl", hash = "sha256:737a0cfb6c36aaa92d97a46957dfd5e55329299074ad06ed12663b98e0c6fc82"}, + {file = "ruff-0.0.278.tar.gz", hash = "sha256:1a9f1d925204cfba81b18368b7ac943befcfccc3a41e170c91353b674c6b7a66"}, +] + +[[package]] +name = "setuptools" +version = "72.1.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, + {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, +] + +[package.extras] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + +[[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 = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "starlette" +version = "0.37.2" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.8" +files = [ + {file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"}, + {file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"}, +] + +[package.dependencies] +anyio = ">=3.4.0,<5" + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] + +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tomlkit" +version = "0.13.0" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, + {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, +] + +[[package]] +name = "towncrier" +version = "23.11.0" +description = "Building newsfiles for your project." +optional = false +python-versions = ">=3.8" +files = [ + {file = "towncrier-23.11.0-py3-none-any.whl", hash = "sha256:2e519ca619426d189e3c98c99558fe8be50c9ced13ea1fc20a4a353a95d2ded7"}, + {file = "towncrier-23.11.0.tar.gz", hash = "sha256:13937c247e3f8ae20ac44d895cf5f96a60ad46cfdcc1671759530d7837d9ee5d"}, +] + +[package.dependencies] +click = "*" +incremental = "*" +jinja2 = "*" + +[package.extras] +dev = ["furo", "packaging", "sphinx (>=5)", "twisted"] + +[[package]] +name = "typer" +version = "0.12.3" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +files = [ + {file = "typer-0.12.3-py3-none-any.whl", hash = "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914"}, + {file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20240316" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, +] + +[[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 = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[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 = "uvicorn" +version = "0.30.5" +description = "The lightning-fast ASGI server." +optional = false +python-versions = ">=3.8" +files = [ + {file = "uvicorn-0.30.5-py3-none-any.whl", hash = "sha256:b2d86de274726e9878188fa07576c9ceeff90a839e2b6e25c917fe05f5a6c835"}, + {file = "uvicorn-0.30.5.tar.gz", hash = "sha256:ac6fdbd4425c5fd17a9fe39daf4d4d075da6fdc80f653e5894cdc2fd98752bee"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} +h11 = ">=0.8" +httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} +python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} +uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} + +[package.extras] +standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] + +[[package]] +name = "uvloop" +version = "0.19.0" +description = "Fast implementation of asyncio event loop on top of libuv" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, + {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, +] + +[package.extras] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] + +[[package]] +name = "watchfiles" +version = "0.22.0" +description = "Simple, modern and high performance file watching and code reload in python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchfiles-0.22.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538"}, + {file = "watchfiles-0.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61af9efa0733dc4ca462347becb82e8ef4945aba5135b1638bfc20fad64d4f0e"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d9188979a58a096b6f8090e816ccc3f255f137a009dd4bbec628e27696d67c1"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2bdadf6b90c099ca079d468f976fd50062905d61fae183f769637cb0f68ba59a"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:067dea90c43bf837d41e72e546196e674f68c23702d3ef80e4e816937b0a3ffd"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbf8a20266136507abf88b0df2328e6a9a7c7309e8daff124dda3803306a9fdb"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1235c11510ea557fe21be5d0e354bae2c655a8ee6519c94617fe63e05bca4171"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2444dc7cb9d8cc5ab88ebe792a8d75709d96eeef47f4c8fccb6df7c7bc5be71"}, + {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c5af2347d17ab0bd59366db8752d9e037982e259cacb2ba06f2c41c08af02c39"}, + {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9624a68b96c878c10437199d9a8b7d7e542feddda8d5ecff58fdc8e67b460848"}, + {file = "watchfiles-0.22.0-cp310-none-win32.whl", hash = "sha256:4b9f2a128a32a2c273d63eb1fdbf49ad64852fc38d15b34eaa3f7ca2f0d2b797"}, + {file = "watchfiles-0.22.0-cp310-none-win_amd64.whl", hash = "sha256:2627a91e8110b8de2406d8b2474427c86f5a62bf7d9ab3654f541f319ef22bcb"}, + {file = "watchfiles-0.22.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8c39987a1397a877217be1ac0fb1d8b9f662c6077b90ff3de2c05f235e6a8f96"}, + {file = "watchfiles-0.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a927b3034d0672f62fb2ef7ea3c9fc76d063c4b15ea852d1db2dc75fe2c09696"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052d668a167e9fc345c24203b104c313c86654dd6c0feb4b8a6dfc2462239249"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e45fb0d70dda1623a7045bd00c9e036e6f1f6a85e4ef2c8ae602b1dfadf7550"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c49b76a78c156979759d759339fb62eb0549515acfe4fd18bb151cc07366629c"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a65474fd2b4c63e2c18ac67a0c6c66b82f4e73e2e4d940f837ed3d2fd9d4da"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc0cba54f47c660d9fa3218158b8963c517ed23bd9f45fe463f08262a4adae1"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ebe84a035993bb7668f58a0ebf998174fb723a39e4ef9fce95baabb42b787f"}, + {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e0f0a874231e2839abbf473256efffe577d6ee2e3bfa5b540479e892e47c172d"}, + {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:213792c2cd3150b903e6e7884d40660e0bcec4465e00563a5fc03f30ea9c166c"}, + {file = "watchfiles-0.22.0-cp311-none-win32.whl", hash = "sha256:b44b70850f0073b5fcc0b31ede8b4e736860d70e2dbf55701e05d3227a154a67"}, + {file = "watchfiles-0.22.0-cp311-none-win_amd64.whl", hash = "sha256:00f39592cdd124b4ec5ed0b1edfae091567c72c7da1487ae645426d1b0ffcad1"}, + {file = "watchfiles-0.22.0-cp311-none-win_arm64.whl", hash = "sha256:3218a6f908f6a276941422b035b511b6d0d8328edd89a53ae8c65be139073f84"}, + {file = "watchfiles-0.22.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c7b978c384e29d6c7372209cbf421d82286a807bbcdeb315427687f8371c340a"}, + {file = "watchfiles-0.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd4c06100bce70a20c4b81e599e5886cf504c9532951df65ad1133e508bf20be"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:425440e55cd735386ec7925f64d5dde392e69979d4c8459f6bb4e920210407f2"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68fe0c4d22332d7ce53ad094622b27e67440dacefbaedd29e0794d26e247280c"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8a31bfd98f846c3c284ba694c6365620b637debdd36e46e1859c897123aa232"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc2e8fe41f3cac0660197d95216c42910c2b7e9c70d48e6d84e22f577d106fc1"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b7cc10261c2786c41d9207193a85c1db1b725cf87936df40972aab466179b6"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28585744c931576e535860eaf3f2c0ec7deb68e3b9c5a85ca566d69d36d8dd27"}, + {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00095dd368f73f8f1c3a7982a9801190cc88a2f3582dd395b289294f8975172b"}, + {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:52fc9b0dbf54d43301a19b236b4a4614e610605f95e8c3f0f65c3a456ffd7d35"}, + {file = "watchfiles-0.22.0-cp312-none-win32.whl", hash = "sha256:581f0a051ba7bafd03e17127735d92f4d286af941dacf94bcf823b101366249e"}, + {file = "watchfiles-0.22.0-cp312-none-win_amd64.whl", hash = "sha256:aec83c3ba24c723eac14225194b862af176d52292d271c98820199110e31141e"}, + {file = "watchfiles-0.22.0-cp312-none-win_arm64.whl", hash = "sha256:c668228833c5619f6618699a2c12be057711b0ea6396aeaece4ded94184304ea"}, + {file = "watchfiles-0.22.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d47e9ef1a94cc7a536039e46738e17cce058ac1593b2eccdede8bf72e45f372a"}, + {file = "watchfiles-0.22.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28f393c1194b6eaadcdd8f941307fc9bbd7eb567995232c830f6aef38e8a6e88"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd64f3a4db121bc161644c9e10a9acdb836853155a108c2446db2f5ae1778c3d"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2abeb79209630da981f8ebca30a2c84b4c3516a214451bfc5f106723c5f45843"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cc382083afba7918e32d5ef12321421ef43d685b9a67cc452a6e6e18920890e"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d048ad5d25b363ba1d19f92dcf29023988524bee6f9d952130b316c5802069cb"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:103622865599f8082f03af4214eaff90e2426edff5e8522c8f9e93dc17caee13"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3e1f3cf81f1f823e7874ae563457828e940d75573c8fbf0ee66818c8b6a9099"}, + {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8597b6f9dc410bdafc8bb362dac1cbc9b4684a8310e16b1ff5eee8725d13dcd6"}, + {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0b04a2cbc30e110303baa6d3ddce8ca3664bc3403be0f0ad513d1843a41c97d1"}, + {file = "watchfiles-0.22.0-cp38-none-win32.whl", hash = "sha256:b610fb5e27825b570554d01cec427b6620ce9bd21ff8ab775fc3a32f28bba63e"}, + {file = "watchfiles-0.22.0-cp38-none-win_amd64.whl", hash = "sha256:fe82d13461418ca5e5a808a9e40f79c1879351fcaeddbede094028e74d836e86"}, + {file = "watchfiles-0.22.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3973145235a38f73c61474d56ad6199124e7488822f3a4fc97c72009751ae3b0"}, + {file = "watchfiles-0.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:280a4afbc607cdfc9571b9904b03a478fc9f08bbeec382d648181c695648202f"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a0d883351a34c01bd53cfa75cd0292e3f7e268bacf2f9e33af4ecede7e21d1d"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9165bcab15f2b6d90eedc5c20a7f8a03156b3773e5fb06a790b54ccecdb73385"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc1b9b56f051209be458b87edb6856a449ad3f803315d87b2da4c93b43a6fe72"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc1fc25a1dedf2dd952909c8e5cb210791e5f2d9bc5e0e8ebc28dd42fed7562"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc92d2d2706d2b862ce0568b24987eba51e17e14b79a1abcd2edc39e48e743c8"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97b94e14b88409c58cdf4a8eaf0e67dfd3ece7e9ce7140ea6ff48b0407a593ec"}, + {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96eec15e5ea7c0b6eb5bfffe990fc7c6bd833acf7e26704eb18387fb2f5fd087"}, + {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:28324d6b28bcb8d7c1041648d7b63be07a16db5510bea923fc80b91a2a6cbed6"}, + {file = "watchfiles-0.22.0-cp39-none-win32.whl", hash = "sha256:8c3e3675e6e39dc59b8fe5c914a19d30029e36e9f99468dddffd432d8a7b1c93"}, + {file = "watchfiles-0.22.0-cp39-none-win_amd64.whl", hash = "sha256:25c817ff2a86bc3de3ed2df1703e3d24ce03479b27bb4527c57e722f8554d971"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b810a2c7878cbdecca12feae2c2ae8af59bea016a78bc353c184fa1e09f76b68"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7e1f9c5d1160d03b93fc4b68a0aeb82fe25563e12fbcdc8507f8434ab6f823c"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030bc4e68d14bcad2294ff68c1ed87215fbd9a10d9dea74e7cfe8a17869785ab"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace7d060432acde5532e26863e897ee684780337afb775107c0a90ae8dbccfd2"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5834e1f8b71476a26df97d121c0c0ed3549d869124ed2433e02491553cb468c2"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:0bc3b2f93a140df6806c8467c7f51ed5e55a931b031b5c2d7ff6132292e803d6"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fdebb655bb1ba0122402352b0a4254812717a017d2dc49372a1d47e24073795"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c8e0aa0e8cc2a43561e0184c0513e291ca891db13a269d8d47cb9841ced7c71"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2f350cbaa4bb812314af5dab0eb8d538481e2e2279472890864547f3fe2281ed"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7a74436c415843af2a769b36bf043b6ccbc0f8d784814ba3d42fc961cdb0a9dc"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00ad0bcd399503a84cc688590cdffbe7a991691314dde5b57b3ed50a41319a31"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72a44e9481afc7a5ee3291b09c419abab93b7e9c306c9ef9108cb76728ca58d2"}, + {file = "watchfiles-0.22.0.tar.gz", hash = "sha256:988e981aaab4f3955209e7e28c7794acdb690be1efa7f16f8ea5aba7ffdadacb"}, +] + +[package.dependencies] +anyio = ">=3.0.0" + +[[package]] +name = "websockets" +version = "12.0" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, +] + +[[package]] +name = "werkzeug" +version = "3.0.3" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"}, + {file = "werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "win32-setctime" +version = "1.1.0" +description = "A small Python utility to set file creation time on Windows" +optional = false +python-versions = ">=3.5" +files = [ + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, +] + +[package.extras] +dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "2bd671cb6603e82bccbe58c58592e2f8b27d1e65f42af6a46a3bbbd79146cd12" diff --git a/integrations/octopus/poetry.toml b/integrations/octopus/poetry.toml new file mode 100644 index 0000000000..99efa6fa7e --- /dev/null +++ b/integrations/octopus/poetry.toml @@ -0,0 +1,3 @@ +[virtualenvs] +create = true +in-project = true diff --git a/integrations/octopus/pyproject.toml b/integrations/octopus/pyproject.toml new file mode 100644 index 0000000000..bedf008515 --- /dev/null +++ b/integrations/octopus/pyproject.toml @@ -0,0 +1,102 @@ +[tool.poetry] +name = "octopus" +version = "0.1.0-beta" +description = "This integration ingest data from octopus deploy" +authors = ["Adebayo Iyanuoluwa "] + +[tool.poetry.dependencies] +python = "^3.11" +port_ocean = {extras = ["cli"], version = "^0.10.0"} + +[tool.poetry.group.dev.dependencies] +pytest = "^7.2" +black = "^23.3.0" +mypy = "^1.3.0" +ruff = "^0.0.278" +pylint = "^2.17.4" +towncrier = "^23.6.0" + +[tool.towncrier] +directory = "changelog" +filename = "CHANGELOG.md" +package = "port_ocean" + + [[tool.towncrier.type]] + directory = "breaking" + name = "Breaking Changes" + showcontent = true + + [[tool.towncrier.type]] + directory = "deprecation" + name = "Deprecations" + showcontent = true + + [[tool.towncrier.type]] + directory = "feature" + name = "Features" + showcontent = true + + [[tool.towncrier.type]] + directory = "improvement" + name = "Improvements" + showcontent = true + + [[tool.towncrier.type]] + directory = "bugfix" + name = "Bug Fixes" + showcontent = true + + [[tool.towncrier.type]] + directory = "doc" + name = "Improved Documentation" + showcontent = true + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" + +[tool.mypy] +exclude = [ + 'venv', + '.venv', +] +plugins = [ + "pydantic.mypy" +] + +follow_imports = "silent" +warn_redundant_casts = true +warn_unused_ignores = true +disallow_any_generics = true +check_untyped_defs = true +no_implicit_reexport = true + +# for strict mypy: (this is the tricky one :-)) +disallow_untyped_defs = true + + +[tool.ruff] +# Never enforce `E501` (line length violations). +ignore = ["E501"] + +[tool.pydantic-mypy] +init_forbid_extra = true +init_typed = true +warn_required_dynamic_aliases = true +warn_untyped_fields = true + +[tool.black] +line-length = 88 +target-version = ['py311'] +include = '\.pyi?$' +exclude = ''' +/( + \scripts + \.toml + |\.sh + |\.git + |\.ini + |Dockerfile + |\.venv +)/ +''' diff --git a/integrations/octopus/sonar-project.properties b/integrations/octopus/sonar-project.properties new file mode 100644 index 0000000000..cca05905d6 --- /dev/null +++ b/integrations/octopus/sonar-project.properties @@ -0,0 +1,3 @@ +sonar.projectKey=port-labs_ocean_octopus +sonar.organization=port-labs + diff --git a/integrations/octopus/tests/__init__.py b/integrations/octopus/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/integrations/octopus/tests/test_sample.py b/integrations/octopus/tests/test_sample.py new file mode 100644 index 0000000000..dc80e299c8 --- /dev/null +++ b/integrations/octopus/tests/test_sample.py @@ -0,0 +1,2 @@ +def test_example() -> None: + assert 1 == 1 From ec5b5fef5b26f2bbe5c0fb181d60dc308cefd62b Mon Sep 17 00:00:00 2001 From: Matan <51418643+matan84@users.noreply.github.com> Date: Sun, 25 Aug 2024 09:25:49 +0300 Subject: [PATCH 079/177] [GCP] Changed tf module for gcp integration (#921) # Description What - Changed GCP tf module Why - Detaches providers creation from the module to the customer's main.tf file to keep with terraform's best practices + more QOL changes with the module How - Changed the spec.yaml file ## Type of change Please leave one option from the following and delete the rest: - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] New Integration (non-breaking change which adds a new integration) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Non-breaking change (fix of existing functionality that will not change current behavior) - [x] Documentation (added/updated documentation) --- integrations/gcp/.port/spec.yaml | 39 +++----------------------------- integrations/gcp/CHANGELOG.md | 7 ++++++ integrations/gcp/pyproject.toml | 2 +- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/integrations/gcp/.port/spec.yaml b/integrations/gcp/.port/spec.yaml index 5ba5430620..2822fa9a2f 100644 --- a/integrations/gcp/.port/spec.yaml +++ b/integrations/gcp/.port/spec.yaml @@ -12,7 +12,7 @@ configurations: description: Base64 encoding of your Google Cloud's ADC Credentials configuration file. For more information, see the Google documentation deploymentMethodRequirements: - type: default - configurations: ['encodedADCConfiguration'] + configurations: ["encodedADCConfiguration"] deploymentMethodOverride: - type: helm - type: docker @@ -20,39 +20,6 @@ deploymentMethodOverride: - type: gitlabCI - type: terraform-gcp module: port-labs/integration-factory/ocean - example: gcp_integration_with_real_time + example: gcp_cloud_run title: GCP's Cloud Run - version: ">=0.0.25" - extraVars: - - name: assets_types_for_monitoring - description: A list of resources to filter events from Google Cloud. - required: true - default: - - "cloudresourcemanager.googleapis.com/Organization" - - "cloudresourcemanager.googleapis.com/Project" - - "storage.googleapis.com/Bucket" - - "cloudfunctions.googleapis.com/CloudFunction" - - "pubsub.googleapis.com/Subscription" - - "pubsub.googleapis.com/Topic" - - "container.googleapis.com/Cluster" - type: array - - name: gcp_ocean_integration_sa_permissions - description: A list of permissions that will be assigned to the Google Cloud Service account to export Google Cloud Resources. - required: true - default: - - "cloudasset.assets.exportResource" - - "cloudasset.assets.listCloudAssetFeeds" - - "cloudasset.assets.listResource" - - "cloudasset.assets.searchAllResources" - - "cloudasset.feeds.create" - - "cloudasset.feeds.list" - - "pubsub.topics.list" - - "pubsub.topics.get" - - "resourcemanager.projects.get" - - "resourcemanager.projects.list" - - "resourcemanager.folders.get" - - "resourcemanager.folders.list" - - "resourcemanager.organizations.get" - - "run.routes.invoke" - - "run.jobs.run" - type: array + version: ">=0.0.31" diff --git a/integrations/gcp/CHANGELOG.md b/integrations/gcp/CHANGELOG.md index 34bbe6e081..a1e663d68b 100644 --- a/integrations/gcp/CHANGELOG.md +++ b/integrations/gcp/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.43 (2024-08-25) + + +### Improvements + +- Changed tf module in order to detach provider creation from the module and QOL changes with the module (#1) + ## 0.1.42 (2024-08-22) diff --git a/integrations/gcp/pyproject.toml b/integrations/gcp/pyproject.toml index a1421bc9dc..e3d9a4ad83 100644 --- a/integrations/gcp/pyproject.toml +++ b/integrations/gcp/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "gcp" -version = "0.1.42" +version = "0.1.43" description = "A GCP ocean integration" authors = ["Matan Geva "] From 2b7377c242d6013f8511b872b4ade2a6be8bafa0 Mon Sep 17 00:00:00 2001 From: erikzaadi Date: Mon, 19 Aug 2024 11:21:20 +0300 Subject: [PATCH 080/177] Update cookiecutter to integration standards * Proper `.env.example` files * Update vscode launch configuration with new generated integration * Add initial static examples to see the integration quickly in Port, including example blueprints and mappings * Add unit test stub --- Makefile | 3 +- poetry.lock | 176 ++++++++++-------- port_ocean/cli/commands/new.py | 42 ++++- .../.env.example | 2 + .../.port/resources/blueprints.json | 41 ++++ .../.port/resources/port-app-config.yml | 16 ++ .../.port/spec.yaml | 12 +- .../CHANGELOG.md | 2 +- .../CONTRIBUTING.md | 7 + .../Makefile | 6 +- .../changelog/.gitignore | 1 + .../{{cookiecutter.integration_slug}}/main.py | 17 +- .../pyproject.toml | 10 +- port_ocean/config/settings.py | 11 +- pyproject.toml | 4 +- 15 files changed, 243 insertions(+), 107 deletions(-) create mode 100644 port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example create mode 100644 port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json create mode 100644 port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml create mode 100644 port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md diff --git a/Makefile b/Makefile index c01368dbce..dd5e2bf913 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ define run_checks cd $1; \ poetry check || exit_code=$$?;\ mypy . --exclude '/\.venv/' || exit_code=$$?; \ - ruff . || exit_code=$$?; \ + ruff check . || exit_code=$$?; \ black --check . || exit_code=$$?; \ yamllint . || exit_code=$$?; \ if [ $$exit_code -eq 1 ]; then \ @@ -55,6 +55,7 @@ install: $(call install_precommit) test/all: test + $(ACTIVATE) && \ pytest --import-mode=importlib -n auto ./port_ocean/tests ./integrations/*/tests install/all: install diff --git a/poetry.lock b/poetry.lock index ab89eb77ae..e5bb11e386 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1328,19 +1328,19 @@ files = [ [[package]] name = "setuptools" -version = "72.2.0" +version = "73.0.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, - {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, + {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, + {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] [[package]] name = "shellingham" @@ -1463,13 +1463,13 @@ typing-extensions = ">=3.7.4.3" [[package]] name = "types-python-dateutil" -version = "2.9.0.20240316" +version = "2.9.0.20240821" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, - {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, + {file = "types-python-dateutil-2.9.0.20240821.tar.gz", hash = "sha256:9649d1dcb6fef1046fb18bebe9ea2aa0028b160918518c34589a46045f6ebd98"}, + {file = "types_python_dateutil-2.9.0.20240821-py3-none-any.whl", hash = "sha256:f5889fcb4e63ed4aaa379b44f93c32593d50b9a94c9a60a0c854d8cc3511cd57"}, ] [[package]] @@ -1712,83 +1712,97 @@ anyio = ">=3.0.0" [[package]] name = "websockets" -version = "12.0" +version = "13.0" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" files = [ - {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, - {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, - {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, - {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, - {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, - {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, - {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, - {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, - {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, - {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, - {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, - {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, - {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, - {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, - {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, - {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, - {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, - {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, - {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, - {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, - {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, - {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, - {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, - {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, - {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, - {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, - {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, - {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, - {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, - {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, - {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, - {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, - {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, - {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, - {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, - {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, - {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, - {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, - {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, - {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, - {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, - {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, - {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, - {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, - {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, - {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, - {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, - {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, - {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, - {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, - {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, - {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, - {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, - {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, - {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, - {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, - {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, - {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, - {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, - {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, - {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, - {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, - {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, - {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, - {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, - {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, - {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, - {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, - {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, - {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, - {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, - {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, + {file = "websockets-13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528"}, + {file = "websockets-13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e"}, + {file = "websockets-13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37"}, + {file = "websockets-13.0-cp310-cp310-win32.whl", hash = "sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424"}, + {file = "websockets-13.0-cp310-cp310-win_amd64.whl", hash = "sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8"}, + {file = "websockets-13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0"}, + {file = "websockets-13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709"}, + {file = "websockets-13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f"}, + {file = "websockets-13.0-cp311-cp311-win32.whl", hash = "sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a"}, + {file = "websockets-13.0-cp311-cp311-win_amd64.whl", hash = "sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452"}, + {file = "websockets-13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107"}, + {file = "websockets-13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4"}, + {file = "websockets-13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a"}, + {file = "websockets-13.0-cp312-cp312-win32.whl", hash = "sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53"}, + {file = "websockets-13.0-cp312-cp312-win_amd64.whl", hash = "sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a"}, + {file = "websockets-13.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278"}, + {file = "websockets-13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3"}, + {file = "websockets-13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0"}, + {file = "websockets-13.0-cp313-cp313-win32.whl", hash = "sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687"}, + {file = "websockets-13.0-cp313-cp313-win_amd64.whl", hash = "sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e"}, + {file = "websockets-13.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178"}, + {file = "websockets-13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a"}, + {file = "websockets-13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796"}, + {file = "websockets-13.0-cp38-cp38-win32.whl", hash = "sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa"}, + {file = "websockets-13.0-cp38-cp38-win_amd64.whl", hash = "sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41"}, + {file = "websockets-13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8"}, + {file = "websockets-13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33"}, + {file = "websockets-13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717"}, + {file = "websockets-13.0-cp39-cp39-win32.whl", hash = "sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c"}, + {file = "websockets-13.0-cp39-cp39-win_amd64.whl", hash = "sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a"}, + {file = "websockets-13.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417"}, + {file = "websockets-13.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273"}, + {file = "websockets-13.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d"}, + {file = "websockets-13.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68"}, + {file = "websockets-13.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d"}, + {file = "websockets-13.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c"}, + {file = "websockets-13.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966"}, + {file = "websockets-13.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e"}, + {file = "websockets-13.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f"}, + {file = "websockets-13.0-py3-none-any.whl", hash = "sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de"}, + {file = "websockets-13.0.tar.gz", hash = "sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602"}, ] [[package]] diff --git a/port_ocean/cli/commands/new.py b/port_ocean/cli/commands/new.py index ac4c2ae881..0a3b87d607 100644 --- a/port_ocean/cli/commands/new.py +++ b/port_ocean/cli/commands/new.py @@ -1,12 +1,39 @@ # -*- coding: utf-8 -*- import click +import json from cookiecutter.main import cookiecutter # type: ignore +import os from port_ocean.cli.commands.main import cli_start, print_logo, console from port_ocean.cli.utils import cli_root_path +def add_vscode_configuration(result: str, name: str) -> None: + vscode_entry_root_path = "${workspaceFolder}/integrations/" + name + new_vscode_entry = { + "console": "integratedTerminal", + "cwd": vscode_entry_root_path, + "envFile": f"{vscode_entry_root_path}/.env", + "justMyCode": True, + "name": f"Run {name} integration", + "program": f"{vscode_entry_root_path}/debug.py", + "python": f"{vscode_entry_root_path}/.venv/bin/python", + "request": "launch", + "type": "debugpy", + } + + vs_code_json_path = os.path.join(os.path.dirname(result), "../.vscode/launch.json") + if not os.path.exists(vs_code_json_path): + return + vs_code_json = json.load(open(vs_code_json_path, "r")) + vs_code_json["configurations"].append(new_vscode_entry) + + with open(vs_code_json_path, "w") as vs_code_json_file: + json.dump(vs_code_json, vs_code_json_file, indent=2) + vs_code_json_file.write("\n") + + @cli_start.command() @click.argument("path", default=".", type=click.Path(exists=True)) @click.option( @@ -37,6 +64,9 @@ def new(path: str, is_private_integration: bool) -> None: ) name = result.split("/")[-1] + if not is_private_integration: + add_vscode_configuration(result, name) + console.print( "\n🌊 Ahoy, Captain! Your project is ready to set sail into the vast ocean of possibilities!", style="bold", @@ -47,10 +77,14 @@ def new(path: str, is_private_integration: bool) -> None: f"▶️ [bold][blue]cd {path}/{name} && make install && . .venv/bin/activate[/blue][/bold]\n" ) console.print( - "⚓️ Set sail with [blue]Ocean[/blue]: Run [bold][blue]ocean sail[/blue] [/bold] to run the project using Ocean.\n" - f"▶️ [bold][blue]ocean sail {path}/{name}[/blue][/bold] \n" + f"⚓️ Copy example env file: Run [bold][blue]cp {path}/{name}.env.example {path}/{name}/.env [/blue][/bold] and set your port credentials in the created file.\n" ) console.print( - "⚓️ Smooth sailing with [blue]Make[/blue]: Alternatively, you can run [bold][blue]make run[/blue][/bold] to launch your project using Make. \n" - f"▶️ [bold][blue]make run {path}/{name}[/blue][/bold]" + "⚓️ Set sail with [blue]Ocean[/blue]: Run [bold][blue]ocean sail[/blue] [/bold] to run the project using Ocean.\n" + f"▶️ [bold][blue]ocean sail {path}/{name}[/blue][/bold] \n" ) + if not is_private_integration: + console.print( + "⚓️ Smooth sailing with [blue]Make[/blue]: Alternatively, you can run [bold][blue]make run[/blue][/bold] to launch your project using Make. \n" + f"▶️ [bold][blue]make run {path}/{name}[/blue][/bold]" + ) diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example new file mode 100644 index 0000000000..263a38a9c0 --- /dev/null +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example @@ -0,0 +1,2 @@ +OCEAN__PORT__CLIENT_ID="" +OCEAN__PORT__CLIENT_SECRET="" diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json new file mode 100644 index 0000000000..79410f8b70 --- /dev/null +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json @@ -0,0 +1,41 @@ +[ + { + "identifier": "{{ cookiecutter.integration_slug }}ExampleBlueprint", + "title": "{{ cookiecutter.integration_name }} Example", + "icon": "Blueprint", + "schema": { + "properties": { + "status": { + "type": "string", + "enum": [ + "VALID", + "FAILED" + ], + "enumColors": { + "VALID": "green", + "FAILED": "red" + }, + "title": "Status" + }, + "text": { + "type": "string", + "title": "Text" + }, + "component": { + "type": "string", + "title": "Component" + }, + "service": { + "type": "string", + "title": "Service" + }, + "score": { + "type": "number", + "title": "Score" + } + }, + "required": [] + }, + "relations": {} + } +] diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml new file mode 100644 index 0000000000..0090812fcb --- /dev/null +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml @@ -0,0 +1,16 @@ +resources: + - kind: {{ cookiecutter.integration_slug}}-example-kind + selector: + query: 'true' + port: + entity: + mappings: + identifier: .my_custom_id + title: '(.my_component + " @ " + .my_service)' + blueprint: '"{{ cookiecutter.integration_slug }}ExampleBlueprint"' + properties: + status: .my_enum + text: .my_custom_text + component: .my_component + service: .my_service + score: .my_special_score diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml index 30f2752450..f781358547 100644 --- a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml @@ -1,14 +1,14 @@ description: {{cookiecutter.integration_name}} integration for Port Ocean -icon: Cookiecutter # Should be one of the available icons in Port +icon: Cookiecutter # Should be one of the available icons in Port features: - type: exporter - section: Git Providers # Should be one of the available sections in Port + section: Under Development # Should be one of the available sections in Port resources: - - kind: - - kind: + - kind: {{ cookiecutter.integration_slug }}-example-kind + # - kind: configurations: - - name: myGitToken - required: true + - name: my{{ cookiecutter.integration_slug}}Token + # required: true type: string sensitive: true - name: someApplicationUrl diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md index 14e279d66d..6af0ab71ad 100644 --- a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md @@ -1,4 +1,4 @@ -# Changelog +# Changelog - Ocean - {{ cookiecutter.integration_slug }} All notable changes to this project will be documented in this file. diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md new file mode 100644 index 0000000000..148fc12741 --- /dev/null +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Contributing to Ocean - {{ cookiecutter.integration_slug }} + +## Running locally + +#### NOTE: Add your own instructions of how to run {{ cookiecutter.integration_slug }} + +This could be any gotcha's such as rate limiting, how to setup credentials and so forth diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/Makefile b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/Makefile index 9808e60140..0ef42cab54 100644 --- a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/Makefile +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/Makefile @@ -55,8 +55,8 @@ lint: run: $(ACTIVATE) && ocean sail -test: lint - $(ACTIVATE) && poetry run pytest +test: + $(ACTIVATE) && poetry run pytest -n auto clean: @find . -name '.venv' -type d -exec rm -rf {} \; @@ -71,4 +71,4 @@ clean: rm -rf htmlcov rm -rf .tox/ rm -rf docs/_build - rm -rf dist/ \ No newline at end of file + rm -rf dist/ diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore index f935021a8f..d6b7ef32c8 100644 --- a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore @@ -1 +1,2 @@ +* !.gitignore diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py index 48f98141e9..433ee913cc 100644 --- a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py @@ -15,6 +15,21 @@ async def on_resync(kind: str) -> list[dict[Any, Any]]: # return [{"some_project_key": "someProjectValue", ...}] # if kind == "issues": # return [{"some_issue_key": "someIssueValue", ...}] + + # Initial stub to show complete flow, replace this with your own logic + if kind == "{{ cookiecutter.integration_slug }}-example-kind": + return [ + { + "my_custom_id": f"id_{x}", + "my_custom_text": f"very long text with {x} in it", + "my_special_score": x * 32 % 3, + "my_component": f"component-{x}", + "my_service": f"service-{x %2}", + "my_enum": "VALID" if x % 2 == 0 else "FAILED", + } + for x in range(25) + ] + return [] @@ -38,4 +53,4 @@ async def on_resync(kind: str) -> list[dict[Any, Any]]: async def on_start() -> None: # Something to do when the integration starts # For example create a client to query 3rd party services - GitHub, Jira, etc... - print("Starting integration") + print("Starting {{ cookiecutter.integration_slug }} integration") diff --git a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml index dcee42d4e2..dc1694ffa8 100644 --- a/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml +++ b/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml @@ -9,13 +9,17 @@ python = "^3.11" port_ocean = { version = "^{% version %}", extras = ["cli"] } [tool.poetry.group.dev.dependencies] +# Uncomment this if you want to debug the ocean core together with your integration +# port_ocean = { path = '../../', develop = true, extras = ['all'] } pytest = "^7.2" +pytest-xdist = "^3.6.1" +pre-commit = "^3.7.1" +requests = "^2.32.3" black = "^23.3.0" mypy = "^1.3.0" ruff = "^0.0.278" pylint = "^2.17.4" towncrier = "^23.6.0" -pytest-xdist = "^3.6.1" [tool.towncrier] directory = "changelog" @@ -54,8 +58,8 @@ underlines = [""] showcontent = true [build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" [tool.mypy] exclude = [ diff --git a/port_ocean/config/settings.py b/port_ocean/config/settings.py index 1de4829211..6a3fd3e7d4 100644 --- a/port_ocean/config/settings.py +++ b/port_ocean/config/settings.py @@ -1,4 +1,4 @@ -from typing import Any, Literal, Type +from typing import Any, Literal, Type, cast from pydantic import Extra, AnyHttpUrl, parse_obj_as, parse_raw_as from pydantic.class_validators import root_validator, validator @@ -55,9 +55,8 @@ def root_validator(cls, values: dict[str, Any]) -> dict[str, Any]: integ_type = get_integration_name() values["type"] = integ_type.lower() if integ_type else None - values["identifier"] = values.get( - "identifier", f"my-{integ_type}-integration".lower() - ) + if not values.get("identifier"): + values["identifier"] = f"my-{integ_type}-integration".lower() return values @@ -71,7 +70,9 @@ class IntegrationConfiguration(BaseOceanSettings, extra=Extra.allow): client_timeout: int = 30 send_raw_data_examples: bool = True port: PortSettings - event_listener: EventListenerSettingsType + event_listener: EventListenerSettingsType = Field( + default=cast(EventListenerSettingsType, {"type": "POLLING"}) + ) # If an identifier or type is not provided, it will be generated based on the integration name integration: IntegrationSettings = Field( default_factory=lambda: IntegrationSettings(type="", identifier="") diff --git a/pyproject.toml b/pyproject.toml index c0bf6bab0f..3f7678859a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,8 +31,8 @@ classifiers = [ ocean = "port_ocean.cli.cli:cli_start" [build-system] -requires = ["poetry-core"] -build-backend = "poetry.masonry.api" +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" [tool.poetry.dependencies] python = "^3.11" From fcdcd09d184f0f9b407af73eb38204a587f3d6cd Mon Sep 17 00:00:00 2001 From: omby8888 <160610297+omby8888@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:49:57 +0300 Subject: [PATCH 081/177] [Framework] Refer to entity in upsert entity response (#943) # Description What - Refer to entity in upsert entity response Why - Response from upsert entity api isn't processed right and causes ocean core to use the raw entity that contains dict typed relation instead of string which is the relation's entity identifier How - Simply refer to the entity key in a response that looks like {ok: true, entity: {...}} ## Type of change Please leave one option from the following and delete the rest: - [X] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] New Integration (non-breaking change which adds a new integration) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Non-breaking change (fix of existing functionality that will not change current behavior) - [ ] Documentation (added/updated documentation) ## Screenshots Include screenshots from your environment showing how the resources of the integration will look. ## API Documentation Provide links to the API documentation used for this integration. --- .idea/watcherTasks.xml | 2 +- CHANGELOG.md | 14 ++++++++++---- port_ocean/clients/port/mixins/entities.py | 2 +- pyproject.toml | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml index 6df1a76d86..78fc450138 100644 --- a/.idea/watcherTasks.xml +++ b/.idea/watcherTasks.xml @@ -1,7 +1,7 @@ - +