Spaces:
Running
Running
Download scripts/package_release.py from hasimjaneef/omniAI: direct link, hf CLI and curl.
- Browser
- Download file 6.68 kB
-
https://huggingface.co/spaces/hasimjaneef/omniAI/resolve/main/scripts/package_release.py
- Command line
-
hf download hf://spaces/hasimjaneef/omniAI/scripts/package_release.py
-
curl -L -o package_release.py https://huggingface.co/spaces/hasimjaneef/omniAI/resolve/main/scripts/package_release.py
6.68 kB
| """Allowlisted consistent HF packages. Never uploads; never packages arbitrary cwd files.""" | |
| from __future__ import annotations | |
| import argparse | |
| import hashlib | |
| import json | |
| import re | |
| import shutil | |
| import subprocess | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[1] | |
| DIRS = ("backend", "frontend", "gpu_service", "docs", "deploy", "scripts", "tests") | |
| FILES = ("README.md", "Dockerfile", ".dockerignore", ".gitignore", ".env.example", "pyproject.toml", | |
| "requirements.txt", "requirements-dev.txt", "requirements-gpu.txt", "constraints-cpu.txt", "model-lock.json") | |
| EXCLUDED = {"node_modules", "dist", "__pycache__", ".pytest_cache", ".ruff_cache", ".venv", "output", "private-media"} | |
| ALLOWED = {".py", ".md", ".txt", ".json", ".html", ".css", ".ts", ".tsx", ".js", ".sh", ".ttf", ".toml", ".Dockerfile"} | |
| REQUIRED = ("backend/main.py", "backend/session.py", "backend/perception.py", "backend/portfolio.py", | |
| "backend/public_output.py", "backend/settings.py", "backend/schemas.py", | |
| "frontend/package.json", "frontend/package-lock.json", "frontend/index.html", | |
| "frontend/vite.config.ts", "frontend/src/App.tsx", "frontend/src/api.ts", "frontend/src/styles.css", | |
| "frontend/src/mediaCapture.ts", "frontend/src/transport.ts", "frontend/src/audio.ts", "frontend/src/latency.ts", | |
| "frontend/public/audio-worklet.js", "frontend/src/components/ObservatoryLogo.tsx", | |
| "frontend/src/components/InstrumentPicker.tsx", "frontend/src/instruments.ts", | |
| "frontend/src/components/PortfolioEditor.tsx", "frontend/src/portfolio.ts", | |
| "frontend/src/instrumentSearch.ts", "frontend/src/catalog/equities.json", | |
| "frontend/src/catalog/funds.json", "frontend/src/catalog/maritime.json", | |
| "frontend/src/assets/manrope/Manrope-Variable.ttf", "frontend/src/assets/manrope/OFL.txt", | |
| "frontend/public/licenses/Manrope-OFL.txt", "gpu_service/app.py", "gpu_service/native.py", | |
| "gpu_service/contracts.py", "gpu_service/smoke.py", "requirements.txt", | |
| "requirements-gpu.txt", "constraints-cpu.txt", "deploy/gpu.Dockerfile", | |
| "docs/model-interface.md", "docs/architecture.md", "docs/hugging-face-delivery.md", | |
| "docs/verification.md", "model-lock.json", "scripts/verify_gpu_install.py") | |
| SECRET = re.compile(rb"\b(?:hf_[A-Za-z0-9]{16,}|sk-[A-Za-z0-9_-]{20,})\b") | |
| def files(): | |
| result = [] | |
| for directory in DIRS: | |
| for path in (ROOT / directory).rglob("*"): | |
| relative = path.relative_to(ROOT) | |
| if set(relative.parts) & EXCLUDED or path.name.endswith(".tsbuildinfo"): | |
| continue | |
| if path.is_symlink(): | |
| raise RuntimeError("Symlink is not allowed in release: " + str(relative)) | |
| if path.is_dir(): | |
| continue | |
| if path.name.startswith(".env"): | |
| raise RuntimeError("Runtime environment file cannot be released: " + str(relative)) | |
| if path.suffix not in ALLOWED and path.name != "Dockerfile": | |
| raise RuntimeError("Unexpected file in release directory: " + str(relative)) | |
| result.append(path) | |
| result.extend(ROOT / name for name in FILES) | |
| for relative in REQUIRED: | |
| if ROOT / relative not in result: | |
| raise RuntimeError("Required application file missing: " + relative) | |
| return sorted(set(result)) | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--validate-only", action="store_true") | |
| parser.add_argument("--output", type=Path, default=ROOT / "release") | |
| args = parser.parse_args() | |
| selected = files() | |
| manifest = {} | |
| for source in selected: | |
| data = source.read_bytes() | |
| # Secret-shaped fixture rejection strings are written via concatenation | |
| # in tests, so the exact package never contains usable token-shaped text. | |
| if SECRET.search(data): | |
| raise RuntimeError("Credential-shaped value found; remove it before release: " + str(source.relative_to(ROOT))) | |
| manifest[str(source.relative_to(ROOT))] = hashlib.sha256(data).hexdigest() | |
| canonical = json.dumps(manifest, sort_keys=True, separators=(",", ":")).encode() | |
| revision = hashlib.sha256(canonical).hexdigest() | |
| try: | |
| git_revision = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=ROOT, stderr=subprocess.DEVNULL, text=True).strip() | |
| except subprocess.CalledProcessError: | |
| git_revision = None | |
| if args.validate_only: | |
| print(f"Package validation passed: {len(manifest)} allowlisted files; source SHA256 {revision}") | |
| return | |
| destination = args.output.resolve() | |
| # Keep all writes inside an explicit package output folder; refuse workspace root. | |
| if destination == ROOT or ROOT.is_relative_to(destination): | |
| raise RuntimeError("Choose a release output subdirectory, not the source root") | |
| for flavor in ("app", "gpu"): | |
| stage = destination / flavor | |
| if stage.exists(): | |
| shutil.rmtree(stage) | |
| stage.mkdir(parents=True) | |
| for source in selected: | |
| target = stage / source.relative_to(ROOT) | |
| target.parent.mkdir(parents=True, exist_ok=True) | |
| shutil.copyfile(source, target) | |
| if hashlib.sha256(target.read_bytes()).hexdigest() != manifest[str(source.relative_to(ROOT))]: | |
| raise RuntimeError("Source changed during packaging; rerun after edits finish") | |
| if flavor == "gpu": | |
| shutil.copyfile(stage / "deploy/gpu.Dockerfile", stage / "Dockerfile") | |
| (stage / "README.md").write_text("---\ntitle: OmnAI MiniCPM-o 4.5\nsdk: docker\napp_port: 8090\n---\n\nPersistent authenticated MiniCPM-o 4.5 audiovisual and portfolio research service. One model, one ongoing native duplex session. See docs/model-interface.md, docs/architecture.md and docs/hugging-face-delivery.md.\n\nSource package SHA256: " + revision + "\n") | |
| package_files = {str(p.relative_to(stage)): hashlib.sha256(p.read_bytes()).hexdigest() | |
| for p in stage.rglob("*") if p.is_file()} | |
| record = {"source_sha256": revision, "git_revision": git_revision, "flavor": flavor, | |
| "source_files": manifest, "package_files": package_files} | |
| (stage / "RELEASE_MANIFEST.json").write_text(json.dumps(record, indent=2) + "\n") | |
| for name, digest in package_files.items(): | |
| assert hashlib.sha256((stage / name).read_bytes()).hexdigest() == digest | |
| print(f"Validated app and GPU packages: {destination}\nShared source SHA256: {revision}") | |
| if __name__ == "__main__": | |
| main() | |