CropAI / backend /models.py
bapi143's picture
Deploy CropAI Deep Learning backend, YOLO11 pest model and Audio-CNN
970be68
Raw History Blame Contribute Delete
13.3 kB
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field
from datetime import datetime, timezone
def current_utc_time():
return datetime.now(timezone.utc)
class AlternativeDiagnosis(BaseModel):
disease_id: str
disease_name: str
crop: str
confidence: float = Field(..., ge=0.0, le=1.0)
class TreatmentPlan(BaseModel):
immediate_action: List[str]
organic_control: List[str]
chemical_control: List[str]
class DiseaseDetail(BaseModel):
id: str
name: str
scientific_name: Optional[str] = None
crop: str
severity: str = Field(..., description="Healthy | Low | Moderate | Severe | Critical | Invalid")
is_healthy: bool = False
symptoms: List[str]
treatment: TreatmentPlan
prevention: List[str]
expert_consultation_recommended: bool = False
class DiagnosisResponse(BaseModel):
success: bool = True
is_valid_leaf: bool = Field(default=True, description="False if image is a car, object, or non-plant")
timestamp: datetime = Field(default_factory=current_utc_time)
image_id: str
crop: str
disease: str
disease_id: str
scientific_name: Optional[str] = None
is_healthy: bool
severity: str
confidence: float = Field(..., ge=0.0, le=1.0)
confidence_percentage: str
symptoms: List[str]
management: TreatmentPlan
prevention: List[str]
alternatives: List[AlternativeDiagnosis] = []
similar_crops: List[str] = []
expert_escalation: dict = Field(
default_factory=lambda: {
"recommended": False,
"helpline_number": "+918817814859",
"whatsapp_expert": "+918817814859",
"reason": None
}
)
class CropInfo(BaseModel):
crop_name: str
supported_diseases_count: int
diseases: List[str]
class SupportedCropsResponse(BaseModel):
total_crops: int
total_classes: int
crops: List[CropInfo]
class ExpertTicketRequest(BaseModel):
farmer_name: str
phone_number: str
location: Optional[str] = None
crop: str
disease_suspected: Optional[str] = None
confidence_score: Optional[float] = None
notes: Optional[str] = None
image_url_or_id: Optional[str] = None
class ExpertTicketResponse(BaseModel):
ticket_id: str
status: str = "PENDING_REVIEW"
created_at: datetime = Field(default_factory=current_utc_time)
message: str
assigned_expert: str = "Dr. S. Sharma (Senior Agronomist, Plant Pathology)"
estimated_callback_minutes: int = 30
class DosageCalculationRequest(BaseModel):
crop: str
disease_id: str
farm_area_acres: float = Field(..., gt=0.0, description="Farm area in acres")
knapsack_tank_liters: float = Field(default=16.0, gt=0.0, description="Knapsack sprayer tank capacity in liters")
treatment_type: str = Field(default="chemical", description="chemical | organic")
class DosageCalculationResponse(BaseModel):
crop: str
disease: str
farm_area_acres: float
recommended_chemical_or_bio: str
total_water_liters: float
total_dosage_amount: str
dosage_per_tank: str
total_knapsack_tanks: int
spray_instructions: List[str]
safety_precautions: List[str]
class SporeCastPoint(BaseModel):
district: str
latitude: float
longitude: float
disease: str
risk_level: str # Low, Moderate, High, Severe Epidemic
wind_vector: str
forecast_48h: str
affected_farms_reported: int
class SporeCastAlertResponse(BaseModel):
active_epidemics: int
highest_risk_region: str
spore_dispersion_speed_kmh: float
regional_heatmap: List[SporeCastPoint]
kvk_advisory: str
class GreenCreditRequest(BaseModel):
farmer_id: Optional[str] = "FARMER-001"
crop: str
farm_area_acres: float
adopted_practice: str = Field(..., description="bio_fungicide | neem_extract | trichoderma | balanced_ipm")
class GreenCreditResponse(BaseModel):
green_credits_earned: int
chemical_pesticide_saved_kg: float
carbon_offset_kg_co2e: float
soil_microbiome_health_score: str
reward_redemption_eligible: bool
certificate_id: str
class SpectroscopyAnalysisResponse(BaseModel):
is_leaf: bool = True
is_valid_leaf: bool = True
rejection_code: Optional[str] = None
error_message: Optional[str] = None
chlorophyll_retention_percentage: float = 0.0
green_leaf_index_gli: float = 0.0
vari_index: float = 0.0
ngrdi_index: float = 0.0
health_status: str
asymptomatic_stress_detected: bool = False
risk_classification: str
spectral_diagnosis: str
early_action_protocol: List[str] = []
foliage_coverage_percentage: Optional[float] = None
diagnostics: Optional[dict] = None
class FarmMemorySaveRequest(BaseModel):
crop: str
disease: str
disease_id: str
severity: str
confidence: float
temperature_c: float
humidity_pct: float
weather_condition: str
location_name: Optional[str] = "Ambikapur, Surguja"
gps_lat: Optional[float] = 23.1188
gps_lng: Optional[float] = 83.1979
farmer_notes: Optional[str] = ""
diagnosis_date: Optional[str] = None
class SeasonalAlertItem(BaseModel):
alert_id: str
crop: str
disease: str
disease_id: str
historical_outbreak_date: str
threat_level: str
recurrence_risk_score: float
window_description: str
alert_title: str
alert_message: str
prophylactic_plan: dict
class SeasonalAlertsResponse(BaseModel):
status: str = "success"
active_alerts_count: int
alerts: List[SeasonalAlertItem]
class BioAcousticAnalysisResponse(BaseModel):
pest_detected: bool
pest_identified: str
threat_level: str
confidence_score: float
dominant_frequency_hz: float
pest_acoustic_energy_ratio: float
diagnosis_summary: str
recommended_actions: List[str]
engine_type: Optional[str] = "Mel_CNN_BioAcoustic"
class_probabilities: Optional[Dict[str, float]] = None
mastication_rhythm_index: Optional[float] = None
class BioTwinForecastResponse(BaseModel):
crop: str
target_pathogen: str
spore_germination_index_pct: float
risk_classification: str
calculated_dew_point_c: float
effective_leaf_wetness_hours: float
critical_infection_window_hours: int
physics_forecast_summary: str
preventive_canopy_actions: List[str]
class DroneVRAMissionRequest(BaseModel):
field_id: str = "FIELD-01"
center_lat: float = 23.1188
center_lng: float = 83.1979
field_area_acres: float = Field(..., gt=0.0)
infected_clusters: List[dict] = Field(default_factory=list)
spray_altitude_meters: float = Field(default=2.5, gt=0.5, le=10.0)
class DroneVRAMissionResponse(BaseModel):
mission_id: str
field_area_acres: float
flight_altitude_meters: float
swath_width_meters: float
total_waypoints: int
estimated_flight_duration_minutes: float
vra_spot_spray_liters: float
traditional_blanket_spray_liters: float
chemical_savings_percentage: str
waypoints: List[dict]
geojson_flight_plan: dict
qgroundcontrol_format_compatible: bool
class ProofOfFarmingRequest(BaseModel):
farmer_id: str = "FARMER-101"
farmer_name: str
khasra_survey_number: str
district: str = "Surguja"
state: str = "Chhattisgarh"
crop: str = "Paddy (Rice)"
disease_identified: str
severity_percentage: float = Field(..., ge=0.0, le=100.0)
affected_area_acres: float = Field(..., gt=0.0)
gps_latitude: float
gps_longitude: float
image_hash: Optional[str] = None
class ProofOfFarmingResponse(BaseModel):
certificate_id: str
digital_signature_sha256: str
created_at_utc: str
claim_status: str
fast_track_claim_payload: dict
blockchain_smart_contract_ready: bool
verification_qr_payload: str
class GovernmentSchemeItem(BaseModel):
id: str
title_hi: str
title_en: str
category: str
category_hi: str
benefit_amount: str
summary_hi: str
summary_en: str
eligibility_hi: str
required_documents_hi: List[str]
official_portal: str
direct_apply_url: Optional[str] = None
status_check_url: Optional[str] = None
guidelines_pdf_url: Optional[str] = None
source_portal_authority: Optional[str] = "Government of India"
helpline: str
icon: str
badge_color: str
last_synced_utc: Optional[str] = None
class GovernmentSchemesResponse(BaseModel):
total_schemes: int
myscheme_portal_url: str = "https://www.myscheme.gov.in/search/category/Agriculture,Rural%20&%20Environment"
live_sync_status: str = "SYNCED_WITH_GOVT_PORTALS"
categories: List[str]
schemes: List[GovernmentSchemeItem]
class KisanPollOptionItem(BaseModel):
id: str
title_hi: str
title_en: str
description_hi: str
icon: str
votes_count: int
vote_percentage: float
recommended_govt_action_hi: str
class KisanPollVoteRequest(BaseModel):
problem_id: str
district: Optional[str] = "Surguja"
state: Optional[str] = "Chhattisgarh"
crop_affected: Optional[str] = "Paddy (Rice)"
farmer_comment: Optional[str] = ""
class KisanPollResultsResponse(BaseModel):
target_district: str
total_farmer_responses: int
highest_priority_issue: str
highest_priority_vote_share: str
recommended_immediate_intervention: str
issues_breakdown: List[KisanPollOptionItem]
last_updated: str
# =========================================================================
# Next-Gen Innovation Schemas (Voice, Traps, Satellite, Soil, GNN)
# =========================================================================
class VoiceAdvisoryRequest(BaseModel):
user_query: str
dialect: Optional[str] = "ch-IN"
crop: Optional[str] = None
class VoiceAdvisoryResponse(BaseModel):
status: str = "success"
dialect: str
dialect_name: str
user_query: str
normalized_context: dict
spoken_title: str
advisory_text: str
tank_prescription: dict
tts_playback_metadata: dict
class SoilHealthCardRequest(BaseModel):
crop: Optional[str] = "Rice"
area_acres: Optional[float] = 1.0
ph: Optional[float] = 6.8
organic_carbon_pct: Optional[float] = 0.52
available_n_kg_ha: Optional[float] = 220.0
available_p_kg_ha: Optional[float] = 14.5
available_k_kg_ha: Optional[float] = 180.0
zinc_ppm: Optional[float] = 0.55
has_active_blast: Optional[bool] = False
class SoilHealthCardResponse(BaseModel):
status: str = "success"
soil_test_readings: dict
target_crop: str
area_acres: float
total_commercial_fertilizer: dict
split_schedule: List[dict]
safety_alert: Optional[str] = None
# =========================================================================
# Extreme Weather Shock & IoT Telemetry Schemas
# =========================================================================
class WeatherShockForecastRequest(BaseModel):
crop: Optional[str] = "Potato"
ambient_temp_c: Optional[float] = 4.0
min_predicted_temp_c: Optional[float] = 1.5
max_predicted_temp_c: Optional[float] = 24.0
relative_humidity: Optional[float] = 55.0
wind_speed_kmh: Optional[float] = 3.0
cloud_cover_pct: Optional[float] = 5.0
growth_stage: Optional[str] = None
class WeatherShockForecastResponse(BaseModel):
status: str = "success"
crop: str
vulnerable_stage: str
primary_threat: str
microclimate_snapshot: dict
frost_assessment: dict
heatwave_assessment: dict
class IoTTelemetryPacket(BaseModel):
device_id: str = "NODE-SURGUJA-01"
battery_voltage_v: float = 3.92
solar_charging: bool = True
rssi_dbm: int = -88
snr_db: float = 8.5
soil_moisture_vwc_15cm: float = 24.5
soil_moisture_vwc_30cm: float = 28.2
canopy_temp_c: float = 26.4
canopy_rh_pct: float = 82.0
leaf_wetness_pct: float = 45.0
class IoTTelemetryResponse(BaseModel):
status: str = "success"
device_id: str
packet_timestamp_utc: str
soil_moisture_assessment: dict
microclimate: dict
hardware_telemetry: dict
active_alarms: List[dict]
# =========================================================================
# Kisan Jan-Mat Community Poll & Government Scheme Schemas
# =========================================================================
class KisanPollVoteRequest(BaseModel):
problem_id: str
district: Optional[str] = "Surguja"
state: Optional[str] = "Chhattisgarh"
crop_affected: Optional[str] = "Paddy (Rice)"
farmer_comment: Optional[str] = ""
device_id: Optional[str] = ""
class KisanPollVoteResponse(BaseModel):
status: str
message_hi: str
message_en: str
ballot_id: str
total_community_votes: int
updated_results: List[dict]
class KisanPollQuestionsResponse(BaseModel):
status: str = "success"
total_options: int
options: List[dict]
class KisanPollResultsResponse(BaseModel):
status: str = "success"
target_district: str
total_farmer_responses: int
highest_priority_issue: str
highest_priority_vote_share: str
recommended_immediate_intervention: str
issues_breakdown: List[dict]
recent_grassroot_ballots: Optional[List[dict]] = []
last_updated: str