From b758d0dfda6a861f03417563743c47e2fef3755b Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Fri, 30 Aug 2024 19:38:56 +0100 Subject: [PATCH 01/49] feat(security): add approved rooms/users/domains as env variables (#277) * feat(security): add approved rooms/users/domains as env variables * chore(lint): fix R0902 * chore(lint): fix C0114 * chore(lint): fix C0116 * chore(lint): fix C0413 --- .env.default | 9 ++++++--- README.md | 6 ++++++ app/main.py | 8 ++++---- app/utils/config.py | 47 ++++++++++++++++++++++++++++++------------- app/utils/helpers.py | 16 +++++++++++++++ test.sh | 4 ++-- tests/test_config.py | 24 +++++++++++++++++----- tests/test_helpers.py | 23 +++++++++++++++++++++ 8 files changed, 109 insertions(+), 28 deletions(-) create mode 100644 app/utils/helpers.py create mode 100644 tests/test_helpers.py diff --git a/.env.default b/.env.default index 0c62acf..9008ecc 100644 --- a/.env.default +++ b/.env.default @@ -1,8 +1,11 @@ -APP_LIFECYCLE="dev" -SENTRY_ENABLED="False" -SENTRY_DSN="" ADMIN_EMAIL="" ADMIN_FIRST_NAME="" +APP_LIFECYCLE="dev" +APPROVED_DOMAINS="example.com,hello.com" +APPROVED_ROOMS="abc123,def456" +APPROVED_USERS="bob@example.com,john@me.com" BOT_NAME="" N8N_WEBHOOK_URL="" +SENTRY_DSN="" +SENTRY_ENABLED="False" WEBEX_API_KEY="" diff --git a/README.md b/README.md index 52be22e..d0349eb 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,14 @@ Add tasks to a Wekan to do list via Webex and n8n. 3. Edit `.env` as required: - `ADMIN_EMAIL` - comma-separated list of admin (who owns the to-do list) email addresses - `ADMIN_FIRST_NAME` - admin first name + - `APP_LIFECYCLE` - for use in Sentry only, set the name of the environment + - `APPROVED_DOMAINS` - comma-separated list of domains that users are allowed to message the bot from + - `APPROVED_ROOMS` - comma-separated list of room IDs that users are allowed to message the bot from + - `APPROVED_USERS` - comma-separated list of email addresses of approved users - `BOT_NAME` - Webex bot name - `N8N_WEBHOOK_URL` - n8n webhook URL + - `SENTRY_DSN` - for use in Sentry only, set the DSN of the Sentry project + - `SENTRY_ENABLED` - for use in Sentry only, enable sending data to Sentry - `WEBEX_API_KEY` - Webex API key ## How to use diff --git a/app/main.py b/app/main.py index 19df55a..c222c89 100644 --- a/app/main.py +++ b/app/main.py @@ -2,14 +2,12 @@ import sentry_sdk from sentry_sdk.integrations.stdlib import StdlibIntegration - from webex_bot.webex_bot import WebexBot from app.commands.exit import ExitCommand from app.commands.submit_task import SubmitTaskCommand from app.utils.config import config - if config.sentry_enabled: apm = sentry_sdk.init( dsn=config.sentry_dsn, @@ -17,7 +15,7 @@ if config.sentry_enabled: environment=config.environment, release=config.version, integrations=[StdlibIntegration()], - spotlight=True + spotlight=True, ) @@ -26,7 +24,9 @@ def create_bot() -> WebexBot: webex_bot: WebexBot = WebexBot( bot_name=config.bot_name, teams_bot_token=config.webex_token, - approved_domains=["cisco.com"], + approved_domains=config.approved_domains, + approved_rooms=config.approved_rooms, + approved_users=config.approved_users, ) webex_bot.commands.clear() webex_bot.add_command(SubmitTaskCommand()) diff --git a/app/utils/config.py b/app/utils/config.py index b9e6231..5cce4b4 100644 --- a/app/utils/config.py +++ b/app/utils/config.py @@ -2,19 +2,19 @@ import os +from app.utils.helpers import validate_email_syntax + class Config: """Configuration module.""" + def __init__(self) -> None: """Configuration module.""" - self.__environment: str = os.environ.get("APP_LIFECYCLE", "DEV").upper() - self.__version: str = os.environ["APP_VERSION"] - self.__bot_name: str = os.environ["BOT_NAME"] - self.__webex_token: str = os.environ["WEBEX_API_KEY"] - self.__admin_first_name: str = os.environ["ADMIN_FIRST_NAME"] - self.__admin_emails: list = os.environ["ADMIN_EMAIL"].split(",") - self.__n8n_webhook_url: str = os.environ["N8N_WEBHOOK_URL"] + + # Sentry config needs to be processed first for loop prevention. + self.__sentry_dsn: str = os.environ.get("SENTRY_DSN", "") + self.__sentry_enabled: bool = bool( os.environ.get("SENTRY_ENABLED", "False").upper() == "TRUE" and self.__sentry_dsn != "" @@ -23,12 +23,12 @@ class Config: @property def environment(self) -> str: """Returns the current app lifecycle.""" - return self.__environment + return os.environ.get("APP_LIFECYCLE", "DEV").upper() @property def version(self) -> str: """Returns the current app version.""" - return self.__version + return os.environ["APP_VERSION"] @property def sentry_enabled(self) -> bool: @@ -46,27 +46,46 @@ class Config: @property def bot_name(self) -> str: """Returns the bot name.""" - return self.__bot_name + return os.environ["BOT_NAME"] @property def webex_token(self) -> str: """Returns the Webex API key.""" - return self.__webex_token + return os.environ["WEBEX_API_KEY"] @property def admin_first_name(self) -> str: """Returns the first name of the bot admin.""" - return self.__admin_first_name + return os.environ["ADMIN_FIRST_NAME"] @property def admin_emails(self) -> list: """Returns a list of admin email addresses.""" - return self.__admin_emails + return os.environ["ADMIN_EMAIL"].split(",") @property def n8n_webhook_url(self) -> str: """Returns the n8n webhook URL.""" - return self.__n8n_webhook_url + return os.environ["N8N_WEBHOOK_URL"] + + @property + def approved_users(self) -> list: + """Returns a list of approved users.""" + emails: list[str] = os.environ.get("APPROVED_USERS", "").split(",") + emails = [i.strip() for i in emails if validate_email_syntax(i.strip())] + return emails + + @property + def approved_rooms(self) -> list: + """Returns a list of approved rooms.""" + rooms: list[str] = os.environ.get("APPROVED_ROOMS", "").split(",") + return [i.strip() for i in rooms] + + @property + def approved_domains(self) -> list: + """Returns a list of approved domains.""" + domains: list[str] = os.environ.get("APPROVED_DOMAINS", "").split(",") + return [i.strip() for i in domains] config: Config = Config() diff --git a/app/utils/helpers.py b/app/utils/helpers.py new file mode 100644 index 0000000..8130666 --- /dev/null +++ b/app/utils/helpers.py @@ -0,0 +1,16 @@ +"""Standalone helper functions.""" + +import re + + +def validate_email_syntax(email: str) -> bool: + """Validate email syntax. + + Args: + email (str): Email address. + + Returns: + bool: True if valid, else False. + """ + pattern = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" + return re.match(pattern, email) is not None diff --git a/test.sh b/test.sh index 1fcaf08..ee3861d 100755 --- a/test.sh +++ b/test.sh @@ -1,3 +1,3 @@ -export $(cat .env | xargs) +export $(cat .env.test | xargs) python -B -m app.main -unset APP_LIFECYCLE SENTRY_ENABLED SENTRY_DSN BOT_NAME WEBEX_API_KEY ADMIN_FIRST_NAME ADMIN_EMAIL N8N_WEBHOOK_URL +unset ADMIN_EMAIL ADMIN_FIRST_NAME APP_LIFECYCLE APP_VERSION APPROVED_DOMAINS APPROVED_ROOMS APPROVED_USERS BOT_NAME N8N_WEBHOOK_URL SENTRY_DSN SENTRY_ENABLED WEBEX_API_KEY diff --git a/tests/test_config.py b/tests/test_config.py index b26465f..070f734 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 +# ruff: noqa: E402 pylint: disable=wrong-import-position + """Provides test cases for app/utils/config.py.""" import os - vars: dict = { "APP_VERSION": "dev", "BOT_NAME": "TestBot", @@ -13,7 +14,10 @@ vars: dict = { "ADMIN_EMAIL": "test@test.com", "N8N_WEBHOOK_URL": "https://n8n.test.com/webhook/abcdefg", "SENTRY_ENABLED": "false", - "SENTRY_DSN": "http://localhost" + "SENTRY_DSN": "http://localhost", + "APPROVED_USERS": "test@test.com", + "APPROVED_DOMAINS": "test.com", + "APPROVED_ROOMS": "test", } @@ -25,8 +29,18 @@ from app.utils.config import config # pragma: no cover def test_config() -> None: - assert config.bot_name == vars["BOT_NAME"] - assert config.webex_token == vars["WEBEX_API_KEY"] - assert config.admin_first_name == vars["ADMIN_FIRST_NAME"] assert config.admin_emails == vars["ADMIN_EMAIL"].split(",") + assert config.admin_first_name == vars["ADMIN_FIRST_NAME"] + assert config.approved_domains == vars["APPROVED_DOMAINS"].split(",") + assert config.approved_rooms == vars["APPROVED_ROOMS"].split(",") + assert config.approved_users == vars["APPROVED_USERS"].split(",") + assert config.bot_name == vars["BOT_NAME"] assert config.n8n_webhook_url == vars["N8N_WEBHOOK_URL"] + assert config.sentry_enabled == bool(vars["SENTRY_ENABLED"].upper() == "TRUE") + assert config.version == vars["APP_VERSION"] + assert config.webex_token == vars["WEBEX_API_KEY"] + + if config.sentry_enabled: + assert config.sentry_dsn == vars["SENTRY_DSN"] + else: + assert config.sentry_dsn == "" diff --git a/tests/test_helpers.py b/tests/test_helpers.py new file mode 100644 index 0000000..d5ac9a0 --- /dev/null +++ b/tests/test_helpers.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +"""Provides test cases for app/utils/helpers.py.""" + +from app.utils.helpers import validate_email_syntax # pragma: no cover + + +def test_validate_email_syntax_true() -> None: + """Test validate_email_syntax() with a real email address.""" + email: str = "test@test.com" + assert validate_email_syntax(email) + + +def test_validate_email_syntax_false1() -> None: + """Test validate_email_syntax() with an invalid email address.""" + email: str = "test@test" + assert not validate_email_syntax(email) + + +def test_validate_email_syntax_false2() -> None: + """Test validate_email_syntax() with an invalid email address.""" + email: str = "test" + assert not validate_email_syntax(email) From c0f06a8555d58c4e76f038a3c943066a6f1cdb9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 18:45:08 +0000 Subject: [PATCH 02/49] chore(pip-prod)(deps): bump certifi from 2024.7.4 to 2024.8.30 Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.7.4 to 2024.8.30. - [Commits](https://github.com/certifi/python-certifi/compare/2024.07.04...2024.08.30) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7e1dda8..34c9926 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ astroid==3.3.2 attrs==24.2.0 autopep8==2.3.1 backoff==2.2.1 -certifi==2024.7.4 +certifi==2024.8.30 cfgv==3.4.0 charset-normalizer==3.3.2 click==8.1.7 From 4305728d533f2928f537cb67e2691635745d9dcd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:58:53 +0000 Subject: [PATCH 03/49] chore(pip-prod)(deps): bump sentry-sdk from 2.13.0 to 2.14.0 Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.13.0 to 2.14.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.13.0...2.14.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 34c9926..07a5b6e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ python-dotenv==1.0.1 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.13.0 +sentry-sdk==2.14.0 six==1.16.0 toml==0.10.2 tomli==2.0.1 From 94a9e7fc10f36c4aa2471b80ba43d3d7fdce2ca0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:13:58 +0000 Subject: [PATCH 04/49] chore(pip-prod)(deps): bump virtualenv from 20.26.3 to 20.26.4 Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.26.3 to 20.26.4. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.26.3...20.26.4) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 07a5b6e..7fed91c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,7 +39,7 @@ toml==0.10.2 tomli==2.0.1 tomlkit==0.13.2 urllib3==2.2.2 -virtualenv==20.26.3 +virtualenv==20.26.4 webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 From 5cfe2a41d4ed7bb922e24156cf689404556af0a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:49:06 +0000 Subject: [PATCH 05/49] chore(pip-prod)(deps): bump platformdirs from 4.2.2 to 4.3.2 Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 4.2.2 to 4.3.2. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/tox-dev/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/4.2.2...4.3.2) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7fed91c..4a32e8a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ mypy-extensions==1.0.0 nodeenv==1.9.1 packaging==24.1 pathspec==0.12.1 -platformdirs==4.2.2 +platformdirs==4.3.2 pluggy==1.5.0 py==1.11.0 pycodestyle==2.12.1 From 268e7e7f6ab55986c1a95762274653fba9fc4466 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:43:51 +0000 Subject: [PATCH 06/49] chore(pip-prod)(deps): bump filelock from 3.15.4 to 3.16.0 Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.15.4 to 3.16.0. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.15.4...3.16.0) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4a32e8a..17be6b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ click==8.1.7 coloredlogs==15.0.1 dill==0.3.8 distlib==0.3.8 -filelock==3.15.4 +filelock==3.16.0 future==1.0.0 humanfriendly==10.0 identify==2.6.0 From 59536eac2c600f346b2aef1fc6b1258f79acf38f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:03:53 +0000 Subject: [PATCH 07/49] chore(pip-prod)(deps): bump urllib3 from 2.2.2 to 2.2.3 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.2...2.2.3) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 17be6b1..6f9df28 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,7 +38,7 @@ six==1.16.0 toml==0.10.2 tomli==2.0.1 tomlkit==0.13.2 -urllib3==2.2.2 +urllib3==2.2.3 virtualenv==20.26.4 webex-bot==0.5.2 webexteamssdk==1.6.1 From 9013262ed237c1bc27403b960275c8149201e2d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 16:13:26 +0000 Subject: [PATCH 08/49] chore(pip-prod)(deps): bump identify from 2.6.0 to 2.6.1 Bumps [identify](https://github.com/pre-commit/identify) from 2.6.0 to 2.6.1. - [Commits](https://github.com/pre-commit/identify/compare/v2.6.0...v2.6.1) --- updated-dependencies: - dependency-name: identify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6f9df28..196cac6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ distlib==0.3.8 filelock==3.16.0 future==1.0.0 humanfriendly==10.0 -identify==2.6.0 +identify==2.6.1 idna==3.8 iniconfig==2.0.0 lazy-object-proxy==1.10.0 From 4041beb6675144f47f2eccada956ff57a3fa39da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:17:19 +0000 Subject: [PATCH 09/49] chore(pip-prod)(deps): bump platformdirs from 4.3.2 to 4.3.3 Bumps [platformdirs](https://github.com/tox-dev/platformdirs) from 4.3.2 to 4.3.3. - [Release notes](https://github.com/tox-dev/platformdirs/releases) - [Changelog](https://github.com/tox-dev/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/tox-dev/platformdirs/compare/4.3.2...4.3.3) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 196cac6..bb582fa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ mypy-extensions==1.0.0 nodeenv==1.9.1 packaging==24.1 pathspec==0.12.1 -platformdirs==4.3.2 +platformdirs==4.3.3 pluggy==1.5.0 py==1.11.0 pycodestyle==2.12.1 From 3d7354bd27d50f835a12d9f307d998cafea40024 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:55:45 +0000 Subject: [PATCH 10/49] chore(pip-prod)(deps): bump idna from 3.8 to 3.10 Bumps [idna](https://github.com/kjd/idna) from 3.8 to 3.10. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](https://github.com/kjd/idna/compare/v3.8...v3.10) --- updated-dependencies: - dependency-name: idna dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bb582fa..fb8dd50 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ filelock==3.16.0 future==1.0.0 humanfriendly==10.0 identify==2.6.1 -idna==3.8 +idna==3.10 iniconfig==2.0.0 lazy-object-proxy==1.10.0 mccabe==0.7.0 From 90be5d3a79bd35af001930c90ab1c2c6e17ed925 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:28:54 +0000 Subject: [PATCH 11/49] chore(pip-prod)(deps): bump filelock from 3.16.0 to 3.16.1 Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.16.0 to 3.16.1. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.16.0...3.16.1) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fb8dd50..2490ee6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ click==8.1.7 coloredlogs==15.0.1 dill==0.3.8 distlib==0.3.8 -filelock==3.16.0 +filelock==3.16.1 future==1.0.0 humanfriendly==10.0 identify==2.6.1 From bcce79b5f03d9c31d8077bcefb6106a9d53d89ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:47:26 +0000 Subject: [PATCH 12/49] chore(pip-prod)(deps): bump virtualenv from 20.26.4 to 20.26.5 Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.26.4 to 20.26.5. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.26.4...20.26.5) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2490ee6..a42cdb0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,7 +39,7 @@ toml==0.10.2 tomli==2.0.1 tomlkit==0.13.2 urllib3==2.2.3 -virtualenv==20.26.4 +virtualenv==20.26.5 webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 From 1611f1dce6ba15296abfab6c5ecd5e9bac0f0ae1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:35:21 +0000 Subject: [PATCH 13/49] chore(pip-prod)(deps): bump platformdirs from 4.3.3 to 4.3.6 Bumps [platformdirs](https://github.com/tox-dev/platformdirs) from 4.3.3 to 4.3.6. - [Release notes](https://github.com/tox-dev/platformdirs/releases) - [Changelog](https://github.com/tox-dev/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/tox-dev/platformdirs/compare/4.3.3...4.3.6) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a42cdb0..e3add0a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ mypy-extensions==1.0.0 nodeenv==1.9.1 packaging==24.1 pathspec==0.12.1 -platformdirs==4.3.3 +platformdirs==4.3.6 pluggy==1.5.0 py==1.11.0 pycodestyle==2.12.1 From 48c84ec319ce362415ec734bb2c3722565e89648 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 16:31:02 +0000 Subject: [PATCH 14/49] chore(pip-prod)(deps): bump astroid from 3.3.2 to 3.3.3 Bumps [astroid](https://github.com/pylint-dev/astroid) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/pylint-dev/astroid/releases) - [Changelog](https://github.com/pylint-dev/astroid/blob/main/ChangeLog) - [Commits](https://github.com/pylint-dev/astroid/compare/v3.3.2...v3.3.3) --- updated-dependencies: - dependency-name: astroid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e3add0a..6f64d5c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ appdirs==1.4.4 -astroid==3.3.2 +astroid==3.3.3 attrs==24.2.0 autopep8==2.3.1 backoff==2.2.1 From 912d9f739cf55e0c0ede3ccc6f719d84f4b90a6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 16:26:53 +0000 Subject: [PATCH 15/49] chore(pip-prod)(deps): bump astroid from 3.3.3 to 3.3.4 Bumps [astroid](https://github.com/pylint-dev/astroid) from 3.3.3 to 3.3.4. - [Release notes](https://github.com/pylint-dev/astroid/releases) - [Changelog](https://github.com/pylint-dev/astroid/blob/main/ChangeLog) - [Commits](https://github.com/pylint-dev/astroid/compare/v3.3.3...v3.3.4) --- updated-dependencies: - dependency-name: astroid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6f64d5c..998d389 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ appdirs==1.4.4 -astroid==3.3.3 +astroid==3.3.4 attrs==24.2.0 autopep8==2.3.1 backoff==2.2.1 From 68eeb3f8d5ec77947f821ac4ebe2c445e108bd03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:52:02 +0000 Subject: [PATCH 16/49] chore(pip-prod)(deps): bump virtualenv from 20.26.5 to 20.26.6 Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.26.5 to 20.26.6. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.26.5...20.26.6) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 998d389..e02b468 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,7 +39,7 @@ toml==0.10.2 tomli==2.0.1 tomlkit==0.13.2 urllib3==2.2.3 -virtualenv==20.26.5 +virtualenv==20.26.6 webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 From 128d50c2993fda3c49409430b138cd8bab28627c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:57:36 +0000 Subject: [PATCH 17/49] chore(pip-prod)(deps): bump dill from 0.3.8 to 0.3.9 Bumps [dill](https://github.com/uqfoundation/dill) from 0.3.8 to 0.3.9. - [Release notes](https://github.com/uqfoundation/dill/releases) - [Commits](https://github.com/uqfoundation/dill/compare/0.3.8...0.3.9) --- updated-dependencies: - dependency-name: dill dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e02b468..5a5fe5a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ cfgv==3.4.0 charset-normalizer==3.3.2 click==8.1.7 coloredlogs==15.0.1 -dill==0.3.8 +dill==0.3.9 distlib==0.3.8 filelock==3.16.1 future==1.0.0 From abd343bd61b8087ee48b84678d6ef0370c71f6be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 16:38:13 +0000 Subject: [PATCH 18/49] chore(pip-prod)(deps): bump sentry-sdk from 2.14.0 to 2.15.0 Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.14.0 to 2.15.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.14.0...2.15.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5a5fe5a..bacabd5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ python-dotenv==1.0.1 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.14.0 +sentry-sdk==2.15.0 six==1.16.0 toml==0.10.2 tomli==2.0.1 From 88d487eaa78710dad81d2be06ef55d4a41b5fbf5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:42:01 +0000 Subject: [PATCH 19/49] chore(pip-prod)(deps): bump tomli from 2.0.1 to 2.0.2 Bumps [tomli](https://github.com/hukkin/tomli) from 2.0.1 to 2.0.2. - [Changelog](https://github.com/hukkin/tomli/blob/master/CHANGELOG.md) - [Commits](https://github.com/hukkin/tomli/compare/2.0.1...2.0.2) --- updated-dependencies: - dependency-name: tomli dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bacabd5..e32fb5f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,7 +36,7 @@ requests-toolbelt==1.0.0 sentry-sdk==2.15.0 six==1.16.0 toml==0.10.2 -tomli==2.0.1 +tomli==2.0.2 tomlkit==0.13.2 urllib3==2.2.3 virtualenv==20.26.6 From 7d52db1221d73cf219f185c7f15d0bf132d4bdd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:21:37 +0000 Subject: [PATCH 20/49] chore(pip-prod)(deps): bump astroid from 3.3.4 to 3.3.5 Bumps [astroid](https://github.com/pylint-dev/astroid) from 3.3.4 to 3.3.5. - [Release notes](https://github.com/pylint-dev/astroid/releases) - [Changelog](https://github.com/pylint-dev/astroid/blob/main/ChangeLog) - [Commits](https://github.com/pylint-dev/astroid/compare/v3.3.4...v3.3.5) --- updated-dependencies: - dependency-name: astroid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e32fb5f..6ec152b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ appdirs==1.4.4 -astroid==3.3.4 +astroid==3.3.5 attrs==24.2.0 autopep8==2.3.1 backoff==2.2.1 From af330c3a87a4b9add3c67a2bc07e9091e8474cf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:56:04 +0000 Subject: [PATCH 21/49] chore(pip-prod)(deps): bump sentry-sdk from 2.15.0 to 2.16.0 Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.15.0 to 2.16.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.15.0...2.16.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6ec152b..2eda4e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ python-dotenv==1.0.1 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.15.0 +sentry-sdk==2.16.0 six==1.16.0 toml==0.10.2 tomli==2.0.2 From cc949369247b40a33487a9ff62a1774e78416ae4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:56:10 +0000 Subject: [PATCH 22/49] chore(pip-prod)(deps): bump xmltodict from 0.13.0 to 0.14.0 Bumps [xmltodict](https://github.com/martinblech/xmltodict) from 0.13.0 to 0.14.0. - [Changelog](https://github.com/martinblech/xmltodict/blob/master/CHANGELOG.md) - [Commits](https://github.com/martinblech/xmltodict/compare/v0.13.0...v0.14.0) --- updated-dependencies: - dependency-name: xmltodict dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2eda4e3..657897e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,5 +44,5 @@ webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 wrapt==1.16.0 -xmltodict==0.13.0 +xmltodict==0.14.0 zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability From 2ca76ae20c9ed1d9c9b12496b0b02eead0f4f4b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:04:37 +0000 Subject: [PATCH 23/49] chore(pip-prod)(deps): bump charset-normalizer from 3.3.2 to 3.4.0 Bumps [charset-normalizer](https://github.com/Ousret/charset_normalizer) from 3.3.2 to 3.4.0. - [Release notes](https://github.com/Ousret/charset_normalizer/releases) - [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md) - [Commits](https://github.com/Ousret/charset_normalizer/compare/3.3.2...3.4.0) --- updated-dependencies: - dependency-name: charset-normalizer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 657897e..129e822 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ autopep8==2.3.1 backoff==2.2.1 certifi==2024.8.30 cfgv==3.4.0 -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 click==8.1.7 coloredlogs==15.0.1 dill==0.3.9 From 03db6de0b173b9d87b0d03be5c91ab8bc36eae16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:32:47 +0000 Subject: [PATCH 24/49] chore(pip-prod)(deps): bump distlib from 0.3.8 to 0.3.9 Bumps [distlib](https://github.com/pypa/distlib) from 0.3.8 to 0.3.9. - [Release notes](https://github.com/pypa/distlib/releases) - [Changelog](https://github.com/pypa/distlib/blob/master/CHANGES.rst) - [Commits](https://github.com/pypa/distlib/compare/0.3.8...0.3.9) --- updated-dependencies: - dependency-name: distlib dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 129e822..8e2660e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ charset-normalizer==3.4.0 click==8.1.7 coloredlogs==15.0.1 dill==0.3.9 -distlib==0.3.8 +distlib==0.3.9 filelock==3.16.1 future==1.0.0 humanfriendly==10.0 From 179e91b7bedb16b273efb49e206ccb1be2dff1f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:50:14 +0000 Subject: [PATCH 25/49] chore(pip-prod)(deps): bump xmltodict from 0.14.0 to 0.14.1 Bumps [xmltodict](https://github.com/martinblech/xmltodict) from 0.14.0 to 0.14.1. - [Changelog](https://github.com/martinblech/xmltodict/blob/master/CHANGELOG.md) - [Commits](https://github.com/martinblech/xmltodict/compare/v0.14.0...v0.14.1) --- updated-dependencies: - dependency-name: xmltodict dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8e2660e..8543c25 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,5 +44,5 @@ webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 wrapt==1.16.0 -xmltodict==0.14.0 +xmltodict==0.14.1 zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability From 073afd068f9bb25e40ee536e8c8f282b68238937 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:25:35 +0000 Subject: [PATCH 26/49] chore(pip-prod)(deps): bump pyparsing from 3.1.4 to 3.2.0 Bumps [pyparsing](https://github.com/pyparsing/pyparsing) from 3.1.4 to 3.2.0. - [Release notes](https://github.com/pyparsing/pyparsing/releases) - [Changelog](https://github.com/pyparsing/pyparsing/blob/master/CHANGES) - [Commits](https://github.com/pyparsing/pyparsing/compare/3.1.4...3.2.0) --- updated-dependencies: - dependency-name: pyparsing dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8543c25..0245eae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,7 +27,7 @@ pluggy==1.5.0 py==1.11.0 pycodestyle==2.12.1 PyJWT==2.9.0 -pyparsing==3.1.4 +pyparsing==3.2.0 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 PyYAML==6.0.2 From ca7c3dca9125074a0081eda2b95555d89817a658 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 16:47:35 +0000 Subject: [PATCH 27/49] chore(pip-prod)(deps): bump xmltodict from 0.14.1 to 0.14.2 Bumps [xmltodict](https://github.com/martinblech/xmltodict) from 0.14.1 to 0.14.2. - [Changelog](https://github.com/martinblech/xmltodict/blob/master/CHANGELOG.md) - [Commits](https://github.com/martinblech/xmltodict/compare/v0.14.1...v0.14.2) --- updated-dependencies: - dependency-name: xmltodict dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0245eae..923a5c7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,5 +44,5 @@ webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 wrapt==1.16.0 -xmltodict==0.14.1 +xmltodict==0.14.2 zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability From a00a900073dc20e5a61ea2a47ab7a634082e91cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 16:45:39 +0000 Subject: [PATCH 28/49] chore(pip-prod)(deps): bump sentry-sdk from 2.16.0 to 2.17.0 Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.16.0 to 2.17.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.16.0...2.17.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 923a5c7..f311041 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ python-dotenv==1.0.1 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.16.0 +sentry-sdk==2.17.0 six==1.16.0 toml==0.10.2 tomli==2.0.2 From e26c785b7e17ef844121f667c4fddd8a185eef82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:46:43 +0000 Subject: [PATCH 29/49] chore(pip-prod)(deps): bump virtualenv from 20.26.6 to 20.27.0 Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.26.6 to 20.27.0. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.26.6...20.27.0) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f311041..1be184e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,7 +39,7 @@ toml==0.10.2 tomli==2.0.2 tomlkit==0.13.2 urllib3==2.2.3 -virtualenv==20.26.6 +virtualenv==20.27.0 webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 From 7d36d4320cc96f9a5585a448fa9d31da959c5bf0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:36:44 +0000 Subject: [PATCH 30/49] chore(pip-prod)(deps): bump virtualenv from 20.27.0 to 20.27.1 Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.27.0 to 20.27.1. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.27.0...20.27.1) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1be184e..571e065 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,7 +39,7 @@ toml==0.10.2 tomli==2.0.2 tomlkit==0.13.2 urllib3==2.2.3 -virtualenv==20.27.0 +virtualenv==20.27.1 webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 From 81bdf2acf76cacbbf5892242a01467312de1e895 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:34:35 +0000 Subject: [PATCH 31/49] chore(pip-prod)(deps): bump sentry-sdk from 2.17.0 to 2.18.0 Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.17.0 to 2.18.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.17.0...2.18.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 571e065..20018b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ python-dotenv==1.0.1 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.17.0 +sentry-sdk==2.18.0 six==1.16.0 toml==0.10.2 tomli==2.0.2 From 702d74d71b3c3505209dd21d7f0b346a46842e47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:31:30 +0000 Subject: [PATCH 32/49] chore(pip-prod)(deps): bump packaging from 24.1 to 24.2 Bumps [packaging](https://github.com/pypa/packaging) from 24.1 to 24.2. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/24.1...24.2) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 20018b6..938451d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,7 @@ lazy-object-proxy==1.10.0 mccabe==0.7.0 mypy-extensions==1.0.0 nodeenv==1.9.1 -packaging==24.1 +packaging==24.2 pathspec==0.12.1 platformdirs==4.3.6 pluggy==1.5.0 From d6b15f6bfcc4aeebc36073b831debfe52591f8fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:32:13 +0000 Subject: [PATCH 33/49] chore(pip-prod)(deps): bump identify from 2.6.1 to 2.6.2 Bumps [identify](https://github.com/pre-commit/identify) from 2.6.1 to 2.6.2. - [Commits](https://github.com/pre-commit/identify/compare/v2.6.1...v2.6.2) --- updated-dependencies: - dependency-name: identify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 938451d..fe666b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ distlib==0.3.9 filelock==3.16.1 future==1.0.0 humanfriendly==10.0 -identify==2.6.1 +identify==2.6.2 idna==3.10 iniconfig==2.0.0 lazy-object-proxy==1.10.0 From a833aaaa63a179848717e44055989b2ca7c854bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:53:48 +0000 Subject: [PATCH 34/49] chore(pip-prod)(deps): bump tomli from 2.0.2 to 2.1.0 Bumps [tomli](https://github.com/hukkin/tomli) from 2.0.2 to 2.1.0. - [Changelog](https://github.com/hukkin/tomli/blob/master/CHANGELOG.md) - [Commits](https://github.com/hukkin/tomli/compare/2.0.2...2.1.0) --- updated-dependencies: - dependency-name: tomli dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fe666b5..6f95898 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,7 +36,7 @@ requests-toolbelt==1.0.0 sentry-sdk==2.18.0 six==1.16.0 toml==0.10.2 -tomli==2.0.2 +tomli==2.1.0 tomlkit==0.13.2 urllib3==2.2.3 virtualenv==20.27.1 From d2025e2bb8864c16e96ff5d0b2f605e2e109a400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:21:08 +0000 Subject: [PATCH 35/49] chore(pip-prod)(deps): bump pyjwt from 2.9.0 to 2.10.0 Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.9.0 to 2.10.0. - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.9.0...2.10.0) --- updated-dependencies: - dependency-name: pyjwt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6f95898..21d5f46 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,7 +26,7 @@ platformdirs==4.3.6 pluggy==1.5.0 py==1.11.0 pycodestyle==2.12.1 -PyJWT==2.9.0 +PyJWT==2.10.0 pyparsing==3.2.0 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 From 1ee89e28e9095687907dc838b97354a2e2af84d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:16:12 +0000 Subject: [PATCH 36/49] chore(pip-prod)(deps): bump sentry-sdk from 2.18.0 to 2.19.0 Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.18.0 to 2.19.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.18.0...2.19.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 21d5f46..12f604d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ python-dotenv==1.0.1 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.18.0 +sentry-sdk==2.19.0 six==1.16.0 toml==0.10.2 tomli==2.1.0 From 968ec8eb7756f882f5208029e7d274c3bce73f9a Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Thu, 21 Nov 2024 21:17:57 +0000 Subject: [PATCH 37/49] feat: switch to Poetry --- .../requirements-dev.txt | 0 requirements.txt => .archive/requirements.txt | 0 .github/workflows/ci.yml | 2 +- .gitignore | 2 + poetry.lock | 908 ++++++++++++++++++ pyproject.toml | 27 + 6 files changed, 938 insertions(+), 1 deletion(-) rename requirements-dev.txt => .archive/requirements-dev.txt (100%) rename requirements.txt => .archive/requirements.txt (100%) create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/requirements-dev.txt b/.archive/requirements-dev.txt similarity index 100% rename from requirements-dev.txt rename to .archive/requirements-dev.txt diff --git a/requirements.txt b/.archive/requirements.txt similarity index 100% rename from requirements.txt rename to .archive/requirements.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 841ed49..49c1599 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ on: jobs: ci: - uses: luketainton/gha-workflows/.github/workflows/ci-python-with-docker.yml@main + uses: luketainton/gha-workflows/.github/workflows/ci-python-poetry-with-docker.yml@main secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} diff --git a/.gitignore b/.gitignore index 7f4045e..9a831ed 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +.ruff_cache/ # Translations *.mo @@ -111,6 +112,7 @@ venv/ ENV/ env.bak/ venv.bak/ +.env.test # Spyder project settings .spyderproject diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..9c16cda --- /dev/null +++ b/poetry.lock @@ -0,0 +1,908 @@ +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. + +[[package]] +name = "astroid" +version = "3.3.5" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.9.0" +files = [ + {file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"}, + {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, +] + +[[package]] +name = "backoff" +version = "2.2.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, + {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, +] + +[[package]] +name = "black" +version = "24.10.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.9" +files = [ + {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, + {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, + {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, + {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, + {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, + {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, + {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, + {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, + {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, + {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, + {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, + {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, + {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, + {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, + {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, + {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, + {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, + {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, + {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, + {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, + {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, + {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, +] + +[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.10)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "certifi" +version = "2024.8.30" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "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 = "coloredlogs" +version = "15.0.1" +description = "Colored terminal output for Python's logging module" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"}, + {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"}, +] + +[package.dependencies] +humanfriendly = ">=9.1" + +[package.extras] +cron = ["capturer (>=2.4)"] + +[[package]] +name = "coverage" +version = "7.6.7" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "coverage-7.6.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:108bb458827765d538abcbf8288599fee07d2743357bdd9b9dad456c287e121e"}, + {file = "coverage-7.6.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c973b2fe4dc445cb865ab369df7521df9c27bf40715c837a113edaa2aa9faf45"}, + {file = "coverage-7.6.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c6b24007c4bcd0b19fac25763a7cac5035c735ae017e9a349b927cfc88f31c1"}, + {file = "coverage-7.6.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acbb8af78f8f91b3b51f58f288c0994ba63c646bc1a8a22ad072e4e7e0a49f1c"}, + {file = "coverage-7.6.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad32a981bcdedb8d2ace03b05e4fd8dace8901eec64a532b00b15217d3677dd2"}, + {file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:34d23e28ccb26236718a3a78ba72744212aa383141961dd6825f6595005c8b06"}, + {file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e25bacb53a8c7325e34d45dddd2f2fbae0dbc230d0e2642e264a64e17322a777"}, + {file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af05bbba896c4472a29408455fe31b3797b4d8648ed0a2ccac03e074a77e2314"}, + {file = "coverage-7.6.7-cp310-cp310-win32.whl", hash = "sha256:796c9b107d11d2d69e1849b2dfe41730134b526a49d3acb98ca02f4985eeff7a"}, + {file = "coverage-7.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:987a8e3da7da4eed10a20491cf790589a8e5e07656b6dc22d3814c4d88faf163"}, + {file = "coverage-7.6.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7e61b0e77ff4dddebb35a0e8bb5a68bf0f8b872407d8d9f0c726b65dfabe2469"}, + {file = "coverage-7.6.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a5407a75ca4abc20d6252efeb238377a71ce7bda849c26c7a9bece8680a5d99"}, + {file = "coverage-7.6.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df002e59f2d29e889c37abd0b9ee0d0e6e38c24f5f55d71ff0e09e3412a340ec"}, + {file = "coverage-7.6.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:673184b3156cba06154825f25af33baa2671ddae6343f23175764e65a8c4c30b"}, + {file = "coverage-7.6.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e69ad502f1a2243f739f5bd60565d14a278be58be4c137d90799f2c263e7049a"}, + {file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60dcf7605c50ea72a14490d0756daffef77a5be15ed1b9fea468b1c7bda1bc3b"}, + {file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9c2eb378bebb2c8f65befcb5147877fc1c9fbc640fc0aad3add759b5df79d55d"}, + {file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c0317288f032221d35fa4cbc35d9f4923ff0dfd176c79c9b356e8ef8ef2dff4"}, + {file = "coverage-7.6.7-cp311-cp311-win32.whl", hash = "sha256:951aade8297358f3618a6e0660dc74f6b52233c42089d28525749fc8267dccd2"}, + {file = "coverage-7.6.7-cp311-cp311-win_amd64.whl", hash = "sha256:5e444b8e88339a2a67ce07d41faabb1d60d1004820cee5a2c2b54e2d8e429a0f"}, + {file = "coverage-7.6.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f07ff574986bc3edb80e2c36391678a271d555f91fd1d332a1e0f4b5ea4b6ea9"}, + {file = "coverage-7.6.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:49ed5ee4109258973630c1f9d099c7e72c5c36605029f3a91fe9982c6076c82b"}, + {file = "coverage-7.6.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3e8796434a8106b3ac025fd15417315d7a58ee3e600ad4dbcfddc3f4b14342c"}, + {file = "coverage-7.6.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3b925300484a3294d1c70f6b2b810d6526f2929de954e5b6be2bf8caa1f12c1"}, + {file = "coverage-7.6.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c42ec2c522e3ddd683dec5cdce8e62817afb648caedad9da725001fa530d354"}, + {file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0266b62cbea568bd5e93a4da364d05de422110cbed5056d69339bd5af5685433"}, + {file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e5f2a0f161d126ccc7038f1f3029184dbdf8f018230af17ef6fd6a707a5b881f"}, + {file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c132b5a22821f9b143f87446805e13580b67c670a548b96da945a8f6b4f2efbb"}, + {file = "coverage-7.6.7-cp312-cp312-win32.whl", hash = "sha256:7c07de0d2a110f02af30883cd7dddbe704887617d5c27cf373362667445a4c76"}, + {file = "coverage-7.6.7-cp312-cp312-win_amd64.whl", hash = "sha256:fd49c01e5057a451c30c9b892948976f5d38f2cbd04dc556a82743ba8e27ed8c"}, + {file = "coverage-7.6.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46f21663e358beae6b368429ffadf14ed0a329996248a847a4322fb2e35d64d3"}, + {file = "coverage-7.6.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:40cca284c7c310d622a1677f105e8507441d1bb7c226f41978ba7c86979609ab"}, + {file = "coverage-7.6.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77256ad2345c29fe59ae861aa11cfc74579c88d4e8dbf121cbe46b8e32aec808"}, + {file = "coverage-7.6.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87ea64b9fa52bf395272e54020537990a28078478167ade6c61da7ac04dc14bc"}, + {file = "coverage-7.6.7-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d608a7808793e3615e54e9267519351c3ae204a6d85764d8337bd95993581a8"}, + {file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdd94501d65adc5c24f8a1a0eda110452ba62b3f4aeaba01e021c1ed9cb8f34a"}, + {file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82c809a62e953867cf57e0548c2b8464207f5f3a6ff0e1e961683e79b89f2c55"}, + {file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb684694e99d0b791a43e9fc0fa58efc15ec357ac48d25b619f207c41f2fd384"}, + {file = "coverage-7.6.7-cp313-cp313-win32.whl", hash = "sha256:963e4a08cbb0af6623e61492c0ec4c0ec5c5cf74db5f6564f98248d27ee57d30"}, + {file = "coverage-7.6.7-cp313-cp313-win_amd64.whl", hash = "sha256:14045b8bfd5909196a90da145a37f9d335a5d988a83db34e80f41e965fb7cb42"}, + {file = "coverage-7.6.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f2c7a045eef561e9544359a0bf5784b44e55cefc7261a20e730baa9220c83413"}, + {file = "coverage-7.6.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dd4e4a49d9c72a38d18d641135d2fb0bdf7b726ca60a103836b3d00a1182acd"}, + {file = "coverage-7.6.7-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c95e0fa3d1547cb6f021ab72f5c23402da2358beec0a8e6d19a368bd7b0fb37"}, + {file = "coverage-7.6.7-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f63e21ed474edd23f7501f89b53280014436e383a14b9bd77a648366c81dce7b"}, + {file = "coverage-7.6.7-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead9b9605c54d15be228687552916c89c9683c215370c4a44f1f217d2adcc34d"}, + {file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0573f5cbf39114270842d01872952d301027d2d6e2d84013f30966313cadb529"}, + {file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e2c8e3384c12dfa19fa9a52f23eb091a8fad93b5b81a41b14c17c78e23dd1d8b"}, + {file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:70a56a2ec1869e6e9fa69ef6b76b1a8a7ef709972b9cc473f9ce9d26b5997ce3"}, + {file = "coverage-7.6.7-cp313-cp313t-win32.whl", hash = "sha256:dbba8210f5067398b2c4d96b4e64d8fb943644d5eb70be0d989067c8ca40c0f8"}, + {file = "coverage-7.6.7-cp313-cp313t-win_amd64.whl", hash = "sha256:dfd14bcae0c94004baba5184d1c935ae0d1231b8409eb6c103a5fd75e8ecdc56"}, + {file = "coverage-7.6.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37a15573f988b67f7348916077c6d8ad43adb75e478d0910957394df397d2874"}, + {file = "coverage-7.6.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b6cce5c76985f81da3769c52203ee94722cd5d5889731cd70d31fee939b74bf0"}, + {file = "coverage-7.6.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ab9763d291a17b527ac6fd11d1a9a9c358280adb320e9c2672a97af346ac2c"}, + {file = "coverage-7.6.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cf96ceaa275f071f1bea3067f8fd43bec184a25a962c754024c973af871e1b7"}, + {file = "coverage-7.6.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee9cf6b0134d6f932d219ce253ef0e624f4fa588ee64830fcba193269e4daa3"}, + {file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2bc3e45c16564cc72de09e37413262b9f99167803e5e48c6156bccdfb22c8327"}, + {file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:623e6965dcf4e28a3debaa6fcf4b99ee06d27218f46d43befe4db1c70841551c"}, + {file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850cfd2d6fc26f8346f422920ac204e1d28814e32e3a58c19c91980fa74d8289"}, + {file = "coverage-7.6.7-cp39-cp39-win32.whl", hash = "sha256:c296263093f099da4f51b3dff1eff5d4959b527d4f2f419e16508c5da9e15e8c"}, + {file = "coverage-7.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:90746521206c88bdb305a4bf3342b1b7316ab80f804d40c536fc7d329301ee13"}, + {file = "coverage-7.6.7-pp39.pp310-none-any.whl", hash = "sha256:0ddcb70b3a3a57581b450571b31cb774f23eb9519c2aaa6176d3a84c9fc57671"}, + {file = "coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24"}, +] + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "datetime" +version = "5.5" +description = "This package provides a DateTime data type, as known from Zope. Unless you need to communicate with Zope APIs, you're probably better off using Python's built-in datetime module." +optional = false +python-versions = ">=3.7" +files = [ + {file = "DateTime-5.5-py3-none-any.whl", hash = "sha256:0abf6c51cb4ba7cee775ca46ccc727f3afdde463be28dbbe8803631fefd4a120"}, + {file = "DateTime-5.5.tar.gz", hash = "sha256:21ec6331f87a7fcb57bd7c59e8a68bfffe6fcbf5acdbbc7b356d6a9a020191d3"}, +] + +[package.dependencies] +pytz = "*" +"zope.interface" = "*" + +[[package]] +name = "dill" +version = "0.3.9" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, + {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + +[[package]] +name = "future" +version = "1.0.0" +description = "Clean single-source support for Python 3 and 2" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, + {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, +] + +[[package]] +name = "humanfriendly" +version = "10.0" +description = "Human friendly output for text interfaces using Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"}, + {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, +] + +[package.dependencies] +pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "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 = "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 = "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.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, +] + +[[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.3.6" +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.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[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 = "pyjwt" +version = "2.10.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, + {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pylint" +version = "3.3.1" +description = "python code static checker" +optional = false +python-versions = ">=3.9.0" +files = [ + {file = "pylint-3.3.1-py3-none-any.whl", hash = "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9"}, + {file = "pylint-3.3.1.tar.gz", hash = "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e"}, +] + +[package.dependencies] +astroid = ">=3.3.4,<=3.4.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, +] +isort = ">=4.2.5,<5.13.0 || >5.13.0,<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 = "pylint-exit" +version = "1.2.0" +description = "Exit code handler for pylint command line utility." +optional = false +python-versions = "*" +files = [ + {file = "pylint-exit-1.2.0.zip", hash = "sha256:b6ad02884c01c5560a5275079fe5a6c792afff90ecccf0c02513e1547ee280b0"}, + {file = "pylint_exit-1.2.0-py2.py3-none-any.whl", hash = "sha256:65c9e7856e9058705a92d7c45628d604b2a4b8ee2b3c18a7303be77f9ed87cbe"}, +] + +[[package]] +name = "pyreadline3" +version = "3.5.4" +description = "A python implementation of GNU readline." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6"}, + {file = "pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7"}, +] + +[package.extras] +dev = ["build", "flake8", "mypy", "pytest", "twine"] + +[[package]] +name = "pytest" +version = "8.3.3" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, + {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytz" +version = "2024.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "sentry-sdk" +version = "2.19.0" +description = "Python client for Sentry (https://sentry.io)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "sentry_sdk-2.19.0-py2.py3-none-any.whl", hash = "sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b"}, + {file = "sentry_sdk-2.19.0.tar.gz", hash = "sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36"}, +] + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.26.11" + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +anthropic = ["anthropic (>=0.16)"] +arq = ["arq (>=0.23)"] +asyncpg = ["asyncpg (>=0.23)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +celery-redbeat = ["celery-redbeat (>=2)"] +chalice = ["chalice (>=1.16.0)"] +clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +fastapi = ["fastapi (>=0.79.0)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] +grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] +http2 = ["httpcore[http2] (==1.*)"] +httpx = ["httpx (>=0.16.0)"] +huey = ["huey (>=2)"] +huggingface-hub = ["huggingface_hub (>=0.22)"] +langchain = ["langchain (>=0.0.210)"] +launchdarkly = ["launchdarkly-server-sdk (>=9.8.0)"] +litestar = ["litestar (>=2.0.0)"] +loguru = ["loguru (>=0.5)"] +openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] +openfeature = ["openfeature-sdk (>=0.7.1)"] +opentelemetry = ["opentelemetry-distro (>=0.35b0)"] +opentelemetry-experimental = ["opentelemetry-distro"] +pure-eval = ["asttokens", "executing", "pure_eval"] +pymongo = ["pymongo (>=3.1)"] +pyspark = ["pyspark (>=2.4.4)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +starlette = ["starlette (>=0.19.1)"] +starlite = ["starlite (>=1.48)"] +tornado = ["tornado (>=6)"] + +[[package]] +name = "setuptools" +version = "75.6.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.9" +files = [ + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +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)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] + +[[package]] +name = "tomlkit" +version = "0.13.2" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "webex-bot" +version = "0.5.2" +description = "Python package for a Webex Bot based on websockets." +optional = false +python-versions = ">=3.8" +files = [ + {file = "webex_bot-0.5.2-py2.py3-none-any.whl", hash = "sha256:1ccde69de4f44bf4ad4d3c9dcc41666c09d0ff40326155f13a4213732352783e"}, + {file = "webex_bot-0.5.2.tar.gz", hash = "sha256:6b381d4ed0ba500d5f1d3e96a68db599ac38466f66d98afda8762cf66138f9ff"}, +] + +[package.dependencies] +backoff = "*" +coloredlogs = "*" +webexteamssdk = "1.6.1" +websockets = "11.0.3" + +[package.extras] +proxy = ["websockets-proxy (>=0.1.1)"] + +[[package]] +name = "webexteamssdk" +version = "1.6.1" +description = "Community-developed Python SDK for the Webex Teams APIs" +optional = false +python-versions = "*" +files = [ + {file = "webexteamssdk-1.6.1-py3-none-any.whl", hash = "sha256:52a7f9d515cd3d53a853e679e16572ec6ca036a223e35b14fea14c99f492a6a4"}, + {file = "webexteamssdk-1.6.1.tar.gz", hash = "sha256:bbc7672f381b26fb22d0d03f87d131a2fa1e7d54c2f37f2e4cd28d725b8b5dfb"}, +] + +[package.dependencies] +future = "*" +PyJWT = "*" +requests = ">=2.4.2" +requests-toolbelt = "*" + +[[package]] +name = "websockets" +version = "11.0.3" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"}, + {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"}, + {file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"}, + {file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"}, + {file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"}, + {file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"}, + {file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"}, + {file = "websockets-11.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f59a3c656fef341a99e3d63189852be7084c0e54b75734cde571182c087b152"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2529338a6ff0eb0b50c7be33dc3d0e456381157a31eefc561771ee431134a97f"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34fd59a4ac42dff6d4681d8843217137f6bc85ed29722f2f7222bd619d15e95b"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:332d126167ddddec94597c2365537baf9ff62dfcc9db4266f263d455f2f031cb"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6505c1b31274723ccaf5f515c1824a4ad2f0d191cec942666b3d0f3aa4cb4007"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f467ba0050b7de85016b43f5a22b46383ef004c4f672148a8abf32bc999a87f0"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9d9acd80072abcc98bd2c86c3c9cd4ac2347b5a5a0cae7ed5c0ee5675f86d9af"}, + {file = "websockets-11.0.3-cp37-cp37m-win32.whl", hash = "sha256:e590228200fcfc7e9109509e4d9125eace2042fd52b595dd22bbc34bb282307f"}, + {file = "websockets-11.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:b16fff62b45eccb9c7abb18e60e7e446998093cdcb50fed33134b9b6878836de"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fb06eea71a00a7af0ae6aefbb932fb8a7df3cb390cc217d51a9ad7343de1b8d0"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8a34e13a62a59c871064dfd8ffb150867e54291e46d4a7cf11d02c94a5275bae"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4841ed00f1026dfbced6fca7d963c4e7043aa832648671b5138008dc5a8f6d99"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a073fc9ab1c8aff37c99f11f1641e16da517770e31a37265d2755282a5d28aa"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68b977f21ce443d6d378dbd5ca38621755f2063d6fdb3335bda981d552cfff86"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a99a7a71631f0efe727c10edfba09ea6bee4166a6f9c19aafb6c0b5917d09c"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bee9fcb41db2a23bed96c6b6ead6489702c12334ea20a297aa095ce6d31370d0"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4b253869ea05a5a073ebfdcb5cb3b0266a57c3764cf6fe114e4cd90f4bfa5f5e"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1553cb82942b2a74dd9b15a018dce645d4e68674de2ca31ff13ebc2d9f283788"}, + {file = "websockets-11.0.3-cp38-cp38-win32.whl", hash = "sha256:f61bdb1df43dc9c131791fbc2355535f9024b9a04398d3bd0684fc16ab07df74"}, + {file = "websockets-11.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311"}, + {file = "websockets-11.0.3-cp39-cp39-win32.whl", hash = "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128"}, + {file = "websockets-11.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"}, + {file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"}, + {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, +] + +[[package]] +name = "zipp" +version = "3.21.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.9" +files = [ + {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, + {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + +[[package]] +name = "zope-interface" +version = "7.1.1" +description = "Interfaces for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zope.interface-7.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6650bd56ef350d37c8baccfd3ee8a0483ed6f8666e641e4b9ae1a1827b79f9e5"}, + {file = "zope.interface-7.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84e87eba6b77a3af187bae82d8de1a7c208c2a04ec9f6bd444fd091b811ad92e"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c4e1b4c06d9abd1037c088dae1566c85f344a3e6ae4350744c3f7f7259d9c67"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cd5e3d910ac87652a09f6e5db8e41bc3b49cf08ddd2d73d30afc644801492cd"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca95594d936ee349620900be5b46c0122a1ff6ce42d7d5cb2cf09dc84071ef16"}, + {file = "zope.interface-7.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:ad339509dcfbbc99bf8e147db6686249c4032f26586699ec4c82f6e5909c9fe2"}, + {file = "zope.interface-7.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e59f175e868f856a77c0a77ba001385c377df2104fdbda6b9f99456a01e102a"}, + {file = "zope.interface-7.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0de23bcb93401994ea00bc5c677ef06d420340ac0a4e9c10d80e047b9ce5af3f"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdb7e7e5524b76d3ec037c1d81a9e2c7457b240fd4cb0a2476b65c3a5a6c81f"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3603ef82a9920bd0bfb505423cb7e937498ad971ad5a6141841e8f76d2fd5446"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1d52d052355e0c5c89e0630dd2ff7c0b823fd5f56286a663e92444761b35e25"}, + {file = "zope.interface-7.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:179ad46ece518c9084cb272e4a69d266b659f7f8f48e51706746c2d8a426433e"}, + {file = "zope.interface-7.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e6503534b52bb1720ace9366ee30838a58a3413d3e197512f3338c8f34b5d89d"}, + {file = "zope.interface-7.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f85b290e5b8b11814efb0d004d8ce6c9a483c35c462e8d9bf84abb93e79fa770"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d029fac6a80edae80f79c37e5e3abfa92968fe921886139b3ee470a1b177321a"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5836b8fb044c6e75ba34dfaabc602493019eadfa0faf6ff25f4c4c356a71a853"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7395f13533318f150ee72adb55b29284b16e73b6d5f02ab21f173b3e83f242b8"}, + {file = "zope.interface-7.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:1d0e23c6b746eb8ce04573cc47bcac60961ac138885d207bd6f57e27a1431ae8"}, + {file = "zope.interface-7.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:9fad9bd5502221ab179f13ea251cb30eef7cf65023156967f86673aff54b53a0"}, + {file = "zope.interface-7.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:55c373becbd36a44d0c9be1d5271422fdaa8562d158fb44b4192297b3c67096c"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed1df8cc01dd1e3970666a7370b8bfc7457371c58ba88c57bd5bca17ab198053"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99c14f0727c978639139e6cad7a60e82b7720922678d75aacb90cf4ef74a068c"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b1eed7670d564f1025d7cda89f99f216c30210e42e95de466135be0b4a499d9"}, + {file = "zope.interface-7.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:3defc925c4b22ac1272d544a49c6ba04c3eefcce3200319ee1be03d9270306dd"}, + {file = "zope.interface-7.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8d0fe45be57b5219aa4b96e846631c04615d5ef068146de5a02ccd15c185321f"}, + {file = "zope.interface-7.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bcbeb44fc16e0078b3b68a95e43f821ae34dcbf976dde6985141838a5f23dd3d"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8e7b05dc6315a193cceaec071cc3cf1c180cea28808ccded0b1283f1c38ba73"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d553e02b68c0ea5a226855f02edbc9eefd99f6a8886fa9f9bdf999d77f46585"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81744a7e61b598ebcf4722ac56a7a4f50502432b5b4dc7eb29075a89cf82d029"}, + {file = "zope.interface-7.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7720322763aceb5e0a7cadcc38c67b839efe599f0887cbf6c003c55b1458c501"}, + {file = "zope.interface-7.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ed0852c25950cf430067f058f8d98df6288502ac313861d9803fe7691a9b3"}, + {file = "zope.interface-7.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9595e478047ce752b35cfa221d7601a5283ccdaab40422e0dc1d4a334c70f580"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2317e1d4dba68203a5227ea3057f9078ec9376275f9700086b8f0ffc0b358e1b"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6821ef9870f32154da873fcde439274f99814ea452dd16b99fa0b66345c4b6b"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:190eeec67e023d5aac54d183fa145db0b898664234234ac54643a441da434616"}, + {file = "zope.interface-7.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:d17e7fc814eaab93409b80819fd6d30342844345c27f3bc3c4b43c2425a8d267"}, + {file = "zope.interface-7.1.1.tar.gz", hash = "sha256:4284d664ef0ff7b709836d4de7b13d80873dc5faeffc073abdb280058bfac5e3"}, +] + +[package.dependencies] +setuptools = "*" + +[package.extras] +docs = ["Sphinx", "furo", "repoze.sphinx.autointerface"] +test = ["coverage[toml]", "zope.event", "zope.testing"] +testing = ["coverage[toml]", "zope.event", "zope.testing"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "341e2cb729a0e9691470e528ed4b51908531612834963958eb5c88fb76939473" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e36bbd7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,27 @@ +[tool.poetry] +name = "roboluke-tasks" +version = "0.0.0" # Version is tracked by GitHub Releases +description = "Add tasks to a Wekan to do list via Webex and n8n." +authors = ["Luke Tainton "] +readme = "README.md" +package-mode = false + +[tool.poetry.dependencies] +python = "^3.11" +webex-bot = "^0.5.2" +sentry-sdk = "^2.19.0" +datetime = "^5.5" +requests = "^2.32.3" + +[tool.poetry.group.dev.dependencies] +black = "^24.10.0" +coverage = "^7.6.7" +isort = "^5.13.2" +pylint = "^3.3.1" +pylint-exit = "^1.2.0" +pytest = "^8.3.3" +zipp = "^3.21.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" From 31269af2185d5abde1cbd6197a4d147f8837eaec Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Thu, 21 Nov 2024 21:45:51 +0000 Subject: [PATCH 38/49] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 33 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..725c75d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,33 @@ +--- +name: Bug report +about: Create a report to help improve the bot. +title: 'BUG: ' +labels: bug +assignees: luketainton + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Webex Client (please complete the following information):** + - Type: [e.g. Browser, Desktop, Mobile] + - OS: [e.g. iOS, Android, Windows, MacOS] + - Browser: [e.g. Chrome, Safari] (only applicable for browser client) + - Version: [e.g. 22] (only applicable for non-browser clients) + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..47ad63f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an enhancement for the bot. +title: 'FEATURE: ' +labels: enhancement +assignees: luketainton + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From f611b685b36315d5ce8c9649d2f70525fa007ef5 Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Thu, 21 Nov 2024 22:26:07 +0000 Subject: [PATCH 39/49] fix(config): return None if env var is empty or non-existent (#315) * fix(config): return None if env var is empty or non-existent * chore: fix pylint issues * fix: add unit test for non-existent env vars --- app/commands/exit.py | 11 ++++--- app/commands/submit_task.py | 57 ++++++++++++++++++++++++------------- app/main.py | 6 ++-- app/utils/config.py | 27 ++++++++++++------ app/utils/datetime.py | 2 +- app/utils/n8n.py | 2 ++ tests/test_config.py | 46 ------------------------------ tests/test_config_1.py | 52 +++++++++++++++++++++++++++++++++ tests/test_config_2.py | 49 +++++++++++++++++++++++++++++++ tests/test_datetime.py | 2 ++ 10 files changed, 172 insertions(+), 82 deletions(-) delete mode 100644 tests/test_config.py create mode 100644 tests/test_config_1.py create mode 100644 tests/test_config_2.py diff --git a/app/commands/exit.py b/app/commands/exit.py index 2bc52cd..8d28cee 100644 --- a/app/commands/exit.py +++ b/app/commands/exit.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +"""Exit command.""" import logging @@ -8,7 +8,10 @@ log: logging.Logger = logging.getLogger(__name__) class ExitCommand(Command): + """Exit command class.""" + def __init__(self) -> None: + """Exit command class.""" super().__init__( command_keyword="exit", help_message="Exit", @@ -17,10 +20,10 @@ class ExitCommand(Command): self.sender: str = "" def pre_execute(self, message, attachment_actions, activity) -> None: - pass + """Pre-execute method.""" def execute(self, message, attachment_actions, activity) -> None: - pass + """Execute method.""" def post_execute(self, message, attachment_actions, activity) -> None: - pass + """Post-execute method.""" diff --git a/app/commands/submit_task.py b/app/commands/submit_task.py index 70ef360..89c619d 100644 --- a/app/commands/submit_task.py +++ b/app/commands/submit_task.py @@ -1,20 +1,12 @@ -#!/usr/bin/env python3 +"""Submit task command.""" import logging -import sentry_sdk +import sentry_sdk from webex_bot.models.command import Command from webex_bot.models.response import Response, response_from_adaptive_card -from webexteamssdk.models.cards import ( - AdaptiveCard, - Column, - ColumnSet, - Date, - FontSize, - FontWeight, - Text, - TextBlock, -) +from webexteamssdk.models.cards import (AdaptiveCard, Column, ColumnSet, Date, + FontSize, FontWeight, Text, TextBlock) from webexteamssdk.models.cards.actions import Submit from app.utils.config import config @@ -24,7 +16,10 @@ log: logging.Logger = logging.getLogger(__name__) class SubmitTaskCommand(Command): + """Submit task command.""" + def __init__(self) -> None: + """Submit task command.""" super().__init__( command_keyword="submit_feedback_dstgmyn", help_message="Submit Task", @@ -34,9 +29,11 @@ class SubmitTaskCommand(Command): self.sender: str = "" def pre_execute(self, message, attachment_actions, activity) -> None: + """Pre-execute method.""" self.sender = activity.get("actor").get("id") def execute(self, message, attachment_actions, activity) -> Response: + """Execute method.""" card_body: list = [ ColumnSet( columns=[ @@ -48,7 +45,8 @@ class SubmitTaskCommand(Command): size=FontSize.MEDIUM, ), TextBlock( - f"Add a task to {config.admin_first_name}'s To Do list. All fields are required. Please don't use special characters.", + f"Add a task to {config.admin_first_name}'s To Do list. " + + "All fields are required. Please don't use special characters.", wrap=True, isSubtle=True, ), @@ -62,7 +60,9 @@ class SubmitTaskCommand(Command): Column( width=2, items=[ - Text(id="issue_title", placeholder="Summary", maxLength=100), + Text( + id="issue_title", placeholder="Summary", maxLength=100 + ), Text( id="issue_description", placeholder="Description", @@ -85,7 +85,8 @@ class SubmitTaskCommand(Command): items=[ Text( id="issue_requester", - placeholder="Requester Email (leave blank to submit for yourself)", + placeholder="Requester Email " + + "(leave blank to submit for yourself)", maxLength=100, ), ], @@ -119,19 +120,26 @@ class SubmitTaskCommand(Command): class SubmitTaskCallback(Command): + """Submit task callback.""" + def __init__(self) -> None: + """Submit task callback.""" super().__init__( - card_callback_keyword="submit_task_callback_rbamzfyx", delete_previous_message=True + card_callback_keyword="submit_task_callback_rbamzfyx", + delete_previous_message=True, ) self.msg: str = "" def pre_execute(self, message, attachment_actions, activity) -> None: + """Pre-execute method.""" issue_title: str = attachment_actions.inputs.get("issue_title") issue_description: str = attachment_actions.inputs.get("issue_description") completion_date: str = attachment_actions.inputs.get("completion_date") sender: str = attachment_actions.inputs.get("sender") - issue_requester: str = attachment_actions.inputs.get("issue_requester") or sender + issue_requester: str = ( + attachment_actions.inputs.get("issue_requester") or sender + ) if not issue_title or not issue_description or not completion_date: self.msg = "Please complete all fields." @@ -145,29 +153,38 @@ class SubmitTaskCallback(Command): ) self.msg = ( - "Submitting your task..." if result else "Failed to submit task. Please try again." + "Submitting your task..." + if result + else "Failed to submit task. Please try again." ) def execute(self, message, attachment_actions, activity) -> str: + """Execute method.""" with sentry_sdk.start_transaction(name="submit_task_callback"): return self.msg class MyTasksCallback(Command): + """My tasks callback.""" + def __init__(self) -> None: + """My tasks callback.""" super().__init__( - card_callback_keyword="my_tasks_callback_rbamzfyx", delete_previous_message=True + card_callback_keyword="my_tasks_callback_rbamzfyx", + delete_previous_message=True, ) self.msg: str = "" def pre_execute(self, message, attachment_actions, activity) -> str: + """Pre-execute method.""" with sentry_sdk.start_transaction(name="my_tasks_preexec"): return "Getting your tasks..." def execute(self, message, attachment_actions, activity) -> str | None: + """Execute method.""" sender: str = attachment_actions.inputs.get("sender") result: bool = get_tasks(requestor=sender) with sentry_sdk.start_transaction(name="my_tasks_exec"): if not result: return "Failed to get tasks. Please try again." - return + return None diff --git a/app/main.py b/app/main.py index c222c89..0e94a6f 100644 --- a/app/main.py +++ b/app/main.py @@ -1,4 +1,6 @@ -#!/usr/bin/env python3 +"""Main module.""" + +import sys import sentry_sdk from sentry_sdk.integrations.stdlib import StdlibIntegration @@ -43,4 +45,4 @@ if __name__ == "__main__": bot.run() except KeyboardInterrupt: print("Shutting down bot...") - exit() + sys.exit(0) diff --git a/app/utils/config.py b/app/utils/config.py index 5cce4b4..84bdfb2 100644 --- a/app/utils/config.py +++ b/app/utils/config.py @@ -69,23 +69,32 @@ class Config: return os.environ["N8N_WEBHOOK_URL"] @property - def approved_users(self) -> list: + def approved_users(self) -> list | None: """Returns a list of approved users.""" - emails: list[str] = os.environ.get("APPROVED_USERS", "").split(",") - emails = [i.strip() for i in emails if validate_email_syntax(i.strip())] + _emails: list[str] = os.environ.get("APPROVED_USERS", "").split(",") + _emails: list[str] = [i.strip() for i in _emails if i] + if not _emails: + return None + emails = [i for i in _emails if validate_email_syntax(i)] return emails @property - def approved_rooms(self) -> list: + def approved_rooms(self) -> list | None: """Returns a list of approved rooms.""" - rooms: list[str] = os.environ.get("APPROVED_ROOMS", "").split(",") - return [i.strip() for i in rooms] + _rooms: list[str] = os.environ.get("APPROVED_ROOMS", "").split(",") + rooms: list[str] = [i.strip() for i in _rooms if i] + if not rooms: + return None + return rooms @property - def approved_domains(self) -> list: + def approved_domains(self) -> list | None: """Returns a list of approved domains.""" - domains: list[str] = os.environ.get("APPROVED_DOMAINS", "").split(",") - return [i.strip() for i in domains] + _domains: list[str] = os.environ.get("APPROVED_DOMAINS", "").split(",") + domains: list[str] = [i.strip() for i in _domains if i] + if not domains: + return None + return domains config: Config = Config() diff --git a/app/utils/datetime.py b/app/utils/datetime.py index f645d3b..8c86270 100644 --- a/app/utils/datetime.py +++ b/app/utils/datetime.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +"""Provides functions for converting timestamps to dates.""" from datetime import datetime from zoneinfo import ZoneInfo diff --git a/app/utils/n8n.py b/app/utils/n8n.py index 6940174..2b59057 100644 --- a/app/utils/n8n.py +++ b/app/utils/n8n.py @@ -1,3 +1,5 @@ +"""N8N utils module.""" + import requests import sentry_sdk diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100644 index 070f734..0000000 --- a/tests/test_config.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 - -# ruff: noqa: E402 pylint: disable=wrong-import-position - -"""Provides test cases for app/utils/config.py.""" - -import os - -vars: dict = { - "APP_VERSION": "dev", - "BOT_NAME": "TestBot", - "WEBEX_API_KEY": "testing", - "ADMIN_FIRST_NAME": "Test", - "ADMIN_EMAIL": "test@test.com", - "N8N_WEBHOOK_URL": "https://n8n.test.com/webhook/abcdefg", - "SENTRY_ENABLED": "false", - "SENTRY_DSN": "http://localhost", - "APPROVED_USERS": "test@test.com", - "APPROVED_DOMAINS": "test.com", - "APPROVED_ROOMS": "test", -} - - -for var, value in vars.items(): - os.environ[var] = value - -# needs to be imported AFTER environment variables are set -from app.utils.config import config # pragma: no cover - - -def test_config() -> None: - assert config.admin_emails == vars["ADMIN_EMAIL"].split(",") - assert config.admin_first_name == vars["ADMIN_FIRST_NAME"] - assert config.approved_domains == vars["APPROVED_DOMAINS"].split(",") - assert config.approved_rooms == vars["APPROVED_ROOMS"].split(",") - assert config.approved_users == vars["APPROVED_USERS"].split(",") - assert config.bot_name == vars["BOT_NAME"] - assert config.n8n_webhook_url == vars["N8N_WEBHOOK_URL"] - assert config.sentry_enabled == bool(vars["SENTRY_ENABLED"].upper() == "TRUE") - assert config.version == vars["APP_VERSION"] - assert config.webex_token == vars["WEBEX_API_KEY"] - - if config.sentry_enabled: - assert config.sentry_dsn == vars["SENTRY_DSN"] - else: - assert config.sentry_dsn == "" diff --git a/tests/test_config_1.py b/tests/test_config_1.py new file mode 100644 index 0000000..bba05e2 --- /dev/null +++ b/tests/test_config_1.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +# ruff: noqa: E402 pylint: disable=wrong-import-position + +"""Provides test cases for app/utils/config.py.""" + +import os + + +def test_config() -> None: + """Test config module.""" + + config_vars: dict = { + "APP_VERSION": "dev", + "BOT_NAME": "TestBot", + "WEBEX_API_KEY": "testing", + "ADMIN_FIRST_NAME": "Test", + "ADMIN_EMAIL": "test@test.com", + "N8N_WEBHOOK_URL": "https://n8n.test.com/webhook/abcdefg", + "SENTRY_ENABLED": "false", + "SENTRY_DSN": "http://localhost", + "APPROVED_USERS": "test@test.com", + "APPROVED_DOMAINS": "test.com", + "APPROVED_ROOMS": "test", + } + + for config_var, value in config_vars.items(): + os.environ[config_var] = value + + # needs to be imported AFTER environment variables are set + from app.utils.config import config # pragma: no cover + + assert config.admin_emails == config_vars["ADMIN_EMAIL"].split(",") + assert config.admin_first_name == config_vars["ADMIN_FIRST_NAME"] + assert config.approved_domains == config_vars["APPROVED_DOMAINS"].split(",") + assert config.approved_rooms == config_vars["APPROVED_ROOMS"].split(",") + assert config.approved_users == config_vars["APPROVED_USERS"].split(",") + assert config.bot_name == config_vars["BOT_NAME"] + assert config.n8n_webhook_url == config_vars["N8N_WEBHOOK_URL"] + assert config.sentry_enabled == bool( + config_vars["SENTRY_ENABLED"].upper() == "TRUE" + ) + assert config.version == config_vars["APP_VERSION"] + assert config.webex_token == config_vars["WEBEX_API_KEY"] + + if config.sentry_enabled: + assert config.sentry_dsn == config_vars["SENTRY_DSN"] + else: + assert config.sentry_dsn == "" + + for config_var in config_vars: + os.environ.pop(config_var, None) diff --git a/tests/test_config_2.py b/tests/test_config_2.py new file mode 100644 index 0000000..f3ec601 --- /dev/null +++ b/tests/test_config_2.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +# ruff: noqa: E402 pylint: disable=wrong-import-position + +"""Provides test cases for app/utils/config.py.""" + +import os + + +def test_config_no_admin_vars() -> None: + """Test config module.""" + + config_vars: dict = { + "APP_VERSION": "dev", + "BOT_NAME": "TestBot", + "WEBEX_API_KEY": "testing", + "ADMIN_FIRST_NAME": "Test", + "ADMIN_EMAIL": "test@test.com", + "N8N_WEBHOOK_URL": "https://n8n.test.com/webhook/abcdefg", + "SENTRY_ENABLED": "false", + "SENTRY_DSN": "http://localhost", + } + + for config_var, value in config_vars.items(): + os.environ[config_var] = value + + # needs to be imported AFTER environment variables are set + from app.utils.config import config # pragma: no cover + + assert config.approved_domains is None + assert config.approved_rooms is None + assert config.approved_users is None + assert config.admin_emails == config_vars["ADMIN_EMAIL"].split(",") + assert config.admin_first_name == config_vars["ADMIN_FIRST_NAME"] + assert config.bot_name == config_vars["BOT_NAME"] + assert config.n8n_webhook_url == config_vars["N8N_WEBHOOK_URL"] + assert config.sentry_enabled == bool( + config_vars["SENTRY_ENABLED"].upper() == "TRUE" + ) + assert config.version == config_vars["APP_VERSION"] + assert config.webex_token == config_vars["WEBEX_API_KEY"] + + if config.sentry_enabled: + assert config.sentry_dsn == config_vars["SENTRY_DSN"] + else: + assert config.sentry_dsn == "" + + for config_var in config_vars: + os.environ.pop(config_var, None) diff --git a/tests/test_datetime.py b/tests/test_datetime.py index 263cc3d..8da21d1 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -8,12 +8,14 @@ from app.utils.datetime import timestamp_to_date # pragma: no cover def test_correct() -> None: + """Test timestamp_to_date() with a correct timestamp.""" timestamp: int = 1680722218 result: str = timestamp_to_date(timestamp) assert result == "2023-04-05" def test_invalid() -> None: + """Test timestamp_to_date() with an invalid timestamp.""" timestamp: str = "hello" with pytest.raises(TypeError) as excinfo: timestamp_to_date(timestamp) From 609fee445f5c15388cf8a274e2e32285555fbc7c Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 09:42:28 +0000 Subject: [PATCH 40/49] fix(docker): switch Dockerfile to Poetry --- Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ec79734..0e86908 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,10 +8,11 @@ WORKDIR /run RUN mkdir -p /.local && \ chmod -R 777 /.local && \ - pip install -U pip + pip install -U pip poetry -COPY requirements.txt /run/requirements.txt -RUN pip install --no-cache-dir -r requirements.txt +COPY pyproject.toml /run/pyproject.toml +COPY poetry.lock /run/poetry.lock +RUN poetry install --withouit dev --no-root ENTRYPOINT ["python3", "-B", "-m", "app.main"] From cf2d542e16010619870fcae78933dceedb731ccc Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 09:45:53 +0000 Subject: [PATCH 41/49] fix(docker): correct typo in Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0e86908..8874974 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ RUN mkdir -p /.local && \ COPY pyproject.toml /run/pyproject.toml COPY poetry.lock /run/poetry.lock -RUN poetry install --withouit dev --no-root +RUN poetry install --without dev --no-root ENTRYPOINT ["python3", "-B", "-m", "app.main"] From 2d4a1294cbdd8fd4908ef7cf92160aba0cbdaf9c Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 10:05:22 +0000 Subject: [PATCH 42/49] fix(sentry): only import/run Sentry if enabled --- app/commands/submit_task.py | 35 ++++++++-- app/main.py | 3 +- app/utils/n8n.py | 39 +++++++---- poetry.lock | 126 ++++++++++++++++++------------------ 4 files changed, 121 insertions(+), 82 deletions(-) diff --git a/app/commands/submit_task.py b/app/commands/submit_task.py index 89c619d..427edcf 100644 --- a/app/commands/submit_task.py +++ b/app/commands/submit_task.py @@ -2,11 +2,18 @@ import logging -import sentry_sdk from webex_bot.models.command import Command from webex_bot.models.response import Response, response_from_adaptive_card -from webexteamssdk.models.cards import (AdaptiveCard, Column, ColumnSet, Date, - FontSize, FontWeight, Text, TextBlock) +from webexteamssdk.models.cards import ( + AdaptiveCard, + Column, + ColumnSet, + Date, + FontSize, + FontWeight, + Text, + TextBlock, +) from webexteamssdk.models.cards.actions import Submit from app.utils.config import config @@ -14,6 +21,9 @@ from app.utils.n8n import get_tasks, submit_task log: logging.Logger = logging.getLogger(__name__) +if config.sentry_enabled: + import sentry_sdk + class SubmitTaskCommand(Command): """Submit task command.""" @@ -115,8 +125,11 @@ class SubmitTaskCommand(Command): Submit(title="Cancel", data={"command_keyword": "exit"}), ], ) + _result = response_from_adaptive_card(card) + if not config.sentry_enabled: + return _result with sentry_sdk.start_transaction(name="submit_task_command"): - return response_from_adaptive_card(card) + return _result class SubmitTaskCallback(Command): @@ -160,6 +173,8 @@ class SubmitTaskCallback(Command): def execute(self, message, attachment_actions, activity) -> str: """Execute method.""" + if not config.sentry_enabled: + return self.msg with sentry_sdk.start_transaction(name="submit_task_callback"): return self.msg @@ -177,14 +192,22 @@ class MyTasksCallback(Command): def pre_execute(self, message, attachment_actions, activity) -> str: """Pre-execute method.""" + _msg: str = "Getting your tasks..." + if not config.sentry_enabled: + return _msg with sentry_sdk.start_transaction(name="my_tasks_preexec"): - return "Getting your tasks..." + return _msg def execute(self, message, attachment_actions, activity) -> str | None: """Execute method.""" sender: str = attachment_actions.inputs.get("sender") result: bool = get_tasks(requestor=sender) + _msg: str = "Failed to get tasks. Please try again." + if not config.sentry_enabled: + if not result: + return _msg + return None with sentry_sdk.start_transaction(name="my_tasks_exec"): if not result: - return "Failed to get tasks. Please try again." + return _msg return None diff --git a/app/main.py b/app/main.py index 0e94a6f..021c1f3 100644 --- a/app/main.py +++ b/app/main.py @@ -2,7 +2,6 @@ import sys -import sentry_sdk from sentry_sdk.integrations.stdlib import StdlibIntegration from webex_bot.webex_bot import WebexBot @@ -11,6 +10,8 @@ from app.commands.submit_task import SubmitTaskCommand from app.utils.config import config if config.sentry_enabled: + import sentry_sdk + apm = sentry_sdk.init( dsn=config.sentry_dsn, enable_tracing=True, diff --git a/app/utils/n8n.py b/app/utils/n8n.py index 2b59057..2f90637 100644 --- a/app/utils/n8n.py +++ b/app/utils/n8n.py @@ -1,10 +1,12 @@ """N8N utils module.""" import requests -import sentry_sdk from app.utils.config import config +if config.sentry_enabled: + import sentry_sdk + def __n8n_post(data: dict) -> bool: """Post data to N8N webhook URL. @@ -38,15 +40,18 @@ def submit_task(summary, description, completion_date, requestor) -> bool: Returns: bool: True if successful, else False. """ - with sentry_sdk.start_transaction(name="submit_task"): - data: dict = { - "requestor": requestor, - "title": summary, - "description": description, - "completiondate": completion_date, - } + data: dict = { + "requestor": requestor, + "title": summary, + "description": description, + "completiondate": completion_date, + } + if not config.sentry_enabled: _data = __n8n_post(data=data) - return _data + return _data + with sentry_sdk.start_transaction(name="submit_task"): + _data = __n8n_post(data=data) + return _data def get_tasks(requestor) -> bool: @@ -58,8 +63,8 @@ def get_tasks(requestor) -> bool: Returns: bool: True if successful, else False. """ - with sentry_sdk.start_transaction(name="get_tasks"): - headers: dict = {"Content-Type": "application/json"} + headers: dict = {"Content-Type": "application/json"} + if not config.sentry_enabled: resp: requests.Response = requests.get( url=config.n8n_webhook_url, headers=headers, @@ -68,4 +73,14 @@ def get_tasks(requestor) -> bool: params={"requestor": requestor}, ) _data = bool(resp.status_code == 200) - return _data + return _data + with sentry_sdk.start_transaction(name="get_tasks"): + resp: requests.Response = requests.get( + url=config.n8n_webhook_url, + headers=headers, + timeout=10, + verify=False, + params={"requestor": requestor}, + ) + _data = bool(resp.status_code == 200) + return _data diff --git a/poetry.lock b/poetry.lock index 9c16cda..569d57a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -235,73 +235,73 @@ cron = ["capturer (>=2.4)"] [[package]] name = "coverage" -version = "7.6.7" +version = "7.6.8" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:108bb458827765d538abcbf8288599fee07d2743357bdd9b9dad456c287e121e"}, - {file = "coverage-7.6.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c973b2fe4dc445cb865ab369df7521df9c27bf40715c837a113edaa2aa9faf45"}, - {file = "coverage-7.6.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c6b24007c4bcd0b19fac25763a7cac5035c735ae017e9a349b927cfc88f31c1"}, - {file = "coverage-7.6.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acbb8af78f8f91b3b51f58f288c0994ba63c646bc1a8a22ad072e4e7e0a49f1c"}, - {file = "coverage-7.6.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad32a981bcdedb8d2ace03b05e4fd8dace8901eec64a532b00b15217d3677dd2"}, - {file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:34d23e28ccb26236718a3a78ba72744212aa383141961dd6825f6595005c8b06"}, - {file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e25bacb53a8c7325e34d45dddd2f2fbae0dbc230d0e2642e264a64e17322a777"}, - {file = "coverage-7.6.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af05bbba896c4472a29408455fe31b3797b4d8648ed0a2ccac03e074a77e2314"}, - {file = "coverage-7.6.7-cp310-cp310-win32.whl", hash = "sha256:796c9b107d11d2d69e1849b2dfe41730134b526a49d3acb98ca02f4985eeff7a"}, - {file = "coverage-7.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:987a8e3da7da4eed10a20491cf790589a8e5e07656b6dc22d3814c4d88faf163"}, - {file = "coverage-7.6.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7e61b0e77ff4dddebb35a0e8bb5a68bf0f8b872407d8d9f0c726b65dfabe2469"}, - {file = "coverage-7.6.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a5407a75ca4abc20d6252efeb238377a71ce7bda849c26c7a9bece8680a5d99"}, - {file = "coverage-7.6.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df002e59f2d29e889c37abd0b9ee0d0e6e38c24f5f55d71ff0e09e3412a340ec"}, - {file = "coverage-7.6.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:673184b3156cba06154825f25af33baa2671ddae6343f23175764e65a8c4c30b"}, - {file = "coverage-7.6.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e69ad502f1a2243f739f5bd60565d14a278be58be4c137d90799f2c263e7049a"}, - {file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60dcf7605c50ea72a14490d0756daffef77a5be15ed1b9fea468b1c7bda1bc3b"}, - {file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9c2eb378bebb2c8f65befcb5147877fc1c9fbc640fc0aad3add759b5df79d55d"}, - {file = "coverage-7.6.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c0317288f032221d35fa4cbc35d9f4923ff0dfd176c79c9b356e8ef8ef2dff4"}, - {file = "coverage-7.6.7-cp311-cp311-win32.whl", hash = "sha256:951aade8297358f3618a6e0660dc74f6b52233c42089d28525749fc8267dccd2"}, - {file = "coverage-7.6.7-cp311-cp311-win_amd64.whl", hash = "sha256:5e444b8e88339a2a67ce07d41faabb1d60d1004820cee5a2c2b54e2d8e429a0f"}, - {file = "coverage-7.6.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f07ff574986bc3edb80e2c36391678a271d555f91fd1d332a1e0f4b5ea4b6ea9"}, - {file = "coverage-7.6.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:49ed5ee4109258973630c1f9d099c7e72c5c36605029f3a91fe9982c6076c82b"}, - {file = "coverage-7.6.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3e8796434a8106b3ac025fd15417315d7a58ee3e600ad4dbcfddc3f4b14342c"}, - {file = "coverage-7.6.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3b925300484a3294d1c70f6b2b810d6526f2929de954e5b6be2bf8caa1f12c1"}, - {file = "coverage-7.6.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c42ec2c522e3ddd683dec5cdce8e62817afb648caedad9da725001fa530d354"}, - {file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0266b62cbea568bd5e93a4da364d05de422110cbed5056d69339bd5af5685433"}, - {file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e5f2a0f161d126ccc7038f1f3029184dbdf8f018230af17ef6fd6a707a5b881f"}, - {file = "coverage-7.6.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c132b5a22821f9b143f87446805e13580b67c670a548b96da945a8f6b4f2efbb"}, - {file = "coverage-7.6.7-cp312-cp312-win32.whl", hash = "sha256:7c07de0d2a110f02af30883cd7dddbe704887617d5c27cf373362667445a4c76"}, - {file = "coverage-7.6.7-cp312-cp312-win_amd64.whl", hash = "sha256:fd49c01e5057a451c30c9b892948976f5d38f2cbd04dc556a82743ba8e27ed8c"}, - {file = "coverage-7.6.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46f21663e358beae6b368429ffadf14ed0a329996248a847a4322fb2e35d64d3"}, - {file = "coverage-7.6.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:40cca284c7c310d622a1677f105e8507441d1bb7c226f41978ba7c86979609ab"}, - {file = "coverage-7.6.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77256ad2345c29fe59ae861aa11cfc74579c88d4e8dbf121cbe46b8e32aec808"}, - {file = "coverage-7.6.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87ea64b9fa52bf395272e54020537990a28078478167ade6c61da7ac04dc14bc"}, - {file = "coverage-7.6.7-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d608a7808793e3615e54e9267519351c3ae204a6d85764d8337bd95993581a8"}, - {file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdd94501d65adc5c24f8a1a0eda110452ba62b3f4aeaba01e021c1ed9cb8f34a"}, - {file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82c809a62e953867cf57e0548c2b8464207f5f3a6ff0e1e961683e79b89f2c55"}, - {file = "coverage-7.6.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb684694e99d0b791a43e9fc0fa58efc15ec357ac48d25b619f207c41f2fd384"}, - {file = "coverage-7.6.7-cp313-cp313-win32.whl", hash = "sha256:963e4a08cbb0af6623e61492c0ec4c0ec5c5cf74db5f6564f98248d27ee57d30"}, - {file = "coverage-7.6.7-cp313-cp313-win_amd64.whl", hash = "sha256:14045b8bfd5909196a90da145a37f9d335a5d988a83db34e80f41e965fb7cb42"}, - {file = "coverage-7.6.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f2c7a045eef561e9544359a0bf5784b44e55cefc7261a20e730baa9220c83413"}, - {file = "coverage-7.6.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dd4e4a49d9c72a38d18d641135d2fb0bdf7b726ca60a103836b3d00a1182acd"}, - {file = "coverage-7.6.7-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c95e0fa3d1547cb6f021ab72f5c23402da2358beec0a8e6d19a368bd7b0fb37"}, - {file = "coverage-7.6.7-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f63e21ed474edd23f7501f89b53280014436e383a14b9bd77a648366c81dce7b"}, - {file = "coverage-7.6.7-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead9b9605c54d15be228687552916c89c9683c215370c4a44f1f217d2adcc34d"}, - {file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0573f5cbf39114270842d01872952d301027d2d6e2d84013f30966313cadb529"}, - {file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e2c8e3384c12dfa19fa9a52f23eb091a8fad93b5b81a41b14c17c78e23dd1d8b"}, - {file = "coverage-7.6.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:70a56a2ec1869e6e9fa69ef6b76b1a8a7ef709972b9cc473f9ce9d26b5997ce3"}, - {file = "coverage-7.6.7-cp313-cp313t-win32.whl", hash = "sha256:dbba8210f5067398b2c4d96b4e64d8fb943644d5eb70be0d989067c8ca40c0f8"}, - {file = "coverage-7.6.7-cp313-cp313t-win_amd64.whl", hash = "sha256:dfd14bcae0c94004baba5184d1c935ae0d1231b8409eb6c103a5fd75e8ecdc56"}, - {file = "coverage-7.6.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37a15573f988b67f7348916077c6d8ad43adb75e478d0910957394df397d2874"}, - {file = "coverage-7.6.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b6cce5c76985f81da3769c52203ee94722cd5d5889731cd70d31fee939b74bf0"}, - {file = "coverage-7.6.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ab9763d291a17b527ac6fd11d1a9a9c358280adb320e9c2672a97af346ac2c"}, - {file = "coverage-7.6.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cf96ceaa275f071f1bea3067f8fd43bec184a25a962c754024c973af871e1b7"}, - {file = "coverage-7.6.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee9cf6b0134d6f932d219ce253ef0e624f4fa588ee64830fcba193269e4daa3"}, - {file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2bc3e45c16564cc72de09e37413262b9f99167803e5e48c6156bccdfb22c8327"}, - {file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:623e6965dcf4e28a3debaa6fcf4b99ee06d27218f46d43befe4db1c70841551c"}, - {file = "coverage-7.6.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850cfd2d6fc26f8346f422920ac204e1d28814e32e3a58c19c91980fa74d8289"}, - {file = "coverage-7.6.7-cp39-cp39-win32.whl", hash = "sha256:c296263093f099da4f51b3dff1eff5d4959b527d4f2f419e16508c5da9e15e8c"}, - {file = "coverage-7.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:90746521206c88bdb305a4bf3342b1b7316ab80f804d40c536fc7d329301ee13"}, - {file = "coverage-7.6.7-pp39.pp310-none-any.whl", hash = "sha256:0ddcb70b3a3a57581b450571b31cb774f23eb9519c2aaa6176d3a84c9fc57671"}, - {file = "coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed"}, + {file = "coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e"}, + {file = "coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0"}, + {file = "coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801"}, + {file = "coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443"}, + {file = "coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad"}, + {file = "coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"}, + {file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"}, + {file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"}, + {file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"}, + {file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea"}, + {file = "coverage-7.6.8-cp39-cp39-win32.whl", hash = "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e"}, + {file = "coverage-7.6.8-cp39-cp39-win_amd64.whl", hash = "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076"}, + {file = "coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce"}, + {file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"}, ] [package.extras] From 5efa42d35d3d407bb521f2d19848af044950d207 Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 10:16:20 +0000 Subject: [PATCH 43/49] feat(sentry): remove Sentry --- .archive/requirements.txt | 1 - .env.default | 2 -- README.md | 4 +-- app/commands/submit_task.py | 29 ++++--------------- app/main.py | 13 --------- app/utils/config.py | 22 --------------- app/utils/n8n.py | 40 ++++++++------------------ poetry.lock | 56 +------------------------------------ pyproject.toml | 1 - test.sh | 2 +- tests/test_config_1.py | 10 ------- tests/test_config_2.py | 10 ------- 12 files changed, 20 insertions(+), 170 deletions(-) diff --git a/.archive/requirements.txt b/.archive/requirements.txt index 12f604d..9cb9faf 100644 --- a/.archive/requirements.txt +++ b/.archive/requirements.txt @@ -33,7 +33,6 @@ python-dotenv==1.0.1 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.19.0 six==1.16.0 toml==0.10.2 tomli==2.1.0 diff --git a/.env.default b/.env.default index 9008ecc..0d6cd03 100644 --- a/.env.default +++ b/.env.default @@ -6,6 +6,4 @@ APPROVED_ROOMS="abc123,def456" APPROVED_USERS="bob@example.com,john@me.com" BOT_NAME="" N8N_WEBHOOK_URL="" -SENTRY_DSN="" -SENTRY_ENABLED="False" WEBEX_API_KEY="" diff --git a/README.md b/README.md index d0349eb..7a07f06 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,12 @@ Add tasks to a Wekan to do list via Webex and n8n. 3. Edit `.env` as required: - `ADMIN_EMAIL` - comma-separated list of admin (who owns the to-do list) email addresses - `ADMIN_FIRST_NAME` - admin first name - - `APP_LIFECYCLE` - for use in Sentry only, set the name of the environment + - `APP_LIFECYCLE` - set the name of the environment - `APPROVED_DOMAINS` - comma-separated list of domains that users are allowed to message the bot from - `APPROVED_ROOMS` - comma-separated list of room IDs that users are allowed to message the bot from - `APPROVED_USERS` - comma-separated list of email addresses of approved users - `BOT_NAME` - Webex bot name - `N8N_WEBHOOK_URL` - n8n webhook URL - - `SENTRY_DSN` - for use in Sentry only, set the DSN of the Sentry project - - `SENTRY_ENABLED` - for use in Sentry only, enable sending data to Sentry - `WEBEX_API_KEY` - Webex API key ## How to use diff --git a/app/commands/submit_task.py b/app/commands/submit_task.py index 427edcf..1d74749 100644 --- a/app/commands/submit_task.py +++ b/app/commands/submit_task.py @@ -21,9 +21,6 @@ from app.utils.n8n import get_tasks, submit_task log: logging.Logger = logging.getLogger(__name__) -if config.sentry_enabled: - import sentry_sdk - class SubmitTaskCommand(Command): """Submit task command.""" @@ -126,10 +123,7 @@ class SubmitTaskCommand(Command): ], ) _result = response_from_adaptive_card(card) - if not config.sentry_enabled: - return _result - with sentry_sdk.start_transaction(name="submit_task_command"): - return _result + return _result class SubmitTaskCallback(Command): @@ -173,10 +167,7 @@ class SubmitTaskCallback(Command): def execute(self, message, attachment_actions, activity) -> str: """Execute method.""" - if not config.sentry_enabled: - return self.msg - with sentry_sdk.start_transaction(name="submit_task_callback"): - return self.msg + return self.msg class MyTasksCallback(Command): @@ -193,21 +184,13 @@ class MyTasksCallback(Command): def pre_execute(self, message, attachment_actions, activity) -> str: """Pre-execute method.""" _msg: str = "Getting your tasks..." - if not config.sentry_enabled: - return _msg - with sentry_sdk.start_transaction(name="my_tasks_preexec"): - return _msg + return _msg def execute(self, message, attachment_actions, activity) -> str | None: """Execute method.""" sender: str = attachment_actions.inputs.get("sender") result: bool = get_tasks(requestor=sender) _msg: str = "Failed to get tasks. Please try again." - if not config.sentry_enabled: - if not result: - return _msg - return None - with sentry_sdk.start_transaction(name="my_tasks_exec"): - if not result: - return _msg - return None + if not result: + return _msg + return None diff --git a/app/main.py b/app/main.py index 021c1f3..5936fcd 100644 --- a/app/main.py +++ b/app/main.py @@ -2,25 +2,12 @@ import sys -from sentry_sdk.integrations.stdlib import StdlibIntegration from webex_bot.webex_bot import WebexBot from app.commands.exit import ExitCommand from app.commands.submit_task import SubmitTaskCommand from app.utils.config import config -if config.sentry_enabled: - import sentry_sdk - - apm = sentry_sdk.init( - dsn=config.sentry_dsn, - enable_tracing=True, - environment=config.environment, - release=config.version, - integrations=[StdlibIntegration()], - spotlight=True, - ) - def create_bot() -> WebexBot: """Create and return a Webex Bot object.""" diff --git a/app/utils/config.py b/app/utils/config.py index 84bdfb2..73e31e7 100644 --- a/app/utils/config.py +++ b/app/utils/config.py @@ -11,15 +11,6 @@ class Config: def __init__(self) -> None: """Configuration module.""" - # Sentry config needs to be processed first for loop prevention. - - self.__sentry_dsn: str = os.environ.get("SENTRY_DSN", "") - - self.__sentry_enabled: bool = bool( - os.environ.get("SENTRY_ENABLED", "False").upper() == "TRUE" - and self.__sentry_dsn != "" - ) - @property def environment(self) -> str: """Returns the current app lifecycle.""" @@ -30,19 +21,6 @@ class Config: """Returns the current app version.""" return os.environ["APP_VERSION"] - @property - def sentry_enabled(self) -> bool: - """Returns True if Sentry SDK is enabled, else False.""" - return self.__sentry_enabled - - @property - def sentry_dsn(self) -> str: - """Returns the Sentry DSN value if Sentry SDK is enabled AND - Sentry DSN is set, else blank string.""" - if not self.__sentry_enabled: - return "" - return self.__sentry_dsn - @property def bot_name(self) -> str: """Returns the bot name.""" diff --git a/app/utils/n8n.py b/app/utils/n8n.py index 2f90637..de74d44 100644 --- a/app/utils/n8n.py +++ b/app/utils/n8n.py @@ -4,9 +4,6 @@ import requests from app.utils.config import config -if config.sentry_enabled: - import sentry_sdk - def __n8n_post(data: dict) -> bool: """Post data to N8N webhook URL. @@ -46,12 +43,8 @@ def submit_task(summary, description, completion_date, requestor) -> bool: "description": description, "completiondate": completion_date, } - if not config.sentry_enabled: - _data = __n8n_post(data=data) - return _data - with sentry_sdk.start_transaction(name="submit_task"): - _data = __n8n_post(data=data) - return _data + _data = __n8n_post(data=data) + return _data def get_tasks(requestor) -> bool: @@ -64,23 +57,12 @@ def get_tasks(requestor) -> bool: bool: True if successful, else False. """ headers: dict = {"Content-Type": "application/json"} - if not config.sentry_enabled: - resp: requests.Response = requests.get( - url=config.n8n_webhook_url, - headers=headers, - timeout=10, - verify=False, - params={"requestor": requestor}, - ) - _data = bool(resp.status_code == 200) - return _data - with sentry_sdk.start_transaction(name="get_tasks"): - resp: requests.Response = requests.get( - url=config.n8n_webhook_url, - headers=headers, - timeout=10, - verify=False, - params={"requestor": requestor}, - ) - _data = bool(resp.status_code == 200) - return _data + resp: requests.Response = requests.get( + url=config.n8n_webhook_url, + headers=headers, + timeout=10, + verify=False, + params={"requestor": requestor}, + ) + _data = bool(resp.status_code == 200) + return _data diff --git a/poetry.lock b/poetry.lock index 569d57a..d531aa0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -611,60 +611,6 @@ files = [ [package.dependencies] requests = ">=2.0.1,<3.0.0" -[[package]] -name = "sentry-sdk" -version = "2.19.0" -description = "Python client for Sentry (https://sentry.io)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "sentry_sdk-2.19.0-py2.py3-none-any.whl", hash = "sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b"}, - {file = "sentry_sdk-2.19.0.tar.gz", hash = "sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36"}, -] - -[package.dependencies] -certifi = "*" -urllib3 = ">=1.26.11" - -[package.extras] -aiohttp = ["aiohttp (>=3.5)"] -anthropic = ["anthropic (>=0.16)"] -arq = ["arq (>=0.23)"] -asyncpg = ["asyncpg (>=0.23)"] -beam = ["apache-beam (>=2.12)"] -bottle = ["bottle (>=0.12.13)"] -celery = ["celery (>=3)"] -celery-redbeat = ["celery-redbeat (>=2)"] -chalice = ["chalice (>=1.16.0)"] -clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] -django = ["django (>=1.8)"] -falcon = ["falcon (>=1.4)"] -fastapi = ["fastapi (>=0.79.0)"] -flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] -grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] -http2 = ["httpcore[http2] (==1.*)"] -httpx = ["httpx (>=0.16.0)"] -huey = ["huey (>=2)"] -huggingface-hub = ["huggingface_hub (>=0.22)"] -langchain = ["langchain (>=0.0.210)"] -launchdarkly = ["launchdarkly-server-sdk (>=9.8.0)"] -litestar = ["litestar (>=2.0.0)"] -loguru = ["loguru (>=0.5)"] -openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] -openfeature = ["openfeature-sdk (>=0.7.1)"] -opentelemetry = ["opentelemetry-distro (>=0.35b0)"] -opentelemetry-experimental = ["opentelemetry-distro"] -pure-eval = ["asttokens", "executing", "pure_eval"] -pymongo = ["pymongo (>=3.1)"] -pyspark = ["pyspark (>=2.4.4)"] -quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] -rq = ["rq (>=0.6)"] -sanic = ["sanic (>=0.8)"] -sqlalchemy = ["sqlalchemy (>=1.2)"] -starlette = ["starlette (>=0.19.1)"] -starlite = ["starlite (>=1.48)"] -tornado = ["tornado (>=6)"] - [[package]] name = "setuptools" version = "75.6.0" @@ -905,4 +851,4 @@ testing = ["coverage[toml]", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "341e2cb729a0e9691470e528ed4b51908531612834963958eb5c88fb76939473" +content-hash = "2b60fc563ffa2c3d82d6714b92627a110680b59194ddc33b2aee62f4cc576d55" diff --git a/pyproject.toml b/pyproject.toml index e36bbd7..d7b490f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ package-mode = false [tool.poetry.dependencies] python = "^3.11" webex-bot = "^0.5.2" -sentry-sdk = "^2.19.0" datetime = "^5.5" requests = "^2.32.3" diff --git a/test.sh b/test.sh index ee3861d..c17fd3e 100755 --- a/test.sh +++ b/test.sh @@ -1,3 +1,3 @@ export $(cat .env.test | xargs) python -B -m app.main -unset ADMIN_EMAIL ADMIN_FIRST_NAME APP_LIFECYCLE APP_VERSION APPROVED_DOMAINS APPROVED_ROOMS APPROVED_USERS BOT_NAME N8N_WEBHOOK_URL SENTRY_DSN SENTRY_ENABLED WEBEX_API_KEY +unset ADMIN_EMAIL ADMIN_FIRST_NAME APP_LIFECYCLE APP_VERSION APPROVED_DOMAINS APPROVED_ROOMS APPROVED_USERS BOT_NAME N8N_WEBHOOK_URL WEBEX_API_KEY diff --git a/tests/test_config_1.py b/tests/test_config_1.py index bba05e2..d694f29 100644 --- a/tests/test_config_1.py +++ b/tests/test_config_1.py @@ -17,8 +17,6 @@ def test_config() -> None: "ADMIN_FIRST_NAME": "Test", "ADMIN_EMAIL": "test@test.com", "N8N_WEBHOOK_URL": "https://n8n.test.com/webhook/abcdefg", - "SENTRY_ENABLED": "false", - "SENTRY_DSN": "http://localhost", "APPROVED_USERS": "test@test.com", "APPROVED_DOMAINS": "test.com", "APPROVED_ROOMS": "test", @@ -37,16 +35,8 @@ def test_config() -> None: assert config.approved_users == config_vars["APPROVED_USERS"].split(",") assert config.bot_name == config_vars["BOT_NAME"] assert config.n8n_webhook_url == config_vars["N8N_WEBHOOK_URL"] - assert config.sentry_enabled == bool( - config_vars["SENTRY_ENABLED"].upper() == "TRUE" - ) assert config.version == config_vars["APP_VERSION"] assert config.webex_token == config_vars["WEBEX_API_KEY"] - if config.sentry_enabled: - assert config.sentry_dsn == config_vars["SENTRY_DSN"] - else: - assert config.sentry_dsn == "" - for config_var in config_vars: os.environ.pop(config_var, None) diff --git a/tests/test_config_2.py b/tests/test_config_2.py index f3ec601..4e0c042 100644 --- a/tests/test_config_2.py +++ b/tests/test_config_2.py @@ -17,8 +17,6 @@ def test_config_no_admin_vars() -> None: "ADMIN_FIRST_NAME": "Test", "ADMIN_EMAIL": "test@test.com", "N8N_WEBHOOK_URL": "https://n8n.test.com/webhook/abcdefg", - "SENTRY_ENABLED": "false", - "SENTRY_DSN": "http://localhost", } for config_var, value in config_vars.items(): @@ -34,16 +32,8 @@ def test_config_no_admin_vars() -> None: assert config.admin_first_name == config_vars["ADMIN_FIRST_NAME"] assert config.bot_name == config_vars["BOT_NAME"] assert config.n8n_webhook_url == config_vars["N8N_WEBHOOK_URL"] - assert config.sentry_enabled == bool( - config_vars["SENTRY_ENABLED"].upper() == "TRUE" - ) assert config.version == config_vars["APP_VERSION"] assert config.webex_token == config_vars["WEBEX_API_KEY"] - if config.sentry_enabled: - assert config.sentry_dsn == config_vars["SENTRY_DSN"] - else: - assert config.sentry_dsn == "" - for config_var in config_vars: os.environ.pop(config_var, None) From ebca87230abf5ac8b02d46874c1470b94f864aae Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 10:24:44 +0000 Subject: [PATCH 44/49] fix(docker): fix dependency installation --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8874974..661e8fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ RUN mkdir -p /.local && \ COPY pyproject.toml /run/pyproject.toml COPY poetry.lock /run/poetry.lock -RUN poetry install --without dev --no-root +RUN poetry install --without dev ENTRYPOINT ["python3", "-B", "-m", "app.main"] From 6cac9dc9c23006c038a164b3f98353774cef4ed4 Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 10:31:49 +0000 Subject: [PATCH 45/49] fix(docker): disable auto-creation of virtualenv inside container --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 661e8fb..26ef8e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,9 @@ RUN mkdir -p /.local && \ COPY pyproject.toml /run/pyproject.toml COPY poetry.lock /run/poetry.lock -RUN poetry install --without dev + +RUN poetry config virtualenvs.create false && \ + poetry install --without dev ENTRYPOINT ["python3", "-B", "-m", "app.main"] From b11cc26daa31c77b3413e39bb1c51128600111e0 Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 10:41:08 +0000 Subject: [PATCH 46/49] fix(config): always return a list, even if empty, as required by webex_bot --- app/utils/config.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/utils/config.py b/app/utils/config.py index 73e31e7..629adc9 100644 --- a/app/utils/config.py +++ b/app/utils/config.py @@ -47,31 +47,27 @@ class Config: return os.environ["N8N_WEBHOOK_URL"] @property - def approved_users(self) -> list | None: + def approved_users(self) -> list: """Returns a list of approved users.""" _emails: list[str] = os.environ.get("APPROVED_USERS", "").split(",") _emails: list[str] = [i.strip() for i in _emails if i] if not _emails: - return None + return [] emails = [i for i in _emails if validate_email_syntax(i)] return emails @property - def approved_rooms(self) -> list | None: + def approved_rooms(self) -> list: """Returns a list of approved rooms.""" _rooms: list[str] = os.environ.get("APPROVED_ROOMS", "").split(",") rooms: list[str] = [i.strip() for i in _rooms if i] - if not rooms: - return None return rooms @property - def approved_domains(self) -> list | None: + def approved_domains(self) -> list: """Returns a list of approved domains.""" _domains: list[str] = os.environ.get("APPROVED_DOMAINS", "").split(",") domains: list[str] = [i.strip() for i in _domains if i] - if not domains: - return None return domains From 70a92c76dbe57c33c4e5e0f141a3c670fab588ce Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 24 Nov 2024 11:02:31 +0000 Subject: [PATCH 47/49] chore(ci): run tests on release workflow --- .github/workflows/release.yml | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6012ad1..41e3b54 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,54 @@ on: - cron: "0 9 * * 0" jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4.1.7 + with: + fetch-depth: 0 + - uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: Dockerfile + output-file: hadolint.out + format: sonarqube + no-fail: true + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + - name: Setup Poetry + uses: abatilo/actions-poetry@v3 + - name: Install dependencies + run: poetry install + - name: Lint + run: | + poetry run pylint --fail-under=8 --recursive=yes --output-format=parseable --output=lintreport.txt . + cat lintreport.txt + - name: Unit Test + run: | + poetry run coverage run -m pytest -v --junitxml=testresults.xml + poetry run coverage xml + sed -i 's@${{ github.workspace }}@/github/workspace@g' coverage.xml + - name: SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + - name: Snyk Vulnerability Scan + uses: snyk/actions/python-3.10@master + continue-on-error: true # To make sure that SARIF upload gets called + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --sarif-file-output=snyk.sarif --all-projects + - name: Upload result to GitHub Code Scanning + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: snyk.sarif + create_release: name: Create Release uses: luketainton/gha-workflows/.github/workflows/create-release.yml@main From 948d223fa4b003e10d1e9cc1b682a8810b5888c5 Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Thu, 28 Nov 2024 21:12:27 +0000 Subject: [PATCH 48/49] fix(tests): config.approved_domains returns empty list when not set --- tests/test_config_2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_config_2.py b/tests/test_config_2.py index 4e0c042..b4247d3 100644 --- a/tests/test_config_2.py +++ b/tests/test_config_2.py @@ -25,9 +25,9 @@ def test_config_no_admin_vars() -> None: # needs to be imported AFTER environment variables are set from app.utils.config import config # pragma: no cover - assert config.approved_domains is None - assert config.approved_rooms is None - assert config.approved_users is None + assert config.approved_domains == [] + assert config.approved_rooms == [] + assert config.approved_users == [] assert config.admin_emails == config_vars["ADMIN_EMAIL"].split(",") assert config.admin_first_name == config_vars["ADMIN_FIRST_NAME"] assert config.bot_name == config_vars["BOT_NAME"] From 33186a47c72cc2add977f9f3c3462e3000438245 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:07:34 +0000 Subject: [PATCH 49/49] chore(actions)(deps): bump actions/checkout from 4.1.7 to 4.2.2 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.7 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.7...v4.2.2) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41e3b54..8e93a0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository code - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.2 with: fetch-depth: 0 - uses: hadolint/hadolint-action@v3.1.0