nepher-cli 0.2.0__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.
- nepher_cli/__init__.py +3 -0
- nepher_cli/__main__.py +4 -0
- nepher_cli/cli.py +59 -0
- nepher_cli/commands/__init__.py +1 -0
- nepher_cli/commands/account.py +527 -0
- nepher_cli/commands/envhub.py +466 -0
- nepher_cli/commands/hackathon.py +760 -0
- nepher_cli/commands/simstore.py +49 -0
- nepher_cli/commands/tournament.py +651 -0
- nepher_cli/config.py +25 -0
- nepher_cli/core/__init__.py +1 -0
- nepher_cli/core/credentials.py +243 -0
- nepher_cli/core/http.py +76 -0
- nepher_cli/envhub/__init__.py +1 -0
- nepher_cli/envhub/cache.py +56 -0
- nepher_cli/envhub/config.py +176 -0
- nepher_cli/py.typed +0 -0
- nepher_cli/tournament/__init__.py +1 -0
- nepher_cli/tournament/agent_check.py +60 -0
- nepher_cli/tournament/api.py +100 -0
- nepher_cli/tournament/packer.py +50 -0
- nepher_cli/tournament/wallet.py +89 -0
- nepher_cli-0.2.0.dist-info/METADATA +193 -0
- nepher_cli-0.2.0.dist-info/RECORD +26 -0
- nepher_cli-0.2.0.dist-info/WHEEL +4 -0
- nepher_cli-0.2.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Tournament submission API calls — httpx only, no external dependencies."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import httpx
|
|
9
|
+
|
|
10
|
+
from nepher_cli.core.http import parse_error_body
|
|
11
|
+
|
|
12
|
+
_DEFAULT_TIMEOUT = 30.0
|
|
13
|
+
_UPLOAD_TIMEOUT = 600.0 # 10 min — large agent ZIPs can be slow
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _json_headers(api_key: str) -> dict[str, str]:
|
|
17
|
+
return {
|
|
18
|
+
"X-API-Key": api_key,
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
"Accept": "application/json",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _raise_for_error(response: httpx.Response) -> None:
|
|
25
|
+
if response.status_code < 400:
|
|
26
|
+
return
|
|
27
|
+
msg = (
|
|
28
|
+
parse_error_body(response.text)
|
|
29
|
+
or response.text.strip()
|
|
30
|
+
or f"HTTP {response.status_code}"
|
|
31
|
+
)
|
|
32
|
+
raise RuntimeError(msg)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
async def request_upload_token(
|
|
36
|
+
*,
|
|
37
|
+
api_key: str,
|
|
38
|
+
api_url: str,
|
|
39
|
+
miner_hotkey: str,
|
|
40
|
+
public_key: str,
|
|
41
|
+
file_info: str,
|
|
42
|
+
signature: str,
|
|
43
|
+
file_size: int,
|
|
44
|
+
tournament_id: str | None = None,
|
|
45
|
+
) -> dict[str, Any]:
|
|
46
|
+
"""POST /api/v1/agents/upload/verify → parsed JSON token dict.
|
|
47
|
+
|
|
48
|
+
The returned dict contains at least ``upload_token`` and ``tournament_id``.
|
|
49
|
+
"""
|
|
50
|
+
body: dict[str, Any] = {
|
|
51
|
+
"miner_hotkey": miner_hotkey,
|
|
52
|
+
"public_key": public_key,
|
|
53
|
+
"file_info": file_info,
|
|
54
|
+
"signature": signature,
|
|
55
|
+
"file_size": file_size,
|
|
56
|
+
}
|
|
57
|
+
if tournament_id is not None:
|
|
58
|
+
body["tournament_id"] = tournament_id
|
|
59
|
+
|
|
60
|
+
url = f"{api_url.rstrip('/')}/api/v1/agents/upload/verify"
|
|
61
|
+
async with httpx.AsyncClient(
|
|
62
|
+
timeout=_DEFAULT_TIMEOUT,
|
|
63
|
+
headers=_json_headers(api_key),
|
|
64
|
+
) as client:
|
|
65
|
+
response = await client.post(url, json=body)
|
|
66
|
+
_raise_for_error(response)
|
|
67
|
+
return response.json()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
async def upload_agent(
|
|
71
|
+
*,
|
|
72
|
+
api_key: str,
|
|
73
|
+
api_url: str,
|
|
74
|
+
tournament_id: str,
|
|
75
|
+
upload_token: str,
|
|
76
|
+
miner_hotkey: str,
|
|
77
|
+
content_hash: str,
|
|
78
|
+
file_path: Path,
|
|
79
|
+
) -> str:
|
|
80
|
+
"""POST /api/v1/agents/upload/{tournament_id} (multipart) → agent_id string."""
|
|
81
|
+
url = f"{api_url.rstrip('/')}/api/v1/agents/upload/{tournament_id}"
|
|
82
|
+
headers = {
|
|
83
|
+
"X-API-Key": api_key,
|
|
84
|
+
"Accept": "application/json",
|
|
85
|
+
"X-Upload-Token": upload_token,
|
|
86
|
+
}
|
|
87
|
+
async with httpx.AsyncClient(timeout=httpx.Timeout(_UPLOAD_TIMEOUT)) as client:
|
|
88
|
+
with open(file_path, "rb") as fh:
|
|
89
|
+
response = await client.post(
|
|
90
|
+
url,
|
|
91
|
+
files={"file": (file_path.name, fh, "application/zip")},
|
|
92
|
+
data={"miner_hotkey": miner_hotkey, "content_hash": content_hash},
|
|
93
|
+
headers=headers,
|
|
94
|
+
)
|
|
95
|
+
_raise_for_error(response)
|
|
96
|
+
data = response.json()
|
|
97
|
+
agent_id = data.get("id") or data.get("agent_id")
|
|
98
|
+
if not agent_id:
|
|
99
|
+
raise RuntimeError(f"No agent ID in upload response: {data}")
|
|
100
|
+
return str(agent_id)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Archive and checksum helpers — pure Python stdlib, no external dependencies."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import zipfile
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
# Names and suffixes excluded from submission archives
|
|
10
|
+
_EXCLUDED_NAMES: frozenset[str] = frozenset({
|
|
11
|
+
"__pycache__", ".git", ".gitignore",
|
|
12
|
+
"logs", "outputs", ".env", "venv", ".venv", "node_modules",
|
|
13
|
+
})
|
|
14
|
+
_EXCLUDED_SUFFIXES: frozenset[str] = frozenset({".pyc", ".pyo"})
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _is_excluded(path_part: str) -> bool:
|
|
18
|
+
p = Path(path_part)
|
|
19
|
+
return p.name in _EXCLUDED_NAMES or p.suffix in _EXCLUDED_SUFFIXES
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def zip_directory(source_dir: Path, output_path: Path) -> None:
|
|
23
|
+
"""Create a ZIP archive of *source_dir* at *output_path*.
|
|
24
|
+
|
|
25
|
+
Files are added in sorted order for reproducibility. Common
|
|
26
|
+
build artefacts and VCS directories are excluded automatically.
|
|
27
|
+
"""
|
|
28
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
29
|
+
with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zf:
|
|
30
|
+
for file_path in sorted(source_dir.rglob("*")):
|
|
31
|
+
if not file_path.is_file():
|
|
32
|
+
continue
|
|
33
|
+
rel = file_path.relative_to(source_dir)
|
|
34
|
+
if any(_is_excluded(part) for part in rel.parts):
|
|
35
|
+
continue
|
|
36
|
+
zf.write(file_path, rel)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def compute_checksum(file_path: Path) -> str:
|
|
40
|
+
"""Return the SHA-256 hex digest of *file_path*."""
|
|
41
|
+
h = hashlib.sha256()
|
|
42
|
+
with open(file_path, "rb") as f:
|
|
43
|
+
for chunk in iter(lambda: f.read(8192), b""):
|
|
44
|
+
h.update(chunk)
|
|
45
|
+
return h.hexdigest()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_file_size(file_path: Path) -> int:
|
|
49
|
+
"""Return the size of *file_path* in bytes."""
|
|
50
|
+
return file_path.stat().st_size
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Bittensor wallet operations — lazy import so bittensor is an optional dependency."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
_BITTENSOR_HINT = (
|
|
8
|
+
"Agent submission requires [bold]bittensor[/bold] for wallet signing.\n\n"
|
|
9
|
+
"Install it with:\n"
|
|
10
|
+
" [bold]pip install bittensor[/bold]\n\n"
|
|
11
|
+
"Or if you installed nepher-cli via pip:\n"
|
|
12
|
+
" [bold]pip install \"nepher-cli[bittensor]\"[/bold]"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _require_wallet_class():
|
|
17
|
+
"""Return the ``bittensor_wallet.Wallet`` class or exit with a clear error.
|
|
18
|
+
|
|
19
|
+
``bittensor_wallet`` is a standalone package that is installed automatically
|
|
20
|
+
as a dependency of ``bittensor``. Importing it directly keeps the check
|
|
21
|
+
lightweight — we do not need the full bittensor package at import time.
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
from bittensor_wallet import Wallet # type: ignore[import]
|
|
25
|
+
return Wallet
|
|
26
|
+
except ImportError:
|
|
27
|
+
from rich.console import Console
|
|
28
|
+
Console(stderr=True).print(
|
|
29
|
+
f"[red]bittensor not installed.[/red]\n\n{_BITTENSOR_HINT}"
|
|
30
|
+
)
|
|
31
|
+
raise SystemExit(1)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def load_wallet(wallet_name: str, wallet_hotkey: str):
|
|
35
|
+
"""Load a Bittensor wallet by name and hotkey name.
|
|
36
|
+
|
|
37
|
+
Exits with a user-friendly message if bittensor is not installed or the
|
|
38
|
+
hotkey file does not exist on this machine.
|
|
39
|
+
"""
|
|
40
|
+
Wallet = _require_wallet_class()
|
|
41
|
+
wallet = Wallet(name=wallet_name, hotkey=wallet_hotkey)
|
|
42
|
+
if not wallet.hotkey_file.exists_on_device():
|
|
43
|
+
from rich.console import Console
|
|
44
|
+
Console(stderr=True).print(
|
|
45
|
+
f"[red]Hotkey '[bold]{wallet_hotkey}[/bold]' not found "
|
|
46
|
+
f"for wallet '[bold]{wallet_name}[/bold]'.[/red]\n"
|
|
47
|
+
"Check the wallet name and hotkey with [bold]btcli wallet list[/bold]."
|
|
48
|
+
)
|
|
49
|
+
raise SystemExit(1)
|
|
50
|
+
return wallet
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_hotkey(wallet) -> str:
|
|
54
|
+
"""Return the SS58 address of the wallet's hotkey."""
|
|
55
|
+
return wallet.hotkey.ss58_address
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def get_public_key(wallet) -> str:
|
|
59
|
+
"""Return the hex-encoded public key of the wallet's hotkey."""
|
|
60
|
+
return wallet.hotkey.public_key.hex()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def sign_message(wallet, message: str) -> str:
|
|
64
|
+
"""Sign *message* with the wallet's hotkey and return a hex-encoded signature."""
|
|
65
|
+
return wallet.hotkey.sign(message.encode()).hex()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def create_file_info(miner_hotkey: str, content_hash: str, timestamp: int) -> str:
|
|
69
|
+
"""Build the canonical file_info string: ``'hotkey:content_hash:timestamp'``."""
|
|
70
|
+
return f"{miner_hotkey}:{content_hash}:{timestamp}"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def prepare_submission_credentials(
|
|
74
|
+
wallet_name: str,
|
|
75
|
+
wallet_hotkey: str,
|
|
76
|
+
content_hash: str,
|
|
77
|
+
) -> tuple[str, str, str, str]:
|
|
78
|
+
"""Load wallet and produce all signing artefacts needed for a submission.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
``(miner_hotkey, public_key, file_info, signature)``
|
|
82
|
+
"""
|
|
83
|
+
wallet = load_wallet(wallet_name, wallet_hotkey)
|
|
84
|
+
miner_hotkey = get_hotkey(wallet)
|
|
85
|
+
public_key = get_public_key(wallet)
|
|
86
|
+
timestamp = int(time.time())
|
|
87
|
+
file_info = create_file_info(miner_hotkey, content_hash, timestamp)
|
|
88
|
+
signature = sign_message(wallet, file_info)
|
|
89
|
+
return miner_hotkey, public_key, file_info, signature
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nepher-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: npcli — unified Nepher command-line interface for accounts, hackathons, EnvHub, tournaments, and SimStore
|
|
5
|
+
Project-URL: Homepage, https://github.com/nepher-ai/nepher-cli
|
|
6
|
+
Author: Nepher
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: bittensor,cli,envhub,hackathon,nepher,subnet,tournament
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: click>=8.1.0
|
|
18
|
+
Requires-Dist: httpx>=0.27.0
|
|
19
|
+
Requires-Dist: keyring>=25.0.0
|
|
20
|
+
Requires-Dist: platformdirs>=4.0.0
|
|
21
|
+
Requires-Dist: rich>=13.7.0
|
|
22
|
+
Provides-Extra: bittensor
|
|
23
|
+
Requires-Dist: bittensor; extra == 'bittensor'
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# nepher-cli
|
|
30
|
+
|
|
31
|
+
The unified CLI for [Nepher Robotics](https://nepher.ai) — accounts, hackathons, EnvHub, tournaments, and SimStore from a single tool.
|
|
32
|
+
|
|
33
|
+
**Requires:** Python 3.10+
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install nepher-cli
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Both `npcli` and `nepher-cli` entry points are registered after install.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npcli --version
|
|
45
|
+
npcli --help
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
| Command / Group | Description |
|
|
51
|
+
|-----------------|-------------|
|
|
52
|
+
| `npcli login` | Log in with a Nepher API key |
|
|
53
|
+
| `npcli whoami` | Show the currently authenticated user |
|
|
54
|
+
| `npcli logout` | Clear locally stored credentials |
|
|
55
|
+
| `npcli account` | API keys and coldkey registration |
|
|
56
|
+
| `npcli tournament` | Browse tournaments, submit agents, leaderboards |
|
|
57
|
+
| `npcli envhub` | Manage Isaac Lab environment bundles |
|
|
58
|
+
| `npcli hackathon` | Browse and submit to hackathons |
|
|
59
|
+
| `npcli simstore` | SimStore marketplace *(coming soon)* |
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
62
|
+
|
|
63
|
+
### Authenticate
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npcli login --api-key nepher_xxxxxxxx
|
|
67
|
+
npcli whoami
|
|
68
|
+
npcli logout
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Get your API key at [account.nepher.ai](https://account.nepher.ai) → Account → API Keys.
|
|
72
|
+
For CI/CD, set `NEPHER_API_KEY=nepher_xxxxxxxx` instead of logging in.
|
|
73
|
+
|
|
74
|
+
### Tournaments
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npcli tournament list
|
|
78
|
+
npcli tournament list-active
|
|
79
|
+
npcli tournament status <tournament_id>
|
|
80
|
+
npcli tournament leaderboard <tournament_id>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Check your agent directory structure (no extra dependencies needed):
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npcli tournament check --path ./my-agent
|
|
87
|
+
npcli tournament check --path ./my-agent --verbose # also show recommended-file warnings
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Submit an agent (requires `bittensor` for wallet signing):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install bittensor
|
|
94
|
+
# or: pip install "nepher-cli[bittensor]"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npcli tournament submit --path ./my-agent --wallet-name miner --wallet-hotkey default
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Full options for `submit`:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
--path <path> Agent directory
|
|
105
|
+
--wallet-name <str> Bittensor wallet name (default: miner)
|
|
106
|
+
--wallet-hotkey <str> Bittensor wallet hotkey (default: default)
|
|
107
|
+
--api-key <key> Nepher API key (falls back to stored credentials)
|
|
108
|
+
--tournament-id <id> Target tournament ID (required when multiple are active)
|
|
109
|
+
--api-url <url> Override tournament API URL
|
|
110
|
+
-v / --verbose Verbose output
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### EnvHub
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npcli envhub list
|
|
117
|
+
npcli envhub download <env_id>
|
|
118
|
+
npcli envhub upload ./my-bundle --category navigation
|
|
119
|
+
npcli envhub cache list
|
|
120
|
+
npcli envhub cache info
|
|
121
|
+
npcli envhub cache clear
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Hackathons
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npcli hackathon list
|
|
128
|
+
|
|
129
|
+
npcli hackathon submit \
|
|
130
|
+
--title "My entry" \
|
|
131
|
+
--submission ./my-project \
|
|
132
|
+
--assets ./my-assets
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Full options:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
--hackathon-id <uuid> Required when multiple hackathons are open
|
|
139
|
+
--title <str> Entry title
|
|
140
|
+
--description <markdown> Entry description
|
|
141
|
+
--thumbnail <file> Cover image (JPEG, PNG, WebP, GIF)
|
|
142
|
+
--submission <path> Project folder or submission.zip
|
|
143
|
+
--assets <path> Assets folder or assets.zip (images, videos, PDFs)
|
|
144
|
+
--public-source Mark source as public
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### API Keys
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npcli account api-keys list
|
|
151
|
+
npcli account api-keys create --name "CI key" --platform hackertone
|
|
152
|
+
npcli account api-keys revoke <key_id>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Coldkey Registration
|
|
156
|
+
|
|
157
|
+
Bind a Bittensor coldkey to your account (requires `bittensor` + `btcli` on PATH):
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pip install bittensor
|
|
161
|
+
npcli account register-coldkey --wallet <wallet_name>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## API Key Requirements
|
|
165
|
+
|
|
166
|
+
- Must start with `nepher_`
|
|
167
|
+
- Must be active and not expired
|
|
168
|
+
- `hackathon submit` requires **Hackathon** scope (or an unrestricted key)
|
|
169
|
+
- `tournament submit` requires **Tournament** scope (or an unrestricted key)
|
|
170
|
+
|
|
171
|
+
## Troubleshooting
|
|
172
|
+
|
|
173
|
+
| Error | Fix |
|
|
174
|
+
|-------|-----|
|
|
175
|
+
| `npcli: command not found` | Ensure `pip install` succeeded and Python scripts dir is on `PATH` |
|
|
176
|
+
| `invalid api key format` | Key must start with `nepher_` |
|
|
177
|
+
| `api key does not have hackathon access` | Enable Hackathon scope or use an unrestricted key |
|
|
178
|
+
| `api key expired` | Run `npcli account api-keys create` |
|
|
179
|
+
| `Several hackathons are accepting submissions` | Re-run with `--hackathon-id` |
|
|
180
|
+
| `bittensor not installed` | `pip install bittensor` (only needed for `tournament submit`) |
|
|
181
|
+
| `Not logged in` | `npcli login --api-key nepher_...` |
|
|
182
|
+
|
|
183
|
+
Run any command with `--help` for full flag details:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
npcli --help
|
|
187
|
+
npcli hackathon submit --help
|
|
188
|
+
npcli tournament submit --help
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
nepher_cli/__init__.py,sha256=L11vbIe673ZKYNG-FDL_KhGKcTmharqE6PQS9Wo-Rrw,81
|
|
2
|
+
nepher_cli/__main__.py,sha256=FMYmbifGU7eWdjSmv0RXSgXUO0EGzqsMkn2AA2dAws4,93
|
|
3
|
+
nepher_cli/cli.py,sha256=LUCi6ZjpcAjPiUKvKyabddASUoddzLK2aVJ3s5eqP3c,1873
|
|
4
|
+
nepher_cli/config.py,sha256=u3-D3XVSpmu_QCXaVqN7A4gXI5tkCp5P66M2SrWrscw,916
|
|
5
|
+
nepher_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
nepher_cli/commands/__init__.py,sha256=JXNTkej-suvV6Jc3JD0EbB1gd1tN4kRpghV9_B4Smj4,29
|
|
7
|
+
nepher_cli/commands/account.py,sha256=F76UrcCakYBYT9w-gGCaz66XrEFDlUEGCtLqPKQrtwA,19574
|
|
8
|
+
nepher_cli/commands/envhub.py,sha256=EapZjDahWwLFxHA5hWKGIJQkOJoLBlvzjaKjVZtOI2g,17984
|
|
9
|
+
nepher_cli/commands/hackathon.py,sha256=8YtoW-w9nmNbEN1hfmQwVNGeIkJXCLR5u5TT_8LiQHE,29042
|
|
10
|
+
nepher_cli/commands/simstore.py,sha256=8lrUIQEZzynPzQMWN9K8TWwoSWUUYBTPRO4NUTzi-OY,1339
|
|
11
|
+
nepher_cli/commands/tournament.py,sha256=pg4ZcriLZjF9lwJID4XK3-hwTWqVU8TLGyU_KKSN1C8,25374
|
|
12
|
+
nepher_cli/core/__init__.py,sha256=9XoS2YWSa28pFNeSvj0lQ6qcprhgXKVmwUZyQck0F44,55
|
|
13
|
+
nepher_cli/core/credentials.py,sha256=i6HLNLkawydJnzpjw_YRGqcMu5P3CvIuq8vsdKBwmhk,6723
|
|
14
|
+
nepher_cli/core/http.py,sha256=gGwIqd-rTSYASmwhSwamK6ksNUPTc3cmNztJzmer47M,2497
|
|
15
|
+
nepher_cli/envhub/__init__.py,sha256=l-VLi2YioXuRRJiJc7qfQlyaHIreQB30OXAENRjsl6M,64
|
|
16
|
+
nepher_cli/envhub/cache.py,sha256=fTxSdk3Kf4rbTD93juhUFhMNN7K4JK3lKCBDjJKMp90,1815
|
|
17
|
+
nepher_cli/envhub/config.py,sha256=Fa8KcihM9X5rW4xqz1ppzHUDjenn5o-bGGfpeGf-LvE,5395
|
|
18
|
+
nepher_cli/tournament/__init__.py,sha256=o-Ap1Pke9Gq4LrcQd33GP5Gu8o3K8amiXMRhDgM8Gbk,65
|
|
19
|
+
nepher_cli/tournament/agent_check.py,sha256=9k92L4e49Np54IDHEzIpKI0xjbDyY7YCU6hqNoYl3iU,2229
|
|
20
|
+
nepher_cli/tournament/api.py,sha256=141yi2elQ3bJB68m26kICMurT7uE9ewLhSxdpSTeeBo,2957
|
|
21
|
+
nepher_cli/tournament/packer.py,sha256=Xa6HMFjP5bRLDGr2Cws8DJFrQZoNCNBnWenVrjkQAjI,1742
|
|
22
|
+
nepher_cli/tournament/wallet.py,sha256=tfeUA7YOWr7GW0zMXVlaXDAIGxRw8wBLwFNcPOxwmwI,3250
|
|
23
|
+
nepher_cli-0.2.0.dist-info/METADATA,sha256=6_zB4KiNtO65Bzr8KihUpDrvi-GY67X3OXdCTISmHGU,5463
|
|
24
|
+
nepher_cli-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
25
|
+
nepher_cli-0.2.0.dist-info/entry_points.txt,sha256=QQ1l07o9WxwntxuU1K3Hnz7nRc0fFKRBRMAHJlkjfEQ,79
|
|
26
|
+
nepher_cli-0.2.0.dist-info/RECORD,,
|