nepher-cli-test 0.2.7__tar.gz → 0.2.8__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.
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/PKG-INFO +49 -63
- nepher_cli_test-0.2.8/README.md +172 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/pyproject.toml +6 -5
- nepher_cli_test-0.2.8/src/nepher_cli/__init__.py +10 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/cli.py +6 -1
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/commands/account.py +73 -1
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/commands/tournament.py +39 -9
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/config.py +2 -4
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/tournament/api.py +20 -3
- nepher_cli_test-0.2.7/README.test.md +0 -186
- nepher_cli_test-0.2.7/src/nepher_cli/__init__.py +0 -3
- nepher_cli_test-0.2.7/src/nepher_cli/cli_test.py +0 -19
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/.gitignore +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/__main__.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/commands/__init__.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/commands/envhub.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/commands/hackathon.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/commands/highlight.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/commands/simstore.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/core/__init__.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/core/credentials.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/core/http.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/envhub/__init__.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/envhub/cache.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/envhub/config.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/py.typed +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/tournament/__init__.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/tournament/agent_check.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/tournament/packer.py +0 -0
- {nepher_cli_test-0.2.7 → nepher_cli_test-0.2.8}/src/nepher_cli/tournament/wallet.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nepher-cli-test
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: npcli
|
|
3
|
+
Version: 0.2.8
|
|
4
|
+
Summary: npcli — unified Nepher command-line interface for accounts, hackathons, EnvHub, tournaments, and SimStore
|
|
5
5
|
Project-URL: Homepage, https://github.com/nepher-ai/nepher-cli
|
|
6
6
|
Author: Nepher
|
|
7
7
|
License: MIT
|
|
@@ -26,90 +26,76 @@ Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
|
26
26
|
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
|
|
29
|
-
# nepher-cli
|
|
29
|
+
# nepher-cli
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
For production, use [`nepher-cli`](https://pypi.org/project/nepher-cli/) and the `npcli` command instead.
|
|
31
|
+
The unified CLI for [Nepher Robotics](https://nepher.ai) — accounts, hackathons, EnvHub, tournaments, and SimStore from a single tool.
|
|
34
32
|
|
|
35
33
|
**Requires:** Python 3.10+
|
|
36
34
|
|
|
37
35
|
## Install
|
|
38
36
|
|
|
39
37
|
```bash
|
|
40
|
-
pip install nepher-cli
|
|
38
|
+
pip install nepher-cli
|
|
41
39
|
```
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
Both `npcli` and `nepher-cli` entry points are registered after install.
|
|
44
42
|
|
|
45
43
|
```bash
|
|
46
|
-
npcli
|
|
47
|
-
npcli
|
|
44
|
+
npcli --version
|
|
45
|
+
npcli --help
|
|
48
46
|
```
|
|
49
47
|
|
|
50
|
-
## Staging API endpoints
|
|
51
|
-
|
|
52
|
-
| Service | Default base |
|
|
53
|
-
|---------|--------------|
|
|
54
|
-
| Account | `https://api.staging.nepher.ai/account` |
|
|
55
|
-
| Tournament | `https://api.staging.nepher.ai/tournament` |
|
|
56
|
-
| EnvHub | `https://api.staging.nepher.ai/envhub` |
|
|
57
|
-
| Hackathon | `https://api.staging.nepher.ai/hackathon` |
|
|
58
|
-
| SimStore | `https://simstore-staging.nepher.ai` |
|
|
59
|
-
|
|
60
|
-
Override with `NEPHER_API_URL` (and service-specific vars) if needed.
|
|
61
|
-
|
|
62
48
|
## Commands
|
|
63
49
|
|
|
64
50
|
| Command / Group | Description |
|
|
65
51
|
|-----------------|-------------|
|
|
66
|
-
| `npcli
|
|
67
|
-
| `npcli
|
|
68
|
-
| `npcli
|
|
69
|
-
| `npcli
|
|
70
|
-
| `npcli
|
|
71
|
-
| `npcli
|
|
72
|
-
| `npcli
|
|
73
|
-
| `npcli
|
|
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)* |
|
|
74
60
|
|
|
75
61
|
## Quick Start
|
|
76
62
|
|
|
77
63
|
### Authenticate
|
|
78
64
|
|
|
79
65
|
```bash
|
|
80
|
-
npcli
|
|
81
|
-
npcli
|
|
82
|
-
npcli
|
|
66
|
+
npcli login --api-key nepher_xxxxxxxx
|
|
67
|
+
npcli whoami
|
|
68
|
+
npcli logout
|
|
83
69
|
```
|
|
84
70
|
|
|
85
|
-
Get
|
|
71
|
+
Get your API key at [nepher.ai/account](https://nepher.ai/account) → Account → API Keys.
|
|
86
72
|
For CI/CD, set `NEPHER_API_KEY=nepher_xxxxxxxx` instead of logging in.
|
|
87
73
|
|
|
88
74
|
### Tournaments
|
|
89
75
|
|
|
90
76
|
```bash
|
|
91
|
-
npcli
|
|
92
|
-
npcli
|
|
93
|
-
npcli
|
|
94
|
-
npcli
|
|
77
|
+
npcli tournament list
|
|
78
|
+
npcli tournament list-active
|
|
79
|
+
npcli tournament status <tournament_id>
|
|
80
|
+
npcli tournament leaderboard <tournament_id>
|
|
95
81
|
```
|
|
96
82
|
|
|
97
83
|
Check your agent directory structure (no extra dependencies needed):
|
|
98
84
|
|
|
99
85
|
```bash
|
|
100
|
-
npcli
|
|
101
|
-
npcli
|
|
86
|
+
npcli tournament check --path ./my-agent
|
|
87
|
+
npcli tournament check --path ./my-agent --verbose # also show recommended-file warnings
|
|
102
88
|
```
|
|
103
89
|
|
|
104
90
|
Submit an agent (requires `bittensor-wallet` for wallet signing):
|
|
105
91
|
|
|
106
92
|
```bash
|
|
107
93
|
pip install bittensor-wallet
|
|
108
|
-
# or: pip install "nepher-cli
|
|
94
|
+
# or: pip install "nepher-cli[bittensor]"
|
|
109
95
|
```
|
|
110
96
|
|
|
111
97
|
```bash
|
|
112
|
-
npcli
|
|
98
|
+
npcli tournament submit --path ./my-agent --wallet-name miner --wallet-hotkey default
|
|
113
99
|
```
|
|
114
100
|
|
|
115
101
|
Full options for `submit`:
|
|
@@ -127,20 +113,20 @@ Full options for `submit`:
|
|
|
127
113
|
### EnvHub
|
|
128
114
|
|
|
129
115
|
```bash
|
|
130
|
-
npcli
|
|
131
|
-
npcli
|
|
132
|
-
npcli
|
|
133
|
-
npcli
|
|
134
|
-
npcli
|
|
135
|
-
npcli
|
|
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
|
|
136
122
|
```
|
|
137
123
|
|
|
138
124
|
### Hackathons
|
|
139
125
|
|
|
140
126
|
```bash
|
|
141
|
-
npcli
|
|
127
|
+
npcli hackathon list
|
|
142
128
|
|
|
143
|
-
npcli
|
|
129
|
+
npcli hackathon submit \
|
|
144
130
|
--title "My entry" \
|
|
145
131
|
--submission ./my-project \
|
|
146
132
|
--assets ./my-assets
|
|
@@ -160,14 +146,14 @@ Full options:
|
|
|
160
146
|
|
|
161
147
|
### API Keys
|
|
162
148
|
|
|
163
|
-
`list` / `create` / `revoke` need a **JWT session** from `npcli
|
|
149
|
+
`list` / `create` / `revoke` need a **JWT session** from `npcli account login`.
|
|
164
150
|
Do **not** pass `--api-key` on these commands (that flag sends `X-API-Key`, which the account API rejects for key management).
|
|
165
151
|
|
|
166
152
|
```bash
|
|
167
|
-
npcli
|
|
168
|
-
npcli
|
|
169
|
-
npcli
|
|
170
|
-
npcli
|
|
153
|
+
npcli account login --api-key nepher_...
|
|
154
|
+
npcli account api-keys list
|
|
155
|
+
npcli account api-keys create --name "CI key" --platform hackathon
|
|
156
|
+
npcli account api-keys revoke <key_id>
|
|
171
157
|
```
|
|
172
158
|
|
|
173
159
|
### Coldkey Registration
|
|
@@ -176,7 +162,7 @@ Bind a Bittensor coldkey to your account (requires `bittensor-wallet`; `btcli` i
|
|
|
176
162
|
|
|
177
163
|
```bash
|
|
178
164
|
pip install bittensor-wallet
|
|
179
|
-
npcli
|
|
165
|
+
npcli account register-coldkey --wallet <wallet_name>
|
|
180
166
|
```
|
|
181
167
|
|
|
182
168
|
Signing uses the local coldkey via `bittensor-wallet` and does not import `btcli`. If you still have a mixed Bittensor venv (`scalecodec` + `cyscale`), `register-coldkey` keeps working as long as `bittensor-wallet` is installed.
|
|
@@ -192,21 +178,21 @@ Signing uses the local coldkey via `bittensor-wallet` and does not import `btcli
|
|
|
192
178
|
|
|
193
179
|
| Error | Fix |
|
|
194
180
|
|-------|-----|
|
|
195
|
-
| `npcli
|
|
181
|
+
| `npcli: command not found` | Ensure `pip install` succeeded and Python scripts dir is on `PATH` |
|
|
196
182
|
| `invalid api key format` | Key must start with `nepher_` |
|
|
197
183
|
| `api key does not have hackathon access` | Enable Hackathon scope or use an unrestricted key |
|
|
198
|
-
| `api key expired` | Run `npcli
|
|
184
|
+
| `api key expired` | Run `npcli account api-keys create` |
|
|
199
185
|
| `Several hackathons are accepting submissions` | Re-run with `--hackathon-id` |
|
|
200
186
|
| `bittensor-wallet not installed` | `pip install bittensor-wallet` (needed for `tournament submit` and `account register-coldkey`) |
|
|
201
|
-
| `Not logged in` | `npcli
|
|
202
|
-
| `Conflict detected: 'scalecodec' ... conflicts with 'cyscale'` | Leftover `scalecodec` after a Bittensor upgrade. Prefer `pip install bittensor-wallet` so npcli
|
|
187
|
+
| `Not logged in` | `npcli login --api-key nepher_...` |
|
|
188
|
+
| `Conflict detected: 'scalecodec' ... conflicts with 'cyscale'` | Leftover `scalecodec` after a Bittensor upgrade. Prefer `pip install bittensor-wallet` so npcli never needs `btcli`. To repair `btcli` itself: `pip uninstall scalecodec cyscale -y && pip install -U cyscale --force-reinstall` |
|
|
203
189
|
|
|
204
190
|
Run any command with `--help` for full flag details:
|
|
205
191
|
|
|
206
192
|
```bash
|
|
207
|
-
npcli
|
|
208
|
-
npcli
|
|
209
|
-
npcli
|
|
193
|
+
npcli --help
|
|
194
|
+
npcli hackathon submit --help
|
|
195
|
+
npcli tournament submit --help
|
|
210
196
|
```
|
|
211
197
|
|
|
212
198
|
## License
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# nepher-cli
|
|
2
|
+
|
|
3
|
+
The unified CLI for [Nepher Robotics](https://nepher.ai) — accounts, hackathons, EnvHub, tournaments, and SimStore from a single tool.
|
|
4
|
+
|
|
5
|
+
**Requires:** Python 3.10+
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install nepher-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Both `npcli` and `nepher-cli` entry points are registered after install.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npcli --version
|
|
17
|
+
npcli --help
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
| Command / Group | Description |
|
|
23
|
+
|-----------------|-------------|
|
|
24
|
+
| `npcli login` | Log in with a Nepher API key |
|
|
25
|
+
| `npcli whoami` | Show the currently authenticated user |
|
|
26
|
+
| `npcli logout` | Clear locally stored credentials |
|
|
27
|
+
| `npcli account` | API keys and coldkey registration |
|
|
28
|
+
| `npcli tournament` | Browse tournaments, submit agents, leaderboards |
|
|
29
|
+
| `npcli envhub` | Manage Isaac Lab environment bundles |
|
|
30
|
+
| `npcli hackathon` | Browse and submit to hackathons |
|
|
31
|
+
| `npcli simstore` | SimStore marketplace *(coming soon)* |
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Authenticate
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npcli login --api-key nepher_xxxxxxxx
|
|
39
|
+
npcli whoami
|
|
40
|
+
npcli logout
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Get your API key at [nepher.ai/account](https://nepher.ai/account) → Account → API Keys.
|
|
44
|
+
For CI/CD, set `NEPHER_API_KEY=nepher_xxxxxxxx` instead of logging in.
|
|
45
|
+
|
|
46
|
+
### Tournaments
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npcli tournament list
|
|
50
|
+
npcli tournament list-active
|
|
51
|
+
npcli tournament status <tournament_id>
|
|
52
|
+
npcli tournament leaderboard <tournament_id>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Check your agent directory structure (no extra dependencies needed):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npcli tournament check --path ./my-agent
|
|
59
|
+
npcli tournament check --path ./my-agent --verbose # also show recommended-file warnings
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Submit an agent (requires `bittensor-wallet` for wallet signing):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install bittensor-wallet
|
|
66
|
+
# or: pip install "nepher-cli[bittensor]"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npcli tournament submit --path ./my-agent --wallet-name miner --wallet-hotkey default
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Full options for `submit`:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
--path <path> Agent directory
|
|
77
|
+
--wallet-name <str> Bittensor wallet name (default: miner)
|
|
78
|
+
--wallet-hotkey <str> Bittensor wallet hotkey (default: default)
|
|
79
|
+
--api-key <key> Nepher API key (falls back to stored credentials)
|
|
80
|
+
--tournament-id <id> Target tournament ID (required when multiple are active)
|
|
81
|
+
--api-url <url> Override tournament API URL
|
|
82
|
+
-v / --verbose Verbose output
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### EnvHub
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npcli envhub list
|
|
89
|
+
npcli envhub download <env_id>
|
|
90
|
+
npcli envhub upload ./my-bundle --category navigation
|
|
91
|
+
npcli envhub cache list
|
|
92
|
+
npcli envhub cache info
|
|
93
|
+
npcli envhub cache clear
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Hackathons
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npcli hackathon list
|
|
100
|
+
|
|
101
|
+
npcli hackathon submit \
|
|
102
|
+
--title "My entry" \
|
|
103
|
+
--submission ./my-project \
|
|
104
|
+
--assets ./my-assets
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Full options:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
--hackathon-id <uuid> Required when multiple hackathons are open
|
|
111
|
+
--title <str> Entry title
|
|
112
|
+
--description <markdown> Entry description
|
|
113
|
+
--thumbnail <file> Cover image (JPEG, PNG, WebP, GIF)
|
|
114
|
+
--submission <path> Project folder or submission.zip
|
|
115
|
+
--assets <path> Assets folder or assets.zip (images, videos, PDFs)
|
|
116
|
+
--public-source Mark source as public
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### API Keys
|
|
120
|
+
|
|
121
|
+
`list` / `create` / `revoke` need a **JWT session** from `npcli account login`.
|
|
122
|
+
Do **not** pass `--api-key` on these commands (that flag sends `X-API-Key`, which the account API rejects for key management).
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npcli account login --api-key nepher_...
|
|
126
|
+
npcli account api-keys list
|
|
127
|
+
npcli account api-keys create --name "CI key" --platform hackathon
|
|
128
|
+
npcli account api-keys revoke <key_id>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Coldkey Registration
|
|
132
|
+
|
|
133
|
+
Bind a Bittensor coldkey to your account (requires `bittensor-wallet`; `btcli` is optional fallback):
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install bittensor-wallet
|
|
137
|
+
npcli account register-coldkey --wallet <wallet_name>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Signing uses the local coldkey via `bittensor-wallet` and does not import `btcli`. If you still have a mixed Bittensor venv (`scalecodec` + `cyscale`), `register-coldkey` keeps working as long as `bittensor-wallet` is installed.
|
|
141
|
+
|
|
142
|
+
## API Key Requirements
|
|
143
|
+
|
|
144
|
+
- Must start with `nepher_`
|
|
145
|
+
- Must be active and not expired
|
|
146
|
+
- `hackathon submit` requires **Hackathon** scope (or an unrestricted key)
|
|
147
|
+
- `tournament submit` requires **Tournament** scope (or an unrestricted key)
|
|
148
|
+
|
|
149
|
+
## Troubleshooting
|
|
150
|
+
|
|
151
|
+
| Error | Fix |
|
|
152
|
+
|-------|-----|
|
|
153
|
+
| `npcli: command not found` | Ensure `pip install` succeeded and Python scripts dir is on `PATH` |
|
|
154
|
+
| `invalid api key format` | Key must start with `nepher_` |
|
|
155
|
+
| `api key does not have hackathon access` | Enable Hackathon scope or use an unrestricted key |
|
|
156
|
+
| `api key expired` | Run `npcli account api-keys create` |
|
|
157
|
+
| `Several hackathons are accepting submissions` | Re-run with `--hackathon-id` |
|
|
158
|
+
| `bittensor-wallet not installed` | `pip install bittensor-wallet` (needed for `tournament submit` and `account register-coldkey`) |
|
|
159
|
+
| `Not logged in` | `npcli login --api-key nepher_...` |
|
|
160
|
+
| `Conflict detected: 'scalecodec' ... conflicts with 'cyscale'` | Leftover `scalecodec` after a Bittensor upgrade. Prefer `pip install bittensor-wallet` so npcli never needs `btcli`. To repair `btcli` itself: `pip uninstall scalecodec cyscale -y && pip install -U cyscale --force-reinstall` |
|
|
161
|
+
|
|
162
|
+
Run any command with `--help` for full flag details:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npcli --help
|
|
166
|
+
npcli hackathon submit --help
|
|
167
|
+
npcli tournament submit --help
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT
|
|
@@ -4,9 +4,9 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nepher-cli-test"
|
|
7
|
-
version = "0.2.
|
|
8
|
-
description = "npcli
|
|
9
|
-
readme = "README.
|
|
7
|
+
version = "0.2.8"
|
|
8
|
+
description = "npcli — unified Nepher command-line interface for accounts, hackathons, EnvHub, tournaments, and SimStore"
|
|
9
|
+
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = { text = "MIT" }
|
|
12
12
|
authors = [{ name = "Nepher" }]
|
|
@@ -36,7 +36,8 @@ dev = [
|
|
|
36
36
|
]
|
|
37
37
|
|
|
38
38
|
[project.scripts]
|
|
39
|
-
npcli
|
|
39
|
+
npcli = "nepher_cli.cli:main"
|
|
40
|
+
nepher-cli = "nepher_cli.cli:main"
|
|
40
41
|
|
|
41
42
|
[project.urls]
|
|
42
43
|
Homepage = "https://github.com/nepher-ai/nepher-cli"
|
|
@@ -46,7 +47,7 @@ packages = ["src/nepher_cli"]
|
|
|
46
47
|
core-metadata-version = "2.4"
|
|
47
48
|
|
|
48
49
|
[tool.hatch.build.targets.sdist]
|
|
49
|
-
include = ["src/nepher_cli", "README.
|
|
50
|
+
include = ["src/nepher_cli", "README.md", "pyproject.toml"]
|
|
50
51
|
core-metadata-version = "2.4"
|
|
51
52
|
|
|
52
53
|
[tool.ruff]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""npcli — unified Nepher command-line interface."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
__version__ = version("nepher-cli")
|
|
9
|
+
except PackageNotFoundError: # pragma: no cover
|
|
10
|
+
__version__ = "0.0.0"
|
|
@@ -15,7 +15,7 @@ from nepher_cli.commands.tournament import tournament
|
|
|
15
15
|
@click.group(
|
|
16
16
|
context_settings={"help_option_names": ["-h", "--help"], "max_content_width": 100},
|
|
17
17
|
)
|
|
18
|
-
@click.version_option(version=__version__)
|
|
18
|
+
@click.version_option(version=__version__, package_name="nepher-cli", prog_name="npcli")
|
|
19
19
|
def main() -> None:
|
|
20
20
|
"""npcli — the unified Nepher command-line interface.
|
|
21
21
|
|
|
@@ -39,6 +39,11 @@ def main() -> None:
|
|
|
39
39
|
npcli envhub list
|
|
40
40
|
npcli tournament list
|
|
41
41
|
|
|
42
|
+
\b
|
|
43
|
+
Tournament submit requires bittensor-wallet for wallet signing:
|
|
44
|
+
pip install bittensor-wallet
|
|
45
|
+
# or: pip install "nepher-cli[bittensor]"
|
|
46
|
+
|
|
42
47
|
Run any sub-command with --help for details and examples.
|
|
43
48
|
|
|
44
49
|
API keys are created at https://nepher.ai/account (Account > API Keys).
|
|
@@ -396,7 +396,7 @@ def register_coldkey(wallet: str, api_key: str, base_url: str) -> int:
|
|
|
396
396
|
|
|
397
397
|
@click.group("account")
|
|
398
398
|
def account() -> None:
|
|
399
|
-
"""Manage your Nepher account — login, API keys, and
|
|
399
|
+
"""Manage your Nepher account — login, API keys, coldkey, and platform balance."""
|
|
400
400
|
|
|
401
401
|
|
|
402
402
|
# ── Auth ────────────────────────────────────────────────────────────────────
|
|
@@ -627,6 +627,78 @@ def api_keys_revoke(key_id: str, api_key: str | None) -> None:
|
|
|
627
627
|
# ── Coldkey ──────────────────────────────────────────────────────────────────
|
|
628
628
|
|
|
629
629
|
|
|
630
|
+
@account.command("balance")
|
|
631
|
+
@click.option(
|
|
632
|
+
"--api-key", "--apikey", "api_key",
|
|
633
|
+
default=None, envvar="NEPHER_API_KEY", metavar="KEY",
|
|
634
|
+
help="Nepher API key (nepher_...). Falls back to stored credentials.",
|
|
635
|
+
)
|
|
636
|
+
def cmd_balance(api_key: str | None) -> None:
|
|
637
|
+
"""Show platform balance used for submission fees and unlocks."""
|
|
638
|
+
headers = _require_auth(api_key)
|
|
639
|
+
url = f"{ACCOUNT_BACKEND.rstrip('/')}/api/v1/billing/balance"
|
|
640
|
+
try:
|
|
641
|
+
r = httpx.get(url, headers=headers, timeout=30.0)
|
|
642
|
+
except httpx.RequestError as e:
|
|
643
|
+
console.print(f"[red]Network error[/red]: {e}")
|
|
644
|
+
raise SystemExit(1) from e
|
|
645
|
+
if r.status_code >= 400:
|
|
646
|
+
console.print(f"[red]{parse_error_body(r.text) or r.text.strip() or f'HTTP {r.status_code}'}[/red]")
|
|
647
|
+
raise SystemExit(1)
|
|
648
|
+
body = r.json()
|
|
649
|
+
console.print(f" Balance : [bold]{body.get('balance_tao', 0)} TAO[/bold]")
|
|
650
|
+
if body.get("coldkey"):
|
|
651
|
+
console.print(f" Coldkey : {body['coldkey']}")
|
|
652
|
+
else:
|
|
653
|
+
console.print(" Coldkey : [yellow]not registered[/yellow] — run npcli account register-coldkey")
|
|
654
|
+
if body.get("network"):
|
|
655
|
+
console.print(f" Network : {body['network']}")
|
|
656
|
+
console.print(
|
|
657
|
+
" Deposit : "
|
|
658
|
+
+ ("available via Account → Billing on the website" if body.get("deposit_available") else "unavailable")
|
|
659
|
+
)
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
@account.command("ledger")
|
|
663
|
+
@click.option("--limit", default=20, show_default=True, help="Number of ledger rows.")
|
|
664
|
+
@click.option(
|
|
665
|
+
"--api-key", "--apikey", "api_key",
|
|
666
|
+
default=None, envvar="NEPHER_API_KEY", metavar="KEY",
|
|
667
|
+
help="Nepher API key (nepher_...). Falls back to stored credentials.",
|
|
668
|
+
)
|
|
669
|
+
def cmd_ledger(limit: int, api_key: str | None) -> None:
|
|
670
|
+
"""Show recent platform billing history (deposits, fees, unlocks)."""
|
|
671
|
+
headers = _require_auth(api_key)
|
|
672
|
+
url = f"{ACCOUNT_BACKEND.rstrip('/')}/api/v1/billing/ledger"
|
|
673
|
+
try:
|
|
674
|
+
r = httpx.get(url, headers=headers, params={"limit": limit}, timeout=30.0)
|
|
675
|
+
except httpx.RequestError as e:
|
|
676
|
+
console.print(f"[red]Network error[/red]: {e}")
|
|
677
|
+
raise SystemExit(1) from e
|
|
678
|
+
if r.status_code >= 400:
|
|
679
|
+
console.print(f"[red]{parse_error_body(r.text) or r.text.strip() or f'HTTP {r.status_code}'}[/red]")
|
|
680
|
+
raise SystemExit(1)
|
|
681
|
+
items = (r.json() or {}).get("items") or []
|
|
682
|
+
if not items:
|
|
683
|
+
console.print("[dim]No billing activity yet.[/dim]")
|
|
684
|
+
return
|
|
685
|
+
table = Table(show_header=True, header_style="bold")
|
|
686
|
+
table.add_column("When")
|
|
687
|
+
table.add_column("Type")
|
|
688
|
+
table.add_column("Amount (TAO)", justify="right")
|
|
689
|
+
table.add_column("Balance after", justify="right")
|
|
690
|
+
table.add_column("Details")
|
|
691
|
+
for row in items:
|
|
692
|
+
table.add_row(
|
|
693
|
+
str(row.get("created_at") or "—"),
|
|
694
|
+
str(row.get("entry_type") or "—"),
|
|
695
|
+
f"{float(row.get('amount_tao') or 0):.6f}",
|
|
696
|
+
f"{float(row.get('balance_after_tao') or 0):.6f}",
|
|
697
|
+
str(row.get("description") or "—"),
|
|
698
|
+
)
|
|
699
|
+
console.print(table)
|
|
700
|
+
|
|
701
|
+
|
|
630
702
|
@account.command("register-coldkey")
|
|
631
703
|
@click.option("--wallet", required=True, metavar="NAME", help="Bittensor wallet name. Must exist in your local btcli wallet.")
|
|
632
704
|
@click.option(
|
|
@@ -530,6 +530,7 @@ def tournament_submit(
|
|
|
530
530
|
|
|
531
531
|
Requires [bold]bittensor-wallet[/bold] for wallet signing:
|
|
532
532
|
pip install bittensor-wallet
|
|
533
|
+
# or: pip install "nepher-cli[bittensor]"
|
|
533
534
|
"""
|
|
534
535
|
resolved_key = _resolve_api_key(api_key)
|
|
535
536
|
resolved_url = api_url or TOURNAMENT_BACKEND
|
|
@@ -581,16 +582,43 @@ def tournament_submit(
|
|
|
581
582
|
resolved_tournament_id = token_data["tournament_id"]
|
|
582
583
|
upload_token = token_data["upload_token"]
|
|
583
584
|
|
|
585
|
+
fee = token_data.get("submission_fee_tao")
|
|
586
|
+
if fee is not None:
|
|
587
|
+
console.print(
|
|
588
|
+
f"Submission fee: [bold]{fee} TAO[/bold] "
|
|
589
|
+
f"(debited from platform balance on upload)"
|
|
590
|
+
)
|
|
591
|
+
fee_min = token_data.get("submission_fee_min_tao")
|
|
592
|
+
fee_max = token_data.get("submission_fee_max_tao")
|
|
593
|
+
fee_dur = token_data.get("submission_fee_duration_hours")
|
|
594
|
+
if fee_min is not None and fee_max is not None:
|
|
595
|
+
console.print(
|
|
596
|
+
f" [dim]Fee curve: {fee_max} → {fee_min} TAO"
|
|
597
|
+
+ (f" over {fee_dur}h" if fee_dur is not None else "")
|
|
598
|
+
+ "[/dim]"
|
|
599
|
+
)
|
|
600
|
+
|
|
584
601
|
console.print("Uploading agent...")
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
602
|
+
try:
|
|
603
|
+
upload_result = await tournament_api.upload_agent(
|
|
604
|
+
api_key=resolved_key,
|
|
605
|
+
api_url=resolved_url,
|
|
606
|
+
tournament_id=resolved_tournament_id,
|
|
607
|
+
upload_token=upload_token,
|
|
608
|
+
miner_hotkey=miner_hotkey,
|
|
609
|
+
content_hash=content_hash,
|
|
610
|
+
file_path=archive,
|
|
611
|
+
)
|
|
612
|
+
except tournament_api.UploadChargeError as e:
|
|
613
|
+
console.print(f"[red]Submission fee failed:[/red] {e}")
|
|
614
|
+
console.print(
|
|
615
|
+
" Check balance with [bold]npcli account balance[/bold], "
|
|
616
|
+
"then deposit TAO on Account → Billing."
|
|
617
|
+
)
|
|
618
|
+
return 1
|
|
619
|
+
|
|
620
|
+
agent_id = upload_result["agent_id"]
|
|
621
|
+
charged = upload_result.get("submission_fee_tao")
|
|
594
622
|
|
|
595
623
|
t_title = _tournament_title(token_data)
|
|
596
624
|
t_task = _tournament_task_name(token_data)
|
|
@@ -599,6 +627,8 @@ def tournament_submit(
|
|
|
599
627
|
console.print("[green]Agent submitted successfully.[/green]")
|
|
600
628
|
console.print(f" Agent ID : [bold]{agent_id}[/bold]")
|
|
601
629
|
console.print(f" Tournament ID: [bold]{resolved_tournament_id}[/bold]")
|
|
630
|
+
if charged is not None:
|
|
631
|
+
console.print(f" Fee charged : [bold]{charged} TAO[/bold]")
|
|
602
632
|
if t_title and t_title != "—":
|
|
603
633
|
console.print(f" Title : {t_title}")
|
|
604
634
|
if t_task and t_task != "—":
|
|
@@ -5,10 +5,8 @@ from __future__ import annotations
|
|
|
5
5
|
import os
|
|
6
6
|
|
|
7
7
|
# Unified public API host (embedded product mounts). SimStore stays separate.
|
|
8
|
-
DEFAULT_WEBSITE_API = "https://api.nepher.ai"
|
|
9
|
-
|
|
10
|
-
SIMSTORE_BACKEND_DEFAULT = "https://api.simstore.nepher.ai"
|
|
11
|
-
STAGING_SIMSTORE_BACKEND = "https://simstore-staging.nepher.ai"
|
|
8
|
+
DEFAULT_WEBSITE_API = "https://api.staing.nepher.ai"
|
|
9
|
+
SIMSTORE_BACKEND_DEFAULT = "https://api.simstore-staging.nepher.ai"
|
|
12
10
|
|
|
13
11
|
|
|
14
12
|
def website_api_base() -> str:
|
|
@@ -21,6 +21,14 @@ def _json_headers(api_key: str) -> dict[str, str]:
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
class UploadChargeError(RuntimeError):
|
|
25
|
+
"""Raised when upload fails due to payment / platform balance."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, message: str, *, status_code: int = 402):
|
|
28
|
+
super().__init__(message)
|
|
29
|
+
self.status_code = status_code
|
|
30
|
+
|
|
31
|
+
|
|
24
32
|
def _raise_for_error(response: httpx.Response) -> None:
|
|
25
33
|
if response.status_code < 400:
|
|
26
34
|
return
|
|
@@ -29,6 +37,8 @@ def _raise_for_error(response: httpx.Response) -> None:
|
|
|
29
37
|
or response.text.strip()
|
|
30
38
|
or f"HTTP {response.status_code}"
|
|
31
39
|
)
|
|
40
|
+
if response.status_code == 402:
|
|
41
|
+
raise UploadChargeError(msg, status_code=402)
|
|
32
42
|
raise RuntimeError(msg)
|
|
33
43
|
|
|
34
44
|
|
|
@@ -76,8 +86,11 @@ async def upload_agent(
|
|
|
76
86
|
miner_hotkey: str,
|
|
77
87
|
content_hash: str,
|
|
78
88
|
file_path: Path,
|
|
79
|
-
) -> str:
|
|
80
|
-
"""POST /api/v1/agents/upload/{tournament_id} (multipart) →
|
|
89
|
+
) -> dict[str, Any]:
|
|
90
|
+
"""POST /api/v1/agents/upload/{tournament_id} (multipart) → response dict.
|
|
91
|
+
|
|
92
|
+
Returns at least ``agent_id``; may include ``submission_fee_tao``.
|
|
93
|
+
"""
|
|
81
94
|
url = f"{api_url.rstrip('/')}/api/v1/agents/upload/{tournament_id}"
|
|
82
95
|
headers = {
|
|
83
96
|
"X-API-Key": api_key,
|
|
@@ -97,4 +110,8 @@ async def upload_agent(
|
|
|
97
110
|
agent_id = data.get("id") or data.get("agent_id")
|
|
98
111
|
if not agent_id:
|
|
99
112
|
raise RuntimeError(f"No agent ID in upload response: {data}")
|
|
100
|
-
return
|
|
113
|
+
return {
|
|
114
|
+
"agent_id": str(agent_id),
|
|
115
|
+
"submission_fee_tao": data.get("submission_fee_tao"),
|
|
116
|
+
"raw": data,
|
|
117
|
+
}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
# nepher-cli-test
|
|
2
|
-
|
|
3
|
-
**Staging build** of the [Nepher CLI](https://github.com/nepher-ai/nepher-cli) — same commands as production, but defaults to **staging APIs** (`api.staging.nepher.ai`).
|
|
4
|
-
|
|
5
|
-
For production, use [`nepher-cli`](https://pypi.org/project/nepher-cli/) and the `npcli` command instead.
|
|
6
|
-
|
|
7
|
-
**Requires:** Python 3.10+
|
|
8
|
-
|
|
9
|
-
## Install
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
pip install nepher-cli-test
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
The `npcli-test` command is registered after install.
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npcli-test --version
|
|
19
|
-
npcli-test --help
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Staging API endpoints
|
|
23
|
-
|
|
24
|
-
| Service | Default base |
|
|
25
|
-
|---------|--------------|
|
|
26
|
-
| Account | `https://api.staging.nepher.ai/account` |
|
|
27
|
-
| Tournament | `https://api.staging.nepher.ai/tournament` |
|
|
28
|
-
| EnvHub | `https://api.staging.nepher.ai/envhub` |
|
|
29
|
-
| Hackathon | `https://api.staging.nepher.ai/hackathon` |
|
|
30
|
-
| SimStore | `https://simstore-staging.nepher.ai` |
|
|
31
|
-
|
|
32
|
-
Override with `NEPHER_API_URL` (and service-specific vars) if needed.
|
|
33
|
-
|
|
34
|
-
## Commands
|
|
35
|
-
|
|
36
|
-
| Command / Group | Description |
|
|
37
|
-
|-----------------|-------------|
|
|
38
|
-
| `npcli-test login` | Log in with a Nepher API key |
|
|
39
|
-
| `npcli-test whoami` | Show the currently authenticated user |
|
|
40
|
-
| `npcli-test logout` | Clear locally stored credentials |
|
|
41
|
-
| `npcli-test account` | API keys and coldkey registration |
|
|
42
|
-
| `npcli-test tournament` | Browse tournaments, submit agents, leaderboards |
|
|
43
|
-
| `npcli-test envhub` | Manage Isaac Lab environment bundles |
|
|
44
|
-
| `npcli-test hackathon` | Browse and submit to hackathons |
|
|
45
|
-
| `npcli-test simstore` | SimStore marketplace *(coming soon)* |
|
|
46
|
-
|
|
47
|
-
## Quick Start
|
|
48
|
-
|
|
49
|
-
### Authenticate
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npcli-test login --api-key nepher_xxxxxxxx
|
|
53
|
-
npcli-test whoami
|
|
54
|
-
npcli-test logout
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Get a staging API key at [staging.nepher.ai/account](https://staging.nepher.ai/account) → Account → API Keys.
|
|
58
|
-
For CI/CD, set `NEPHER_API_KEY=nepher_xxxxxxxx` instead of logging in.
|
|
59
|
-
|
|
60
|
-
### Tournaments
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
npcli-test tournament list
|
|
64
|
-
npcli-test tournament list-active
|
|
65
|
-
npcli-test tournament status <tournament_id>
|
|
66
|
-
npcli-test tournament leaderboard <tournament_id>
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Check your agent directory structure (no extra dependencies needed):
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
npcli-test tournament check --path ./my-agent
|
|
73
|
-
npcli-test tournament check --path ./my-agent --verbose # also show recommended-file warnings
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Submit an agent (requires `bittensor-wallet` for wallet signing):
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
pip install bittensor-wallet
|
|
80
|
-
# or: pip install "nepher-cli-test[bittensor]"
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
npcli-test tournament submit --path ./my-agent --wallet-name miner --wallet-hotkey default
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Full options for `submit`:
|
|
88
|
-
|
|
89
|
-
```
|
|
90
|
-
--path <path> Agent directory
|
|
91
|
-
--wallet-name <str> Bittensor wallet name (default: miner)
|
|
92
|
-
--wallet-hotkey <str> Bittensor wallet hotkey (default: default)
|
|
93
|
-
--api-key <key> Nepher API key (falls back to stored credentials)
|
|
94
|
-
--tournament-id <id> Target tournament ID (required when multiple are active)
|
|
95
|
-
--api-url <url> Override tournament API URL
|
|
96
|
-
-v / --verbose Verbose output
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### EnvHub
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
npcli-test envhub list
|
|
103
|
-
npcli-test envhub download <env_id>
|
|
104
|
-
npcli-test envhub upload ./my-bundle --category navigation
|
|
105
|
-
npcli-test envhub cache list
|
|
106
|
-
npcli-test envhub cache info
|
|
107
|
-
npcli-test envhub cache clear
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Hackathons
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
npcli-test hackathon list
|
|
114
|
-
|
|
115
|
-
npcli-test hackathon submit \
|
|
116
|
-
--title "My entry" \
|
|
117
|
-
--submission ./my-project \
|
|
118
|
-
--assets ./my-assets
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Full options:
|
|
122
|
-
|
|
123
|
-
```
|
|
124
|
-
--hackathon-id <uuid> Required when multiple hackathons are open
|
|
125
|
-
--title <str> Entry title
|
|
126
|
-
--description <markdown> Entry description
|
|
127
|
-
--thumbnail <file> Cover image (JPEG, PNG, WebP, GIF)
|
|
128
|
-
--submission <path> Project folder or submission.zip
|
|
129
|
-
--assets <path> Assets folder or assets.zip (images, videos, PDFs)
|
|
130
|
-
--public-source Mark source as public
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### API Keys
|
|
134
|
-
|
|
135
|
-
`list` / `create` / `revoke` need a **JWT session** from `npcli-test account login`.
|
|
136
|
-
Do **not** pass `--api-key` on these commands (that flag sends `X-API-Key`, which the account API rejects for key management).
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
npcli-test account login --api-key nepher_...
|
|
140
|
-
npcli-test account api-keys list
|
|
141
|
-
npcli-test account api-keys create --name "CI key" --platform hackathon
|
|
142
|
-
npcli-test account api-keys revoke <key_id>
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Coldkey Registration
|
|
146
|
-
|
|
147
|
-
Bind a Bittensor coldkey to your account (requires `bittensor-wallet`; `btcli` is optional fallback):
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
pip install bittensor-wallet
|
|
151
|
-
npcli-test account register-coldkey --wallet <wallet_name>
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Signing uses the local coldkey via `bittensor-wallet` and does not import `btcli`. If you still have a mixed Bittensor venv (`scalecodec` + `cyscale`), `register-coldkey` keeps working as long as `bittensor-wallet` is installed.
|
|
155
|
-
|
|
156
|
-
## API Key Requirements
|
|
157
|
-
|
|
158
|
-
- Must start with `nepher_`
|
|
159
|
-
- Must be active and not expired
|
|
160
|
-
- `hackathon submit` requires **Hackathon** scope (or an unrestricted key)
|
|
161
|
-
- `tournament submit` requires **Tournament** scope (or an unrestricted key)
|
|
162
|
-
|
|
163
|
-
## Troubleshooting
|
|
164
|
-
|
|
165
|
-
| Error | Fix |
|
|
166
|
-
|-------|-----|
|
|
167
|
-
| `npcli-test: command not found` | Ensure `pip install` succeeded and Python scripts dir is on `PATH` |
|
|
168
|
-
| `invalid api key format` | Key must start with `nepher_` |
|
|
169
|
-
| `api key does not have hackathon access` | Enable Hackathon scope or use an unrestricted key |
|
|
170
|
-
| `api key expired` | Run `npcli-test account api-keys create` |
|
|
171
|
-
| `Several hackathons are accepting submissions` | Re-run with `--hackathon-id` |
|
|
172
|
-
| `bittensor-wallet not installed` | `pip install bittensor-wallet` (needed for `tournament submit` and `account register-coldkey`) |
|
|
173
|
-
| `Not logged in` | `npcli-test login --api-key nepher_...` |
|
|
174
|
-
| `Conflict detected: 'scalecodec' ... conflicts with 'cyscale'` | Leftover `scalecodec` after a Bittensor upgrade. Prefer `pip install bittensor-wallet` so npcli-test never needs `btcli`. To repair `btcli` itself: `pip uninstall scalecodec cyscale -y && pip install -U cyscale --force-reinstall` |
|
|
175
|
-
|
|
176
|
-
Run any command with `--help` for full flag details:
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
npcli-test --help
|
|
180
|
-
npcli-test hackathon submit --help
|
|
181
|
-
npcli-test tournament submit --help
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## License
|
|
185
|
-
|
|
186
|
-
MIT
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"""npcli-test — staging entry point (defaults to api.staging.nepher.ai)."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
|
|
7
|
-
# Set staging defaults before any nepher_cli submodule imports config.
|
|
8
|
-
os.environ.setdefault("NEPHER_API_URL", "https://api.staging.nepher.ai")
|
|
9
|
-
os.environ.setdefault("NEPHER_SIMSTORE_API_URL", "https://simstore-staging.nepher.ai")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def main() -> None:
|
|
13
|
-
from nepher_cli.cli import main as cli_main
|
|
14
|
-
|
|
15
|
-
cli_main()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if __name__ == "__main__":
|
|
19
|
-
raise SystemExit(main())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|