|
|
import gradio as gr |
|
|
import requests |
|
|
import pandas as pd |
|
|
import plotly.express as px |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def process_species_data(species_name, habitat, water_disturbance, land_disturbance, noise_level): |
|
|
if not species_name: |
|
|
return "Please enter a species name.", None, None |
|
|
|
|
|
|
|
|
wiki_url = "https://en.wikipedia.org/w/api.php" |
|
|
headers = { |
|
|
'User-Agent': 'BioVigilusApp/1.0 (educational-research-project)' |
|
|
} |
|
|
params = { |
|
|
"action": "query", |
|
|
"format": "json", |
|
|
"prop": "extracts", |
|
|
"titles": species_name.replace(" ", "_"), |
|
|
"explaintext": True, |
|
|
"exintro": False, |
|
|
} |
|
|
|
|
|
try: |
|
|
response = requests.get(wiki_url, params=params, headers=headers).json() |
|
|
pages = response.get("query", {}).get("pages", {}) |
|
|
|
|
|
if "-1" in pages: |
|
|
extract = f"Species '{species_name}' not found. Please check spelling (e.g., use 'Panthera tigris' instead of 'Tiger')." |
|
|
else: |
|
|
page = next(iter(pages.values())) |
|
|
extract = page.get("extract", "No summary available.") |
|
|
|
|
|
except Exception as e: |
|
|
extract = f"Connection Error: {str(e)}" |
|
|
|
|
|
|
|
|
words = extract.split() |
|
|
|
|
|
|
|
|
if len(words) < 150: |
|
|
educational_filler = ( |
|
|
"\n\n[Additional Ecological Context]\n" |
|
|
f"The species {species_name} is an integral part of its local food web. " |
|
|
"Biodiversity loss regarding this species could trigger a trophic cascade, affecting both prey and predator populations. " |
|
|
"Conservationists monitor such species as bio-indicators of environmental health. " |
|
|
"Preserving their natural habitat is essential not just for their survival, but for the stability of the entire ecosystem. " |
|
|
"Effective conservation strategies include habitat restoration, anti-poaching laws, and community awareness programs." |
|
|
) |
|
|
extract += educational_filler |
|
|
words = extract.split() |
|
|
|
|
|
|
|
|
summary_text = " ".join(words[:250]) + "..." |
|
|
|
|
|
|
|
|
analysis_section = f""" |
|
|
|
|
|
------------------------------------------------ |
|
|
๐ ENVIRONMENTAL IMPACT ANALYSIS |
|
|
------------------------------------------------ |
|
|
โข Target Habitat: {habitat} |
|
|
|
|
|
โ ๏ธ STRESS INDICATORS: |
|
|
โข Water Stress: {water_disturbance}/100 |
|
|
(High levels indicate pollution or drought risk) |
|
|
โข Land Disturbance: {land_disturbance}/100 |
|
|
(Reflects habitat fragmentation or loss) |
|
|
โข Noise Pollution: {noise_level}/100 |
|
|
(Impacts communication and breeding patterns) |
|
|
""" |
|
|
|
|
|
final_output = summary_text + analysis_section |
|
|
|
|
|
|
|
|
gbif_url = f"https://api.gbif.org/v1/occurrence/search?scientificName={species_name}&limit=300" |
|
|
coords = [] |
|
|
try: |
|
|
gbif_res = requests.get(gbif_url).json() |
|
|
results = gbif_res.get("results", []) |
|
|
for r in results: |
|
|
if r.get("decimalLatitude") and r.get("decimalLongitude"): |
|
|
coords.append({"lat": r.get("decimalLatitude"), "lon": r.get("decimalLongitude")}) |
|
|
except: |
|
|
pass |
|
|
|
|
|
if coords: |
|
|
df = pd.DataFrame(coords) |
|
|
fig = px.scatter_mapbox(df, lat="lat", lon="lon", zoom=1, height=350) |
|
|
fig.update_layout(mapbox_style="open-street-map", margin={"r":0,"t":0,"l":0,"b":0}) |
|
|
else: |
|
|
fig = px.scatter_mapbox(pd.DataFrame({"lat":[], "lon":[]}), lat="lat", lon="lon", zoom=0) |
|
|
fig.update_layout(mapbox_style="open-street-map", margin={"r":0,"t":0,"l":0,"b":0}) |
|
|
|
|
|
|
|
|
filename = "BioVigilus_Report.txt" |
|
|
with open(filename, "w", encoding="utf-8") as f: |
|
|
f.write(f"=== BioVigilus Project Report ===\n{final_output}") |
|
|
|
|
|
return final_output, fig, filename |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vibrant_css = """ |
|
|
<style> |
|
|
.gradio-container { |
|
|
background: linear-gradient(135deg, #004d40 0%, #2e7d32 100%) !important; |
|
|
} |
|
|
#main-title { |
|
|
color: #ffffff !important; |
|
|
font-family: sans-serif; |
|
|
font-weight: 800; |
|
|
font-size: 2.5rem; |
|
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3); |
|
|
text-align: center; |
|
|
margin-bottom: 5px; |
|
|
} |
|
|
#sub-title { |
|
|
color: #a5d6a7 !important; |
|
|
font-size: 1.2rem; |
|
|
text-align: center; |
|
|
margin-bottom: 25px; |
|
|
font-family: sans-serif; |
|
|
} |
|
|
.custom-card { |
|
|
background: #ffffff !important; |
|
|
padding: 25px !important; |
|
|
border-radius: 12px !important; |
|
|
box-shadow: 0 10px 30px rgba(0,0,0,0.2) !important; |
|
|
border: none !important; |
|
|
} |
|
|
/* Button - Gradient Green */ |
|
|
button.primary { |
|
|
background: linear-gradient(90deg, #1b5e20 0%, #2e7d32 100%) !important; |
|
|
color: white !important; |
|
|
font-size: 1.1rem !important; |
|
|
border-radius: 8px !important; |
|
|
} |
|
|
</style> |
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
|
|
|
gr.HTML(vibrant_css) |
|
|
|
|
|
gr.HTML(""" |
|
|
<div id="main-title">๐ฟ BioVigilus</div> |
|
|
<div id="sub-title">Advanced Biodiversity & Environmental Stress Analyzer</div> |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
|
|
|
with gr.Column(elem_classes="custom-card"): |
|
|
gr.Markdown("### ๐ Species Configuration") |
|
|
species_name = gr.Textbox( |
|
|
label="Scientific Name", |
|
|
placeholder="e.g. Panthera tigris", |
|
|
value="Panthera tigris" |
|
|
) |
|
|
|
|
|
habitat = gr.Dropdown( |
|
|
["Tropical Rainforest", "Savanna", "Desert", "Wetlands", "Urban", "Marine"], |
|
|
label="Habitat Environment", |
|
|
value="Tropical Rainforest" |
|
|
) |
|
|
|
|
|
gr.Markdown("---") |
|
|
gr.Markdown("### โ ๏ธ Environmental Stressors") |
|
|
|
|
|
water = gr.Slider(0, 100, value=25, label="Water Pollution Level") |
|
|
land = gr.Slider(0, 100, value=65, label="Land Degradation") |
|
|
noise = gr.Slider(0, 100, value=30, label="Noise Pollution (dB)") |
|
|
|
|
|
analyze_btn = gr.Button("๐ Run Analysis", variant="primary") |
|
|
|
|
|
|
|
|
with gr.Column(elem_classes="custom-card"): |
|
|
gr.Markdown("### ๐ Analysis Results") |
|
|
|
|
|
|
|
|
out_summary = gr.Textbox( |
|
|
label="Ecological Summary & Impact Report", |
|
|
lines=12, |
|
|
interactive=False |
|
|
) |
|
|
|
|
|
out_map = gr.Plot(label="Global Occurrence Map") |
|
|
out_file = gr.File(label="๐ฅ Download Full Report") |
|
|
|
|
|
analyze_btn.click( |
|
|
process_species_data, |
|
|
inputs=[species_name, habitat, water, land, noise], |
|
|
outputs=[out_summary, out_map, out_file] |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |