Public Backend API¶
Backend packages should import this public surface, not the internal
app.adapters modules. sfmapi ships no real backend. It provides
layered backend protocols, registry hooks, contract checkers, and a
no-op stub for tests / ephemeral demos.
Action-only packages can satisfy the minimal Backend protocol and
expose native tools through backend actions. Complete engines can
satisfy SfmBackend and implement the full portable feature, match,
mapping, refinement, and export surface.
Stable backend-authoring API for sfmapi plugins.
- class sfmapi.backends.ArtifactConversionBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolConvert one stage artifact format into another.
- convert_artifact(*, input_artifact, output_dir, to_format, to_kind=None, options=None)[source]
Convert an artifact and return one or more artifact descriptors.
- Parameters:
input_artifact (dict[str, Any])
output_dir (Path)
to_format (str)
to_kind (str | None)
options (dict[str, Any] | None)
- Return type:
dict[str, Any]
- class sfmapi.backends.Backend(*args, **kwargs)[source]
Bases:
BackendIdentity,ProtocolMinimum contract every registered backend must satisfy.
- capabilities()[source]
Portable sfmapi capability names this backend implements.
This set must contain only names from
app.core.capabilities.ALL_KNOWN. Backend-native tools belong in the action catalog, not here.- Return type:
set[str]
- runtime_versions()[source]
Engine/dependency versions that influence cache identity.
- Return type:
dict[str, str]
- class sfmapi.backends.BackendActionProvider(*args, **kwargs)[source]
Bases:
ProtocolOptional structural protocol implemented by richer backends.
- list_backend_actions(*, include_schemas=False)[source]
- Parameters:
include_schemas (bool)
- Return type:
list[dict[str, Any]]
- get_backend_action(action_id)[source]
- Parameters:
action_id (str)
- Return type:
dict[str, Any]
- validate_backend_action(action_id, inputs)[source]
- Parameters:
action_id (str)
inputs (dict[str, Any])
- Return type:
dict[str, Any]
- run_backend_action(action_id, inputs, *, workspace=None, progress=None)[source]
- Parameters:
action_id (str)
inputs (dict[str, Any])
workspace (Path | None)
progress (Any | None)
- Return type:
dict[str, Any]
- class sfmapi.backends.BackendArtifactContractProvider(*args, **kwargs)[source]
Bases:
ProtocolOptional structural protocol for backends with explicit artifact I/O.
- list_backend_artifact_contracts()[source]
- Return type:
list[dict[str, Any]]
- class sfmapi.backends.BackendConfigSchemaProvider(*args, **kwargs)[source]
Bases:
ProtocolOptional structural protocol implemented by richer backends.
- list_backend_config_schemas(*, include_schemas=True)[source]
- Parameters:
include_schemas (bool)
- Return type:
list[dict[str, Any]]
- class sfmapi.backends.BackendIdentity(*args, **kwargs)[source]
Bases:
ProtocolBackend identity fields surfaced by /v1/version and discovery.
- property name: str
Canonical short name, e.g.
"pycolmap"or"realityscan_cli".
- property version: str
Backend adapter version string.
- property vendor: str
Optional human-readable vendor or upstream project.
- class sfmapi.backends.BatchLocalizationBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolBatch or sequence localization helpers.
- localize_batch(**kwargs)[source]
Localize multiple query images.
- Parameters:
kwargs (Any)
- Return type:
list[Any]
- class sfmapi.backends.ExportBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolPortable reconstruction export stages.
- export(*, model_path, output_path, format)[source]
Export a sparse model.
- Parameters:
model_path (Path)
output_path (Path)
format (str)
- Return type:
dict[str, Any]
- class sfmapi.backends.FeatureBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolPortable feature, pair-selection, matching, and verification stages.
- extract_features(*, database_path, image_root, image_list, options)[source]
Run feature extraction over
image_listinto the SfM database.- Parameters:
database_path (Path)
image_root (Path)
image_list (list[str])
options (dict[str, Any])
- Return type:
dict[str, Any]
- match(*, database_path, mode, options)[source]
Run feature matching for the given pair-selection strategy.
- Parameters:
database_path (Path)
mode (str)
options (dict[str, Any])
- Return type:
dict[str, Any]
- verify_matches(*, database_path, options)[source]
Run geometric verification on existing matches.
- Parameters:
database_path (Path)
options (dict[str, Any])
- Return type:
dict[str, Any]
- class sfmapi.backends.LocalizationBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolSingle-image localization helpers.
- localize_from_memory(*, sparse_dir, query_image, spec)[source]
Localize a query image against a sparse model.
- Parameters:
sparse_dir (Path)
query_image (Path)
spec (dict[str, Any])
- Return type:
dict[str, Any]
- class sfmapi.backends.MappingBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolPortable mapping stages.
- run_mapping(*, kind, db_path, image_root, sparse_root, job_dir, spec, pose_priors=None)[source]
Run incremental/global/hierarchical/spherical mapping.
- Parameters:
kind (str)
db_path (Path)
image_root (Path)
sparse_root (Path)
job_dir (Path)
spec (dict[str, Any])
pose_priors (dict[str, Any] | None)
- Return type:
tuple[list[dict[str, Any]], list[Any]]
- class sfmapi.backends.NoopProgressReporter[source]
Bases:
objectDrop-in reporter for tests and backend code paths without a job.
- phase_started(phase)[source]
- Parameters:
phase (Literal['feature_extraction', 'matching', 'geometric_verification', 'incremental_init', 'incremental_register', 'incremental_ba', 'global_rotation_avg', 'global_positioning', 'global_ba', 'hierarchical_cluster', 'hierarchical_merge', 'panorama', 'spherical', 'bundle_adjust', 'triangulate', 'relocalize', 'pose_graph_optimize', 'segment', 'export', 'vlad_index', 'backend_action', 'artifact_conversion'])
- Return type:
None
- phase_progress(phase, *, current, total=None, rate=None)[source]
- Parameters:
phase (Literal['feature_extraction', 'matching', 'geometric_verification', 'incremental_init', 'incremental_register', 'incremental_ba', 'global_rotation_avg', 'global_positioning', 'global_ba', 'hierarchical_cluster', 'hierarchical_merge', 'panorama', 'spherical', 'bundle_adjust', 'triangulate', 'relocalize', 'pose_graph_optimize', 'segment', 'export', 'vlad_index', 'backend_action', 'artifact_conversion'])
current (int)
total (int | None)
rate (float | None)
- Return type:
None
- phase_completed(phase)[source]
- Parameters:
phase (Literal['feature_extraction', 'matching', 'geometric_verification', 'incremental_init', 'incremental_register', 'incremental_ba', 'global_rotation_avg', 'global_positioning', 'global_ba', 'hierarchical_cluster', 'hierarchical_merge', 'panorama', 'spherical', 'bundle_adjust', 'triangulate', 'relocalize', 'pose_graph_optimize', 'segment', 'export', 'vlad_index', 'backend_action', 'artifact_conversion'])
- Return type:
None
- metric(key, value)[source]
- Parameters:
key (str)
value (float)
- Return type:
None
- snapshot_available(*, snapshot_seq, summary)[source]
- Parameters:
snapshot_seq (int)
summary (dict[str, Any])
- Return type:
None
- log_line(level, message)[source]
- Parameters:
level (Literal['DEBUG', 'INFO', 'WARNING', 'ERROR'])
message (str)
- Return type:
None
- warning(message)[source]
- Parameters:
message (str)
- Return type:
None
- error(*, error_class, message, detail=None)[source]
- Parameters:
error_class (str)
message (str)
detail (dict[str, Any] | None)
- Return type:
None
- class sfmapi.backends.ObservationBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolRead observation sidecars from a backend feature/match store.
- read_keypoints(*, database_path, image_id)[source]
Read keypoints and descriptors for one image.
- Parameters:
database_path (Path)
image_id (int)
- Return type:
tuple[list[list[float]], bytes, int]
- iter_two_view_geometries(*, database_path)[source]
Yield verified two-view geometry rows.
- Parameters:
database_path (Path)
- Return type:
Iterator[tuple[int, int, Any]]
- iter_correspondences(*, database_path)[source]
Yield raw match correspondences.
- Parameters:
database_path (Path)
- Return type:
Iterator[tuple[int, int, Any]]
- class sfmapi.backends.ProgressReporter(*args, **kwargs)[source]
Bases:
ProtocolBest-effort sink for backend progress telemetry.
The reporter writes the existing
ProgressEventwire shape. It must never be required for backend correctness: implementations should tolerate reporter failures and keep the reconstruction work moving.- phase_started(phase)[source]
- Parameters:
phase (Literal['feature_extraction', 'matching', 'geometric_verification', 'incremental_init', 'incremental_register', 'incremental_ba', 'global_rotation_avg', 'global_positioning', 'global_ba', 'hierarchical_cluster', 'hierarchical_merge', 'panorama', 'spherical', 'bundle_adjust', 'triangulate', 'relocalize', 'pose_graph_optimize', 'segment', 'export', 'vlad_index', 'backend_action', 'artifact_conversion'])
- Return type:
None
- phase_progress(phase, *, current, total=None, rate=None)[source]
- Parameters:
phase (Literal['feature_extraction', 'matching', 'geometric_verification', 'incremental_init', 'incremental_register', 'incremental_ba', 'global_rotation_avg', 'global_positioning', 'global_ba', 'hierarchical_cluster', 'hierarchical_merge', 'panorama', 'spherical', 'bundle_adjust', 'triangulate', 'relocalize', 'pose_graph_optimize', 'segment', 'export', 'vlad_index', 'backend_action', 'artifact_conversion'])
current (int)
total (int | None)
rate (float | None)
- Return type:
None
- phase_completed(phase)[source]
- Parameters:
phase (Literal['feature_extraction', 'matching', 'geometric_verification', 'incremental_init', 'incremental_register', 'incremental_ba', 'global_rotation_avg', 'global_positioning', 'global_ba', 'hierarchical_cluster', 'hierarchical_merge', 'panorama', 'spherical', 'bundle_adjust', 'triangulate', 'relocalize', 'pose_graph_optimize', 'segment', 'export', 'vlad_index', 'backend_action', 'artifact_conversion'])
- Return type:
None
- metric(key, value)[source]
- Parameters:
key (str)
value (float)
- Return type:
None
- snapshot_available(*, snapshot_seq, summary)[source]
- Parameters:
snapshot_seq (int)
summary (dict[str, Any])
- Return type:
None
- log_line(level, message)[source]
- Parameters:
level (Literal['DEBUG', 'INFO', 'WARNING', 'ERROR'])
message (str)
- Return type:
None
- warning(message)[source]
- Parameters:
message (str)
- Return type:
None
- error(*, error_class, message, detail=None)[source]
- Parameters:
error_class (str)
message (str)
detail (dict[str, Any] | None)
- Return type:
None
- class sfmapi.backends.ReconstructionMergeBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolMulti-reconstruction merge helpers.
- merge_reconstructions(*, model_paths, output_path, sim3_aligners=None)[source]
Merge multiple sparse models into one output model.
- Parameters:
model_paths (list[Path])
output_path (Path)
sim3_aligners (Any)
- Return type:
dict[str, Any]
- class sfmapi.backends.ReconstructionReaderBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolRead a sparse model into a snapshot-emitter-compatible object.
- read_reconstruction(path)[source]
Return a duck-typed reconstruction object.
- Parameters:
path (Path)
- Return type:
Any
- class sfmapi.backends.RefinementBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolPortable refinement and model-edit stages.
- bundle_adjustment(*, model_path, output_path, spec)[source]
Run bundle adjustment.
- Parameters:
model_path (Path)
output_path (Path)
spec (dict[str, Any])
- Return type:
dict[str, Any]
- triangulate(*, model_path, database_path, image_root, output_path)[source]
Re-triangulate against an existing database.
- Parameters:
model_path (Path)
database_path (Path)
image_root (Path)
output_path (Path)
- Return type:
dict[str, Any]
- relocalize(*, model_path, database_path, image_root, output_path, image_ids)[source]
Register additional images into an existing reconstruction.
- Parameters:
model_path (Path)
database_path (Path)
image_root (Path)
output_path (Path)
image_ids (list[int])
- Return type:
dict[str, Any]
- pose_graph_optimize(*, model_path, output_path, spec)[source]
Run pose-graph optimization.
- Parameters:
model_path (Path)
output_path (Path)
spec (dict[str, Any])
- Return type:
dict[str, Any]
- class sfmapi.backends.RetrievalBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolImage retrieval and similarity helpers.
- build_vlad_index(*, image_paths_by_id, spec)[source]
Compute VLAD descriptors for a set of images.
- Parameters:
image_paths_by_id (dict[str, Path])
spec (dict[str, Any])
- Return type:
tuple[list[str], Any]
- class sfmapi.backends.SfmBackend(*args, **kwargs)[source]
Bases:
FeatureBackend,ObservationBackend,MappingBackend,RefinementBackend,ExportBackend,SphericalBackend,RetrievalBackend,LocalizationBackend,BatchLocalizationBackend,TransformBackend,ReconstructionReaderBackend,ReconstructionMergeBackend,ArtifactConversionBackend,ProtocolFull portable SfM backend protocol kept for complete engines.
New backend packages should usually target the smallest protocol layer they actually implement and expose native tools through backend actions where no portable stage contract exists.
- class sfmapi.backends.SphericalBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolSpherical/panorama conversion helpers.
- project_images(*, operation, input_image_path, output_path, spec)[source]
Run a portable image projection transform over a dataset.
- Parameters:
operation (str)
input_image_path (Path)
output_path (Path)
spec (dict[str, Any])
- Return type:
dict[str, Any]
- convert_spherical_to_cubemap(*, input_model_path, input_image_path, output_path)[source]
Convert a spherical reconstruction to a cubemap rig.
- Parameters:
input_model_path (Path)
input_image_path (Path)
output_path (Path)
- Return type:
dict[str, Any]
- render_spherical_cubemap_images(*, input_image_path, output_path, face_size=None)[source]
Render every panorama into six cubemap face images.
- Parameters:
input_image_path (Path)
output_path (Path)
face_size (int | None)
- Return type:
dict[str, Any]
- class sfmapi.backends.TransformBackend(*args, **kwargs)[source]
Bases:
Backend,ProtocolGeometry transform helpers.
- apply_sim3(*, model_path, output_path, sim3)[source]
Apply a Sim(3) similarity transform to a sparse model.
- Parameters:
model_path (Path)
output_path (Path)
sim3 (dict[str, Any])
- Return type:
dict[str, Any]
- sfmapi.backends.accepts_progress(call)[source]
Return true when
callcan receiveprogress=....Native-extension callables do not always expose inspectable signatures. In that case the safe compatibility choice is to omit the optional argument.
- Parameters:
call (Callable[[...], Any])
- Return type:
bool
- sfmapi.backends.assert_backend_action_contract(backend)[source]
Raise
AssertionErrorif a backend mixes capabilities and actions.- Parameters:
backend (Any)
- Return type:
None
- sfmapi.backends.assert_backend_artifact_contract(backend)[source]
- Parameters:
backend (Any)
- Return type:
None
- sfmapi.backends.assert_backend_config_contract(backend)[source]
Raise
AssertionErrorif backend option schemas are malformed.- Parameters:
backend (Any)
- Return type:
None
- sfmapi.backends.assert_backend_contract(backend)[source]
Raise
AssertionErrorif backend extension metadata is unsafe.- Parameters:
backend (Any)
- Return type:
None
- sfmapi.backends.backend_action_contract_violations(backend)[source]
Return backend action contract violations for backend authors.
Backend packages can use this in their own test suites:
from app.adapters.backend_actions import assert_backend_action_contract def test_backend_contract(): assert_backend_action_contract(MyBackend())
This catches the most common extension-surface mistake: putting backend-native action ids such as
vendor.toolintocapabilities()instead of exposing them throughlist_backend_actions().- Parameters:
backend (Any)
- Return type:
list[str]
- sfmapi.backends.backend_artifact_contract_violations(backend)[source]
- Parameters:
backend (Any)
- Return type:
list[str]
- sfmapi.backends.backend_capability_contract_violations(backend)[source]
Return capability-specific contract violations for backend authors.
- Parameters:
backend (Any)
- Return type:
list[str]
- sfmapi.backends.backend_config_contract_violations(backend)[source]
Return backend config-schema contract violations for backend authors.
- Parameters:
backend (Any)
- Return type:
list[str]
- sfmapi.backends.backend_contract_violations(backend)[source]
Return all extension-contract violations for a backend.
- Parameters:
backend (Any)
- Return type:
list[str]
- sfmapi.backends.call_with_optional_progress(call, *, progress, **kwargs)[source]
Call a backend method, adding
progressonly when supported.- Parameters:
call (Callable[[...], Any])
progress (ProgressReporter | None)
kwargs (Any)
- Return type:
Any
- sfmapi.backends.get_backend(name=None)[source]
Resolve and instantiate the configured backend.
nameoverrides the env var when set (mostly for tests). RaisesKeyErrorif no backend is registered under the resolved name — sfmapi ships no default implementation, so the caller (or test fixture, or app-startup hook) must register one before workers can run.- Parameters:
name (str | None)
- Return type:
Backend
- sfmapi.backends.get_backend_action(action_id, backend=None)[source]
Read one normalized action descriptor with its schema.
- Parameters:
action_id (str)
backend (Any | None)
- Return type:
dict[str, Any]
- sfmapi.backends.get_backend_artifact_contract(contract_id, backend=None)[source]
- Parameters:
contract_id (str)
backend (Any | None)
- Return type:
dict[str, Any]
- sfmapi.backends.get_backend_config_schema(config_id, backend=None)[source]
- Parameters:
config_id (str)
backend (Any | None)
- Return type:
dict[str, Any]
- sfmapi.backends.has_backend_actions(backend=None)[source]
Cheap capability probe for the public capabilities envelope.
- Parameters:
backend (Any | None)
- Return type:
bool
- sfmapi.backends.has_backend_artifact_contracts(backend=None)[source]
- Parameters:
backend (Any | None)
- Return type:
bool
- sfmapi.backends.has_backend_config_schemas(backend=None)[source]
- Parameters:
backend (Any | None)
- Return type:
bool
- sfmapi.backends.has_backend_method(backend, method_name)[source]
Return whether
backendexposes a callable method.- Parameters:
backend (object)
method_name (str)
- Return type:
bool
- sfmapi.backends.list_backend_actions(backend=None, *, include_schemas=False)[source]
List normalized backend action descriptors.
- Parameters:
backend (Any | None)
include_schemas (bool)
- Return type:
list[dict[str, Any]]
- sfmapi.backends.list_backend_artifact_contracts(backend=None)[source]
- Parameters:
backend (Any | None)
- Return type:
list[dict[str, Any]]
- sfmapi.backends.list_backend_config_schemas(backend=None, *, include_schemas=True)[source]
List normalized backend-specific option schemas.
- Parameters:
backend (Any | None)
include_schemas (bool)
- Return type:
list[dict[str, Any]]
- sfmapi.backends.list_backends()[source]
- Return type:
list[str]
- sfmapi.backends.register_backend(name, factory)[source]
Register a backend factory. Re-registering an existing name overwrites it (useful for tests).
- Parameters:
name (str)
factory (Callable[[], Backend])
- Return type:
None
- sfmapi.backends.require_backend_method(backend, method_name, *, capability, reason=None)[source]
Return a backend method or raise a clean capability error.
This is the guard portable workers use before calling optional protocol surfaces. It lets action-only or artifact-only backends omit unsupported methods entirely while preserving sfmapi’s normal 501 response semantics.
- Parameters:
backend (object)
method_name (str)
capability (str)
reason (str | None)
- Return type:
Callable[[…], Any]
- sfmapi.backends.run_backend_action(action_id, inputs, *, workspace=None, progress=None, backend=None)[source]
Execute an action through the backend implementation.
- Parameters:
action_id (str)
inputs (dict[str, Any])
workspace (Path | None)
progress (Any | None)
backend (Any | None)
- Return type:
dict[str, Any]
- sfmapi.backends.validate_backend_action(action_id, inputs, backend=None)[source]
Validate input for one action without submitting work.
- Parameters:
action_id (str)
inputs (dict[str, Any])
backend (Any | None)
- Return type:
dict[str, Any]
- sfmapi.backends.validate_backend_options(*, stage, options, capability=None, provider=None, backend=None)[source]
Validate one stage’s
backend_optionsif the backend exposes a schema.Backends may omit schemas; in that case sfmapi passes options through and the backend remains the source of truth. When a schema is available, sfmapi catches unknown keys and simple type mistakes before creating a job.
- Parameters:
stage (str)
options (dict[str, Any] | None)
capability (str | None)
provider (str | None)
backend (Any | None)
- Return type:
dict[str, Any]
Runtime hooks for embedding sfmapi with backend plugins.
- sfmapi.runtime.create_app()[source]
Create the FastAPI app without side effects at
sfmapi.runtimeimport time.- Return type:
FastAPI
- sfmapi.runtime.get_backend(name=None)[source]
Resolve and instantiate the configured backend.
nameoverrides the env var when set (mostly for tests). RaisesKeyErrorif no backend is registered under the resolved name — sfmapi ships no default implementation, so the caller (or test fixture, or app-startup hook) must register one before workers can run.- Parameters:
name (str | None)
- Return type:
Backend
- sfmapi.runtime.list_backends()[source]
- Return type:
list[str]
- sfmapi.runtime.load_installed_plugins()[source]
Load installed backend entry points into the process-local registry.
- Return type:
list[Any]
- sfmapi.runtime.register_backend(name, factory)[source]
Register a backend factory. Re-registering an existing name overwrites it (useful for tests).
- Parameters:
name (str)
factory (Callable[[], Backend])
- Return type:
None
- sfmapi.runtime.register_plugin(plugin)[source]
Register one plugin object with the process-local backend registry.
- Parameters:
plugin (BackendPlugin)
- Return type:
None
Stable exception classes for sfmapi extensions.
- exception sfmapi.errors.BadRequestError(detail='', **extras)[source]
Bases:
SfmApiError400 — request couldn’t be parsed or violates a non-schema invariant.
Use
ValidationError(422) when the request shape is well-formed but a field value is wrong; use this when the request couldn’t even be interpreted (e.g., malformed Content-Range, conflicting query params).- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 400
- error_type: str = 'bad_request'
- title: str = 'Bad request'
- exception sfmapi.errors.CapabilityUnavailableError(*, capability, reason='')[source]
Bases:
SfmApiErrorThe requested SfM feature isn’t supported by the current backend.
Returns
501 Not Implementedrather than 5xx because the request itself is well-formed and the server is healthy — it just doesn’t expose the requested capability. Thecapabilityextra carries the canonical feature name (seeapp.core.capabilities) so clients can correlate withGET /v1/capabilities.- Parameters:
capability (str)
reason (str)
- Return type:
None
- status_code: int = 501
- error_type: str = 'capability_unavailable'
- title: str = 'Capability not available in this deployment'
- exception sfmapi.errors.ConflictError(detail='', **extras)[source]
Bases:
SfmApiError409 — the request conflicts with the current resource state.
Use for optimistic-concurrency / state-machine violations (e.g., finalizing an upload that’s already finalized, deleting a project with active jobs). Use
ValidationError(422) when the request itself is wrong; use this when the request would be valid against a different server state.- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 409
- error_type: str = 'conflict'
- title: str = 'Conflict'
- exception sfmapi.errors.NotFoundError(detail='', **extras)[source]
Bases:
SfmApiError404 — the addressed resource doesn’t exist for this tenant.
Routes MUST raise this rather than returning
Noneso the failure shows up asapplication/problem+json. Tenant scoping is implicit: a row that exists under a different tenant looks like 404 to the caller (seeL2— multi-tenant boundary).- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 404
- error_type: str = 'not_found'
- title: str = 'Resource not found'
- exception sfmapi.errors.PycolmapUnavailableError(reason='')[source]
Bases:
CapabilityUnavailableErrorBackwards-compat: the colmap_mod backend can’t load pycolmap.
Subclass of
CapabilityUnavailableErrorso callers that catch the parent see this too. Status code stays 501 — the failure is the same shape (a capability the deployment doesn’t expose), even though the reason is backend-specific.- Parameters:
reason (str)
- Return type:
None
- error_type: str = 'pycolmap_unavailable'
- title: str = 'pycolmap not available in this deployment'
- exception sfmapi.errors.QuotaExceededError(detail='', **extras)[source]
Bases:
SfmApiError429 — caller hit a per-tenant or per-request rate / size cap.
Currently fires on oneshot request-body caps (
oneshot_max_request_bytes); Phase 5 plumbs in fair-share scheduling + per-tenant job quotas through this same error. SDK ergonomics shims interpret 429 as retryable whenretry_afteris set.- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 429
- error_type: str = 'quota_exceeded'
- title: str = 'Quota exceeded'
- exception sfmapi.errors.SfmApiError(detail='', **extras)[source]
Bases:
ExceptionBase class for every domain error sfmapi raises.
Subclasses MUST set
status_code(HTTP) anderror_type(the slug used to buildtype: https://sfmapi.github.io/errors/<slug>in the RFC 7807 envelope). The FastAPI exception handler inapp/main.py::sfmapi_error_handlerturns these intoapplication/problem+jsonresponses; never raise rawHTTPExceptionfrom services — keep the wire shape consistent.Free-form
extrasare merged into the envelope as top-level keys (capabilityon 501,retry_afteron 429); see the typed surface inProblemResponse.- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 500
- error_type: str = 'internal'
- title: str = 'Internal error'
- as_problem(instance=None)[source]
- Parameters:
instance (str | None)
- Return type:
dict[str, Any]
- exception sfmapi.errors.StorageError(detail='', **extras)[source]
Bases:
SfmApiError507 Insufficient Storage — the backing store rejected a write.
Used for blob-store write failures, snapshot rename collisions, workspace-out-of-space conditions. Distinct from a generic 500: the request itself was valid, the storage layer couldn’t hold it.
- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 507
- error_type: str = 'storage'
- title: str = 'Storage error'
- exception sfmapi.errors.TenantViolationError(detail='', **extras)[source]
Bases:
SfmApiError403 — tenant scoping was bypassed or auth resolution failed.
Raised by
app.core.tenancy.current_tenant()when the Authorization header is missing / unrecognized, and by repository helpers that detect a tenant_id mismatch. SeeL2indecisions.md(multi-tenant from day 1,defaultuntil auth lands). Once real auth ships, 401 (missing) and 403 (rejected) will split — for now both surface here.- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 403
- error_type: str = 'tenant_violation'
- title: str = 'Tenant boundary violation'
- exception sfmapi.errors.ValidationError(detail='', **extras)[source]
Bases:
SfmApiError422 — semantic validation failed after parsing succeeded.
Distinct from FastAPI’s
fastapi.RequestValidationError(Pydantic schema-shape failures): this fires from inside services when a value is well-typed but rejected on a domain rule (cross-field consistency, foreign-key lookup, plausibility). Both paths emit the same RFC 7807problem+jsonshape — seeL19for the structurederrors[]invariant.- Parameters:
detail (str)
extras (Any)
- Return type:
None
- status_code: int = 422
- error_type: str = 'validation'
- title: str = 'Validation error'
Stub full backend used by tests + ephemeral mode.
sfmapi ships no real SfM engine; the wire surface and orchestration shell live in this repo, while engine implementations (pycolmap, OpenSfM, hloc, custom forks) live in separate packages. This module provides a no-op stub that satisfies the protocol structurally — useful for:
unit / integration / contract tests that exercise routing, scheduling, snapshot writing, etc., without needing a real engine,
the
SFMAPI_EPHEMERAL=trueself-contained demo runtime, which registers it on lifespan startup,SDK live tests that boot the app in a subprocess.
Most operations raise CapabilityUnavailableError — only
capabilities() and trivial probes return real values. Production
deployments register a real backend via
app.adapters.registry.register_backend().
- class app.adapters.stub_backend.StubBackend[source]
Bases:
objectNo-op stub satisfying the full
SfmBackendunion.- name = 'stub'
- version = '0.0.1'
- vendor = 'test'
- capabilities()[source]
- Return type:
set[str]
- extract_features(*, database_path, image_root, image_list, options)[source]
- Parameters:
database_path (Path)
image_root (Path)
image_list (list[str])
options (dict)
- Return type:
dict
- match(*, database_path, mode, options)[source]
- Parameters:
database_path (Path)
mode (str)
options (dict)
- Return type:
dict
- verify_matches(*, database_path, options)[source]
- Parameters:
database_path (Path)
options (dict)
- Return type:
dict
- read_keypoints(**_)[source]
- Parameters:
_ (Any)
- Return type:
tuple[list[list[float]], bytes, int]
- iter_two_view_geometries(*, database_path)[source]
- Parameters:
database_path (Path)
- Return type:
Iterator
- iter_correspondences(*, database_path)[source]
- Parameters:
database_path (Path)
- Return type:
Iterator
- run_mapping(**_)[source]
- Parameters:
_ (Any)
- Return type:
tuple[list[dict], list[Any]]
- bundle_adjustment(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- triangulate(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- relocalize(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- pose_graph_optimize(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- export(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- convert_spherical_to_cubemap(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- project_images(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- render_spherical_cubemap_images(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- build_vlad_index(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- convert_artifact(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- localize_from_memory(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- apply_sim3(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- merge_reconstructions(**_)[source]
- Parameters:
_ (Any)
- Return type:
dict
- localize_batch(**_)[source]
- Parameters:
_ (Any)
- Return type:
list
- read_reconstruction(path)[source]
- Parameters:
path (Path)
- Return type:
Any
- runtime_versions()[source]
- Return type:
dict[str, str]