Computed Data Interfaces¶
CalculationInterface (general_manager.interface.CalculationInterface) models dynamic data that is derived rather than stored. It combines declarative inputs with lazy evaluation to calculate results on demand.
Declaring inputs¶
Inputs use the Input descriptor to specify the expected type and optional value providers.
from datetime import date
from general_manager.interface import CalculationInterface
from general_manager.manager import GeneralManager, Input, graph_ql_property
class ProjectSummary(GeneralManager):
project: Project
date: date
class Interface(CalculationInterface):
project = Input(Project)
date = Input(date)
Computing values¶
Expose computed attributes with @graph_ql_property. The decorator registers the method as a GraphQL field and caches results per manager instance.
@graph_ql_property
def total_volume(self) -> int:
return sum(
derivative.volume
for derivative in self.project.derivative_list.filter(date=self.date)
)
Iterating combinations¶
Call ProjectSummary.all() to iterate through all possible input combinations. Filter inputs with keyword arguments:
for summary in ProjectSummary.filter(project=my_project):
print(summary.date, summary.total_volume)
Because calculation managers do not persist data, create, update, and delete are unavailable. They still participate in dependency tracking, so cached calculations refresh when related managers change.
Input helpers¶
- Use
required=Falsefor optional inputs. Calculation metadata and parsing now treat those fields as nullable and default them toNonewhen omitted. - Use
possible_valuesto restrict input choices or provide a callable for dynamic options. - Use
min_value,max_value, andvalidatorfor scalar constraints without eagerly enumerating every allowed value. - Employ
Input.date_range(...),Input.monthly_date(...), andInput.yearly_date(...)for structured date domains such as month-end or year-start inputs. - Prefer domain objects such as
DateRangeDomainandNumericRangeDomainwhen you need structured range metadata rather than an eager list. - Set
GENERAL_MANAGER["VALIDATE_INPUT_VALUES"] = TrueorGENERAL_MANAGER_VALIDATE_INPUT_VALUES = Trueto enforcepossible_valuesmembership outsideDEBUG. - Use
depends_on(or rely on callable signature introspection) to declare dependencies between inputs. - Use
Input.from_manager_query(...)to build manager-backed dependent inputs without repeating query boilerplate. - Call
Input.cast()in custom workflows to convert raw data into the expected types when bypassing the interface.