iscc-search 0.1.0__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.
- iscc_search-0.1.0/.dockerignore +11 -0
- iscc_search-0.1.0/.editorconfig +20 -0
- iscc_search-0.1.0/.env.example +85 -0
- iscc_search-0.1.0/.gitattributes +25 -0
- iscc_search-0.1.0/.github/actions/setup-python-env/action.yml +30 -0
- iscc_search-0.1.0/.github/workflows/ci.yml +223 -0
- iscc_search-0.1.0/.github/workflows/release.yml +235 -0
- iscc_search-0.1.0/.gitignore +168 -0
- iscc_search-0.1.0/.pre-commit-config.yaml +31 -0
- iscc_search-0.1.0/CHANGELOG.md +55 -0
- iscc_search-0.1.0/CLAUDE.md +230 -0
- iscc_search-0.1.0/CNAME +1 -0
- iscc_search-0.1.0/CONTRIBUTING.md +123 -0
- iscc_search-0.1.0/Dockerfile +45 -0
- iscc_search-0.1.0/LICENSE +202 -0
- iscc_search-0.1.0/PKG-INFO +231 -0
- iscc_search-0.1.0/README.md +190 -0
- iscc_search-0.1.0/compose.yaml +49 -0
- iscc_search-0.1.0/docs/CNAME +1 -0
- iscc_search-0.1.0/docs/assets/favicon.png +0 -0
- iscc_search-0.1.0/docs/assets/logo_dark.png +0 -0
- iscc_search-0.1.0/docs/assets/logo_light.png +0 -0
- iscc_search-0.1.0/docs/development/contributing.md +95 -0
- iscc_search-0.1.0/docs/explanation/architecture.md +132 -0
- iscc_search-0.1.0/docs/explanation/iscc-primer.md +112 -0
- iscc_search-0.1.0/docs/explanation/similarity-search.md +152 -0
- iscc_search-0.1.0/docs/howto/cli.md +189 -0
- iscc_search-0.1.0/docs/howto/deployment.md +218 -0
- iscc_search-0.1.0/docs/howto/index-backends.md +99 -0
- iscc_search-0.1.0/docs/howto/rest-api.md +160 -0
- iscc_search-0.1.0/docs/includes/abbreviations.md +17 -0
- iscc_search-0.1.0/docs/index.md +108 -0
- iscc_search-0.1.0/docs/javascripts/copilot.js +27 -0
- iscc_search-0.1.0/docs/javascripts/copypage.js +202 -0
- iscc_search-0.1.0/docs/llms.txt +34 -0
- iscc_search-0.1.0/docs/overrides/main.html +28 -0
- iscc_search-0.1.0/docs/reference/api.md +34 -0
- iscc_search-0.1.0/docs/reference/configuration.md +125 -0
- iscc_search-0.1.0/docs/reference/for-coding-agents.md +344 -0
- iscc_search-0.1.0/docs/robots.txt +2 -0
- iscc_search-0.1.0/docs/stylesheets/copilot.css +119 -0
- iscc_search-0.1.0/docs/stylesheets/extra.css +289 -0
- iscc_search-0.1.0/docs/tutorials/getting-started.md +229 -0
- iscc_search-0.1.0/iscc_search/__init__.py +13 -0
- iscc_search-0.1.0/iscc_search/cli/__init__.py +55 -0
- iscc_search-0.1.0/iscc_search/cli/__main__.py +6 -0
- iscc_search-0.1.0/iscc_search/cli/add.py +343 -0
- iscc_search-0.1.0/iscc_search/cli/common.py +190 -0
- iscc_search-0.1.0/iscc_search/cli/datasets.py +85 -0
- iscc_search-0.1.0/iscc_search/cli/get.py +74 -0
- iscc_search-0.1.0/iscc_search/cli/hub.py +332 -0
- iscc_search-0.1.0/iscc_search/cli/index.py +225 -0
- iscc_search-0.1.0/iscc_search/cli/search.py +70 -0
- iscc_search-0.1.0/iscc_search/cli/serve.py +78 -0
- iscc_search-0.1.0/iscc_search/config.py +429 -0
- iscc_search-0.1.0/iscc_search/indexes/__init__.py +0 -0
- iscc_search-0.1.0/iscc_search/indexes/common.py +270 -0
- iscc_search-0.1.0/iscc_search/indexes/lmdb/__init__.py +12 -0
- iscc_search-0.1.0/iscc_search/indexes/lmdb/index.py +507 -0
- iscc_search-0.1.0/iscc_search/indexes/lmdb/manager.py +240 -0
- iscc_search-0.1.0/iscc_search/indexes/memory/__init__.py +5 -0
- iscc_search-0.1.0/iscc_search/indexes/memory/index.py +244 -0
- iscc_search-0.1.0/iscc_search/indexes/simprint/__init__.py +7 -0
- iscc_search-0.1.0/iscc_search/indexes/simprint/lmdb_ops.py +315 -0
- iscc_search-0.1.0/iscc_search/indexes/simprint/models.py +46 -0
- iscc_search-0.1.0/iscc_search/indexes/simprint/usearch_core.py +277 -0
- iscc_search-0.1.0/iscc_search/indexes/usearch/__init__.py +17 -0
- iscc_search-0.1.0/iscc_search/indexes/usearch/index.py +1634 -0
- iscc_search-0.1.0/iscc_search/indexes/usearch/manager.py +274 -0
- iscc_search-0.1.0/iscc_search/log_config.json +45 -0
- iscc_search-0.1.0/iscc_search/models.py +420 -0
- iscc_search-0.1.0/iscc_search/openapi/CommonProperties.yaml +23 -0
- iscc_search-0.1.0/iscc_search/openapi/HttpError.yaml +17 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccAddResult.yaml +28 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccChunk.yaml +151 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccChunkMatch.yaml +203 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccEntry.yaml +74 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccGlobalMatch.yaml +78 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccIndex.yaml +31 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccMatchedChunk.yaml +90 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccMetadata.yaml +52 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccQuery.yaml +121 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccSearchResult.yaml +55 -0
- iscc_search-0.1.0/iscc_search/openapi/IsccSimprint.yaml +66 -0
- iscc_search-0.1.0/iscc_search/openapi/TextQuery.yaml +15 -0
- iscc_search-0.1.0/iscc_search/openapi/openapi.json +1914 -0
- iscc_search-0.1.0/iscc_search/openapi/openapi.yaml +615 -0
- iscc_search-0.1.0/iscc_search/options.py +296 -0
- iscc_search-0.1.0/iscc_search/processing.py +69 -0
- iscc_search-0.1.0/iscc_search/protocols/__init__.py +0 -0
- iscc_search-0.1.0/iscc_search/protocols/index.py +170 -0
- iscc_search-0.1.0/iscc_search/remote/__init__.py +9 -0
- iscc_search-0.1.0/iscc_search/remote/client.py +260 -0
- iscc_search-0.1.0/iscc_search/schema.py +538 -0
- iscc_search-0.1.0/iscc_search/server/__init__.py +273 -0
- iscc_search-0.1.0/iscc_search/server/__main__.py +25 -0
- iscc_search-0.1.0/iscc_search/server/assets.py +73 -0
- iscc_search-0.1.0/iscc_search/server/auth.py +35 -0
- iscc_search-0.1.0/iscc_search/server/indexes.py +103 -0
- iscc_search-0.1.0/iscc_search/server/playground.py +458 -0
- iscc_search-0.1.0/iscc_search/server/search.py +117 -0
- iscc_search-0.1.0/iscc_search/utils.py +5 -0
- iscc_search-0.1.0/mkdocs.yml +58 -0
- iscc_search-0.1.0/pyproject.toml +146 -0
- iscc_search-0.1.0/scripts/bundle_openapi.py +164 -0
- iscc_search-0.1.0/scripts/gen_llms_full.py +83 -0
- iscc_search-0.1.0/tests/conftest.py +442 -0
- iscc_search-0.1.0/tests/test_cli_common.py +156 -0
- iscc_search-0.1.0/tests/test_cli_index.py +121 -0
- iscc_search-0.1.0/tests/test_cli_serve.py +69 -0
- iscc_search-0.1.0/tests/test_config.py +607 -0
- iscc_search-0.1.0/tests/test_indexes_common.py +341 -0
- iscc_search-0.1.0/tests/test_indexes_lmdb_index.py +476 -0
- iscc_search-0.1.0/tests/test_indexes_lmdb_integration.py +363 -0
- iscc_search-0.1.0/tests/test_indexes_lmdb_manager.py +382 -0
- iscc_search-0.1.0/tests/test_indexes_memory_index.py +516 -0
- iscc_search-0.1.0/tests/test_indexes_simprint_lmdb_ops.py +480 -0
- iscc_search-0.1.0/tests/test_indexes_simprint_models.py +124 -0
- iscc_search-0.1.0/tests/test_indexes_usearch_index.py +815 -0
- iscc_search-0.1.0/tests/test_indexes_usearch_manager.py +514 -0
- iscc_search-0.1.0/tests/test_indexes_usearch_persistence.py +627 -0
- iscc_search-0.1.0/tests/test_indexes_usearch_simprint_approx.py +1260 -0
- iscc_search-0.1.0/tests/test_indexes_usearch_simprint_exact.py +468 -0
- iscc_search-0.1.0/tests/test_indexes_usearch_simprint_m1.py +119 -0
- iscc_search-0.1.0/tests/test_indexes_usearch_simprint_m2.py +316 -0
- iscc_search-0.1.0/tests/test_models.py +369 -0
- iscc_search-0.1.0/tests/test_models_iscc_base.py +402 -0
- iscc_search-0.1.0/tests/test_models_iscc_code.py +430 -0
- iscc_search-0.1.0/tests/test_models_iscc_id.py +665 -0
- iscc_search-0.1.0/tests/test_models_iscc_item.py +665 -0
- iscc_search-0.1.0/tests/test_models_iscc_unit.py +502 -0
- iscc_search-0.1.0/tests/test_options.py +255 -0
- iscc_search-0.1.0/tests/test_processing.py +259 -0
- iscc_search-0.1.0/tests/test_protocols_index.py +260 -0
- iscc_search-0.1.0/tests/test_remote.py +479 -0
- iscc_search-0.1.0/tests/test_server.py +307 -0
- iscc_search-0.1.0/tests/test_server_assets.py +159 -0
- iscc_search-0.1.0/tests/test_server_auth.py +279 -0
- iscc_search-0.1.0/tests/test_server_indexes.py +146 -0
- iscc_search-0.1.0/tests/test_server_search.py +368 -0
- iscc_search-0.1.0/tests/test_usearch_add.py +465 -0
- iscc_search-0.1.0/tests/test_usearch_contains.py +235 -0
- iscc_search-0.1.0/tests/test_usearch_get.py +254 -0
- iscc_search-0.1.0/tests/test_usearch_multi.py +456 -0
- iscc_search-0.1.0/tests/test_usearch_remove.py +282 -0
- iscc_search-0.1.0/tests/test_usearch_search.py +727 -0
- iscc_search-0.1.0/tests/test_utils.py +102 -0
- iscc_search-0.1.0/uv.lock +3114 -0
- iscc_search-0.1.0/zensical.toml +136 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Allowlist-style .dockerignore: ignore everything, then explicitly allow the build inputs.
|
|
2
|
+
# The Docker image installs from a pre-built wheel, so no source files are required in the context.
|
|
3
|
+
# This prevents dev artifacts (cauldron/, .claude/, scratch/, tests/, docs/, .git/, secrets) from
|
|
4
|
+
# ever entering the image layers or being cached by BuildKit.
|
|
5
|
+
|
|
6
|
+
# Ignore everything
|
|
7
|
+
**
|
|
8
|
+
|
|
9
|
+
# Allow the Dockerfile and the pre-built wheel produced by `uv build`
|
|
10
|
+
!Dockerfile
|
|
11
|
+
!dist/*.whl
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# see http://editorconfig.org
|
|
2
|
+
|
|
3
|
+
# Top-level config
|
|
4
|
+
root = true
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# All files
|
|
8
|
+
[*]
|
|
9
|
+
charset = utf-8
|
|
10
|
+
indent_style = space
|
|
11
|
+
indent_size = 4
|
|
12
|
+
end_of_line = lf
|
|
13
|
+
insert_final_newline = true
|
|
14
|
+
trim_trailing_whitespace = true
|
|
15
|
+
max_line_length = 119
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# YAML files
|
|
19
|
+
[*.{yml,yaml}]
|
|
20
|
+
indent_size = 2
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# ISCC-Search Configuration
|
|
2
|
+
# Copy to .env and customize as needed. All values shown are defaults.
|
|
3
|
+
|
|
4
|
+
# --- Server ---
|
|
5
|
+
|
|
6
|
+
# Index backend URI (memory://, lmdb:///path, usearch:///path)
|
|
7
|
+
# Default: usearch:/// + platform-specific user data dir (e.g. ~/.local/share/iscc-search)
|
|
8
|
+
# ISCC_SEARCH_INDEX_URI=usearch:///path/to/data
|
|
9
|
+
|
|
10
|
+
# API secret for authentication (unset = public API)
|
|
11
|
+
# ISCC_SEARCH_API_SECRET=
|
|
12
|
+
|
|
13
|
+
# CORS allowed origins (comma-separated, or * for all)
|
|
14
|
+
# ISCC_SEARCH_CORS_ORIGINS=*
|
|
15
|
+
|
|
16
|
+
# Server host and port
|
|
17
|
+
# ISCC_SEARCH_HOST=0.0.0.0
|
|
18
|
+
# ISCC_SEARCH_PORT=8000
|
|
19
|
+
|
|
20
|
+
# Number of worker processes (production only, unset = single worker)
|
|
21
|
+
# NOTE: workers > 1 is REJECTED with the usearch:// backend — concurrent writers
|
|
22
|
+
# corrupt .usearch files. Leave unset (single worker) for usearch-backed deployments.
|
|
23
|
+
# ISCC_SEARCH_WORKERS=
|
|
24
|
+
|
|
25
|
+
# Auto-flush sub-indexes after N dirty key mutations (0 = disabled).
|
|
26
|
+
# Only safe with a single writer process. Production recommendation: 100000.
|
|
27
|
+
# Reduces blast radius of hard crashes (OOM / SIGKILL / power loss).
|
|
28
|
+
# ISCC_SEARCH_FLUSH_INTERVAL=0
|
|
29
|
+
|
|
30
|
+
# Log level (debug, info, warning, error, critical)
|
|
31
|
+
# ISCC_SEARCH_LOG_LEVEL=info
|
|
32
|
+
|
|
33
|
+
# --- Shard Sizes (MB) ---
|
|
34
|
+
|
|
35
|
+
# Maximum shard file size for ISCC-UNIT indexes
|
|
36
|
+
# ISCC_SEARCH_SHARD_SIZE_UNITS=1024
|
|
37
|
+
|
|
38
|
+
# Maximum shard file size for simprint indexes
|
|
39
|
+
# ISCC_SEARCH_SHARD_SIZE_SIMPRINTS=1024
|
|
40
|
+
|
|
41
|
+
# --- HNSW Parameters (Units) ---
|
|
42
|
+
|
|
43
|
+
# Build-time search depth (efConstruction) for unit indexes
|
|
44
|
+
# ISCC_SEARCH_HNSW_EXPANSION_ADD_UNITS=128
|
|
45
|
+
|
|
46
|
+
# Query-time search depth (ef) for unit indexes
|
|
47
|
+
# ISCC_SEARCH_HNSW_EXPANSION_SEARCH_UNITS=64
|
|
48
|
+
|
|
49
|
+
# Graph connectivity (M) for unit indexes
|
|
50
|
+
# ISCC_SEARCH_HNSW_CONNECTIVITY_UNITS=16
|
|
51
|
+
|
|
52
|
+
# --- HNSW Parameters (Simprints) ---
|
|
53
|
+
|
|
54
|
+
# Build-time search depth (efConstruction) for simprint indexes
|
|
55
|
+
# ISCC_SEARCH_HNSW_EXPANSION_ADD_SIMPRINTS=16
|
|
56
|
+
|
|
57
|
+
# Query-time search depth (ef) for simprint indexes
|
|
58
|
+
# ISCC_SEARCH_HNSW_EXPANSION_SEARCH_SIMPRINTS=512
|
|
59
|
+
|
|
60
|
+
# Graph connectivity (M) for simprint indexes
|
|
61
|
+
# ISCC_SEARCH_HNSW_CONNECTIVITY_SIMPRINTS=8
|
|
62
|
+
|
|
63
|
+
# --- Match Thresholds ---
|
|
64
|
+
|
|
65
|
+
# Minimum score for unit similarity matches (0.0-1.0)
|
|
66
|
+
# ISCC_SEARCH_MATCH_THRESHOLD_UNITS=0.75
|
|
67
|
+
|
|
68
|
+
# Minimum score for simprint matches (0.0-1.0)
|
|
69
|
+
# ISCC_SEARCH_MATCH_THRESHOLD_SIMPRINTS=0.75
|
|
70
|
+
|
|
71
|
+
# --- Scoring ---
|
|
72
|
+
|
|
73
|
+
# Exponent for confidence-weighted score aggregation
|
|
74
|
+
# ISCC_SEARCH_CONFIDENCE_EXPONENT=4
|
|
75
|
+
|
|
76
|
+
# Oversampling multiplier for simprint search diversity
|
|
77
|
+
# ISCC_SEARCH_OVERSAMPLING_FACTOR=20
|
|
78
|
+
|
|
79
|
+
# --- Error Tracking (Sentry) ---
|
|
80
|
+
|
|
81
|
+
# Sentry DSN for error tracking (unset = disabled)
|
|
82
|
+
# ISCC_SEARCH_SENTRY_DSN=
|
|
83
|
+
|
|
84
|
+
# Sentry performance sampling rate (0.0-1.0)
|
|
85
|
+
# ISCC_SEARCH_SENTRY_TRACES_SAMPLE_RATE=0.05
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Set default behavior to automatically normalize line endings
|
|
2
|
+
* text=auto
|
|
3
|
+
|
|
4
|
+
# Force LF line endings for markdown files
|
|
5
|
+
*.md text eol=lf
|
|
6
|
+
|
|
7
|
+
# Force LF for other text files that should have consistent endings
|
|
8
|
+
*.py text eol=lf
|
|
9
|
+
*.yml text eol=lf
|
|
10
|
+
*.yaml text eol=lf
|
|
11
|
+
*.toml text eol=lf
|
|
12
|
+
*.cfg text eol=lf
|
|
13
|
+
*.ini text eol=lf
|
|
14
|
+
*.json text eol=lf
|
|
15
|
+
*.txt text eol=lf
|
|
16
|
+
*.sh text eol=lf
|
|
17
|
+
Makefile text eol=lf
|
|
18
|
+
|
|
19
|
+
# Binary files
|
|
20
|
+
*.png binary
|
|
21
|
+
*.jpg binary
|
|
22
|
+
*.jpeg binary
|
|
23
|
+
*.gif binary
|
|
24
|
+
*.ico binary
|
|
25
|
+
*.pdf binary
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: "Setup Python Environment"
|
|
2
|
+
description: "Set up Python environment for the given Python version"
|
|
3
|
+
|
|
4
|
+
inputs:
|
|
5
|
+
python-version:
|
|
6
|
+
description: "Python version to use"
|
|
7
|
+
required: true
|
|
8
|
+
default: "3.12"
|
|
9
|
+
uv-version:
|
|
10
|
+
description: "uv version to use"
|
|
11
|
+
required: true
|
|
12
|
+
default: "0.6.14"
|
|
13
|
+
|
|
14
|
+
runs:
|
|
15
|
+
using: "composite"
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/setup-python@v6
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ inputs.python-version }}
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v8.0.0
|
|
23
|
+
with:
|
|
24
|
+
version: ${{ inputs.uv-version }}
|
|
25
|
+
enable-cache: 'true'
|
|
26
|
+
cache-suffix: ${{ matrix.python-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install Python dependencies
|
|
29
|
+
run: uv sync --frozen
|
|
30
|
+
shell: bash
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [develop, main]
|
|
7
|
+
|
|
8
|
+
# Cancel stale in-flight PR runs; let push runs complete so publish isn't cancelled.
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test-full:
|
|
18
|
+
name: Test (ubuntu-latest, py${{ matrix.python-version }})
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
23
|
+
fail-fast: false
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v6
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0 # hatch-vcs needs git history to derive version
|
|
28
|
+
|
|
29
|
+
- uses: ./.github/actions/setup-python-env
|
|
30
|
+
with:
|
|
31
|
+
python-version: ${{ matrix.python-version }}
|
|
32
|
+
|
|
33
|
+
# Cache the iscc-sct ONNX model across runs. Parallel pytest-xdist workers
|
|
34
|
+
# otherwise race on the download and can produce a corrupt ONNX file.
|
|
35
|
+
- name: Cache iscc-sct model
|
|
36
|
+
uses: actions/cache@v5
|
|
37
|
+
with:
|
|
38
|
+
path: |
|
|
39
|
+
~/.local/share/iscc-sct
|
|
40
|
+
~/Library/Application Support/iscc-sct
|
|
41
|
+
~\AppData\Local\iscc\iscc-sct
|
|
42
|
+
key: iscc-sct-model-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
43
|
+
restore-keys: |
|
|
44
|
+
iscc-sct-model-${{ runner.os }}-
|
|
45
|
+
|
|
46
|
+
- name: Pre-download iscc-sct model (serial, before parallel tests)
|
|
47
|
+
run: uv run python -c "import iscc_sct.code_semantic_text as sct; sct.model()"
|
|
48
|
+
|
|
49
|
+
- name: OpenAPI build + validation
|
|
50
|
+
run: uv run poe build
|
|
51
|
+
|
|
52
|
+
- name: Run tests
|
|
53
|
+
run: uv run poe test
|
|
54
|
+
|
|
55
|
+
- name: Upload coverage to Codecov
|
|
56
|
+
if: matrix.python-version == '3.11'
|
|
57
|
+
uses: codecov/codecov-action@v6
|
|
58
|
+
env:
|
|
59
|
+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
60
|
+
|
|
61
|
+
test-smoke:
|
|
62
|
+
name: Test (${{ matrix.os }}, py3.12)
|
|
63
|
+
runs-on: ${{ matrix.os }}
|
|
64
|
+
strategy:
|
|
65
|
+
matrix:
|
|
66
|
+
os: [windows-latest, macos-latest]
|
|
67
|
+
fail-fast: false
|
|
68
|
+
defaults:
|
|
69
|
+
run:
|
|
70
|
+
shell: bash
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v6
|
|
73
|
+
with:
|
|
74
|
+
fetch-depth: 0
|
|
75
|
+
|
|
76
|
+
- uses: ./.github/actions/setup-python-env
|
|
77
|
+
with:
|
|
78
|
+
python-version: "3.12"
|
|
79
|
+
|
|
80
|
+
- name: Cache iscc-sct model
|
|
81
|
+
uses: actions/cache@v5
|
|
82
|
+
with:
|
|
83
|
+
path: |
|
|
84
|
+
~/.local/share/iscc-sct
|
|
85
|
+
~/Library/Application Support/iscc-sct
|
|
86
|
+
~\AppData\Local\iscc\iscc-sct
|
|
87
|
+
key: iscc-sct-model-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
88
|
+
restore-keys: |
|
|
89
|
+
iscc-sct-model-${{ runner.os }}-
|
|
90
|
+
|
|
91
|
+
- name: Pre-download iscc-sct model
|
|
92
|
+
run: uv run python -c "import iscc_sct.code_semantic_text as sct; sct.model()"
|
|
93
|
+
|
|
94
|
+
- name: Run tests
|
|
95
|
+
run: uv run poe test
|
|
96
|
+
|
|
97
|
+
wheel-build:
|
|
98
|
+
name: Build wheel
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
steps:
|
|
101
|
+
- uses: actions/checkout@v6
|
|
102
|
+
with:
|
|
103
|
+
fetch-depth: 0
|
|
104
|
+
|
|
105
|
+
- uses: ./.github/actions/setup-python-env
|
|
106
|
+
|
|
107
|
+
- name: Build wheel + sdist
|
|
108
|
+
run: uv build
|
|
109
|
+
|
|
110
|
+
- name: Upload dist artifact
|
|
111
|
+
uses: actions/upload-artifact@v6
|
|
112
|
+
with:
|
|
113
|
+
name: dist
|
|
114
|
+
path: dist/
|
|
115
|
+
retention-days: 7
|
|
116
|
+
|
|
117
|
+
wheel-smoke:
|
|
118
|
+
name: Install wheel and smoke-test
|
|
119
|
+
needs: wheel-build
|
|
120
|
+
runs-on: ubuntu-latest
|
|
121
|
+
steps:
|
|
122
|
+
- uses: actions/setup-python@v6
|
|
123
|
+
with:
|
|
124
|
+
python-version: "3.12"
|
|
125
|
+
|
|
126
|
+
- uses: actions/download-artifact@v7
|
|
127
|
+
with:
|
|
128
|
+
name: dist
|
|
129
|
+
path: dist
|
|
130
|
+
|
|
131
|
+
- name: Install wheel into clean venv
|
|
132
|
+
run: |
|
|
133
|
+
python -m venv .smoke-venv
|
|
134
|
+
.smoke-venv/bin/pip install --upgrade pip
|
|
135
|
+
.smoke-venv/bin/pip install dist/*.whl
|
|
136
|
+
|
|
137
|
+
- name: Verify import and CLI
|
|
138
|
+
run: |
|
|
139
|
+
.smoke-venv/bin/python -c "import iscc_search; print('version:', iscc_search.__version__)"
|
|
140
|
+
.smoke-venv/bin/iscc-search --help
|
|
141
|
+
|
|
142
|
+
docker-smoke:
|
|
143
|
+
name: Build + smoke-test Docker image
|
|
144
|
+
needs: wheel-build
|
|
145
|
+
runs-on: ubuntu-latest
|
|
146
|
+
steps:
|
|
147
|
+
- uses: actions/checkout@v6
|
|
148
|
+
|
|
149
|
+
- uses: actions/download-artifact@v7
|
|
150
|
+
with:
|
|
151
|
+
name: dist
|
|
152
|
+
path: dist
|
|
153
|
+
|
|
154
|
+
- uses: docker/setup-buildx-action@v4
|
|
155
|
+
|
|
156
|
+
- name: Build image (load into local daemon)
|
|
157
|
+
uses: docker/build-push-action@v7
|
|
158
|
+
with:
|
|
159
|
+
context: .
|
|
160
|
+
file: ./Dockerfile
|
|
161
|
+
load: true
|
|
162
|
+
tags: iscc-search:smoke
|
|
163
|
+
cache-from: type=gha
|
|
164
|
+
cache-to: type=gha,mode=max
|
|
165
|
+
|
|
166
|
+
- name: Run container and probe health endpoints
|
|
167
|
+
run: |
|
|
168
|
+
docker run -d --name iscc-search-smoke -p 8000:8000 iscc-search:smoke
|
|
169
|
+
# Wait up to 60s for /readyz to return 200
|
|
170
|
+
for i in $(seq 1 30); do
|
|
171
|
+
if curl -sf http://localhost:8000/readyz > /dev/null; then
|
|
172
|
+
echo "Ready after ${i} attempts"
|
|
173
|
+
break
|
|
174
|
+
fi
|
|
175
|
+
sleep 2
|
|
176
|
+
done
|
|
177
|
+
curl -sf http://localhost:8000/healthz
|
|
178
|
+
curl -sf http://localhost:8000/readyz
|
|
179
|
+
echo "--- container logs ---"
|
|
180
|
+
docker logs iscc-search-smoke
|
|
181
|
+
docker stop iscc-search-smoke
|
|
182
|
+
|
|
183
|
+
publish-develop:
|
|
184
|
+
name: Publish Docker image (develop)
|
|
185
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
|
|
186
|
+
needs: [test-full, test-smoke, wheel-smoke, docker-smoke]
|
|
187
|
+
runs-on: ubuntu-latest
|
|
188
|
+
permissions:
|
|
189
|
+
contents: read
|
|
190
|
+
packages: write
|
|
191
|
+
steps:
|
|
192
|
+
- uses: actions/checkout@v6
|
|
193
|
+
|
|
194
|
+
- uses: actions/download-artifact@v7
|
|
195
|
+
with:
|
|
196
|
+
name: dist
|
|
197
|
+
path: dist
|
|
198
|
+
|
|
199
|
+
- uses: docker/setup-buildx-action@v4
|
|
200
|
+
|
|
201
|
+
- uses: docker/login-action@v4
|
|
202
|
+
with:
|
|
203
|
+
registry: ghcr.io
|
|
204
|
+
username: ${{ github.actor }}
|
|
205
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
206
|
+
|
|
207
|
+
- id: meta
|
|
208
|
+
uses: docker/metadata-action@v6
|
|
209
|
+
with:
|
|
210
|
+
images: ghcr.io/${{ github.repository }}
|
|
211
|
+
tags: |
|
|
212
|
+
type=raw,value=develop
|
|
213
|
+
type=sha,prefix=develop-
|
|
214
|
+
|
|
215
|
+
- name: Build and push
|
|
216
|
+
uses: docker/build-push-action@v7
|
|
217
|
+
with:
|
|
218
|
+
context: .
|
|
219
|
+
file: ./Dockerfile
|
|
220
|
+
push: true
|
|
221
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
222
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
223
|
+
cache-from: type=gha
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Triggered when a GitHub Release is published. The release tag (vX.Y.Z) becomes the package version
|
|
4
|
+
# via hatch-vcs. Pre-release tags (v1.0.0-rc1) publish to PyPI + ghcr but do NOT update `latest`.
|
|
5
|
+
on:
|
|
6
|
+
release:
|
|
7
|
+
types: [published]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Test (ubuntu-latest, py${{ matrix.python-version }})
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
19
|
+
fail-fast: false
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v6
|
|
22
|
+
with:
|
|
23
|
+
fetch-depth: 0
|
|
24
|
+
|
|
25
|
+
- uses: ./.github/actions/setup-python-env
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
|
|
29
|
+
- name: Cache iscc-sct model
|
|
30
|
+
uses: actions/cache@v5
|
|
31
|
+
with:
|
|
32
|
+
path: |
|
|
33
|
+
~/.local/share/iscc-sct
|
|
34
|
+
~/Library/Application Support/iscc-sct
|
|
35
|
+
~\AppData\Local\iscc\iscc-sct
|
|
36
|
+
key: iscc-sct-model-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
37
|
+
restore-keys: |
|
|
38
|
+
iscc-sct-model-${{ runner.os }}-
|
|
39
|
+
|
|
40
|
+
- name: Pre-download iscc-sct model
|
|
41
|
+
run: uv run python -c "import iscc_sct.code_semantic_text as sct; sct.model()"
|
|
42
|
+
|
|
43
|
+
- name: OpenAPI build + validation
|
|
44
|
+
run: uv run poe build
|
|
45
|
+
|
|
46
|
+
- name: Run tests
|
|
47
|
+
run: uv run poe test
|
|
48
|
+
|
|
49
|
+
test-smoke:
|
|
50
|
+
name: Test (${{ matrix.os }}, py3.12)
|
|
51
|
+
runs-on: ${{ matrix.os }}
|
|
52
|
+
strategy:
|
|
53
|
+
matrix:
|
|
54
|
+
os: [windows-latest, macos-latest]
|
|
55
|
+
fail-fast: false
|
|
56
|
+
defaults:
|
|
57
|
+
run:
|
|
58
|
+
shell: bash
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v6
|
|
61
|
+
with:
|
|
62
|
+
fetch-depth: 0
|
|
63
|
+
|
|
64
|
+
- uses: ./.github/actions/setup-python-env
|
|
65
|
+
with:
|
|
66
|
+
python-version: "3.12"
|
|
67
|
+
|
|
68
|
+
- name: Cache iscc-sct model
|
|
69
|
+
uses: actions/cache@v5
|
|
70
|
+
with:
|
|
71
|
+
path: |
|
|
72
|
+
~/.local/share/iscc-sct
|
|
73
|
+
~/Library/Application Support/iscc-sct
|
|
74
|
+
~\AppData\Local\iscc\iscc-sct
|
|
75
|
+
key: iscc-sct-model-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
76
|
+
restore-keys: |
|
|
77
|
+
iscc-sct-model-${{ runner.os }}-
|
|
78
|
+
|
|
79
|
+
- name: Pre-download iscc-sct model
|
|
80
|
+
run: uv run python -c "import iscc_sct.code_semantic_text as sct; sct.model()"
|
|
81
|
+
|
|
82
|
+
- name: Run tests
|
|
83
|
+
run: uv run poe test
|
|
84
|
+
|
|
85
|
+
wheel-build:
|
|
86
|
+
name: Build wheel + sdist
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/checkout@v6
|
|
90
|
+
with:
|
|
91
|
+
fetch-depth: 0
|
|
92
|
+
|
|
93
|
+
- uses: ./.github/actions/setup-python-env
|
|
94
|
+
|
|
95
|
+
- name: Build
|
|
96
|
+
run: uv build
|
|
97
|
+
|
|
98
|
+
- name: Verify version matches release tag
|
|
99
|
+
run: |
|
|
100
|
+
# hatch-vcs strips the leading `v` from tags, so `v0.1.0` → `0.1.0`
|
|
101
|
+
expected="${GITHUB_REF_NAME#v}"
|
|
102
|
+
actual=$(ls dist/iscc_search-*.whl | sed -E 's|dist/iscc_search-([^-]+)-.*|\1|' | head -1)
|
|
103
|
+
if [ "$expected" != "$actual" ]; then
|
|
104
|
+
echo "::error::Wheel version ($actual) does not match release tag ($expected)"
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
echo "Version verified: $actual"
|
|
108
|
+
|
|
109
|
+
- uses: actions/upload-artifact@v6
|
|
110
|
+
with:
|
|
111
|
+
name: dist
|
|
112
|
+
path: dist/
|
|
113
|
+
retention-days: 30
|
|
114
|
+
|
|
115
|
+
wheel-smoke:
|
|
116
|
+
name: Smoke-test wheel (${{ matrix.os }})
|
|
117
|
+
needs: wheel-build
|
|
118
|
+
runs-on: ${{ matrix.os }}
|
|
119
|
+
strategy:
|
|
120
|
+
matrix:
|
|
121
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
122
|
+
fail-fast: false
|
|
123
|
+
defaults:
|
|
124
|
+
run:
|
|
125
|
+
shell: bash
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/setup-python@v6
|
|
128
|
+
with:
|
|
129
|
+
python-version: "3.12"
|
|
130
|
+
|
|
131
|
+
- uses: actions/download-artifact@v7
|
|
132
|
+
with:
|
|
133
|
+
name: dist
|
|
134
|
+
path: dist
|
|
135
|
+
|
|
136
|
+
- name: Install and verify
|
|
137
|
+
run: |
|
|
138
|
+
python -m venv .smoke-venv
|
|
139
|
+
# Cross-platform venv bin dir:
|
|
140
|
+
if [ -d ".smoke-venv/Scripts" ]; then
|
|
141
|
+
BIN=.smoke-venv/Scripts
|
|
142
|
+
else
|
|
143
|
+
BIN=.smoke-venv/bin
|
|
144
|
+
fi
|
|
145
|
+
"$BIN/python" -m pip install --upgrade pip
|
|
146
|
+
"$BIN/python" -m pip install dist/*.whl
|
|
147
|
+
"$BIN/python" -c "import iscc_search; print('version:', iscc_search.__version__)"
|
|
148
|
+
"$BIN/iscc-search" --help
|
|
149
|
+
|
|
150
|
+
publish-pypi:
|
|
151
|
+
name: Publish to PyPI
|
|
152
|
+
needs: [test, test-smoke, wheel-smoke]
|
|
153
|
+
runs-on: ubuntu-latest
|
|
154
|
+
environment: pypi
|
|
155
|
+
steps:
|
|
156
|
+
- uses: actions/download-artifact@v7
|
|
157
|
+
with:
|
|
158
|
+
name: dist
|
|
159
|
+
path: dist
|
|
160
|
+
|
|
161
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
162
|
+
with:
|
|
163
|
+
version: "0.6.14"
|
|
164
|
+
|
|
165
|
+
- name: Publish
|
|
166
|
+
run: uv publish dist/*
|
|
167
|
+
env:
|
|
168
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
|
169
|
+
|
|
170
|
+
publish-docker:
|
|
171
|
+
name: Publish Docker image
|
|
172
|
+
needs: [test, test-smoke, wheel-smoke]
|
|
173
|
+
runs-on: ubuntu-latest
|
|
174
|
+
permissions:
|
|
175
|
+
contents: read
|
|
176
|
+
packages: write
|
|
177
|
+
steps:
|
|
178
|
+
- uses: actions/checkout@v6
|
|
179
|
+
|
|
180
|
+
- uses: actions/download-artifact@v7
|
|
181
|
+
with:
|
|
182
|
+
name: dist
|
|
183
|
+
path: dist
|
|
184
|
+
|
|
185
|
+
- uses: docker/setup-buildx-action@v4
|
|
186
|
+
|
|
187
|
+
- uses: docker/login-action@v4
|
|
188
|
+
with:
|
|
189
|
+
registry: ghcr.io
|
|
190
|
+
username: ${{ github.actor }}
|
|
191
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
192
|
+
|
|
193
|
+
- id: meta
|
|
194
|
+
uses: docker/metadata-action@v6
|
|
195
|
+
with:
|
|
196
|
+
images: ghcr.io/${{ github.repository }}
|
|
197
|
+
# `latest=auto` attaches `latest` only to the highest non-prerelease tag.
|
|
198
|
+
flavor: |
|
|
199
|
+
latest=auto
|
|
200
|
+
tags: |
|
|
201
|
+
type=semver,pattern={{version}}
|
|
202
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
203
|
+
type=semver,pattern={{major}}
|
|
204
|
+
|
|
205
|
+
- name: Build and push
|
|
206
|
+
uses: docker/build-push-action@v7
|
|
207
|
+
with:
|
|
208
|
+
context: .
|
|
209
|
+
file: ./Dockerfile
|
|
210
|
+
push: true
|
|
211
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
212
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
213
|
+
cache-from: type=gha
|
|
214
|
+
cache-to: type=gha,mode=max
|
|
215
|
+
|
|
216
|
+
deploy-docs:
|
|
217
|
+
name: Deploy documentation
|
|
218
|
+
needs: publish-pypi
|
|
219
|
+
runs-on: ubuntu-latest
|
|
220
|
+
permissions:
|
|
221
|
+
contents: write # zensical gh-deploy pushes to gh-pages
|
|
222
|
+
steps:
|
|
223
|
+
- uses: actions/checkout@v6
|
|
224
|
+
with:
|
|
225
|
+
fetch-depth: 0
|
|
226
|
+
|
|
227
|
+
- uses: ./.github/actions/setup-python-env
|
|
228
|
+
|
|
229
|
+
- name: Build docs
|
|
230
|
+
run: |
|
|
231
|
+
uv run zensical build
|
|
232
|
+
uv run python scripts/gen_llms_full.py
|
|
233
|
+
|
|
234
|
+
- name: Deploy to gh-pages
|
|
235
|
+
run: uv run zensical gh-deploy --force
|