-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a7e17b5
commit c625a54
Showing
11 changed files
with
222 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,87 @@ | ||
"""Module for managing configuration settings for the Datacosmos SDK. | ||
"""Configuration module for the Datacosmos SDK. | ||
Supports loading from YAML files and environment variables. | ||
Handles configuration management using Pydantic and Pydantic Settings. | ||
It loads default values, allows overrides via YAML configuration files, | ||
and supports environment variable-based overrides. | ||
""" | ||
|
||
import os | ||
from dataclasses import dataclass | ||
from typing import Literal | ||
|
||
import yaml | ||
from pydantic import model_validator | ||
from pydantic_settings import BaseSettings, SettingsConfigDict | ||
|
||
from config.models.m2m_authentication_config import M2MAuthenticationConfig | ||
from config.models.url import URL | ||
|
||
@dataclass | ||
class Config: | ||
"""Configuration for the Datacosmos SDK. | ||
|
||
Contains authentication details such as client ID, secret, token | ||
URL, and audience. | ||
""" | ||
class Config(BaseSettings): | ||
"""Centralized configuration for the Datacosmos SDK.""" | ||
|
||
client_id: str | ||
client_secret: str | ||
token_url: str | ||
audience: str | ||
model_config = SettingsConfigDict( | ||
env_nested_delimiter="__", | ||
nested_model_default_partial_update=True, | ||
) | ||
|
||
@staticmethod | ||
def from_yaml(file_path: str = "config/config.yaml") -> "Config": | ||
"""Load configuration from a YAML file. | ||
# General configurations | ||
environment: Literal["local", "test", "prod"] = "test" | ||
log_format: Literal["json", "text"] = "text" | ||
log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR"] = "INFO" | ||
|
||
Defaults to 'config/config.yaml' unless otherwise specified. | ||
# Authentication configuration | ||
authentication: M2MAuthenticationConfig = M2MAuthenticationConfig( | ||
type="m2m", | ||
client_id="zCeZWJamwnb8ZIQEK35rhx0hSAjsZI4D", | ||
token_url="https://login.open-cosmos.com/oauth/token", | ||
audience="https://test.beeapp.open-cosmos.com", | ||
client_secret="tAeaSgLds7g535ofGq79Zm2DSbWMCOsuRyY5lbyObJe9eAeSN_fxoy-5kaXnVSYa", | ||
) | ||
|
||
# STAC API configuration | ||
stac: URL = URL( | ||
protocol="https", | ||
host="test.app.open-cosmos.com", | ||
port=443, | ||
path="/api/data/v0/stac", | ||
) | ||
|
||
@classmethod | ||
def from_yaml(cls, file_path: str = "config/config.yaml") -> "Config": | ||
"""Load configuration from a YAML file and override defaults. | ||
Args: | ||
file_path (str): The path to the YAML configuration file. | ||
Returns: | ||
Config: An instance of the Config class with loaded settings. | ||
""" | ||
with open(file_path, "r") as f: | ||
data = yaml.safe_load(f) | ||
auth = data.get("auth", {}) | ||
return Config( | ||
client_id=auth["client-id"], | ||
client_secret=auth["client-secret"], | ||
token_url=auth["token-url"], | ||
audience=auth["audience"], | ||
) | ||
|
||
@staticmethod | ||
def from_env() -> "Config": | ||
"""Load configuration from environment variables. | ||
Raises an exception if any required variable is missing. | ||
config_data = {} | ||
if os.path.exists(file_path): | ||
with open(file_path, "r") as f: | ||
yaml_data = yaml.safe_load(f) or {} | ||
# Remove empty values from YAML to avoid overwriting with `None` | ||
config_data = { | ||
k: v for k, v in yaml_data.items() if v not in [None, ""] | ||
} | ||
return cls(**config_data) | ||
|
||
@model_validator(mode="before") | ||
@classmethod | ||
def merge_with_env(cls, values): | ||
"""Override settings with environment variables if set. | ||
This method checks if any environment variables corresponding to the | ||
config fields are set and updates their values accordingly. | ||
Args: | ||
values (dict): The configuration values before validation. | ||
Returns: | ||
dict: The updated configuration values with environment variable overrides. | ||
""" | ||
return Config( | ||
client_id=os.getenv("OC_AUTH_CLIENT_ID"), | ||
client_secret=os.getenv("OC_AUTH_CLIENT_SECRET"), | ||
token_url=os.getenv("OC_AUTH_TOKEN_URL"), | ||
audience=os.getenv("OC_AUTH_AUDIENCE"), | ||
) | ||
for field in cls.model_fields: | ||
env_value = os.getenv(f"OC_{field.upper()}") | ||
if env_value: | ||
values[field] = env_value | ||
return values |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
"""Module for configuring machine-to-machine (M2M) authentication. | ||
Used when running scripts in the cluster that require automated authentication | ||
without user interaction. | ||
""" | ||
|
||
from typing import Literal | ||
|
||
from pydantic import BaseModel | ||
|
||
|
||
class M2MAuthenticationConfig(BaseModel): | ||
"""Configuration for machine-to-machine authentication. | ||
This is used when running scripts in the cluster that require authentication | ||
with client credentials. | ||
""" | ||
|
||
type: Literal["m2m"] | ||
client_id: str | ||
token_url: str | ||
audience: str | ||
# Some infrastructure deployments do not require a client secret. | ||
client_secret: str = "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
"""Module defining a structured URL configuration model. | ||
Ensures that URLs contain required components such as protocol, host, | ||
port, and path. | ||
""" | ||
|
||
from common.domain.url import URL as DomainURL | ||
from pydantic import BaseModel | ||
|
||
|
||
class URL(BaseModel): | ||
"""Generic configuration model for a URL. | ||
This class provides attributes to store URL components and a method | ||
to convert them into a `DomainURL` instance. | ||
""" | ||
|
||
protocol: str | ||
host: str | ||
port: int | ||
path: str | ||
|
||
def as_domain_url(self) -> DomainURL: | ||
"""Convert the URL instance to a `DomainURL` object. | ||
Returns: | ||
DomainURL: A domain-specific URL object. | ||
""" | ||
return DomainURL( | ||
protocol=self.protocol, | ||
host=self.host, | ||
port=self.port, | ||
base=self.path, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.