Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
764 commits
Select commit Hold shift + click to select a range
324266b
Update version
VladimirShitov Sep 12, 2025
4711fe8
Fix code style
VladimirShitov Sep 12, 2025
852b8ee
Change catching Exception to more specific errors
VladimirShitov Sep 12, 2025
ee5461a
Merge pull request #110 from lueckenlab/add-spare-metrics
VladimirShitov Sep 12, 2025
ed070a0
Fix getting layer from obsm instead of a general slot
VladimirShitov Oct 20, 2025
7a788f7
Bump up the version
VladimirShitov Oct 20, 2025
7aaba7c
Merge pull request #112 from lueckenlab/Fix/gloscope_py_X
VladimirShitov Oct 20, 2025
55e38f0
Add anndata2ri
VladimirShitov Oct 21, 2025
30a8af6
Update R interface to use converters
VladimirShitov Oct 22, 2025
ac245e5
Set negative distances to 0 in gloscope
VladimirShitov Oct 22, 2025
2ebd4a3
Add more explanations, run all implementations
VladimirShitov Oct 23, 2025
86e7429
Bump up version
VladimirShitov Oct 23, 2025
e4e13f3
Add plots for gloscope reimplementation
VladimirShitov Oct 23, 2025
bf98d66
Add a conclusion
VladimirShitov Oct 23, 2025
1c8113e
Rename the notebook
VladimirShitov Oct 23, 2025
731b39a
Remove the unused tutorial
VladimirShitov Oct 23, 2025
9a77ddc
Pt gloscope tutorial after the basic one, remove unused links
VladimirShitov Oct 23, 2025
df939cd
Describe 0.11.2 updates
VladimirShitov Oct 23, 2025
0da546b
Bump up version
VladimirShitov Oct 23, 2025
7893a40
Merge branch 'main' into gloscope_reimplementation_tutorial
VladimirShitov Oct 23, 2025
d28212b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 23, 2025
8a5a70e
Merge pull request #109 from EmmaSchonner/gloscope_reimplementation_t…
VladimirShitov Oct 23, 2025
ec3a1a7
Remove negative distances from gloscope output
VladimirShitov Nov 5, 2025
3581751
Bump version up
VladimirShitov Nov 5, 2025
360609c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 5, 2025
15b308f
Change order of commands to save sample names correctly
VladimirShitov Nov 5, 2025
0ceb6e7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 5, 2025
32fe7fc
Add a test for removing negative distances
VladimirShitov Nov 5, 2025
05ecbb1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 5, 2025
cecd3fa
Merge pull request #114 from lueckenlab/Fix/negative-distances
VladimirShitov Nov 5, 2025
f5ab4cc
init tests for sample rep methods
farhadmd7 Nov 28, 2025
d464d4c
impl conftest.py
farhadmd7 Nov 28, 2025
05dbfc7
add test and refactors
farhadmd7 Nov 28, 2025
9f91fb9
impl tests for preprocessing basic.py
farhadmd7 Nov 28, 2025
9005152
refactors
farhadmd7 Nov 28, 2025
d0a52f5
small bug fix
farhadmd7 Nov 28, 2025
676ad07
tests for tl/evaluation.py
farhadmd7 Nov 28, 2025
a878093
Support for csr sparse matrices
LArnoldt Dec 11, 2025
6a44fca
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 11, 2025
087a4cb
SETA class
WinterHannah Dec 23, 2025
aa2f3b9
seta implementation
WinterHannah Dec 25, 2025
32b684d
corrected sample order
WinterHannah Dec 26, 2025
ec72757
simplify code
Jan 15, 2026
a06af4a
add tests
Jan 15, 2026
55e3be3
make code more compact
Jan 15, 2026
c67995e
extended CellGroupComposition class
Jan 19, 2026
fbc769b
Remove tests from the wrong place
VladimirShitov Feb 18, 2026
11b6a96
Remove the example test
VladimirShitov Feb 18, 2026
e09e31b
Add pbmc3k fixture
VladimirShitov Feb 18, 2026
2329768
Test every sample representation method
VladimirShitov Feb 18, 2026
c086f5e
Test util functions
VladimirShitov Feb 18, 2026
6645222
Test prediction and moving layer to X
VladimirShitov Feb 18, 2026
96109bd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 19, 2026
4eaf9a4
Remove a duplicated test
VladimirShitov Feb 19, 2026
7e9cf7f
Add a comment on pilot exception
VladimirShitov Feb 19, 2026
ea61835
Move import higher
VladimirShitov Feb 19, 2026
dd5c6b5
Make sure that copy of adata is used in different tests, add rare cel…
VladimirShitov Feb 19, 2026
d64c338
Run pre commit hooks
VladimirShitov Feb 19, 2026
516aa37
Bump up version
VladimirShitov Feb 19, 2026
859faa4
Ignore ruff error
VladimirShitov Feb 19, 2026
6f47b1a
Add pypi and codecov badges
VladimirShitov Feb 19, 2026
e996453
Merge pull request #121 from lueckenlab/features/tests
VladimirShitov Feb 19, 2026
b769262
SupervisedSampleMethod class and MixMIL
LArnoldt Mar 4, 2026
6d4dfc8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 4, 2026
d34400b
Merge branch 'main' into supervised
LArnoldt Mar 4, 2026
0a9631c
PULSAR, Tests
LArnoldt Mar 5, 2026
5186fa3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 5, 2026
8514b56
PULSAR, Tests
LArnoldt Mar 5, 2026
da601c2
PULSAR, Tests
LArnoldt Mar 5, 2026
76516d2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 5, 2026
005ed0b
Restructuring base sample class, diverse fixes to MixMIL and PULSAR
LArnoldt Mar 7, 2026
d0715c0
Differential analysis with condition utils
LArnoldt Mar 7, 2026
79afda5
Fix package version
LArnoldt Mar 7, 2026
70b93ea
Merge branch 'supervised' of https://github.com/LArnoldt/patpy into s…
LArnoldt Mar 7, 2026
7efb295
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 7, 2026
dd6ef39
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 7, 2026
7efb3c6
Removed unnecessary distances argument from BaseSampleMethod.embed()
VladimirShitov Mar 16, 2026
913dff3
Initialize sample_representation in the base class
VladimirShitov Mar 16, 2026
cf4b6aa
Implement sample_representation field support for both supervised met…
VladimirShitov Mar 16, 2026
0b3c59f
Initialize sample_representation in the base class
VladimirShitov Mar 16, 2026
3ff95a8
Removed embed() as it is now identical to the base class method
VladimirShitov Mar 16, 2026
a29117f
Move datasets to src to enable importing
VladimirShitov Mar 16, 2026
7b537d3
Move fit_linear_probe to the base class, add test labels support
VladimirShitov Mar 16, 2026
bcd9632
Add tests for linear probe
VladimirShitov Mar 16, 2026
69e87f6
Fix using extract_metadata
VladimirShitov Mar 16, 2026
8ea1f39
Use set comprehension to calm down pre-commit hooks
VladimirShitov Mar 16, 2026
24cbf71
Move import and change expection to a less broader to calm down pre-c…
VladimirShitov Mar 16, 2026
4998141
Run pre-commit hooks
VladimirShitov Mar 16, 2026
90dd7f3
Run pre-commit hooks
VladimirShitov Mar 16, 2026
e74602c
Rename check_fitted to check_adata_loaded
VladimirShitov Mar 16, 2026
a6bff97
Fix extract_metadata to keep sample key if it is in columns
VladimirShitov Mar 16, 2026
d7a58a0
Add _check_fitted, test it
VladimirShitov Mar 16, 2026
68af7ac
Remove fake classes, test real MultiMIL
VladimirShitov Mar 16, 2026
4dae2ee
Patch pulsar with a smaller model to run the test in reasonable time
VladimirShitov Mar 16, 2026
0609c4a
Update changelog
VladimirShitov Mar 16, 2026
1714572
Merge remote-tracking branch 'origin/main' into feature/helicalAI
VladimirShitov Mar 17, 2026
bddc11c
Bump up version
VladimirShitov Mar 17, 2026
77044d0
Describe changes
VladimirShitov Mar 17, 2026
479ad0a
Make sure X is sparse before running UCE
VladimirShitov Mar 17, 2026
75ccb3a
Add lightweight tests for helical models with mocks
VladimirShitov Mar 17, 2026
1549a75
Test real helical models
VladimirShitov Mar 17, 2026
49f8110
Add environment for helical
VladimirShitov Mar 17, 2026
aa12409
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 17, 2026
6bd11b2
Run pre-commit hooks
VladimirShitov Mar 17, 2026
3e3b04d
Skip helical tests if it's not installed
VladimirShitov Mar 17, 2026
81c544f
Skip pytorch tensor conversion to numpy test if helical is not installed
VladimirShitov Mar 17, 2026
8872f87
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 17, 2026
c437a21
Update pyproject-fmt
VladimirShitov Mar 17, 2026
f985eee
Update pyproject-fmt, reformat the file
VladimirShitov Mar 17, 2026
637fa6f
Merge pull request #108 from lueckenlab/feature/helicalAI
VladimirShitov Mar 17, 2026
e300bcb
impl get_helical_embedding
farhadmd7 Jun 12, 2025
a307a30
fix
farhadmd7 Jun 12, 2025
d80d26f
converrt transcriptformer embedding from torch tensor to numpy array
farhadmd7 Aug 8, 2025
125ab6b
fix geneformer
farhadmd7 Aug 11, 2025
ec99df6
add to imports
farhadmd7 Aug 11, 2025
ebab250
Bump up version
VladimirShitov Mar 17, 2026
c53025f
Describe changes
VladimirShitov Mar 17, 2026
791151e
Make sure X is sparse before running UCE
VladimirShitov Mar 17, 2026
9028f06
Add lightweight tests for helical models with mocks
VladimirShitov Mar 17, 2026
89438a9
Test real helical models
VladimirShitov Mar 17, 2026
ecf8b70
Add environment for helical
VladimirShitov Mar 17, 2026
f8b0df8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 17, 2026
5eb0cfd
Run pre-commit hooks
VladimirShitov Mar 17, 2026
bb7802f
Skip helical tests if it's not installed
VladimirShitov Mar 17, 2026
9b494d9
Skip pytorch tensor conversion to numpy test if helical is not installed
VladimirShitov Mar 17, 2026
1db08b1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 17, 2026
84f6f75
Update pyproject-fmt
VladimirShitov Mar 17, 2026
7fad950
Update pyproject-fmt, reformat the file
VladimirShitov Mar 17, 2026
a0c0db7
Monkey patch pulsar if there is a transformers version mismatch
VladimirShitov Mar 17, 2026
3da2429
Bump up version
VladimirShitov Mar 17, 2026
b40ca23
Remove unnecessary method call, it is now inherited
VladimirShitov Mar 17, 2026
e277484
Simplify _donor_col
VladimirShitov Mar 17, 2026
1bc6731
Add predict and fine_tune methods to the SupervisedSampleMethod
VladimirShitov Mar 18, 2026
e9251cf
Implement fine_tune and predict for MixMIL
VladimirShitov Mar 18, 2026
fac8395
Support labels and tasks as a single string
VladimirShitov Mar 18, 2026
67bf4b1
predict() and fit_linear_probe() now return f"{label}_pred" instead o…
VladimirShitov Mar 18, 2026
10ee48d
Test that mixmil loss doesn't jump after fine-runing
VladimirShitov Mar 18, 2026
8ced721
Make sure fine-tuning doesn't return mixmil to an untrained step
VladimirShitov Mar 18, 2026
13b1f3c
Add sample order tests for unsupervised methods too
VladimirShitov Mar 18, 2026
da2ce5f
Run pre-commit hooks
VladimirShitov Mar 18, 2026
d9c4131
Mention predict and fine_tune
VladimirShitov Mar 18, 2026
3ac1e2a
Merge branch 'main' into supervised_patch
VladimirShitov Mar 18, 2026
69cc632
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 18, 2026
f105ee5
Remove mentions of self.labels to generalise to unsupervised methods
VladimirShitov Mar 18, 2026
be88617
Refactor for better readability
VladimirShitov Mar 18, 2026
3930ae0
Add regression and edge case tests
VladimirShitov Mar 18, 2026
97057e0
Don't set _fitted to True in prepare_anndata
VladimirShitov Mar 18, 2026
07bf0f2
Add tutorial for the supervised methods
VladimirShitov Mar 18, 2026
500d940
Remove check_fitted for unsupervised methods
VladimirShitov Mar 18, 2026
7fe0a4f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 18, 2026
aa03328
Skip tests when no torch, pulsar or mixmil are installed
VladimirShitov Mar 18, 2026
fedd770
Change torch skip to a more specific mixmil skip if it is not installed
VladimirShitov Mar 18, 2026
5c7092d
Merge pull request #124 from lueckenlab/supervised_patch
VladimirShitov Mar 18, 2026
437a896
Updated differential analysis
LArnoldt Mar 18, 2026
5f71124
Merge branch 'differential' of https://github.com/LArnoldt/patpy into…
LArnoldt Mar 18, 2026
2deec58
Updated differential analysis
LArnoldt Mar 18, 2026
240806f
Add PaSCient as a supervised method in patpy.tl
claude Apr 9, 2026
51887ef
Add PaSCient tests and bump version to 0.14.0
claude Apr 9, 2026
45e13ff
Implement gradient-based cell importance using Integrated Gradients
claude Apr 9, 2026
8edc523
Support end-to-end PaSCient training from AnnData
claude Apr 9, 2026
e07608c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 9, 2026
1341410
Align PaSCient defaults with the upstream repo config
claude Apr 9, 2026
6528969
Fix CI: skip test_pascient.py when torch is not installed
claude Apr 9, 2026
ef21f1a
Add clarifying comments for BasicMLP n_hidden_layers=-1 convention
claude Apr 9, 2026
bacf216
Use generic component names in _train docstring
claude Apr 9, 2026
21f6d4e
Use SamplePredictor from pascient instead of custom _Model
claude Apr 9, 2026
531a2bb
Use Lightning Trainer.fit() for PaSCient training
claude Apr 9, 2026
a3562fa
Add integration tests with real pascient components
claude Apr 9, 2026
ce474f1
Point ImportError messages to pip install patpy[pascient]
claude Apr 9, 2026
7a4b1ec
Add lightning and s3fs to pascient optional dependencies
claude Apr 9, 2026
ade5a52
Add PaSCient example notebook and fix integration test
VladimirShitov Apr 9, 2026
d300215
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 9, 2026
6f6a144
Updated differential analysis
LArnoldt Apr 9, 2026
8ea09d3
Address review: update reference, make val_fraction configurable
claude Apr 9, 2026
caf35dc
Update PaSCient notebook: raw counts layer, IG vs cosine comparison
VladimirShitov Apr 9, 2026
21157c9
Improve cell importance visualization and add summary statistics
VladimirShitov Apr 9, 2026
ebc4aaa
Implement native predict() and fine_tune() using SamplePredictor
claude Apr 10, 2026
e28dd47
Extract _subset_or_pad_cells to deduplicate cell subsampling logic
claude Apr 10, 2026
2a2dc41
Fix citation: Liu, De Brouwer et al. 2025 with correct Cell Systems URL
claude Apr 10, 2026
80ba3d5
Remove intermediate closure variables and dead expression.shape[1] lines
claude Apr 10, 2026
85a0996
Set model to train mode before Trainer.fit()
claude Apr 10, 2026
8dbbb74
Simplify tutorial notebook, fix device mismatches and fine-tune for n…
VladimirShitov Apr 10, 2026
884e507
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 10, 2026
12b927b
Remove render_notebook.sbatch from tracking
VladimirShitov Apr 10, 2026
d29af09
Add class-count weighting to CrossEntropyLossViews
claude Apr 10, 2026
df34d89
Render tutorial notebook with class weighting and target=1 importance
VladimirShitov Apr 10, 2026
d658f9c
Merge origin/main into winterhannah-main
VladimirShitov Apr 10, 2026
dad6d73
Update tutorial: 10 epochs, post-finetune UMAP, boxplots, sorted impo…
VladimirShitov Apr 10, 2026
69563ec
Add checking loading adata
VladimirShitov Apr 10, 2026
c80eabd
Remove default values from sample and cell type key
VladimirShitov Apr 10, 2026
fce45c6
Bump up version
VladimirShitov Apr 10, 2026
b6b5543
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 10, 2026
4123f4b
Merge pull request #120 from WinterHannah/main
VladimirShitov Apr 10, 2026
0c0a4e4
Merge main into fix_sparse_csr_matrix
VladimirShitov Apr 12, 2026
24a8472
Apply suggestions from code review
VladimirShitov Apr 12, 2026
7912bf3
Add tests with sparse layers
VladimirShitov Apr 12, 2026
42204a1
Bump up version
VladimirShitov Apr 12, 2026
4e140f1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 12, 2026
90a6961
Merge pull request #117 from LArnoldt/fix_sparse_csr_matrix
VladimirShitov Apr 12, 2026
ea7d91c
Merge branch 'main' into template-update-v2-lueckenlab-patpy-v0.7.0
VladimirShitov Apr 12, 2026
4f39534
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 12, 2026
18a6312
Merge pull request #119 from scverse-bot/template-update-v2-lueckenla…
VladimirShitov Apr 12, 2026
9d3fcf5
Merge pascient example to supervised methods notebook
VladimirShitov Apr 12, 2026
2c64bb9
Bump up version
VladimirShitov Apr 12, 2026
b0bb3c9
Merge branch 'main' into claude/integrate-pascient-patpy-jOfOZ
VladimirShitov Apr 12, 2026
d47afe5
Fixes differential analysis
LArnoldt Apr 14, 2026
64aa6d1
Merge pull request #125 from lueckenlab/claude/integrate-pascient-pat…
VladimirShitov Apr 27, 2026
c9b7939
Merge branch 'main' into differential
VladimirShitov Apr 27, 2026
7822dad
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 27, 2026
25004c0
Fixed broken list
VladimirShitov Apr 27, 2026
71bcf0b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 27, 2026
4299b08
Fixed broken list
VladimirShitov Apr 27, 2026
d20a675
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 27, 2026
84c13da
Center stars and dots in embedding_covariate_heatmap
VladimirShitov Apr 27, 2026
e9ae4e7
Merge pull request #123 from LArnoldt/differential
VladimirShitov Apr 27, 2026
8f0a6af
Remove git dependencies to make it possible to push to pypi, change d…
VladimirShitov Apr 27, 2026
ce28e3a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 27, 2026
d35cb93
Update version to 0.15.2
VladimirShitov Apr 27, 2026
4d10827
Remove the accidentally commited file
VladimirShitov Apr 27, 2026
f1d6dee
Merge pull request #126 from lueckenlab/Fix/pypi
VladimirShitov Apr 27, 2026
e886e6c
Add missing docs dependencies
VladimirShitov Apr 27, 2026
c5c5899
Merge pull request #127 from lueckenlab/Fix/pypi
VladimirShitov Apr 27, 2026
9c55ab6
Ignore warnings on building docs
VladimirShitov Apr 27, 2026
9973e82
Merge pull request #128 from lueckenlab/Fix/pypi
VladimirShitov Apr 27, 2026
ccdd171
Add differential expression example to the docs
VladimirShitov Apr 28, 2026
8043927
Merge pull request #129 from lueckenlab/Fix/pypi
VladimirShitov Apr 28, 2026
593988d
MPC working
grpinto May 4, 2026
af92d01
Use n_neighbors parameter in the knn_prediction_score
VladimirShitov May 4, 2026
692a487
Reverse technical score only if reverse_technical_score is true
VladimirShitov May 4, 2026
6174487
Add agentic skills under src/patpy/skills/
benjaminfreyuu May 4, 2026
7c5b290
Add agentic skills under src/patpy/skills/
benjaminfreyuu May 4, 2026
7a9574e
Add tests for the fixed bugs
VladimirShitov May 4, 2026
02d7f84
Update version to 0.15.3
VladimirShitov May 4, 2026
ef64aa4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 4, 2026
25dc3cd
Merge pull request #140 from lueckenlab/Fix/knn_score
VladimirShitov May 4, 2026
893f848
Add packaging test for bundled skills
benjaminfreyuu May 4, 2026
899fa0d
Add packaging test for bundled skills
benjaminfreyuu May 4, 2026
a05cc52
Merge branch 'lueckenlab:main' into feature/agent-skills
benjaminfreyuu May 4, 2026
1b6e0ad
Merge branch 'lueckenlab:main' into feature/agent-skills
benjaminfreyuu May 4, 2026
2de19be
Merge pull request #2 from grpinto/feature/agent-skills
grpinto May 4, 2026
0f594e7
Add patpy-mcp dataset-discovery MCP server
grpinto May 4, 2026
a2f3b52
added MCP to externally call CellXgGene
grpinto May 5, 2026
0e5c592
Merge pull request #3 from grpinto/grpinto_branch
grpinto May 5, 2026
e0488a2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2026
bec7f06
added an agents file
grpinto May 5, 2026
f59880f
chore(patpy-mcp): cookiecutter alignment, skill fixes, prune scratch …
grpinto May 5, 2026
565401f
Add agentic skills export and MCP server
benjaminfreyuu May 5, 2026
fbbe7f3
Merge remote-tracking branch 'grpinto/main' into feature/agent-skills
benjaminfreyuu May 5, 2026
16fffff
Merge branch 'feature/agent-skills' of https://github.com/grpinto/pat…
benjaminfreyuu May 5, 2026
a82a7ea
Merge pull request #4 from grpinto/feature/agent-skills
grpinto May 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
45 changes: 45 additions & 0 deletions .github/workflows/build-patpy-mcp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Check Build patpy-mcp

