hyctl 1.0.1__py3-none-any.whl

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.
hyctl/__init__.py ADDED
@@ -0,0 +1,117 @@
1
+ """hyctl — Python launcher for the Hydra CLI.
2
+
3
+ Pure-Python wrapper: on first run it downloads the prebuilt `hyctl` binary
4
+ matching this package's version from the GitHub release, verifies its
5
+ checksum, caches it, and then execs it. No Go toolchain required.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import hashlib
10
+ import os
11
+ import platform
12
+ import stat
13
+ import sys
14
+ import tarfile
15
+ import tempfile
16
+ import urllib.request
17
+ import zipfile
18
+ from pathlib import Path
19
+
20
+ __version__ = "1.0.1"
21
+
22
+ REPO = "ankit373/hydra"
23
+ PROJECT = "hydra" # goreleaser archive filename prefix
24
+ TAG = f"v{__version__}"
25
+ BASE = f"https://github.com/{REPO}/releases/download/{TAG}"
26
+
27
+ _OS = {"darwin": "darwin", "linux": "linux", "windows": "windows"}
28
+ _ARCH = {"x86_64": "amd64", "amd64": "amd64", "arm64": "arm64", "aarch64": "arm64"}
29
+
30
+
31
+ def _target() -> tuple[str, str]:
32
+ osname = _OS.get(platform.system().lower())
33
+ arch = _ARCH.get(platform.machine().lower())
34
+ if not osname or not arch:
35
+ _die(f"unsupported platform {platform.system()}/{platform.machine()}")
36
+ return osname, arch
37
+
38
+
39
+ def _die(msg: str) -> None:
40
+ sys.stderr.write(f"\n hyctl: {msg}\n")
41
+ sys.stderr.write(f" Install manually from https://github.com/{REPO}/releases/tag/{TAG}\n\n")
42
+ raise SystemExit(1)
43
+
44
+
45
+ def _cache_dir() -> Path:
46
+ root = os.environ.get("XDG_CACHE_HOME") or str(Path.home() / ".cache")
47
+ d = Path(root) / "hyctl" / __version__
48
+ d.mkdir(parents=True, exist_ok=True)
49
+ return d
50
+
51
+
52
+ def _fetch(url: str) -> bytes:
53
+ req = urllib.request.Request(url, headers={"User-Agent": "hyctl-pip-installer"})
54
+ with urllib.request.urlopen(req) as resp: # noqa: S310 (trusted GitHub host)
55
+ return resp.read()
56
+
57
+
58
+ def _verify(archive: bytes, name: str) -> None:
59
+ try:
60
+ sums = _fetch(f"{BASE}/checksums.txt").decode("utf-8")
61
+ except Exception:
62
+ sys.stderr.write("hyctl: checksums.txt unavailable — skipping verification\n")
63
+ return
64
+ for line in sums.splitlines():
65
+ if line.strip().endswith(name):
66
+ expected = line.split()[0]
67
+ actual = hashlib.sha256(archive).hexdigest()
68
+ if expected != actual:
69
+ _die(f"checksum mismatch (expected {expected}, got {actual})")
70
+ return
71
+
72
+
73
+ def _ensure_binary() -> Path:
74
+ osname, arch = _target()
75
+ exe = "hyctl.exe" if osname == "windows" else "hyctl"
76
+ dest = _cache_dir() / exe
77
+ if dest.exists():
78
+ return dest
79
+
80
+ ext = "zip" if osname == "windows" else "tar.gz"
81
+ archive_name = f"{PROJECT}_{__version__}_{osname}_{arch}.{ext}"
82
+ sys.stderr.write(f"hyctl: downloading {archive_name} ({TAG})…\n")
83
+ try:
84
+ blob = _fetch(f"{BASE}/{archive_name}")
85
+ except Exception as e: # noqa: BLE001
86
+ _die(f"download failed — {e}")
87
+
88
+ _verify(blob, archive_name)
89
+
90
+ with tempfile.TemporaryDirectory() as tmp:
91
+ apath = Path(tmp) / archive_name
92
+ apath.write_bytes(blob)
93
+ if ext == "zip":
94
+ with zipfile.ZipFile(apath) as z:
95
+ z.extract(exe, tmp)
96
+ else:
97
+ with tarfile.open(apath) as t:
98
+ t.extract(exe, tmp) # noqa: S202 (single known member)
99
+ (Path(tmp) / exe).replace(dest)
100
+
101
+ if osname != "windows":
102
+ dest.chmod(dest.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
103
+ return dest
104
+
105
+
106
+ def main() -> None:
107
+ binary = _ensure_binary()
108
+ args = [str(binary), *sys.argv[1:]]
109
+ if os.name == "nt":
110
+ import subprocess # noqa: PLC0415
111
+
112
+ raise SystemExit(subprocess.run(args).returncode)
113
+ os.execv(str(binary), args)
114
+
115
+
116
+ if __name__ == "__main__":
117
+ main()
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: hyctl
3
+ Version: 1.0.1
4
+ Summary: Hydra (hyctl) — local-first, multi-vendor AI control plane. Routes each task to the cheapest model on your machine that clears your target confidence.
5
+ Author: ankit373
6
+ License: MIT
7
+ Project-URL: Homepage, https://hydra.uvansa.com
8
+ Project-URL: Source, https://github.com/ankit373/hydra
9
+ Project-URL: Issues, https://github.com/ankit373/hydra/issues
10
+ Keywords: ai,llm,orchestration,cli,router,ollama,local-first
11
+ Classifier: Environment :: Console
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Software Development :: Build Tools
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+
18
+ # hyctl
19
+
20
+ **Hydra** — a local-first, multi-vendor AI control plane. This package installs the `hyctl` CLI.
21
+
22
+ ```bash
23
+ pip install hyctl
24
+ hyctl init
25
+ ```
26
+
27
+ On first run it downloads the prebuilt `hyctl` binary matching this package's version from the [GitHub release](https://github.com/ankit373/hydra/releases), verifies its checksum, and caches it under `~/.cache/hyctl/`. No Go toolchain required.
28
+
29
+ ## Other install methods
30
+
31
+ ```bash
32
+ brew tap ankit373/hydra && brew install hyctl # Homebrew
33
+ npm install -g hyctl # npm
34
+ npx hyctl init # npx (no install)
35
+ curl -fsSL https://raw.githubusercontent.com/ankit373/hydra/main/install.sh | sh # standalone
36
+ ```
37
+
38
+ - Docs: https://hydra.uvansa.com
39
+ - Source: https://github.com/ankit373/hydra
40
+ - License: MIT
@@ -0,0 +1,6 @@
1
+ hyctl/__init__.py,sha256=QI2JcifB4exODFRJIbBZBV0Vj_-znsx4_kmxlgzVb0Y,3615
2
+ hyctl-1.0.1.dist-info/METADATA,sha256=3arFgJDXIKpaTRISiXcRaKkCZM-OnoEkUdjfO4-eSsA,1549
3
+ hyctl-1.0.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
4
+ hyctl-1.0.1.dist-info/entry_points.txt,sha256=ucI3fC5dgIuonuLGON604fz9hpZ5A7iNbqP3Nz3WzO8,37
5
+ hyctl-1.0.1.dist-info/top_level.txt,sha256=S8QeN4aRruhKV_ryMJO2AkzByPPqG85XocmemNzvJ5M,6
6
+ hyctl-1.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ hyctl = hyctl:main
@@ -0,0 +1 @@
1
+ hyctl