Max elevation
Browse files
app.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import logging
|
| 3 |
from camptocamp_api import CamptocampAPI
|
|
@@ -21,7 +23,66 @@ ACTIVITIES = [
|
|
| 21 |
]
|
| 22 |
|
| 23 |
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
logger.info(f"[Outings] Resolving location: {location}")
|
| 26 |
bbox = c2c.get_bbox_from_location(location)
|
| 27 |
if not bbox:
|
|
@@ -31,7 +92,7 @@ def get_recent_outings_by_location(location: str, start_date: Optional[str] = No
|
|
| 31 |
date_range = (start_date, end_date) if start_date and end_date else None
|
| 32 |
result = c2c.get_recent_outings(bbox, date_range, activity, limit)
|
| 33 |
logger.info(f"Returned {len(result.get('documents', []))} outings.")
|
| 34 |
-
return result
|
| 35 |
|
| 36 |
def search_routes_by_location(location: str, activity: str, limit: int = 10) -> dict:
|
| 37 |
logger.info(f"[Routes] Resolving location: {location}")
|
|
@@ -81,11 +142,16 @@ with gr.Blocks(title="Camptocamp MCP Server") as demo:
|
|
| 81 |
start = gr.Textbox(label="Start Date (YYYY-MM-DD)")
|
| 82 |
end = gr.Textbox(label="End Date (YYYY-MM-DD)")
|
| 83 |
act = gr.Dropdown(label="Activity", choices=ACTIVITIES, value="alpine_climbing")
|
| 84 |
-
limit = gr.Number(label="Result Limit", value=
|
|
|
|
|
|
|
| 85 |
out = gr.JSON()
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
with gr.Tab("🧗 Search Routes"):
|
| 91 |
rloc = gr.Textbox(label="Location (e.g. Alps)")
|
|
|
|
| 1 |
+
from dataclasses import dataclass
|
| 2 |
+
from typing import Optional, List
|
| 3 |
import gradio as gr
|
| 4 |
import logging
|
| 5 |
from camptocamp_api import CamptocampAPI
|
|
|
|
| 23 |
]
|
| 24 |
|
| 25 |
|
| 26 |
+
@dataclass
|
| 27 |
+
class SimplifiedOuting:
|
| 28 |
+
title: Optional[str]
|
| 29 |
+
condition_rating: Optional[str]
|
| 30 |
+
date_start: Optional[str]
|
| 31 |
+
date_end: Optional[str]
|
| 32 |
+
elevation_max: Optional[int]
|
| 33 |
+
global_rating: Optional[str]
|
| 34 |
+
equipment_rating: Optional[str]
|
| 35 |
+
rock_free_rating: Optional[str]
|
| 36 |
+
area_titles: List[str]
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def simplify_outings_response(
|
| 40 |
+
response: dict,
|
| 41 |
+
elevation_max_threshold: Optional[int] = None
|
| 42 |
+
) -> List[SimplifiedOuting]:
|
| 43 |
+
results = []
|
| 44 |
+
for doc in response.get("documents", []):
|
| 45 |
+
elevation = doc.get("elevation_max")
|
| 46 |
+
if elevation is None:
|
| 47 |
+
continue
|
| 48 |
+
elif elevation_max_threshold is not None and elevation is not None:
|
| 49 |
+
if elevation < elevation_max_threshold:
|
| 50 |
+
continue # filter it out
|
| 51 |
+
|
| 52 |
+
title = None
|
| 53 |
+
if doc.get("locales"):
|
| 54 |
+
title = doc["locales"][0].get("title")
|
| 55 |
+
|
| 56 |
+
area_titles = []
|
| 57 |
+
for area in doc.get("areas", []):
|
| 58 |
+
for loc in area.get("locales", []):
|
| 59 |
+
t = loc.get("title")
|
| 60 |
+
if t:
|
| 61 |
+
area_titles.append(t)
|
| 62 |
+
break
|
| 63 |
+
|
| 64 |
+
results.append(SimplifiedOuting(
|
| 65 |
+
title=title,
|
| 66 |
+
condition_rating=doc.get("condition_rating"),
|
| 67 |
+
date_start=doc.get("date_start"),
|
| 68 |
+
date_end=doc.get("date_end"),
|
| 69 |
+
elevation_max=elevation,
|
| 70 |
+
global_rating=doc.get("global_rating"),
|
| 71 |
+
equipment_rating=doc.get("equipment_rating"),
|
| 72 |
+
rock_free_rating=doc.get("rock_free_rating"),
|
| 73 |
+
area_titles=area_titles
|
| 74 |
+
))
|
| 75 |
+
return results
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def get_recent_outings_by_location(
|
| 79 |
+
location: str,
|
| 80 |
+
start_date: Optional[str] = None,
|
| 81 |
+
end_date: Optional[str] = None,
|
| 82 |
+
activity: Optional[str] = None,
|
| 83 |
+
limit: int = 10,
|
| 84 |
+
elevation_max_threshold: Optional[int] = 4000
|
| 85 |
+
) -> List[SimplifiedOuting]:
|
| 86 |
logger.info(f"[Outings] Resolving location: {location}")
|
| 87 |
bbox = c2c.get_bbox_from_location(location)
|
| 88 |
if not bbox:
|
|
|
|
| 92 |
date_range = (start_date, end_date) if start_date and end_date else None
|
| 93 |
result = c2c.get_recent_outings(bbox, date_range, activity, limit)
|
| 94 |
logger.info(f"Returned {len(result.get('documents', []))} outings.")
|
| 95 |
+
return simplify_outings_response(result, elevation_max_threshold=elevation_max_threshold)
|
| 96 |
|
| 97 |
def search_routes_by_location(location: str, activity: str, limit: int = 10) -> dict:
|
| 98 |
logger.info(f"[Routes] Resolving location: {location}")
|
|
|
|
| 142 |
start = gr.Textbox(label="Start Date (YYYY-MM-DD)")
|
| 143 |
end = gr.Textbox(label="End Date (YYYY-MM-DD)")
|
| 144 |
act = gr.Dropdown(label="Activity", choices=ACTIVITIES, value="alpine_climbing")
|
| 145 |
+
limit = gr.Number(label="Result Limit", value=30)
|
| 146 |
+
elev_slider = gr.Slider(label="Minimum maximal elevation (m)", minimum=0, maximum=4000, value=4000, step=100)
|
| 147 |
+
|
| 148 |
out = gr.JSON()
|
| 149 |
+
|
| 150 |
+
gr.Button("Get Outings").click(
|
| 151 |
+
get_recent_outings_by_location,
|
| 152 |
+
inputs=[loc, start, end, act, limit, elev_slider],
|
| 153 |
+
outputs=out
|
| 154 |
+
)
|
| 155 |
|
| 156 |
with gr.Tab("🧗 Search Routes"):
|
| 157 |
rloc = gr.Textbox(label="Location (e.g. Alps)")
|