Skip to content

angee.integrate.models ​

Source models for Angee's integration runtime primitives.

This addon owns the integration layer end to end. The connection substrate — the OAuthClient registration, the user's ExternalAccount at a provider, and the per-user Credential material — authenticates everything above it. On top of that sit the third-party Vendor catalogue, the first-class Integration an integration runs over, concrete child integration kinds such as VcsBridge, addon-owned children such as agents.InferenceProvider, the host-agnostic VCS inventory (VcsBridge + Repository/Source/ Template), and outbound WebhookSubscription.

This addon is pure OAuth: it connects out to external systems and never authenticates a session. OIDC login fields and ID-token verification live one level up in iam_integrate_oidc, which extends this OAuth base and composes the iam user. Host-specific VCS backends live in their own addons (integrate_github) and are named per VcsBridge.backend_class row; this addon never imports them.

AccountStatus ​

python
class AccountStatus(models.TextChoices)

Connection lifecycle for a linked external account.

Pure connection health — does the account's credential still work. The integration implementation health lives on Integration, not here.

CredentialStatus ​

python
class CredentialStatus(models.TextChoices)

Lifecycle state for per-user credential material.

OAuthClientQuerySet ​

python
class OAuthClientQuerySet(AngeeQuerySet[Any])

REBAC-scoped reads for OAuth client registration.

connectable ​

python
def connectable() -> OAuthClientQuerySet

Return enabled, client-configured OAuth clients for the connect picker.

enabled_for_slug ​

python
def enabled_for_slug(slug: str, *, environment: str = "prod") -> Any | None

Return the preferred OAuth client for a slug when that row is enabled.

OAuthClientManager ​

python
class OAuthClientManager(AngeeManager.from_queryset(OAuthClientQuerySet))

Manager for settings-sourced OAuth client registration.

OAuth only: settings entries carry the OAuth base fields. The OIDC refinement (issuer/JWKS/discovery + login policy) is owned by the iam_integrate_oidc addon and seeded there, never from here.

sync_from_settings ​

python
def sync_from_settings(
    entries: Iterable[Mapping[str, Any]] | Mapping[str, Mapping[str, Any]]
    | None = None
) -> tuple[Any, ...]

Create or update OAuth clients declared in settings.ANGEE_INTEGRATE_OAUTH_CLIENTS.

The host owns reading environment variables. Integrate reads only Django settings and keeps secrets out of resource files.

OAuthClient ​

python
class OAuthClient(SqidMixin, ImplDefaultsMixin, AuditMixin, AngeeModel)

OAuth2 client registration for connecting an external account.

The base of the connection substrate: enough to run the authorization-code and refresh flows and act against a provider's API (Gemini, Grok, Anthropic). It carries no identity or login policy itself — a provider that also authenticates a login gains direct fields from the iam_integrate_oidc extension when that addon is installed.

Self-describing: slug is its own connect-client key and icon/ display_name its own button branding. The third-party catalogue is integrate.Vendor; that slug is a deliberately independent namespace, not a foreign key into this one.

provider_type ​

Provider preset key whose defaults seed this OAuth client.

userinfo_endpoint ​

Access-token-protected profile endpoint used to label a connected account (read through the claim mappings below). Plain OAuth, not OIDC: a connect-only provider populates its ExternalAccount from here without any ID token.

Meta ​

python
class Meta()

Django model options for OAuth clients.

__str__ ​

python
def __str__() -> str

Return the configured OAuth client display name or slug environment.

configuration_state ​

python
@property
def configuration_state() -> str

Return this OAuth client's operator-facing configuration readiness.

default_scope_values ​

python
@property
def default_scope_values() -> list[str]

Return the configured default OAuth scopes as strings.

scopes_catalogue_values ​

python
@property
def scopes_catalogue_values() -> list[str]

Return the advertised OAuth scopes as strings.

authorize_param_values ​

python
@property
def authorize_param_values() -> dict[str, str]

Return configured provider-specific authorize parameters.

token_param_values ​

python
@property
def token_param_values() -> dict[str, Any]

Return provider token parameters while preserving JSON scalar types.