# Mirrors biocontext-ai/mcp-server-cookiecutter's `build.yaml`, but builds the
# patpy-mcp subproject under ``mcp/`` instead of the parent patpy package.
# Catches a broken `mcp/pyproject.toml` on PRs instead of at release-tag time.
on:
push:
branches: [main]
paths:
- "mcp/**"
- ".github/workflows/build-patpy-mcp.yaml"
pull_request:
branches: [main]
paths:
- "mcp/**"
- ".github/workflows/build-patpy-mcp.yaml"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

defaults:
run:
shell: bash -euo pipefail {0}

jobs:
package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
filter: blob:none
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: mcp/pyproject.toml

- name: Build patpy-mcp package
working-directory: mcp
run: uv build

- name: Check patpy-mcp distributions
run: uvx twine check --strict mcp/dist/*.whl mcp/dist/*.tar.gz
44 changes: 44 additions & 0 deletions .github/workflows/release-patpy-mcp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Release patpy-mcp

# Triggered by tags of the form `patpy-mcp-v0.1.0`, so the patpy-mcp
# subproject can be released independently of the parent patpy package.
# Mirrors biocontext-ai/mcp-server-cookiecutter's release.yaml, but the
# build step runs inside ``mcp/`` so only the subproject ships to PyPI.
on:
push:
tags:
- "patpy-mcp-v*"

defaults:
run:
shell: bash -euo pipefail {0}

jobs:
release:
name: Upload patpy-mcp release to PyPI
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/patpy-mcp-v')
environment:
name: pypi
url: https://pypi.org/p/patpy-mcp
permissions:
id-token: write
steps:
- uses: actions/checkout@v5
with:
filter: blob:none
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: mcp/pyproject.toml

- name: Build patpy-mcp package
working-directory: mcp
run: uv build

- name: Publish patpy-mcp distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: mcp/dist
66 changes: 66 additions & 0 deletions .github/workflows/test-patpy-mcp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Test patpy-mcp

# Mirrors biocontext-ai/mcp-server-cookiecutter's `test.yaml`, but scoped to the
# patpy-mcp subproject under ``mcp/`` so the parent patpy package and the MCP
# subproject can be tested independently.
on:
push:
branches: [main]
paths:
- "mcp/**"
- ".github/workflows/test-patpy-mcp.yaml"
pull_request:
branches: [main]
paths:
- "mcp/**"
- ".github/workflows/test-patpy-mcp.yaml"
schedule:
- cron: "0 5 1,15 * *"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

defaults:
run:
shell: bash -euo pipefail {0}
working-directory: mcp

jobs:
test:
name: pytest (Python ${{ matrix.python }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: ["3.11", "3.13"]

steps:
- uses: actions/checkout@v5
with:
filter: blob:none
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python }}
cache-dependency-glob: mcp/pyproject.toml

- name: Install patpy-mcp[test]
run: uv pip install --system -e ".[test]"

- name: Run pytest
env:
MPLBACKEND: agg
run: pytest -v --color=yes

check:
name: All patpy-mcp tests pass
if: always()
needs: [test]
runs-on: ubuntu-latest
steps:
- uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ buck-out/

# Compiled files
.venv/
.venv-*/
__pycache__/
.*cache/
.cache-*/

