data-translation-experiments / schema_classes.py
rosemariafontana's picture
Update schema_classes.py
86d64eb verified
from pydantic import BaseModel, Field, validator, ValidationError
from typing import List, Dict, Any, Optional, Literal, Union
from enum import Enum
# These are the necessary components that make up the Trials
class Variables(BaseModel):
controlled: Union[List[str], None] = Field(..., title="Controlled Variables", description="An array of controlled variables, which will be constant (controlled) across all trials")
independent: Union[List[str], None] = Field(..., title="Independent Variables", description="An array of independent variables (ie treatments), which will be intentionally varied across one or more trials")
outcome: Union[List[str], None] = Field(..., title="Outcome Variables", description="An array of outcome variables (ie dependent or response variables) which is hypothesized to change across the trials")
class Treatment(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="The treatment name")
description: Union[str, None] = Field(..., title="Description", description="The treatment description, including the conditions within this treatment")
crops: Union[List[str], None] = Field(..., title="Crops", description="An array of crops being tested in this treatment")
fields: Union[List[str], None] = Field(..., title="Fields", description="An array of fields in which this treatment has occurred or will occur")
learnings: Union[List[str], None] = Field(..., title="Learnings", description="An array of lessons learned from this experiment")
variables: Union[Variables, None] = Field(..., title="Variables", description="Variables (ie factors) in this experiment. Some variables are constant (controlled) and some will vary in order to learn something (independent)")
confoundingFactors: Union[List[str], None] = Field(..., title="Confounding Factors", description="An array of factors which may impact the outcomes of the experiment that were not planned for.")
class Trial(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="The name of this trial")
description: Union[str, None] = Field(..., title="Description", description="A description of this trial")
treatments: Union[List[Treatment], None] = Field(..., title="Treatments", description="An array of different treatments (strips or blocks with the same conditions applied) performed by the partner")
class TrialLite(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="The name of this trial")
description: Union[str, None] = Field(..., title="Description", description="A description of this trial")
#################################################################################
# These are the necessary components that make up the Interactions
class Role(str, Enum):
PARTNER = 'partner'
STAFF = 'staff'
AGRONOMIST = 'agronomist'
OTHER = 'other'
def description(self):
descriptions = {
'partner': "A partner in the trial or interaction.",
'staff': "Staff members working on the project.",
'agronomist': "Agronomist providing expertise in the trial.",
'other': "Other roles involved in the trial or interaction."
}
return descriptions.get(self.value, "No description available.")
class Person(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="Name of this person")
role: Union[Role, None] = Field(..., title="Role", description="Role of this person")
class Interactions(BaseModel):
people: Union[List[Person], None] = Field(..., title="People", description="An array of people involved in or mentioned in this interaction")
date: Union[str, None] = Field(..., title="Date", description="Date of the interaction in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
nextMeeting: Union[str, None] = Field(..., title="Date of next meeting in ISO 8601 format (YYYY-MM-DD)", description="Proposed date of the next future interaction in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
nextSteps: Union[List[str], None] = Field(..., title="Next Steps", description="Array containing a list of next steps from the interaction")
summary: Union[str, None] = Field(..., title="Summary", description="Summary of the interaction")
class InteractionsLite(BaseModel):
date: Union[str, None] = Field(..., title="Date", description="Date of the interaction in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
nextMeeting: Union[str, None] = Field(..., title="Date of next meeting", description="Proposed date of the next future interaction")
nextSteps: Union[List[str], None] = Field(..., title="Next Steps", description="List of individual next steps derived from the interaction")
summary: Union[str, None] = Field(..., title="Summary", description="Summary of the interaction")
#################################################################################
# These are the components for Farm Activities, Fields, and Plantings
class Status(str, Enum):
ACTIVE = 'active'
ARCHIVED = 'archived'
# Depending on how well this works, come back and hard-code this based on some parameter(s)
class Convention(str, Enum):
ACTIVITY = 'log--activity'
OBSERVATION = 'log--observation'
FLAMING = 'log--activity--flaming'
GRAZING = 'log--activity--grazing'
MOWING = 'log--activity--mowing'
SOLARIZATION = 'log--activity--solarization'
TERMINATION = 'log--activity--termination'
TILLAGE = 'log--activity--tillage'
HARVEST = 'log--activity--harvest'
HERBICIDE = 'log--input--herbicide_or_pesticide'
IRRIGATION = 'log--input--irrigation'
LIME = 'log--input--lime'
ORGANIC = 'log--input--organic_matter'
SEEDTREAT = 'log--input--seed_treatment'
SEEDLINGTREAT = 'log--input--seedling_treatment'
MODUS = 'log--lab_test--modus_lab_test'
SEEDING = 'log--seeding--seeding'
TRANSPLANT = 'log--transplanting--transplant'
class Structure(str, Enum):
CLAY = 'clay'
SANDYCLAY = 'sandy clay'
SILTYCLAY = 'silty clay'
SANDYCLAYLOAM = 'sandy clay loam'
SILYCLAMLOAM = 'silty clay loam'
CLAYLOAM = 'clay loam'
SANDYLOAM = 'sandy loam'
SILTLOAM = 'silt loam'
LOAM = 'loam'
LOAMYSAND = 'loamy sand'
SAND = 'sand'
SILT = 'silt'
class Log(BaseModel):
convention: Union[Convention, None] = Field(..., title="Logs", description="This log's convention (i.e. this log's category or type)")
date: Union[str, None] = Field(..., title="Date", description="Date the log (i.e. action of the activity or input) was performed in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
description: Union[str, None] = Field(..., title="Description", description="A description of the details of the log (i.e. details about farm activity performed")
class Soil(BaseModel):
description: Union[str, None] = Field(..., title="Description", description="A general description of the soil")
structure: Union[List[Structure], None] = Field(..., title="Structure", description="The structure of the soil using options from the major soil texture classes (sand, clay, silt)")
biology: Union[str, None] = Field(..., title="Biology", description="Biological activity levels of the soil, including fluffiness, worms and bugs, and other evidence of soil biological activity")
class Yield(BaseModel):
quantity: Union[str, None] = Field(..., title="Quantity", description="A description of the total yield (harvested amount) from this planting, including units when available")
quality: Union[str, None] = Field(..., title="Quality", description="The product quality of the harvest. For example, small or large fruits, sweet or tart flavor, easily molding or containing mold, high number of product seconds, etc.)")
# It breaks if soil and yield aren't lists for some reason
class Planting(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="The name of the planting")
status: Union[Status, None] = Field(..., title="Status", description="The status of the planting. \"active\" is a planting which is currently still in the field. \"archived\" is a planting which is no longer in the field (has been terminated or harvested)")
crop: Union[List[str], None] = Field(..., title="Crop", description="A list of the crops in this planting")
variety: Union[List[str], None] = Field(..., title="Variety", description="A list of the crop varieties in this planting")
logs: Union[List[Log], None] = Field(..., title="Logs", description="An array of all logs that are associated with this individual planting")
soil: Union[List[Soil], None] = Field(..., title="Soil", description="Information about the soil associated with or observed during the time of this planting")
yield_: Union[List[Yield], None] = Field(..., title="Yield", description="One set of quantitative and qualitative yield observations for this planting")
class FarmActivities(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="The name of the agricultural field.")
description: Union[str, None] = Field(..., title="Description", description="The description of the agricultural field.")
plantings: Union[List[Planting], None] = Field(..., title="Plantings", description="An array of all the plantings which have occurred on this field")
# These are extra for the modular approach (step-wise)
class FarmActivitiesLite(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="The name of the agricultural field.")
description: Union[str, None] = Field(..., title="Description", description="The description of the agricultural field.")
class PlantingLite(BaseModel):
name: Union[str, None] = Field(..., title="Name", description="The name of the planting")
status: Union[Status, None] = Field(..., title="Status", description="The status of the planting. \"active\" is a planting which is currently still in the field. \"archived\" is a planting which is no longer in the field (has been terminated or harvested)")
crop: Union[List[str], None] = Field(..., title="Crop", description="An array of the crops in this planting")
variety: Union[List[str], None] = Field(..., title="Variety", description="An array of the varieties in this planting")