AGENTS Guide
This docs page intentionally includes the canonical root file at ../AGENTS.md.
Edit the root file only so repository and docs guidance stay in sync.
AGENTS.md
Last updated: July 21, 2026 Document type: Development workflow guide
For developers working on the SDK: understand repository structure, coding patterns, and architectural decisions.
For a compact version, see AGENTS.quickstart.md.
Scope and source of truth
Treat
src/britecore_sdk/as the active codebase; ignore generated copies inbuild/,dist/,env/, and*.egg-info/unless packaging issues require them.Tests live under
tests/(not undersrc/), so run targeted pytest for changed modules and keep focused import/smoke checks for config-sensitive paths.
Repo layout contract
Authored source lives in
src/britecore_sdk/; authored tests live intests/; authored docs live in root*.mdfiles anddocs/.Generated outputs are non-source and should not be edited directly:
build/,dist/,env/,.venv/,*.egg-info/,htmlcov/, anddocs/_build/.Canonical compatibility/backlog docs are root files:
PYTHON_COMPATIBILITY.mdandUNIMPLEMENTED_API_STUBS.md; files underdocs/include them for documentation builds.
Big-picture architecture
API access centers on
BritecoreAPIClientinsrc/britecore_sdk/api/britecore_api_client.py; endpoint wrappers calldo_request(...)thenprocess_result(...).API module client access is lazy in
src/britecore_sdk/api/api_calls/__init__.py:api_clientis a proxy and initializes throughget_api_client()on first use.Auth mode is selected in
BritecoreAPIClient.init_client(): API key ifclient_id/client_secretare blank, otherwise OAuth viaOAuthToken(src/britecore_sdk/api/britecore_oauth_token_manager.py).Domain shaping is separate from transport: models in
src/britecore_sdk/models/and validators insrc/britecore_sdk/validators/prepare payloads, API modules send them.Legacy compatibility layer exists in
src/britecore_sdk/classes/__init__.pyand raisesImportErrordirecting consumers tomodels/validators; prefer imports frommodels/validators.
API module pattern (copy this when adding endpoints)
Follow
src/britecore_sdk/api/api_calls/v2/quotes.py: build request dict, callAPI_CLIENT.do_request(path=..., json=..., **kwargs), then returnAPI_CLIENT.process_result(...).Use
RequestParameters(TypedDictinbritecore_api_client.py) with**kwargs: Unpack[RequestParameters]for timeout/retry/header overrides.For mutually exclusive identifiers, reuse
API_CLIENT.multiple_parameter_verification(...)(example:retrieve_policyinv2/policies.py).Keep endpoints under
api/api_calls/v2for active SDK development; v1 wrappers remain supported (not legacy) where no v2 equivalent exists in the reference API.
Docstring source policy
For endpoint wrapper functions, use
api_specs/current/britecore.jsonas the primary source for summary, parameter intent, and response semantics.Treat files under
api_specs/legacy/as archival/reference input only; useapi_specs/current/britecore.jsonfor wrapper docs and tests.Add SDK-specific context only where needed (for example: snake_case aliases,
RequestParameters, orprocess_result(...)normalization behavior).If the spec and current wrapper behavior differ, prefer describing the documented API contract and call out SDK-specific differences explicitly and briefly.
Configuration and integration points
Runtime config uses a layered file hierarchy (lowest → highest priority):
SDK package defaults (
src/britecore_sdk/settings/settings.toml+.secrets.toml)User-level config (
~/.britecore/settings.toml+~/.britecore/.secrets.toml)Project-local config (
./britecore.toml+./.britecore_secrets.tomlin CWD)Explicit file path (
BRITECORE_SDK_SETTINGS_FILEenv var)BRITECORE_SDK_*environment variables (always highest priority)
_discover_settings_files()(inconfig.py) builds the Dynaconfsettings_fileslist at import time; callfrom britecore_sdk.settings import setting_files_fullto inspect what was resolved.init_api_client()andBritecoreAPIClient.init_client()accept explicitbase_url,api_key,client_id,client_secretkwargs to bypass file-based lookup entirely. Whenbase_urlis given,target_siteis optional (defaults to"explicit").Required site keys are validated (
base_url,client_id,client_secret,api_key) for configured environments.Important env vars used directly by code:
target_site(client init) andsystem(regex map selection inmaps/britecore_policy_name_map.py).External integrations:
urllib3(HTTP sync transport),httpx(optional native async transport —britecore_sdk[async-http]), OAuth2 token endpoint/api/auth/oauth2/token, CSV-backed zip lookup inutils/zip_code_lookup.py.TOML I/O uses stdlib
tomllibfor parsing andtomli-wfor writing viabritecore_sdk.utils.toml_compat; thetomlpackage is no longer a dependency.Optional
pydantic-settingsintegration available viaget_typed_settings()(installbritecore_sdk[typed-config]); Dynaconf remains the runtime source of truth.
Developer workflow in this repo
Python target in
pyproject.tomlis>=3.11; keep edits syntax-compatible with modern Python 3 and avoid introducing features that would unnecessarily raise the minimum version.Single source of truth: Use
pyproject.tomlfor version and dependency specs. Bothsetup.pyand allrequirements.txtfiles are kept in sync automatically.Install editable package from repo root:
python -m pip install -e .
python -m pip install -e .
Minimal smoke check after changes (adjust module names to your edits):
python -c "import britecore_sdk; from britecore_sdk.api.britecore_api_client import BritecoreAPIClient; print(britecore_sdk.__version__)"
python -c "import britecore_sdk; from britecore_sdk.api.britecore_api_client import BritecoreAPIClient; print(britecore_sdk.__version__)"
When changing
docs/content or root Markdown files included via docs wrappers, run a strict Sphinx build because.readthedocs.ymlis configured withfail_on_warning: true:
python -m sphinx -W --keep-going -b html .\docs .\docs\_build\html-strict
python -m sphinx -W --keep-going -b html ./docs ./docs/_build/html-strict
Logging
Logger is exposed as
britecore_sdk.logger(standard Pythonlogging.Logger).Use
logger.info(),logger.debug(),logger.error(), etc. for logging.SDK import does not configure root/global logging; the default package logger uses a
NullHandler.Use
britecore_sdk.configure_logging(...)when you want SDK-managed console/file handlers.Library users can configure logging via standard Python logging mechanisms:
import logging
logging.getLogger("britecore_sdk").setLevel(logging.DEBUG) # Module-level control
logging.basicConfig(level=logging.INFO) # Global config
Don’t create new logger instances in modules; use the package logger or
logging.getLogger(__name__).
Pre-commit hooks and quality gates
Pre-commit framework (pre-commit.com) runs automated checks before commits/pushes. This is MANDATORY for preventing CI failures.
Setup (first time only)
pip install pre-commit
pre-commit install
What runs automatically on git commit
All hooks defined in .pre-commit-config.yaml:
Code linters (ruff, black) — code style and import ordering
Type checker (mypy) — type errors in key modules
Unit smoke tests (pytest) — quick validation before commit
Markdown linter (pymarkdown) — markdown syntax
Markdown structure — custom validation of headings, links, tables
Sphinx documentation build — build docs in strict mode (
-W)
What runs on git push
Release compliance check — validates LICENSE, metadata, and legal docs
Preventing the documentation build failures
The Sphinx hook validates documentation builds before you commit, matching the RTD -W --keep-going flags:
python -m sphinx -W --keep-going -b html ./docs ./docs/_build/html-strict
If this fails locally, it will also fail in CI. The solution is always visible in the pre-commit output. Common issues:
Adjacent transitions (
---markers too close together)Invalid MyST substitutions or syntax
Malformed markdown tables
Unknown Sphinx directives
See docs/DOCUMENTATION_BUILD_TROUBLESHOOTING.md for detailed remedies.
Manual invocation (for debugging)
# Test all hooks on all files
pre-commit run --all-files
# Test specific hook
pre-commit run sphinx-build --all-files --verbose
# Dry run (no changes)
pre-commit run --all-files --dry-run
Bypass (only when absolutely necessary)
git commit --no-verify # Skip hooks for this commit ONLY
git push --no-verify # Skip pre-push hooks ONLY
Note: Bypassing pre-commit leads to CI failures. If you bypass, you are responsible for fixing CI failures before merge.
Gotchas that affect agent changes
API client initialization is now lazy:
api_clientis a proxy that initializes on first use, avoiding failures in contexts without config/env. Callget_api_client()for explicit control.init_client()returnsSelf— one-linerclient = BritecoreAPIClient("site").init_client()is valid and preferred in examples.BritecoreAPIClientsupports the context-manager protocol (__enter__/__exit__); preferwithblocks in examples that need clean teardown.reset_api_client()(fromapi.api_calls) clears the module-level client; use it in tests for site isolation instead of monkeypatching globals.do_request(...)acceptsdry_run=True(part ofRequestParameters) — logs request details without sending. Document this in any debugging section.Flat exception aliases are exported from
britecore_sdk.exceptionsand the top-level package (NotFoundError,AuthenticationError, etc.). Prefer these in new example code; the nestedBritecoreError.Xform still works.Every outbound request carries an
X-SDK-Request-IDheader (short hex correlation ID). The same ID appears in[req_id] → METHOD /pathdebug log lines.process_result(...)expects JSON responses shaped like{success, data, message/messages}; some supported v1 wrappers with no v2 equivalent may parse raw payloads directly.Keep public exports updated via
__all__in package__init__.pyfiles when adding new top-level functionality.CLI entry points (
britecore-healthcheck,britecore-check-config,britecore-run-checks) are registered inpyproject.toml [project.scripts]; re-runpip install -e .after adding new ones.