Skip to main content

Secure and extensible credential management SDK for Python applications.

Project description

infra-core-sdk

PyPI version Python License

infra-core-sdk is a small infrastructure SDK for Python projects that need:

  • predictable project root resolution
  • centralized path configuration
  • encrypted credential setup and loading
  • typed, reusable runtime filesystem operations

Current published version: 0.2.1.post1


Why this SDK exists

Most internal Python projects eventually reinvent the same infrastructure code:

  • hardcoded paths scattered across modules
  • inconsistent root discovery between local runs, scripts, CI, and installed packages
  • ad-hoc secret files and manual key handling
  • duplicated filesystem setup logic

infra-core-sdk turns those concerns into explicit, reusable building blocks.

Instead of solving paths and credentials separately in every project, you define them once and consume them through a consistent API.


What the SDK gives you

Root-aware path resolution

Resolve paths relative to the real project root instead of relying on fragile cwd assumptions.

The SDK supports:

  • marker-based root discovery
  • explicit start_path configuration
  • installed-package fallback for consumer scripts

Centralized path management

Define your important paths once and resolve or create them anywhere in your codebase.

Typical examples:

  • secrets directory
  • key file
  • credentials files
  • logs
  • cache directories
  • external absolute paths

Secure credentials flow

Store credentials as typed objects, encrypt them with Fernet, and load them back through a predictable setup/load flow.

Better reuse across projects

This SDK is designed to be installed and consumed by other Python projects, not just used from inside this repository.


Installation

Latest published version:

pip install infra-core-sdk==0.2.1.post1

Or install the latest available release:

pip install infra-core-sdk

Quick Example

This is the simplest end-to-end flow:

from dataclasses import dataclass

from infra_core import (
    CredentialsLoader,
    CredentialsSetupService,
    FernetEncryption,
    PathConfig,
    RootConfig,
    RootConfigProvider,
)
from infra_core.core.path.path_config_provider import PathConfigProvider
from infra_core.core.path.path_definition import PathDefinition
from infra_core.credentials.models.base_credentials import BaseCredentials


@dataclass(frozen=True)
class MyCredentials(BaseCredentials):
    api_token: str


RootConfigProvider.set(
    RootConfig(
        markers=(".git", "pyproject.toml"),
    )
)

path_config = PathConfig()
path_config = path_config.addPath("secrets", PathDefinition("secrets"))
path_config = path_config.addPath("secret_key", PathDefinition("secrets/key.key"))
path_config = path_config.addPath(
    "credentials",
    PathDefinition("secrets/{name}.json"),
)

PathConfigProvider.set(path_config)

setup = CredentialsSetupService(FernetEncryption)
setup.setup(MyCredentials(api_token="123"), name="default")

creds = CredentialsLoader.load(
    MyCredentials,
    FernetEncryption,
    name="default",
)

print(creds.api_token)

Generated structure:

project_root/
├── secrets/
│   ├── key.key
│   └── default.json

If you want a runnable example from this repository, see:


Core Concepts

1. Root resolution

The SDK resolves the consumer project's root using markers such as:

.git
pyproject.toml
requirements.txt

You can also provide an explicit start_path:

from pathlib import Path

from infra_core import RootConfig, RootConfigProvider

RootConfigProvider.set(
    RootConfig(
        markers=(".git", "pyproject.toml"),
        start_path=Path(__file__).resolve().parent,
    )
)

This is especially useful when your application may run from a different cwd.

2. Path definitions

Each path is registered as a PathDefinition:

PathDefinition(path: str, use_root: bool = True)

Behavior:

Mode Meaning
use_root=True path is relative to the resolved project root
use_root=False path must be absolute

Template variables are supported:

PathDefinition("secrets/{name}.json")

3. Credentials lifecycle

The default flow is:

SETUP
  -> ensure key exists
  -> encrypt typed credentials
  -> save encrypted file

LOAD
  -> try environment variables first
  -> fallback to encrypted file
  -> return typed credentials object

Step-by-Step Usage

1. Define a credentials model

from dataclasses import dataclass

from infra_core.credentials.models.base_credentials import BaseCredentials


@dataclass(frozen=True)
class MyCredentials(BaseCredentials):
    api_token: str
    client_id: str

2. Configure root behavior

from infra_core import RootConfig, RootConfigProvider

RootConfigProvider.set(
    RootConfig(
        markers=(".git", "pyproject.toml"),
    )
)

3. Configure paths

from pathlib import Path

from infra_core import PathConfig
from infra_core.core.path.path_config_provider import PathConfigProvider
from infra_core.core.path.path_definition import PathDefinition

config = PathConfig()

