Skip to content

Commit

Permalink
Make some changes regarding code formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
TiagoOpenCosmos committed Jan 22, 2025
1 parent 21d0ee3 commit 1efe6ed
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,6 @@ dmypy.json

# Cython debug symbols
cython_debug/

# Ignore config.yaml
config/config.yaml
9 changes: 9 additions & 0 deletions config/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Configuration package for the Datacosmos SDK.
This package includes modules for loading and managing authentication configurations.

Check failure on line 3 in config/__init__.py

View workflow job for this annotation

GitHub Actions / Flake8

config/__init__.py#L3

Line too long (85 > 79 characters) (E501)
"""

# Expose Config class for easier imports
from .config import Config

__all__ = ["Config"]
25 changes: 17 additions & 8 deletions config/config.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
from __future__ import annotations
"""Module for managing configuration settings for the Datacosmos SDK.
Supports loading from YAML files and environment variables.
"""

import os
import yaml
from dataclasses import dataclass

import yaml


@dataclass
class Config:
"""Configuration for the Datacosmos SDK.
Contains authentication details such as client ID, secret, token URL, and audience.

Check failure on line 16 in config/config.py

View workflow job for this annotation

GitHub Actions / Flake8

config/config.py#L16

Line too long (87 > 79 characters) (E501)
"""

client_id: str
client_secret: str
token_url: str
audience: str

@staticmethod
def from_yaml(file_path: str = "config/config.yaml") -> Config:
"""
Load configuration from a YAML file.
def from_yaml(file_path: str = "config/config.yaml") -> "Config":
"""Load configuration from a YAML file.
Defaults to 'config/config.yaml' unless otherwise specified.
"""
with open(file_path, "r") as f:
Expand All @@ -29,9 +38,9 @@ def from_yaml(file_path: str = "config/config.yaml") -> Config:
)

@staticmethod
def from_env() -> Config:
"""
Load configuration from environment variables.
def from_env() -> "Config":
"""Load configuration from environment variables.
Raises an exception if any required variable is missing.
"""
return Config(
Expand Down
40 changes: 27 additions & 13 deletions datacosmos/client.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
import os
"""Datacosmos client for interacting with the Datacosmos API.
Provides an authenticated HTTP client and convenience methods for HTTP requests.

Check failure on line 3 in datacosmos/client.py

View workflow job for this annotation

GitHub Actions / Flake8

datacosmos/client.py#L3

Line too long (80 > 79 characters) (E501)
"""

import os
from datetime import datetime, timedelta, timezone
from typing import Optional, Any
from typing import Any, Optional

import requests
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session

from config.config import Config


class DatacosmosClient:
"""DatacosmosClient handles authenticated interactions with the Datacosmos API.

Check failure on line 18 in datacosmos/client.py

View workflow job for this annotation

GitHub Actions / Flake8

datacosmos/client.py#L18

Line too long (83 > 79 characters) (E501)
Automatically manages token refreshing and provides HTTP convenience methods.

Check failure on line 20 in datacosmos/client.py

View workflow job for this annotation

GitHub Actions / Flake8

datacosmos/client.py#L20

Line too long (81 > 79 characters) (E501)
"""

def __init__(
self, config: Optional[Config] = None, config_file: str = "config/config.yaml"

Check failure on line 24 in datacosmos/client.py

View workflow job for this annotation

GitHub Actions / Flake8

datacosmos/client.py#L24

Line too long (86 > 79 characters) (E501)
):
"""Initialize the DatacosmosClient.
If no configuration is provided, it will load from the specified YAML file

Check failure on line 28 in datacosmos/client.py

View workflow job for this annotation

GitHub Actions / Flake8

datacosmos/client.py#L28

Line too long (82 > 79 characters) (E501)
or fall back to environment variables.
"""
self.config = config or self._load_config(config_file)
self.token = None
self.token_expiry = None
self._http_client = self._authenticate_and_initialize_client()

def _load_config(self, config_file: str) -> Config:
"""Load configuration from the YAML file. Fall back to environment variables if the file is missing."""

Check failure on line 37 in datacosmos/client.py

View workflow job for this annotation

GitHub Actions / Flake8

datacosmos/client.py#L37

Line too long (111 > 79 characters) (E501)
if os.path.exists(config_file):
return Config.from_yaml(config_file)
return Config.from_env()

def _authenticate_and_initialize_client(self) -> requests.Session:
"""Authenticate and initialize the HTTP client with a valid token."""
client = BackendApplicationClient(client_id=self.config.client_id)
oauth_session = OAuth2Session(client=client)

Expand All @@ -47,37 +64,34 @@ def _authenticate_and_initialize_client(self) -> requests.Session:
return http_client

def _refresh_token_if_needed(self):
"""
Refreshes the token if it has expired.
"""
"""Refresh the token if it has expired."""
if not self.token or self.token_expiry <= datetime.now(timezone.utc):
self._http_client = self._authenticate_and_initialize_client()

def get_http_client(self) -> requests.Session:
"""
Returns the authenticated HTTP client, refreshing the token if necessary.
"""
"""Return the authenticated HTTP client, refreshing the token if necessary."""

Check failure on line 72 in datacosmos/client.py

View workflow job for this annotation

GitHub Actions / Flake8

datacosmos/client.py#L72

Line too long (86 > 79 characters) (E501)
self._refresh_token_if_needed()
return self._http_client

# Proxy HTTP methods to the underlying authenticated session
def request(
self, method: str, url: str, *args: Any, **kwargs: Any
) -> requests.Response:
"""
Proxy method to send HTTP requests using the authenticated session.
"""
"""Send an HTTP request using the authenticated session."""
self._refresh_token_if_needed()
return self._http_client.request(method, url, *args, **kwargs)

def get(self, url: str, *args: Any, **kwargs: Any) -> requests.Response:
"""Send a GET request using the authenticated session."""
return self.request("GET", url, *args, **kwargs)

def post(self, url: str, *args: Any, **kwargs: Any) -> requests.Response:
"""Send a POST request using the authenticated session."""
return self.request("POST", url, *args, **kwargs)

def put(self, url: str, *args: Any, **kwargs: Any) -> requests.Response:
"""Send a PUT request using the authenticated session."""
return self.request("PUT", url, *args, **kwargs)

def delete(self, url: str, *args: Any, **kwargs: Any) -> requests.Response:
"""Send a DELETE request using the authenticated session."""
return self.request("DELETE", url, *args, **kwargs)
55 changes: 55 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ test = [
"isort==5.11.4",
"pydocstyle==6.1.1",
"flake8-cognitive-complexity==0.1.0",
"ruff==0.0.286"
]

[tool.setuptools.packages]
Expand All @@ -34,3 +35,57 @@ find = {}

[tool.pydocstyle]
convention = "google"

[tool.ruff]
fix = true
line-length = 88
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
]

[tool.ruff.lint]
extend-select = ["I", "SLF", "F", "C90", "BLE", "B", "ARG", "ERA"]
ignore = []
fixable = ["ALL"]
unfixable = []

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
docstring-code-format = false

[tool.ruff.lint.mccabe]
max-complexity = 10

[tool.black]
line-length = 88

[tool.isort]
profile = "black"
8 changes: 5 additions & 3 deletions tests/test_pass.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""An example test to check pytest setup."""
"""Test suite for basic functionality and CI setup."""


class TestPass:
"""A simple test class to validate the CI pipeline setup."""

def test_pass(self):
"""A passing test, to check the pytest CI setup."""
pass
"""A passing test to ensure the CI pipeline is functional."""
assert True

0 comments on commit 1efe6ed

Please sign in to comment.