Metadata-Version: 2.4
Name: britecore_sdk
Version: 2.0.4
Summary: Professional Python SDK for the BriteCore API — complete endpoint coverage, async support, OAuth/API key auth, and type hints.
Author: sshimek
License-Expression: Apache-2.0
Keywords: britecore,api,sdk,insurance,async,oauth2,rest-api
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: dynaconf<3.4.0,>=3.2.13
Requires-Dist: typing-extensions<5.0.0,>=4.15.0
Requires-Dist: urllib3<3.0.0,>=2.7.0
Requires-Dist: toml<0.11.0,>=0.10.2
Provides-Extra: interactive
Requires-Dist: questionary~=2.1.1; extra == "interactive"
Provides-Extra: all
Requires-Dist: britecore_sdk[interactive]; extra == "all"
Provides-Extra: dev
Requires-Dist: setuptools>=83.0.0; extra == "dev"
Requires-Dist: pytest>=9.0.3; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
Requires-Dist: pytest-mock>=3.15.1; extra == "dev"
Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
Requires-Dist: pytest-randomly>=4.0.1; extra == "dev"
Requires-Dist: hypothesis>=6.112.0; extra == "dev"
Requires-Dist: python-dotenv>=1.2.2; extra == "dev"
Requires-Dist: black>=26.3.1; extra == "dev"
Requires-Dist: ruff>=0.15.11; extra == "dev"
Requires-Dist: mypy>=1.20.0; extra == "dev"
Requires-Dist: pre-commit>=4.5.1; extra == "dev"
Requires-Dist: pymarkdownlnt>=0.9.36; extra == "dev"
Requires-Dist: pip-audit>=2.10.0; extra == "dev"
Requires-Dist: britecore_sdk[all]; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx<9.1,>=9.0.4; extra == "docs"
Requires-Dist: myst-parser>=5.0.0; extra == "docs"
Requires-Dist: sphinx-rtd-theme>=3.0.2; extra == "docs"
Dynamic: license-file

# britecore_sdk

*Last updated: July 21, 2026*
*Document type: Living guide*

A professional **Python SDK for the BriteCore API** — complete endpoint coverage, async support, OAuth/API key authentication, and type hints.

> No existing BriteCore client library? Look no further. This SDK provides spec-aligned wrappers, domain models, validators, and clean async helpers.

