Skip to content

Commit d985364

Browse files
authored
feat(freefloating): add support for freefloating nearby API (#89)
Changelog: * Add support for freefloating nearby APIs * Add tests
1 parent 1613f8f commit d985364

File tree

6 files changed

+513
-0
lines changed

6 files changed

+513
-0
lines changed
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
from typing import Any, Dict, Optional, Sequence, Tuple
2+
3+
from navitia_client.client.apis.api_base_client import ApiBaseClient
4+
from navitia_client.entities.free_floating import FreeFloating
5+
from navitia_client.entities.pagination import Pagination
6+
7+
8+
class FreefloatingsNearbyApiClient(ApiBaseClient):
9+
"""
10+
A client class to interact with the Navitia API for fetching nearby free-floating vehicles.
11+
12+
See https://doc.navitia.io/#freefloatings-nearby-api
13+
14+
Methods
15+
-------
16+
_get_freefloatings_nearby(
17+
url: str, filters: dict
18+
) -> Tuple[Sequence[FreeFloating], Pagination]:
19+
Retrieves free-floating vehicles from the Navitia API based on provided URL and filters.
20+
21+
list_freefloatings_nearby(
22+
region_id: str,
23+
lon: float,
24+
lat: float,
25+
distance: int = 500,
26+
type: Optional[Sequence[str]] = None,
27+
count: int = 10,
28+
) -> Tuple[Sequence[FreeFloating], Pagination]:
29+
Retrieves free-floating vehicles near coordinates in a specific region from the Navitia API.
30+
31+
list_freefloatings_nearby_with_resource_path(
32+
region_id: str,
33+
resource_path: str,
34+
distance: int = 500,
35+
type: Optional[Sequence[str]] = None,
36+
count: int = 10,
37+
) -> Tuple[Sequence[FreeFloating], Pagination]:
38+
Retrieves free-floating vehicles near a specific resource path in a region from the Navitia API.
39+
40+
list_freefloatings_nearby_by_coordinates(
41+
region_lon: float,
42+
region_lat: float,
43+
lon: float,
44+
lat: float,
45+
distance: int = 500,
46+
type: Optional[Sequence[str]] = None,
47+
count: int = 10,
48+
) -> Tuple[Sequence[FreeFloating], Pagination]:
49+
Retrieves free-floating vehicles near coordinates, navitia guesses the region from coordinates.
50+
51+
list_freefloatings_nearby_by_coordinates_only(
52+
lon: float,
53+
lat: float,
54+
distance: int = 500,
55+
type: Optional[Sequence[str]] = None,
56+
count: int = 10,
57+
) -> Tuple[Sequence[FreeFloating], Pagination]:
58+
Retrieves free-floating vehicles near coordinates without any region id.
59+
"""
60+
61+
def _get_freefloatings_nearby(
62+
self, url: str, filters: dict
63+
) -> Tuple[Sequence[FreeFloating], Pagination]:
64+
"""
65+
Retrieves free-floating vehicles from the Navitia API based on provided URL and filters.
66+
67+
Parameters:
68+
url (str): The URL for the API request.
69+
filters (dict): Filters to apply to the API request.
70+
71+
Returns:
72+
Tuple[Sequence[FreeFloating], Pagination]: A tuple containing sequences of FreeFloating objects and Pagination object.
73+
"""
74+
results = self.get_navitia_api(url + self._generate_filter_query(filters))
75+
free_floatings = [
76+
FreeFloating.from_payload(data) for data in results.json()["free_floatings"]
77+
]
78+
pagination = Pagination.from_payload(results.json()["pagination"])
79+
return free_floatings, pagination
80+
81+
def list_freefloatings_nearby(
82+
self,
83+
region_id: str,
84+
lon: float,
85+
lat: float,
86+
distance: int = 500,
87+
type: Optional[Sequence[str]] = None,
88+
count: int = 10,
89+
) -> Tuple[Sequence[FreeFloating], Pagination]:
90+
"""
91+
Retrieves free-floating vehicles near coordinates in a specific region from the Navitia API.
92+
93+
This service provides access to nearby shared mobility options (such as bikes,
94+
scooters, or cars) based on user-provided coordinates.
95+
96+
Parameters:
97+
region_id (str): The region ID (coverage identifier).
98+
lon (float): The longitude coordinate.
99+
lat (float): The latitude coordinate.
100+
distance (int): Search radius in meters. Defaults to 500.
101+
type (Optional[Sequence[str]]): The type of shared mobility vehicles to return (e.g., bike, scooter, car).
102+
count (int): Maximum number of results to return. Defaults to 10.
103+
104+
Returns:
105+
Tuple[Sequence[FreeFloating], Pagination]: A tuple containing sequences of FreeFloating objects and Pagination object.
106+
107+
Note:
108+
This feature requires a specific configuration from a freefloating data service provider.
109+
Therefore, this service is not available by default.
110+
"""
111+
request_url = f"{self.base_navitia_url}/coverage/{region_id}/coords/{lon};{lat}/freefloatings_nearby"
112+
113+
filters: Dict[str, Any] = {
114+
"distance": distance,
115+
"count": count,
116+
}
117+
118+
if type:
119+
filters["type[]"] = type
120+
121+
return self._get_freefloatings_nearby(request_url, filters)
122+
123+
def list_freefloatings_nearby_with_resource_path(
124+
self,
125+
region_id: str,
126+
resource_path: str,
127+
distance: int = 500,
128+
type: Optional[Sequence[str]] = None,
129+
count: int = 10,
130+
) -> Tuple[Sequence[FreeFloating], Pagination]:
131+
"""
132+
Retrieves free-floating vehicles near a specific resource path in a region from the Navitia API.
133+
134+
This service provides access to nearby shared mobility options (such as bikes,
135+
scooters, or cars) near a specific resource (stop area, address, etc.).
136+
137+
Parameters:
138+
region_id (str): The region ID (coverage identifier).
139+
resource_path (str): The resource path (e.g., 'stop_areas/stop_area:XXX').
140+
distance (int): Search radius in meters. Defaults to 500.
141+
type (Optional[Sequence[str]]): The type of shared mobility vehicles to return (e.g., bike, scooter, car).
142+
count (int): Maximum number of results to return. Defaults to 10.
143+
144+
Returns:
145+
Tuple[Sequence[FreeFloating], Pagination]: A tuple containing sequences of FreeFloating objects and Pagination object.
146+
147+
Note:
148+
This feature requires a specific configuration from a freefloating data service provider.
149+
Therefore, this service is not available by default.
150+
"""
151+
request_url = f"{self.base_navitia_url}/coverage/{region_id}/{resource_path}/freefloatings_nearby"
152+
153+
filters: Dict[str, Any] = {
154+
"distance": distance,
155+
"count": count,
156+
}
157+
158+
if type:
159+
filters["type[]"] = type
160+
161+
return self._get_freefloatings_nearby(request_url, filters)
162+
163+
def list_freefloatings_nearby_by_coordinates(
164+
self,
165+
region_lon: float,
166+
region_lat: float,
167+
lon: float,
168+
lat: float,
169+
distance: int = 500,
170+
type: Optional[Sequence[str]] = None,
171+
count: int = 10,
172+
) -> Tuple[Sequence[FreeFloating], Pagination]:
173+
"""
174+
Retrieves free-floating vehicles near coordinates, navitia guesses the region from coordinates.
175+
176+
This service provides access to nearby shared mobility options (such as bikes,
177+
scooters, or cars) based on user-provided coordinates. Navitia will automatically
178+
determine the region based on the provided region coordinates.
179+
180+
Parameters:
181+
region_lon (float): The longitude coordinate for region identification.
182+
region_lat (float): The latitude coordinate for region identification.
183+
lon (float): The longitude coordinate for the search center.
184+
lat (float): The latitude coordinate for the search center.
185+
distance (int): Search radius in meters. Defaults to 500.
186+
type (Optional[Sequence[str]]): The type of shared mobility vehicles to return (e.g., bike, scooter, car).
187+
count (int): Maximum number of results to return. Defaults to 10.
188+
189+
Returns:
190+
Tuple[Sequence[FreeFloating], Pagination]: A tuple containing sequences of FreeFloating objects and Pagination object.
191+
192+
Note:
193+
This feature requires a specific configuration from a freefloating data service provider.
194+
Therefore, this service is not available by default.
195+
"""
196+
request_url = f"{self.base_navitia_url}/coverage/{region_lon};{region_lat}/coords/{lon};{lat}/freefloatings_nearby"
197+
198+
filters: Dict[str, Any] = {
199+
"distance": distance,
200+
"count": count,
201+
}
202+
203+
if type:
204+
filters["type[]"] = type
205+
206+
return self._get_freefloatings_nearby(request_url, filters)
207+
208+
def list_freefloatings_nearby_by_coordinates_only(
209+
self,
210+
lon: float,
211+
lat: float,
212+
distance: int = 500,
213+
type: Optional[Sequence[str]] = None,
214+
count: int = 10,
215+
) -> Tuple[Sequence[FreeFloating], Pagination]:
216+
"""
217+
Retrieves free-floating vehicles near coordinates without any region id.
218+
219+
This service provides access to nearby shared mobility options (such as bikes,
220+
scooters, or cars) based on user-provided coordinates. This method does not require
221+
a region ID; Navitia will automatically determine the appropriate region.
222+
223+
Parameters:
224+
lon (float): The longitude coordinate.
225+
lat (float): The latitude coordinate.
226+
distance (int): Search radius in meters. Defaults to 500.
227+
type (Optional[Sequence[str]]): The type of shared mobility vehicles to return (e.g., bike, scooter, car).
228+
count (int): Maximum number of results to return. Defaults to 10.
229+
230+
Returns:
231+
Tuple[Sequence[FreeFloating], Pagination]: A tuple containing sequences of FreeFloating objects and Pagination object.
232+
233+
Note:
234+
This feature requires a specific configuration from a freefloating data service provider.
235+
Therefore, this service is not available by default.
236+
"""
237+
request_url = f"{self.base_navitia_url}/coord/{lon};{lat}/freefloatings_nearby"
238+
239+
filters: Dict[str, Any] = {
240+
"distance": distance,
241+
"count": count,
242+
}
243+
244+
if type:
245+
filters["type[]"] = type
246+
247+
return self._get_freefloatings_nearby(request_url, filters)

navitia_client/client/navitia_client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
from navitia_client.client.apis.datasets_apis import DatasetsApiClient
77
from navitia_client.client.apis.departure_apis import DepartureApiClient
88
from navitia_client.client.apis.equipment_report_apis import EquipmentReportsApiClient
9+
from navitia_client.client.apis.freefloatings_nearby_apis import (
10+
FreefloatingsNearbyApiClient,
11+
)
912
from navitia_client.client.apis.inverted_geocoding_apis import (
1013
InvertedGeocodingApiClient,
1114
)
@@ -106,6 +109,8 @@ class NavitiaClient:
106109
Get an instance of TrafficReportsApiClient for accessing traffic reports-related endpoints.
107110
equipment_reports -> EquipmentReportsApiClient:
108111
Get an instance of EquipmentReportsApiClient for accessing equipment reports-related endpoints.
112+
freefloatings_nearby -> FreefloatingsNearbyApiClient:
113+
Get an instance of FreefloatingsNearbyApiClient for accessing freefloatings nearby-related endpoints.
109114
journeys -> JourneyApiClient:
110115
Get an instance of JourneyApiClient for accessing journey-related endpoints.
111116
isochrones -> IsochronesApiClient:
@@ -290,6 +295,13 @@ def equipment_reports(self) -> EquipmentReportsApiClient:
290295
auth_token=self.auth_token, base_navitia_url=self.base_navitia_url
291296
)
292297

