File size: 3,881 Bytes
b2ff92e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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)