motorbay-client 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- motorbay_client-0.1.0/.gitignore +6 -0
- motorbay_client-0.1.0/PKG-INFO +50 -0
- motorbay_client-0.1.0/README.md +33 -0
- motorbay_client-0.1.0/motorbay/__init__.py +118 -0
- motorbay_client-0.1.0/motorbay_client/__init__.py +8 -0
- motorbay_client-0.1.0/motorbay_client/api/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/account/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/account/get_account_usage.py +210 -0
- motorbay_client-0.1.0/motorbay_client/api/blocking_reasons/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/blocking_reasons/get_blocking_reason.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/blocking_reasons/list_blocking_reasons.py +260 -0
- motorbay_client-0.1.0/motorbay_client/api/blocking_reasons/list_vehicle_blocking_reasons.py +284 -0
- motorbay_client-0.1.0/motorbay_client/api/colors/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/colors/get_color.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/colors/list_colors.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/dataset/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/dataset/get_dataset.py +202 -0
- motorbay_client-0.1.0/motorbay_client/api/designation_types/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/designation_types/get_designation_type.py +248 -0
- motorbay_client-0.1.0/motorbay_client/api/designation_types/list_designation_types.py +282 -0
- motorbay_client-0.1.0/motorbay_client/api/emission_standards/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/emission_standards/get_emission_standard.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/emission_standards/list_emission_standards.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/equipment/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/equipment/get_equipment.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/equipment/list_equipment.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/equipment/list_vehicle_equipment.py +269 -0
- motorbay_client-0.1.0/motorbay_client/api/fuel_types/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/fuel_types/get_fuel_type.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/fuel_types/list_fuel_types.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/fuel_types/list_vehicle_fuel_types.py +280 -0
- motorbay_client-0.1.0/motorbay_client/api/kinds/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/kinds/get_kind.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/kinds/list_kinds.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/leasing_periods/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/leasing_periods/list_vehicle_leasing_periods.py +276 -0
- motorbay_client-0.1.0/motorbay_client/api/makes/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/makes/get_make.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/makes/list_makes.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/models/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/models/get_model.py +235 -0
- motorbay_client-0.1.0/motorbay_client/api/models/list_models.py +276 -0
- motorbay_client-0.1.0/motorbay_client/api/permits/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/permits/get_permit_type.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/permits/list_permit_types.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/permits/list_vehicle_permits.py +280 -0
- motorbay_client-0.1.0/motorbay_client/api/statistics/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/statistics/get_vehicle_statistics.py +446 -0
- motorbay_client-0.1.0/motorbay_client/api/usages/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/usages/get_usage.py +222 -0
- motorbay_client-0.1.0/motorbay_client/api/usages/list_usages.py +256 -0
- motorbay_client-0.1.0/motorbay_client/api/usages/list_vehicle_secondary_usages.py +269 -0
- motorbay_client-0.1.0/motorbay_client/api/variants/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/variants/get_variant.py +248 -0
- motorbay_client-0.1.0/motorbay_client/api/variants/list_variants.py +289 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicle_check/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicle_check/check_vehicle.py +238 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicle_check/check_vehicle_by_plate.py +249 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicle_check/check_vehicle_by_vin.py +238 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/__init__.py +1 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle.py +268 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_by_plate.py +296 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_by_plate_or_vin.py +284 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_by_vin.py +268 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_calculated.py +238 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_engine.py +226 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_environmental_information.py +230 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_inspection.py +230 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/get_vehicle_technical_details.py +226 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/list_vehicles.py +497 -0
- motorbay_client-0.1.0/motorbay_client/api/vehicles/lookup_vehicles_by_plates.py +270 -0
- motorbay_client-0.1.0/motorbay_client/client.py +271 -0
- motorbay_client-0.1.0/motorbay_client/errors.py +14 -0
- motorbay_client-0.1.0/motorbay_client/models/__init__.py +165 -0
- motorbay_client-0.1.0/motorbay_client/models/account_usage_response.py +182 -0
- motorbay_client-0.1.0/motorbay_client/models/batch_plate_error.py +100 -0
- motorbay_client-0.1.0/motorbay_client/models/batch_plate_result.py +182 -0
- motorbay_client-0.1.0/motorbay_client/models/batch_plates_request.py +100 -0
- motorbay_client-0.1.0/motorbay_client/models/batch_plates_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/blocking_reason_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/dataset_response.py +119 -0
- motorbay_client-0.1.0/motorbay_client/models/equipment_response.py +119 -0
- motorbay_client-0.1.0/motorbay_client/models/fixed_connection_permit_response.py +101 -0
- motorbay_client-0.1.0/motorbay_client/models/fuel_type_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/get_vehicle_by_plate_include_item.py +19 -0
- motorbay_client-0.1.0/motorbay_client/models/get_vehicle_by_plate_or_vin_include_item.py +19 -0
- motorbay_client-0.1.0/motorbay_client/models/get_vehicle_by_vin_include_item.py +19 -0
- motorbay_client-0.1.0/motorbay_client/models/get_vehicle_include_item.py +19 -0
- motorbay_client-0.1.0/motorbay_client/models/get_vehicle_statistics_registration_status.py +10 -0
- motorbay_client-0.1.0/motorbay_client/models/http_validation_problem_details.py +198 -0
- motorbay_client-0.1.0/motorbay_client/models/http_validation_problem_details_errors.py +76 -0
- motorbay_client-0.1.0/motorbay_client/models/leasing_period_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/list_vehicles_registration_status.py +10 -0
- motorbay_client-0.1.0/motorbay_client/models/list_vehicles_sort_by.py +14 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_metadata.py +129 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_blocking_reason_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_equipment_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_fuel_type_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_leasing_period_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_permit_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_permit_type_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_blocking_reason_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_color_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_designation_type_response.py +142 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_emission_standard_response.py +142 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_equipment_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_fuel_type_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_kind_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_make_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_model_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_usage_mapping_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_usage_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/pagination_response_of_vehicle_variant_response.py +141 -0
- motorbay_client-0.1.0/motorbay_client/models/permit_response.py +175 -0
- motorbay_client-0.1.0/motorbay_client/models/permit_type_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/problem_details.py +175 -0
- motorbay_client-0.1.0/motorbay_client/models/variable_combination_permit_response.py +116 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_age_response.py +96 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_age_until_response_type_1.py +8 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_blocking_reason_response.py +96 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_body_type_response.py +16 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_calculated_response.py +318 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_check_flag_code_response.py +17 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_check_flag_response.py +103 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_check_response.py +415 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_check_severity_response.py +9 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_color_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_condition_response.py +10 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_creation_source_response.py +10 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_designation_type_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_emission_standard_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_engine_information_response.py +248 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_environmental_information_response.py +257 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_equipment_response.py +109 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_fuel_type_response.py +180 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_inspection_report_response.py +167 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_inspection_report_result_response.py +12 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_inspection_report_status_response.py +7 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_inspection_report_type_response.py +11 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_kind_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_make_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_manufacturer_region_response_type_1.py +12 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_model_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_reference_response.py +96 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_registration_status_response.py +10 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_response.py +1172 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_statistics_group_response.py +302 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_statistics_response.py +124 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_status_response.py +19 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_technical_details_response.py +777 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_usage_mapping_response.py +94 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_usage_response.py +94 -0
- motorbay_client-0.1.0/motorbay_client/models/vehicle_variant_response.py +95 -0
- motorbay_client-0.1.0/motorbay_client/types.py +53 -0
- motorbay_client-0.1.0/pyproject.toml +36 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: motorbay-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the Motorbay API: Danish vehicle data from Motorstyrelsen's public weekly extract. Generated from the OpenAPI document.
|
|
5
|
+
Project-URL: Homepage, https://motorbay.app
|
|
6
|
+
Project-URL: Documentation, https://app.motorbay.app/en/docs
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: api,client,denmark,dmr,motorbay,motorregister,vehicle
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Typing :: Typed
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Requires-Dist: attrs>=22.2.0
|
|
14
|
+
Requires-Dist: httpx<0.29.0,>=0.23.0
|
|
15
|
+
Requires-Dist: python-dateutil>=2.8.0
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# motorbay-client
|
|
19
|
+
|
|
20
|
+
Python client for the Motorbay API (Danish vehicle data from Motorstyrelsen's
|
|
21
|
+
public weekly extract). `motorbay` is the small wrapper you import.
|
|
22
|
+
`motorbay_client` holds the models, generated by openapi-python-client from the
|
|
23
|
+
API's OpenAPI document. Python 3.10+.
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pip install motorbay-client
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from motorbay import MotorbayApiError, MotorbayClient
|
|
31
|
+
|
|
32
|
+
with MotorbayClient(api_key="mbk_live_...") as motorbay:
|
|
33
|
+
try:
|
|
34
|
+
vehicle = motorbay.lookup_vehicle("AB12345", include=["engine", "inspection"])
|
|
35
|
+
print(vehicle.make.name, vehicle.registration_number)
|
|
36
|
+
except MotorbayApiError as e:
|
|
37
|
+
if e.code == "VehicleNotFound":
|
|
38
|
+
print("No such vehicle")
|
|
39
|
+
elif e.status == 429:
|
|
40
|
+
print(f"Retry in {e.retry_after}s")
|
|
41
|
+
else:
|
|
42
|
+
raise
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Setup and tests (offline, httpx.MockTransport):
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
uv venv .venv && uv pip install -p .venv -r requirements-dev.txt
|
|
49
|
+
.venv/bin/python -m pytest -q
|
|
50
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# motorbay-client
|
|
2
|
+
|
|
3
|
+
Python client for the Motorbay API (Danish vehicle data from Motorstyrelsen's
|
|
4
|
+
public weekly extract). `motorbay` is the small wrapper you import.
|
|
5
|
+
`motorbay_client` holds the models, generated by openapi-python-client from the
|
|
6
|
+
API's OpenAPI document. Python 3.10+.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pip install motorbay-client
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from motorbay import MotorbayApiError, MotorbayClient
|
|
14
|
+
|
|
15
|
+
with MotorbayClient(api_key="mbk_live_...") as motorbay:
|
|
16
|
+
try:
|
|
17
|
+
vehicle = motorbay.lookup_vehicle("AB12345", include=["engine", "inspection"])
|
|
18
|
+
print(vehicle.make.name, vehicle.registration_number)
|
|
19
|
+
except MotorbayApiError as e:
|
|
20
|
+
if e.code == "VehicleNotFound":
|
|
21
|
+
print("No such vehicle")
|
|
22
|
+
elif e.status == 429:
|
|
23
|
+
print(f"Retry in {e.retry_after}s")
|
|
24
|
+
else:
|
|
25
|
+
raise
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Setup and tests (offline, httpx.MockTransport):
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
uv venv .venv && uv pip install -p .venv -r requirements-dev.txt
|
|
32
|
+
.venv/bin/python -m pytest -q
|
|
33
|
+
```
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Thin, hand-written wrapper over the generated ``motorbay_client`` package.
|
|
2
|
+
|
|
3
|
+
``motorbay_client`` is generated by openapi-python-client from ../openapi/v1.json
|
|
4
|
+
(scripts/generate-all.sh). This module is not generated.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from collections.abc import Iterable
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import httpx
|
|
13
|
+
|
|
14
|
+
from motorbay_client.api.vehicles import (
|
|
15
|
+
get_vehicle_by_plate,
|
|
16
|
+
get_vehicle_by_plate_or_vin,
|
|
17
|
+
get_vehicle_by_vin,
|
|
18
|
+
)
|
|
19
|
+
from motorbay_client.models.vehicle_response import VehicleResponse
|
|
20
|
+
|
|
21
|
+
__all__ = ["DEFAULT_BASE_URL", "MotorbayApiError", "MotorbayClient", "VehicleResponse"]
|
|
22
|
+
|
|
23
|
+
DEFAULT_BASE_URL = "https://api.motorbay.app"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class MotorbayApiError(Exception):
|
|
27
|
+
"""A problem+json error answer from the API."""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
status: int,
|
|
32
|
+
code: str | None = None,
|
|
33
|
+
title: str | None = None,
|
|
34
|
+
detail: str | None = None,
|
|
35
|
+
request_id: str | None = None,
|
|
36
|
+
retry_after: int | None = None,
|
|
37
|
+
body: Any = None,
|
|
38
|
+
) -> None:
|
|
39
|
+
super().__init__(detail or title or f"Motorbay API answered {status}")
|
|
40
|
+
self.status = status
|
|
41
|
+
self.code = code
|
|
42
|
+
self.title = title
|
|
43
|
+
self.detail = detail
|
|
44
|
+
self.request_id = request_id
|
|
45
|
+
#: Seconds from the Retry-After header, set on 429 and 503.
|
|
46
|
+
self.retry_after = retry_after
|
|
47
|
+
self.body = body
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class MotorbayClient:
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
api_key: str,
|
|
54
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
55
|
+
*,
|
|
56
|
+
timeout: float = 30.0,
|
|
57
|
+
transport: httpx.BaseTransport | None = None,
|
|
58
|
+
) -> None:
|
|
59
|
+
if not api_key:
|
|
60
|
+
raise ValueError("api_key is required")
|
|
61
|
+
self._http = httpx.Client(
|
|
62
|
+
base_url=base_url.rstrip("/"),
|
|
63
|
+
headers={"X-Api-Key": api_key, "Accept": "application/json, application/problem+json"},
|
|
64
|
+
timeout=timeout,
|
|
65
|
+
transport=transport,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def close(self) -> None:
|
|
69
|
+
self._http.close()
|
|
70
|
+
|
|
71
|
+
def __enter__(self) -> MotorbayClient:
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
def __exit__(self, *exc: object) -> None:
|
|
75
|
+
self.close()
|
|
76
|
+
|
|
77
|
+
def lookup_vehicle(self, plate_or_vin: str, include: Iterable[str] | None = None) -> VehicleResponse:
|
|
78
|
+
"""GET /v1/vehicles/lookup/{plateOrVin}: a plate or a VIN, with optional include parts."""
|
|
79
|
+
return self._vehicle(get_vehicle_by_plate_or_vin._get_kwargs(plate_or_vin), include)
|
|
80
|
+
|
|
81
|
+
def get_vehicle_by_plate(self, plate: str, include: Iterable[str] | None = None) -> VehicleResponse:
|
|
82
|
+
return self._vehicle(get_vehicle_by_plate._get_kwargs(plate), include)
|
|
83
|
+
|
|
84
|
+
def get_vehicle_by_vin(self, vin: str, include: Iterable[str] | None = None) -> VehicleResponse:
|
|
85
|
+
return self._vehicle(get_vehicle_by_vin._get_kwargs(vin), include)
|
|
86
|
+
|
|
87
|
+
def _vehicle(self, kwargs: dict[str, Any], include: Iterable[str] | None) -> VehicleResponse:
|
|
88
|
+
params = dict(kwargs.get("params") or {})
|
|
89
|
+
parts = [getattr(p, "value", p) for p in include or ()]
|
|
90
|
+
if parts:
|
|
91
|
+
params["include"] = ",".join(parts)
|
|
92
|
+
response = self._http.request(kwargs["method"], kwargs["url"], params=params)
|
|
93
|
+
if response.is_success:
|
|
94
|
+
return VehicleResponse.from_dict(response.json())
|
|
95
|
+
raise _to_error(response)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _to_error(response: httpx.Response) -> MotorbayApiError:
|
|
99
|
+
try:
|
|
100
|
+
body = response.json()
|
|
101
|
+
except ValueError:
|
|
102
|
+
body = None
|
|
103
|
+
data = body if isinstance(body, dict) else {}
|
|
104
|
+
|
|
105
|
+
def text(key: str) -> str | None:
|
|
106
|
+
value = data.get(key)
|
|
107
|
+
return value if isinstance(value, str) else None
|
|
108
|
+
|
|
109
|
+
retry_header = (response.headers.get("Retry-After") or "").strip()
|
|
110
|
+
return MotorbayApiError(
|
|
111
|
+
status=response.status_code,
|
|
112
|
+
code=text("code"),
|
|
113
|
+
title=text("title"),
|
|
114
|
+
detail=text("detail"),
|
|
115
|
+
request_id=text("requestId") or response.headers.get("X-Request-Id"),
|
|
116
|
+
retry_after=int(retry_header) if retry_header.isdigit() else None,
|
|
117
|
+
body=body,
|
|
118
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
""" Contains methods for accessing the API """
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
""" Contains endpoint functions for accessing the API """
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any, cast
|
|
3
|
+
from urllib.parse import quote
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ...client import AuthenticatedClient, Client
|
|
8
|
+
from ...types import Response, UNSET
|
|
9
|
+
from ... import errors
|
|
10
|
+
|
|
11
|
+
from ...models.account_usage_response import AccountUsageResponse
|
|
12
|
+
from ...models.problem_details import ProblemDetails
|
|
13
|
+
from typing import cast
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _get_kwargs(
|
|
18
|
+
|
|
19
|
+
) -> dict[str, Any]:
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
_kwargs: dict[str, Any] = {
|
|
27
|
+
"method": "get",
|
|
28
|
+
"url": "/v1/usage",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
return _kwargs
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> AccountUsageResponse | ProblemDetails | None:
|
|
37
|
+
if response.status_code == 200:
|
|
38
|
+
response_200 = AccountUsageResponse.from_dict(response.json())
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
return response_200
|
|
43
|
+
|
|
44
|
+
if response.status_code == 401:
|
|
45
|
+
response_401 = ProblemDetails.from_dict(response.json())
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
return response_401
|
|
50
|
+
|
|
51
|
+
if response.status_code == 402:
|
|
52
|
+
response_402 = ProblemDetails.from_dict(response.json())
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
return response_402
|
|
57
|
+
|
|
58
|
+
if response.status_code == 429:
|
|
59
|
+
response_429 = ProblemDetails.from_dict(response.json())
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
return response_429
|
|
64
|
+
|
|
65
|
+
if response.status_code == 500:
|
|
66
|
+
response_500 = ProblemDetails.from_dict(response.json())
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
return response_500
|
|
71
|
+
|
|
72
|
+
if response.status_code == 503:
|
|
73
|
+
response_503 = ProblemDetails.from_dict(response.json())
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
return response_503
|
|
78
|
+
|
|
79
|
+
if client.raise_on_unexpected_status:
|
|
80
|
+
raise errors.UnexpectedStatus(response.status_code, response.content)
|
|
81
|
+
else:
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[AccountUsageResponse | ProblemDetails]:
|
|
86
|
+
return Response(
|
|
87
|
+
status_code=HTTPStatus(response.status_code),
|
|
88
|
+
content=response.content,
|
|
89
|
+
headers=response.headers,
|
|
90
|
+
parsed=_parse_response(client=client, response=response),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def sync_detailed(
|
|
95
|
+
*,
|
|
96
|
+
client: AuthenticatedClient | Client,
|
|
97
|
+
|
|
98
|
+
) -> Response[AccountUsageResponse | ProblemDetails]:
|
|
99
|
+
""" Get this month's usage
|
|
100
|
+
|
|
101
|
+
Returns the account's usage this calendar month (UTC): requests counted, the plan's included
|
|
102
|
+
requests, the hard limit and what remains of it (null on paid plans, which have none), and the
|
|
103
|
+
requests counted with the API key that asks. Only answered (2xx) requests count toward the plan, and
|
|
104
|
+
a batch counts the plates it found. This call is free: it does not count toward the plan. It counts
|
|
105
|
+
toward the per-minute rate limit like every request.
|
|
106
|
+
|
|
107
|
+
Raises:
|
|
108
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
109
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
Response[AccountUsageResponse | ProblemDetails]
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
kwargs = _get_kwargs(
|
|
117
|
+
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
response = client.get_httpx_client().request(
|
|
121
|
+
**kwargs,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
return _build_response(client=client, response=response)
|
|
125
|
+
|
|
126
|
+
def sync(
|
|
127
|
+
*,
|
|
128
|
+
client: AuthenticatedClient | Client,
|
|
129
|
+
|
|
130
|
+
) -> AccountUsageResponse | ProblemDetails | None:
|
|
131
|
+
""" Get this month's usage
|
|
132
|
+
|
|
133
|
+
Returns the account's usage this calendar month (UTC): requests counted, the plan's included
|
|
134
|
+
requests, the hard limit and what remains of it (null on paid plans, which have none), and the
|
|
135
|
+
requests counted with the API key that asks. Only answered (2xx) requests count toward the plan, and
|
|
136
|
+
a batch counts the plates it found. This call is free: it does not count toward the plan. It counts
|
|
137
|
+
toward the per-minute rate limit like every request.
|
|
138
|
+
|
|
139
|
+
Raises:
|
|
140
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
141
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
AccountUsageResponse | ProblemDetails
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
return sync_detailed(
|
|
149
|
+
client=client,
|
|
150
|
+
|
|
151
|
+
).parsed
|
|
152
|
+
|
|
153
|
+
async def asyncio_detailed(
|
|
154
|
+
*,
|
|
155
|
+
client: AuthenticatedClient | Client,
|
|
156
|
+
|
|
157
|
+
) -> Response[AccountUsageResponse | ProblemDetails]:
|
|
158
|
+
""" Get this month's usage
|
|
159
|
+
|
|
160
|
+
Returns the account's usage this calendar month (UTC): requests counted, the plan's included
|
|
161
|
+
requests, the hard limit and what remains of it (null on paid plans, which have none), and the
|
|
162
|
+
requests counted with the API key that asks. Only answered (2xx) requests count toward the plan, and
|
|
163
|
+
a batch counts the plates it found. This call is free: it does not count toward the plan. It counts
|
|
164
|
+
toward the per-minute rate limit like every request.
|
|
165
|
+
|
|
166
|
+
Raises:
|
|
167
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
168
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
Response[AccountUsageResponse | ProblemDetails]
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
kwargs = _get_kwargs(
|
|
176
|
+
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
response = await client.get_async_httpx_client().request(
|
|
180
|
+
**kwargs
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
return _build_response(client=client, response=response)
|
|
184
|
+
|
|
185
|
+
async def asyncio(
|
|
186
|
+
*,
|
|
187
|
+
client: AuthenticatedClient | Client,
|
|
188
|
+
|
|
189
|
+
) -> AccountUsageResponse | ProblemDetails | None:
|
|
190
|
+
""" Get this month's usage
|
|
191
|
+
|
|
192
|
+
Returns the account's usage this calendar month (UTC): requests counted, the plan's included
|
|
193
|
+
requests, the hard limit and what remains of it (null on paid plans, which have none), and the
|
|
194
|
+
requests counted with the API key that asks. Only answered (2xx) requests count toward the plan, and
|
|
195
|
+
a batch counts the plates it found. This call is free: it does not count toward the plan. It counts
|
|
196
|
+
toward the per-minute rate limit like every request.
|
|
197
|
+
|
|
198
|
+
Raises:
|
|
199
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
200
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
AccountUsageResponse | ProblemDetails
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
return (await asyncio_detailed(
|
|
208
|
+
client=client,
|
|
209
|
+
|
|
210
|
+
)).parsed
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
""" Contains endpoint functions for accessing the API """
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any, cast
|
|
3
|
+
from urllib.parse import quote
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ...client import AuthenticatedClient, Client
|
|
8
|
+
from ...types import Response, UNSET
|
|
9
|
+
from ... import errors
|
|
10
|
+
|
|
11
|
+
from ...models.blocking_reason_response import BlockingReasonResponse
|
|
12
|
+
from ...models.problem_details import ProblemDetails
|
|
13
|
+
from typing import cast
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _get_kwargs(
|
|
18
|
+
id: int | str,
|
|
19
|
+
|
|
20
|
+
) -> dict[str, Any]:
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
_kwargs: dict[str, Any] = {
|
|
28
|
+
"method": "get",
|
|
29
|
+
"url": "/v1/blocking-reasons/{id}".format(id=quote(str(id), safe=""),),
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
return _kwargs
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> BlockingReasonResponse | ProblemDetails | None:
|
|
38
|
+
if response.status_code == 200:
|
|
39
|
+
response_200 = BlockingReasonResponse.from_dict(response.json())
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
return response_200
|
|
44
|
+
|
|
45
|
+
if response.status_code == 401:
|
|
46
|
+
response_401 = ProblemDetails.from_dict(response.json())
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
return response_401
|
|
51
|
+
|
|
52
|
+
if response.status_code == 402:
|
|
53
|
+
response_402 = ProblemDetails.from_dict(response.json())
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
return response_402
|
|
58
|
+
|
|
59
|
+
if response.status_code == 404:
|
|
60
|
+
response_404 = ProblemDetails.from_dict(response.json())
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
return response_404
|
|
65
|
+
|
|
66
|
+
if response.status_code == 429:
|
|
67
|
+
response_429 = ProblemDetails.from_dict(response.json())
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
return response_429
|
|
72
|
+
|
|
73
|
+
if response.status_code == 500:
|
|
74
|
+
response_500 = ProblemDetails.from_dict(response.json())
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
return response_500
|
|
79
|
+
|
|
80
|
+
if response.status_code == 503:
|
|
81
|
+
response_503 = ProblemDetails.from_dict(response.json())
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
return response_503
|
|
86
|
+
|
|
87
|
+
if client.raise_on_unexpected_status:
|
|
88
|
+
raise errors.UnexpectedStatus(response.status_code, response.content)
|
|
89
|
+
else:
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[BlockingReasonResponse | ProblemDetails]:
|
|
94
|
+
return Response(
|
|
95
|
+
status_code=HTTPStatus(response.status_code),
|
|
96
|
+
content=response.content,
|
|
97
|
+
headers=response.headers,
|
|
98
|
+
parsed=_parse_response(client=client, response=response),
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def sync_detailed(
|
|
103
|
+
id: int | str,
|
|
104
|
+
*,
|
|
105
|
+
client: AuthenticatedClient | Client,
|
|
106
|
+
|
|
107
|
+
) -> Response[BlockingReasonResponse | ProblemDetails]:
|
|
108
|
+
""" Get a blocking reason
|
|
109
|
+
|
|
110
|
+
Retrieves a specific blocking reason by ID, such as Totalskadet køretøj or Mangel.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
id (int | str):
|
|
114
|
+
|
|
115
|
+
Raises:
|
|
116
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
117
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
Response[BlockingReasonResponse | ProblemDetails]
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
kwargs = _get_kwargs(
|
|
125
|
+
id=id,
|
|
126
|
+
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
response = client.get_httpx_client().request(
|
|
130
|
+
**kwargs,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
return _build_response(client=client, response=response)
|
|
134
|
+
|
|
135
|
+
def sync(
|
|
136
|
+
id: int | str,
|
|
137
|
+
*,
|
|
138
|
+
client: AuthenticatedClient | Client,
|
|
139
|
+
|
|
140
|
+
) -> BlockingReasonResponse | ProblemDetails | None:
|
|
141
|
+
""" Get a blocking reason
|
|
142
|
+
|
|
143
|
+
Retrieves a specific blocking reason by ID, such as Totalskadet køretøj or Mangel.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
id (int | str):
|
|
147
|
+
|
|
148
|
+
Raises:
|
|
149
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
150
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
BlockingReasonResponse | ProblemDetails
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
return sync_detailed(
|
|
158
|
+
id=id,
|
|
159
|
+
client=client,
|
|
160
|
+
|
|
161
|
+
).parsed
|
|
162
|
+
|
|
163
|
+
async def asyncio_detailed(
|
|
164
|
+
id: int | str,
|
|
165
|
+
*,
|
|
166
|
+
client: AuthenticatedClient | Client,
|
|
167
|
+
|
|
168
|
+
) -> Response[BlockingReasonResponse | ProblemDetails]:
|
|
169
|
+
""" Get a blocking reason
|
|
170
|
+
|
|
171
|
+
Retrieves a specific blocking reason by ID, such as Totalskadet køretøj or Mangel.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
id (int | str):
|
|
175
|
+
|
|
176
|
+
Raises:
|
|
177
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
178
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
Response[BlockingReasonResponse | ProblemDetails]
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
kwargs = _get_kwargs(
|
|
186
|
+
id=id,
|
|
187
|
+
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
response = await client.get_async_httpx_client().request(
|
|
191
|
+
**kwargs
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return _build_response(client=client, response=response)
|
|
195
|
+
|
|
196
|
+
async def asyncio(
|
|
197
|
+
id: int | str,
|
|
198
|
+
*,
|
|
199
|
+
client: AuthenticatedClient | Client,
|
|
200
|
+
|
|
201
|
+
) -> BlockingReasonResponse | ProblemDetails | None:
|
|
202
|
+
""" Get a blocking reason
|
|
203
|
+
|
|
204
|
+
Retrieves a specific blocking reason by ID, such as Totalskadet køretøj or Mangel.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
id (int | str):
|
|
208
|
+
|
|
209
|
+
Raises:
|
|
210
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
211
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
BlockingReasonResponse | ProblemDetails
|
|
215
|
+
"""
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
return (await asyncio_detailed(
|
|
219
|
+
id=id,
|
|
220
|
+
client=client,
|
|
221
|
+
|
|
222
|
+
)).parsed
|