298+
@property
299+
def freefloatings_nearby(self) -> FreefloatingsNearbyApiClient:
300+
"""Get an instance of FreefloatingsNearbyApiClient for accessing nearby free-floating vehicle endpoints."""
301+
return FreefloatingsNearbyApiClient(
302+
auth_token=self.auth_token, base_navitia_url=self.base_navitia_url
303+
)
304+
293305
@property
294306
def journeys(self) -> JourneyApiClient:
295307
"""Get an instance of JourneyApiClient for accessing journey-related endpoints."""
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from dataclasses import dataclass
2+
from typing import Dict, Any, Optional
3+
4+
from .coord import Coord
5+
6+
7+
@dataclass
8+
class FreeFloating:
9+
"""
10+
Represents a free-floating shared mobility vehicle (bike, scooter, car, etc.).
11+
12+
Attributes:
13+
public_id: Public identifier of the vehicle
14+
provider_name: Name of the service provider
15+
id: Identifier of the vehicle
16+
type: Type of vehicle (bike, scooter, car, etc.)
17+
propulsion: Type of propulsion (electric, human, etc.)
18+
battery: Battery level in percentage (0-100)
19+
distance: Distance from the search point in meters
20+
deeplink: Deep link URL to the provider's app
21+
coord: Coordinates of the vehicle
22+
"""
23+
24+
public_id: str
25+
provider_name: str
26+
id: str
27+
type: str
28+
propulsion: Optional[str] = None
29+
battery: Optional[int] = None
30+
distance: Optional[int] = None
31+
deeplink: Optional[str] = None
32+
coord: Optional[Coord] = None
33+
34+
@classmethod
35+
def from_payload(cls, data: Dict[str, Any]) -> "FreeFloating":
36+
"""
37+
Create a FreeFloating instance from API payload data.
38+
39+
Parameters:
40+
data: Dictionary containing free floating data from the API
41+
42+
Returns:
43+
FreeFloating: An instance of FreeFloating
44+
"""
45+
coord = None
46+
if "coord" in data:
47+
coord = Coord.from_payload(data["coord"])
48+
49+
return cls(
50+
public_id=data.get("public_id", ""),
51+
provider_name=data.get("provider_name", ""),
52+
id=data.get("id", ""),
53+
type=data.get("type", ""),
54+
propulsion=data.get("propulsion"),
55+
battery=data.get("battery"),
56+
distance=data.get("distance"),
57+
deeplink=data.get("deeplink"),
58+
coord=coord,
59+
)

0 commit comments

Comments
 (0)