This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
pLannotate is a command-line tool and web server for annotating engineered plasmid sequences. The tool performs multi-method searches using BLAST, DIAMOND, and Infernal to identify features in DNA sequences and generate interactive visualizations.
The main application is organized into focused modules:
plannotate/main.py- CLI entry point using Typer with commands:plannotate batch- Main annotation commandplannotate setupdb- Database setupplannotate makedb- Build a custom BLAST/DIAMOND database (plus descriptions and a ready-to-run YAML) from a FASTA and optional CSVplannotate yaml- Configuration exportplannotate databases- Print the installed database manifestplannotate streamlit- Launch the optional web app (requires theserverextra)
plannotate/annotate.py- Candidate collection and final annotation pipelineplannotate/models.py-Construct,Feature, conversions, and output methodsplannotate/_tools/- BLAST, DIAMOND, and Infernal integrationsplannotate/_concurrency.py- Core allocation and ordered thread-pool executionplannotate/_curation.py- Curated selection-marker, origin copy-number, global feature-suppression, and composite-reference-region lookups (data/data/selection_markers.csv,data/data/ori_copy_number.csv,data/data/feature_suppressions.csv,data/data/composite_reference_regions.csv,data/data/fragment_suppression_regions.csv). Tables are keyed on source accessions, so they are pinned to one database bundle; runpython tools/curation_pins.py checkaftersetupdbto surface drift. Exact SnapGene composite-region validation also requiresblastdbcmdplannotate/_nested.py- Conservative nested-feature policy shared by runtime annotation and the audit/viewer. Pair overrides live indata/data/nested_feature_overrides.csv; source-level embedded-component intervals live indata/data/composite_reference_regions.csv, and manually adjudicated low-specificity fragment intervals live indata/data/fragment_suppression_regions.csvplannotate/_package_data.py- Packaged assets and database configurationplannotate/_database_builder.py- Build custom BLAST/DIAMOND databases from a FASTA (behindplannotate makedb)plannotate/bokeh_plot.py- Plot preparation, geometry, and Bokeh renderingplannotate/streamlit_app.py- Optional Streamlit web front end, built onConstruct
The tool uses multiple annotation databases configured via YAML:
- SnapGene - Curated plasmid features (BLAST nucleotide search)
- Swiss-Prot - Protein sequences (DIAMOND protein search)
- FPbase - Fluorescent proteins (DIAMOND protein search)
- Rfam - RNA families (Infernal covariance model search)
Database locations and search parameters are defined in plannotate/data/data/databases.yml.
validation.validate_file()reads one FASTA or GenBank record.Constructcallsannotate.annotate().annotate.annotate()runs configured sources and finalizes their candidates._filter.filter_and_clean_hits()scores hits and resolves overlaps.Constructexports GenBank, CSV, or optional Bokeh HTML.
# Create conda environment from file
conda env create -f environment.yml
conda activate plannotate
# Install the package and development dependencies
pip install -e '.[test,lint]'
# Download required databases
plannotate setupdb# Fast suite
pytest
# Include external tools and downloaded databases
pytest --run-integration
# GitHub skips the integration job when PLANNOTATE_DATABASE_URL is unavailable;
# run it locally before merging any annotation-output change.
# Static checks
python -m mypy
ruff check .
ruff format --check .# Format code
ruff format .
# Lint code
ruff check .Python comments should be clear and concise, following the project's style guidelines. Use docstrings for module, class, and function documentation. Inline comments should explain complex logic or decisions; explain they "why" rather than the "what" of the code. Start inline comments with a lowercase letter and keep them brief. Use # TODO for tasks that need to be addressed later, and # NOTE for particularly thorny or important points that may not be immediately obvious.
# Basic annotation
plannotate batch -i input/plasmid.fa -o output/ --html
# Annotation with custom database
plannotate batch -i input/plasmid.fa -o output/ --yaml-file custom_db.yaml
# Linear DNA annotation
plannotate batch -i input/linear.fa --linear --csvRuntime annotation uses only the Python standard library for scheduling. Snakemake is
an optional database-build dependency: pip install -e '.[databases]'. The build
workflow lives under plannotate/gather_databases/; it is not part of the runtime
annotation path.
The supported Python entry point for rebuilding the bundle is
plannotate.build_databases(output_directory, cores=...).
The tool can be imported and used programmatically:
from plannotate.annotate import annotate
from plannotate import Construct
# Direct annotation
hits_df = annotate(sequence_string, linear=False)
# Full pipeline with outputs
construct = Construct(seq=sequence, linear=False)
gbk_content = construct.to_genbank()
html_content = construct.to_html()
csv_df = construct.to_csv()- Databases must be downloaded via
plannotate setupdbbefore first use - Custom databases can be configured by modifying the YAML configuration
- External tools required: BLAST+, DIAMOND, and Infernal
- Input: FASTA (.fa, .fasta, .fas, .fna), GenBank (.gbk, .gb, .gbf, .gbff)
- Output: GenBank, HTML (interactive Bokeh plots), CSV
- Annotation permits nested features of different types and applies the curated nested-feature policy introduced in #83
- Large sequences may require significant processing time
- DIAMOND searches are faster than BLAST for protein sequences
- Library modules use standard
logging.getLogger(__name__)loggers. - The CLI configures the
plannotatelogger;--verboseenables debug output.
When writing shell commands in Snakemake rules, follow these strict guidelines:
# Correct format - call Python scripts, never inline code
python3 example.py \
--input {input.seq} \
--output {output.hits} \
--database {params.db_name} \
>& {log}- NEVER use
python3 -cwith inline code in shell directives - All Python code must be in separate scripts in
scripts/directory - Use backslashes (
\) for line continuation - Align parameters vertically with proper indentation
- Place each parameter on its own line for long commands
- Use
>& {log}for log redirection (combines stdout and stderr) - Keep commands readable and well-structured
- All scripts in
scripts/should use properargparsefor command-line arguments - Scripts should have clear error handling and logging
- Each script should have a single, focused purpose
- Use docstrings and follow the project's Python style guidelines
This architecture emphasizes modularity, with each component having a single focused responsibility and clear interfaces between modules.