resolve_connect_redirect ​

python
def resolve_connect_redirect(proposed_redirect_uri: str) -> tuple[str, str]

Return the (redirect_uri, mode) this client uses to connect from a browser.

mode is "auto" (the provider redirects back to the returned redirect) or "manual" (the user copies the code the provider displays and pastes it back). A client with no manual_redirect_uri always redirects back to the browser-proposed redirect. A fixed public client (manual_redirect_uri set) has an allow-list we cannot extend: on localhost it can round-trip only to the loopback path its allow-list registers, so the proposed redirect's path is replaced with loopback_redirect_path (origin preserved); off-localhost — or with no loopback path declared — its allow-list rejects the redirect and the cross-origin callback would drop the session, so it falls back to manual paste.

token_request_format_value ​

python
@property
def token_request_format_value() -> str

Return the configured token request body format.

external_id_from_claims ​

python
def external_id_from_claims(claims: Mapping[str, Any]) -> str

Return this provider account's stable external id from profile claims.

email_from_claims ​

python
def email_from_claims(claims: Mapping[str, Any]) -> str

Return this provider account's email from profile claims.

display_name_from_claims ​

python
def display_name_from_claims(claims: Mapping[str, Any], email: str) -> str

Return this provider account's display label from profile claims.

avatar_url_from_claims ​

python
def avatar_url_from_claims(claims: Mapping[str, Any]) -> str

Return this provider account's avatar URL from profile claims.

fill_endpoints_from_discovery ​

python
def fill_endpoints_from_discovery(discovery: Mapping[str, Any]) -> bool

Fill this client's blank endpoints from a discovery document; return whether changed.

The client owns projecting a discovery document onto its own endpoint fields, so a caller (the OIDC protocol/discovery action) never reaches in to set them by name.

fill_extension_fields_from_discovery ​

python
def fill_extension_fields_from_discovery(discovery: Mapping[str, Any]) -> bool

Hook for composed extensions to project discovery onto their own fields.

discover_endpoints ​

python
def discover_endpoints() -> Mapping[str, Any]

Fetch discovery and fill blank OAuth/extension endpoints on this row.

ExternalAccountQuerySet ​

python
class ExternalAccountQuerySet(AngeeQuerySet[Any])

REBAC-scoped reads for external accounts.

console_external_accounts ​

python
def console_external_accounts() -> ExternalAccountQuerySet

Return admin-visible external accounts with guarded FK joins.

ExternalAccountManager ​

python
class ExternalAccountManager(
        AngeeManager.from_queryset(ExternalAccountQuerySet))

Manager for idempotent external account linking.

Actor-less framework writes run under system_context; update paths do not maintain updated_by.

python
def link(oauth_client: Any,
         external_id: str,
         *,
         owner: Any | None = None,
         **identity: Any) -> Any

Create or update one (oauth_client, external_id) external account.

grant_owner ​

python
def grant_owner(account: Any, owner: Any) -> None

Grant owner direct ownership of an external account.

revoke_owner ​

python
def revoke_owner(account: Any, owner: Any) -> None

Revoke owner direct ownership of an external account.

owner_for ​

python
def owner_for(account: Any) -> Any | None

Return the user granted owner on account, if one exists.

ExternalAccount ​

python
class ExternalAccount(SqidMixin, AuditMixin, AngeeModel)

A user's identity at a provider, shared by principals through REBAC grants.

Connection identity only: which client minted it (oauth_client), which external subject (external_id), and the credential that authenticates as it. The integration that runs over a connection lives in integrate.Integration, which owns implementation health.

Meta ​

python
class Meta()

Django model options for external accounts.

__str__ ​

python
def __str__() -> str

Return a stable provider-qualified account label.

credential_status ​

python
@property
def credential_status() -> str

Return the current OAuth credential status, if this account has one.

provider_slug ​

python
@property
def provider_slug() -> str

Return the originating OAuth client's slug.

provider_environment ​

python
@property
def provider_environment() -> str

Return the originating OAuth client's environment.

provider_label ​

python
@property
def provider_label() -> str

Return the originating OAuth client's display label.

provider_icon ​

