Spaces:
Sleeping
Sleeping
| """ | |
| MCP Server for Agricultural Weed Pressure Analysis | |
| Integrates tools, resources and prompts from the mcp/ folder | |
| """ | |
| import gradio as gr | |
| import pandas as pd | |
| import numpy as np | |
| import plotly.express as px | |
| from data_loader import AgriculturalDataLoader | |
| from agricultural_mcp.tools import WeedPressureAnalyzer, analyze_herbicide_trends, predict_future_weed_pressure, recommend_sensitive_crop_plots, explore_raw_data, get_available_plots, get_available_crops, get_available_interventions | |
| from agricultural_mcp.resources import AgriculturalResources | |
| import warnings | |
| warnings.filterwarnings('ignore') | |
| # Initialize analyzer and resources | |
| analyzer = WeedPressureAnalyzer() | |
| resources = AgriculturalResources() | |
| def create_mcp_interface(): | |
| """ | |
| Create the main MCP interface with 5 tabs: | |
| 1. Analyse Tendances - IFT herbicide analysis | |
| 2. Prédictions - Weed pressure predictions 2025-2027 | |
| 3. Recommandations - Sensitive crop recommendations | |
| 4. Exploration Données - Raw data exploration | |
| 5. MCP Resources - Display resources.py content | |
| """ | |
| with gr.Blocks(title="Serveur MCP - Analyse Pression Adventices", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# 🌾 Serveur MCP - Analyse Pression Adventices") | |
| gr.Markdown(""" | |
| **Analyse de la pression adventices et recommandations pour cultures sensibles** | |
| Ce serveur MCP (Model Context Protocol) fournit des outils d'analyse pour : | |
| - Calculer l'IFT (Indice de Fréquence de Traitement) des herbicides | |
| - Prédire la pression adventices pour 2025-2027 | |
| - Recommander des parcelles pour cultures sensibles (pois, haricot) | |
| - Explorer les données agricoles avec filtres avancés | |
| """) | |
| with gr.Tabs(): | |
| # Tab 1: Analyse Tendances | |
| with gr.Tab("📈 Analyse Tendances"): | |
| gr.Markdown("### Analyse des tendances IFT herbicides") | |
| gr.Markdown(""" | |
| **Méthode de calcul IFT :** | |
| - IFT = Nombre d'applications herbicides / Surface de la parcelle | |
| - Analyse de l'évolution temporelle par parcelle | |
| - Classification des niveaux de risque : Faible (IFT < 1.0), Modéré (1.0 ≤ IFT < 2.0), Élevé (IFT ≥ 2.0) | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| year_start = gr.Slider( | |
| minimum=2014, | |
| maximum=2025, | |
| value=2014, | |
| step=1, | |
| label="Année de début" | |
| ) | |
| year_end = gr.Slider( | |
| minimum=2014, | |
| maximum=2025, | |
| value=2025, | |
| step=1, | |
| label="Année de fin" | |
| ) | |
| plot_filter = gr.Dropdown( | |
| choices=get_available_plots(), | |
| value="Toutes", | |
| label="Filtrer par parcelle" | |
| ) | |
| analyze_btn = gr.Button("📊 Analyser les Tendances", variant="primary") | |
| with gr.Row(): | |
| trend_plot = gr.Plot() | |
| trend_summary = gr.Markdown() | |
| analyze_btn.click( | |
| analyze_herbicide_trends, | |
| inputs=[year_start, year_end, plot_filter], | |
| outputs=[trend_plot, trend_summary] | |
| ) | |
| # Tab 2: Prédictions | |
| with gr.Tab("🔮 Prédictions"): | |
| gr.Markdown("### Prédictions de pression adventices 2025-2027") | |
| gr.Markdown(""" | |
| **Méthode de prédiction :** | |
| - Régression linéaire sur les données IFT historiques | |
| - Extrapolation pour les années 2025-2027 | |
| - Classification des niveaux de risque basée sur l'IFT prédit | |
| - Prise en compte de l'historique des cultures récentes | |
| """) | |
| with gr.Row(): | |
| predict_btn = gr.Button("🔮 Générer les Prédictions", variant="primary") | |
| with gr.Row(): | |
| pred_plot = gr.Plot() | |
| pred_summary = gr.Markdown() | |
| predict_btn.click( | |
| predict_future_weed_pressure, | |
| outputs=[pred_plot, pred_summary] | |
| ) | |
| # Tab 3: Recommandations | |
| with gr.Tab("🌱 Recommandations"): | |
| gr.Markdown("### Recommandations pour cultures sensibles") | |
| gr.Markdown(""" | |
| **Critères de recommandation :** | |
| - Parcelles avec IFT prédit < 1.0 (faible pression adventices) | |
| - Score de recommandation : 100 - (IFT_prédit × 30) | |
| - Cultures sensibles : pois, haricot | |
| - Prise en compte de l'historique cultural récent | |
| """) | |
| with gr.Row(): | |
| recommend_btn = gr.Button("🌱 Générer les Recommandations", variant="primary") | |
| with gr.Row(): | |
| rec_plot = gr.Plot() | |
| rec_summary = gr.Markdown() | |
| recommend_btn.click( | |
| recommend_sensitive_crop_plots, | |
| outputs=[rec_plot, rec_summary] | |
| ) | |
| # Tab 4: Exploration Données | |
| with gr.Tab("🔍 Exploration Données"): | |
| gr.Markdown("### Exploration des données brutes") | |
| gr.Markdown(""" | |
| **Filtres disponibles :** | |
| - Années : 2014-2025 | |
| - Parcelles : 106 parcelles disponibles | |
| - Cultures : 42 types de cultures | |
| - Types d'intervention : Herbicides, Fertilisation, Semis, etc. | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| data_year_start = gr.Slider( | |
| minimum=2014, | |
| maximum=2025, | |
| value=2014, | |
| step=1, | |
| label="Année de début" | |
| ) | |
| data_year_end = gr.Slider( | |
| minimum=2014, | |
| maximum=2025, | |
| value=2025, | |
| step=1, | |
| label="Année de fin" | |
| ) | |
| data_plot_filter = gr.Dropdown( | |
| choices=get_available_plots(), | |
| value="Toutes", | |
| label="Filtrer par parcelle" | |
| ) | |
| data_crop_filter = gr.Dropdown( | |
| choices=get_available_crops(), | |
| value="Toutes", | |
| label="Filtrer par culture" | |
| ) | |
| data_intervention_filter = gr.Dropdown( | |
| choices=get_available_interventions(), | |
| value="Toutes", | |
| label="Filtrer par type d'intervention" | |
| ) | |
| explore_btn = gr.Button("🔍 Explorer les Données", variant="primary") | |
| with gr.Row(): | |
| data_plot = gr.Plot() | |
| data_summary = gr.Markdown() | |
| explore_btn.click( | |
| explore_raw_data, | |
| inputs=[data_year_start, data_year_end, data_plot_filter, data_crop_filter, data_intervention_filter], | |
| outputs=[data_plot, data_summary] | |
| ) | |
| # Tab 5: MCP Resources | |
| with gr.Tab("🔧 MCP Resources"): | |
| gr.Markdown("### Resources MCP disponibles") | |
| gr.Markdown(""" | |
| **Resources MCP exposées :** | |
| - `dataset://years` - Liste des millésimes disponibles | |
| - `exploitation://{siret}/{millesime}` - Informations d'exploitation | |
| - `parcelle://{millesime}/{numparcell}` - Informations de parcelle | |
| - `intervention://{millesime}/{numparcell}/{rang}` - Informations d'intervention | |
| - `intrant://{codeamm}` - Informations d'intrant | |
| - `materiel://{millesime}/{numparcell}/{rang}` - Informations de matériel | |
| - `maindoeuvre://{millesime}/{numparcell}/{rang}` - Informations de main d'œuvre | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("#### Test des Resources MCP") | |
| # Test Years | |
| years_btn = gr.Button("📅 Liste des Années", variant="primary") | |
| # Test Exploitation | |
| with gr.Row(): | |
| siret_input = gr.Textbox( | |
| label="SIRET Exploitation", | |
| value="18560001000016", | |
| placeholder="18560001000016" | |
| ) | |
| siret_millesime_input = gr.Textbox( | |
| label="Millesime", | |
| value="2025", | |
| placeholder="2025" | |
| ) | |
| siret_btn = gr.Button("🏢 Test Exploitation", variant="secondary") | |
| # Test Parcelle | |
| with gr.Row(): | |
| parcelle_millesime_input = gr.Textbox( | |
| label="Millesime", | |
| value="2025", | |
| placeholder="2025" | |
| ) | |
| parcelle_input = gr.Textbox( | |
| label="Numéro Parcelle", | |
| value="12", | |
| placeholder="12" | |
| ) | |
| parcelle_btn = gr.Button("🏞️ Test Parcelle", variant="secondary") | |
| # Test Intervention | |
| with gr.Row(): | |
| intervention_millesime_input = gr.Textbox( | |
| label="Millesime", | |
| value="2025", | |
| placeholder="2025" | |
| ) | |
| intervention_parcelle_input = gr.Textbox( | |
| label="Num Parcelle", | |
| value="12", | |
| placeholder="12" | |
| ) | |
| intervention_rang_input = gr.Textbox( | |
| label="Rang", | |
| value="1", | |
| placeholder="1" | |
| ) | |
| intervention_btn = gr.Button("⚙️ Test Intervention", variant="secondary") | |
| # Test Intrant | |
| with gr.Row(): | |
| intrant_input = gr.Textbox( | |
| label="Code AMM Intrant", | |
| value="9100296", | |
| placeholder="9100296" | |
| ) | |
| intrant_millesime_input = gr.Textbox( | |
| label="Millesime (optionnel)", | |
| value="", | |
| placeholder="2025" | |
| ) | |
| intrant_btn = gr.Button("🧪 Test Intrant", variant="secondary") | |
| # Test Matériel | |
| with gr.Row(): | |
| materiel_millesime_input = gr.Textbox( | |
| label="Millesime", | |
| value="2025", | |
| placeholder="2025" | |
| ) | |
| materiel_parcelle_input = gr.Textbox( | |
| label="Num Parcelle", | |
| value="12", | |
| placeholder="12" | |
| ) | |
| materiel_rang_input = gr.Textbox( | |
| label="Rang", | |
| value="1", | |
| placeholder="1" | |
| ) | |
| materiel_btn = gr.Button("🔧 Test Matériel", variant="secondary") | |
| with gr.Column(): | |
| gr.Markdown("#### Résultat") | |
| resource_output = gr.JSON(label="Résultat de la resource") | |
| # Connexions des boutons | |
| years_btn.click( | |
| lambda: resources.list_years(), | |
| outputs=[resource_output] | |
| ) | |
| siret_btn.click( | |
| lambda siret, millesime: resources.get_exploitation(siret, millesime), | |
| inputs=[siret_input, siret_millesime_input], | |
| outputs=[resource_output] | |
| ) | |
| parcelle_btn.click( | |
| lambda millesime, parcelle: resources.get_parcelle(millesime, parcelle), | |
| inputs=[parcelle_millesime_input, parcelle_input], | |
| outputs=[resource_output] | |
| ) | |
| intervention_btn.click( | |
| lambda millesime, parcelle, rang: resources.get_intervention(millesime, parcelle, rang), | |
| inputs=[intervention_millesime_input, intervention_parcelle_input, intervention_rang_input], | |
| outputs=[resource_output] | |
| ) | |
| intrant_btn.click( | |
| lambda codeamm, millesime: resources.get_intrant(codeamm, millesime if millesime else None), | |
| inputs=[intrant_input, intrant_millesime_input], | |
| outputs=[resource_output] | |
| ) | |
| materiel_btn.click( | |
| lambda millesime, parcelle, rang: resources.get_materiel(millesime, parcelle, rang), | |
| inputs=[materiel_millesime_input, materiel_parcelle_input, materiel_rang_input], | |
| outputs=[resource_output] | |
| ) | |
| return demo |