codabench-client 0.1.0__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.
- codabench_client-0.1.0/LICENSE +21 -0
- codabench_client-0.1.0/PKG-INFO +258 -0
- codabench_client-0.1.0/README.md +238 -0
- codabench_client-0.1.0/codabench/__init__.py +56 -0
- codabench_client-0.1.0/codabench/__main__.py +8 -0
- codabench_client-0.1.0/codabench/auth.py +133 -0
- codabench_client-0.1.0/codabench/cli.py +428 -0
- codabench_client-0.1.0/codabench/client.py +423 -0
- codabench_client-0.1.0/codabench/competitions.py +200 -0
- codabench_client-0.1.0/codabench/downloads.py +80 -0
- codabench_client-0.1.0/codabench/errors.py +29 -0
- codabench_client-0.1.0/codabench/text.py +59 -0
- codabench_client-0.1.0/codabench_client.egg-info/PKG-INFO +258 -0
- codabench_client-0.1.0/codabench_client.egg-info/SOURCES.txt +18 -0
- codabench_client-0.1.0/codabench_client.egg-info/dependency_links.txt +1 -0
- codabench_client-0.1.0/codabench_client.egg-info/entry_points.txt +2 -0
- codabench_client-0.1.0/codabench_client.egg-info/requires.txt +1 -0
- codabench_client-0.1.0/codabench_client.egg-info/top_level.txt +1 -0
- codabench_client-0.1.0/pyproject.toml +31 -0
- codabench_client-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Abderrahmane Moujar [Scarface]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codabench-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A small, readable Python client and CLI for the Codabench API.
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/amoujar/codabench-client
|
|
7
|
+
Project-URL: Issues, https://github.com/amoujar/codabench-client/issues
|
|
8
|
+
Keywords: codabench,codalab,benchmark,competition,machine-learning
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests>=2.25
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# codabench-client
|
|
22
|
+
|
|
23
|
+
A small, readable Python client and CLI for the [Codabench](https://www.codabench.org/) API.
|
|
24
|
+
|
|
25
|
+
Codabench is a great benchmark platform, but a lot of what you can do in its web UI —
|
|
26
|
+
grabbing a starting kit, submitting a zip, pulling the scoring logs of a failed run —
|
|
27
|
+
is tedious to click through and awkward to automate. This package does all of it from
|
|
28
|
+
the terminal or from Python.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
codabench show 17363 # everything about a competition
|
|
32
|
+
codabench files 16161 # download the starting kit & public data
|
|
33
|
+
codabench submit 17525 -z run.zip --wait # submit and watch the score come back
|
|
34
|
+
codabench outputs 17525 # fetch the prediction & scoring output
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/<you>/api-codabench.git
|
|
43
|
+
cd api-codabench
|
|
44
|
+
pip install -e .
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Python 3.9+ and `requests` are the only requirements. Without installing, everything
|
|
48
|
+
also works as `python -m codabench ...` and `python examples/01_show_competition.py`.
|
|
49
|
+
|
|
50
|
+
## Credentials
|
|
51
|
+
|
|
52
|
+
Copy the template and fill it in:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
cp .env.example .env
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```ini
|
|
59
|
+
CODABENCH_USERNAME=your_username
|
|
60
|
+
CODABENCH_PASSWORD=your_password
|
|
61
|
+
# CODABENCH_URL=https://dev.codabench.org/ # optional; default is www.codabench.org
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`.env` is gitignored. Environment variables win over the file, so CI can just set
|
|
65
|
+
`CODABENCH_USERNAME` / `CODABENCH_PASSWORD`. Reading a **public** competition needs no
|
|
66
|
+
credentials at all.
|
|
67
|
+
|
|
68
|
+
> **Accounts are per-instance.** A `www.codabench.org` login does not work on
|
|
69
|
+
> `dev.codabench.org`, and vice versa.
|
|
70
|
+
|
|
71
|
+
## Commands
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
| Command | What it does |
|
|
75
|
+
| ---------------------------------------------- | ---------------------------------------------------------- |
|
|
76
|
+
| `codabench competitions [--search TEXT]` | List competitions |
|
|
77
|
+
| `codabench show <id|url>` | Pages, phases, tasks, files, leaderboard |
|
|
78
|
+
| `codabench files <id|url>` | List / download the "Files" tab |
|
|
79
|
+
| `codabench submit <id|url> -z FILE` | Upload a submission, optionally wait for the score |
|
|
80
|
+
| `codabench outputs <id|url>` | Download a submission's zip, prediction & scoring output |
|
|
81
|
+
| `codabench rerun --submission ID --task KEY` | Re-run a submission on another task (robot accounts) |
|
|
82
|
+
| `codabench create -b bundle.zip` | Create a competition from a bundle |
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
| Command | What it does |
|
|
86
|
+
| ------------------------------------------------ | ---------------------------------------------------------- |
|
|
87
|
+
| `codabench competitions [--search TEXT]` | List competitions |
|
|
88
|
+
| `codabench show <id|url>` | Pages, phases, tasks, files, leaderboard |
|
|
89
|
+
| `codabench files <id|url>` | List / download the "Files" tab |
|
|
90
|
+
| `codabench submit <id|url> -z FILE` | Upload a submission, optionally wait for the score |
|
|
91
|
+
| `codabench outputs <id|url>` | Download a submission's zip, prediction & scoring output |
|
|
92
|
+
| `codabench rerun --submission ID --task KEY` | Re-run a submission on another task (robot accounts) |
|
|
93
|
+
| `codabench create -b bundle.zip` | Create a competition from a bundle |
|
|
94
|
+
|
|
95
|
+
Every command takes `--url`, `--username`, `--password`, `--env`, and `--help`.
|
|
96
|
+
|
|
97
|
+
### Inspect a competition
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
codabench show 17363 # or the full https://www.codabench.org/competitions/17363/ URL
|
|
101
|
+
codabench show 17363 --pages # full text of every page
|
|
102
|
+
codabench show 17363 --json # raw API payload
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Save the whole thing — description, one markdown file per page, and every file you are
|
|
106
|
+
allowed to download:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
codabench show 17363 --save-dir workdir/17363
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
workdir/17363/
|
|
114
|
+
├── description.md
|
|
115
|
+
├── pages/
|
|
116
|
+
│ ├── 00-overview.md
|
|
117
|
+
│ ├── 01-data.md
|
|
118
|
+
│ └── ...
|
|
119
|
+
└── input/
|
|
120
|
+
└── Track 1 Starting Kit V5/
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Add `--no-download` for the text only.
|
|
124
|
+
|
|
125
|
+
### Download competition files
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
codabench files 16161 --list # see what exists first
|
|
129
|
+
codabench files 16161 # download into files/16161/
|
|
130
|
+
codabench files 16161 --only starting_kit # filter by type or name
|
|
131
|
+
codabench files 16161 --no-extract # keep the zips
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Submit and get scored
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
codabench submit 17525 -z submission.zip --wait
|
|
138
|
+
codabench submit 17525 -z submission.zip --wait \
|
|
139
|
+
--results-json results.json --download-dir outputs
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The phase is resolved automatically (the only one, or the currently open one); pass
|
|
143
|
+
`--phase <id>` or `--phase-index <n>` when a competition has several open at once.
|
|
144
|
+
Submitting **consumes your daily quota** — the command checks eligibility first and
|
|
145
|
+
tells you if you are out.
|
|
146
|
+
|
|
147
|
+
### Get a submission's output
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
codabench outputs 17525 --list # your submissions on the phase
|
|
151
|
+
codabench outputs 17525 # newest submission
|
|
152
|
+
codabench outputs 17525 --last 2 # the one before it
|
|
153
|
+
codabench outputs --submission 856524 # a specific id
|
|
154
|
+
codabench outputs 17525 --only scoring # just the scoring step
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Everything lands in `outputs/<submission id>/` with the zips extracted, plus a
|
|
158
|
+
`details.json` holding the scores, logs and exit statuses — which is usually where the
|
|
159
|
+
answer is when a submission fails.
|
|
160
|
+
|
|
161
|
+
## Python API
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from codabench import CodabenchClient, collect_files, find_phase
|
|
165
|
+
|
|
166
|
+
client = CodabenchClient() # reads .env / environment
|
|
167
|
+
|
|
168
|
+
competition = client.competition(17363) # id or URL
|
|
169
|
+
phase = find_phase(competition) # the open phase
|
|
170
|
+
|
|
171
|
+
for entry in collect_files(competition):
|
|
172
|
+
path = client.download_dataset(entry.key, "input/", entry.filename)
|
|
173
|
+
print(entry.name, "->", path or "not authorized")
|
|
174
|
+
|
|
175
|
+
submission = client.submit(phase["id"], "run.zip")
|
|
176
|
+
client.wait_for_submission(submission["id"])
|
|
177
|
+
print(client.results(submission["id"])["metrics"])
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The client raises `CodabenchError` (with `AuthError` and `ApiError` subclasses) and
|
|
181
|
+
never calls `sys.exit`, so it is safe to use inside a notebook or a larger program.
|
|
182
|
+
|
|
183
|
+
## What you can actually download
|
|
184
|
+
|
|
185
|
+
This trips everyone up, so it is worth stating plainly. Codabench decides per file, and
|
|
186
|
+
this tool cannot widen what your account is allowed to see:
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
| File | Who can download it |
|
|
190
|
+
| --------------------------------- | ----------------------------------------------------------------------- |
|
|
191
|
+
| Starting kit, public data | Any approved participant |
|
|
192
|
+
| Ingestion / scoring program | Participants**only if** the organizer set `make_programs_available` |
|
|
193
|
+
| Input data | Participants**only if** the organizer set `make_input_data_available` |
|
|
194
|
+
| Reference data (the answer key) | Organizers only, always |
|
|
195
|
+
| Competition bundle | Organizers only |
|
|
196
|
+
|
|
197
|
+
Files your account may not fetch are skipped, not treated as an error. `codabench show`
|
|
198
|
+
prints the organizer's two flags so you can see why something is missing.
|
|
199
|
+
|
|
200
|
+
## How authentication works
|
|
201
|
+
|
|
202
|
+
Codabench uses **two** mechanisms and you need both — the reason `CodabenchClient` holds
|
|
203
|
+
a token *and* a session:
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
| Endpoint | Auth |
|
|
207
|
+
| ----------------------------- | ------------------------------------------------------- |
|
|
208
|
+
| `/api/...` | Token from`POST /api/api-token-auth/` |
|
|
209
|
+
| `/datasets/download/<key>/` | Django**session cookie** from `POST /accounts/login/` |
|
|
210
|
+
|
|
211
|
+
The download route behind the "Files" tab is a plain Django view that ignores the API
|
|
212
|
+
token, which is why a token-only client gets 403s on files a participant can plainly
|
|
213
|
+
download in the browser. Both schemes read the same credentials, so callers never have
|
|
214
|
+
to think about it.
|
|
215
|
+
|
|
216
|
+
(There is also `GET /api/competitions/{id}/get_files/`, but it is organizer-only and
|
|
217
|
+
returns 403 for participants — this package does not rely on it.)
|
|
218
|
+
|
|
219
|
+
## Repository layout
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
codabench/ the library
|
|
223
|
+
├── auth.py credentials, token auth, session login
|
|
224
|
+
├── client.py CodabenchClient — every API call
|
|
225
|
+
├── competitions.py pure helpers over a competition payload
|
|
226
|
+
├── downloads.py saving & extracting artifacts
|
|
227
|
+
├── text.py HTML→text, slugs, sizes
|
|
228
|
+
├── errors.py CodabenchError / AuthError / ApiError
|
|
229
|
+
└── cli.py the `codabench` command
|
|
230
|
+
|
|
231
|
+
examples/ the same flows as standalone scripts
|
|
232
|
+
├── 01_show_competition.py
|
|
233
|
+
├── 02_download_competition_files.py
|
|
234
|
+
├── 03_submit_and_wait.py
|
|
235
|
+
├── 04_download_submission_outputs.py
|
|
236
|
+
├── 05_create_competition.py
|
|
237
|
+
└── 06_rerun_submission.py
|
|
238
|
+
|
|
239
|
+
assets/ a sample submission zip and competition bundle
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Run any example directly — no install needed:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
python examples/01_show_competition.py 17363
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Notes
|
|
249
|
+
|
|
250
|
+
* **Organizers**: `codabench create -b bundle.zip` uploads a competition bundle and polls
|
|
251
|
+
until it is unpacked. Try it on `https://dev.codabench.org/` first.
|
|
252
|
+
* **Robot accounts**: `codabench rerun` re-runs an existing submission against another
|
|
253
|
+
task, reusing the uploaded data. It needs an account flagged `is_bot`, or the API
|
|
254
|
+
answers 403.
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
MIT.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# codabench-client
|
|
2
|
+
|
|
3
|
+
A small, readable Python client and CLI for the [Codabench](https://www.codabench.org/) API.
|
|
4
|
+
|
|
5
|
+
Codabench is a great benchmark platform, but a lot of what you can do in its web UI —
|
|
6
|
+
grabbing a starting kit, submitting a zip, pulling the scoring logs of a failed run —
|
|
7
|
+
is tedious to click through and awkward to automate. This package does all of it from
|
|
8
|
+
the terminal or from Python.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
codabench show 17363 # everything about a competition
|
|
12
|
+
codabench files 16161 # download the starting kit & public data
|
|
13
|
+
codabench submit 17525 -z run.zip --wait # submit and watch the score come back
|
|
14
|
+
codabench outputs 17525 # fetch the prediction & scoring output
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git clone https://github.com/<you>/api-codabench.git
|
|
23
|
+
cd api-codabench
|
|
24
|
+
pip install -e .
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Python 3.9+ and `requests` are the only requirements. Without installing, everything
|
|
28
|
+
also works as `python -m codabench ...` and `python examples/01_show_competition.py`.
|
|
29
|
+
|
|
30
|
+
## Credentials
|
|
31
|
+
|
|
32
|
+
Copy the template and fill it in:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
cp .env.example .env
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```ini
|
|
39
|
+
CODABENCH_USERNAME=your_username
|
|
40
|
+
CODABENCH_PASSWORD=your_password
|
|
41
|
+
# CODABENCH_URL=https://dev.codabench.org/ # optional; default is www.codabench.org
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`.env` is gitignored. Environment variables win over the file, so CI can just set
|
|
45
|
+
`CODABENCH_USERNAME` / `CODABENCH_PASSWORD`. Reading a **public** competition needs no
|
|
46
|
+
credentials at all.
|
|
47
|
+
|
|
48
|
+
> **Accounts are per-instance.** A `www.codabench.org` login does not work on
|
|
49
|
+
> `dev.codabench.org`, and vice versa.
|
|
50
|
+
|
|
51
|
+
## Commands
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
| Command | What it does |
|
|
55
|
+
| ---------------------------------------------- | ---------------------------------------------------------- |
|
|
56
|
+
| `codabench competitions [--search TEXT]` | List competitions |
|
|
57
|
+
| `codabench show <id|url>` | Pages, phases, tasks, files, leaderboard |
|
|
58
|
+
| `codabench files <id|url>` | List / download the "Files" tab |
|
|
59
|
+
| `codabench submit <id|url> -z FILE` | Upload a submission, optionally wait for the score |
|
|
60
|
+
| `codabench outputs <id|url>` | Download a submission's zip, prediction & scoring output |
|
|
61
|
+
| `codabench rerun --submission ID --task KEY` | Re-run a submission on another task (robot accounts) |
|
|
62
|
+
| `codabench create -b bundle.zip` | Create a competition from a bundle |
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
| Command | What it does |
|
|
66
|
+
| ------------------------------------------------ | ---------------------------------------------------------- |
|
|
67
|
+
| `codabench competitions [--search TEXT]` | List competitions |
|
|
68
|
+
| `codabench show <id|url>` | Pages, phases, tasks, files, leaderboard |
|
|
69
|
+
| `codabench files <id|url>` | List / download the "Files" tab |
|
|
70
|
+
| `codabench submit <id|url> -z FILE` | Upload a submission, optionally wait for the score |
|
|
71
|
+
| `codabench outputs <id|url>` | Download a submission's zip, prediction & scoring output |
|
|
72
|
+
| `codabench rerun --submission ID --task KEY` | Re-run a submission on another task (robot accounts) |
|
|
73
|
+
| `codabench create -b bundle.zip` | Create a competition from a bundle |
|
|
74
|
+
|
|
75
|
+
Every command takes `--url`, `--username`, `--password`, `--env`, and `--help`.
|
|
76
|
+
|
|
77
|
+
### Inspect a competition
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
codabench show 17363 # or the full https://www.codabench.org/competitions/17363/ URL
|
|
81
|
+
codabench show 17363 --pages # full text of every page
|
|
82
|
+
codabench show 17363 --json # raw API payload
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Save the whole thing — description, one markdown file per page, and every file you are
|
|
86
|
+
allowed to download:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
codabench show 17363 --save-dir workdir/17363
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
workdir/17363/
|
|
94
|
+
├── description.md
|
|
95
|
+
├── pages/
|
|
96
|
+
│ ├── 00-overview.md
|
|
97
|
+
│ ├── 01-data.md
|
|
98
|
+
│ └── ...
|
|
99
|
+
└── input/
|
|
100
|
+
└── Track 1 Starting Kit V5/
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Add `--no-download` for the text only.
|
|
104
|
+
|
|
105
|
+
### Download competition files
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
codabench files 16161 --list # see what exists first
|
|
109
|
+
codabench files 16161 # download into files/16161/
|
|
110
|
+
codabench files 16161 --only starting_kit # filter by type or name
|
|
111
|
+
codabench files 16161 --no-extract # keep the zips
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Submit and get scored
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
codabench submit 17525 -z submission.zip --wait
|
|
118
|
+
codabench submit 17525 -z submission.zip --wait \
|
|
119
|
+
--results-json results.json --download-dir outputs
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The phase is resolved automatically (the only one, or the currently open one); pass
|
|
123
|
+
`--phase <id>` or `--phase-index <n>` when a competition has several open at once.
|
|
124
|
+
Submitting **consumes your daily quota** — the command checks eligibility first and
|
|
125
|
+
tells you if you are out.
|
|
126
|
+
|
|
127
|
+
### Get a submission's output
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
codabench outputs 17525 --list # your submissions on the phase
|
|
131
|
+
codabench outputs 17525 # newest submission
|
|
132
|
+
codabench outputs 17525 --last 2 # the one before it
|
|
133
|
+
codabench outputs --submission 856524 # a specific id
|
|
134
|
+
codabench outputs 17525 --only scoring # just the scoring step
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Everything lands in `outputs/<submission id>/` with the zips extracted, plus a
|
|
138
|
+
`details.json` holding the scores, logs and exit statuses — which is usually where the
|
|
139
|
+
answer is when a submission fails.
|
|
140
|
+
|
|
141
|
+
## Python API
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from codabench import CodabenchClient, collect_files, find_phase
|
|
145
|
+
|
|
146
|
+
client = CodabenchClient() # reads .env / environment
|
|
147
|
+
|
|
148
|
+
competition = client.competition(17363) # id or URL
|
|
149
|
+
phase = find_phase(competition) # the open phase
|
|
150
|
+
|
|
151
|
+
for entry in collect_files(competition):
|
|
152
|
+
path = client.download_dataset(entry.key, "input/", entry.filename)
|
|
153
|
+
print(entry.name, "->", path or "not authorized")
|
|
154
|
+
|
|
155
|
+
submission = client.submit(phase["id"], "run.zip")
|
|
156
|
+
client.wait_for_submission(submission["id"])
|
|
157
|
+
print(client.results(submission["id"])["metrics"])
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The client raises `CodabenchError` (with `AuthError` and `ApiError` subclasses) and
|
|
161
|
+
never calls `sys.exit`, so it is safe to use inside a notebook or a larger program.
|
|
162
|
+
|
|
163
|
+
## What you can actually download
|
|
164
|
+
|
|
165
|
+
This trips everyone up, so it is worth stating plainly. Codabench decides per file, and
|
|
166
|
+
this tool cannot widen what your account is allowed to see:
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
| File | Who can download it |
|
|
170
|
+
| --------------------------------- | ----------------------------------------------------------------------- |
|
|
171
|
+
| Starting kit, public data | Any approved participant |
|
|
172
|
+
| Ingestion / scoring program | Participants**only if** the organizer set `make_programs_available` |
|
|
173
|
+
| Input data | Participants**only if** the organizer set `make_input_data_available` |
|
|
174
|
+
| Reference data (the answer key) | Organizers only, always |
|
|
175
|
+
| Competition bundle | Organizers only |
|
|
176
|
+
|
|
177
|
+
Files your account may not fetch are skipped, not treated as an error. `codabench show`
|
|
178
|
+
prints the organizer's two flags so you can see why something is missing.
|
|
179
|
+
|
|
180
|
+
## How authentication works
|
|
181
|
+
|
|
182
|
+
Codabench uses **two** mechanisms and you need both — the reason `CodabenchClient` holds
|
|
183
|
+
a token *and* a session:
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
| Endpoint | Auth |
|
|
187
|
+
| ----------------------------- | ------------------------------------------------------- |
|
|
188
|
+
| `/api/...` | Token from`POST /api/api-token-auth/` |
|
|
189
|
+
| `/datasets/download/<key>/` | Django**session cookie** from `POST /accounts/login/` |
|
|
190
|
+
|
|
191
|
+
The download route behind the "Files" tab is a plain Django view that ignores the API
|
|
192
|
+
token, which is why a token-only client gets 403s on files a participant can plainly
|
|
193
|
+
download in the browser. Both schemes read the same credentials, so callers never have
|
|
194
|
+
to think about it.
|
|
195
|
+
|
|
196
|
+
(There is also `GET /api/competitions/{id}/get_files/`, but it is organizer-only and
|
|
197
|
+
returns 403 for participants — this package does not rely on it.)
|
|
198
|
+
|
|
199
|
+
## Repository layout
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
codabench/ the library
|
|
203
|
+
├── auth.py credentials, token auth, session login
|
|
204
|
+
├── client.py CodabenchClient — every API call
|
|
205
|
+
├── competitions.py pure helpers over a competition payload
|
|
206
|
+
├── downloads.py saving & extracting artifacts
|
|
207
|
+
├── text.py HTML→text, slugs, sizes
|
|
208
|
+
├── errors.py CodabenchError / AuthError / ApiError
|
|
209
|
+
└── cli.py the `codabench` command
|
|
210
|
+
|
|
211
|
+
examples/ the same flows as standalone scripts
|
|
212
|
+
├── 01_show_competition.py
|
|
213
|
+
├── 02_download_competition_files.py
|
|
214
|
+
├── 03_submit_and_wait.py
|
|
215
|
+
├── 04_download_submission_outputs.py
|
|
216
|
+
├── 05_create_competition.py
|
|
217
|
+
└── 06_rerun_submission.py
|
|
218
|
+
|
|
219
|
+
assets/ a sample submission zip and competition bundle
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Run any example directly — no install needed:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
python examples/01_show_competition.py 17363
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Notes
|
|
229
|
+
|
|
230
|
+
* **Organizers**: `codabench create -b bundle.zip` uploads a competition bundle and polls
|
|
231
|
+
until it is unpacked. Try it on `https://dev.codabench.org/` first.
|
|
232
|
+
* **Robot accounts**: `codabench rerun` re-runs an existing submission against another
|
|
233
|
+
task, reusing the uploaded data. It needs an account flagged `is_bot`, or the API
|
|
234
|
+
answers 403.
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""A small, readable Python client for the `Codabench <https://www.codabench.org/>`_ API.
|
|
2
|
+
|
|
3
|
+
Typical use::
|
|
4
|
+
|
|
5
|
+
from codabench import CodabenchClient
|
|
6
|
+
|
|
7
|
+
client = CodabenchClient() # reads .env / environment
|
|
8
|
+
competition = client.competition(17363) # URL or id both work
|
|
9
|
+
for f in collect_files(competition):
|
|
10
|
+
client.download_dataset(f.key, "input/", f.filename)
|
|
11
|
+
|
|
12
|
+
Every command in the ``codabench`` CLI is a thin wrapper over these methods —
|
|
13
|
+
see ``examples/`` for the same flows written as standalone scripts.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from .auth import Credentials, DEFAULT_URL, load_dotenv
|
|
19
|
+
from .client import ARTIFACTS, CodabenchClient, TERMINAL_STATES, default_env_path
|
|
20
|
+
from .competitions import (
|
|
21
|
+
CompetitionFile,
|
|
22
|
+
collect_files,
|
|
23
|
+
description_markdown,
|
|
24
|
+
find_phase,
|
|
25
|
+
pages,
|
|
26
|
+
parse_competition_id,
|
|
27
|
+
phases,
|
|
28
|
+
primary_metric,
|
|
29
|
+
save_description,
|
|
30
|
+
)
|
|
31
|
+
from .errors import ApiError, AuthError, CodabenchError
|
|
32
|
+
|
|
33
|
+
__version__ = "0.1.0"
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
"ARTIFACTS",
|
|
37
|
+
"ApiError",
|
|
38
|
+
"AuthError",
|
|
39
|
+
"CodabenchClient",
|
|
40
|
+
"CodabenchError",
|
|
41
|
+
"CompetitionFile",
|
|
42
|
+
"Credentials",
|
|
43
|
+
"DEFAULT_URL",
|
|
44
|
+
"TERMINAL_STATES",
|
|
45
|
+
"__version__",
|
|
46
|
+
"collect_files",
|
|
47
|
+
"default_env_path",
|
|
48
|
+
"description_markdown",
|
|
49
|
+
"find_phase",
|
|
50
|
+
"load_dotenv",
|
|
51
|
+
"pages",
|
|
52
|
+
"parse_competition_id",
|
|
53
|
+
"phases",
|
|
54
|
+
"primary_metric",
|
|
55
|
+
"save_description",
|
|
56
|
+
]
|