from pydantic import BaseModel, Field from typing import Literal, List, Union, Optional # Base class for CircumstanceType with a discriminator field 'type' class CircumstanceTypeBase(BaseModel): type: str # Collision with means of transport class RoadVehicleCollision(CircumstanceTypeBase): type: Literal['road_vehicle'] infrastructure_number: Optional[str] = None road_type: Literal['highway', 'main road', 'secondary road', 'local road/path/trail', 'parking lot'] class TrainCollision(CircumstanceTypeBase): type: Literal['train'] infrastructure_number: str class AircraftCollision(CircumstanceTypeBase): type: Literal['aircraft'] class BoatCollision(CircumstanceTypeBase): type: Literal['boat'] class OtherTransportCollision(CircumstanceTypeBase): type: Literal['other transport collision'] class UnknownTransportCollision(CircumstanceTypeBase): type: Literal['unknown transport collision'] # Destruction / Deliberately removed class HuntingDestruction(CircumstanceTypeBase): type: Literal['hunting'] method: Literal['shooting', 'bow', 'falconry', 'hounds hunting', 'digging up', "other hunting", "unknow hunting"] class TrapDestruction(CircumstanceTypeBase): type: Literal['trap'] method: Literal['killing trap', 'pole trap', 'trap cage', 'corvids nasse', 'net', 'cage trap', 'fall-trap', 'glue trap', 'insect trap', "other trap", "unknown trap"] class PoisoningDestruction(CircumstanceTypeBase): type: Literal['poisoning'] class RemovalDestruction(CircumstanceTypeBase): type: Literal['removal or direct capture'] method: Literal['gassing', 'raptor captured at nest', 'brood destruction', 'traffic/trade', 'capture accident', 'scientific sample', "other removal", "unknown removal"] class FishingDestruction(CircumstanceTypeBase): type: Literal['fishing'] method: Literal['drowned/tangled', 'beached with capture indications', "other fishing", "unknown fishing"] class OtherDestruction(CircumstanceTypeBase): type: Literal['other destruction'] class UnknownDestruction(CircumstanceTypeBase): type: Literal['unknown destruction'] # Indirect destruction class PylonElectricGridDestruction(CircumstanceTypeBase): type: Literal['pylone and electric grid'] infrastructure: Literal['electric line', 'pole/pylon', "other structure", "unknown structure"] cause: Literal['collision', 'electrocution'] class WindfarmDestruction(CircumstanceTypeBase): type: Literal['windfarm'] class OtherCollisionDestruction(CircumstanceTypeBase): type: Literal['other collision'] object: Literal['window', 'building', 'lighthouse', 'cable', 'wire fence/barbed wire', 'other crash', 'unknown crash'] class FallDestruction(CircumstanceTypeBase): type: Literal['fall'] location: Literal['chimney', 'empty pole', 'hole/well', 'other fall', 'unknown fall'] class DevelopmentWorkDestruction(CircumstanceTypeBase): type: Literal['development work'] work_type: Literal['transport infrastructure', 'building', 'other work', 'unknown work'] class PollutionContaminationDestruction(CircumstanceTypeBase): type: Literal['pollution / contamination'] pollution_type: Literal['oil pollution', 'chemical pollution', 'heavy metals', 'light', 'noise', 'plastic ingestion', 'other pollution', 'unknown pollution'] class AgriculturalNetProtectionDestruction(CircumstanceTypeBase): type: Literal['agricultural net protection'] class VegetalForestWorkDestruction(CircumstanceTypeBase): type: Literal['vegetal / forest work'] work_type: Literal['clearing/mowing/plowing', 'tree felling/pruning', 'other forest work', 'unknown forest work'] class OtherIndirectDestruction(CircumstanceTypeBase): type: Literal['other indirect destruction'] class UnknownIndirectDestruction(CircumstanceTypeBase): type: Literal['unknown indirect destruction'] # Natural cause class Predation(CircumstanceTypeBase): type: Literal['predation'] predator: Literal['cat', 'dog', 'rooster/hen', 'other domestic animal', 'wild birds', 'wild mammal', 'other predator', 'unknown predator'] class Weather(CircumstanceTypeBase): type: Literal['weather'] condition: Literal['cold wave', 'drought', 'hail', 'lightening', 'storm', 'other weather', 'unknown weather'] class NaturalDisaster(CircumstanceTypeBase): type: Literal['natural disaster'] disaster: Literal['fire', 'avalanche', 'rock fall', 'mudslide', 'volcanic eruption/ashes', 'other natural disaster', 'unknown natural disaster'] class NestFall(CircumstanceTypeBase): type: Literal['nest fall'] class StrandingExhaustion(CircumstanceTypeBase): type: Literal['stranding due to exhaustion'] class DiseaseParasite(CircumstanceTypeBase): type: Literal['disease/parasite'] class AccidentalDrowning(CircumstanceTypeBase): type: Literal['accidental drowning'] drowning_location: Literal['drinking trough', 'pool', 'storm pool', 'irrigation pool', 'natural pool', 'flood', 'other location', 'unknown location'] class OtherNaturalCause(CircumstanceTypeBase): type: Literal['other natural cause'] class UnknownNaturalCause(CircumstanceTypeBase): type: Literal['unknown natural cause'] # Unknown cause class UnknownCircumstance(CircumstanceTypeBase): type: Literal['unknown'] # Union of all possible CircumstanceTypes with 'type' as the discriminator CircumstanceType = Union[ RoadVehicleCollision, TrainCollision, AircraftCollision, BoatCollision, OtherTransportCollision, UnknownTransportCollision, HuntingDestruction, TrapDestruction, PoisoningDestruction, RemovalDestruction, FishingDestruction, OtherDestruction, UnknownDestruction, PylonElectricGridDestruction, WindfarmDestruction, OtherCollisionDestruction, FallDestruction, DevelopmentWorkDestruction, PollutionContaminationDestruction, AgriculturalNetProtectionDestruction, VegetalForestWorkDestruction, OtherIndirectDestruction, UnknownIndirectDestruction, Predation, Weather, NaturalDisaster, NestFall, StrandingExhaustion, DiseaseParasite, AccidentalDrowning, OtherNaturalCause, UnknownNaturalCause, UnknownCircumstance ] # Main Circumstance class class Circumstances(BaseModel): circumstance_radio: str # e.g., "Yes" circumstance: Optional[str] = None # e.g., "COLLISION" circumstance_type: Optional[CircumstanceType] = Field(None, discriminator='type') # Example usage # json_data = { # "circumstance": "COLLISION", # "circumstance_radio": "Yes", # "circumstance_type": { # "type": "Train", # "infrastructure_number": "56" # } # } # circumstance_instance = Circumstance(**json_data) # circumstance_schema = Circumstance.schema_json(indent=2)