app.sources.port¶
Provider-neutral port between polling and the source adapters.
A SourceAdapter reads the published ref of one source
registration. Everything crossing the port is provider-neutral: project
id/path, file path, change token, content bytes, source URL, author and
ref. Pagination, API formats, scopes and credentials stay inside the
adapter module.
Polling drives an adapter in three steps:
SourceAdapter.list_projects()– the in-scope projects with the resolved published ref of each.complete=Falsemeans the listing may miss projects; polling then deletes nothing.SourceAdapter.list_documents()– the ADR files of one project under the registrationpathwith their change tokens. The adapter receives the stored tokens and marks each documentchangedor not; polling fetches only changed documents.complete=Falsemeans files may be missing; polling then deletes nothing in that project.SourceAdapter.fetch()– the exact bytes of one changed file.
Change tokens are opaque strings chosen by the adapter (for example
mtime_ns:size or a blob id). A document reported with
changed=False but a token different from the stored one keeps its
content; polling only rewrites the stored token. Adapters may use that
to carry project-level state (such as a branch head) in the token.
Adapters raise SourceError subclasses for source problems;
messages must be actionable and must never contain secrets.
Public API: SourceProject, ProjectListing,
SourceDocument, DocumentListing,
FetchedDocument, SourceAdapter, SourceError,
ConfigErrorCode, SourceConfigError,
SourceUnavailableError,
SourceAccessError, SourceNotFoundError.
- exception app.sources.port.SourceError(message, *, code=None, hint=None, extra=None)¶
Bases:
AdrianoErrorA source could not be read; prior content must be preserved.
- class app.sources.port.ConfigErrorCode(*values)¶
Bases:
StrEnumStable, machine-readable reason why a registration is disabled.
The readable
config_errortext stays the detailed explanation; the code lets the UI show plain-language copy.invalid_settings– a field of the entry, its type-specific options or itsscopefailed validation (missing, wrong type, bad URL, unknown key, …).unknown_type– thetypeis not a known source type.type_unavailable– the type is known but has no adapter in this build.invalid_published_ref–published_refis not usable for the type.token_env_missing– the env var named bytoken_envis not set.removed_from_config– the registration is stored but no longer incatalog.yaml.other– any other configuration error.
- INVALID_SETTINGS = 'invalid_settings'¶
- UNKNOWN_TYPE = 'unknown_type'¶
- TYPE_UNAVAILABLE = 'type_unavailable'¶
- INVALID_PUBLISHED_REF = 'invalid_published_ref'¶
- TOKEN_ENV_MISSING = 'token_env_missing'¶
- REMOVED_FROM_CONFIG = 'removed_from_config'¶
- OTHER = 'other'¶
- exception app.sources.port.SourceConfigError(message, *, config_code=ConfigErrorCode.OTHER)¶
Bases:
SourceErrorType-specific registration settings are invalid.
- Parameters:
message (
str) – Readable, secret-free description.config_code (
ConfigErrorCode) – Stable reason code (ConfigErrorCode).
Bases:
SourceErrorThe source is temporarily unreachable (network, timeout, 5xx).
- exception app.sources.port.SourceAccessError(message, *, code=None, hint=None, extra=None)¶
Bases:
SourceErrorThe source refused access (bad or insufficient credentials).
- exception app.sources.port.SourceNotFoundError(message, *, code=None, hint=None, extra=None)¶
Bases:
SourceErrorA configured root, project or path does not exist at the source.
- class app.sources.port.SourceProject(*, id, path, ref)¶
Bases:
objectOne in-scope project (repository or directory) of a registration.
- Parameters:
- class app.sources.port.ProjectListing(*, projects, complete=True, problems=())¶
Bases:
objectThe in-scope projects of a registration.
- Parameters:
- projects: tuple[SourceProject, ...]¶
- class app.sources.port.SourceDocument(*, project, path, change_token, changed=True)¶
Bases:
objectOne ADR file found in a project listing.
- Parameters:
project (
SourceProject) – Owning project.path (
str) – POSIX file path inside the project (including the registrationpathprefix).change_token (
str|None) – Opaque token that changes when the content may have changed;Noneif the source offers none.changed (
bool) – Whether the content may differ from the content that produced the stored token; polling fetches only these.
- project: SourceProject¶
- class app.sources.port.DocumentListing(*, documents, complete=True, problems=())¶
Bases:
objectThe ADR files of one project.
- Parameters:
- documents: tuple[SourceDocument, ...]¶
- class app.sources.port.FetchedDocument(*, content, source_url=None, author=None)¶
Bases:
objectThe content of one document.
- Parameters:
- class app.sources.port.SourceAdapter(*args, **kwargs)¶
Bases:
ProtocolReads the published ref of one source registration.
- async list_projects()¶
List the in-scope projects.
- Return type:
- Returns:
The listing.
- Raises:
SourceError – If no listing can be produced at all.
- async list_documents(project, previous_tokens)¶
List the ADR files of one project.
- Parameters:
project (
SourceProject) – A project fromlist_projects().previous_tokens (
Mapping[str,str|None]) – Stored change token per file path of this project (empty on the first poll).
- Return type:
- Returns:
The listing.
- Raises:
SourceError – If the project cannot be listed.
- async fetch(document)¶
Read one document.
- Parameters:
document (
SourceDocument) – A document fromlist_documents().- Return type:
- Returns:
Its content.
- Raises:
SourceError – If the document cannot be read.