dr-wandb 0.1.0__tar.gz → 0.1.1__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.
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/PKG-INFO +3 -2
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/README.md +2 -1
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/pyproject.toml +1 -1
- dr_wandb-0.1.1/src/dr_wandb/__init__.py +9 -0
- dr_wandb-0.1.1/src/dr_wandb/fetch.py +80 -0
- dr_wandb-0.1.1/tests/test_fetch.py +50 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/uv.lock +1 -1
- dr_wandb-0.1.0/src/dr_wandb/__init__.py +0 -2
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/.claude/settings.local.json +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/.example.env +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/.gitignore +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/.python-version +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/CLAUDE.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/LICENSE +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/CODING_PRINCIPLES.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/README.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/audit_synthesis_pipeline.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/design_philosophy.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/documentation_organizer_guide.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/fresh_eyes_review_guide.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/general_project_extraction_prompt.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/project_consolidation_methodology.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/reporting_guide.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/strategic_collaboration_guide.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/docs/processes/tactical_execution_guide.md +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/cli/__init__.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/cli/download.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/constants.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/downloader.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/history_entry_record.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/py.typed +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/run_record.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/store.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/src/dr_wandb/utils.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/tests/conftest.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/tests/test_cli_contract.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/tests/test_cli_download.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/tests/test_history_entry_record.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/tests/test_query_builders.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/tests/test_run_record.py +0 -0
- {dr_wandb-0.1.0 → dr_wandb-0.1.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dr-wandb
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Interact with wandb from python
|
|
5
5
|
Author-email: Danielle Rothermel <danielle.rothermel@gmail.com>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,6 +17,8 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
|
|
18
18
|
A command-line utility for downloading and archiving Weights & Biases experiment data to local storage formats optimized for offline analysis. Stores to PostgreSQL db + Parquet files, supports incremental updates and selective data retrieval.
|
|
19
19
|
|
|
20
|
+
> For shared context and onboarding steps, see the [Agent Guide](../dr_ref/docs/guides/AGENT_GUIDE_dr_wandb.md).
|
|
21
|
+
|
|
20
22
|
## Installation
|
|
21
23
|
|
|
22
24
|
```bash
|
|
@@ -120,4 +122,3 @@ The tool generates the following files in the output directory:
|
|
|
120
122
|
- **runtime**: Elapsed time since run start
|
|
121
123
|
- **wandb_metadata**: Platform logging metadata (JSONB)
|
|
122
124
|
- **metrics**: All logged metrics and values (JSONB, flattened in Parquet export)
|
|
123
|
-
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A command-line utility for downloading and archiving Weights & Biases experiment data to local storage formats optimized for offline analysis. Stores to PostgreSQL db + Parquet files, supports incremental updates and selective data retrieval.
|
|
4
4
|
|
|
5
|
+
> For shared context and onboarding steps, see the [Agent Guide](../dr_ref/docs/guides/AGENT_GUIDE_dr_wandb.md).
|
|
6
|
+
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
@@ -105,4 +107,3 @@ The tool generates the following files in the output directory:
|
|
|
105
107
|
- **runtime**: Elapsed time since run start
|
|
106
108
|
- **wandb_metadata**: Platform logging metadata (JSONB)
|
|
107
109
|
- **metrics**: All logged metrics and values (JSONB, flattened in Parquet export)
|
|
108
|
-
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Lightweight WandB fetch utilities that avoid database storage."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable, Iterator
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import wandb
|
|
9
|
+
|
|
10
|
+
from dr_wandb.history_entry_record import HistoryEntryRecord
|
|
11
|
+
from dr_wandb.run_record import RunRecord
|
|
12
|
+
from dr_wandb.utils import default_progress_callback
|
|
13
|
+
|
|
14
|
+
ProgressFn = Callable[[int, int, str], None]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _iterate_runs(
|
|
18
|
+
entity: str,
|
|
19
|
+
project: str,
|
|
20
|
+
*,
|
|
21
|
+
runs_per_page: int,
|
|
22
|
+
) -> Iterator[wandb.apis.public.Run]:
|
|
23
|
+
api = wandb.Api()
|
|
24
|
+
yield from api.runs(f"{entity}/{project}", per_page=runs_per_page)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def serialize_run(run: wandb.apis.public.Run) -> dict[str, Any]:
|
|
28
|
+
"""Convert a WandB run into a JSON-friendly dict."""
|
|
29
|
+
|
|
30
|
+
record = RunRecord.from_wandb_run(run)
|
|
31
|
+
return record.to_dict(include="all")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def serialize_history_entry(
|
|
35
|
+
run: wandb.apis.public.Run, history_entry: dict[str, Any]
|
|
36
|
+
) -> dict[str, Any]:
|
|
37
|
+
"""Convert a raw history payload into a structured dict."""
|
|
38
|
+
|
|
39
|
+
record = HistoryEntryRecord.from_wandb_history(history_entry, run.id)
|
|
40
|
+
return {
|
|
41
|
+
"run_id": record.run_id,
|
|
42
|
+
"step": record.step,
|
|
43
|
+
"timestamp": record.timestamp,
|
|
44
|
+
"runtime": record.runtime,
|
|
45
|
+
"wandb_metadata": record.wandb_metadata,
|
|
46
|
+
"metrics": record.metrics,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def fetch_project_runs(
|
|
51
|
+
entity: str,
|
|
52
|
+
project: str,
|
|
53
|
+
*,
|
|
54
|
+
runs_per_page: int = 500,
|
|
55
|
+
include_history: bool = True,
|
|
56
|
+
progress_callback: ProgressFn | None = None,
|
|
57
|
+
) -> tuple[list[dict[str, Any]], list[list[dict[str, Any]]]]:
|
|
58
|
+
"""Download runs (and optional history) without requiring Postgres."""
|
|
59
|
+
|
|
60
|
+
progress = progress_callback or default_progress_callback
|
|
61
|
+
|
|
62
|
+
runs: list[dict[str, Any]] = []
|
|
63
|
+
histories: list[list[dict[str, Any]]] = []
|
|
64
|
+
|
|
65
|
+
run_iter = list(_iterate_runs(entity, project, runs_per_page=runs_per_page))
|
|
66
|
+
total = len(run_iter)
|
|
67
|
+
|
|
68
|
+
for index, run in enumerate(run_iter, start=1):
|
|
69
|
+
runs.append(serialize_run(run))
|
|
70
|
+
if include_history:
|
|
71
|
+
history_payloads = [
|
|
72
|
+
serialize_history_entry(run, entry) for entry in run.scan_history()
|
|
73
|
+
]
|
|
74
|
+
histories.append(history_payloads)
|
|
75
|
+
progress(index, total, run.name)
|
|
76
|
+
|
|
77
|
+
if not include_history:
|
|
78
|
+
histories = []
|
|
79
|
+
|
|
80
|
+
return runs, histories
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
from dr_wandb.fetch import fetch_project_runs
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_fetch_project_runs_with_history(mock_wandb_run, sample_history_entries):
|
|
9
|
+
mock_wandb_run.scan_history.return_value = sample_history_entries
|
|
10
|
+
|
|
11
|
+
with patch("dr_wandb.fetch._iterate_runs", return_value=iter([mock_wandb_run])):
|
|
12
|
+
runs, histories = fetch_project_runs(
|
|
13
|
+
"test_entity",
|
|
14
|
+
"test_project",
|
|
15
|
+
runs_per_page=50,
|
|
16
|
+
include_history=True,
|
|
17
|
+
progress_callback=lambda *args: None,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
assert len(runs) == 1
|
|
21
|
+
run_payload = runs[0]
|
|
22
|
+
assert run_payload["run_id"] == mock_wandb_run.id
|
|
23
|
+
assert run_payload["config"]["learning_rate"] == 0.001
|
|
24
|
+
|
|
25
|
+
assert len(histories) == 1
|
|
26
|
+
history_entries = histories[0]
|
|
27
|
+
assert history_entries[0]["run_id"] == mock_wandb_run.id
|
|
28
|
+
assert history_entries[0]["metrics"]["loss"] == sample_history_entries[0]["loss"]
|
|
29
|
+
assert history_entries[0]["timestamp"].isoformat().startswith("2024-01-")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_fetch_project_runs_without_history(mock_wandb_run):
|
|
33
|
+
progress_calls: list[tuple[int, int, str]] = []
|
|
34
|
+
|
|
35
|
+
def progress(idx: int, total: int, name: str) -> None:
|
|
36
|
+
progress_calls.append((idx, total, name))
|
|
37
|
+
|
|
38
|
+
with patch("dr_wandb.fetch._iterate_runs", return_value=iter([mock_wandb_run])):
|
|
39
|
+
runs, histories = fetch_project_runs(
|
|
40
|
+
"test_entity",
|
|
41
|
+
"test_project",
|
|
42
|
+
include_history=False,
|
|
43
|
+
progress_callback=progress,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
assert len(runs) == 1
|
|
47
|
+
assert runs[0]["run_id"] == mock_wandb_run.id
|
|
48
|
+
assert histories == []
|
|
49
|
+
assert progress_calls == [(1, 1, mock_wandb_run.name)]
|
|
50
|
+
|
|
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
|
|
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
|