simple-module-images 0.0.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- simple_module_images-0.0.14/.gitignore +57 -0
- simple_module_images-0.0.14/NOTICE +61 -0
- simple_module_images-0.0.14/PKG-INFO +202 -0
- simple_module_images-0.0.14/README.md +160 -0
- simple_module_images-0.0.14/docs/access.md +196 -0
- simple_module_images-0.0.14/docs/code-layout.md +61 -0
- simple_module_images-0.0.14/docs/imports.md +224 -0
- simple_module_images-0.0.14/docs/index.md +227 -0
- simple_module_images-0.0.14/docs/migrating-from-portal.md +139 -0
- simple_module_images-0.0.14/docs/pipeline.md +406 -0
- simple_module_images-0.0.14/docs/worker.md +251 -0
- simple_module_images-0.0.14/docs/writing-a-plugin.md +268 -0
- simple_module_images-0.0.14/package.json +31 -0
- simple_module_images-0.0.14/pyproject.toml +120 -0
- simple_module_images-0.0.14/sm_images/__init__.py +7 -0
- simple_module_images-0.0.14/sm_images/contracts/__init__.py +78 -0
- simple_module_images-0.0.14/sm_images/contracts/events.py +86 -0
- simple_module_images-0.0.14/sm_images/contracts/reads.py +145 -0
- simple_module_images-0.0.14/sm_images/contracts/schemas.py +93 -0
- simple_module_images-0.0.14/sm_images/core/__init__.py +5 -0
- simple_module_images-0.0.14/sm_images/core/access/__init__.py +275 -0
- simple_module_images-0.0.14/sm_images/core/access/redaction.py +173 -0
- simple_module_images-0.0.14/sm_images/core/access/resource_types.py +66 -0
- simple_module_images-0.0.14/sm_images/core/access/starter_right.py +81 -0
- simple_module_images-0.0.14/sm_images/core/access/write.py +91 -0
- simple_module_images-0.0.14/sm_images/core/billing/__init__.py +203 -0
- simple_module_images-0.0.14/sm_images/core/billing/install.py +206 -0
- simple_module_images-0.0.14/sm_images/core/billing/metering_keys.py +27 -0
- simple_module_images-0.0.14/sm_images/core/billing/ops.py +275 -0
- simple_module_images-0.0.14/sm_images/core/billing/repair.py +224 -0
- simple_module_images-0.0.14/sm_images/core/billing/repair_cursor.py +100 -0
- simple_module_images-0.0.14/sm_images/core/billing/settle.py +211 -0
- simple_module_images-0.0.14/sm_images/core/billing/subject.py +156 -0
- simple_module_images-0.0.14/sm_images/core/clock/__init__.py +17 -0
- simple_module_images-0.0.14/sm_images/core/clock/db.py +43 -0
- simple_module_images-0.0.14/sm_images/core/constants.py +277 -0
- simple_module_images-0.0.14/sm_images/core/errors.py +199 -0
- simple_module_images-0.0.14/sm_images/core/events.py +82 -0
- simple_module_images-0.0.14/sm_images/core/settings/__init__.py +141 -0
- simple_module_images-0.0.14/sm_images/core/settings/boot.py +49 -0
- simple_module_images-0.0.14/sm_images/core/storage/__init__.py +145 -0
- simple_module_images-0.0.14/sm_images/core/storage/intents.py +73 -0
- simple_module_images-0.0.14/sm_images/core/storage/keys.py +71 -0
- simple_module_images-0.0.14/sm_images/core/tenancy/__init__.py +263 -0
- simple_module_images-0.0.14/sm_images/core/tenancy/_guard.py +100 -0
- simple_module_images-0.0.14/sm_images/core/tenancy/_mode.py +273 -0
- simple_module_images-0.0.14/sm_images/core/tenancy/request_context.py +50 -0
- simple_module_images-0.0.14/sm_images/index.ts +11 -0
- simple_module_images-0.0.14/sm_images/ingest/__init__.py +23 -0
- simple_module_images-0.0.14/sm_images/ingest/_holds_host.py +30 -0
- simple_module_images-0.0.14/sm_images/ingest/admission.py +148 -0
- simple_module_images-0.0.14/sm_images/ingest/b64.py +40 -0
- simple_module_images-0.0.14/sm_images/ingest/dedupe.py +122 -0
- simple_module_images-0.0.14/sm_images/ingest/direct.py +247 -0
- simple_module_images-0.0.14/sm_images/ingest/guards.py +106 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/__init__.py +1 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/access.py +106 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/beat.py +85 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/chunk.py +216 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/claims.py +71 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/cleanup.py +132 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/controls.py +194 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/dns.py +115 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/download.py +195 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/errors.py +27 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/features.py +212 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/fetch.py +252 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/filename_pattern.py +138 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/geojson_stream.py +173 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/item_claim.py +140 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/item_errors.py +93 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/jobs.py +244 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/launch.py +80 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/log_redact.py +70 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/lookup.py +63 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/manage_right.py +82 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/mapping.py +73 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/netsafe.py +100 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/rate_limit.py +144 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/recover.py +261 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/reset.py +159 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/retrying.py +188 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/runner.py +229 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/service.py +132 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/settle.py +279 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/stage.py +82 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/staging.py +158 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/tasks.py +60 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/terminal.py +178 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/url_safety.py +181 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/values.py +165 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_abort.py +47 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_entries.py +126 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_eocd.py +83 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_import.py +241 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_metadata.py +70 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_safety.py +252 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_source.py +127 -0
- simple_module_images-0.0.14/sm_images/ingest/imports/zip_upload.py +260 -0
- simple_module_images-0.0.14/sm_images/ingest/meta.py +137 -0
- simple_module_images-0.0.14/sm_images/ingest/multipart.py +165 -0
- simple_module_images-0.0.14/sm_images/ingest/service.py +238 -0
- simple_module_images-0.0.14/sm_images/ingest/service_holds.py +67 -0
- simple_module_images-0.0.14/sm_images/ingest/slots.py +194 -0
- simple_module_images-0.0.14/sm_images/ingest/sniff.py +50 -0
- simple_module_images-0.0.14/sm_images/ingest/ticket.py +92 -0
- simple_module_images-0.0.14/sm_images/ingest/upload_reaper.py +111 -0
- simple_module_images-0.0.14/sm_images/ingest/upload_session.py +220 -0
- simple_module_images-0.0.14/sm_images/jobs/__init__.py +1 -0
- simple_module_images-0.0.14/sm_images/jobs/janitor.py +256 -0
- simple_module_images-0.0.14/sm_images/jobs/phases.py +52 -0
- simple_module_images-0.0.14/sm_images/jobs/placeholders.py +78 -0
- simple_module_images-0.0.14/sm_images/jobs/purge.py +222 -0
- simple_module_images-0.0.14/sm_images/jobs/purge_delete.py +121 -0
- simple_module_images-0.0.14/sm_images/jobs/purge_select.py +241 -0
- simple_module_images-0.0.14/sm_images/jobs/reconcile.py +204 -0
- simple_module_images-0.0.14/sm_images/jobs/reconcile_dispatch.py +121 -0
- simple_module_images-0.0.14/sm_images/jobs/regroup/__init__.py +1 -0
- simple_module_images-0.0.14/sm_images/jobs/regroup/control.py +103 -0
- simple_module_images-0.0.14/sm_images/jobs/regroup/jobs.py +257 -0
- simple_module_images-0.0.14/sm_images/jobs/regroup/runner.py +103 -0
- simple_module_images-0.0.14/sm_images/locales/de.json +682 -0
- simple_module_images-0.0.14/sm_images/locales/en.json +682 -0
- simple_module_images-0.0.14/sm_images/map/__init__.py +15 -0
- simple_module_images-0.0.14/sm_images/map/build.py +223 -0
- simple_module_images-0.0.14/sm_images/map/objects.py +33 -0
- simple_module_images-0.0.14/sm_images/map/pmtiles_build.py +147 -0
- simple_module_images-0.0.14/sm_images/map/points.py +136 -0
- simple_module_images-0.0.14/sm_images/map/recover.py +56 -0
- simple_module_images-0.0.14/sm_images/map/revoke.py +121 -0
- simple_module_images-0.0.14/sm_images/map/schedule.py +208 -0
- simple_module_images-0.0.14/sm_images/map/style.py +71 -0
- simple_module_images-0.0.14/sm_images/map/tasks.py +35 -0
- simple_module_images-0.0.14/sm_images/models/__init__.py +66 -0
- simple_module_images-0.0.14/sm_images/models/_base.py +14 -0
- simple_module_images-0.0.14/sm_images/models/_cols.py +56 -0
- simple_module_images-0.0.14/sm_images/models/billing_op.py +84 -0
- simple_module_images-0.0.14/sm_images/models/collection.py +82 -0
- simple_module_images-0.0.14/sm_images/models/enums.py +88 -0
- simple_module_images-0.0.14/sm_images/models/group.py +25 -0
- simple_module_images-0.0.14/sm_images/models/image.py +120 -0
- simple_module_images-0.0.14/sm_images/models/import_item.py +51 -0
- simple_module_images-0.0.14/sm_images/models/import_job.py +71 -0
- simple_module_images-0.0.14/sm_images/models/object_intent.py +35 -0
- simple_module_images-0.0.14/sm_images/models/pipeline_restart.py +37 -0
- simple_module_images-0.0.14/sm_images/models/prompt.py +93 -0
- simple_module_images-0.0.14/sm_images/models/regroup_job.py +94 -0
- simple_module_images-0.0.14/sm_images/models/rendition.py +30 -0
- simple_module_images-0.0.14/sm_images/models/step_run.py +50 -0
- simple_module_images-0.0.14/sm_images/models/upload_admission.py +33 -0
- simple_module_images-0.0.14/sm_images/models/upload_session.py +59 -0
- simple_module_images-0.0.14/sm_images/module.py +245 -0
- simple_module_images-0.0.14/sm_images/pagebuilder-blocks.ts +43 -0
- simple_module_images-0.0.14/sm_images/pages/Collection.tsx +254 -0
- simple_module_images-0.0.14/sm_images/pages/Collections.tsx +75 -0
- simple_module_images-0.0.14/sm_images/pages/Image.tsx +111 -0
- simple_module_images-0.0.14/sm_images/pages/PublicCollection.tsx +72 -0
- simple_module_images-0.0.14/sm_images/pages/Review.tsx +190 -0
- simple_module_images-0.0.14/sm_images/pipeline/__init__.py +91 -0
- simple_module_images-0.0.14/sm_images/pipeline/advance.py +196 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/__init__.py +21 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/codes.py +46 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/cross_check.py +138 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/group_inputs.py +103 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/group_lease.py +189 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/group_load.py +179 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/group_members.py +159 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/group_request.py +145 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/group_run.py +221 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/group_store.py +78 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/prompt_steps.py +171 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/reads.py +51 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/results.py +193 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/review.py +150 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/run.py +191 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/runner.py +158 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/schema_model.py +172 -0
- simple_module_images-0.0.14/sm_images/pipeline/ai/schema_safety.py +221 -0
- simple_module_images-0.0.14/sm_images/pipeline/builtin_steps.py +103 -0
- simple_module_images-0.0.14/sm_images/pipeline/claim.py +250 -0
- simple_module_images-0.0.14/sm_images/pipeline/config.py +214 -0
- simple_module_images-0.0.14/sm_images/pipeline/control.py +163 -0
- simple_module_images-0.0.14/sm_images/pipeline/cycle.py +113 -0
- simple_module_images-0.0.14/sm_images/pipeline/eager_drain.py +70 -0
- simple_module_images-0.0.14/sm_images/pipeline/executor.py +218 -0
- simple_module_images-0.0.14/sm_images/pipeline/extensions.py +122 -0
- simple_module_images-0.0.14/sm_images/pipeline/finish.py +243 -0
- simple_module_images-0.0.14/sm_images/pipeline/keeper.py +17 -0
- simple_module_images-0.0.14/sm_images/pipeline/load.py +135 -0
- simple_module_images-0.0.14/sm_images/pipeline/orchestrate.py +203 -0
- simple_module_images-0.0.14/sm_images/pipeline/plan.py +237 -0
- simple_module_images-0.0.14/sm_images/pipeline/presets.py +102 -0
- simple_module_images-0.0.14/sm_images/pipeline/processing/__init__.py +1 -0
- simple_module_images-0.0.14/sm_images/pipeline/processing/exif.py +147 -0
- simple_module_images-0.0.14/sm_images/pipeline/processing/heif.py +28 -0
- simple_module_images-0.0.14/sm_images/pipeline/processing/renditions.py +58 -0
- simple_module_images-0.0.14/sm_images/pipeline/publish.py +222 -0
- simple_module_images-0.0.14/sm_images/pipeline/registry.py +247 -0
- simple_module_images-0.0.14/sm_images/pipeline/reopen.py +84 -0
- simple_module_images-0.0.14/sm_images/pipeline/restart.py +165 -0
- simple_module_images-0.0.14/sm_images/pipeline/runtime.py +129 -0
- simple_module_images-0.0.14/sm_images/pipeline/step.py +152 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/__init__.py +1 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/anonymize/__init__.py +19 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/anonymize/blur.py +72 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/anonymize/detectors.py +138 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/anonymize/models.py +229 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/anonymize/step.py +200 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/anonymize/weights.py +191 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/classify.py +111 -0
- simple_module_images-0.0.14/sm_images/pipeline/steps/quality.py +115 -0
- simple_module_images-0.0.14/sm_images/pipeline/storage_hold.py +229 -0
- simple_module_images-0.0.14/sm_images/pipeline/worker_runtime.py +196 -0
- simple_module_images-0.0.14/sm_images/task_config.py +65 -0
- simple_module_images-0.0.14/sm_images/tasks.py +179 -0
- simple_module_images-0.0.14/sm_images/ui/components/ChipGroup.tsx +39 -0
- simple_module_images-0.0.14/sm_images/ui/components/ConfirmDialog.tsx +90 -0
- simple_module_images-0.0.14/sm_images/ui/components/ImagesLayout.tsx +9 -0
- simple_module_images-0.0.14/sm_images/ui/components/block/ImageGalleryBlock.test.tsx +191 -0
- simple_module_images-0.0.14/sm_images/ui/components/block/ImageGalleryBlock.tsx +118 -0
- simple_module_images-0.0.14/sm_images/ui/components/block/ImageStatsBlock.test.tsx +210 -0
- simple_module_images-0.0.14/sm_images/ui/components/block/ImageStatsBlock.tsx +106 -0
- simple_module_images-0.0.14/sm_images/ui/components/block/ImageStatsRender.tsx +118 -0
- simple_module_images-0.0.14/sm_images/ui/components/collections/CollectionCard.tsx +32 -0
- simple_module_images-0.0.14/sm_images/ui/components/collections/CreateCollectionDialog.tsx +126 -0
- simple_module_images-0.0.14/sm_images/ui/components/collections/PublicLink.tsx +42 -0
- simple_module_images-0.0.14/sm_images/ui/components/collections/VisibilitySelect.tsx +42 -0
- simple_module_images-0.0.14/sm_images/ui/components/gallery/Gallery.tsx +105 -0
- simple_module_images-0.0.14/sm_images/ui/components/gallery/GalleryTile.tsx +62 -0
- simple_module_images-0.0.14/sm_images/ui/components/gallery/UploadButton.tsx +81 -0
- simple_module_images-0.0.14/sm_images/ui/components/groups/GroupCard.tsx +95 -0
- simple_module_images-0.0.14/sm_images/ui/components/groups/GroupForm.tsx +81 -0
- simple_module_images-0.0.14/sm_images/ui/components/groups/GroupsTab.tsx +116 -0
- simple_module_images-0.0.14/sm_images/ui/components/groups/MemberThumb.tsx +36 -0
- simple_module_images-0.0.14/sm_images/ui/components/groups/RegroupPanel.tsx +159 -0
- simple_module_images-0.0.14/sm_images/ui/components/imports/ImportFailures.tsx +54 -0
- simple_module_images-0.0.14/sm_images/ui/components/imports/ImportWizard.tsx +261 -0
- simple_module_images-0.0.14/sm_images/ui/components/imports/ImportsTab.tsx +70 -0
- simple_module_images-0.0.14/sm_images/ui/components/imports/JobRow.tsx +157 -0
- simple_module_images-0.0.14/sm_images/ui/components/imports/JobRowFailures.test.tsx +66 -0
- simple_module_images-0.0.14/sm_images/ui/components/imports/MappingFields.tsx +98 -0
- simple_module_images-0.0.14/sm_images/ui/components/imports/PreviewSummary.tsx +68 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/CollectionMap.test.tsx +115 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/CollectionMap.tsx +98 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/MapCanvas.test.tsx +229 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/MapCanvas.tsx +214 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/mapRevision.test.ts +23 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/mapRevision.ts +15 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/mapSource.test.ts +138 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/mapSource.ts +101 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/mapWorker.test.ts +24 -0
- simple_module_images-0.0.14/sm_images/ui/components/map/mapWorker.ts +22 -0
- simple_module_images-0.0.14/sm_images/ui/components/pipeline/ParamsForm.tsx +246 -0
- simple_module_images-0.0.14/sm_images/ui/components/pipeline/PipelineTab.tsx +271 -0
- simple_module_images-0.0.14/sm_images/ui/components/pipeline/StepCard.tsx +103 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/GroupResults.tsx +128 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/PresetPicker.tsx +85 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/PromptForm.tsx +196 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/PromptRow.tsx +169 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/PromptsTab.tsx +178 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/RunConfirm.tsx +79 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/RunOnImages.tsx +113 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/SchemaEditor.tsx +122 -0
- simple_module_images-0.0.14/sm_images/ui/components/prompts/SchemaFieldBuilder.tsx +139 -0
- simple_module_images-0.0.14/sm_images/ui/components/public/Lightbox.test.tsx +74 -0
- simple_module_images-0.0.14/sm_images/ui/components/public/Lightbox.tsx +78 -0
- simple_module_images-0.0.14/sm_images/ui/components/public/PublicGallery.test.tsx +71 -0
- simple_module_images-0.0.14/sm_images/ui/components/public/PublicGallery.tsx +138 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/GenericResultView.test.tsx +71 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/GenericResultView.tsx +61 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/PromptAnswer.test.tsx +58 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/PromptAnswer.tsx +54 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/ResultView.tsx +13 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/plugins.ts +14 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/registry.test.tsx +90 -0
- simple_module_images-0.0.14/sm_images/ui/components/results/registry.ts +55 -0
- simple_module_images-0.0.14/sm_images/ui/components/review/CorrectionForm.tsx +187 -0
- simple_module_images-0.0.14/sm_images/ui/components/review/ReviewPanel.tsx +136 -0
- simple_module_images-0.0.14/sm_images/ui/components/share/ShareDialog.tsx +155 -0
- simple_module_images-0.0.14/sm_images/ui/components/viewer/GroupEditor.tsx +170 -0
- simple_module_images-0.0.14/sm_images/ui/components/viewer/ImageMeta.tsx +86 -0
- simple_module_images-0.0.14/sm_images/ui/components/viewer/ImageViewer.tsx +85 -0
- simple_module_images-0.0.14/sm_images/ui/components/viewer/NeighborNav.tsx +74 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useCollections.ts +21 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useCursorList.ts +90 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useGeoJsonPreview.ts +37 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useGroups.ts +42 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useImages.ts +47 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useImportJobs.ts +99 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/usePipelinePoll.ts +57 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/usePromptResults.ts +121 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useRegroupJob.test.tsx +89 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useRegroupJob.ts +71 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useReviewKeys.ts +43 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useReviewQueue.ts +148 -0
- simple_module_images-0.0.14/sm_images/ui/hooks/useShares.ts +83 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/Collection.test.tsx +175 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/CollectionMapTab.test.tsx +69 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/CollectionPublicLink.test.tsx +53 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/Collections.test.tsx +66 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/GroupResults.test.tsx +280 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/GroupsEdit.test.tsx +233 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/GroupsTab.test.tsx +103 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/Image.test.tsx +149 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/ImageNav.test.tsx +66 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/ImportWizard.test.tsx +179 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/ImportsTab.test.tsx +150 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/PipelineFixes.test.tsx +181 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/PipelineRestartWatch.test.tsx +122 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/PipelineTab.test.tsx +216 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/PromptRunConfirm.test.tsx +106 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/PromptsFixes.test.tsx +193 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/PromptsTab.test.tsx +225 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/PublicCollection.test.tsx +113 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/Review.test.tsx +137 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/ReviewLabel.test.tsx +20 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/ReviewPaging.test.tsx +149 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/ShareDialog.test.tsx +108 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/TestReportFixes.test.tsx +165 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/pagebuilder-blocks.test.ts +18 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/reviewSupport.tsx +56 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/support.tsx +152 -0
- simple_module_images-0.0.14/sm_images/ui/page-tests/test-dom.tsx +121 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api-groups.ts +66 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api-imports.ts +60 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api-net.ts +76 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api-prompts.ts +71 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api-public.ts +67 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api-review.ts +48 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api-shares.ts +42 -0
- simple_module_images-0.0.14/sm_images/ui/utils/api.ts +175 -0
- simple_module_images-0.0.14/sm_images/ui/utils/csrf.ts +62 -0
- simple_module_images-0.0.14/sm_images/ui/utils/direct-upload.test.ts +112 -0
- simple_module_images-0.0.14/sm_images/ui/utils/direct-upload.ts +92 -0
- simple_module_images-0.0.14/sm_images/ui/utils/geojsonDetect.ts +81 -0
- simple_module_images-0.0.14/sm_images/ui/utils/geojsonHeadScanner.ts +197 -0
- simple_module_images-0.0.14/sm_images/ui/utils/geojsonPreview.test.ts +101 -0
- simple_module_images-0.0.14/sm_images/ui/utils/geojsonPreview.ts +146 -0
- simple_module_images-0.0.14/sm_images/ui/utils/i18n.ts +182 -0
- simple_module_images-0.0.14/sm_images/ui/utils/labels.ts +86 -0
- simple_module_images-0.0.14/sm_images/ui/utils/schemaFields.test.ts +64 -0
- simple_module_images-0.0.14/sm_images/ui/utils/schemaFields.ts +134 -0
- simple_module_images-0.0.14/sm_images/ui/utils/types-prompts.ts +70 -0
- simple_module_images-0.0.14/sm_images/ui/utils/types-public.ts +39 -0
- simple_module_images-0.0.14/sm_images/ui/utils/types.ts +245 -0
- simple_module_images-0.0.14/sm_images/web/__init__.py +3 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/__init__.py +1 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/__init__.py +50 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/_runtime.py +24 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/collections.py +118 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/groups.py +199 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/images.py +246 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/imports.py +227 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/map.py +58 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/pipeline.py +107 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/presets.py +50 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/prompts.py +188 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/review.py +90 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/serve.py +65 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/shares.py +60 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/api/uploads.py +163 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/csrf.py +26 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/deps.py +29 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/map_params.py +69 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/menu.py +29 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/public.py +173 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/public_views.py +58 -0
- simple_module_images-0.0.14/sm_images/web/endpoints/views.py +150 -0
- simple_module_images-0.0.14/sm_images/web/schemas/__init__.py +1 -0
- simple_module_images-0.0.14/sm_images/web/schemas/collection.py +65 -0
- simple_module_images-0.0.14/sm_images/web/schemas/group.py +100 -0
- simple_module_images-0.0.14/sm_images/web/schemas/image.py +179 -0
- simple_module_images-0.0.14/sm_images/web/schemas/imports.py +85 -0
- simple_module_images-0.0.14/sm_images/web/schemas/pipeline.py +30 -0
- simple_module_images-0.0.14/sm_images/web/schemas/prompt.py +132 -0
- simple_module_images-0.0.14/sm_images/web/schemas/review.py +38 -0
- simple_module_images-0.0.14/sm_images/web/services/__init__.py +32 -0
- simple_module_images-0.0.14/sm_images/web/services/collections.py +169 -0
- simple_module_images-0.0.14/sm_images/web/services/cursor.py +62 -0
- simple_module_images-0.0.14/sm_images/web/services/gallery.py +155 -0
- simple_module_images-0.0.14/sm_images/web/services/groups.py +265 -0
- simple_module_images-0.0.14/sm_images/web/services/neighbors.py +50 -0
- simple_module_images-0.0.14/sm_images/web/services/present.py +102 -0
- simple_module_images-0.0.14/sm_images/web/services/presets.py +161 -0
- simple_module_images-0.0.14/sm_images/web/services/prompt_answers.py +48 -0
- simple_module_images-0.0.14/sm_images/web/services/prompts.py +211 -0
- simple_module_images-0.0.14/sm_images/web/services/public_gallery.py +81 -0
- simple_module_images-0.0.14/sm_images/web/services/public_stats.py +113 -0
- simple_module_images-0.0.14/sm_images/web/services/regroup.py +198 -0
- simple_module_images-0.0.14/sm_images/web/services/regroup_write.py +153 -0
- simple_module_images-0.0.14/sm_images/web/services/review_queue.py +101 -0
- simple_module_images-0.0.14/sm_images/web/services/slugs.py +19 -0
- simple_module_images-0.0.14/sm_images/web/services/stats.py +150 -0
- simple_module_images-0.0.14/sm_images/web/services/viewer_stats.py +89 -0
- simple_module_images-0.0.14/sm_images/web/serving/__init__.py +2 -0
- simple_module_images-0.0.14/sm_images/web/serving/cache.py +156 -0
- simple_module_images-0.0.14/sm_images/web/serving/ranges.py +90 -0
- simple_module_images-0.0.14/sm_images/web/serving/respond.py +263 -0
- simple_module_images-0.0.14/sm_images/web/serving/urls.py +124 -0
- simple_module_images-0.0.14/tests/__init__.py +11 -0
- simple_module_images-0.0.14/tests/conftest.py +100 -0
- simple_module_images-0.0.14/tests/core/__init__.py +0 -0
- simple_module_images-0.0.14/tests/core/access/__init__.py +0 -0
- simple_module_images-0.0.14/tests/core/access/test_access.py +127 -0
- simple_module_images-0.0.14/tests/core/access/test_access_sql.py +178 -0
- simple_module_images-0.0.14/tests/core/access/test_access_tenants.py +66 -0
- simple_module_images-0.0.14/tests/core/access/test_share_candidates.py +153 -0
- simple_module_images-0.0.14/tests/core/access/test_sharing_routes.py +215 -0
- simple_module_images-0.0.14/tests/core/access/test_starter_rights.py +156 -0
- simple_module_images-0.0.14/tests/core/billing/__init__.py +0 -0
- simple_module_images-0.0.14/tests/core/billing/test_billing_op_db_time.py +91 -0
- simple_module_images-0.0.14/tests/core/billing/test_billing_subject.py +176 -0
- simple_module_images-0.0.14/tests/core/billing/test_billing_subject_columns.py +16 -0
- simple_module_images-0.0.14/tests/core/billing/test_metering_keys.py +85 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering.py +150 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_closure.py +199 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_deadline.py +128 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_direct.py +84 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_durable.py +136 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_pipeline.py +130 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_pipeline_subject.py +152 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_real.py +194 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_repair.py +118 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_subject.py +242 -0
- simple_module_images-0.0.14/tests/core/billing/test_storage_metering_swap.py +241 -0
- simple_module_images-0.0.14/tests/core/storage/__init__.py +0 -0
- simple_module_images-0.0.14/tests/core/storage/test_storage.py +127 -0
- simple_module_images-0.0.14/tests/core/storage/test_storage_keys.py +44 -0
- simple_module_images-0.0.14/tests/core/test_contracts.py +145 -0
- simple_module_images-0.0.14/tests/core/test_error_labels.py +93 -0
- simple_module_images-0.0.14/tests/core/test_intents.py +66 -0
- simple_module_images-0.0.14/tests/core/test_models.py +89 -0
- simple_module_images-0.0.14/tests/core/test_module_boot.py +125 -0
- simple_module_images-0.0.14/tests/core/test_seed_guard.py +92 -0
- simple_module_images-0.0.14/tests/core/test_task_discovery.py +28 -0
- simple_module_images-0.0.14/tests/fixtures/geotagged.jpg +0 -0
- simple_module_images-0.0.14/tests/fixtures/make_fixtures.py +79 -0
- simple_module_images-0.0.14/tests/fixtures/real_face.jpg +0 -0
- simple_module_images-0.0.14/tests/fixtures/real_plate.jpg +0 -0
- simple_module_images-0.0.14/tests/fixtures/rotated.jpg +0 -0
- simple_module_images-0.0.14/tests/fixtures/sample.heic +0 -0
- simple_module_images-0.0.14/tests/fixtures/transparent.png +0 -0
- simple_module_images-0.0.14/tests/fixtures/zero_gps.jpg +0 -0
- simple_module_images-0.0.14/tests/ingest/__init__.py +0 -0
- simple_module_images-0.0.14/tests/ingest/imports/__init__.py +0 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_ai_import_fixes.py +54 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_api.py +164 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_claim_at_slot.py +96 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_controls.py +266 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_download.py +251 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_fencing.py +266 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_fixes.py +164 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_fixes2.py +116 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_fixes3.py +124 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_item_errors.py +92 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_manage_right.py +107 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_parse.py +190 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_runner.py +217 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_import_tasks.py +200 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_fetch.py +253 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_fetch_deadline.py +126 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_fetch_hardening.py +173 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_fetch_tls.py +152 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_log_redact.py +83 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_rate_limit.py +178 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_url_safety.py +192 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_imports_user_agent.py +40 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_phase4_api.py +126 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_phase4_fixes.py +211 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_phase4_fixes2.py +178 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_phase4_round2.py +149 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_phase4_round3.py +98 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_phase4_round4.py +122 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_api.py +123 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_fixes.py +253 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_fixes2.py +147 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_fixes3.py +124 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_fixes4.py +148 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_import.py +206 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_import_recovery.py +126 -0
- simple_module_images-0.0.14/tests/ingest/imports/test_zip_safety.py +139 -0
- simple_module_images-0.0.14/tests/ingest/test_direct_upload.py +120 -0
- simple_module_images-0.0.14/tests/ingest/test_direct_upload_review.py +183 -0
- simple_module_images-0.0.14/tests/ingest/test_direct_upload_transient.py +127 -0
- simple_module_images-0.0.14/tests/ingest/test_ingest_guards.py +111 -0
- simple_module_images-0.0.14/tests/ingest/test_ingest_hold_outcome.py +96 -0
- simple_module_images-0.0.14/tests/ingest/test_ingest_hold_rollback.py +92 -0
- simple_module_images-0.0.14/tests/ingest/test_ingest_hold_subject.py +116 -0
- simple_module_images-0.0.14/tests/ingest/test_ingest_staged_size.py +43 -0
- simple_module_images-0.0.14/tests/ingest/test_review_round1.py +122 -0
- simple_module_images-0.0.14/tests/ingest/test_service_holds_host.py +43 -0
- simple_module_images-0.0.14/tests/ingest/test_slots_savepoint_commit.py +28 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_admission.py +105 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_admission_race.py +114 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_api.py +215 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_base64.py +128 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_body_limit.py +66 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_file_db.py +37 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_lease.py +215 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_lease_r3.py +133 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_reaper.py +86 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_reaper_race.py +68 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_session.py +164 -0
- simple_module_images-0.0.14/tests/ingest/test_upload_subject.py +134 -0
- simple_module_images-0.0.14/tests/jobs/__init__.py +0 -0
- simple_module_images-0.0.14/tests/jobs/test_janitor.py +192 -0
- simple_module_images-0.0.14/tests/jobs/test_janitor_task.py +228 -0
- simple_module_images-0.0.14/tests/jobs/test_phase_isolation.py +137 -0
- simple_module_images-0.0.14/tests/jobs/test_purge_failures.py +225 -0
- simple_module_images-0.0.14/tests/jobs/test_purge_failures_r2.py +75 -0
- simple_module_images-0.0.14/tests/jobs/test_purge_shares.py +91 -0
- simple_module_images-0.0.14/tests/map/__init__.py +0 -0
- simple_module_images-0.0.14/tests/map/test_map_build.py +215 -0
- simple_module_images-0.0.14/tests/map/test_map_points.py +226 -0
- simple_module_images-0.0.14/tests/map/test_map_points_etag.py +64 -0
- simple_module_images-0.0.14/tests/map/test_map_revoke.py +212 -0
- simple_module_images-0.0.14/tests/map/test_map_revoke_moves.py +192 -0
- simple_module_images-0.0.14/tests/map/test_map_stale.py +73 -0
- simple_module_images-0.0.14/tests/map/test_map_style.py +88 -0
- simple_module_images-0.0.14/tests/map/test_map_tiles.py +217 -0
- simple_module_images-0.0.14/tests/map/test_map_tippecanoe.py +132 -0
- simple_module_images-0.0.14/tests/pg_support.py +76 -0
- simple_module_images-0.0.14/tests/pipeline/__init__.py +0 -0
- simple_module_images-0.0.14/tests/pipeline/ai/__init__.py +0 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_ai_auto_run.py +58 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_ai_fixes.py +124 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_ai_fixes2.py +151 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_ai_schema_fixes3.py +42 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_ai_schema_safety.py +196 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_ai_steps.py +245 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_ai_subject.py +82 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_cross_check_executor.py +160 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_group_prompts.py +235 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_group_prompts_api.py +120 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_group_prompts_store.py +139 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_group_run_hardening.py +159 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_presets_api.py +154 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_presets_contract.py +75 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_prompts_api.py +183 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_prompts_api_fixes.py +86 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_review_api.py +230 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_review_fixes.py +117 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_step_run_answers.py +94 -0
- simple_module_images-0.0.14/tests/pipeline/ai/test_viewer_prompt_results.py +49 -0
- simple_module_images-0.0.14/tests/pipeline/steps/__init__.py +0 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_degenerate.py +213 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_fork.py +75 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_malformed.py +99 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_mapping.py +91 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_models.py +132 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_pipeline.py +165 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_real.py +97 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_step.py +266 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_weights.py +146 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_anonymize_wiring.py +131 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_classify_vocabulary.py +27 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_exif.py +113 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_processing_review.py +90 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_quality_step.py +141 -0
- simple_module_images-0.0.14/tests/pipeline/steps/test_renditions.py +69 -0
- simple_module_images-0.0.14/tests/pipeline/test_collection_default_pipeline.py +25 -0
- simple_module_images-0.0.14/tests/pipeline/test_extensions.py +144 -0
- simple_module_images-0.0.14/tests/pipeline/test_framework_pins.py +33 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_api.py +106 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_api_put.py +76 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_api_run.py +123 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_config.py +75 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_executor.py +253 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_leases.py +216 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_missing_stale.py +80 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_reopen.py +170 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_restart.py +146 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_review_fixes.py +257 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_review_fixes2.py +132 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_review_fixes3.py +100 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_review_fixes4.py +141 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_review_fixes5.py +48 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_tenancy.py +193 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_web.py +115 -0
- simple_module_images-0.0.14/tests/pipeline/test_pipeline_worker.py +168 -0
- simple_module_images-0.0.14/tests/pipeline/test_plugin_e2e.py +106 -0
- simple_module_images-0.0.14/tests/pipeline/test_registry.py +178 -0
- simple_module_images-0.0.14/tests/pipeline/test_step_context.py +144 -0
- simple_module_images-0.0.14/tests/pipeline/test_step_run_labels.py +90 -0
- simple_module_images-0.0.14/tests/plugin_fixture/broken_fixture/__init__.py +3 -0
- simple_module_images-0.0.14/tests/plugin_fixture/images_testplugin/__init__.py +5 -0
- simple_module_images-0.0.14/tests/plugin_fixture/images_testplugin/images_extensions.py +85 -0
- simple_module_images-0.0.14/tests/plugin_fixture/images_testplugin/module.py +9 -0
- simple_module_images-0.0.14/tests/plugin_fixture/lucas_fixture/__init__.py +1 -0
- simple_module_images-0.0.14/tests/plugin_fixture/lucas_fixture/images_extensions.py +30 -0
- simple_module_images-0.0.14/tests/support/__init__.py +1 -0
- simple_module_images-0.0.14/tests/support/access.py +147 -0
- simple_module_images-0.0.14/tests/support/ai.py +125 -0
- simple_module_images-0.0.14/tests/support/anonymize.py +77 -0
- simple_module_images-0.0.14/tests/support/app_harness.py +140 -0
- simple_module_images-0.0.14/tests/support/billing.py +274 -0
- simple_module_images-0.0.14/tests/support/direct.py +39 -0
- simple_module_images-0.0.14/tests/support/fetch.py +89 -0
- simple_module_images-0.0.14/tests/support/groups.py +80 -0
- simple_module_images-0.0.14/tests/support/imports.py +194 -0
- simple_module_images-0.0.14/tests/support/isolation.py +62 -0
- simple_module_images-0.0.14/tests/support/map.py +61 -0
- simple_module_images-0.0.14/tests/support/onnx.py +112 -0
- simple_module_images-0.0.14/tests/support/pipeline.py +214 -0
- simple_module_images-0.0.14/tests/support/pipeline_api.py +57 -0
- simple_module_images-0.0.14/tests/support/prompts.py +44 -0
- simple_module_images-0.0.14/tests/support/public_stats.py +76 -0
- simple_module_images-0.0.14/tests/support/read_routes.py +80 -0
- simple_module_images-0.0.14/tests/support/serve.py +143 -0
- simple_module_images-0.0.14/tests/support/step.py +27 -0
- simple_module_images-0.0.14/tests/support/stub_auth.py +64 -0
- simple_module_images-0.0.14/tests/support/upload.py +110 -0
- simple_module_images-0.0.14/tests/support/zip.py +177 -0
- simple_module_images-0.0.14/tests/web/__init__.py +0 -0
- simple_module_images-0.0.14/tests/web/collections/__init__.py +0 -0
- simple_module_images-0.0.14/tests/web/collections/test_collection_public_path.py +13 -0
- simple_module_images-0.0.14/tests/web/collections/test_collections_api.py +266 -0
- simple_module_images-0.0.14/tests/web/collections/test_collections_list.py +164 -0
- simple_module_images-0.0.14/tests/web/collections/test_console_views.py +223 -0
- simple_module_images-0.0.14/tests/web/collections/test_gallery_api.py +134 -0
- simple_module_images-0.0.14/tests/web/collections/test_image_neighbors.py +94 -0
- simple_module_images-0.0.14/tests/web/collections/test_public_page.py +103 -0
- simple_module_images-0.0.14/tests/web/collections/test_public_stats.py +184 -0
- simple_module_images-0.0.14/tests/web/collections/test_public_stats_bounded.py +87 -0
- simple_module_images-0.0.14/tests/web/collections/test_stats.py +230 -0
- simple_module_images-0.0.14/tests/web/collections/test_viewer_stats.py +179 -0
- simple_module_images-0.0.14/tests/web/groups/__init__.py +0 -0
- simple_module_images-0.0.14/tests/web/groups/test_group_fixes.py +208 -0
- simple_module_images-0.0.14/tests/web/groups/test_groups.py +264 -0
- simple_module_images-0.0.14/tests/web/groups/test_groups_fences.py +134 -0
- simple_module_images-0.0.14/tests/web/groups/test_groups_jobs.py +253 -0
- simple_module_images-0.0.14/tests/web/groups/test_groups_races.py +109 -0
- simple_module_images-0.0.14/tests/web/serving/__init__.py +0 -0
- simple_module_images-0.0.14/tests/web/serving/test_cache_headers.py +130 -0
- simple_module_images-0.0.14/tests/web/serving/test_ranges.py +69 -0
- simple_module_images-0.0.14/tests/web/serving/test_read_routes.py +209 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve.py +178 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_display_browser.py +74 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_display_origin.py +128 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_display_trust.py +153 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_gate.py +84 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_public.py +159 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_redaction.py +236 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_revalidate.py +105 -0
- simple_module_images-0.0.14/tests/web/serving/test_serve_versions.py +139 -0
- simple_module_images-0.0.14/tests/web/serving/test_urls.py +171 -0
- simple_module_images-0.0.14/tests/web/serving/test_viewer_error_shape.py +114 -0
- simple_module_images-0.0.14/tests/web/serving/test_viewer_withheld.py +143 -0
- simple_module_images-0.0.14/tsconfig.json +10 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
.claude/settings.local.json
|
|
2
|
+
|
|
3
|
+
# Python
|
|
4
|
+
.venv/
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.pyc
|
|
7
|
+
*.egg-info/
|
|
8
|
+
|
|
9
|
+
# Node
|
|
10
|
+
node_modules/
|
|
11
|
+
dist/
|
|
12
|
+
|
|
13
|
+
# Built module frontend bundles (force-included into wheels at build time)
|
|
14
|
+
modules/*/*/static/dist/
|
|
15
|
+
|
|
16
|
+
# Host build output and the module-pages manifest regenerated by `make gen-pages`
|
|
17
|
+
host/static/dist/
|
|
18
|
+
host/client_app/modules.manifest.json
|
|
19
|
+
host/client_app/modules.generated.ts
|
|
20
|
+
host/client_app/modules.generated.css
|
|
21
|
+
host/client_app/modules.assets.json
|
|
22
|
+
|
|
23
|
+
# Local databases. `make migrate` resolves alembic's script_location relative
|
|
24
|
+
# to the repo root, so running it the documented way leaves ./app.db here —
|
|
25
|
+
# not under host/ — and it must never be committed.
|
|
26
|
+
host/*.db
|
|
27
|
+
app.db*
|
|
28
|
+
# SQLite runs in WAL mode since framework 0.0.35 (#339): its sidecar files.
|
|
29
|
+
host/*.db-wal
|
|
30
|
+
host/*.db-shm
|
|
31
|
+
# `make beat` keeps Celery beat's schedule state in the repo root.
|
|
32
|
+
celerybeat-schedule*
|
|
33
|
+
|
|
34
|
+
# Runtime upload storage (PagebuilderSettings.media_root)
|
|
35
|
+
var/
|
|
36
|
+
# file_storage's local backend (DEFAULT_FS_ROOT = ./uploads), which the dev
|
|
37
|
+
# host creates in the repo root
|
|
38
|
+
uploads/
|
|
39
|
+
|
|
40
|
+
# Env
|
|
41
|
+
.env
|
|
42
|
+
|
|
43
|
+
# Playwright
|
|
44
|
+
playwright-report/
|
|
45
|
+
test-results/
|
|
46
|
+
.e2e-shards/
|
|
47
|
+
blob-report/
|
|
48
|
+
.playwright-mcp/
|
|
49
|
+
|
|
50
|
+
# macOS
|
|
51
|
+
.DS_Store
|
|
52
|
+
|
|
53
|
+
# QA / verify pipeline artifacts (/qa, /vf)
|
|
54
|
+
.qa/
|
|
55
|
+
.verify/
|
|
56
|
+
# Scratch database a /qa run boots against, so it never touches host/app.db.
|
|
57
|
+
qa.db*
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
simple_module_images
|
|
2
|
+
Copyright (c) Anto Subash. Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
The optional `anonymize` step downloads the following third-party models at
|
|
5
|
+
run time. They are not included in this package; their notices are reproduced
|
|
6
|
+
here because a deployment that caches or redistributes them must keep them.
|
|
7
|
+
|
|
8
|
+
-------------------------------------------------------------------------------
|
|
9
|
+
YuNet face detector - face_detection_yunet_2026may.onnx
|
|
10
|
+
Source: https://github.com/opencv/opencv_zoo/tree/eb9f4f2d4b79b58e5513b5d25d5f0243a8357bf4/models/face_detection_yunet
|
|
11
|
+
Training code: https://github.com/ShiqiYu/libfacedetection.train
|
|
12
|
+
License: MIT
|
|
13
|
+
|
|
14
|
+
MIT License
|
|
15
|
+
|
|
16
|
+
Copyright (c) 2020 Shiqi Yu <shiqi.yu@gmail.com>
|
|
17
|
+
|
|
18
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
20
|
+
in the Software without restriction, including without limitation the rights
|
|
21
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
22
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
23
|
+
furnished to do so, subject to the following conditions:
|
|
24
|
+
|
|
25
|
+
The above copyright notice and this permission notice shall be included in all
|
|
26
|
+
copies or substantial portions of the Software.
|
|
27
|
+
|
|
28
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
29
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
30
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
31
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
32
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
33
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
34
|
+
SOFTWARE.
|
|
35
|
+
|
|
36
|
+
-------------------------------------------------------------------------------
|
|
37
|
+
YOLOv9 licence-plate detector - yolo-v9-s-608-license-plates-end2end.onnx
|
|
38
|
+
Source: https://github.com/ankandrew/open-image-models/releases/tag/assets
|
|
39
|
+
License: MIT
|
|
40
|
+
|
|
41
|
+
MIT License
|
|
42
|
+
|
|
43
|
+
Copyright (c) 2024 ankandrew
|
|
44
|
+
|
|
45
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
46
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
47
|
+
in the Software without restriction, including without limitation the rights
|
|
48
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
49
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
50
|
+
furnished to do so, subject to the following conditions:
|
|
51
|
+
|
|
52
|
+
The above copyright notice and this permission notice shall be included in all
|
|
53
|
+
copies or substantial portions of the Software.
|
|
54
|
+
|
|
55
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
56
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
57
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
58
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
59
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
60
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
61
|
+
SOFTWARE.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: simple_module_images
|
|
3
|
+
Version: 0.0.14
|
|
4
|
+
Summary: Image collections with a processing pipeline: EXIF, renditions, quality checks, optional anonymisation, geo-located imports and map tiles
|
|
5
|
+
Project-URL: Repository, https://github.com/antosubash/simple_module_python_modules
|
|
6
|
+
Author-email: Anto Subash <antosubash@live.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: NOTICE
|
|
9
|
+
Keywords: exif,gallery,geo,images,simple-module
|
|
10
|
+
Requires-Python: >=3.12
|
|
11
|
+
Requires-Dist: httpx>=0.27
|
|
12
|
+
Requires-Dist: ijson>=3.2
|
|
13
|
+
Requires-Dist: itsdangerous<3,>=2.0
|
|
14
|
+
Requires-Dist: pillow-heif>=1.4
|
|
15
|
+
Requires-Dist: pillow>=10.0
|
|
16
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
17
|
+
Requires-Dist: regex>=2023.0
|
|
18
|
+
Requires-Dist: simple-module-background-tasks<0.1,>=0.0.44
|
|
19
|
+
Requires-Dist: simple-module-core<0.1,>=0.0.42
|
|
20
|
+
Requires-Dist: simple-module-db<0.1,>=0.0.41
|
|
21
|
+
Requires-Dist: simple-module-file-storage<0.1,>=0.0.44
|
|
22
|
+
Requires-Dist: simple-module-hosting<0.1,>=0.0.42
|
|
23
|
+
Requires-Dist: simple-module-inertia<0.1,>=0.0.41
|
|
24
|
+
Requires-Dist: simple-module-settings<0.1,>=0.0.41
|
|
25
|
+
Requires-Dist: simple-module-sharing<0.1,>=0.0.44
|
|
26
|
+
Provides-Extra: ai
|
|
27
|
+
Requires-Dist: simple-module-ai<0.1,>=0.0.14; extra == 'ai'
|
|
28
|
+
Provides-Extra: anonymize
|
|
29
|
+
Requires-Dist: onnxruntime>=1.18; extra == 'anonymize'
|
|
30
|
+
Provides-Extra: billing
|
|
31
|
+
Requires-Dist: simple-module-billing<0.1,>=0.0.14; extra == 'billing'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pmtiles>=3.2; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: simple-module-test<0.1,>=0.0.41; extra == 'dev'
|
|
37
|
+
Provides-Extra: pagebuilder
|
|
38
|
+
Requires-Dist: simple-module-pagebuilder<0.1,>=0.0.12; extra == 'pagebuilder'
|
|
39
|
+
Provides-Extra: quality
|
|
40
|
+
Requires-Dist: opencv-python-headless>=4.9; extra == 'quality'
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
|
|
43
|
+
# simple_module_images
|
|
44
|
+
|
|
45
|
+
Image collections for SimpleModule hosts. A collection holds images whose
|
|
46
|
+
**originals are immutable**; everything derived from them (EXIF and location,
|
|
47
|
+
renditions, quality metrics, an optionally anonymised display copy, map tiles)
|
|
48
|
+
is produced by pipeline steps that run as background tasks. Collections are
|
|
49
|
+
private to their owner, shared with chosen users, internal to the organisation
|
|
50
|
+
or public.
|
|
51
|
+
|
|
52
|
+
Imports take single files, batches, large direct uploads, ZIP archives and
|
|
53
|
+
GeoJSON sources of up to a million located images. Groups, AI prompts with a
|
|
54
|
+
review queue, a map (GeoJSON points and PMTiles) and a public gallery are
|
|
55
|
+
included. Design:
|
|
56
|
+
`docs/superpowers/specs/2026-10-28-images-module-design.md` in the source repo;
|
|
57
|
+
the guides are in [`docs/`](docs/index.md).
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install simple_module_images
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Add `simple_module_images` to your host's dependencies; for an in-repo checkout,
|
|
66
|
+
resolve it from the workspace:
|
|
67
|
+
|
|
68
|
+
```toml
|
|
69
|
+
[tool.uv.sources.simple_module_images]
|
|
70
|
+
workspace = true
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
A plain install pulls no onnxruntime or OpenCV. Heavy processors are
|
|
74
|
+
extras, imported only inside the step that needs them:
|
|
75
|
+
|
|
76
|
+
| Extra | Adds |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `quality` | OpenCV: resolution, blur and exposure metrics |
|
|
79
|
+
| `anonymize` | onnxruntime: YuNet face and YOLOv9 plate detection (MIT models), blurred into a display copy (the original is kept); weights from `anonymize_weights_path` or a pinned, checksummed download on first use |
|
|
80
|
+
| `ai` | `simple_module_ai`: prompt-based image analysis |
|
|
81
|
+
| `billing` | `simple_module_billing`: storage and request metering |
|
|
82
|
+
| `pagebuilder` | `simple_module_pagebuilder`: an image gallery block |
|
|
83
|
+
|
|
84
|
+
The map view needs no extra: its PMTiles archive is built by the `tippecanoe`
|
|
85
|
+
binary (`tippecanoe_path`), which must be on the worker's machine.
|
|
86
|
+
|
|
87
|
+
**Models and licences.** The `anonymize` extra installs only onnxruntime
|
|
88
|
+
(MIT). The step downloads two MIT-licensed ONNX models on first use, pinned by
|
|
89
|
+
SHA-256: **YuNet** (faces; Shiqi Yu, via
|
|
90
|
+
[OpenCV Zoo](https://github.com/opencv/opencv_zoo/tree/eb9f4f2d4b79b58e5513b5d25d5f0243a8357bf4/models/face_detection_yunet))
|
|
91
|
+
and **YOLOv9 licence-plate detector** (ankandrew,
|
|
92
|
+
[open-image-models](https://github.com/ankandrew/open-image-models)). Their
|
|
93
|
+
copyright notices are in this module's `NOTICE`. Recall is unverified, and
|
|
94
|
+
weights are cached under `~/.cache/simple_module_images/models` unless
|
|
95
|
+
`anonymize_weights_path` points at `face.onnx` and `plate.onnx`. See
|
|
96
|
+
[docs/index.md](docs/index.md#anonymize-models-and-licences).
|
|
97
|
+
|
|
98
|
+
The module needs the framework's `settings`, `sharing`, `file_storage` and
|
|
99
|
+
`background_tasks` modules. Migrations live in the consuming host
|
|
100
|
+
(`make migration`), never in the wheel.
|
|
101
|
+
|
|
102
|
+
Image processing runs in Celery workers (`make worker`, `worker-imports`,
|
|
103
|
+
`worker-heavy`, `worker-gpu`, `beat`) or inline with
|
|
104
|
+
`SM_BG_TASKS_TASK_ALWAYS_EAGER=true`. A plugin that adds steps ships an
|
|
105
|
+
`images_extensions.py` and must be installed in the web process and every
|
|
106
|
+
worker. See [docs/worker.md](docs/worker.md) and
|
|
107
|
+
[docs/writing-a-plugin.md](docs/writing-a-plugin.md).
|
|
108
|
+
|
|
109
|
+
## Usage
|
|
110
|
+
|
|
111
|
+
The console is at `/admin/images`, the JSON API under `/api/images` and public
|
|
112
|
+
collections at `/images/c/{slug}`. Every router binds a tenant: a single-tenant
|
|
113
|
+
host uses `default`, a multi-tenant host the organisation the framework
|
|
114
|
+
resolved (403 `tenant_required` for the console, 404 for public routes when
|
|
115
|
+
none).
|
|
116
|
+
|
|
117
|
+
### Permissions
|
|
118
|
+
|
|
119
|
+
| Permission | Allows |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `images.view` | See collections and images the access policy admits |
|
|
122
|
+
| `images.create` | Create collections and upload images |
|
|
123
|
+
| `images.publish` | Make a collection public or internal |
|
|
124
|
+
| `images.manage` | Manage every collection regardless of owner |
|
|
125
|
+
| `images.originals.view` | Download the immutable original |
|
|
126
|
+
|
|
127
|
+
### Settings
|
|
128
|
+
|
|
129
|
+
The module's settings are governed by the framework's `settings.edit`, as every
|
|
130
|
+
other module's are; images has no settings permission of its own.
|
|
131
|
+
|
|
132
|
+
Stored in the database and edited on the Settings screen; there is no
|
|
133
|
+
`SM_IMAGES_*` environment variable. System scope: one configuration for every
|
|
134
|
+
tenant. Fields marked as needing a restart (`tippecanoe_path`,
|
|
135
|
+
`public_asset_base_url`) are read once at boot; workers pick up the rest within
|
|
136
|
+
about 30 seconds.
|
|
137
|
+
|
|
138
|
+
| Setting | Default |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `max_image_bytes` | 50 MiB |
|
|
141
|
+
| `batch_max` | 50 |
|
|
142
|
+
| `upload_body_max_bytes` | 100 MiB |
|
|
143
|
+
| `direct_upload_threshold` | 20 MiB |
|
|
144
|
+
| `max_open_uploads_per_tenant` | 20 |
|
|
145
|
+
| `zip_max_bytes` / `zip_max_entries` | 2 GiB / 10 000 |
|
|
146
|
+
| `zip_max_entry_bytes` / `zip_max_total_bytes` / `zip_max_ratio` | 200 MiB / 8 GiB / 200 |
|
|
147
|
+
| `geojson_max_features` / `geojson_max_bytes` / `geojson_max_feature_bytes` | 1 000 000 / 2 GiB / 60 MiB |
|
|
148
|
+
| `download_concurrency_per_domain` / `download_concurrency_total` (per download task) / `download_timeout` | 4 / 32 / 60 s |
|
|
149
|
+
| `thumbnail_sizes` | marker 64, small 160, medium 400, large 1024 |
|
|
150
|
+
| `dedupe_by_hash` | off |
|
|
151
|
+
| `tippecanoe_path`, `anonymize_weights_path` | `tippecanoe`, empty |
|
|
152
|
+
| `map_rebuild_threshold_pct` / `map_rebuild_threshold_abs` | 5 / 100 |
|
|
153
|
+
| `map_style_url` (basemap; empty = flat, no third-party request) | `https://tiles.openfreemap.org/styles/positron` |
|
|
154
|
+
| `public_asset_base_url` | empty |
|
|
155
|
+
| `janitor_grace_days`, `step_output_max_bytes`, `step_lease_seconds` | 7, 65 536, 1 800 |
|
|
156
|
+
|
|
157
|
+
### Routes
|
|
158
|
+
|
|
159
|
+
Upload routes (`/api/images/collections/{id}/images`, `.../imports`,
|
|
160
|
+
`.../imports/zip` and `/api/images/uploads/`) carry a request-body ceiling of
|
|
161
|
+
`upload_body_max_bytes` plus multipart framing; the rest use the host's global
|
|
162
|
+
limit. Public exemptions are `GET`/`HEAD` only, under `/images/c/` and
|
|
163
|
+
`/api/images/public/`.
|
|
164
|
+
|
|
165
|
+
### Map
|
|
166
|
+
|
|
167
|
+
- `GET /api/images/collections/{id}/points?bbox=minx,miny,maxx,maxy&limit=&cursor=`
|
|
168
|
+
(anonymous twin: `/api/images/public/c/{slug}/points`) answers a GeoJSON
|
|
169
|
+
`FeatureCollection`. Each point carries only `id`, `captured_at` and
|
|
170
|
+
`group_id`; an image whose display mutator has not settled is not a point.
|
|
171
|
+
`limit` is clamped to 5000; follow `next_cursor` for the rest.
|
|
172
|
+
- `GET|HEAD …/collections/{id}/map.pmtiles` (twin: `/api/images/public/c/{slug}/map.pmtiles`)
|
|
173
|
+
serves the collection's PMTiles archive with `Range`, checking access on
|
|
174
|
+
every request. It is a 404 until a map is built.
|
|
175
|
+
- `images.build_map` (queue `images`) builds the archive with `tippecanoe`.
|
|
176
|
+
A rebuild starts once the changes since the last build reach
|
|
177
|
+
`map_rebuild_threshold_abs` or `map_rebuild_threshold_pct` percent of its
|
|
178
|
+
points (both at least 1). A move does not wait for the threshold. A visibility
|
|
179
|
+
change, a removed point (an image trashed or its location cleared) and a
|
|
180
|
+
pipeline save that changes the redaction gate withdraw the archive in the
|
|
181
|
+
same transaction and build a fresh one. An archive is stamped with the
|
|
182
|
+
redaction gate it was built under, and is a 404 under any other (for
|
|
183
|
+
example once a mutator plugin is removed) until `images.reconcile` rebuilds it.
|
|
184
|
+
- The `images.tippecanoe` health check is degraded while the binary cannot be
|
|
185
|
+
found. Points keep working.
|
|
186
|
+
- The points are drawn over the basemap `map_style_url` names (OpenFreeMap's
|
|
187
|
+
Positron by default; its origin is added to the CSP). Viewers' browsers
|
|
188
|
+
fetch its tiles from that host, so it sees their IP and the area they view;
|
|
189
|
+
set it to empty for a flat background with no third-party request. A style
|
|
190
|
+
that cannot be fetched falls back to the flat background.
|
|
191
|
+
|
|
192
|
+
## Documentation
|
|
193
|
+
|
|
194
|
+
| Page | For |
|
|
195
|
+
| --- | --- |
|
|
196
|
+
| [docs/index.md](docs/index.md) | Concepts, install, permissions, every setting |
|
|
197
|
+
| [docs/access.md](docs/access.md) | Visibility, shares, originals, withheld images |
|
|
198
|
+
| [docs/imports.md](docs/imports.md) | Uploads, direct upload and bucket CORS, ZIP, GeoJSON, limits |
|
|
199
|
+
| [docs/pipeline.md](docs/pipeline.md) | Steps, leases, AI prompts, groups, presets, review, storage metering |
|
|
200
|
+
| [docs/writing-a-plugin.md](docs/writing-a-plugin.md) | Steps, presets and result views from another module |
|
|
201
|
+
| [docs/worker.md](docs/worker.md) | Workers, beat, timeouts, tuning, recovery times |
|
|
202
|
+
| [docs/migrating-from-portal.md](docs/migrating-from-portal.md) | Moving off the portal's feature |
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# simple_module_images
|
|
2
|
+
|
|
3
|
+
Image collections for SimpleModule hosts. A collection holds images whose
|
|
4
|
+
**originals are immutable**; everything derived from them (EXIF and location,
|
|
5
|
+
renditions, quality metrics, an optionally anonymised display copy, map tiles)
|
|
6
|
+
is produced by pipeline steps that run as background tasks. Collections are
|
|
7
|
+
private to their owner, shared with chosen users, internal to the organisation
|
|
8
|
+
or public.
|
|
9
|
+
|
|
10
|
+
Imports take single files, batches, large direct uploads, ZIP archives and
|
|
11
|
+
GeoJSON sources of up to a million located images. Groups, AI prompts with a
|
|
12
|
+
review queue, a map (GeoJSON points and PMTiles) and a public gallery are
|
|
13
|
+
included. Design:
|
|
14
|
+
`docs/superpowers/specs/2026-10-28-images-module-design.md` in the source repo;
|
|
15
|
+
the guides are in [`docs/`](docs/index.md).
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install simple_module_images
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Add `simple_module_images` to your host's dependencies; for an in-repo checkout,
|
|
24
|
+
resolve it from the workspace:
|
|
25
|
+
|
|
26
|
+
```toml
|
|
27
|
+
[tool.uv.sources.simple_module_images]
|
|
28
|
+
workspace = true
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
A plain install pulls no onnxruntime or OpenCV. Heavy processors are
|
|
32
|
+
extras, imported only inside the step that needs them:
|
|
33
|
+
|
|
34
|
+
| Extra | Adds |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `quality` | OpenCV: resolution, blur and exposure metrics |
|
|
37
|
+
| `anonymize` | onnxruntime: YuNet face and YOLOv9 plate detection (MIT models), blurred into a display copy (the original is kept); weights from `anonymize_weights_path` or a pinned, checksummed download on first use |
|
|
38
|
+
| `ai` | `simple_module_ai`: prompt-based image analysis |
|
|
39
|
+
| `billing` | `simple_module_billing`: storage and request metering |
|
|
40
|
+
| `pagebuilder` | `simple_module_pagebuilder`: an image gallery block |
|
|
41
|
+
|
|
42
|
+
The map view needs no extra: its PMTiles archive is built by the `tippecanoe`
|
|
43
|
+
binary (`tippecanoe_path`), which must be on the worker's machine.
|
|
44
|
+
|
|
45
|
+
**Models and licences.** The `anonymize` extra installs only onnxruntime
|
|
46
|
+
(MIT). The step downloads two MIT-licensed ONNX models on first use, pinned by
|
|
47
|
+
SHA-256: **YuNet** (faces; Shiqi Yu, via
|
|
48
|
+
[OpenCV Zoo](https://github.com/opencv/opencv_zoo/tree/eb9f4f2d4b79b58e5513b5d25d5f0243a8357bf4/models/face_detection_yunet))
|
|
49
|
+
and **YOLOv9 licence-plate detector** (ankandrew,
|
|
50
|
+
[open-image-models](https://github.com/ankandrew/open-image-models)). Their
|
|
51
|
+
copyright notices are in this module's `NOTICE`. Recall is unverified, and
|
|
52
|
+
weights are cached under `~/.cache/simple_module_images/models` unless
|
|
53
|
+
`anonymize_weights_path` points at `face.onnx` and `plate.onnx`. See
|
|
54
|
+
[docs/index.md](docs/index.md#anonymize-models-and-licences).
|
|
55
|
+
|
|
56
|
+
The module needs the framework's `settings`, `sharing`, `file_storage` and
|
|
57
|
+
`background_tasks` modules. Migrations live in the consuming host
|
|
58
|
+
(`make migration`), never in the wheel.
|
|
59
|
+
|
|
60
|
+
Image processing runs in Celery workers (`make worker`, `worker-imports`,
|
|
61
|
+
`worker-heavy`, `worker-gpu`, `beat`) or inline with
|
|
62
|
+
`SM_BG_TASKS_TASK_ALWAYS_EAGER=true`. A plugin that adds steps ships an
|
|
63
|
+
`images_extensions.py` and must be installed in the web process and every
|
|
64
|
+
worker. See [docs/worker.md](docs/worker.md) and
|
|
65
|
+
[docs/writing-a-plugin.md](docs/writing-a-plugin.md).
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
The console is at `/admin/images`, the JSON API under `/api/images` and public
|
|
70
|
+
collections at `/images/c/{slug}`. Every router binds a tenant: a single-tenant
|
|
71
|
+
host uses `default`, a multi-tenant host the organisation the framework
|
|
72
|
+
resolved (403 `tenant_required` for the console, 404 for public routes when
|
|
73
|
+
none).
|
|
74
|
+
|
|
75
|
+
### Permissions
|
|
76
|
+
|
|
77
|
+
| Permission | Allows |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `images.view` | See collections and images the access policy admits |
|
|
80
|
+
| `images.create` | Create collections and upload images |
|
|
81
|
+
| `images.publish` | Make a collection public or internal |
|
|
82
|
+
| `images.manage` | Manage every collection regardless of owner |
|
|
83
|
+
| `images.originals.view` | Download the immutable original |
|
|
84
|
+
|
|
85
|
+
### Settings
|
|
86
|
+
|
|
87
|
+
The module's settings are governed by the framework's `settings.edit`, as every
|
|
88
|
+
other module's are; images has no settings permission of its own.
|
|
89
|
+
|
|
90
|
+
Stored in the database and edited on the Settings screen; there is no
|
|
91
|
+
`SM_IMAGES_*` environment variable. System scope: one configuration for every
|
|
92
|
+
tenant. Fields marked as needing a restart (`tippecanoe_path`,
|
|
93
|
+
`public_asset_base_url`) are read once at boot; workers pick up the rest within
|
|
94
|
+
about 30 seconds.
|
|
95
|
+
|
|
96
|
+
| Setting | Default |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `max_image_bytes` | 50 MiB |
|
|
99
|
+
| `batch_max` | 50 |
|
|
100
|
+
| `upload_body_max_bytes` | 100 MiB |
|
|
101
|
+
| `direct_upload_threshold` | 20 MiB |
|
|
102
|
+
| `max_open_uploads_per_tenant` | 20 |
|
|
103
|
+
| `zip_max_bytes` / `zip_max_entries` | 2 GiB / 10 000 |
|
|
104
|
+
| `zip_max_entry_bytes` / `zip_max_total_bytes` / `zip_max_ratio` | 200 MiB / 8 GiB / 200 |
|
|
105
|
+
| `geojson_max_features` / `geojson_max_bytes` / `geojson_max_feature_bytes` | 1 000 000 / 2 GiB / 60 MiB |
|
|
106
|
+
| `download_concurrency_per_domain` / `download_concurrency_total` (per download task) / `download_timeout` | 4 / 32 / 60 s |
|
|
107
|
+
| `thumbnail_sizes` | marker 64, small 160, medium 400, large 1024 |
|
|
108
|
+
| `dedupe_by_hash` | off |
|
|
109
|
+
| `tippecanoe_path`, `anonymize_weights_path` | `tippecanoe`, empty |
|
|
110
|
+
| `map_rebuild_threshold_pct` / `map_rebuild_threshold_abs` | 5 / 100 |
|
|
111
|
+
| `map_style_url` (basemap; empty = flat, no third-party request) | `https://tiles.openfreemap.org/styles/positron` |
|
|
112
|
+
| `public_asset_base_url` | empty |
|
|
113
|
+
| `janitor_grace_days`, `step_output_max_bytes`, `step_lease_seconds` | 7, 65 536, 1 800 |
|
|
114
|
+
|
|
115
|
+
### Routes
|
|
116
|
+
|
|
117
|
+
Upload routes (`/api/images/collections/{id}/images`, `.../imports`,
|
|
118
|
+
`.../imports/zip` and `/api/images/uploads/`) carry a request-body ceiling of
|
|
119
|
+
`upload_body_max_bytes` plus multipart framing; the rest use the host's global
|
|
120
|
+
limit. Public exemptions are `GET`/`HEAD` only, under `/images/c/` and
|
|
121
|
+
`/api/images/public/`.
|
|
122
|
+
|
|
123
|
+
### Map
|
|
124
|
+
|
|
125
|
+
- `GET /api/images/collections/{id}/points?bbox=minx,miny,maxx,maxy&limit=&cursor=`
|
|
126
|
+
(anonymous twin: `/api/images/public/c/{slug}/points`) answers a GeoJSON
|
|
127
|
+
`FeatureCollection`. Each point carries only `id`, `captured_at` and
|
|
128
|
+
`group_id`; an image whose display mutator has not settled is not a point.
|
|
129
|
+
`limit` is clamped to 5000; follow `next_cursor` for the rest.
|
|
130
|
+
- `GET|HEAD …/collections/{id}/map.pmtiles` (twin: `/api/images/public/c/{slug}/map.pmtiles`)
|
|
131
|
+
serves the collection's PMTiles archive with `Range`, checking access on
|
|
132
|
+
every request. It is a 404 until a map is built.
|
|
133
|
+
- `images.build_map` (queue `images`) builds the archive with `tippecanoe`.
|
|
134
|
+
A rebuild starts once the changes since the last build reach
|
|
135
|
+
`map_rebuild_threshold_abs` or `map_rebuild_threshold_pct` percent of its
|
|
136
|
+
points (both at least 1). A move does not wait for the threshold. A visibility
|
|
137
|
+
change, a removed point (an image trashed or its location cleared) and a
|
|
138
|
+
pipeline save that changes the redaction gate withdraw the archive in the
|
|
139
|
+
same transaction and build a fresh one. An archive is stamped with the
|
|
140
|
+
redaction gate it was built under, and is a 404 under any other (for
|
|
141
|
+
example once a mutator plugin is removed) until `images.reconcile` rebuilds it.
|
|
142
|
+
- The `images.tippecanoe` health check is degraded while the binary cannot be
|
|
143
|
+
found. Points keep working.
|
|
144
|
+
- The points are drawn over the basemap `map_style_url` names (OpenFreeMap's
|
|
145
|
+
Positron by default; its origin is added to the CSP). Viewers' browsers
|
|
146
|
+
fetch its tiles from that host, so it sees their IP and the area they view;
|
|
147
|
+
set it to empty for a flat background with no third-party request. A style
|
|
148
|
+
that cannot be fetched falls back to the flat background.
|
|
149
|
+
|
|
150
|
+
## Documentation
|
|
151
|
+
|
|
152
|
+
| Page | For |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| [docs/index.md](docs/index.md) | Concepts, install, permissions, every setting |
|
|
155
|
+
| [docs/access.md](docs/access.md) | Visibility, shares, originals, withheld images |
|
|
156
|
+
| [docs/imports.md](docs/imports.md) | Uploads, direct upload and bucket CORS, ZIP, GeoJSON, limits |
|
|
157
|
+
| [docs/pipeline.md](docs/pipeline.md) | Steps, leases, AI prompts, groups, presets, review, storage metering |
|
|
158
|
+
| [docs/writing-a-plugin.md](docs/writing-a-plugin.md) | Steps, presets and result views from another module |
|
|
159
|
+
| [docs/worker.md](docs/worker.md) | Workers, beat, timeouts, tuning, recovery times |
|
|
160
|
+
| [docs/migrating-from-portal.md](docs/migrating-from-portal.md) | Moving off the portal's feature |
|