hugpy-storage 0.2.2__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.
- hugpy_storage-0.2.2/LICENSE +41 -0
- hugpy_storage-0.2.2/PKG-INFO +41 -0
- hugpy_storage-0.2.2/README.md +7 -0
- hugpy_storage-0.2.2/docs/REGISTRY-DB-INDEX.md +109 -0
- hugpy_storage-0.2.2/pyproject.toml +71 -0
- hugpy_storage-0.2.2/setup.cfg +4 -0
- hugpy_storage-0.2.2/src/hugpy_storage/__init__.py +56 -0
- hugpy_storage-0.2.2/src/hugpy_storage/admission.py +435 -0
- hugpy_storage-0.2.2/src/hugpy_storage/archive_mark.py +136 -0
- hugpy_storage-0.2.2/src/hugpy_storage/catalog_source.py +269 -0
- hugpy_storage-0.2.2/src/hugpy_storage/cli.py +98 -0
- hugpy_storage-0.2.2/src/hugpy_storage/console/__init__.py +0 -0
- hugpy_storage-0.2.2/src/hugpy_storage/console/cancelable_downloads.py +87 -0
- hugpy_storage-0.2.2/src/hugpy_storage/console/downloader.py +113 -0
- hugpy_storage-0.2.2/src/hugpy_storage/console/downloads.py +57 -0
- hugpy_storage-0.2.2/src/hugpy_storage/console/model_physical.py +557 -0
- hugpy_storage-0.2.2/src/hugpy_storage/deploy/hugpy-downloader-dev.service +58 -0
- hugpy_storage-0.2.2/src/hugpy_storage/download_models.py +751 -0
- hugpy_storage-0.2.2/src/hugpy_storage/downloader/__init__.py +34 -0
- hugpy_storage-0.2.2/src/hugpy_storage/downloader/__main__.py +8 -0
- hugpy_storage-0.2.2/src/hugpy_storage/downloader/daemon.py +333 -0
- hugpy_storage-0.2.2/src/hugpy_storage/downloader/engine.py +577 -0
- hugpy_storage-0.2.2/src/hugpy_storage/downloader/presence.py +73 -0
- hugpy_storage-0.2.2/src/hugpy_storage/downloader/queue.py +253 -0
- hugpy_storage-0.2.2/src/hugpy_storage/env.py +16 -0
- hugpy_storage-0.2.2/src/hugpy_storage/events.py +53 -0
- hugpy_storage-0.2.2/src/hugpy_storage/format_select.py +368 -0
- hugpy_storage-0.2.2/src/hugpy_storage/gguf_inspect.py +766 -0
- hugpy_storage-0.2.2/src/hugpy_storage/hf_metadata.py +29 -0
- hugpy_storage-0.2.2/src/hugpy_storage/hf_token.py +228 -0
- hugpy_storage-0.2.2/src/hugpy_storage/huggingface_api.py +240 -0
- hugpy_storage-0.2.2/src/hugpy_storage/hugpy_marker.py +811 -0
- hugpy_storage-0.2.2/src/hugpy_storage/model_config_shim.py +16 -0
- hugpy_storage-0.2.2/src/hugpy_storage/model_metadata.py +640 -0
- hugpy_storage-0.2.2/src/hugpy_storage/model_paths.py +439 -0
- hugpy_storage-0.2.2/src/hugpy_storage/model_physical.py +614 -0
- hugpy_storage-0.2.2/src/hugpy_storage/model_presence.py +321 -0
- hugpy_storage-0.2.2/src/hugpy_storage/model_status_cache.py +413 -0
- hugpy_storage-0.2.2/src/hugpy_storage/model_sync.py +162 -0
- hugpy_storage-0.2.2/src/hugpy_storage/providers.py +151 -0
- hugpy_storage-0.2.2/src/hugpy_storage/provision.py +2143 -0
- hugpy_storage-0.2.2/src/hugpy_storage/py.typed +0 -0
- hugpy_storage-0.2.2/src/hugpy_storage/schemas/__init__.py +0 -0
- hugpy_storage-0.2.2/src/hugpy_storage/schemas/download_schemas.py +43 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/PKG-INFO +41 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/SOURCES.txt +66 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/dependency_links.txt +1 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/entry_points.txt +3 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/requires.txt +10 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/scm_file_list.json +62 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/scm_version.json +8 -0
- hugpy_storage-0.2.2/src/hugpy_storage.egg-info/top_level.txt +1 -0
- hugpy_storage-0.2.2/tests/conftest.py +24 -0
- hugpy_storage-0.2.2/tests/test_admission_hook.py +178 -0
- hugpy_storage-0.2.2/tests/test_catalog_changed_event.py +90 -0
- hugpy_storage-0.2.2/tests/test_catalog_source.py +105 -0
- hugpy_storage-0.2.2/tests/test_cli_and_console.py +116 -0
- hugpy_storage-0.2.2/tests/test_download_queue_recovery.py +450 -0
- hugpy_storage-0.2.2/tests/test_downloader_queue.py +210 -0
- hugpy_storage-0.2.2/tests/test_import_policy.py +107 -0
- hugpy_storage-0.2.2/tests/test_install_manifest.py +171 -0
- hugpy_storage-0.2.2/tests/test_is_model_dir_owner_levels.py +68 -0
- hugpy_storage-0.2.2/tests/test_paths_archive_exclusion.py +82 -0
- hugpy_storage-0.2.2/tests/test_promote_finalize.py +115 -0
- hugpy_storage-0.2.2/tests/test_providers_and_presence.py +203 -0
- hugpy_storage-0.2.2/tests/test_transfer_rate.py +87 -0
- hugpy_storage-0.2.2/tests/test_worker_central_only.py +194 -0
- hugpy_storage-0.2.2/tests/test_worker_puller_auth.py +250 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
hugpy — Source-Available License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 putkoff (hugpy.ai). All rights reserved.
|
|
4
|
+
|
|
5
|
+
Permission is granted, free of charge, to use this software ("hugpy") for
|
|
6
|
+
personal and non-commercial purposes, and for time-limited commercial
|
|
7
|
+
evaluation, subject to the following conditions:
|
|
8
|
+
|
|
9
|
+
1. Non-commercial use means use by an individual for personal purposes, or
|
|
10
|
+
use by a non-profit or educational institution for its own internal
|
|
11
|
+
purposes. Any use by, for, or on behalf of a for-profit business or in
|
|
12
|
+
connection with revenue-generating activity is commercial use — including
|
|
13
|
+
internal business use, use in producing goods or services, and use on
|
|
14
|
+
paid engagements.
|
|
15
|
+
|
|
16
|
+
2. Commercial use requires a commercial license from the copyright holder.
|
|
17
|
+
Exception: a business may evaluate the software internally for up to
|
|
18
|
+
thirty (30) days free of charge; continued use after that requires a
|
|
19
|
+
commercial license.
|
|
20
|
+
|
|
21
|
+
3. Redistribution of this software, in source or binary form, modified or
|
|
22
|
+
unmodified, is not permitted without prior written permission from the
|
|
23
|
+
copyright holder. Downloading the software from an official distribution
|
|
24
|
+
channel (PyPI, npm, hugpy.ai) is not redistribution.
|
|
25
|
+
|
|
26
|
+
4. Modification for personal use or internal evaluation is permitted;
|
|
27
|
+
distribution of modified versions is not.
|
|
28
|
+
|
|
29
|
+
5. This notice must be retained in all copies or substantial portions of
|
|
30
|
+
the software.
|
|
31
|
+
|
|
32
|
+
6. Any use outside these terms automatically terminates this license.
|
|
33
|
+
|
|
34
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
35
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
36
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
37
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING
|
|
38
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
39
|
+
IN THE SOFTWARE.
|
|
40
|
+
|
|
41
|
+
For commercial licensing or redistribution permission: https://hugpy.ai
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hugpy-storage
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Hugpy storage: model download queue and daemon, Hugging Face transport and token, resumable transfers, model sync, physical inventory and on-disk model layout
|
|
5
|
+
Author-email: putkoff <support@hugpy.ai>
|
|
6
|
+
License-Expression: LicenseRef-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://hugpy.ai
|
|
8
|
+
Project-URL: Documentation, https://github.com/hugpy/hugpy/blob/main/py/storage/hugpy_storage/README.md
|
|
9
|
+
Project-URL: Repository, https://github.com/hugpy/hugpy
|
|
10
|
+
Project-URL: Source, https://github.com/hugpy/hugpy/tree/main/py/storage/hugpy_storage
|
|
11
|
+
Project-URL: Issues, https://github.com/hugpy/hugpy/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/hugpy/hugpy/releases
|
|
13
|
+
Project-URL: Architecture, https://github.com/hugpy/hugpy/blob/main/PARTITION.md
|
|
14
|
+
Keywords: hugpy,llm,self-hosted,huggingface,downloads,model-storage,gguf
|
|
15
|
+
Classifier: Development Status :: 3 - Alpha
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: hugpy-platform
|
|
25
|
+
Requires-Dist: hugpy-control
|
|
26
|
+
Requires-Dist: abstract_essentials
|
|
27
|
+
Requires-Dist: huggingface_hub>=0.20
|
|
28
|
+
Requires-Dist: requests>=2.28
|
|
29
|
+
Requires-Dist: pydantic>=2
|
|
30
|
+
Provides-Extra: test
|
|
31
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
32
|
+
Requires-Dist: pytest-timeout; extra == "test"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# hugpy-storage
|
|
36
|
+
|
|
37
|
+
`hugpy_storage` — extracted from `abstract_hugpy_dev` as part of the Hugpy
|
|
38
|
+
partition. Ownership and allowed dependencies are declared in
|
|
39
|
+
`py/partition.toml`; see `PARTITION.md` at the workspace root.
|
|
40
|
+
|
|
41
|
+
Allowed Python dependencies inside the ecosystem: hugpy_platform, hugpy_control.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# hugpy-storage
|
|
2
|
+
|
|
3
|
+
`hugpy_storage` — extracted from `abstract_hugpy_dev` as part of the Hugpy
|
|
4
|
+
partition. Ownership and allowed dependencies are declared in
|
|
5
|
+
`py/partition.toml`; see `PARTITION.md` at the workspace root.
|
|
6
|
+
|
|
7
|
+
Allowed Python dependencies inside the ecosystem: hugpy_platform, hugpy_control.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Registry → rebuildable DB index (operator decision, 2026-09-10)
|
|
2
|
+
|
|
3
|
+
**Decision (operator-approved):** keep `hugpy.json` markers as the per-model
|
|
4
|
+
source of truth co-located with the weights; replace the aggregate JSON
|
|
5
|
+
registries (`projects/model_discovery.json`, `projects/model_manifest.json`)
|
|
6
|
+
with a **database index that is rebuilt from markers** — droppable and
|
|
7
|
+
regenerable at any time, never a second truth.
|
|
8
|
+
|
|
9
|
+
## Why
|
|
10
|
+
|
|
11
|
+
The 2026-09-10 incident chain showed the JSON registries' failure modes:
|
|
12
|
+
|
|
13
|
+
- **Phantom persistence.** The walk registered org dirs (`gguf/<org>`),
|
|
14
|
+
downloader staging (`<repo>.tmp-<pid>`), `_archive/` and `incoming/` rows;
|
|
15
|
+
the merge ("re-adopt prior location — don't throw it away") and the shrink
|
|
16
|
+
guard then kept them alive after the walk bugs were fixed. Rows had to be
|
|
17
|
+
removed by hand-editing JSON.
|
|
18
|
+
- **Count wobble.** The console model total moved with every download
|
|
19
|
+
start/finish because staging dirs entered and left the walk.
|
|
20
|
+
- **Swallowed models.** `gguf/ponpoke` registered as a model and pruned the
|
|
21
|
+
walk, hiding `flux2-klein-9b-uncensored-text-encoder` from the catalog
|
|
22
|
+
entirely (fixed in `paths.py::is_model_dir` — org-level guard).
|
|
23
|
+
- **Whole-file rewrites** race between central, the worker agent and the
|
|
24
|
+
downloader; there is no row-level write.
|
|
25
|
+
|
|
26
|
+
## Shape
|
|
27
|
+
|
|
28
|
+
- **Markers (`hugpy.json`)** — identity, capability flags, and now the
|
|
29
|
+
**`quants` manifest** (`[{file, quant, bytes, shards}]`, mmproj excluded,
|
|
30
|
+
shard sets collapsed), stamped at `write_hugpy_marker` time and kept true by
|
|
31
|
+
`sync_marker_quants` on every discovery walk (2026-09-10). Markers travel
|
|
32
|
+
with the files, survive central loss, and make the store self-describing.
|
|
33
|
+
- **DB index** — SQLite beside the comms mirror
|
|
34
|
+
(`llm_storage/comms/`, same pattern the download queue already uses) or the
|
|
35
|
+
toolserver Postgres. Tables ≈ models(hub_id, name, framework, tasks,
|
|
36
|
+
folder, bytes, status, marker_json, walked_at), quants(model, file, quant,
|
|
37
|
+
bytes, shards). `rebuild()` = walk markers → truncate + reinsert. All
|
|
38
|
+
readers (`get_models_dict`, /api/models, quant choices, storage proposals)
|
|
39
|
+
move to the index; the JSONs become export artifacts or die.
|
|
40
|
+
- **No shrink guard needed**: a degraded-mount walk is detected the same way,
|
|
41
|
+
but the remedy is "don't rebuild now", not "never delete rows".
|
|
42
|
+
|
|
43
|
+
## Prerequisite already done
|
|
44
|
+
|
|
45
|
+
Discovery hardening shipped 2026-09-10 (src + both installed wheels):
|
|
46
|
+
org-level guard in `is_model_dir`, `.tmp-` exclusion, `_archive`/`incoming`/
|
|
47
|
+
`dedupes` excluded from the walk, quant manifest on markers. A future
|
|
48
|
+
`backfill_markers` sweep (exists in `hugpy_marker.py`) will stamp the last
|
|
49
|
+
unstamped dirs so the index can be built from markers alone.
|
|
50
|
+
|
|
51
|
+
## Phase 1 — SHIPPED 2026-09-10
|
|
52
|
+
|
|
53
|
+
- Database `hugpy` (owner: user `hugpy`) on the toolserver's Postgres server —
|
|
54
|
+
same infra, separate database, toolserver's tables untouched.
|
|
55
|
+
- `imports/src/model_index.py`: env-gated (`HUGPY_REGISTRY_DB=pg` +
|
|
56
|
+
`HUGPY_REGISTRY_PG_DSN`, URI form — a space-separated DSN breaks shell
|
|
57
|
+
sourcing of the env file), autocommit + `conn.transaction()` (psycopg3's
|
|
58
|
+
`with conn:` CLOSES the connection — do not reintroduce it).
|
|
59
|
+
- Dual-write: `discover_models` saves the report to the DB after the shrink
|
|
60
|
+
guard (a refused degraded walk never reaches the DB; an empty report never
|
|
61
|
+
truncates). JSON remains the fallback/export.
|
|
62
|
+
- DB-first read: `models_config._load_discovery_report` — DB when enabled and
|
|
63
|
+
populated, else the JSON path byte-identical to before. Workers (no flag,
|
|
64
|
+
no psycopg) are untouched.
|
|
65
|
+
- `model_quants` fills from marker `quants` riding the report rows; it grows
|
|
66
|
+
as markers get stamped/synced (backfill_markers sweep = the remaining step
|
|
67
|
+
to full coverage).
|
|
68
|
+
|
|
69
|
+
## Next phases (operator: "most everything for hugpy should be converted to db")
|
|
70
|
+
|
|
71
|
+
1. `model_manifest.json` (download registry) → table, same dual-write pattern.
|
|
72
|
+
2. Marker backfill sweep so model_quants covers the whole store.
|
|
73
|
+
3. Runtime settings / overrides / priority groups stores → tables.
|
|
74
|
+
4. Retire the JSON files once each reader is DB-first and burned in.
|
|
75
|
+
|
|
76
|
+
## Metrics card — SHIPPED 2026-09-10 (same session)
|
|
77
|
+
|
|
78
|
+
Modeled on the operator's `llm_storage/assets/metrics.xlsx_0.ods`:
|
|
79
|
+
- `model_metrics` — rollup card, one row per (model × quant × alloc_mode ×
|
|
80
|
+
worker): cold/hot load s (fed later by load probes/battery), last +
|
|
81
|
+
running-average tok/s, n_samples, upload_time_s, media_bytes, task.
|
|
82
|
+
- `model_calls` — append-only per-call ledger (every serve: tok/s,
|
|
83
|
+
prompt/completion tokens, elapsed, request_id, config-state snapshot).
|
|
84
|
+
- Recorder hook: `workers.record_serve_metrics` (the one tok/s writer) —
|
|
85
|
+
captures worker/alloc/moe/4-bit inside the store lock, writes outside it.
|
|
86
|
+
- Read: `GET /api/llm/models/<key>/metrics` → {metrics, worker_averages,
|
|
87
|
+
calls}; alias-tolerant (`Jackrong~X` ≡ `X`).
|
|
88
|
+
- Seeded from the fleet's live model_tok_stats (31 rows).
|
|
89
|
+
- Gotcha fixed: PID fork-guard on the PG connection (gunicorn forks after a
|
|
90
|
+
boot-time connect; a shared socket = "SSL bad record mac").
|
|
91
|
+
|
|
92
|
+
## DB code layout — STANDARD (operator ruling, 2026-09-10)
|
|
93
|
+
|
|
94
|
+
All hugpy DB creation and calls follow the explicit repository pattern of
|
|
95
|
+
solcatcher's `src/db/repositories/repos` — implemented for the model index at
|
|
96
|
+
`imports/src/model_index/` and REQUIRED for every future table:
|
|
97
|
+
|
|
98
|
+
query_registry.py EVERY SQL statement, named constants grouped per
|
|
99
|
+
repository (CREATE_TABLE + CREATE_INDEXES first,
|
|
100
|
+
then the named operations). Nothing inlines SQL.
|
|
101
|
+
client.py DatabaseClient — DSN resolution, PID fork-guard,
|
|
102
|
+
psycopg3 autocommit + transaction(), fail-open
|
|
103
|
+
mark_unavailable(). The only file that imports psycopg.
|
|
104
|
+
repositories.py One class per table, one explicit method per query.
|
|
105
|
+
Thin: parameters in, rows out.
|
|
106
|
+
service.py The business layer — enabled() gate, locking,
|
|
107
|
+
transactions, alias forms, guards, degradation.
|
|
108
|
+
__init__.py Explicit exports + a module-level singleton exposing
|
|
109
|
+
the plain-function API call sites use.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "setuptools-scm>=8"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "hugpy-storage"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Hugpy storage: model download queue and daemon, Hugging Face transport and token, resumable transfers, model sync, physical inventory and on-disk model layout"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "LicenseRef-Proprietary"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "putkoff", email = "support@hugpy.ai" }]
|
|
14
|
+
keywords = [
|
|
15
|
+
"hugpy",
|
|
16
|
+
"llm",
|
|
17
|
+
"self-hosted",
|
|
18
|
+
"huggingface",
|
|
19
|
+
"downloads",
|
|
20
|
+
"model-storage",
|
|
21
|
+
"gguf",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 3 - Alpha",
|
|
25
|
+
"Intended Audience :: Developers",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
29
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
30
|
+
]
|
|
31
|
+
dependencies = [
|
|
32
|
+
"hugpy-platform",
|
|
33
|
+
"hugpy-control",
|
|
34
|
+
"abstract_essentials",
|
|
35
|
+
"huggingface_hub>=0.20",
|
|
36
|
+
"requests>=2.28",
|
|
37
|
+
"pydantic>=2",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://hugpy.ai"
|
|
42
|
+
Documentation = "https://github.com/hugpy/hugpy/blob/main/py/storage/hugpy_storage/README.md"
|
|
43
|
+
Repository = "https://github.com/hugpy/hugpy"
|
|
44
|
+
Source = "https://github.com/hugpy/hugpy/tree/main/py/storage/hugpy_storage"
|
|
45
|
+
Issues = "https://github.com/hugpy/hugpy/issues"
|
|
46
|
+
Changelog = "https://github.com/hugpy/hugpy/releases"
|
|
47
|
+
Architecture = "https://github.com/hugpy/hugpy/blob/main/PARTITION.md"
|
|
48
|
+
|
|
49
|
+
[project.optional-dependencies]
|
|
50
|
+
test = ["pytest>=8", "pytest-timeout"]
|
|
51
|
+
|
|
52
|
+
[project.scripts]
|
|
53
|
+
hugpy-storage = "hugpy_storage.cli:main"
|
|
54
|
+
# Transitional alias for the systemd unit / operators (PARTITION.md).
|
|
55
|
+
hugpy-downloader = "hugpy_storage.downloader.daemon:main"
|
|
56
|
+
|
|
57
|
+
[tool.setuptools.packages.find]
|
|
58
|
+
where = ["src"]
|
|
59
|
+
|
|
60
|
+
[tool.setuptools.package-data]
|
|
61
|
+
hugpy_storage = ["py.typed", "**/*.json", "**/*.sh", "**/*.md", "**/*.txt", "deploy/*.service"]
|
|
62
|
+
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
# Lockstep workspace version (2026-09-22): every in-tree hugpy-* distribution
|
|
65
|
+
# takes ONE version from the workspace git tag (vX.Y.Z at the repo root), so a
|
|
66
|
+
# release is a tag and a build always carries the commit it came from
|
|
67
|
+
# (X.Y.Z.devN+g<sha>[.dirty] between tags). A checkout without git metadata
|
|
68
|
+
# builds as 0.0.0+unknown, which central refuses to advertise to workers.
|
|
69
|
+
[tool.setuptools_scm]
|
|
70
|
+
root = "../../.."
|
|
71
|
+
fallback_version = "0.0.0+unknown"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""hugpy_storage — bytes at rest and in transit.
|
|
2
|
+
|
|
3
|
+
The download queue and daemon (``downloader``), resumable central/HF transfer
|
|
4
|
+
(``provision``, ``model_sync``, ``download_models``), Hugging Face transport
|
|
5
|
+
and token (``huggingface_api``, ``hf_token``, ``model_metadata``), physical
|
|
6
|
+
inventory and its caches (``model_physical``, ``model_status_cache``,
|
|
7
|
+
``model_presence``), the on-disk model layout (``model_paths``,
|
|
8
|
+
``hugpy_marker``, ``gguf_inspect``) and the console-side helpers.
|
|
9
|
+
|
|
10
|
+
Seams to the layers above (installed by the composition root):
|
|
11
|
+
|
|
12
|
+
* :mod:`hugpy_storage.catalog_source` — the model registry Protocol
|
|
13
|
+
(``set_catalog_source``); null default knows no models.
|
|
14
|
+
* :mod:`hugpy_storage.providers` — budget gate, transfer telemetry, executor
|
|
15
|
+
registrar, serve-path hook, footprint selector.
|
|
16
|
+
* :mod:`hugpy_storage.events` — ``catalog.changed`` on the control bus after
|
|
17
|
+
the inventory moves.
|
|
18
|
+
|
|
19
|
+
This ``__init__`` is deliberately light: nothing heavy (huggingface_hub,
|
|
20
|
+
requests, pydantic, sqlite stores) is imported here.
|
|
21
|
+
"""
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
from hugpy_storage.catalog_source import (
|
|
25
|
+
CatalogSource,
|
|
26
|
+
DictCatalogSource,
|
|
27
|
+
NullCatalogSource,
|
|
28
|
+
get_catalog_source,
|
|
29
|
+
set_catalog_source,
|
|
30
|
+
)
|
|
31
|
+
from hugpy_storage.events import publish_catalog_changed
|
|
32
|
+
from hugpy_storage.providers import (
|
|
33
|
+
set_budget_gate,
|
|
34
|
+
set_executor_registrar,
|
|
35
|
+
set_footprint_selector,
|
|
36
|
+
set_serve_path_hook,
|
|
37
|
+
set_transfer_telemetry,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
try: # the installed distribution's version: the workspace tag/commit, never a literal
|
|
41
|
+
from importlib.metadata import version as _dist_version
|
|
42
|
+
__version__ = _dist_version("hugpy-storage")
|
|
43
|
+
except Exception: # noqa: BLE001 — source tree without metadata
|
|
44
|
+
__version__ = "0.0.0+unknown"
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
"__version__",
|
|
48
|
+
# catalog seam
|
|
49
|
+
"CatalogSource", "NullCatalogSource", "DictCatalogSource",
|
|
50
|
+
"set_catalog_source", "get_catalog_source",
|
|
51
|
+
# upper-layer hooks
|
|
52
|
+
"set_budget_gate", "set_transfer_telemetry", "set_executor_registrar",
|
|
53
|
+
"set_serve_path_hook", "set_footprint_selector",
|
|
54
|
+
# events
|
|
55
|
+
"publish_catalog_changed",
|
|
56
|
+
]
|