config = config.addPath("secrets", PathDefinition("secrets"))
config = config.addPath("secret_key", PathDefinition("secrets/key.key"))
config = config.addPath("credentials", PathDefinition("secrets/{name}.json"))

absolute_logs = str(Path.cwd() / "logs" / "app")
config = config.addPath(
    "logs",
    PathDefinition(absolute_logs, use_root=False),
)

PathConfigProvider.set(config)

4. Setup encrypted credentials

from infra_core import CredentialsSetupService, FernetEncryption

setup = CredentialsSetupService(FernetEncryption)

setup.setup(
    MyCredentials(
        api_token="123",
        client_id="abc",
    ),
    name="default",
)

5. Load credentials

from infra_core import CredentialsLoader, FernetEncryption

creds = CredentialsLoader.load(
    MyCredentials,
    FernetEncryption,
    name="default",
)

print(creds.api_token)
print(creds.client_id)

Public API Highlights

Top-level imports currently supported:

from infra_core import (
    CredentialsLoader,
    CredentialsService,
    CredentialsSetupService,
    FernetEncryption,
    PathConfig,
    PathManager,
    RootConfig,
    RootConfigProvider,
    RootResolver,
)

Useful subpackage imports:

from infra_core.core.root import RootConfig, RootConfigProvider, RootResolver
from infra_core.exceptions import SDKError
from infra_core.credentials.exceptions import CredentialsError

Path Management

Resolve paths:

from infra_core import PathManager

manager = PathManager()

print(manager.getPath("secrets"))
print(manager.getPath("credentials", name="default"))

Ensure resources exist:

manager.ensurePathExists("secrets")
manager.ensurePathExists(
    "credentials",
    variables={"name": "default"},
    is_file=True,
)

Delete files or directories:

manager.deleteResource("credentials", name="default")
manager.deleteResource("secrets")

Multiple Credential Profiles

The same key can be reused for multiple profiles:

setup.setup(..., name="aws")
setup.setup(..., name="stripe")
setup.setup(..., name="internal")

Then load the profile you need:

aws = CredentialsLoader.load(MyCredentials, FernetEncryption, name="aws")

Custom Encryption

Fernet is the default recommendation:

from infra_core import FernetEncryption

You can also inject a custom encryption class:

class CustomEncryption:
    def __init__(self, key: bytes) -> None:
        self._key = key

    def encrypt(self, value: str) -> str:
        return value

    def decrypt(self, value: str) -> str:
        return value

Use it the same way:

setup = CredentialsSetupService(CustomEncryption)
creds = CredentialsLoader.load(MyCredentials, CustomEncryption, name="default")

Important Rules

Do not manually manage keys in your application flow.

Use:

CredentialsSetupService(...)

Do not use relative paths with use_root=False.

Invalid:

PathDefinition("logs", use_root=False)

Valid:

from pathlib import Path

PathDefinition(str(Path.cwd() / "logs"), use_root=False)

Development

pip install -e .[dev]
python -m pytest
python -m mypy src
python -m black .
python -m build
python -m twine check dist/*

Architecture Overview

infra_core/
  core/
    path/
    root/
  credentials/
    models/
    services/
    setup/
  exceptions/
  security/

Responsibility split:

  • core.root: project root discovery
  • core.path: path definitions, configuration, and runtime operations
  • credentials.models: typed credential objects
  • credentials.services: save/load flows
  • credentials.setup: initial setup and key lifecycle
  • security: encryption implementations

License

MIT


Author

Rafael Cavalcante

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

infra_core_sdk-0.2.1.post1.tar.gz (30.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

infra_core_sdk-0.2.1.post1-py3-none-any.whl (36.9 kB view details)

Uploaded Python 3

File details

Details for the file infra_core_sdk-0.2.1.post1.tar.gz.

File metadata

  • Download URL: infra_core_sdk-0.2.1.post1.tar.gz
  • Upload date:
  • Size: 30.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for infra_core_sdk-0.2.1.post1.tar.gz
Algorithm Hash digest
SHA256 06270612558f633d36ad901489423c76d5cb8e6727f5405f1308ddf432535577
MD5 458f202c3327b6afb7018b2376115966
BLAKE2b-256 2f4660d20a148ce3062e5dfdb34ca7d226492c1e749a53cefe65c04eb36347f2

See more details on using hashes here.

File details

Details for the file infra_core_sdk-0.2.1.post1-py3-none-any.whl.

File metadata

File hashes

Hashes for infra_core_sdk-0.2.1.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 46044174921d6fdfdb2434bb494498d4eb2e042fac0c864590e1c811f8057bfb
MD5 f66878739414be7ebb3c41e8759db3f9
BLAKE2b-256 3768305b71a362a4ecc414c5b3833a996fe86636be6dba9b1735ebe2e5816313

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page