cli¶
The deeperfly terminal interface, thin by design (ADR-0019).
Six commands (ADR-0084, ADR-0151): gui (gui) opens a project
or a collection in the browser, train (train) trains a
detector on projects, run (run) applies a run config to
projects, models (models) lists, downloads and removes the
released detectors, cache (cache) reports and clears what
deeperfly keeps, each through subcommands (ADR-0154), and doctor
(doctor) reports the installation. The commands follow the
conventions deeperfly shares with octacam and spintrack (CONTRIBUTING.md):
-c/--config, --set KEY=VALUE, -o/--out, --force, -v/--verbose. Suggestions
and swapping two animals of a run are GUI actions. Typer is imported only here, when
the command runs.
deeperfly run PATH... -c config.toml: a run config applied to projects.
Every run serves a live view (ADR-0126) that stays idle until its printed URL is
opened; --live has it watch from the first batch and opens it, --no-live serves
none.
Swapping two animals of a run is the GUI's Runs panel (ADR-0084), over swap_animals.
run ¶
run(
paths: Annotated[
list[Path],
Argument(
help="Projects: each a project folder, a directory holding a deeperfly/ project, or a directory of video files, which gets the default project deeperfly/ on its first run.",
show_default=False,
),
],
config: Annotated[
Path,
Option(
--config,
-c,
help="The run config, a TOML file (see `docs/config-schema.md`).",
),
],
sets: Sets = None,
only: Annotated[
list[str] | None,
Option(--only, help="Run just these stages."),
] = None,
skip: Annotated[
list[str] | None,
Option(--skip, help="Leave these stages out."),
] = None,
out: Annotated[
Path | None,
Option(
--out,
-o,
help="Output root: `<out>/<project>/<name>.h5` (default: `<project>/results/<name>.h5`).",
),
] = None,
force: Annotated[
bool,
Option(
--force,
help="Recompute every frame asked for, let another config take over a run of this name, and replace a results file written for other video.",
),
] = False,
dry_run: Annotated[
bool,
Option(
--dry - run,
help="Validate and print the plan; run nothing, create no project.",
),
] = False,
device: Annotated[
str | None,
Option(help="Override `[compute] device`."),
] = None,
name: Annotated[
str | None,
Option(
--name,
help="The run's name (default: the config's, else the time).",
),
] = None,
frames: Annotated[
str | None,
Option(
--frames,
help="Frames to cover, comma-separated slices and indices, e.g. 0:1000:2,5000,6000::10 (default: the config's, else every frame).",
),
] = None,
batch: Annotated[
int | None,
Option(
--batch,
min=1,
metavar="<int>",
help="Override `[compute] batch`: frames per pass.",
),
] = None,
precision: Annotated[
str | None,
Option(
--precision,
help="Override `[compute] precision`: auto, float32, float16, bfloat16.",
),
] = None,
compile: Annotated[
bool | None,
Option(
--compile / --no - compile,
help="Override `[compute] compile`: torch.compile the pose net.",
),
] = None,
accumulate: Annotated[
str | None,
Option(
--accumulate,
help="Override `[compute] accumulate`: float32, or float16 with `--precision float16`.",
),
] = None,
live: Annotated[
bool,
Option(
--live,
help="Watch from the first batch and open the live view now; without it the view is idle until its printed URL is opened.",
),
] = False,
no_live: Annotated[
bool,
Option(--no - live, help="Serve no live view."),
] = False,
port: Annotated[
int | None,
Option(
--port,
min=1,
max=65535,
metavar="<int>",
help="Port of the live view (default: 8100, or the next free one).",
show_default=False,
),
] = None,
verbose: Verbose = False,
) -> None
Apply a run config to each project, stage by stage, over a frame set.
Each path is resolved to a project: a project folder as it is, else its
deeperfly/, else, for a directory of video files, the default project
deeperfly/ is created in it (one view per video file, fly38, one animal).
A run is <project>/results/<name>.h5 with its config copied to <name>.toml
beside it, and its videos under <project>/renders/<name>/. The name is the
config's name, else the time of the invocation. A run of that name with the
same config is continued: only the frames it does not cover are computed. Another
config under the name is refused unless --force, which also recomputes every
frame asked for and replaces a results file written for other video.
--set keys count as part of the config, and the copy beside the results has
them written in; [compute] keys, like --device, do not. --name and
--frames stand in for the config's name and frames, which may differ between
invocations of one run. --dry-run checks every project and prints the coverage
plan. A failed project is reported, the rest continue, and the command exits
non-zero.
The live view's URL is printed first: opening it shows the detections as they are made, the stages and the log, and can stop the run as Ctrl-C would, which exits 130.
Source code in src/deeperfly/cli/run.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | |
deeperfly train: a detector trained from a TOML config, over projects.
train ¶
train(
config: Annotated[
Path,
Option(
--config,
-c,
help="The training config, a TOML file (see `docs/config-schema.md`).",
),
],
paths: Annotated[
list[Path] | None,
Argument(
help="Projects to train on, each a project or a directory of them; they replace the config's `[data] projects`.",
show_default=False,
),
] = None,
sets: Sets = None,
out: Annotated[
Path | None,
Option(
--out,
-o,
help="Output directory (default: `[train] out`, else `<config dir>/<stem>/`).",
),
] = None,
steps: Annotated[
int | None,
Option(
help="Override the config's train steps, for a quick run."
),
] = None,
device: Annotated[
str | None,
Option(
help="Override the config's compute device."
),
] = None,
workers: Annotated[
int | None,
Option(
help="Override the config's compute workers."
),
] = None,
verbose: Verbose = False,
) -> None
Train a 2D detector on projects' labels and score it on held-out projects.
The output directory gets the trained detector, its report, and the config as
trained: --set keys and the projects given here written in. [compute] keys,
like --device, are left out of it.
Source code in src/deeperfly/cli/train.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
deeperfly gui: the browser workspace over a project or a collection.
Setup, calibration, labeling, suggestions, runs and swapping two animals of a run are all done there (ADR-0084).
gui ¶
gui(
paths: Annotated[
list[Path] | None,
Argument(
help="Projects to open: each a project folder, a directory holding a deeperfly/ project, or a directory of projects. None opens the launcher; one directory of videos opens the setup form over it.",
show_default=False,
),
] = None,
host: Annotated[
str, Option(help="Interface to bind.")
] = "127.0.0.1",
port: Annotated[
int | None,
Option(
help="Port to serve on. Default: 8000, or the next free port.",
show_default=False,
),
] = None,
no_browser: Annotated[
bool,
Option(
--no - browser, help="Do not open a browser."
),
] = False,
stop: Annotated[
bool,
Option(
--stop,
help="Stop your running GUI server, and exit.",
),
] = False,
verbose: Verbose = False,
) -> None
Launch the browser GUI: set up projects, calibrate, label.
One project opens straight in its workspace; several, or a directory whose children are projects, open together as a collection. A directory of videos with no project yet opens the setup form over it. The paths are checked here first. A server already running opens them in a new tab instead.
Source code in src/deeperfly/cli/gui.py
deeperfly models: the released detectors, and the copies of them in the cache.
Three subcommands (ADR-0154). list prints the catalog this deeperfly ships with
(released), rig by rig, and whether each model is
downloaded. A run config names a model where it would give a path (ADR-0151) and
downloads it on first use (ADR-0153); download fetches the models named ahead of
that, or all of them with --all, and remove deletes the models named from the
cache. All of the cache at once is deeperfly cache clear's to delete.
download ¶
download(
names: Annotated[
list[str] | None,
Argument(help=NAMES, show_default=False),
] = None,
everything: Annotated[
bool,
Option(
--all, help="Download every released model."
),
] = False,
verbose: Verbose = False,
) -> None
Download the released models named, or all of them with --all.
The first run that names a model downloads it, so this is for fetching ahead of time, as for a machine that will run without a network. A model already in the cache is checked against its SHA-256 and not fetched again.
Source code in src/deeperfly/cli/models.py
list_models ¶
list_models(
as_json: Annotated[
bool,
Option(
--json,
help="Print the list as JSON, for a script.",
),
] = False,
verbose: Verbose = False,
) -> None
List the released detectors and locators, and whether each is downloaded.
A model is named in a run config where a path would go: [pose2d] weights =
["NAME"], and locator = "NAME" for a rig that needs one.
Source code in src/deeperfly/cli/models.py
remove ¶
remove(
names: Annotated[
list[str], Argument(help=NAMES, show_default=False)
],
verbose: Verbose = False,
) -> None
Remove the downloaded models named from the cache.
Removing costs only time: the next run that names a model downloads it again.
A models directory that is a link to a shared copy is left alone.
deeperfly cache clear deletes every model at once, with the rest of the cache.
Source code in src/deeperfly/cli/models.py
deeperfly cache: where deeperfly keeps what it can fetch or make again.
Two subcommands (ADR-0154): info reports the cache directory
(cache_dir) and what each part of it holds, and clear
deletes all of it (ADR-0151). A single model is deeperfly models remove's to delete.
clear ¶
Delete everything in the cache: every model and every kernel.
Clearing costs only time: a model is downloaded again, a kernel compiled again.
A models directory that is a link to a shared copy loses the link only.
deeperfly models remove deletes the models named and leaves the rest.
Source code in src/deeperfly/cli/cache.py
info ¶
info(
as_json: Annotated[
bool,
Option(
--json,
help="Print the report as JSON, for a script.",
),
] = False,
verbose: Verbose = False,
) -> None
Show the cache directory and what it holds.
The cache holds the released models deeperfly downloaded and the kernels the
GUI compiled. $DEEPERFLY_CACHE_DIR moves the directory.
Source code in src/deeperfly/cli/cache.py
deeperfly doctor: report the state of the installation, seam by seam.
Does the numeric core work (JAX in float64, on the CPU, as intended)? Can video be
decoded, and against which linked libav? Which optional extras are installed
(detect, ik, ball), and which accelerator does torch see? Where is the cache,
and which released models does it hold? A missing extra is reported with where to
read how to add it, not as a fault. Every probe reports rather
than raises, so doctor runs to the end on the install that needs diagnosing.
--json prints the same findings for a script, and --check makes warnings fail
too.
Section
dataclass
¶
One probe's verdict: a status word, how bad it is, and the lines under it.
Source code in src/deeperfly/cli/doctor.py
row ¶
doctor ¶
doctor(
as_json: Annotated[
bool,
Option(
--json,
help="Print the report as JSON, for a script.",
),
] = False,
check: Annotated[
bool,
Option(
--check,
help="Exit non-zero on warnings too, not only errors.",
),
] = False,
verbose: Verbose = False,
) -> None
Report the state of the deeperfly installation and its optional pieces.
Exits 1 when a piece is broken (with --check, also when one needs a look), so
it can gate a script.
Source code in src/deeperfly/cli/doctor.py
What the deeperfly commands share: options, error handling, loading configs.
Every command takes -v/--verbose and goes through command, which turns an
unexpected error into one line (a traceback with -v) and Ctrl-C into exit code 130.
A config failure the operator can fix becomes a Typer parameter error naming the
argument.
command ¶
Wrap a command: --verbose logging, and errors as one line.
A usage error stays Typer's (exit 2). Any other error prints error: ... and
exits 1, with its traceback when the command ran with --verbose; Ctrl-C exits
130.
Source code in src/deeperfly/cli/common.py
load_run ¶
Load a run config with --set changes, a config error as a CLI error.
Source code in src/deeperfly/cli/common.py
megabytes ¶
split_sets ¶
The --set items as typed values: the document's keys, and [compute]'s.
[compute] keys are kept apart: like --device, they say how to compute, not
what, so they are applied over the loaded config and left out of what the run
records.