1+ # Copyright 2025 Ben Chapman
2+ #
3+ # This file is part of The EV Finder.
4+ #
5+ # The EV Finder is free software: you can redistribute it and/or modify it under the
6+ # terms of the GNU General Public License as published by the Free Software Foundation,
7+ # either version 3 of the License, or (at your option) any later version.
8+ #
9+ # The EV Finder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10+ # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+ # See the GNU General Public License for more details.
12+ #
13+ # You should have received a copy of the GNU General Public License along with The EV Finder.
14+ # If not, see <https://www.gnu.org/licenses/>.
15+
116from fastapi import APIRouter , Depends , Request
217
318from src .libs .common_query_params import CommonInventoryQueryParams
4- from src .libs .responses import error_response , send_response
519from src .libs .http import AsyncHTTPClient
20+ from src .libs .responses import error_response , send_response
621
722router = APIRouter (prefix = "/api" )
823verify_ssl = True
924chevrolet_base_url = "https://www.chevrolet.com/chevrolet/shopping/api"
25+ error_message = "An error occurred with the Chevrolet inventory service"
1026
1127
1228@router .get ("/inventory/chevrolet" )
1329async def get_chevrolet_inventory (
1430 req : Request , common_params : CommonInventoryQueryParams = Depends ()
1531) -> dict :
16- """A description of what's unique about the logic for this manufacturer's API"""
17-
1832 headers = {
1933 "User-Agent" : req .headers .get ("User-Agent" ),
2034 "referer" : "https://www.chevrolet.com/shopping/inventory/search" ,
@@ -37,36 +51,53 @@ async def get_chevrolet_inventory(
3751 "pagination" : {"size" : 100 },
3852 }
3953
54+ facets_post_data = {
55+ "filters" : {
56+ "year" : {"values" : [str (common_params .year )]},
57+ "model" : {"values" : [common_params .model .lower ()]},
58+ "geo" : {"zipCode" : common_params .zip , "radius" : common_params .radius },
59+ }
60+ }
61+
4062 async with AsyncHTTPClient (
4163 base_url = chevrolet_base_url ,
4264 timeout_value = 30.0 ,
4365 ) as http :
44- g = await http .post (
66+ i = await http .post (
4567 uri = "/aec-cp-discovery-api/p/v1/vehicles/search" ,
4668 headers = headers ,
4769 post_data = inventory_post_data ,
4870 )
49-
71+ # Some Chevrolet vehicle detail is accessible through a separate API endpoint.
72+ # Making that call here, and will combine with the inventory results later.
73+ f = await http .post (
74+ uri = "/aec-cp-discovery-api/p/v1/vehicles/facets" ,
75+ headers = headers ,
76+ post_data = facets_post_data ,
77+ )
5078 try :
51- data = g .json ()
79+ inventory = i .json ()
80+ facets = f .json ()
5281 except ValueError :
5382 return error_response (
54- error_message = f"An error occurred with the Chevrolet inventory service: { g .text } "
83+ error_message = f"An error occurred with the Chevrolet inventory service: { i .text } "
5584 )
5685
57- error_message = "An error occurred with the Chevrolet inventory service"
86+ # Add vehicle facets to the inventory response
87+ inventory ["facets" ] = facets
88+
5889 try :
59- data ["data" ]["hits" ]
90+ inventory ["data" ]["hits" ]
6091 return send_response (
61- response_data = data ,
92+ response_data = inventory ,
6293 cache_control_age = 3600 ,
6394 )
6495 except KeyError :
6596 try :
66- data ["errorDetails" ]["key" ]
97+ inventory ["errorDetails" ]["key" ]
6798 return send_response (response_data = {})
6899 except Exception :
69- return error_response (error_message = error_message , error_data = data )
100+ return error_response (error_message = error_message , error_data = inventory )
70101
71102
72103@router .get ("/vin/chevrolet" )
0 commit comments