Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .coverage
Binary file not shown.
13 changes: 12 additions & 1 deletion gavaconnect/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
"""GavaConnect SDK for Python."""

from ._version import __version__
from .checkers import KRAPINChecker
from .config import SDKConfig
from .errors import APIError, RateLimitError, SDKError, TransportError

__all__ = ["KRAPINChecker"]
__all__ = [
"__version__",
"SDKConfig",
"SDKError",
"APIError",
"RateLimitError",
"TransportError",
"KRAPINChecker",
]
4 changes: 4 additions & 0 deletions gavaconnect/_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The SDK version
# x-release-please-start-version
__version__: str = "0.2.1"
# x-release-please-end
2 changes: 2 additions & 0 deletions gavaconnect/checkers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Checkers module for various validation utilities."""

from ._pin import KRAPINChecker

__all__ = ["KRAPINChecker"]
2 changes: 1 addition & 1 deletion gavaconnect/checkers/_pin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class KRAPINChecker:
"""Checker for KRA PIN."""

def __init__(self, id_number: str):
def __init__(self, id_number: str) -> None:
self.id_number = id_number

def check_by_id_number(self) -> str:
Expand Down
24 changes: 24 additions & 0 deletions gavaconnect/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Configuration classes for the GavaConnect SDK."""

from dataclasses import dataclass, field


@dataclass(slots=True)
class RetryPolicy:
"""Configuration for retry behavior."""

max_attempts: int = 3
base_backoff_s: float = 0.2
retry_on_status: tuple[int, ...] = (429, 500, 502, 503, 504)


@dataclass(slots=True)
class SDKConfig:
"""Main configuration for the GavaConnect SDK."""

base_url: str
connect_timeout_s: float = 5.0
read_timeout_s: float = 30.0
total_timeout_s: float = 40.0
retry: RetryPolicy = field(default_factory=RetryPolicy)
user_agent: str = "gavaconnect-py/1.0.0"
42 changes: 42 additions & 0 deletions gavaconnect/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Error classes for the GavaConnect SDK."""

from __future__ import annotations


class SDKError(Exception):
"""Base exception for all SDK errors."""


class TransportError(SDKError):
"""Exception raised for network/transport related errors."""


class SerializationError(SDKError):
"""Exception raised for data serialization/deserialization errors."""


class APIError(SDKError):
"""Exception raised for API-related errors."""

def __init__(
self,
status: int,
type_: str,
message: str,
code: str | None,
request_id: str | None,
retry_after_s: float | None,
body: bytes | None,
) -> None:
"""Initialize APIError with response details."""
super().__init__(message)
self.status = status
self.type = type_
self.code = code
self.request_id = request_id
self.retry_after_s = retry_after_s
self.body = body


class RateLimitError(APIError):
"""Exception raised when API rate limits are exceeded."""
27 changes: 16 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ gavaconnect-sdk-python = "gavaconnect:main"
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.setuptools.package-data]

# Ruff configuration
[tool.ruff]
target-version = "py313"
Expand All @@ -56,24 +58,18 @@ exclude = [
]

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"S", # bandit (security)
]
select = ["E","F","I","UP","B","N","ANN","D"]

ignore = [
"E501", # line too long (handled by formatter)
"B008", # do not perform function calls in argument defaults
"S101", # use of assert detected (pytest uses assert)
"D203", # 1 blank line required before class docstring
"D213", # Multi-line docstring summary should start at the second line
]

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"] # Allow assert in tests
"tests/*" = ["S101", "ANN201", "D103", "D100"] # Allow assert in tests, missing return types and docstrings

# MyPy configuration
[tool.mypy]
Expand Down Expand Up @@ -121,3 +117,12 @@ exclude_lines = [

[tool.hatch.build.targets.wheel]
packages = ["gavaconnect"]
include = [
"gavaconnect/py.typed"
]

[dependency-groups]
dev = [
"pytest>=8.4.1",
"pytest-cov>=6.2.1",
]
Loading
Loading