Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
c593091
Remove linting from main ci workflow
cpaniaguam Jul 31, 2026
b4e44c1
Add linting and formatting workflow
cpaniaguam Jul 31, 2026
b72172c
Fix formatting
cpaniaguam Jul 31, 2026
e9ffbbd
Autofix fixable linting problems
cpaniaguam Jul 31, 2026
08d2324
Use context managers
cpaniaguam Jul 31, 2026
f2d3613
Rewrite as set comprehension
cpaniaguam Jul 31, 2026
5f725f1
Update type in function signature arg to include None
cpaniaguam Jul 31, 2026
fcddb5a
Use enumerate
cpaniaguam Jul 31, 2026
9607277
Remove unused variable
cpaniaguam Jul 31, 2026
faf7f0b
Use get method
cpaniaguam Jul 31, 2026
e1f9c4f
Update torch_mlp
cpaniaguam Jul 31, 2026
283e2fc
Use set comp
cpaniaguam Jul 31, 2026
05dadd2
Simplify serialization step
cpaniaguam Jul 31, 2026
53d9e9d
Delete commeted code
cpaniaguam Jul 31, 2026
51f7a07
Use TypeError instead of ValueError
cpaniaguam Jul 31, 2026
9ee816d
Simplify logic
cpaniaguam Jul 31, 2026
273b6e9
Simplify serialization
cpaniaguam Jul 31, 2026
ba656f0
Remove unused vars
cpaniaguam Jul 31, 2026
2b86808
Use TypeError instead of ValueError
cpaniaguam Jul 31, 2026
ef9ca8e
Improve exception
cpaniaguam Jul 31, 2026
8ffb6eb
Simplify logic
cpaniaguam Jul 31, 2026
2f43ab0
Use TypeError instead of ValueError
cpaniaguam Jul 31, 2026
f1114a2
Add ruff lint exceptions
cpaniaguam Jul 31, 2026
c1a1dca
Sort exported names
cpaniaguam Jul 31, 2026
5bee526
Update torch train
cpaniaguam Jul 31, 2026
41e61c5
Make more readable
cpaniaguam Jul 31, 2026
e19327e
Update serialization
cpaniaguam Jul 31, 2026
6c79703
Format file
cpaniaguam Jul 31, 2026
0cbcaa3
Fix unpacking
cpaniaguam Jul 31, 2026
9f3170b
Fix unpacking
cpaniaguam Jul 31, 2026
80ffaa5
Fix logging message
cpaniaguam Jul 31, 2026
bf00bd4
Deprecate mocking in test
cpaniaguam Jul 31, 2026
41598ef
Update test jax mlp
cpaniaguam Jul 31, 2026
f67a20d
Use tmp_path
cpaniaguam Jul 31, 2026
c7ac744
Organize imports
cpaniaguam Jul 31, 2026
a0157e6
Ignore .vscode dir
cpaniaguam Jul 31, 2026
9301939
Pass python-version to install uv action
cpaniaguam Jul 31, 2026
aff0251
chore(deps): bump actions/setup-python from 6 to 7
dependabot[bot] Aug 1, 2026
5c48560
Merge branch '102-separate-linting-workflow-in-ci' into dependabot/gi…
cpaniaguam Aug 3, 2026
47af75d
Fix linting workflow commands to use 'uv run' instead of 'uvx'
cpaniaguam Aug 3, 2026
bbaa34d
Fix linting
cpaniaguam Aug 4, 2026
b7d0f7d
Remove unnecessary blank line in test_bayesflow_nle_export.py
cpaniaguam Aug 4, 2026
26df33e
Merge pull request #104 from lnccbrown/dependabot/github_actions/acti…
AlexanderFengler Aug 6, 2026
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
27 changes: 27 additions & 0 deletions .github/workflows/linting_formatting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Linting and Formatting

on:
pull_request:

jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.12.0"

- name: Install package
run: uv sync --group dev

- name: Check styling
run: uv run ruff format --check .

- name: Check linting
run: uv run ruff check src/lanfactory
30 changes: 8 additions & 22 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,20 @@ jobs:
with:
persist-credentials: false

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.6.5"
version: "0.12.0"
Comment thread
cpaniaguam marked this conversation as resolved.
python-version: ${{ matrix.python-version }}
# enable-cache: true
# cache-dependency-glob: "pyproject.toml pdm.lock"

- name: Clear all caches
run: |
rm -rf ~/.cache/pip
rm -rf ~/.cache/uv
rm -rf ~/.cache/conda
rm -rf ~/.cache/npm
rm -rf ~/.cache/pip
rm -rf ~/.cache/uv
rm -rf ~/.cache/conda
rm -rf ~/.cache/npm

- name: Install package
run: uv sync --all-groups --reinstall
Expand All @@ -47,12 +43,6 @@ jobs:
- name: Run pytest
run: uv run pytest

- name: Check styling
run: uv run ruff format --check .

