import requests from typing import Tuple, Optional, Dict, Any class CamptocampAPI: """ A Python wrapper for the Camptocamp.org REST API v6. Supports querying outings, routes, waypoints, and more. """ BASE_URL = "https://api.camptocamp.org" def __init__(self, language: str = "en") -> None: """ Initialize the API client. Args: language (str): Language code for results ('en', 'fr', etc.). """ self.language = language def _request(self, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]: """ Internal method to send a GET request to the Camptocamp API. Args: endpoint (str): API endpoint (e.g., "/outings"). params (Dict): Dictionary of query parameters. Returns: Dict: Parsed JSON response. """ params["pl"] = self.language url = f"{self.BASE_URL}{endpoint}" response = requests.get(url, params=params) response.raise_for_status() return response.json() def get_recent_outings( self, bbox: Tuple[float, float, float, float], date_range: Optional[Tuple[str, str]] = None, activity: Optional[str] = None, limit: int = 10, ) -> Dict[str, Any]: """ Get recent outings around a specific location and date. Args: bbox (Tuple[float, float, float, float]): Bounding box as (west, south, east, north). date_range (Optional[Tuple[str, str]]): Date range (start, end) in YYYY-MM-DD format. activity (Optional[str]): Activity filter (e.g., "climbing", "hiking"). limit (int): Max number of results. Returns: Dict: API response containing outings. """ params = { "bbox": ",".join(map(str, bbox)), "limit": limit, "orderby": "-date", } if date_range: params["date"] = f"{date_range[0]},{date_range[1]}" if activity: params["act"] = activity return self._request("/outings", params) def search_routes_by_activity( self, bbox: Tuple[float, float, float, float], activity: str, limit: int = 10, ) -> Dict[str, Any]: """ Search for routes in a given area and activity type. Args: bbox (Tuple[float, float, float, float]): Bounding box as (west, south, east, north). activity (str): Activity filter (e.g., "rock_climbing"). limit (int): Max number of results. Returns: Dict: API response containing route data. """ params = { "bbox": ",".join(map(str, bbox)), "act": activity, "limit": limit, "orderby": "-date", } return self._request("/routes", params) def get_route_details(self, route_id: int) -> Dict[str, Any]: """ Retrieve full route information by its ID. Args: route_id (int): Camptocamp route ID. Returns: Dict: Full route document with metadata and description. """ return self._request(f"/routes/{route_id}/{self.language}", {}) def search_waypoints( self, bbox: Tuple[float, float, float, float], limit: int = 10, ) -> Dict[str, Any]: """ Get waypoints (e.g., huts, summits) within a given area. Args: bbox (Tuple[float, float, float, float]): Bounding box as (west, south, east, north). limit (int): Max number of results. Returns: Dict: API response with waypoint data. """ params = { "bbox": ",".join(map(str, bbox)), "limit": limit, } return self._request("/waypoints", params)