1515from vigobusapi .logger import logger
1616from .http_requester import http_request , ListOfTuples
1717
18- __all__ = ("GoogleMapRequest" , "get_map" )
18+ __all__ = ("GoogleMapRequest" , "GoogleStreetviewRequest" , " get_map" , "get_photo " )
1919
2020# TODO May refactor in package with different modules (at least split classes and logic)
2121
2222GOOGLE_MAPS_STATIC_API_URL = "https://maps.googleapis.com/maps/api/staticmap"
23+ GOOGLE_STREETVIEW_STATIC_API_URL = "https://maps.googleapis.com/maps/api/streetview"
2324
2425
2526class _GoogleMapsBaseRequest (BaseModel , ChecksumableClass ):
@@ -112,12 +113,17 @@ def checksum_hash(self):
112113 map_type : MapTypes
113114
114115
115- async def _request (url : str , params : Union [dict , ListOfTuples ]):
116+ class GoogleStreetviewRequest (_GoogleMapsBaseRequest ):
117+ pass
118+
119+
120+ async def _request (url : str , params : Union [dict , ListOfTuples ], expect_http_error : bool = False ):
116121 """HTTP requester for Google Maps API calls, automatically including the configured API key.
117122 Raises exception if the API Key is not configured.
118123
119124 :param url: URL for the Google API, WITHOUT query parameters
120125 :param params: query parameters
126+ :param expect_http_error: if True, raise_for_status=False and not_retry_400_errors=True
121127 """
122128 if not settings .enabled :
123129 raise Exception ("Google Maps API Key not set in settings" )
@@ -131,7 +137,9 @@ async def _request(url: str, params: Union[dict, ListOfTuples]):
131137 url = url ,
132138 method = "GET" ,
133139 params = params ,
134- retries = 1
140+ retries = 1 ,
141+ raise_for_status = not expect_http_error ,
142+ not_retry_400_errors = expect_http_error
135143 )
136144
137145
@@ -164,3 +172,29 @@ async def get_map(request: GoogleMapRequest) -> bytes:
164172 params .append (("markers" , tag_param ))
165173
166174 return (await _request (url = GOOGLE_MAPS_STATIC_API_URL , params = params )).content
175+
176+
177+ async def get_photo (request : GoogleStreetviewRequest ) -> Optional [bytes ]:
178+ """Get a static StreetView picture from the Google StreetView Static API. Return the acquired PNG picture as bytes.
179+ If the requested location does not have an available picture, returns None.
180+
181+ References:
182+ https://developers.google.com/maps/documentation/streetview/overview
183+ """
184+ logger .bind (streetview_request = request .dict ()).debug ("Requesting Google Static StreetView picture..." )
185+ # TODO cache loaded pictures
186+ # TODO Support specific parameters for tuning camera, if required
187+ params = [
188+ ("location" , request .location_str ),
189+ ("size" , request .size_str ),
190+ ("return_error_code" , "true" ),
191+ ("source" , "outdoor" )
192+ ]
193+
194+ response = await _request (GOOGLE_STREETVIEW_STATIC_API_URL , params = params , expect_http_error = True )
195+ if response .status_code == 404 :
196+ logger .debug ("No StreetView picture available for the request" )
197+ return None
198+
199+ response .raise_for_status ()
200+ return response .content
0 commit comments