- name: Linting
run: uv run ruff check src/lanfactory

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v7
with:
Expand All @@ -67,15 +57,11 @@ jobs:
with:
persist-credentials: false

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.12"

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.6.5"
version: "0.12.0"
python-version: ${{ matrix.python-version }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use a defined Python version for test_notebooks.

test_notebooks does not define a strategy.matrix, so ${{ matrix.python-version }} is undefined. This causes the workflow validation error reported by actionlint and prevents the notebook job from selecting its intended interpreter. Set this to "3.12" or add a matrix to this job.

Proposed fix
-          python-version: ${{ matrix.python-version }}
+          python-version: "3.12"
🧰 Tools
🪛 actionlint (1.7.12)

[error] 64-64: property "python-version" is not defined in object type {}

(expression)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/run_tests.yml at line 64, Update the Python setup step for
the test_notebooks job to use the explicitly defined Python version "3.12"
instead of the undefined matrix.python-version reference; do not add a matrix
unless this job is intended to run across multiple versions.

Source: Linters/SAST tools


- name: Install package (with notebook + backend deps)
run: uv sync --all-groups
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,4 @@ explorations/
__marimo__/

uv.lock
.vscode/
10 changes: 9 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ dev = [
"pytest-timer>=1.0.0",
"pytest-xdist>=3.6.1",
"pytest>=8.3.1",
"ruff>=0.14.4",
"ruff>=0.15.1",
"types-PyYAML",
"mlflow>=3.14.0",
"jaxonnxruntime>=0.3",
Expand Down Expand Up @@ -120,6 +120,14 @@ line-length = 88
src = ["src/lanfactory", "tests"]
exclude = ["notebooks/*", "docs/*", "docs/basic_tutorial/basic_tutorial.ipynb"]

[tool.ruff.lint]
ignore = [
"B008", # Function calls in default arguments (Typer/FastAPI options)
"EXE001", # Shebang present but file is not executable
"EXE002", # Executable file fails to declare a shebang
"BLE001", #
]

# Coverage settings
[tool.coverage.run]
source = ["src"]
Expand Down
7 changes: 2 additions & 5 deletions src/lanfactory/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
__version__ = "0.8.0"

from . import config
from . import trainers
from . import utils
from . import onnx
from . import config, onnx, trainers, utils

__all__ = ["config", "trainers", "utils", "onnx", "network_inspectors"]
__all__ = ["config", "network_inspectors", "onnx", "trainers", "utils"]


def __getattr__(name):
Expand Down
1 change: 0 additions & 1 deletion src/lanfactory/cli/download_hf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from pathlib import Path

import typer

from lanfactory.hf import DEFAULT_REPO_ID, VALID_NETWORK_TYPES

app = typer.Typer()
Expand Down
17 changes: 7 additions & 10 deletions src/lanfactory/cli/jax_train.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,10 @@ def main(

if mlflow_tracking_enabled:
try:
import mlflow
import os

import mlflow

# Set tracking URI with priority: CLI arg > env var > default
if mlflow_tracking_uri:
tracking_uri = mlflow_tracking_uri
Expand Down Expand Up @@ -234,9 +235,10 @@ def main(

if not mlflow_tracking_enabled:
# Need to initialize MLflow just for querying
import mlflow
import os

import mlflow

# Use same logic as above for tracking URI
if mlflow_tracking_uri:
tracking_uri = mlflow_tracking_uri
Expand Down Expand Up @@ -312,7 +314,7 @@ def main(
# Mode 2: Validation - verify MLflow files exist in training_data_folder
if mlflow_lineage_info and training_data_folder:
expected_files = set(mlflow_lineage_info["all_files"])
actual_files = set(f.name for f in valid_file_list)
actual_files = {f.name for f in valid_file_list}

missing_files = expected_files - actual_files
extra_files = actual_files - expected_files
Expand Down Expand Up @@ -463,13 +465,8 @@ def main(
]
)

pickle.dump(
network_config,
open(
networks_path / file_name_suffix,
"wb",
),
)
file_path = networks_path / file_name_suffix
file_path.write_bytes(pickle.dumps(network_config))

# Load network
net = lanfactory.trainers.JaxMLPFactory(
Expand Down
20 changes: 8 additions & 12 deletions src/lanfactory/cli/torch_train.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@
from importlib.resources import as_file, files
from pathlib import Path

import lanfactory
import psutil
import torch
import typer

import lanfactory
from lanfactory.cli.utils import (
_get_train_network_config,
)
Expand Down Expand Up @@ -168,9 +167,10 @@ def main(

if mlflow_tracking_enabled:
try:
import mlflow
import os

import mlflow

# Set tracking URI with priority: CLI arg > env var > default
if mlflow_tracking_uri:
tracking_uri = mlflow_tracking_uri
Expand Down Expand Up @@ -238,9 +238,10 @@ def main(

if not mlflow_tracking_enabled:
# Need to initialize MLflow just for querying
import mlflow
import os

import mlflow

# Use same logic as above for tracking URI
if mlflow_tracking_uri:
tracking_uri = mlflow_tracking_uri
Expand Down Expand Up @@ -316,7 +317,7 @@ def main(
# Mode 2: Validation - verify MLflow files exist in training_data_folder
if mlflow_lineage_info and training_data_folder:
expected_files = set(mlflow_lineage_info["all_files"])
actual_files = set(f.name for f in valid_file_list)
actual_files = {f.name for f in valid_file_list}

missing_files = expected_files - actual_files
extra_files = actual_files - expected_files
Expand Down Expand Up @@ -467,13 +468,8 @@ def main(
]
)

pickle.dump(
network_config,
open(
networks_path / file_name_suffix,
"wb",
),
)
file_path = networks_path / file_name_suffix
file_path.write_bytes(pickle.dumps(network_config))

# Load network
net = lanfactory.trainers.TorchMLP(
Expand Down
1 change: 0 additions & 1 deletion src/lanfactory/cli/upload_hf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from pathlib import Path

import typer

from lanfactory.hf import DEFAULT_REPO_ID, VALID_NETWORK_TYPES

app = typer.Typer()
Expand Down
15 changes: 8 additions & 7 deletions src/lanfactory/cli/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# import argparse
import logging
from pathlib import Path
import pickle
import yaml
import numpy as np
from pathlib import Path

import lanfactory
import numpy as np
import yaml

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -88,9 +89,9 @@ def _make_train_network_configs(
if save_name:
save_folder = Path(save_folder)
save_folder.mkdir(parents=True, exist_ok=True) # pragma: no cover
save_name = save_folder / save_name
pickle.dump(config_dict, open(save_name, "wb"))
print(f"Saved to: {save_name}")
save_path = save_folder / save_name
save_path.write_bytes(pickle.dumps(config_dict))
print(f"Saved to: {save_path}")
else:
print("No save name provided, config not saved to file.")

Expand All @@ -99,7 +100,7 @@ def _make_train_network_configs(

def _get_train_network_config(yaml_config_path: str | Path | None = None, net_index=0):
if yaml_config_path is not None:
basic_config = yaml.safe_load(open(yaml_config_path, "rb"))
basic_config = yaml.safe_load(Path(yaml_config_path).read_bytes())
network_type = basic_config["NETWORK_TYPE"]
else:
raise ValueError("No YAML config path provided")
Expand Down
16 changes: 8 additions & 8 deletions src/lanfactory/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
from .network_configs import (
network_config_mlp,
network_config_choice_prob,
network_config_opn,
network_config_cpn,
train_config_mlp,
network_config_mlp,
network_config_opn,
train_config_choice_prob,
train_config_opn,
train_config_cpn,
train_config_mlp,
train_config_opn,
)

__all__ = [
"network_config_mlp",
"network_config_choice_prob",
"network_config_opn",
"network_config_cpn",
"train_config_mlp",
"network_config_mlp",
"network_config_opn",
"train_config_choice_prob",
"train_config_opn",
"train_config_cpn",
"train_config_mlp",
"train_config_opn",
]
16 changes: 8 additions & 8 deletions src/lanfactory/hf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
DEFAULT_REPO_ID = "franklab/HSSM"
VALID_NETWORK_TYPES = ("lan", "cpn", "opn")

from lanfactory.hf.model_card import ( # noqa: E402
load_model_card_yaml,
generate_readme,
from lanfactory.hf.download import download_model
from lanfactory.hf.model_card import (
ModelCardConfig,
generate_readme,
load_model_card_yaml,
)
from lanfactory.hf.upload import upload_model # noqa: E402
from lanfactory.hf.download import download_model # noqa: E402
from lanfactory.hf.upload import upload_model

__all__ = [
"DEFAULT_REPO_ID",
"VALID_NETWORK_TYPES",
"load_model_card_yaml",
"generate_readme",
"ModelCardConfig",
"upload_model",
"download_model",
"generate_readme",
"load_model_card_yaml",
"upload_model",
]
3 changes: 2 additions & 1 deletion src/lanfactory/hf/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ def _download_model_hf( # pragma: no cover
model_files = [f for f in all_files if f.startswith(path_prefix)]

if not model_files:
top_level_dirs = {f.split("/")[0] for f in all_files if "/" in f}
raise FileNotFoundError(
f"No files found at {repo_id}/{path_prefix}. "
f"Available paths: {set(f.split('/')[0] for f in all_files if '/' in f)}"
f"Available paths: {top_level_dirs}"
)

if include_patterns:
Expand Down
3 changes: 2 additions & 1 deletion src/lanfactory/hf/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ def _upload_to_hf( # pragma: no cover
) -> str:
"""HF-dependent implementation of upload_model."""
try:
from huggingface_hub import HfApi, create_repo as hf_create_repo
from huggingface_hub import HfApi
from huggingface_hub import create_repo as hf_create_repo
except ImportError as exc:
raise ImportError(
"huggingface_hub is required for HuggingFace uploads. "
Expand Down
6 changes: 3 additions & 3 deletions src/lanfactory/network_inspectors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
from .loaders import get_torch_mlp

__all__ = [
"GridSpec",
"ModelSpec",
"PlotConfig",
"get_torch_mlp",
"kde_vs_lan_likelihoods",
"lan_manifold",
"ModelSpec",
"PlotConfig",
"GridSpec",
]
Loading