# Distribution / packaging
/dist/
/mcp/dist/

# Tests and coverage
/data/
Expand All @@ -19,3 +22,9 @@ __pycache__/
# docs
/docs/generated/
/docs/_build/

# patpy-mcp scratch outputs (never commit downloaded datasets or run logs)
/outputs/
/outputs_run.log
/.cellxgene-test-target.json
/run_*.py
151 changes: 151 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# AGENTS.md

> Instructions for AI coding agents working on this repository.

Read this file first. It tells you where things live, how to install / test, what conventions matter, and where to find more detailed guidance on specific tasks.

## What this repository is

Two related projects share this monorepo:

1. **`patpy`** — a Python package for **sample-level** (donor / patient) representation learning from single-cell data. Operates on `anndata.AnnData` objects where each row is a single cell and each donor contributes many cells. Source: `src/patpy/`. Released to PyPI as [`patpy`](https://pypi.org/project/patpy/).
2. **`patpy-mcp`** — a standalone Model Context Protocol server that exposes CellxGene Discover dataset search and download as MCP tools. Source: `mcp/`. Released to PyPI **independently** as [`patpy-mcp`](https://pypi.org/project/patpy-mcp/) — it does **not** depend on `patpy`. Built with the [BioContextAI cookiecutter](https://github.com/biocontext-ai/mcp-server-cookiecutter) and registered in the [BioContextAI Registry](https://biocontext.ai/registry).

Both ship from this single repo and can be released independently:

- `patpy` — workflows `.github/workflows/test.yaml`, `build.yaml`, `release.yaml`; release tag `v*`.
- `patpy-mcp` — workflows `.github/workflows/test-patpy-mcp.yaml`, `build-patpy-mcp.yaml`, `release-patpy-mcp.yaml`; release tag `patpy-mcp-v*`. All three only run when `mcp/**` changes (path-filtered).

## Repository layout

```
.
├── src/patpy/ # the patpy library
│ ├── pp/ tl/ pl/ datasets/ # Public API: pp (preprocessing), tl (tools), pl (plots)
│ └── skills/ # SKILL.md files — see "Skills" below
├── mcp/ # the patpy-mcp standalone subproject
│ ├── pyproject.toml # patpy-mcp's own packaging (separate from the parent)
│ ├── meta.yaml # BioContextAI Registry: Schema.org metadata
│ ├── mcp.json # BioContextAI Registry: MCP client config snippet ({ mcpServers: { ... } })
│ ├── Dockerfile # slim deploy image (build context = repo root for shared LICENSE)
│ ├── src/patpy_mcp/ # package code (cookiecutter layout)
│ │ ├── main.py # click CLI entrypoint (run_app)
│ │ ├── mcp.py # module-level FastMCP instance
│ │ ├── cache.py # ~/.cache/patpy-mcp/ layout + sidecars
│ │ ├── sources/cellxgene/ # REST client for CellxGene Discover
│ │ └── tools/_<name>.py # ONE tool per file, decorated with @mcp.tool
│ └── tests/ # patpy-mcp's own test suite
├── tests/ # patpy's test suite (unrelated to mcp/tests/)
├── docs/ # Sphinx docs (incl. docs/mcp.md)
├── pyproject.toml # patpy package config
├── README.md # human-facing
└── AGENTS.md # this file
```

When in doubt: edits to anything under `src/patpy/` belong to the `patpy` package; anything under `mcp/` belongs to `patpy-mcp`. Their dependencies, tests, and release pipelines are intentionally separate.

## Environments and tooling

The repo uses **`uv`** for the patpy-mcp venv and **mamba/conda** for the patpy main env (because patpy has many heavyweight scientific deps).

- The patpy-mcp subproject has its own venv at `.venv-patpy-mcp/`, created with:
```bash
uv venv .venv-patpy-mcp --python 3.12
source .venv-patpy-mcp/bin/activate
uv pip install -e "./mcp[test]"
```
- For the main patpy library, use mamba/conda envs as the user prefers; do **not** install patpy and patpy-mcp into the same env unless you have a reason to.

## Running tests

Two separate suites; run them in their own roots:

```bash
# patpy-mcp
cd mcp && pytest # 20 tests, runs in <5 s, fully offline

# patpy
cd <repo root> && pytest # full patpy suite (needs the patpy env)
```

Always run `pytest` from inside `mcp/` for patpy-mcp work — its `pyproject.toml` sets `pythonpath = "src"` so imports resolve correctly only from there.

## Coding conventions

- **Formatter / linter**: ruff. Both `pyproject.toml` files declare ruff config; respect `line-length = 120`.
- **Public API discipline**: only symbols re-exported from `patpy.__init__`, `patpy.pp`, `patpy.tl`, `patpy.pl`, `patpy.datasets` are public. Anything starting with `_` is private. Do not call private symbols from new code, tests, or skills.
- **Type hints**: required on all new functions; use `from __future__ import annotations` at the top of new modules.
- **Tests for new tools** (in `mcp/`): one tool per file, mock HTTP with the hand-rolled `_FakeSession` pattern in `mcp/tests/test_cellxgene_discover.py` — do not introduce `responses` or `pytest-httpx` dependencies.

## Skills (where to look first when given a task)

`src/patpy/skills/` is an index of **task-specific guidance** the agent should consult before writing code that uses patpy or patpy-mcp. Every subdirectory has a `SKILL.md` whose YAML frontmatter declares `name:` + `description:`; read the description to decide whether to load the body.

**Never guess the patpy API — always consult the relevant skill first.** The model's training-time priors on patpy are weak; the skills capture conventions and gotchas that are not obvious from the source alone.

| Task at hand | Read this skill |
| --- | --- |
| Find / download a public single-cell dataset (CellxGene Discover) | [`src/patpy/skills/cellxgene/SKILL.md`](src/patpy/skills/cellxgene/SKILL.md) |
| QC, filter samples / cell groups, prepare AnnData | [`src/patpy/skills/preprocessing/SKILL.md`](src/patpy/skills/preprocessing/SKILL.md) |
| Build a sample×sample distance matrix from cells | [`src/patpy/skills/sample_representation/SKILL.md`](src/patpy/skills/sample_representation/SKILL.md) |
| Predict donor-level labels from per-cell features | [`src/patpy/skills/supervised_methods/SKILL.md`](src/patpy/skills/supervised_methods/SKILL.md) |
| Score a representation against metadata (kNN, silhouette, distance test, persistence) | [`src/patpy/skills/evaluation/SKILL.md`](src/patpy/skills/evaluation/SKILL.md) |
| Volcano / heatmap plots | [`src/patpy/skills/plotting/SKILL.md`](src/patpy/skills/plotting/SKILL.md) |
| Synthetic data with controlled perturbations | [`src/patpy/skills/datasets/SKILL.md`](src/patpy/skills/datasets/SKILL.md) |

Top-level index with cross-cutting pitfalls and the `pp`/`tl`/`pl` mental model: [`src/patpy/skills/SKILL.md`](src/patpy/skills/SKILL.md).

## MCP server (`patpy-mcp`)

`patpy-mcp` exposes nine tools that any MCP-capable agent can call:

| Tool | Purpose |
| --- | --- |
| `list_sources` / `describe_source` | Discover which data sources are enabled. |
| `cellxgene_search_datasets` | Search CellxGene Discover by disease / tissue / organism / assay. |
| `cellxgene_get_dataset` | Full per-dataset metadata + asset list. |
| `cellxgene_list_collections` / `cellxgene_get_collection` | Collection (publication) browsing. |
| `cellxgene_list_disease_terms` / `cellxgene_list_tissue_terms` | Distinct ontology terms (label + ID). |
| `cellxgene_download_dataset` | Stream a dataset asset to `$PATPY_MCP_CACHE` with SHA-256 + sidecar. |

Run it with `uvx patpy-mcp` or `patpy-mcp` (after `pip install patpy-mcp` or after activating `.venv-patpy-mcp`). Configure clients with:

```json
{ "mcpServers": { "patpy": { "command": "patpy-mcp" } } }
```

Detailed user-facing docs: [`docs/mcp.md`](docs/mcp.md). Subproject README: [`mcp/README.md`](mcp/README.md).

### Adding a new MCP tool

1. Create `mcp/src/patpy_mcp/tools/_<your_tool>.py` with one `@mcp.tool`-decorated function. The function name **becomes** the tool name; no `name=` argument needed.
2. Re-export it from `mcp/src/patpy_mcp/tools/__init__.py` (the side-effect import that `main.py`'s `from .tools import *` relies on).
3. Add a regression test under `mcp/tests/`.
4. Update [`src/patpy/skills/cellxgene/SKILL.md`](src/patpy/skills/cellxgene/SKILL.md) (or write a new skill) so future agents know when to call your tool.

### Hard-won gotchas (do not regress)

- **fastmcp ≥ 2** uses `on_duplicate="error"`, **not** the pre-2.0 `on_duplicate_tools=`. We use `on_duplicate="error"` in `mcp/src/patpy_mcp/mcp.py` so accidental tool-name collisions blow up at import time.
- **CellxGene Curation API has no flat `/datasets/{id}` endpoint.** Per-dataset metadata only lives at `/collections/{cid}/datasets/{dsid}`. `DiscoverClient.get_dataset_raw` resolves the parent collection from the cached `/datasets` list. There is a regression test (`test_get_dataset_uses_nested_collection_endpoint`) — keep it green.
- **`fastmcp.Client(mcp)` is the right way to drive the server in tests** (in-memory transport, no subprocess). See `try_mcp.py` at the repo root for a runnable demo.
- **`asyncio.run(mcp.list_tools())`** is how you introspect registered tools in fastmcp 2.x. There is no synchronous `get_tools()`.
- **The `LICENSE` file is shared.** `mcp/pyproject.toml` references `../LICENSE` from the parent repo; do not duplicate it under `mcp/`.

## When you should NOT modify something

- `src/patpy/skills/SKILL.md`'s frontmatter `description:` — changing it changes how the agent routes; coordinate with the maintainers.
- `mcp/meta.yaml` — this is the BioContextAI Registry submission. Edits propagate to a separate registry repository.
- `.github/workflows/release*.yaml` — releases are triggered by tag prefix (`v*` for patpy, `patpy-mcp-v*` for patpy-mcp); do not change the trigger conditions casually.
- `pyproject.toml` `version = "..."` — the release pipeline drives version bumps; don't hand-edit.

## Pull request expectations

1. Both test suites pass (`pytest` in repo root *and* in `mcp/`).
2. New behaviour comes with tests. Bug fixes come with regression tests.
3. New tools / functions have type hints and docstrings — those docstrings are what the LLM reads when picking the tool.
4. Update the relevant `SKILL.md` if you changed the public API surface or added a new common workflow.
5. Keep `patpy-mcp` self-contained — do **not** add `patpy` as a dependency of `patpy-mcp` unless you're shipping a tool that genuinely needs the patpy library at runtime.

---

If anything in this file is out of date, fix it as part of the PR that made it stale. Future agents will thank you.
Loading