From 1a99a715e19504d062afab5bac2a66cf649adb2f Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Wed, 3 Jul 2024 10:31:52 -0400 Subject: [PATCH 1/9] update config.py --- analytics/config.py | 55 +++++++++++++--------- analytics/src/analytics/integrations/db.py | 4 +- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/analytics/config.py b/analytics/config.py index 60a7786b6..7cf1eca46 100644 --- a/analytics/config.py +++ b/analytics/config.py @@ -9,27 +9,38 @@ For more information visit: https://www.dynaconf.com/ """ -from dynaconf import Dynaconf, Validator, ValidationError +# from dynaconf import Dynaconf, Validator, ValidationError +from pydantic_settings import BaseSettings +from pydantic import Field -settings = Dynaconf( - # set env vars with `export ANALYTICS_FOO=bar` - envvar_prefix="ANALYTICS", - # looks for config vars in the following files - # with vars in .secrets.toml overriding vars in settings.toml - settings_files=["settings.toml", ".secrets.toml"], - # merge the settings found in all files - merge_enabled= True, - # add validators for our required config vars - validators=[ - Validator("SLACK_BOT_TOKEN", must_exist=True), - Validator("REPORTING_CHANNEL_ID", must_exist=True), - ], -) +class DBSettings(BaseSettings): + # will load from the DB_HOST env var if it exists, otherwise use the default + db_host: str = "localhost" -# raises after all possible errors are evaluated -try: - settings.validators.validate_all() -except ValidationError as error: - list_of_all_errors = error.details - print(list_of_all_errors) - raise + # Without a default, will error if the env var isn't set + port: 5432 + user: "app" + password: "secret123" + +# settings = Dynaconf( +# # set env vars with `export ANALYTICS_FOO=bar` +# envvar_prefix="ANALYTICS", +# # looks for config vars in the following files +# # with vars in .secrets.toml overriding vars in settings.toml +# settings_files=["settings.toml", ".secrets.toml"], +# # merge the settings found in all files +# merge_enabled= True, +# # add validators for our required config vars +# validators=[ +# Validator("SLACK_BOT_TOKEN", must_exist=True), +# Validator("REPORTING_CHANNEL_ID", must_exist=True), +# ], +# ) + +# # raises after all possible errors are evaluated +# try: +# settings.validators.validate_all() +# except ValidationError as error: +# list_of_all_errors = error.details +# print(list_of_all_errors) +# raise diff --git a/analytics/src/analytics/integrations/db.py b/analytics/src/analytics/integrations/db.py index 6f6ef1155..609511b86 100644 --- a/analytics/src/analytics/integrations/db.py +++ b/analytics/src/analytics/integrations/db.py @@ -3,7 +3,7 @@ from sqlalchemy import Engine, create_engine -from config import settings +from config import DBSettings # The variables used in the connection url are set in settings.toml and @@ -23,7 +23,7 @@ def get_db() -> Engine: A SQLAlchemy engine object representing the connection to the database. """ return create_engine( - f"postgresql+psycopg://{settings.postgres_user}:{settings.postgres_password}@{settings.postgres_host}:{settings.postgres_port}", + f"postgresql+psycopg://{DBSettings.user}:{DBSettings.password}@{DBSettings.db_host}:{DBSettings.port}", pool_pre_ping=True, hide_parameters=True, ) From 42e2f6e56dfa83c2a26a994b8882b17ddc70965a Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Mon, 8 Jul 2024 13:37:38 -0400 Subject: [PATCH 2/9] remove dynaconf settings; add pydantic settings --- analytics/config.py | 54 ++++++---------------- analytics/poetry.lock | 35 +++++++++++++- analytics/pyproject.toml | 1 + analytics/src/analytics/integrations/db.py | 4 +- 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/analytics/config.py b/analytics/config.py index 7cf1eca46..9ad131131 100644 --- a/analytics/config.py +++ b/analytics/config.py @@ -1,46 +1,18 @@ -"""Loads configuration variables from settings files and settings files +"""Loads configuration variables from settings files -Dynaconf provides a few valuable features for configuration management: -- Load variables from env vars and files with predictable overrides -- Validate the existence and format of required configs -- Connect with secrets managers like HashiCorp's Vault server -- Load different configs based on environment (e.g. DEV, PROD, STAGING) - -For more information visit: https://www.dynaconf.com/ """ - -# from dynaconf import Dynaconf, Validator, ValidationError -from pydantic_settings import BaseSettings +import os +from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic import Field -class DBSettings(BaseSettings): - # will load from the DB_HOST env var if it exists, otherwise use the default - db_host: str = "localhost" - - # Without a default, will error if the env var isn't set - port: 5432 - user: "app" - password: "secret123" - -# settings = Dynaconf( -# # set env vars with `export ANALYTICS_FOO=bar` -# envvar_prefix="ANALYTICS", -# # looks for config vars in the following files -# # with vars in .secrets.toml overriding vars in settings.toml -# settings_files=["settings.toml", ".secrets.toml"], -# # merge the settings found in all files -# merge_enabled= True, -# # add validators for our required config vars -# validators=[ -# Validator("SLACK_BOT_TOKEN", must_exist=True), -# Validator("REPORTING_CHANNEL_ID", must_exist=True), -# ], -# ) +# reads environment variables from .env files defaulting to "local.env" +class PydanticBaseEnvConfig(BaseSettings): + model_config = SettingsConfigDict(env_file="%s.env" % os.getenv("ENVIRONMENT", "local"), extra="ignore") # set extra to ignore so that it ignores variables irrelevant to the database config (e.g. metabase settings) -# # raises after all possible errors are evaluated -# try: -# settings.validators.validate_all() -# except ValidationError as error: -# list_of_all_errors = error.details -# print(list_of_all_errors) -# raise +class DBSettings(PydanticBaseEnvConfig): + db_host: str = Field(alias="DB_HOST") + port: int = Field(5432,alias="DB_PORT") + user: str = Field (alias="DB_USER") + password: str = Field(alias="DB_PASSWORD") + ssl_mode: str = Field(alias="DB_SSL_MODE") +# Need to figure out how to get slackbot an gh tokens here \ No newline at end of file diff --git a/analytics/poetry.lock b/analytics/poetry.lock index 3029d81fe..6b45d2084 100644 --- a/analytics/poetry.lock +++ b/analytics/poetry.lock @@ -2104,6 +2104,25 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydantic-settings" +version = "2.3.4" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"}, + {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"}, +] + +[package.dependencies] +pydantic = ">=2.7.0" +python-dotenv = ">=0.21.0" + +[package.extras] +toml = ["tomli (>=2.0.1)"] +yaml = ["pyyaml (>=6.0.1)"] + [[package]] name = "pygments" version = "2.18.0" @@ -2197,6 +2216,20 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "python-json-logger" version = "2.0.7" @@ -3183,4 +3216,4 @@ test = ["websockets"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "5cfdff4542a0784685c9464acce097c7fb579ddea7bfe49946b62c7c512144ee" +content-hash = "0a82827fbe80ff77cf44f3b02808a828b311bae027b6955afbd774e426e15063" diff --git a/analytics/pyproject.toml b/analytics/pyproject.toml index 0972263d4..85f0edbec 100644 --- a/analytics/pyproject.toml +++ b/analytics/pyproject.toml @@ -22,6 +22,7 @@ slack-sdk = "^3.23.0" typer = { extras = ["all"], version = "^0.9.0" } sqlalchemy = "^2.0.30" psycopg = ">=3.0.7" +pydantic-settings = "^2.3.4" [tool.poetry.group.dev.dependencies] black = "^23.7.0" diff --git a/analytics/src/analytics/integrations/db.py b/analytics/src/analytics/integrations/db.py index 609511b86..40d5812af 100644 --- a/analytics/src/analytics/integrations/db.py +++ b/analytics/src/analytics/integrations/db.py @@ -22,8 +22,10 @@ def get_db() -> Engine: sqlalchemy.engine.Engine A SQLAlchemy engine object representing the connection to the database. """ + db = DBSettings() + print(f"postgresql+psycopg://{db.user}:{db.password}@{db.db_host}:{db.port}") return create_engine( - f"postgresql+psycopg://{DBSettings.user}:{DBSettings.password}@{DBSettings.db_host}:{DBSettings.port}", + f"postgresql+psycopg://{db.user}:{db.password}@{db.db_host}:{db.port}", pool_pre_ping=True, hide_parameters=True, ) From 0a445b5c6c14c375458b011b022452d229f576f2 Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Mon, 8 Jul 2024 15:01:25 -0400 Subject: [PATCH 3/9] fix tests --- analytics/config.py | 3 ++- analytics/src/analytics/cli.py | 2 +- analytics/tests/integrations/test_slack.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/analytics/config.py b/analytics/config.py index 9ad131131..7e5ab024c 100644 --- a/analytics/config.py +++ b/analytics/config.py @@ -15,4 +15,5 @@ class DBSettings(PydanticBaseEnvConfig): user: str = Field (alias="DB_USER") password: str = Field(alias="DB_PASSWORD") ssl_mode: str = Field(alias="DB_SSL_MODE") -# Need to figure out how to get slackbot an gh tokens here \ No newline at end of file + slack_bot_token: str = Field(alias="SLACK_BOT_TOKEN") + reporting_channel_id: str = Field(alias="REPORTING_CHANNEL_ID") \ No newline at end of file diff --git a/analytics/src/analytics/cli.py b/analytics/src/analytics/cli.py index 60b482160..fd041bd86 100644 --- a/analytics/src/analytics/cli.py +++ b/analytics/src/analytics/cli.py @@ -241,7 +241,7 @@ def show_and_or_post_results( """Optionally show the results of a metric and/or post them to slack.""" # defer load of settings until this command is called # this prevents an error if ANALYTICS_SLACK_BOT_TOKEN env var is unset - from config import settings + from config import DBSettings as settings # optionally display the burndown chart in the browser if show_results: diff --git a/analytics/tests/integrations/test_slack.py b/analytics/tests/integrations/test_slack.py index 6caef5c7a..8a4282c7c 100644 --- a/analytics/tests/integrations/test_slack.py +++ b/analytics/tests/integrations/test_slack.py @@ -5,7 +5,7 @@ from slack_sdk import WebClient from analytics.integrations.slack import FileMapping, SlackBot -from config import settings +from config import DBSettings as settings client = WebClient(token=settings.slack_bot_token) From 0946598bf7c5cc92e6de4a0f76d8c6e0a6082bea Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Mon, 8 Jul 2024 15:11:37 -0400 Subject: [PATCH 4/9] remove dynaconf references --- analytics/.gitignore | 2 -- analytics/settings.toml | 4 ---- analytics/src/analytics/integrations/db.py | 6 ++---- 3 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 analytics/settings.toml diff --git a/analytics/.gitignore b/analytics/.gitignore index e2a66772c..9e67bd47d 100644 --- a/analytics/.gitignore +++ b/analytics/.gitignore @@ -1,4 +1,2 @@ data -# Ignore dynaconf secret files -.secrets.* diff --git a/analytics/settings.toml b/analytics/settings.toml deleted file mode 100644 index 7ff7221cc..000000000 --- a/analytics/settings.toml +++ /dev/null @@ -1,4 +0,0 @@ -POSTGRES_NAME = "app" -POSTGRES_HOST = "grants-analytics-db" -POSTGRES_USER = "app" -POSTGRES_PORT = 5432 \ No newline at end of file diff --git a/analytics/src/analytics/integrations/db.py b/analytics/src/analytics/integrations/db.py index 40d5812af..5109d288b 100644 --- a/analytics/src/analytics/integrations/db.py +++ b/analytics/src/analytics/integrations/db.py @@ -6,10 +6,8 @@ from config import DBSettings -# The variables used in the connection url are set in settings.toml and -# .secrets.toml. These can be overridden with the custom prefix defined in config.py: "ANALYTICS". -# e.g. `export ANALYTICS_POSTGRES_USER=new_usr`. -# Docs: https://www.dynaconf.com/envvars/ +# The variables used in the connection url are pulled from local.env and configured in the DBSettings class found in config.py + def get_db() -> Engine: """ Get a connection to the database using a SQLAlchemy engine object. From 7d9a5da7236db23fa5904e367faa46e101a98eab Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Mon, 8 Jul 2024 15:41:21 -0400 Subject: [PATCH 5/9] lint; update validators --- analytics/src/analytics/cli.py | 6 +++--- analytics/src/analytics/integrations/db.py | 5 +++-- analytics/tests/integrations/test_slack.py | 10 ++++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/analytics/src/analytics/cli.py b/analytics/src/analytics/cli.py index fd041bd86..238413ef4 100644 --- a/analytics/src/analytics/cli.py +++ b/analytics/src/analytics/cli.py @@ -241,7 +241,7 @@ def show_and_or_post_results( """Optionally show the results of a metric and/or post them to slack.""" # defer load of settings until this command is called # this prevents an error if ANALYTICS_SLACK_BOT_TOKEN env var is unset - from config import DBSettings as settings + from config import DBSettings # optionally display the burndown chart in the browser if show_results: @@ -249,9 +249,9 @@ def show_and_or_post_results( print("Slack message:\n") print(metric.format_slack_message()) if post_results: - slackbot = slack.SlackBot(client=WebClient(token=settings.slack_bot_token)) + slackbot = slack.SlackBot(client=WebClient(token=DBSettings.slack_bot_token)) metric.post_results_to_slack( slackbot=slackbot, - channel_id=settings.reporting_channel_id, + channel_id=DBSettings.reporting_channel_id, output_dir=Path(output_dir), ) diff --git a/analytics/src/analytics/integrations/db.py b/analytics/src/analytics/integrations/db.py index 5109d288b..8b6edf18d 100644 --- a/analytics/src/analytics/integrations/db.py +++ b/analytics/src/analytics/integrations/db.py @@ -5,8 +5,9 @@ from config import DBSettings +# The variables used in the connection url are pulled from local.env +# and configured in the DBSettings class found in config.py -# The variables used in the connection url are pulled from local.env and configured in the DBSettings class found in config.py def get_db() -> Engine: """ @@ -20,7 +21,7 @@ def get_db() -> Engine: sqlalchemy.engine.Engine A SQLAlchemy engine object representing the connection to the database. """ - db = DBSettings() + db = DBSettings print(f"postgresql+psycopg://{db.user}:{db.password}@{db.db_host}:{db.port}") return create_engine( f"postgresql+psycopg://{db.user}:{db.password}@{db.db_host}:{db.port}", diff --git a/analytics/tests/integrations/test_slack.py b/analytics/tests/integrations/test_slack.py index 8a4282c7c..a065f4093 100644 --- a/analytics/tests/integrations/test_slack.py +++ b/analytics/tests/integrations/test_slack.py @@ -5,9 +5,9 @@ from slack_sdk import WebClient from analytics.integrations.slack import FileMapping, SlackBot -from config import DBSettings as settings +from config import DBSettings -client = WebClient(token=settings.slack_bot_token) +client = WebClient(token=DBSettings.slack_bot_token) @pytest.fixture(name="slackbot") @@ -19,7 +19,9 @@ def mock_slackbot() -> SlackBot: @pytest.mark.skip(reason="requires Slack token") def test_fetch_slack_channels(slackbot: SlackBot): """The fetch_slack_channels() function should execute correctly.""" - result = slackbot.fetch_slack_channel_info(channel_id=settings.reporting_channel_id) + result = slackbot.fetch_slack_channel_info( + channel_id=DBSettings.reporting_channel_id, + ) assert result["ok"] is True assert result["channel"]["name"] == "z_bot-analytics-ci-test" @@ -47,7 +49,7 @@ def test_upload_files_to_slack_channel(slackbot: SlackBot): """ result = slackbot.upload_files_to_slack_channel( files=files, - channel_id=settings.reporting_channel_id, + channel_id=DBSettings.reporting_channel_id, message=markdown, ) assert result["ok"] is True From b1546b57de6f6d2e7bb6e7aff19f1d963f1f4498 Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Tue, 9 Jul 2024 15:22:47 -0400 Subject: [PATCH 6/9] update package --- analytics/poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/analytics/poetry.lock b/analytics/poetry.lock index 6b45d2084..3b24238a9 100644 --- a/analytics/poetry.lock +++ b/analytics/poetry.lock @@ -276,13 +276,13 @@ css = ["tinycss2 (>=1.1.0,<1.3)"] [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] From 0fe4fdfd10accf4561b861e812d8054b9d242e4f Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Tue, 9 Jul 2024 17:30:48 -0400 Subject: [PATCH 7/9] update config --- analytics/config.py | 5 +++-- analytics/local.env | 10 ++++++++++ analytics/src/analytics/cli.py | 6 ++++-- analytics/tests/integrations/test_slack.py | 7 ++++--- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/analytics/config.py b/analytics/config.py index 7e5ab024c..a52d5d25c 100644 --- a/analytics/config.py +++ b/analytics/config.py @@ -2,6 +2,7 @@ """ import os +from typing import Optional from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic import Field @@ -15,5 +16,5 @@ class DBSettings(PydanticBaseEnvConfig): user: str = Field (alias="DB_USER") password: str = Field(alias="DB_PASSWORD") ssl_mode: str = Field(alias="DB_SSL_MODE") - slack_bot_token: str = Field(alias="SLACK_BOT_TOKEN") - reporting_channel_id: str = Field(alias="REPORTING_CHANNEL_ID") \ No newline at end of file + slack_bot_token: str = Field(alias="ANALYTICS_SLACK_BOT_TOKEN") + reporting_channel_id: str = Field(alias="ANALYTICS_REPORTING_CHANNEL_ID") \ No newline at end of file diff --git a/analytics/local.env b/analytics/local.env index ed6697f5c..f8e658c37 100644 --- a/analytics/local.env +++ b/analytics/local.env @@ -28,3 +28,13 @@ MB_DB_PORT=5432 MB_DB_USER=app MB_DB_PASS=secret123 MB_DB_HOST=grants-analytics-db + +########################### +# Slack Configuration # +########################### +# Do not add these values to this file +# to avoid mistakenly committing them. +# Set these in your shell +# by doing `export ANALYTICS_REPORTING_CHANNEL_ID=whatever` +ANALYTICS_REPORTING_CHANNEL_ID=DO_NOT_SET_HERE +ANALYTICS_SLACK_BOT_TOKEN=DO_NOT_SET_HERE \ No newline at end of file diff --git a/analytics/src/analytics/cli.py b/analytics/src/analytics/cli.py index 238413ef4..841cdd5a6 100644 --- a/analytics/src/analytics/cli.py +++ b/analytics/src/analytics/cli.py @@ -243,15 +243,17 @@ def show_and_or_post_results( # this prevents an error if ANALYTICS_SLACK_BOT_TOKEN env var is unset from config import DBSettings + settings = DBSettings() + # optionally display the burndown chart in the browser if show_results: metric.show_chart() print("Slack message:\n") print(metric.format_slack_message()) if post_results: - slackbot = slack.SlackBot(client=WebClient(token=DBSettings.slack_bot_token)) + slackbot = slack.SlackBot(client=WebClient(token=settings.slack_bot_token)) metric.post_results_to_slack( slackbot=slackbot, - channel_id=DBSettings.reporting_channel_id, + channel_id=settings.reporting_channel_id, output_dir=Path(output_dir), ) diff --git a/analytics/tests/integrations/test_slack.py b/analytics/tests/integrations/test_slack.py index a065f4093..56dbb2e99 100644 --- a/analytics/tests/integrations/test_slack.py +++ b/analytics/tests/integrations/test_slack.py @@ -7,7 +7,8 @@ from analytics.integrations.slack import FileMapping, SlackBot from config import DBSettings -client = WebClient(token=DBSettings.slack_bot_token) +settings = DBSettings() +client = WebClient(token=settings.slack_bot_token) @pytest.fixture(name="slackbot") @@ -20,7 +21,7 @@ def mock_slackbot() -> SlackBot: def test_fetch_slack_channels(slackbot: SlackBot): """The fetch_slack_channels() function should execute correctly.""" result = slackbot.fetch_slack_channel_info( - channel_id=DBSettings.reporting_channel_id, + channel_id=settings.reporting_channel_id, ) assert result["ok"] is True assert result["channel"]["name"] == "z_bot-analytics-ci-test" @@ -49,7 +50,7 @@ def test_upload_files_to_slack_channel(slackbot: SlackBot): """ result = slackbot.upload_files_to_slack_channel( files=files, - channel_id=DBSettings.reporting_channel_id, + channel_id=settings.reporting_channel_id, message=markdown, ) assert result["ok"] is True From 868b50e5b63e708a46cf33e3fc1626dece02ff1e Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Wed, 10 Jul 2024 11:11:08 -0400 Subject: [PATCH 8/9] update config call --- analytics/config.py | 5 ++++- analytics/src/analytics/cli.py | 4 ++-- analytics/tests/integrations/test_slack.py | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/analytics/config.py b/analytics/config.py index a52d5d25c..7bc91adc3 100644 --- a/analytics/config.py +++ b/analytics/config.py @@ -17,4 +17,7 @@ class DBSettings(PydanticBaseEnvConfig): password: str = Field(alias="DB_PASSWORD") ssl_mode: str = Field(alias="DB_SSL_MODE") slack_bot_token: str = Field(alias="ANALYTICS_SLACK_BOT_TOKEN") - reporting_channel_id: str = Field(alias="ANALYTICS_REPORTING_CHANNEL_ID") \ No newline at end of file + reporting_channel_id: str = Field(alias="ANALYTICS_REPORTING_CHANNEL_ID") + +def get_db_settings() -> DBSettings: + return DBSettings() \ No newline at end of file diff --git a/analytics/src/analytics/cli.py b/analytics/src/analytics/cli.py index 841cdd5a6..68d49d48e 100644 --- a/analytics/src/analytics/cli.py +++ b/analytics/src/analytics/cli.py @@ -241,9 +241,9 @@ def show_and_or_post_results( """Optionally show the results of a metric and/or post them to slack.""" # defer load of settings until this command is called # this prevents an error if ANALYTICS_SLACK_BOT_TOKEN env var is unset - from config import DBSettings + from config import get_db_settings - settings = DBSettings() + settings = get_db_settings() # optionally display the burndown chart in the browser if show_results: diff --git a/analytics/tests/integrations/test_slack.py b/analytics/tests/integrations/test_slack.py index 56dbb2e99..32ec6b6bc 100644 --- a/analytics/tests/integrations/test_slack.py +++ b/analytics/tests/integrations/test_slack.py @@ -5,9 +5,9 @@ from slack_sdk import WebClient from analytics.integrations.slack import FileMapping, SlackBot -from config import DBSettings +from config import get_db_settings -settings = DBSettings() +settings = get_db_settings() client = WebClient(token=settings.slack_bot_token) From 6bec7c23e64ba4e5806fa9dd612b32d87dc5b8de Mon Sep 17 00:00:00 2001 From: Alsia Plybeah Date: Tue, 23 Jul 2024 13:45:43 -0400 Subject: [PATCH 9/9] update call --- analytics/src/analytics/integrations/db.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analytics/src/analytics/integrations/db.py b/analytics/src/analytics/integrations/db.py index 8b6edf18d..89bdeaa09 100644 --- a/analytics/src/analytics/integrations/db.py +++ b/analytics/src/analytics/integrations/db.py @@ -3,7 +3,7 @@ from sqlalchemy import Engine, create_engine -from config import DBSettings +from config import get_db_settings # The variables used in the connection url are pulled from local.env # and configured in the DBSettings class found in config.py @@ -21,7 +21,7 @@ def get_db() -> Engine: sqlalchemy.engine.Engine A SQLAlchemy engine object representing the connection to the database. """ - db = DBSettings + db = get_db_settings() print(f"postgresql+psycopg://{db.user}:{db.password}@{db.db_host}:{db.port}") return create_engine( f"postgresql+psycopg://{db.user}:{db.password}@{db.db_host}:{db.port}",