ilulab 0.0.2__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.
- ilulab-0.0.2/.gitignore +52 -0
- ilulab-0.0.2/.pypirc.example +13 -0
- ilulab-0.0.2/DEVELOP.md +68 -0
- ilulab-0.0.2/LICENSE +21 -0
- ilulab-0.0.2/MANIFEST.in +3 -0
- ilulab-0.0.2/Makefile +36 -0
- ilulab-0.0.2/PKG-INFO +107 -0
- ilulab-0.0.2/README.md +81 -0
- ilulab-0.0.2/examples/simple_example.py +71 -0
- ilulab-0.0.2/ilulab/__init__.py +6 -0
- ilulab-0.0.2/ilulab/client.py +362 -0
- ilulab-0.0.2/pyproject.toml +76 -0
- ilulab-0.0.2/tests/test_client.py +204 -0
- ilulab-0.0.2/uv.lock +662 -0
ilulab-0.0.2/.gitignore
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
.mypy_cache/
|
|
4
|
+
.pytest_cache/
|
|
5
|
+
.ruff_cache/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
*.so
|
|
9
|
+
.Python
|
|
10
|
+
build/
|
|
11
|
+
develop-eggs/
|
|
12
|
+
dist/
|
|
13
|
+
downloads/
|
|
14
|
+
eggs/
|
|
15
|
+
.eggs/
|
|
16
|
+
lib64/
|
|
17
|
+
parts/
|
|
18
|
+
sdist/
|
|
19
|
+
var/
|
|
20
|
+
wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
.installed.cfg
|
|
23
|
+
*.egg
|
|
24
|
+
.venv/
|
|
25
|
+
venv/
|
|
26
|
+
ENV/
|
|
27
|
+
env/
|
|
28
|
+
|
|
29
|
+
# Node
|
|
30
|
+
node_modules/
|
|
31
|
+
.next/
|
|
32
|
+
out/
|
|
33
|
+
.env*.local
|
|
34
|
+
|
|
35
|
+
# Database
|
|
36
|
+
*.db
|
|
37
|
+
*.sqlite
|
|
38
|
+
postgres-data/
|
|
39
|
+
|
|
40
|
+
# IDE
|
|
41
|
+
.vscode/
|
|
42
|
+
.idea/
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
*~
|
|
46
|
+
|
|
47
|
+
# OS
|
|
48
|
+
.DS_Store
|
|
49
|
+
Thumbs.db
|
|
50
|
+
|
|
51
|
+
# Logs
|
|
52
|
+
*.log
|
ilulab-0.0.2/DEVELOP.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Development Setup
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
For local development:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync --frozen --extra dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Testing in another project
|
|
12
|
+
|
|
13
|
+
To test the package in another project without publishing to PyPI, you can use `uv add` to install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd ~
|
|
17
|
+
git clone git@github.com:pascal-pfeiffer/ilulab-client.git
|
|
18
|
+
|
|
19
|
+
# From another project directory:
|
|
20
|
+
uv add ~/ilulab-client
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Upload to PyPI
|
|
24
|
+
|
|
25
|
+
#### Create PyPI accounts and API tokens
|
|
26
|
+
|
|
27
|
+
You'll need to create accounts and generate API tokens:
|
|
28
|
+
|
|
29
|
+
- TestPyPI (for testing): <https://test.pypi.org/account/register/>
|
|
30
|
+
- PyPI (production): <https://pypi.org/account/register/>
|
|
31
|
+
|
|
32
|
+
For each, go to Account Settings → API tokens → Add API token. Create tokens scoped to "Entire account" initially (you can scope to specific project after first upload).
|
|
33
|
+
|
|
34
|
+
#### Store tokens securely
|
|
35
|
+
|
|
36
|
+
Create a ~/.pypirc file (NOT in the repo):
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
cp .pypirc.example ~/.pypirc
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
And add your tokens. Then secure it:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
chmod 600 ~/.pypirc
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Test on TestPyPI first
|
|
49
|
+
|
|
50
|
+
Once you have the token, run:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
make publish-test
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then test installation:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install --index-url https://test.pypi.org/simple/ ilulab
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### Upload to real PyPI
|
|
63
|
+
|
|
64
|
+
If TestPyPI works:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
uv run python -m twine upload dist/*
|
|
68
|
+
```
|
ilulab-0.0.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 IluLab contributors
|
|
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.
|
ilulab-0.0.2/MANIFEST.in
ADDED
ilulab-0.0.2/Makefile
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.PHONY: clean
|
|
2
|
+
clean:
|
|
3
|
+
rm -rf dist/ build/ *.egg-info/ .venv/ .mypy_cache/ .pytest_cache/ .ruff_cache/
|
|
4
|
+
find . -type d -name __pycache__ -exec rm -rf {} +
|
|
5
|
+
|
|
6
|
+
.PHONY: build
|
|
7
|
+
build: clean
|
|
8
|
+
uv run --frozen --extra dev python -m build
|
|
9
|
+
|
|
10
|
+
.PHONY: publish-test
|
|
11
|
+
publish-test: build
|
|
12
|
+
uv run --frozen --extra dev python -m twine upload --repository testpypi dist/* --verbose
|
|
13
|
+
|
|
14
|
+
.PHONY: publish
|
|
15
|
+
publish: build
|
|
16
|
+
uv run --frozen --extra dev python -m twine upload dist/*
|
|
17
|
+
|
|
18
|
+
.PHONY: lint
|
|
19
|
+
lint:
|
|
20
|
+
uv run --frozen --extra dev ruff check .
|
|
21
|
+
|
|
22
|
+
.PHONY: format
|
|
23
|
+
format:
|
|
24
|
+
uv run --frozen --extra dev ruff format .
|
|
25
|
+
uv run --frozen --extra dev ruff check --fix .
|
|
26
|
+
|
|
27
|
+
.PHONY: typecheck
|
|
28
|
+
typecheck:
|
|
29
|
+
uv run --frozen --extra dev ty check ilulab
|
|
30
|
+
|
|
31
|
+
.PHONY: check
|
|
32
|
+
check: lint typecheck
|
|
33
|
+
|
|
34
|
+
.PHONY: test
|
|
35
|
+
test:
|
|
36
|
+
uv run --frozen --extra dev pytest tests/
|
ilulab-0.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ilulab
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Lightweight Python client for IluLab
|
|
5
|
+
Author: ilulab contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: experiment-tracking,logging,machine-learning,mlops
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Requires-Dist: httpx>=0.27.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: build>=1.0.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.14.7; extra == 'dev'
|
|
23
|
+
Requires-Dist: twine>=5.0.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: ty>=0.0.1a29; extra == 'dev'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# IluLab Python Client
|
|
28
|
+
|
|
29
|
+
Lightweight Python client for tracking ML experiments with IluLab.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install ilulab
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
Set your API token as an environment variable:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
export ILULAB_TOKEN="your_api_token_here"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
then use the client in your code:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from ilulab import IlulabClient
|
|
49
|
+
|
|
50
|
+
# Initialize client
|
|
51
|
+
client = IlulabClient()
|
|
52
|
+
|
|
53
|
+
# Create a project
|
|
54
|
+
project = client.create_project(
|
|
55
|
+
name="my-ml-project",
|
|
56
|
+
description="Testing ilulab"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Create a run
|
|
60
|
+
run = client.create_run(
|
|
61
|
+
project_id=project["id"],
|
|
62
|
+
name="experiment-1",
|
|
63
|
+
tags=["baseline", "resnet"]
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Log parameters
|
|
67
|
+
run.log_params({
|
|
68
|
+
"batch_size": 32,
|
|
69
|
+
"optimizer": "adam",
|
|
70
|
+
"model": "resnet50"
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
# Log metrics during training
|
|
74
|
+
for epoch in range(10):
|
|
75
|
+
# ... training code ...
|
|
76
|
+
loss = 0.5 - epoch * 0.03 # example
|
|
77
|
+
accuracy = 0.6 + epoch * 0.04 # example
|
|
78
|
+
|
|
79
|
+
run.log_metrics({
|
|
80
|
+
"train_loss": loss,
|
|
81
|
+
"train_accuracy": accuracy
|
|
82
|
+
}, step=epoch)
|
|
83
|
+
|
|
84
|
+
# Mark run as completed
|
|
85
|
+
run.finish()
|
|
86
|
+
|
|
87
|
+
# Clean up
|
|
88
|
+
client.close()
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Using Context Managers
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from ilulab import IlulabClient
|
|
95
|
+
|
|
96
|
+
with IlulabClient() as client:
|
|
97
|
+
project = client.create_project(name="my-project")
|
|
98
|
+
|
|
99
|
+
with client.create_run(project["id"], name="experiment-1") as run:
|
|
100
|
+
run.log_param("learning_rate", 0.001)
|
|
101
|
+
|
|
102
|
+
for step in range(100):
|
|
103
|
+
run.log_metric("loss", 1.0 / (step + 1), step=step)
|
|
104
|
+
|
|
105
|
+
# Automatically marked as completed on exit
|
|
106
|
+
# (or failed if an exception occurs)
|
|
107
|
+
```
|
ilulab-0.0.2/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# IluLab Python Client
|
|
2
|
+
|
|
3
|
+
Lightweight Python client for tracking ML experiments with IluLab.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install ilulab
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
Set your API token as an environment variable:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
export ILULAB_TOKEN="your_api_token_here"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
then use the client in your code:
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from ilulab import IlulabClient
|
|
23
|
+
|
|
24
|
+
# Initialize client
|
|
25
|
+
client = IlulabClient()
|
|
26
|
+
|
|
27
|
+
# Create a project
|
|
28
|
+
project = client.create_project(
|
|
29
|
+
name="my-ml-project",
|
|
30
|
+
description="Testing ilulab"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Create a run
|
|
34
|
+
run = client.create_run(
|
|
35
|
+
project_id=project["id"],
|
|
36
|
+
name="experiment-1",
|
|
37
|
+
tags=["baseline", "resnet"]
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Log parameters
|
|
41
|
+
run.log_params({
|
|
42
|
+
"batch_size": 32,
|
|
43
|
+
"optimizer": "adam",
|
|
44
|
+
"model": "resnet50"
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
# Log metrics during training
|
|
48
|
+
for epoch in range(10):
|
|
49
|
+
# ... training code ...
|
|
50
|
+
loss = 0.5 - epoch * 0.03 # example
|
|
51
|
+
accuracy = 0.6 + epoch * 0.04 # example
|
|
52
|
+
|
|
53
|
+
run.log_metrics({
|
|
54
|
+
"train_loss": loss,
|
|
55
|
+
"train_accuracy": accuracy
|
|
56
|
+
}, step=epoch)
|
|
57
|
+
|
|
58
|
+
# Mark run as completed
|
|
59
|
+
run.finish()
|
|
60
|
+
|
|
61
|
+
# Clean up
|
|
62
|
+
client.close()
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Using Context Managers
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from ilulab import IlulabClient
|
|
69
|
+
|
|
70
|
+
with IlulabClient() as client:
|
|
71
|
+
project = client.create_project(name="my-project")
|
|
72
|
+
|
|
73
|
+
with client.create_run(project["id"], name="experiment-1") as run:
|
|
74
|
+
run.log_param("learning_rate", 0.001)
|
|
75
|
+
|
|
76
|
+
for step in range(100):
|
|
77
|
+
run.log_metric("loss", 1.0 / (step + 1), step=step)
|
|
78
|
+
|
|
79
|
+
# Automatically marked as completed on exit
|
|
80
|
+
# (or failed if an exception occurs)
|
|
81
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Simple example showing how to use ilulab client."""
|
|
2
|
+
|
|
3
|
+
from ilulab import IlulabClient
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
# Initialize client
|
|
8
|
+
client = IlulabClient()
|
|
9
|
+
|
|
10
|
+
# Create a project
|
|
11
|
+
project = client.create_project(name="example-project", description="A simple example project")
|
|
12
|
+
print(f"Created project: {project['name']} ({project['id']})")
|
|
13
|
+
|
|
14
|
+
# Create a run with tags
|
|
15
|
+
run = client.create_run(
|
|
16
|
+
project_id=project["id"],
|
|
17
|
+
name="example-run-1",
|
|
18
|
+
description="Testing the ilulab client",
|
|
19
|
+
tags=["example", "test"],
|
|
20
|
+
)
|
|
21
|
+
print(f"Created run: {run.run_id}")
|
|
22
|
+
|
|
23
|
+
# Log parameters (hyperparameters, config)
|
|
24
|
+
run.log_params(
|
|
25
|
+
{
|
|
26
|
+
"batch_size": 32,
|
|
27
|
+
"optimizer": "adam",
|
|
28
|
+
"model_architecture": "resnet50",
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
print("Logged parameters")
|
|
32
|
+
|
|
33
|
+
# Simulate a training loop
|
|
34
|
+
print("\nSimulating training loop...")
|
|
35
|
+
for epoch in range(10):
|
|
36
|
+
# Simulate metrics
|
|
37
|
+
train_loss = 1.0 / (epoch + 1)
|
|
38
|
+
val_loss = 1.2 / (epoch + 1)
|
|
39
|
+
val_acc = 0.5 + epoch * 0.05
|
|
40
|
+
|
|
41
|
+
# Log metrics for this step
|
|
42
|
+
run.log_metrics(
|
|
43
|
+
{"train_loss": train_loss, "val_loss": val_loss, "val_accuracy": val_acc},
|
|
44
|
+
step=epoch,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
print(
|
|
48
|
+
f"{epoch + 1}/10: train_loss={train_loss:.4f}, "
|
|
49
|
+
"val_loss={val_loss:.4f}, val_accuracy={val_acc:.4f}"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Mark run as completed
|
|
53
|
+
run.finish()
|
|
54
|
+
print("\nRun completed!")
|
|
55
|
+
|
|
56
|
+
# Retrieve run data
|
|
57
|
+
run_data = client.get_run(run.run_id)
|
|
58
|
+
print(
|
|
59
|
+
f"\nRun has {len(run_data['parameters'])} parameters and {len(run_data['metrics'])} metrics"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# List all runs in the project
|
|
63
|
+
runs = client.list_runs(project_id=project["id"])
|
|
64
|
+
print(f"\nTotal runs in project: {len(runs)}")
|
|
65
|
+
|
|
66
|
+
# Clean up
|
|
67
|
+
client.close()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
main()
|