Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ authors = [
license = "Apache-2.0"
keywords=["data-science", "data-version-control", "machine-learning", "reproducibility", "collaboration"]
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.11"
dependencies = [
"cp2k-input-tools",
"dvc>=3.60.0",
"ipsuite",
"massband",
"mlipx",
"pandas>=2.2.3",
"pyyaml>=6.0.2",
"tqdm>=4.67.1",
Expand All @@ -22,6 +26,7 @@ dependencies = [

[project.scripts]
zntrack = 'zntrack.cli:app'
zntrack-mcp = 'zntrack.mcp:mcp.run'

[project.urls]
Repository = "https://github.com/zincware/zntrack"
Expand Down Expand Up @@ -57,6 +62,12 @@ examples = [
"rdkit2ase>=0.1.4",
]

[project.optional-dependencies]
mcp = [
"mcp>=1.12.3",
"fastmcp>=2.10.6",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Expand Down Expand Up @@ -121,5 +132,11 @@ markers = [
]
addopts = "-m 'not benchmark'"

[tool.uv.sources]
ipsuite = { path = "../ipsuite", editable = true }
massband = { path = "../massband", editable = true }
mlipx = { path = "../mlipx", editable = true }
cp2k-input-tools = { git = "https://github.com/cp2k/cp2k-input-tools.git" }
Comment on lines +135 to +139

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify UV sources configuration for production readiness.

The UV sources configuration uses local editable paths and git sources, which suggests this is configured for development. Ensure this configuration is appropriate for the intended deployment environment.


🏁 Script executed:

#!/bin/bash
# Description: Check if the local paths in UV sources exist and verify git repository accessibility
# Expected: Local paths should exist in development environment, git repo should be accessible

echo "Checking local paths:"
ls -la ../ipsuite 2>/dev/null && echo "✓ ipsuite path exists" || echo "✗ ipsuite path missing"
ls -la ../massband 2>/dev/null && echo "✓ massband path exists" || echo "✗ massband path missing" 
ls -la ../mlipx 2>/dev/null && echo "✓ mlipx path exists" || echo "✗ mlipx path missing"

echo -e "\nChecking git repository accessibility:"
git ls-remote --heads https://github.com/cp2k/cp2k-input-tools.git >/dev/null 2>&1 && echo "✓ cp2k-input-tools git repo accessible" || echo "✗ cp2k-input-tools git repo not accessible"

Length of output: 523


Update UV sources for production readiness

The relative paths for ipsuite, massband, and mlipx do not exist in the sandbox and will break installs outside your local dev setup, whereas the cp2k-input-tools git source is reachable. Please replace those editable local‐path entries with stable package references (for example, a PyPI version or a git URL pinned to a release tag) or move them into a development-only profile.

• File: pyproject.toml, section [tool.uv.sources]

  • Remove or comment out
    ipsuite = { path = "../ipsuite", editable = true }
    massband = { path = "../massband", editable = true }
    mlipx = { path = "../mlipx", editable = true }
  • Add versioned or tagged references, e.g.:
    ipsuite = { version = ">=1.2.0" }
    massband = { git = "https://github.com/yourorg/massband.git", tag = "v0.4.1" }
    mlipx = { version = "^2.3.0" }
    cp2k-input-tools = { git = "https://github.com/cp2k/cp2k-input-tools.git" }

Ensure this aligns with your release process so that installing from pyproject.toml works in CI, production, and user setups.

🤖 Prompt for AI Agents
In pyproject.toml around lines 134 to 138, the local editable path entries for
ipsuite, massband, and mlipx under [tool.uv.sources] should be replaced with
stable package references to ensure production readiness. Remove or comment out
the lines using local paths and instead specify version constraints or git URLs
pinned to release tags for these packages. This change will make the
installation work reliably in CI, production, and user environments.


[project.entry-points.'zntrack.nodes']
zntrack-examples = 'zntrack.examples:nodes'
5,995 changes: 4,022 additions & 1,973 deletions uv.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion zntrack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import sys

from zntrack import config
from zntrack import config, entrypoints

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add entrypoints to __all__ or remove unused import.

The entrypoints module is imported but not used within this file and not exported in __all__. Since this is a public API module, either add it to __all__ for public export or remove the import if it's not intended to be part of the public API.

Apply this diff to add it to the public API:

 __all__ = [
     "params",
     "deps",
     "outs",
     "plots",
     "metrics",
     "params_path",
     "deps_path",
     "outs_path",
     "plots_path",
     "metrics_path",
     "Node",
     "Project",
     "nwd",
     "from_rev",
     "apply",
     "add",
     "field",
     "FieldTypes",
     "NOT_AVAILABLE",
     "config",
+    "entrypoints",
 ]

Or remove the unused import:

-from zntrack import config, entrypoints
+from zntrack import config
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from zntrack import config, entrypoints
__all__ = [
"params",
"deps",
"outs",
"plots",
"metrics",
"params_path",
"deps_path",
"outs_path",
"plots_path",
"metrics_path",
"Node",
"Project",
"nwd",
"from_rev",
"apply",
"add",
"field",
"FieldTypes",
"NOT_AVAILABLE",
"config",
"entrypoints",
]
Suggested change
from zntrack import config, entrypoints
-from zntrack import config, entrypoints
+from zntrack import config
🧰 Tools
🪛 Ruff (0.12.2)

5-5: zntrack.entrypoints imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

🤖 Prompt for AI Agents
In zntrack/__init__.py at line 5, the module 'entrypoints' is imported but not
used or exported in __all__. To fix this, either add 'entrypoints' to the
__all__ list to make it part of the public API or remove the import statement if
it is not intended for public use.

from zntrack.add import add
from zntrack.apply import apply
from zntrack.config import NOT_AVAILABLE, FieldTypes
Expand Down
42 changes: 42 additions & 0 deletions zntrack/entrypoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Entry points discovery for ZnTrack nodes.

This module provides functionality to discover and load all packages
that have registered entry points under 'zntrack.nodes'.
"""

import importlib
import importlib.metadata
import logging
from collections import defaultdict

log = logging.getLogger(__name__)


def get_registered_nodes(group: str = "zntrack.nodes") -> dict[str, list[str]]:
"""Get all packages that registered into [project.entry-points.'zntrack.nodes']."""
registered_nodes = defaultdict(list)

try:
# Get all entry points for the 'zntrack.nodes' group
entry_points = importlib.metadata.entry_points(group=group)

for entry_point in entry_points:
try:
# Load the function registered at this entry point
nodes_func = entry_point.load()

# Call the function to get the dictionary of module -> node names
nodes_dict = nodes_func()

for module_name, node_names in nodes_dict.items():
module_name = module_name.replace("-", "_") # Normalize module names
registered_nodes[module_name].extend(node_names)

except Exception as e:
log.error(f"Failed to load entry point '{entry_point.name}': {e}")
continue

except Exception as e:
log.error(f"Failed to discover entry points: {e}")

return dict(registered_nodes)
5 changes: 2 additions & 3 deletions zntrack/examples/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
]


def nodes() -> list[Node]:
def nodes() -> dict[str, list[str]]:
"""Return the available nodes, grouped into categories."""

return [globals()[name] for name in __all__]
return {"zntrack.examples": __all__}
16 changes: 16 additions & 0 deletions zntrack/mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""ZnTrack Model Context Provider (MCP) integration.

Example
-------
To connect the ZnTrack MCP server to claude code at the current working directory, run:

```bash
bunx @anthropic-ai/claude-code mcp add zntrack-server -- uv run \
--project "$(pwd)" zntrack-mcp
bunx @anthropic-ai/claude-code
```
"""

from zntrack.mcp.server import mcp

__all__ = ["mcp"]
13 changes: 13 additions & 0 deletions zntrack/mcp/resources/graph_getting_started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```python
import zntrack
from package import Node1, Node2

project = zntrack.Project()

with project:
node1 = Node1(param="value1")
node2 = Node2(input=node1.output)

if __name__ == "__main__":
project.build()
```
18 changes: 18 additions & 0 deletions zntrack/mcp/resources/graph_with_groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
```python
import zntrack
from package import Node1, Node2

project = zntrack.Project()

with zntrack.group("group1"):
node1 = Node1(param="value1")

with zntrack.group("group2"):
node2 = Node2(input=node1.output)

with project.group("group1", "nested"):
node3 = Node1(param="value2")

if __name__ == "__main__":
project.build()
```
25 changes: 25 additions & 0 deletions zntrack/mcp/resources/node_getting_started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
```py
import zntrack
from pathlib import Path

class MyNode(zntrack.Node):
parameter: dict = zntrack.params()
output: Path = zntrack.outs_path(zntrack.nwd / "file.txt")

def run(self) -> None:
self.output.parent.mkdir(parents=True, exist_ok=True)
self.output.write_text(str(self.parameter))
```

Options include
- `zntrack.deps()` for dependencies to other nodes.
- `zntrack.deps_path` for dependencies to files.
- `zntrack.params` for parameters.
- `zntrack.params_path()` for parameter files (yaml / json)
- `zntrack.outs_path()` for output files.
- `zntrack.outs()` for outputs that are not files.
- `zntrack.metrics()` dict output.
- `zntrack.metrics_path()` for metrics files.

Special directory options include
- `zntrack.nwd` for the node working directory.
Loading
Loading