Biotope Config
Biotope is in draft stage. Functionality may be missing or incomplete.
The API is subject to change.
Overview
The biotope config command manages project configuration and metadata settings. It provides tools for setting up validation requirements, managing project metadata, and configuring remote validation services.
Commands
Set project-level metadata that will be used to pre-fill annotation fields.
Usage:
biotope config set-project-metadata
Interactive Prompts:
- Description: Brief description of the project and its purpose
- URL: Project homepage, repository, or documentation URL
- Creator Name: Name of the project maintainer
- Creator Email: Email address of the project maintainer
- License: Data usage license (e.g., MIT, CC-BY, etc.)
- Citation: How to cite the project or dataset
Example:
$ biotope config set-project-metadata
Project description: A comprehensive dataset for protein structure analysis
Project URL: https://github.com/example/protein-data
Creator name: Dr. Jane Smith
Creator email: jane.smith@university.edu
License: MIT
Citation: Smith, J. et al. (2024). Protein Structure Dataset. Nature Data.
Display the current project-level metadata configuration.
Usage:
biotope config show-project-metadata
Output:
Project Metadata Configuration:
Description: A comprehensive dataset for protein structure analysis
URL: https://github.com/example/protein-data
Creator: Dr. Jane Smith (jane.smith@university.edu)
License: MIT
Citation: Smith, J. et al. (2024). Protein Structure Dataset. Nature Data.
Validation Configuration
biotope config show-validation
Show current validation configuration and requirements.
biotope config set-validation
Set validation requirements for specific fields.
biotope config remove-validation
Remove validation requirements for specific fields.
biotope config toggle-validation
Enable or disable validation checking.
Remote Validation Configuration
biotope config set-remote-validation
Configure remote validation service for cluster-wide policies.
biotope config show-remote-validation
Show remote validation configuration status.
biotope config remove-remote-validation
Remove remote validation configuration.
biotope config clear-validation-cache
Clear cached remote validation configuration.
Configuration File Structure
Project metadata is stored in .biotope/config/biotope.yaml:
project_name: "my-project"
git_integration: true
project_metadata:
description: "Project description"
url: "https://example.com/project"
creator:
name: "John Doe"
email: "john@example.com"
license: "MIT"
citation: "Doe, J. (2024). Project Title. Journal Name."
annotation_validation:
enabled: true
fields:
license:
type: "string"
required: true
min_length: 3
remote_config:
url: "https://cluster.example.com/validation.yaml"
cache_duration: 3600
fallback: true
Use Cases
- During Initialization: Set project metadata during
biotope init
- After Initialization: Use
biotope config set-project-metadata to add or update metadata
- Team Projects: Ensure all team members use consistent project metadata
Annotation Workflow Integration
Project metadata automatically pre-fills annotation forms:
# Set project metadata once
biotope config set-project-metadata
# Use in annotation (metadata will be pre-filled)
biotope annotate edit --staged
Validation Configuration
Configure validation requirements for your project:
# Set required fields
biotope config set-validation --field license --type string --required
# Enable validation
biotope config toggle-validation --enabled
# Check configuration
biotope config show-validation
Best Practices
- Set Project Metadata Early: Configure project metadata during initialization or early in the project lifecycle
- Use Consistent Metadata: Ensure all team members use the same project metadata for consistency
- Regular Updates: Update project metadata when project details change
- Validation Requirements: Set appropriate validation requirements for your use case
- Remote Validation: Use remote validation for cluster-wide policy enforcement
Configuration management commands for biotope.
clear_validation_cache()
Clear cached remote validation configurations.
Source code in biotope/biotope/commands/config.py
| @config.command()
def clear_validation_cache() -> None:
"""Clear cached remote validation configurations."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
cache_dir = biotope_root / ".biotope" / "cache" / "validation"
if cache_dir.exists():
import shutil
shutil.rmtree(cache_dir)
console.print("✅ Cleared validation cache")
else:
console.print("ℹ️ No validation cache found")
|
config()
Manage biotope project configuration.
Source code in biotope/biotope/commands/config.py
| @click.group()
def config() -> None:
"""Manage biotope project configuration."""
|
remove_remote_validation()
Remove remote validation configuration.
Source code in biotope/biotope/commands/config.py
| @config.command()
def remove_remote_validation() -> None:
"""Remove remote validation configuration."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
config_path = biotope_root / ".biotope" / "config.yaml"
if not config_path.exists():
click.echo("❌ Biotope configuration not found. Run 'biotope init' first.")
raise click.Abort
# Load current config
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
click.echo(f"❌ Error reading configuration: {e}")
raise click.Abort
# Remove remote configuration
if "annotation_validation" in config and "remote_config" in config["annotation_validation"]:
del config["annotation_validation"]["remote_config"]
console.print("✅ Removed remote validation configuration")
else:
console.print("⚠️ No remote validation configuration found")
# Save updated config
try:
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
except yaml.YAMLError as e:
click.echo(f"❌ Error writing configuration: {e}")
raise click.Abort
|
remove_validation(field)
Remove a field from annotation validation requirements.
Source code in biotope/biotope/commands/config.py
| @config.command()
@click.option(
"--field",
"-f",
required=True,
help="Field name to remove from required fields",
)
def remove_validation(field: str) -> None:
"""Remove a field from annotation validation requirements."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
config_path = biotope_root / ".biotope" / "config.yaml"
if not config_path.exists():
click.echo("❌ Biotope configuration not found. Run 'biotope init' first.")
raise click.Abort
# Load current config
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
click.echo(f"❌ Error reading configuration: {e}")
raise click.Abort
# Remove field from required fields
if "annotation_validation" in config:
if field in config["annotation_validation"].get("minimum_required_fields", []):
config["annotation_validation"]["minimum_required_fields"].remove(field)
console.print(f"✅ Removed '{field}' from required fields")
else:
console.print(f"⚠️ Field '{field}' is not in required fields")
# Remove field validation rules
if "field_validation" in config["annotation_validation"]:
if field in config["annotation_validation"]["field_validation"]:
del config["annotation_validation"]["field_validation"][field]
console.print(f"✅ Removed validation rules for '{field}'")
# Save updated config
try:
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
console.print("✅ Configuration updated successfully")
except yaml.YAMLError as e:
click.echo(f"❌ Error writing configuration: {e}")
raise click.Abort
|
Set project-level metadata for pre-filling annotations.
Source code in biotope/biotope/commands/config.py
| @config.command()
def set_project_metadata() -> None:
"""Set project-level metadata for pre-filling annotations."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
config_path = biotope_root / ".biotope" / "config.yaml"
if not config_path.exists():
click.echo("❌ Biotope configuration not found. Run 'biotope init' first.")
raise click.Abort
# Load current config
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
click.echo(f"❌ Error reading configuration: {e}")
raise click.Abort
# Initialize project_metadata if it doesn't exist
if "project_metadata" not in config:
config["project_metadata"] = {}
current_metadata = config["project_metadata"]
console.print("\n[bold blue]Project Metadata Setup[/]")
console.print(
"The following information will be used to pre-fill metadata forms when creating dataset annotations."
)
console.print("You can skip any fields by pressing Enter.")
console.print()
# Project description
project_description = click.prompt(
"Project description (what is this project about?)",
default=current_metadata.get("description", ""),
show_default=True,
)
if project_description:
current_metadata["description"] = project_description
elif "description" in current_metadata:
del current_metadata["description"]
# Project URL
project_url = click.prompt(
"Project URL (if available)",
default=current_metadata.get("url", ""),
show_default=True,
)
if project_url:
current_metadata["url"] = project_url
elif "url" in current_metadata:
del current_metadata["url"]
# Creator/Contact
creator = click.prompt(
"Primary contact person (email preferred)",
default=current_metadata.get("creator", ""),
show_default=True,
)
if creator:
current_metadata["creator"] = creator
elif "creator" in current_metadata:
del current_metadata["creator"]
# License
license_url = click.prompt(
"Default license URL",
default=current_metadata.get("license", "https://creativecommons.org/licenses/by/4.0/"),
show_default=True,
)
if license_url:
current_metadata["license"] = license_url
elif "license" in current_metadata:
del current_metadata["license"]
# Citation template
citation_template = click.prompt(
"Citation template (use {name} and {year} as placeholders)",
default=current_metadata.get("citation", "Please cite this dataset as: {name} ({year})"),
show_default=True,
)
if citation_template:
current_metadata["citation"] = citation_template
elif "citation" in current_metadata:
del current_metadata["citation"]
# Access restrictions
has_access_restrictions = click.confirm(
"Does this project have default access restrictions?",
default=bool(current_metadata.get("access_restrictions")),
)
if has_access_restrictions:
access_restrictions = click.prompt(
"Default access restrictions description",
default=current_metadata.get("access_restrictions", ""),
show_default=True,
)
if access_restrictions:
current_metadata["access_restrictions"] = access_restrictions
elif "access_restrictions" in current_metadata:
del current_metadata["access_restrictions"]
elif "access_restrictions" in current_metadata:
del current_metadata["access_restrictions"]
# Legal obligations
has_legal_obligations = click.confirm(
"Does this project have default legal obligations?",
default=bool(current_metadata.get("legal_obligations")),
)
if has_legal_obligations:
legal_obligations = click.prompt(
"Default legal obligations description",
default=current_metadata.get("legal_obligations", ""),
show_default=True,
)
if legal_obligations:
current_metadata["legal_obligations"] = legal_obligations
elif "legal_obligations" in current_metadata:
del current_metadata["legal_obligations"]
elif "legal_obligations" in current_metadata:
del current_metadata["legal_obligations"]
# Collaboration partner
has_collaboration_partner = click.confirm(
"Does this project have a collaboration partner?",
default=bool(current_metadata.get("collaboration_partner")),
)
if has_collaboration_partner:
collaboration_partner = click.prompt(
"Collaboration partner and institute",
default=current_metadata.get("collaboration_partner", ""),
show_default=True,
)
if collaboration_partner:
current_metadata["collaboration_partner"] = collaboration_partner
elif "collaboration_partner" in current_metadata:
del current_metadata["collaboration_partner"]
elif "collaboration_partner" in current_metadata:
del current_metadata["collaboration_partner"]
# Update config
config["project_metadata"] = current_metadata
# Save updated config
try:
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
if current_metadata:
console.print("\n✅ Project metadata updated successfully")
console.print("💡 This metadata will be used to pre-fill annotation forms")
else:
console.print("\n✅ Project metadata cleared")
console.print("💡 No default values will be used for annotations")
except yaml.YAMLError as e:
click.echo(f"❌ Error writing configuration: {e}")
raise click.Abort
|
set_remote_validation(url, cache_duration, fallback_to_local)
Set remote validation configuration URL.
Source code in biotope/biotope/commands/config.py
| @config.command()
@click.option(
"--url",
"-u",
required=True,
help="URL to remote validation configuration",
)
@click.option(
"--cache-duration",
type=int,
default=3600,
help="Cache duration in seconds (default: 3600)",
)
@click.option(
"--fallback-to-local/--no-fallback",
default=True,
help="Fall back to local config if remote fails (default: true)",
)
def set_remote_validation(url: str, cache_duration: int, fallback_to_local: bool) -> None:
"""Set remote validation configuration URL."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
config_path = biotope_root / ".biotope" / "config.yaml"
if not config_path.exists():
click.echo("❌ Biotope configuration not found. Run 'biotope init' first.")
raise click.Abort
# Load current config
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
click.echo(f"❌ Error reading configuration: {e}")
raise click.Abort
# Initialize annotation_validation if it doesn't exist
if "annotation_validation" not in config:
config["annotation_validation"] = {}
# Set remote configuration
config["annotation_validation"]["remote_config"] = {
"url": url,
"cache_duration": cache_duration,
"fallback_to_local": fallback_to_local,
}
# Save updated config
try:
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
console.print(f"✅ Set remote validation URL: {url}")
console.print(f" Cache duration: {cache_duration} seconds")
console.print(f" Fallback to local: {fallback_to_local}")
# Test the remote configuration
console.print("\n[bold blue]Testing remote configuration...[/]")
try:
from biotope.validation import _load_remote_validation_config
remote_config = _load_remote_validation_config(
config["annotation_validation"]["remote_config"], biotope_root
)
if remote_config:
console.print("✅ Remote configuration loaded successfully")
required_fields = remote_config.get("minimum_required_fields", [])
console.print(f" Required fields: {', '.join(required_fields)}")
else:
console.print("⚠️ Remote configuration not available (using fallback)")
except Exception as e:
console.print(f"❌ Error testing remote configuration: {e}")
except yaml.YAMLError as e:
click.echo(f"❌ Error writing configuration: {e}")
raise click.Abort
|
set_validation(field, type, min_length, required_keys)
Set annotation validation requirements.
Source code in biotope/biotope/commands/config.py
| @config.command()
@click.option(
"--field",
"-f",
help="Field name to add to required fields",
)
@click.option(
"--type",
"-t",
type=click.Choice(["string", "object", "array"]),
help="Data type for the field",
)
@click.option(
"--min-length",
type=int,
help="Minimum length for string/array fields",
)
@click.option(
"--required-keys",
help="Comma-separated list of required keys for object fields",
)
def set_validation(
field: Optional[str], type: Optional[str], min_length: Optional[int], required_keys: Optional[str]
) -> None:
"""Set annotation validation requirements."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
config_path = biotope_root / ".biotope" / "config.yaml"
if not config_path.exists():
click.echo("❌ Biotope configuration not found. Run 'biotope init' first.")
raise click.Abort
# Load current config
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
click.echo(f"❌ Error reading configuration: {e}")
raise click.Abort
# Initialize annotation_validation if it doesn't exist
if "annotation_validation" not in config:
config["annotation_validation"] = {"enabled": True, "minimum_required_fields": [], "field_validation": {}}
# Add field to required fields
if field:
if field not in config["annotation_validation"]["minimum_required_fields"]:
config["annotation_validation"]["minimum_required_fields"].append(field)
console.print(f"✅ Added '{field}' to required fields")
else:
console.print(f"⚠️ Field '{field}' is already required")
# Add field validation rules
if field and type:
field_validation = config["annotation_validation"]["field_validation"]
field_validation[field] = {"type": type}
if min_length is not None:
field_validation[field]["min_length"] = min_length
if required_keys:
keys_list = [key.strip() for key in required_keys.split(",")]
field_validation[field]["required_keys"] = keys_list
console.print(f"✅ Added validation rules for '{field}'")
# Save updated config
try:
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
console.print("✅ Configuration updated successfully")
except yaml.YAMLError as e:
click.echo(f"❌ Error writing configuration: {e}")
raise click.Abort
|
set_validation_pattern(pattern)
Set the validation pattern for this project.
Source code in biotope/biotope/commands/config.py
| @config.command()
@click.option(
"--pattern",
"-p",
required=True,
help="Validation pattern name (e.g., 'default', 'cluster-strict', 'storage-management')",
)
def set_validation_pattern(pattern: str) -> None:
"""Set the validation pattern for this project."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
config_path = biotope_root / ".biotope" / "config.yaml"
if not config_path.exists():
click.echo("❌ Biotope configuration not found. Run 'biotope init' first.")
raise click.Abort
# Load current config
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
click.echo(f"❌ Error reading configuration: {e}")
raise click.Abort
# Initialize annotation_validation if it doesn't exist
if "annotation_validation" not in config:
config["annotation_validation"] = {}
config["annotation_validation"]["validation_pattern"] = pattern
# Save updated config
try:
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
console.print(f"✅ Set validation pattern to: [bold green]{pattern}[/]")
console.print("\n💡 Cluster administrators can check compliance with:")
console.print(" biotope config show-validation-pattern")
except yaml.YAMLError as e:
click.echo(f"❌ Error writing configuration: {e}")
raise click.Abort
|
Show current project-level metadata configuration.
Source code in biotope/biotope/commands/config.py
| @config.command()
def show_project_metadata() -> None:
"""Show current project-level metadata configuration."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
# Load config
config = load_biotope_config(biotope_root)
project_metadata = config.get("project_metadata", {})
if project_metadata:
console.print("\n[bold blue]Project Metadata Configuration[/]")
console.print("This metadata will be used to pre-fill annotation forms:")
table = Table(show_header=False)
table.add_column("Field", style="cyan")
table.add_column("Value", style="green")
for key, value in project_metadata.items():
if key == "creator" and isinstance(value, dict):
display_value = value.get("name", str(value))
else:
display_value = str(value)
table.add_row(key, display_value)
console.print(table)
console.print("\n💡 Use 'biotope config set-project-metadata' to update these values")
else:
console.print("\n[bold yellow]No project metadata configured[/]")
console.print("Use 'biotope config set-project-metadata' to add project-level metadata")
|
show_remote_validation()
Show remote validation configuration status.
Source code in biotope/biotope/commands/config.py
| @config.command()
def show_remote_validation() -> None:
"""Show remote validation configuration status."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
# Load config
config = load_biotope_config(biotope_root)
validation_config = config.get("annotation_validation", {})
remote_config = validation_config.get("remote_config", {})
if remote_config:
console.print("\n[bold blue]Remote Validation Configuration[/]")
console.print(f"URL: {remote_config.get('url', 'N/A')}")
console.print(f"Cache Duration: {remote_config.get('cache_duration', 3600)} seconds")
console.print(f"Fallback to Local: {remote_config.get('fallback_to_local', True)}")
# Check cache status
from biotope.validation import _get_cache_file_path
cache_file = _get_cache_file_path(remote_config["url"], biotope_root)
if cache_file.exists():
cache_age = datetime.now() - datetime.fromtimestamp(cache_file.stat().st_mtime)
console.print(f"Cache Status: ✅ Cached ({cache_age.total_seconds():.0f}s ago)")
else:
console.print("Cache Status: ❌ Not cached")
# Show merged configuration
console.print("\n[bold green]Effective Configuration (Remote + Local)[/]")
required_fields = validation_config.get("minimum_required_fields", [])
if required_fields:
console.print(f"Required Fields: {', '.join(required_fields)}")
else:
console.print("Required Fields: None configured")
else:
console.print("\n[bold yellow]No remote validation configuration[/]")
console.print("Use 'biotope config set-remote-validation --url <url>' to add one")
|
show_validation()
Show current annotation validation requirements.
Source code in biotope/biotope/commands/config.py
| @config.command()
def show_validation() -> None:
"""Show current annotation validation requirements."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
# Load config
config = load_biotope_config(biotope_root)
validation_config = config.get("annotation_validation", {})
console.print("\n[bold blue]Annotation Validation Configuration[/]")
console.print(f"Enabled: {'✅' if validation_config.get('enabled', True) else '❌'}")
# Show validation pattern
from biotope.validation import get_validation_pattern
pattern = get_validation_pattern(biotope_root)
console.print(f"Validation Pattern: [bold green]{pattern}[/]")
# Show required fields
required_fields = validation_config.get("minimum_required_fields", [])
if required_fields:
console.print("\n[bold green]Required Fields:[/]")
table = Table(show_header=True, header_style="bold magenta")
table.add_column("Field", style="cyan")
table.add_column("Type", style="green")
table.add_column("Validation Rules", style="yellow")
field_validation = validation_config.get("field_validation", {})
for field in required_fields:
rules = field_validation.get(field, {})
field_type = rules.get("type", "any")
validation_rules = []
if "min_length" in rules:
validation_rules.append(f"min_length: {rules['min_length']}")
if "required_keys" in rules:
validation_rules.append(f"required_keys: {', '.join(rules['required_keys'])}")
table.add_row(field, field_type, "; ".join(validation_rules) if validation_rules else "none")
console.print(table)
else:
console.print("\n[bold yellow]No required fields configured[/]")
console.print("Use 'biotope config set-validation --field <field_name>' to add requirements")
|
show_validation_pattern()
Show validation pattern information for cluster compliance checking.
Source code in biotope/biotope/commands/config.py
| @config.command()
def show_validation_pattern() -> None:
"""Show validation pattern information for cluster compliance checking."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
# Get validation info
from biotope.validation import get_validation_info
info = get_validation_info(biotope_root)
console.print("\n[bold blue]Validation Pattern Information[/]")
console.print(f"Pattern: [bold green]{info['validation_pattern']}[/]")
console.print(f"Enabled: {'✅' if info['enabled'] else '❌'}")
if info["remote_configured"]:
console.print("Remote Validation: ✅ Configured")
console.print(f" URL: {info['remote_url']}")
console.print(f" Cache Duration: {info['cache_duration']} seconds")
console.print(f" Fallback to Local: {info['fallback_to_local']}")
else:
console.print("Remote Validation: ❌ Not configured")
console.print(f"\n[bold green]Required Fields:[/] {len(info['required_fields'])}")
if info["required_fields"]:
console.print(f" {', '.join(info['required_fields'])}")
# Show compliance hints for cluster administrators
pattern = info["validation_pattern"]
if "cluster" in pattern.lower():
console.print("\n[bold green]✅ Cluster-compliant validation pattern[/]")
elif "storage" in pattern.lower():
console.print("\n[bold green]✅ Storage management validation pattern[/]")
else:
console.print("\n[bold yellow]⚠️ Using default validation pattern[/]")
console.print("Consider configuring cluster-specific validation if required.")
|
toggle_validation(enabled)
Enable or disable annotation validation.
Source code in biotope/biotope/commands/config.py
| @config.command()
@click.option(
"--enabled/--disabled",
default=True,
help="Enable or disable annotation validation",
)
def toggle_validation(enabled: bool) -> None:
"""Enable or disable annotation validation."""
console = Console()
# Find biotope project root
biotope_root = _find_biotope_root()
if not biotope_root:
click.echo("❌ Not in a biotope project. Run 'biotope init' first.")
raise click.Abort
config_path = biotope_root / ".biotope" / "config.yaml"
if not config_path.exists():
click.echo("❌ Biotope configuration not found. Run 'biotope init' first.")
raise click.Abort
# Load current config
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
click.echo(f"❌ Error reading configuration: {e}")
raise click.Abort
# Initialize annotation_validation if it doesn't exist
if "annotation_validation" not in config:
config["annotation_validation"] = {}
config["annotation_validation"]["enabled"] = enabled
# Save updated config
try:
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
status = "enabled" if enabled else "disabled"
console.print(f"✅ Annotation validation {status}")
except yaml.YAMLError as e:
click.echo(f"❌ Error writing configuration: {e}")
raise click.Abort
|