[![Python Version](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](https://opensource.org/licenses/Apache-2.0)
[![codecov](https://codecov.io/gh/sshimek42/britecore_sdk/graph/badge.svg)](https://codecov.io/gh/sshimek42/britecore_sdk)

**Status:** Stable (v2.0.4+) | **License:** Apache-2.0 | **Python:** 3.11+

---

## Quick Start

### 1. Install

```bash
pip install britecore_sdk
```

### 2. Configure

Set `target_site` and credentials via config files or environment variables. The SDK discovers
config files automatically from several locations. For the canonical precedence table, see
[`docs/CONFIGURATION.md`](./docs/CONFIGURATION.md#canonical-precedence-table).

**Recommended for most users: user-level config (`~/.britecore/`)**

Works across all your projects without touching the SDK package files:

`~/.britecore/settings.toml`:

```toml
[default]
target_site = "production"
```

`~/.britecore/.secrets.toml`:

```toml
[production]
base_url = "https://your-britecore-instance.com"
api_key = "your_api_key_here"
```

**Alternative: project-local config (current working directory)**

Place `britecore.toml` and `.britecore_secrets.toml` in your project root. Add
`.britecore_secrets.toml` to `.gitignore` to keep secrets out of version control:

```toml
# britecore.toml (safe to commit)
[default]
target_site = "production"
```

```toml
# .britecore_secrets.toml (add to .gitignore!)
[production]
base_url = "https://your-britecore-instance.com"
api_key = "your_api_key_here"
```

#### Alternative: Environment variables

> **Note:** `target_site` is required in standard file/env initialization.
> In explicit mode (`init_api_client(base_url=..., ...)`), `target_site` is optional and defaults
> to `"explicit"`. If all required credentials are set via `BRITECORE_SDK_*` environment
> variables, those values always win; `target_site` only matters if the client needs to fall back
> to TOML sections.

**Linux/macOS (bash):**

```bash
export BRITECORE_SDK_BASE_URL="https://your-britecore-instance.com"
export BRITECORE_SDK_API_KEY="your_api_key_here"
export target_site="production"  # selects .secrets.toml section; any name works when all creds are set via env vars
```

**Windows (PowerShell):**

```powershell
$env:BRITECORE_SDK_BASE_URL="https://your-britecore-instance.com"
$env:BRITECORE_SDK_API_KEY="your_api_key_here"
$env:target_site="production"  # selects .secrets.toml section; any name works when all creds are set via env vars
```

Or for OAuth:

**Linux/macOS (bash):**

```bash
export BRITECORE_SDK_BASE_URL="https://your-britecore-instance.com"
export BRITECORE_SDK_CLIENT_ID="your_client_id"
export BRITECORE_SDK_CLIENT_SECRET="your_client_secret"
export target_site="production"  # selects .secrets.toml section; any name works when all creds are set via env vars
```

**Windows (PowerShell):**

```powershell
$env:BRITECORE_SDK_BASE_URL="https://your-britecore-instance.com"
$env:BRITECORE_SDK_CLIENT_ID="your_client_id"
$env:BRITECORE_SDK_CLIENT_SECRET="your_client_secret"
$env:target_site="production"  # selects .secrets.toml section; any name works when all creds are set via env vars
```

### 3. Use

```python
from britecore_sdk.api.api_calls import get_api_client
from britecore_sdk.api.api_calls.v2 import policies

# Recommended: Use the lazy-initialized client (auto-loads config on first use)
client = get_api_client()

# Retrieve a policy
result = policies.retrieve_policy(policy_number="POL001")
print(result)
```

See [examples/basic_api_usage.py](examples/basic_api_usage.py) for more detailed examples.

---

### About API Client Initialization

The `api_client` proxy (from `api.api_calls`) initializes lazily on first use, avoiding import-time failures if config is missing. Use `get_api_client()` for explicit control over the shared lazy client. Use `init_api_client()` for advanced/manual initialization scenarios (for example explicit credentials or multi-site binding).

If you need to verify selected auth mode during initialization, enable SDK debug logging before client init. The client emits `Auth mode selected during init_client: api_key` or `Auth mode selected during init_client: oauth` at debug level.

Pattern A (app-owned logging, preferred for host apps):

```python
import logging

logging.basicConfig(level=logging.INFO)
logging.getLogger("britecore_sdk").setLevel(logging.DEBUG)
```

Pattern B (SDK-managed handler, opt-in):

```python
import logging
from britecore_sdk import configure_logging

configure_logging(level="INFO")
logging.getLogger("britecore_sdk").setLevel(logging.DEBUG)
```

You can also log directly through the package logger:

```python
from britecore_sdk import logger

logger.info("SDK logger is configured")
```

---

## Features

- ✅ **Spec-aligned API coverage** — wrapper/spec alignment checks against `api_specs/current/britecore.json`
- ✅ **Async-ready** — Cache-aware async wrappers for high-concurrency workflows
- ✅ **Flexible auth** — Automatic API key or OAuth2 token management
- ✅ **Type hints** — Full PEP 561 type information for IDE support
- ✅ **Validators** — Email, phone, address, and name validation utilities
- ✅ **Models** — Domain classes for Contact, Policy, and Quote payloads
- ✅ **Config-first** — Dynaconf-based environment and secrets management
- ✅ **Production-ready** — Stable API, comprehensive tests, security-focused
- ✅ **Context manager** — `with BritecoreAPIClient("site").init_client() as client:`
- ✅ **Flat exceptions** — `from britecore_sdk import NotFoundError, AuthenticationError`
- ✅ **CLI commands** — `britecore-healthcheck`, `britecore-check-config`, `britecore-run-checks`
- ✅ **Debug dry-run** — per-call `dry_run=True` or client default `init_api_client(client_dry_run=True)`
- ✅ **Rate limiting** — Optional token bucket with adaptive backoff on 429 responses
- ✅ **Batch operations** — workflow helpers for parallel quote/contact/policy/risk creation

---

## Documentation

| Topic | Link |
| --- | --- |
| **Setup & examples** | [GETTING_STARTED.md](./GETTING_STARTED.md) |
| **API reference** | [API.md](./API.md) |
| **Async & caching** | [docs/ASYNC_CACHING.md](./docs/ASYNC_CACHING.md) |
| **Rate limiting** | [docs/RATE_LIMITING.md](./docs/RATE_LIMITING.md) |
| **Batch operations** | [docs/BATCH_QUOTE_CREATION.md](./docs/BATCH_QUOTE_CREATION.md) |
| **Architecture** | [ARCHITECTURE.md](./ARCHITECTURE.md) |
| **Python compatibility** | [PYTHON_COMPATIBILITY.md](./PYTHON_COMPATIBILITY.md) |
| **Contributing** | [CONTRIBUTING.md](./CONTRIBUTING.md) |
| **Code of Conduct** | [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) |
| **Troubleshooting** | [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) |
| **Security policy** | [SECURITY.md](./SECURITY.md) |

## Installation & Configuration

### Requirements

- Python `>=3.11`

### Install

```bash
# Base install (API client + wrappers)
pip install britecore_sdk

# With optional extras
pip install britecore_sdk[all]         # All extras
pip install britecore_sdk[dev]         # Development (tests, linting, type checking)
```

### Configuration

The SDK loads settings from multiple locations in priority order — later sources override earlier ones.
`BRITECORE_SDK_*` environment variables always win over any file. See the canonical precedence
table in [`docs/CONFIGURATION.md`](./docs/CONFIGURATION.md#canonical-precedence-table).

#### Option A: User-level config (recommended for pip-installed users)

Create `~/.britecore/settings.toml` and `~/.britecore/.secrets.toml`. Settings here apply to all
projects on the machine without touching SDK package files:

**`~/.britecore/settings.toml`** (example):

```toml
[default]
target_site = "production"
```

**`~/.britecore/.secrets.toml`** (never commit):

##### API key authentication

```toml
[production]
base_url = "https://api.britecore.example.com"
api_key = "your_real_api_key"

[staging]
base_url = "https://api-staging.britecore.example.com"
api_key = "your_staging_api_key"
```

##### OAuth authentication

```toml
[production]
base_url = "https://api.britecore.example.com"
client_id = "your_real_client_id"
client_secret = "your_real_client_secret"

[staging]
base_url = "https://api-staging.britecore.example.com"
client_id = "your_staging_client_id"
client_secret = "your_staging_client_secret"
```

#### Option B: Project-local config

Place `britecore.toml` and `.britecore_secrets.toml` in your project's working directory.
Add `.britecore_secrets.toml` to `.gitignore` to keep secrets out of version control:

**`britecore.toml`** (safe to commit):

```toml
[default]
target_site = "production"
```

**`.britecore_secrets.toml`** (add to `.gitignore`!):

```toml
[production]
base_url = "https://api.britecore.example.com"
api_key = "your_real_api_key"
```

#### Option C: SDK package defaults (repo clones only)

If you have cloned the repo and are working directly from source, you can copy the sample files:

**Linux/macOS (bash):**

```bash
cp src/britecore_sdk/settings/sample/settings.toml src/britecore_sdk/settings/settings.toml
cp src/britecore_sdk/settings/sample/.secrets.toml src/britecore_sdk/settings/.secrets.toml
```

**Windows (PowerShell):**

```powershell
Copy-Item src\britecore_sdk\settings\sample\settings.toml src\britecore_sdk\settings\settings.toml
Copy-Item src\britecore_sdk\settings\sample\.secrets.toml src\britecore_sdk\settings\.secrets.toml
```

#### Option D: Environment variables (highest priority, overrides all files)

> **Note on `target_site` with env vars:** In standard init mode, `target_site` selects which section of `.secrets.toml`
> to use for credentials. When **all** required credentials are supplied via `BRITECORE_SDK_*`
> environment variables, the specific `target_site` value does not affect which credentials are
> loaded — env vars take precedence regardless. If any credential is missing from env vars, the
> client falls back to the `.secrets.toml` section matching `target_site`. Either way, `target_site`
> is required unless you use explicit mode (`init_api_client(base_url=..., ...)`).

API key authentication:

**Linux/macOS (bash):**

```bash
export BRITECORE_SDK_BASE_URL="https://api.britecore.example.com"
export BRITECORE_SDK_API_KEY="your_api_key"
export target_site="production"  # required; selects .secrets.toml section (any name works when all creds are in env vars)
```

**Windows (PowerShell):**

```powershell
$env:BRITECORE_SDK_BASE_URL="https://api.britecore.example.com"
$env:BRITECORE_SDK_API_KEY="your_api_key"
$env:target_site="production"  # required; selects .secrets.toml section (any name works when all creds are in env vars)
```

Or OAuth authentication:

**Linux/macOS (bash):**

```bash
export BRITECORE_SDK_BASE_URL="https://api.britecore.example.com"
export BRITECORE_SDK_CLIENT_ID="your_client_id"
export BRITECORE_SDK_CLIENT_SECRET="your_client_secret"
export target_site="production"  # required; selects .secrets.toml section (any name works when all creds are in env vars)
```

**Windows (PowerShell):**

```powershell
$env:BRITECORE_SDK_BASE_URL="https://api.britecore.example.com"
$env:BRITECORE_SDK_CLIENT_ID="your_client_id"
$env:BRITECORE_SDK_CLIENT_SECRET="your_client_secret"
$env:target_site="production"  # required; selects .secrets.toml section (any name works when all creds are in env vars)
```

See [GETTING_STARTED.md](./GETTING_STARTED.md) and [docs/CONFIGURATION.md](./docs/CONFIGURATION.md) for detailed setup.

Validate configured sites before first API calls:

```sh
# As an installed command (after pip install) — works in bash and PowerShell:
britecore-check-config

# Or via python -m:
python -m britecore_sdk.utils.check_site_configs
```

Check whether the checked-in local API spec is current and whether upstream has a newer version:

```sh
python -m britecore_sdk.utils.check_api_spec_sync
```

Run an end-user readiness check (config + auth + safe API ping):

```sh
# As an installed command:
britecore-healthcheck --site production

# Or via python -m:
python -m britecore_sdk.utils.healthcheck --site production
```

Validation rule: each site needs `base_url` and either a full OAuth pair
(`client_id` + `client_secret`) or an `api_key`.

---

## What This Package Provides

### API Wrappers

- **Endpoint modules:** broad v2 domain coverage plus v1 compatibility wrappers (see `API.md` for current module inventory)
- **Async wrappers:** Cache-aware async versions of key endpoint workflows

### Utilities

- **Models:** `BritecoreContact`, `BritecorePolicy`, `BritecoreQuote` with type hints
- **Validators:** Email, phone, address, and name validation
- **Auth:** Automatic OAuth2 or API key selection based on config
- **Config:** Dynaconf-based environment/secrets management
- **Logging:** Structured logging with standard Python logging module

### Optional Extras

- **Interactive:** Menu-driven CLI utilities (`questionary`)

---

## Using Async Wrappers

The `v2` package exports async-aware wrappers (e.g., `aget_quote`, `aget_contact`, `aretrieve_policy`) with built-in caching for read operations.

```python
import asyncio
from britecore_sdk.api.api_calls.v2 import async_policies

async def main():
    policy = await async_policies.aretrieve_policy(policy_number="POL001")
    print(policy)

asyncio.run(main())
```

See [docs/ASYNC_CACHING.md](./docs/ASYNC_CACHING.md) for cache configuration and invalidation.

---

## Development

### Install for Development

```bash
pip install -e ".[dev]"
```

### Run Tests

```bash
# All tests
pytest tests/ -v

# By category
pytest tests/unit -m unit -v
pytest tests/integration -m integration -v

# Core client changes
pytest tests/unit/test_api_client.py tests/unit/test_core_client_coverage.py -v
```

### Linting & Type Checking

```bash
ruff check src/
black --check src/
mypy src/britecore_sdk/api/britecore_api_client.py
```

### Release Publishing (GitHub Actions)

- TestPyPI dry-run workflow: `.github/workflows/publish-testpypi.yml` (**manual trigger only** via `workflow_dispatch`)
- Production PyPI workflow: `.github/workflows/publish.yml` (**automatic** after `.github/workflows/release.yml` completes successfully, and also **manually runnable** via `workflow_dispatch`)

Both workflows use OIDC trusted publishing and include build + publish + install smoke tests. Depending on your GitHub environment protection rules, the publish job may still pause for environment approval even when the workflow itself was triggered automatically.

1. Create GitHub environments: `testpypi` and `pypi`.
2. In TestPyPI, add a Trusted Publisher entry for:
   - Repository: `sshimek42/britecore_sdk`
   - Workflow: `.github/workflows/publish-testpypi.yml`
   - Environment: `testpypi`
3. In PyPI, add a Trusted Publisher entry for:
   - Repository: `sshimek42/britecore_sdk`
   - Workflow: `.github/workflows/publish.yml`
   - Environment: `pypi`
4. Run `Publish to TestPyPI` from the Actions tab before cutting a production release.
5. Push a version tag (for example `v2.0.3`) to trigger `.github/workflows/release.yml`, which builds artifacts and creates the GitHub Release automatically.
6. After `.github/workflows/release.yml` completes successfully, `.github/workflows/publish.yml` runs automatically and publishes to PyPI. You can also run `Publish to PyPI` manually from the Actions tab when needed.

### Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for:

- Workflow and branch conventions
- Endpoint wrapper patterns
- Code quality expectations
- Repository-specific guidance in [AGENTS.md](./AGENTS.md)

## Architecture

- **`BritecoreAPIClient`** — Core HTTP transport and response processing
- **Context manager** — `with client:` pattern closes the connection pool on exit
- **Fluent init** — `client = BritecoreAPIClient("site").init_client()` (one-liner)
- **Endpoint modules** — Build request JSON → call `do_request()` → return `process_result()`
- **Auth modes** — Automatic: API key (when `client_id`/`client_secret` blank) or OAuth2 (when both provided)
- **Config** — Dynaconf-based layered config: SDK defaults → `~/.britecore/` → `./britecore.toml` → `BRITECORE_SDK_SETTINGS_FILE` → env vars
- **Lazy initialization** — API client initializes on first use to avoid import-time failures (see "About API Client Initialization" above)
- **Flat exceptions** — Import `NotFoundError`, `AuthenticationError` etc. directly from `britecore_sdk`

See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed design.

---

## Support & Links

- **Issues & feedback:** [GitHub Issues](https://github.com/sshimek42/britecore_sdk/issues)
- **Security concerns:** See [SECURITY.md](SECURITY.md)
- **Roadmap & stability:** See [STABILITY.md](./STABILITY.md)
- **External API docs:** [api.britecore.com](https://api.britecore.com/) (supplemental reference)
