File size: 3,510 Bytes
a9db693
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5dabf8a
a9db693
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5dabf8a
 
a9db693
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5dabf8a
 
 
 
a9db693
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from __future__ import annotations

import argparse
import os
import shutil
import tempfile
from pathlib import Path

from huggingface_hub import HfApi

README_TEMPLATE = """---
title: Archstyle 55 Backend
colorFrom: blue
colorTo: green
sdk: docker
app_port: 7860
pinned: false
suggested_hardware: cpu-basic
---

# Archstyle 55 — FastAPI backend

55-class architectural style classifier. See `/docs` for the API.
"""


def _copy(src: Path, dst: Path, *, ignore: tuple[str, ...] = ()) -> None:
    if src.is_file():
        dst.parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(src, dst)
        return
    for entry in src.iterdir():
        if entry.name in ignore:
            continue
        if any(entry.match(pat) for pat in ("__pycache__", "*.pyc", "*.pyo", ".pytest_cache")):
            continue
        _copy(entry, dst / entry.name, ignore=ignore)


def build_bundle(repo_root: Path, out: Path) -> None:
    backend = repo_root / "service" / "backend"
    pipeline = repo_root / "pipeline"
    splits = repo_root / "pipeline" / "results" / "splits"

    shutil.copy2(backend / "Dockerfile.space", out / "Dockerfile")
    shutil.copy2(backend / "requirements.space.txt", out / "requirements.txt")
    shutil.copy2(backend / "alembic.ini", out / "alembic.ini")

    _copy(backend / "app", out / "app", ignore=("__pycache__",))
    _copy(repo_root / "service" / "scripts", out / "scripts", ignore=("__pycache__",))

    pipe_keep = ("models", "segmentation", "xai", "data", "evaluation",
                 "training", "utils", "config.py", "__init__.py")
    out_pipe = out / "pipeline"
    out_pipe.mkdir(parents=True, exist_ok=True)
    for entry in pipeline.iterdir():
        if entry.name not in pipe_keep:
            continue
        if entry.is_dir():
            _copy(entry, out_pipe / entry.name, ignore=("__pycache__",))
        else:
            shutil.copy2(entry, out_pipe / entry.name)

    out_splits = out / "results" / "splits"
    out_splits.mkdir(parents=True, exist_ok=True)
    for fn in ("idx_to_class.json", "class_to_idx.json"):
        src = splits / fn
        if src.is_file():
            shutil.copy2(src, out_splits / fn)

    hybrid_src = repo_root / "results" / "hybrid_histgbm.pkl"
    if hybrid_src.is_file():
        shutil.copy2(hybrid_src, out / "results" / "hybrid_histgbm.pkl")

    (out / "README.md").write_text(README_TEMPLATE, encoding="utf-8")


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--repo", required=True, help="hf user/space-name")
    parser.add_argument("--token", default=os.environ.get("HF_TOKEN"))
    parser.add_argument("--root", default=str(Path(__file__).resolve().parents[2]))
    args = parser.parse_args()
    assert args.token, "HF_TOKEN required"

    api = HfApi(token=args.token)
    api.create_repo(repo_id=args.repo, repo_type="space",
                    space_sdk="docker", exist_ok=True, private=False)

    with tempfile.TemporaryDirectory() as tmp:
        out = Path(tmp)
        build_bundle(Path(args.root), out)
        sizes = sum(f.stat().st_size for f in out.rglob("*") if f.is_file())
        print(f"bundle size: {sizes / 1024 / 1024:.1f} MB")

        api.upload_folder(
            folder_path=str(out),
            repo_id=args.repo,
            repo_type="space",
            commit_message="deploy: backend bundle",
        )
        print(f"https://huggingface.co/spaces/{args.repo}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())