Configuration#
The protea.config subpackage provides tuning parameters and
configuration helpers used across the PROTEA stack.
Tuning parameters
protea.config.tuning exposes TuningSettings, a Pydantic settings
class that aggregates knobs for batch sizes, timeouts, and algorithm
parameters. Values are read from environment variables (with
PROTEA_ prefix) and fall back to documented defaults. Workers
instantiate a single TuningSettings object at startup; operations
receive it via dependency injection rather than importing it directly,
keeping them independently testable.
Runtime tuning settings (T-CONF.2).
Externalises hardcoded module-level constants from protea/ so an
operator can tune throughput, retry policy and timeouts per
deployment target (dev, prod-cloud, hpc-bsc, hpc-airgap) without
touching code.
Hierarchy (lowest to highest priority):
Defaults baked into the pydantic models below.
tuning:section inprotea/config/system.yaml.Environment variables of the form
PROTEA_TUNING__<group>__<field>.
Currently scoped to the QueueTuning group as a proof of concept.
The remaining categories from docs/CONFIG_INVENTORY.md
(WorkerTuning, OperationTuning, APILimits, ResearchKnobs) follow the
same pattern and will be added incrementally.
Example:
from protea.config.tuning import get_tuning
settings = get_tuning()
for attempt in range(settings.queue.publisher_max_attempts):
...
- class protea.config.tuning.APILimits(*, max_fasta_bytes: Annotated[int, Ge(ge=1024)] = 52428800, max_comment_length: Annotated[int, Ge(ge=1)] = 500, recent_limit: Annotated[int, Ge(ge=1)] = 20, page_limit: Annotated[int, Ge(ge=1)] = 100)#
Bases:
BaseModelHTTP boundary limits enforced at the FastAPI router layer.
Sources:
api/routers/{annotate,query_sets,support}.py(verdocs/CONFIG_INVENTORY.md§D).- max_comment_length: int#
- max_fasta_bytes: int#
- model_config = {}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- page_limit: int#
- recent_limit: int#
- class protea.config.tuning.OperationTuning(*, annotation_chunk_size: Annotated[int, Ge(ge=100)] = 10000, stream_chunk_size: Annotated[int, Ge(ge=100)] = 2000, store_chunk_size: Annotated[int, Ge(ge=500)] = 10000, numpy_query_chunk: Annotated[int, Ge(ge=10)] = 500, ref_cache_freshness_seconds: Annotated[int, Ge(ge=0)] = 300, aspect_knn_workers: Annotated[int, Ge(ge=1)] = 3, gpu_busy_retry_seconds: Annotated[int, Ge(ge=1)] = 8)#
Bases:
BaseModelModule-level chunk and batch sizes used inside operations.
HTTP retry policy and per-source timeouts live inside their respective pydantic payloads (
InsertProteinsPayload,LoadGoaAnnotationsPayload, etc.) because the caller picks them per-job. The values here are infra-level: how to slice work between memory and broker pressure constraints.Sources:
core/feature_enricher.py,core/knn_search.py,core/operations/{predict_go_terms,training_dump_helpers}.py(verdocs/CONFIG_INVENTORY.md§C).- annotation_chunk_size: int#
- aspect_knn_workers: int#
- gpu_busy_retry_seconds: int#
- model_config = {}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- numpy_query_chunk: int#
- ref_cache_freshness_seconds: int#
- store_chunk_size: int#
- stream_chunk_size: int#
- class protea.config.tuning.QueueTuning(*, publisher_max_attempts: Annotated[int, Ge(ge=1)] = 12, publisher_base_delay: Annotated[float, Ge(ge=0.0)] = 1.0, oom_max_retries: Annotated[int, Ge(ge=0)] = 5, oom_base_delay: Annotated[int, Ge(ge=0)] = 5, oom_max_delay: Annotated[int, Ge(ge=1)] = 300, amqp_heartbeat: Annotated[int, Ge(ge=0)] = 600)#
Bases:
BaseModelRabbitMQ publisher / consumer retry and dispatch knobs.
Sources:
infrastructure/queue/publisher.pyandinfrastructure/queue/consumer.py(verdocs/CONFIG_INVENTORY.md§A).- amqp_heartbeat: int#
- model_config = {}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- oom_base_delay: int#
- oom_max_delay: int#
- oom_max_retries: int#
- publisher_base_delay: float#
- publisher_max_attempts: int#
- class protea.config.tuning.ServeTuning(*, default_embedding_config_id: str | None = None, compute_alignments: bool = True, compute_taxonomy: bool = True, compute_v6_features: bool = False, compute_lineage_features: bool = False, interpro_bp_graft: bool = False, interpro_bp_graft_weight: Annotated[float, Ge(ge=0.0), Le(le=1.0)] = 0.5, interpro_bp_graft_source_version: str | None = None, classifier_impl_by_category: bool = False)#
Bases:
BaseModelLive serving-path knobs for the one-click
/annotateendpoint.These pin the validated offline pipeline onto the serving path without hardcoding ids or flipping behaviour. Every default reproduces the pre-existing serve behaviour exactly, so a deployment that sets none of these env vars serves identically to before. To activate the validated pipeline at deploy time, set:
default_embedding_config_idto the learned k-WTA retrieval config,compute_v6_featuresandcompute_lineage_featurestoTrueso the predict payload matches the validated reranker feature schema,interpro_bp_grafttoTruefor the InterPro2GO BP enrichment.
Sources:
api/routers/annotate.pyand the predict post-KNN pipeline.- classifier_impl_by_category: bool#
- compute_alignments: bool#
- compute_lineage_features: bool#
- compute_taxonomy: bool#
- compute_v6_features: bool#
- default_embedding_config_id: str | None#
- interpro_bp_graft: bool#
- interpro_bp_graft_source_version: str | None#
- interpro_bp_graft_weight: float#
- model_config = {}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class protea.config.tuning.TuningSettings(*, queue: QueueTuning = <factory>, worker: WorkerTuning = <factory>, operation: OperationTuning = <factory>, api: APILimits = <factory>, serve: ServeTuning = <factory>)#
Bases:
BaseModelRoot tuning model that composes per-category sub-models.
- model_config = {}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- operation: OperationTuning#
- queue: QueueTuning#
- serve: ServeTuning#
- worker: WorkerTuning#
- class protea.config.tuning.WorkerTuning(*, db_pool_size: Annotated[int, Ge(ge=1)] = 20, db_pool_max_overflow: Annotated[int, Ge(ge=0)] = 40, db_pool_recycle_seconds: Annotated[int, Ge(ge=60)] = 3600, model_cache_max: Annotated[int, Ge(ge=1)] = 1, ref_cache_max: Annotated[int, Ge(ge=1)] = 1, reaper_main_timeout_seconds: Annotated[int, Ge(ge=300)] = 21600, reaper_default_timeout_seconds: Annotated[int, Ge(ge=300)] = 3600, reaper_stall_seconds: Annotated[int, Ge(ge=60)] = 1800, reaper_event_grace_seconds: Annotated[int, Ge(ge=60)] = 2700, worker_shutdown_grace_seconds: Annotated[int, Ge(ge=1)] = 30, job_heartbeat_interval_seconds: Annotated[int, Ge(ge=5)] = 30, max_lease_requeues: Annotated[int, Ge(ge=0)] = 3, api_cache_default_ttl_seconds: Annotated[float, Ge(ge=1.0)] = 300.0)#
Bases:
BaseModelPool sizes, in-process caches and reaper timeouts.
Sources:
infrastructure/database/engine.py,infrastructure/operations/{compute_embeddings,predict_go_terms}.py,workers/stale_job_reaper.py,api/cache.py(verdocs/CONFIG_INVENTORY.md§B).- api_cache_default_ttl_seconds: float#
- db_pool_max_overflow: int#
- db_pool_recycle_seconds: int#
- db_pool_size: int#
- job_heartbeat_interval_seconds: int#
- max_lease_requeues: int#
- model_cache_max: int#
- model_config = {}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- reaper_default_timeout_seconds: int#
- reaper_event_grace_seconds: int#
- reaper_main_timeout_seconds: int#
- reaper_stall_seconds: int#
- ref_cache_max: int#
- worker_shutdown_grace_seconds: int#
- protea.config.tuning.get_tuning() TuningSettings#
Load and cache the tuning settings.
- Cache reset (mostly for tests):
get_tuning.cache_clear()
See also
Configuration Reference: full environment-variable reference.
Infrastructure:
protea.infrastructure.settingsfor the database and AMQP connection strings.