python
@property
def provider_icon() -> str

Return the originating OAuth client's branding icon.

display_name_from_claims ​

python
@staticmethod
def display_name_from_claims(claims: Mapping[str, Any], email: str) -> str

Return the best display label from verified identity claims.

CredentialQuerySet ​

python
class CredentialQuerySet(AngeeQuerySet[Any])

REBAC-scoped reads for credential health and connected accounts.

connected_for ​

python
def connected_for(user: Any) -> CredentialQuerySet

Return user's external-account-backed credentials.

Each row is a credential whose external_account (and that account's credential) is preloaded under the ambient actor's scope. Owns the "what counts as a connected account" predicate for the self-service connected-accounts surface.

console_credentials ​

python
def console_credentials() -> CredentialQuerySet

Return admin-visible credential health with guarded FK joins.

CredentialManager ​

python
class CredentialManager(AngeeManager.from_queryset(CredentialQuerySet))

Manager for idempotent per-user credential writes.

Actor-less framework writes run under system_context; update paths do not maintain updated_by.

check_disconnect ​

python
def check_disconnect(credential: Any) -> None

Run installed credential-disconnect guards for an explicit disconnect.

live_oauth_for_user ​

python
def live_oauth_for_user(user: Any, oauth_client: Any) -> Any | None

Return this user's active, non-expired OAuth credential for one client.

upsert_for_user ​

python
def upsert_for_user(user: Any,
                    oauth_client: Any,
                    kind: str,
                    material: dict[str, Any],
                    *,
                    external_account: Any | None = None,
                    **fields: Any) -> Any

Create or update one (user, oauth_client) OAuth credential (connect/login flow).

create_local_credential ​

python
def create_local_credential(user: Any, *, kind: str, name: str,
                            material: dict[str, Any], **fields: Any) -> Any

Create or update one provider-less (static/ssh) credential, keyed by (user, name).

The provider-less counterpart to :meth:upsert_for_user: oauth_client is NULL (the kind/provider invariant forbids one), and name is the credential's identity. OAuth credentials are minted by the connect/login flow only.

prepare_local_credential ​

python
def prepare_local_credential(user: Any, *, kind: str, name: str,
                             material: dict[str, Any], **fields: Any) -> Any

Return a validated, unsaved provider-less credential for external preflight.

credential_disconnect_guards ​

python
@cache
def credential_disconnect_guards() -> tuple[Any, ...]

Return configured credential-disconnect guard callables.

check_credential_disconnect_guards ​

python
def check_credential_disconnect_guards(
        app_configs: list[object] | None = None,
        **kwargs: object) -> list[checks.CheckMessage]

Validate configured credential-disconnect guard callables.

Credential ​

python
class Credential(SqidMixin, AuditMixin, AngeeModel)

Per-user credential material for acting against a vendor OAuth client.

oauth_client ​

The provider this credential authenticates to — required for oauth (its identity is the provider account), optional for local kinds (static_token/ssh_key), which may be created without one.

name ​

Human credential label; provider-backed rows are named on create, local rows use it as their per-user identity.

Meta ​

python
class Meta()

Django model options for credentials.

handler ​

python
@property
def handler() -> Any

Return the registered handler for this credential kind.

reveal ​

python
def reveal() -> dict[str, Any]

Return decrypted material through the kind handler.

encode_material ​

python
@staticmethod
def encode_material(material: Mapping[str, Any]) -> str

Encode credential material into its deterministic encrypted-field payload.

update_material ​

python
def update_material(**changes: Any) -> None

Merge encrypted material changes under a row lock; None deletes.

Credential material may be edited concurrently by operator and worker processes holding separately-loaded instances. Re-read the row under the same authoritative lock canon as :meth:Bridge.merge_subscription_state so one key's consume-once edit cannot clobber another writer's material. Kind handlers validate required keys at credential creation; transient extra keys remain permitted here.

auth_headers ​

python
def auth_headers() -> dict[str, str]

Return authorization headers through the kind handler.

secret_value ​

python
def secret_value() -> str

Return the primary secret value through the kind handler.

display_name ​

python
@model_property(only=["name", "oauth_client_id", "external_account_id"], )
def display_name() -> str

Return a human label for lists, headers, and relation pickers.

connected_display_name ​

python
@property
def connected_display_name() -> str

Return a public-safe label for the current user's connected account.

ensure_fresh ​

python
def ensure_fresh() -> None

Renew this credential's token in place when it is near expiry and can refresh.

A best-effort freshening hook for a server-side consumer about to use the secret (e.g. syncing it into a provisioned agent): an OAuth credential whose access token is near expiry is renewed through its provider refresh grant; every other case — a non-expiring local token, a still-valid token, or a credential with no refresh grant — is a no-op. The refresh is serialized and re-checked under a row lock (:meth:_refresh_locked), so racing consumers issue at most one network refresh. A provider rejecting the refresh is recorded (last_refresh_status="failed") and logged, not raised, so it never blocks the consumer (the stale token then fails downstream as it would have anyway); unexpected errors propagate.

refresh_now ​

python
def refresh_now() -> None

Force a provider refresh now for an interactive caller, raising on failure.

The explicit counterpart to :meth:ensure_fresh: a console refresh action renews the token regardless of how much life it has left and surfaces the outcome instead of swallowing it. Requires a refresh-capable provider and a stored refresh token — an expired access token still refreshes, since the grant uses the refresh token; otherwise raises ValueError telling the caller to reconnect. A provider rejecting the grant records last_refresh_status as "failed" and re-raises (OAuthFlowError) so the caller can report it. Serialized under the same row lock as :meth:ensure_fresh.

VendorManager ​

python
class VendorManager(AngeeManager)

Manager for the resource-seeded third-party catalogue.

seeded ​

python
def seeded(slug: str) -> Any

Return the seeded vendor named by slug or raise with load guidance.

Vendor ​

python
class Vendor(SqidMixin, AuditMixin, AngeeModel)

Admin-managed third-party catalogue (GitHub, Google, Slack, …).

The single source of truth for "what is this third party" — branding and reference metadata only. New integration addons add their own row via an install-tier resource seed (adopt: slug). The connect-side OAuthClient carries its own slug; that is a deliberately independent namespace, not a foreign key into this catalogue.

Meta ​

python
class Meta()

Django model options for integration vendors.

__str__ ​

python
def __str__() -> str

Return the display label used by Django surfaces.

IntegrationLifecycle ​

python
class IntegrationLifecycle(models.TextChoices)

Durable connection lifecycle shared by every integration.

from_value ​

python
@classmethod
def from_value(cls, value: object) -> IntegrationLifecycle

Return the member for one string or enum integration-lifecycle value.

IntegrationRuntimeStatus ​

python
class IntegrationRuntimeStatus(models.TextChoices)

Observed runtime health for one integration implementation.

from_value ​

python
@classmethod
def from_value(cls, value: object) -> IntegrationRuntimeStatus

Return the member for one string or enum runtime-status value.

IntegrationManager ​

python
class IntegrationManager(AngeeManager)

Manager factories for invariants that span Integration and its impl row.

impl_class_for_key ​

python
def impl_class_for_key(key: str) -> type[IntegrationImpl]

Return the implementation class registered for key on this model.

disconnected_for ​

python
def disconnected_for(user: Any, *, vendor: Any, impl_class: str) -> Any

Return the user's parent row for one disconnected integration.

connect_from_credential ​

python
def connect_from_credential(user: Any,
                            *,
                            vendor: Any,
                            credential: Any,
                            impl_class: str = "none") -> Any

Attach credential to the user's parent row and connect it.

sync_kinds ​

python
def sync_kinds() -> int

Backfill parent rows with the concrete integration kind they materialize.

Integration ​

python
class Integration(SqidMixin, ImplDefaultsMixin, AuditMixin, AngeeModel)

A product/workspace integration to a vendor account.

The first-class "what we're connected to and what runs over it": it draws a credential (and optionally an account) from the connection substrate to authenticate, points at a catalogue vendor, and stores the implementation key that owns integration-level behavior. Domain-specific state and config live on concrete child models.

Lifecycle ​

Expose the lifecycle vocabulary off the row for callers that cannot import this module.

integration_kind_label ​

Human kind label for parent-level integration grouping.

kind ​

Human integration type/kind label, denormalized for server-side grouping.

impl_class ​

Registry key for the implementation this integration runs.

lifecycle ​

Declared connection intent for this integration.

Connected means configured and enabled, paused retains configuration while intentionally stopped, and disconnected releases the connection. Runtime health lives separately on runtime_status.

runtime_status ​

Observed health for the integration's last runtime interaction.

OK and ERROR describe the last credential/sync/use outcome; they do not move the lifecycle journey.

Meta ​

python
class Meta()

Django model options for integrations.

__str__ ​

python
def __str__() -> str

Return a stable vendor-qualified integration label.

integration_kind_value ​

python
@classmethod
def integration_kind_value(cls) -> str

Return the grouping label this integration concrete model contributes.

save ​

python
def save(*args: Any, **kwargs: Any) -> None

Persist the parent grouping kind when a concrete child row saves.

display_label ​

python
@property
def display_label() -> str

Return the operator label, or a vendor-derived one when none was given.

Headers, lists, and relation pickers read this so a named integration shows its name and an unnamed one still reads as Vendor (lifecycle).

impl ​

python
@property
def impl() -> IntegrationImpl

Return this row's integration-level implementation.

connect ​

python
@transition(
    lifecycle,
    source=[IntegrationLifecycle.DISCONNECTED, IntegrationLifecycle.PAUSED],
    target=IntegrationLifecycle.CONNECTED,
    on_success=save_state,
)
def connect(*, credential: Any = _UNSET, account: Any = _UNSET) -> None

Mark this integration connected, optionally attaching connection rows.

pause ​

python
@transition(
    lifecycle,
    source=IntegrationLifecycle.CONNECTED,
    target=IntegrationLifecycle.PAUSED,
    on_success=save_state,
)
def pause() -> None

Pause this connected integration without changing its runtime health.

disconnect ​

python
@transition(
    lifecycle,
    source=[IntegrationLifecycle.CONNECTED, IntegrationLifecycle.PAUSED],
    target=IntegrationLifecycle.DISCONNECTED,
    on_success=save_state,
)
def disconnect() -> None

Disconnect this integration without changing its runtime health.

set_lifecycle ​

python
def set_lifecycle(lifecycle: IntegrationLifecycle | str) -> None

Move to one declared lifecycle state using this model's transition methods.

attach_credential ​

python
def attach_credential(credential: Any) -> None

Attach a live credential and connect this disconnected integration.

report_status ​

python
def report_status(status: IntegrationRuntimeStatus | str,
                  error: str = "") -> None

Record implementation status telemetry and persist this integration.

status is a runtime status, resolved by member name (ERROR — the shape GraphQL serializes) or stored value (error); anything else fails at the vocabulary that could not read it. Only the runtime axis is written — lifecycle is the operator's to declare, and a status report is not the operator. last_used_status keeps what was reported verbatim.

Bridge ​

python
class Bridge(AngeeModel)

Abstract base for child models that synchronize or subscribe to vendor data.

Pure bridge state and behavior. A materialized bridge extends integrate.Integration so common identity, credential, status, and audit fields stay on the integration parent row while bridge-specific settings stay on the child.

SyncStage ​

python
class SyncStage(models.TextChoices)

Generic lifecycle stage for bridge sync jobs.

LiveState ​

python
class LiveState(models.TextChoices)

Desired live-ingest state persisted in subscription_state["desired"].

The base owns this vocabulary: bridge start/stop methods write it, and a live implementation's session loop and reconciler read it. Stopping is cooperative - a running session notices STOPPED and exits.

live_impl_field ​

Name the ImplClassField that selects this bridge's runtime implementation.

config ​

Bridge-scoped settings interpreted by the selected backend.

next_sync_at ​

Next scheduler poll. NULL means unscheduled: a bridge enters the poll loop when its first (eager) sync records a result; the scheduler claims a due row by pushing this one interval out for the duration of the run.

Meta ​

python
class Meta()

Django model options for abstract bridge inheritance.

live_impl ​

python
@property
def live_impl() -> IntegrationImpl

Return this bridge's selected runtime implementation.

is_syncing ​

python
@property
def is_syncing() -> bool

Return whether a worker currently holds this bridge's live sync lock.

effective_sync_stage ​

python
@property
def effective_sync_stage() -> str

Return the sync stage reconciled against the live lock, not the record.

The persisted sync_stage is a progress report, not the source of truth for "is a run alive" — only the advisory lock is. A crashed worker leaves syncing behind forever; this projection reports such a row as FAILED (the run was interrupted) instead of trusting the stale column. queued is exempt: a queued task legitimately holds no lock until a worker picks it up. When the lock backend is process-local (the SQLite floor), the web process cannot see a worker's lock at all — reconciling there would misreport every healthy run, so the column is trusted as-is.

sync_lock_key ​

python
def sync_lock_key() -> LockKey

Return the advisory task lock key for this bridge sync.

mark_sync_started ​

python
def mark_sync_started(*, now: datetime) -> None

Persist the start timestamp for one scheduler sync attempt.

claim_sync ​

python
def claim_sync(*, now: datetime) -> None

Push the next poll one interval out as an in-flight claim.

The scheduler claims a due row under a row lock before running it, so an overlapping scan — a backfill outliving the tick cadence, or a second worker — re-reads the row, sees a future next_sync_at, and skips instead of double-syncing one source. record_sync / record_sync_error recompute the real next poll when the run ends.

mark_sync_queued ​

python
def mark_sync_queued(*, now: datetime) -> None

Persist that a worker task has been queued for this bridge.

reset_sync_queue ​

python
def reset_sync_queue(*, now: datetime) -> None

Make a failed queue dispatch due again for the next scheduler pass.

sync_queue_token_matches ​

python
def sync_queue_token_matches(timestamp: datetime) -> bool

Return whether a queued task payload still matches this bridge row.

release_sync_queue ​

python
def release_sync_queue(*, now: datetime) -> bool

Release a queue claim this run declined; return whether it was still ours.

A declined run is terminal for its queue token — the work is not happening. Leaving the row QUEUED makes the stale-queue recovery in angee.integrate.scheduler re-queue it every _QUEUED_RECOVERY_SECONDS forever, because that recovery exists to repair a lost enqueue and cannot tell one from a declined run. So the task that declines the work is the one that clears the claim.

Guarded by the queue token and re-read under a row lock: whoever holds the sync lock may already have moved this row on (a concurrent :meth:mark_sync_started), and the decliner must never overwrite the holder's stage. Mirrors :meth:merge_subscription_state.

record_sync ​

python
def record_sync(result: int, *, now: datetime) -> None

Persist one successful scheduler sync result and healthy status report.

record_sync_error ​

python
def record_sync_error(error: Exception, *, now: datetime) -> None

Persist one failed scheduler sync result and error status report.

run_sync ​

python
def run_sync(*, now: datetime) -> int

Run one sync attempt and persist its lifecycle telemetry.

sync ​

python
def sync() -> int

Synchronize this bridge with its external system.

handle_webhook ​

python
def handle_webhook(payload: Any) -> None

Apply one verified inbound webhook payload to this bridge.

verify_webhook ​

python
def verify_webhook(request: Any) -> bool

Return whether an inbound webhook request is authentic for this bridge.

dispatch_inbound ​

python
def dispatch_inbound(request_or_payload: Any) -> bool

Verify one inbound webhook and apply it to this bridge when authentic.

start_live ​

python
def start_live() -> None

Start or renew this bridge's live vendor subscription.

stop_live ​

python
def stop_live() -> None

Stop this bridge's live vendor subscription.

merge_subscription_state ​

python
def merge_subscription_state(**values: Any) -> dict[str, Any]

Merge sub-keys into subscription_state under a row lock; return it.

This method merges only — a key can never be removed; consumed markers settle to a sentinel value defined by their owning flow. subscription_state has disjoint owners — the operator writes desired (start/stop), a live session writes its own pairing facts — that may write concurrently from separately-loaded instances. A full read-modify-write from a stale instance would clobber the other owner's key, so this re-reads the row locked, merges only the given keys, and saves. Mirrors :meth:Channel._persist_cursor_slice.

RepoVisibility ​

python
class RepoVisibility(models.TextChoices)

Visibility of a git remote on its host.

VcsBridge ​

python
class VcsBridge(Bridge)

The VCS sync child model over Integration.

A :class:Bridge: the scheduler refreshes its repositories' sources over the host REST API and an inbound push webhook triggers the same refresh. The host-specific wire format is the integration child row's non-model :class:~angee.integrate.vcs.backend.VCSBackend implementation — so github/gitlab/bitbucket share this one table, differing only in behavior. Django keeps the inventory only; the operator performs every git operation, consuming :meth:Source.materialize_spec.

backend_class ​

Registry key for the VCS backend bound to this bridge.

webhook_secret ​

Shared secret for verifying inbound push webhooks (per account, not per repo).

Meta ​

python
class Meta()

Django model options for the VCS bridge child model.

backend ​

python
@property
def backend() -> VCSBackend

Return this bridge's selected VCS backend.

repositories_by_org ​

python
def repositories_by_org() -> dict[str, list[Any]]

Return every visible repository grouped and sorted by owning org.

discover ​

python
def discover(source: Any, *, marker: str,
             parse: Callable[[bytes], dict[str, Any]]) -> list[dict[str, Any]]

Return one descriptor per directory under source bearing marker.

The single enumeration walk shared by every source kind: list the source's subtree, read each marker blob, parse it, record the bearing directory, and return the descriptors in deterministic order. A source kind's output manager supplies only its marker filename and parse function.

sync ​

python
def sync() -> int

Refresh every inventoried repository's sources over REST (Bridge contract).

Repository discovery (creating rows from the account) is the explicit discoverRepositories action; the scheduled/webhook sync refreshes the content of already-inventoried repositories.

handle_webhook ​

python
def handle_webhook(payload: Any) -> None

Re-sync this bridge's inventory on an inbound push webhook.

verify_webhook ​

python
def verify_webhook(request: Any) -> bool

Return whether an inbound push webhook is authentic for this bridge.

search_repositories ​

python
def search_repositories(query: str) -> list[Any]

Return host repositories whose name matches query (the add typeahead).

import_repository ​

python
def import_repository(name: str) -> Any

Inventory one repository by its host name (a picked typeahead result).

discover_repositories ​

python
def discover_repositories(*, org: str = "") -> int

Inventory every repository the account exposes (bulk import; prunes vanished).

RepositoryManager ​

python
class RepositoryManager(AngeeManager)

Manager owning the upsert/reconcile of repository rows from a host listing.

reconcile ​

python
def reconcile(vcs_bridge: Any, descriptors: Iterable[Any]) -> int

Upsert one repository row per descriptor and prune rows that vanished.

Bulk import for discoverRepositories: prunes against the full listing, so the caller must pass every repository (see GitHubBackend.ls_repos pagination), never a partial page.

add ​

python
def add(vcs_bridge: Any, descriptor: Any) -> Any

Inventory one repository (no prune) — the typeahead "add this repo" path.

Repository ​

python
class Repository(SqidMixin, AuditMixin, AngeeModel)

Inventory of one git remote, reached through its VcsBridge.

A plain noun: Django records the remote; the operator clones it. org groups the account's repositories in the browse list.

name ​

The repository's owner/repo path on its remote host.

remote ​

The HTTPS remote URL the operator clones.

Meta ​

python
class Meta()

Django model options for repository inventory.

__str__ ​

python
def __str__() -> str

Return the repository's host path.

Source ​

python
class Source(SqidMixin, AuditMixin, AngeeModel)

A pointer into a Repository at a ref and path, with a kind.

One noun for every source kind. kind binds the source to an output model (Template/Skill) whose manager reconciles its rows; :meth:refresh dispatches there. The operator materializes a source from :meth:materialize_spec.

kind ​

The source kind (e.g. template, skill); resolves to an output model.

ref ​

Branch, tag, or commit oid; blank resolves to the repository's default branch.

path ​

Pathspec of the subtree this source points at within the repository.

Meta ​

python
class Meta()

Django model options for source inventory.

__str__ ​

python
def __str__() -> str

Return a kind-qualified source label.

kind_models ​

python
@classmethod
def kind_models(cls) -> tuple[type[models.Model], ...]

Return the output models that declare a source_kind (e.g. Template).

Source owns "what a kind resolves to": an output model binds itself to a kind with a source_kind class attribute; the integration registry owns the deterministic app scan and contract check.

available_kinds ​

python
@classmethod
def available_kinds(cls) -> tuple[str, ...]

Return the source kinds any installed addon contributes an output model for.

target_for_kind ​

python
@classmethod
def target_for_kind(cls, kind: str) -> type[models.Model]

Return the output model bound to one source kind or raise.

refresh ​

python
def refresh() -> int

Re-enumerate over REST into the kind's output rows; return the row count.

materialize_spec ​

python
def materialize_spec() -> dict[str, str]

Return the operator handoff coordinates to clone and check out this source.

TemplateManager ​

python
class TemplateManager(AngeeManager)

Manager owning the reconcile of template rows from a template source.

sync_from_source ​

python
def sync_from_source(source: Any) -> int

Walk the source for copier.yml and upsert/prune Template rows.

Template ​

python
class Template(SqidMixin, AuditMixin, AngeeModel)

One Copier template discovered under a Source (source_kind="template").

The operator renders these; the kind here is the template kind from the manifest's _angee.kind (stack/workspace/service).

source_kind ​

Binds the template source kind to this output model (see registry).

kind ​

The template kind from _angee.kind (stack/workspace/service).

Meta ​

python
class Meta()

Django model options for discovered templates.

__str__ ​

python
def __str__() -> str

Return a kind-qualified template label.

WebhookSubscriptionManager ​

python
class WebhookSubscriptionManager(AngeeManager)

Manager for webhook subscriptions.

enqueue_event ​

python
def enqueue_event(*,
                  kind: EventKind,
                  payload: Any,
                  impl_app: str = "",
                  integration: Any | None = None) -> None

Queue one event fan-out after the current transaction commits.

deliver_event ​

python
def deliver_event(*,
                  kind: EventKind,
                  payload: Any,
                  impl_app: str = "",
                  integration: Any | None = None) -> dict[str, int]

Deliver one integration event to every matching enabled subscription.

Actor-less framework fan-out: it reads subscriptions across all owners, so it runs under system_context. Each subscription matches and delivers itself; this method only owns the row-set loop and the success/error tally.

WebhookSubscription ​

python
class WebhookSubscription(SqidMixin, AuditMixin, AngeeModel)

Outbound webhook endpoint owned by one user.

Meta ​

python
class Meta()

Django model options for webhook subscriptions.

matches ​

python
def matches(*,
            kind: str,
            impl_app: str,
            integration: Any | None = None,
            integration_pk: Any | None = None) -> bool

Return whether this subscription should receive one event.

deliver ​

python
def deliver(body: bytes) -> str

POST one signed event body to this subscription's pinned target; raise on non-2xx.

deliver_recorded ​

python
def deliver_recorded(body: bytes) -> tuple[bool, str]

Deliver one body, persist telemetry, and return (ok, status_or_error).

deliver_test ​

python
def deliver_test() -> tuple[bool, str]

Send a test event, persist telemetry, and return an action result tuple.

rotate_secret ​

python
def rotate_secret() -> str

Generate a new signing secret, persist it, and return the plaintext once.

The subscription owns its signing material: a console action calls this to roll the secret. The plaintext is returned only here (for one-time display); reads never expose it.

record_delivery ​

python
def record_delivery(status: str) -> None

Persist success telemetry for one delivery attempt (mirrors Bridge.record_sync).

record_delivery_failure ​

python
def record_delivery_failure(*, status: str, error: str) -> None

Persist failure telemetry for one delivery attempt (mirrors Bridge.record_sync_error).

Takes the already-classified status/error: the delivery layer owns turning a delivery exception into those strings.

Released under the AGPL-3.0 License.