Coming soon/api/reference/

API reference.

The public surface is intentionally small, but it exposes the control points users need: config fields, organizer methods, staged functions, return objects, callbacks, and provider protocols.

Python API status: coming soon.

These docs describe the intended package surface. Do not treat the PyPI install path as live until the package, wheel metadata, and import surface are verified. For now, use the CLI from source.

SortMomentsConfig

The config object is the control panel for the default pipeline. Defaults match the app/CLI pipeline.

FieldDefaultWhy change it?
min_face_size80Raise for high-res albums to ignore tiny background faces.
min_confidence0.8Raise for precision, lower if the model misses hard angles.
min_face_ratio0.01Filters faces that are tiny relative to the image.
foreground_ratio_threshold0.1Keeps faces that matter compared with the largest face.
blur_threshold60Raise to reject soft crops; lower for old/noisy albums.
similarity_threshold0.5Higher makes groups stricter; lower merges more aggressively.
batch_size8Tune memory and throughput.
max_workers4Parallel image loading workers.
final_output_folderNoneChoose exact final destination.
session_idNoneKeep multiple runs side by side.
keep_intermediateFalseKeep face crops/embeddings for debugging.

Performance and model fields

SortMomentsConfig(
    prefer_gpu=True,
    model_name="buffalo_l",
    det_size=(640, 640),
    batch_size=8,
    max_workers=4,
)
  • prefer_gpu=False forces CPU execution.
  • model_name is passed to InsightFace model-pack loading.
  • det_size trades speed and detection sensitivity.

organize_photos()

organize_photos(
    input_folder,
    work_folder=None,
    config=None,
    face_model=None,
    embedding_model=None,
    grouping_model=None,
    progress_callback=None,
) -> OrganizationResult

SortMomentsOrganizer

Reusable pipeline wrapper. It stores config, injected models, and callback once.

organizer = SortMomentsOrganizer(
    config=SortMomentsConfig(similarity_threshold=0.58),
    face_model=None,
    embedding_model=None,
    grouping_model=None,
    progress_callback=None,
)

result = organizer.organize("D:/photos/family")
embeddings = organizer.detect_faces("D:/photos/family", "D:/cache/faces")
people, folder = organizer.group_faces("D:/cache/faces", input_folder="D:/photos/family")

detect_faces() and group_faces()

detect_faces(input_folder, output_folder, ...)

Writes face crops and face_embeddings_insightface.pkl. Accepts face_model and embedding_model.

group_faces(intermediate_folder, ...)

Reads embeddings and writes final person folders. Accepts grouping_model.

OrganizationResult

AttributeTypeMeaning
personsMapping[str, Sequence[str]]Person folder id to original photo paths.
output_folderPathFinal organized folder.
embeddings_filePathIntermediate embeddings pickle path.
person_countintNumber of groups created.
face_countintNumber of face records used.

ProgressCallback

def callback(current: int, total: int, message: str) -> None:
    ...

Callbacks should stay quick. If you are updating a UI or remote job record, push work onto your own queue.

Provider protocols

class FaceModel:
    def get(self, image_rgb):
        # Return face objects with bbox, det_score, and optionally embedding.

class EmbeddingModel:
    def embed(self, image_rgb, face):
        # Return one embedding vector for a detected face.

class GroupingModel:
    def group(self, face_records, similarity_threshold=0.5):
        # Return {person_id: [FaceRecord or face_path, ...]}.