vehiclesdb 0.2.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.
- vehiclesdb-0.2.0/CHANGELOG.md +70 -0
- vehiclesdb-0.2.0/CONTRACT.md +244 -0
- vehiclesdb-0.2.0/LICENSE +21 -0
- vehiclesdb-0.2.0/MANIFEST.in +4 -0
- vehiclesdb-0.2.0/NOTICE +16 -0
- vehiclesdb-0.2.0/PKG-INFO +406 -0
- vehiclesdb-0.2.0/README.md +373 -0
- vehiclesdb-0.2.0/fixtures/catalog/bus/makes.json +109 -0
- vehiclesdb-0.2.0/fixtures/catalog/bus/models.json +327 -0
- vehiclesdb-0.2.0/fixtures/catalog/car/makes.json +283 -0
- vehiclesdb-0.2.0/fixtures/catalog/car/models.json +23521 -0
- vehiclesdb-0.2.0/fixtures/catalog/moped/makes.json +61 -0
- vehiclesdb-0.2.0/fixtures/catalog/moped/models.json +609 -0
- vehiclesdb-0.2.0/fixtures/catalog/motorcycle/makes.json +35 -0
- vehiclesdb-0.2.0/fixtures/catalog/motorcycle/models.json +969 -0
- vehiclesdb-0.2.0/fixtures/catalog/truck/makes.json +103 -0
- vehiclesdb-0.2.0/fixtures/catalog/truck/models.json +1003 -0
- vehiclesdb-0.2.0/fixtures/catalog/van/makes.json +154 -0
- vehiclesdb-0.2.0/fixtures/catalog/van/models.json +3435 -0
- vehiclesdb-0.2.0/fixtures/dist/vehicles.json +7129 -0
- vehiclesdb-0.2.0/fixtures/manifest.json +81 -0
- vehiclesdb-0.2.0/pyproject.toml +75 -0
- vehiclesdb-0.2.0/setup.cfg +4 -0
- vehiclesdb-0.2.0/src/vehiclesdb/__init__.py +68 -0
- vehiclesdb-0.2.0/src/vehiclesdb/_labels.py +60 -0
- vehiclesdb-0.2.0/src/vehiclesdb/_normalize.py +19 -0
- vehiclesdb-0.2.0/src/vehiclesdb/_resolution.py +284 -0
- vehiclesdb-0.2.0/src/vehiclesdb/client.py +900 -0
- vehiclesdb-0.2.0/src/vehiclesdb/errors.py +114 -0
- vehiclesdb-0.2.0/src/vehiclesdb/models.py +230 -0
- vehiclesdb-0.2.0/src/vehiclesdb/py.typed +0 -0
- vehiclesdb-0.2.0/src/vehiclesdb.egg-info/PKG-INFO +406 -0
- vehiclesdb-0.2.0/src/vehiclesdb.egg-info/SOURCES.txt +39 -0
- vehiclesdb-0.2.0/src/vehiclesdb.egg-info/dependency_links.txt +1 -0
- vehiclesdb-0.2.0/src/vehiclesdb.egg-info/requires.txt +3 -0
- vehiclesdb-0.2.0/src/vehiclesdb.egg-info/top_level.txt +1 -0
- vehiclesdb-0.2.0/tests/helpers.py +114 -0
- vehiclesdb-0.2.0/tests/test_client.py +804 -0
- vehiclesdb-0.2.0/tests/test_dogfood.py +174 -0
- vehiclesdb-0.2.0/tests/test_full_release.py +148 -0
- vehiclesdb-0.2.0/tests/test_resolution.py +167 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `vehiclesdb` are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the package uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/). While the version is 0.x, a minor
|
|
6
|
+
release may change the API.
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - unreleased
|
|
9
|
+
|
|
10
|
+
Dogfooding fixes (VehiclesDB inside CarHey, 2026-11-10). The API changed, hence
|
|
11
|
+
the minor bump.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- `images()` now calls `GET /api/v1/vehicles/{kind}/{make}/{model}/images`.
|
|
16
|
+
0.1.0 called `/v1/...`, which the API does not serve, so every image call
|
|
17
|
+
failed.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Kind collisions** follow RESOLUTION.md §3a, the rule every VehiclesDB
|
|
22
|
+
surface now shares: lowest `mass_decile`, then van, car, bus, truck, moped,
|
|
23
|
+
motorcycle, then id. Unhinted "Iveco Daily" is now `van/iveco/daily`.
|
|
24
|
+
- Non-2xx API responses raise typed subclasses of `VehiclesDBApiError`:
|
|
25
|
+
`VehiclesDBAuthError` (401/403), `VehiclesDBPaymentRequiredError` (402),
|
|
26
|
+
`VehiclesDBNotFoundError` (404), `VehiclesDBRateLimitError` (429, with
|
|
27
|
+
`retry_after`). Every API error carries `code`. Timeouts raise
|
|
28
|
+
`VehiclesDBTimeoutError` (a `TransportError`).
|
|
29
|
+
- List fields (`aliases`, `forms`, `former_ids`) are `[]` when absent, not
|
|
30
|
+
`None`, matching the JS SDK and the gem.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- `by_id(id, follow=True, kinds=None)` and `successor(id)` for stored ids.
|
|
35
|
+
- `Resolution.confident`: not ambiguous and not a typo guess.
|
|
36
|
+
- `kinds=` on `resolve()`/`model_match()`/`by_id()`/`catalog()`: a hard kind
|
|
37
|
+
filter on every rung, ids included.
|
|
38
|
+
- `catalog(kind=, country=, kinds=)`: picker data for one market.
|
|
39
|
+
- `colors()`, `color_options()`, `color()`, `kind_label()`,
|
|
40
|
+
`body_type_label()` with English and Spanish labels.
|
|
41
|
+
- `Model.mass_decile`, `Model.registration_years` (a hint; `None` until the
|
|
42
|
+
release publishes it), `Make.former_slugs`; make resolution follows former
|
|
43
|
+
slugs (`former_make_slug:` in `via`).
|
|
44
|
+
- `KIND_PRECEDENCE`, `pick_collision`.
|
|
45
|
+
|
|
46
|
+
## [0.1.0] - 2026-11-09
|
|
47
|
+
|
|
48
|
+
First public release.
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- `VehiclesDB` client, with zero required dependencies, Python >= 3.9 support
|
|
53
|
+
and inline type annotations (`py.typed`).
|
|
54
|
+
- **Dataset mode** (default, no key): `makes()`, `models()`, `model()`,
|
|
55
|
+
`resolve()`, `model_match()`, `search()` and `dataset_version`, answered from
|
|
56
|
+
the published CC-BY dataset on jsDelivr. Releases can be pinned with
|
|
57
|
+
`version=`. The dataset is fetched lazily and memoized.
|
|
58
|
+
- **API mode**: `images()` (0.1.0 called the wrong path; fixed in 0.2.0),
|
|
59
|
+
authenticated with `api_key=`.
|
|
60
|
+
- Resolution implements the dataset's `RESOLUTION.md` (exact, former_id, fold,
|
|
61
|
+
alias, form, cleaned and fuzzy rungs, with ambiguity, alternates and an audit
|
|
62
|
+
trail), and passes `conformance/resolve.json` from release 2026.11.1.
|
|
63
|
+
- `attribution` / `attribution_html`: the CC-BY 4.0 notice.
|
|
64
|
+
- Pluggable transport, with `urllib` as the default and an optional `httpx`
|
|
65
|
+
adapter (`pip install "vehiclesdb[httpx]"`).
|
|
66
|
+
- Frozen dataclass models (`Make`, `Model`, `Resolution`) with `to_dict()`.
|
|
67
|
+
- `CONTRACT.md`: the cross-language SDK contract shared with the JS SDK and
|
|
68
|
+
the Ruby gem `vehicles`.
|
|
69
|
+
|
|
70
|
+
[0.1.0]: https://github.com/vehiclesdb/vehiclesdb-python/releases/tag/v0.1.0
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# The VehiclesDB SDK contract
|
|
2
|
+
|
|
3
|
+
This file is identical in [`vehiclesdb-js`](https://github.com/vehiclesdb/vehiclesdb-js)
|
|
4
|
+
(npm `@vehiclesdb/client`) and
|
|
5
|
+
[`vehiclesdb-python`](https://github.com/vehiclesdb/vehiclesdb-python)
|
|
6
|
+
(PyPI `vehiclesdb`). It is the normative description of what every VehiclesDB
|
|
7
|
+
client library does, and the reason the clients can be held to it.
|
|
8
|
+
|
|
9
|
+
Every SDK exists to put one thing into your codebase: the canonical vehicle id
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
kind/make_slug/model_slug e.g. car/volkswagen/golf
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Two requirements follow:
|
|
16
|
+
|
|
17
|
+
1. **The SDKs must agree.** If `resolve("vw golf")` returns
|
|
18
|
+
`car/volkswagen/golf` in Ruby, it returns `car/volkswagen/golf` in
|
|
19
|
+
JavaScript and in Python. Otherwise the id is three dialects, not a standard.
|
|
20
|
+
2. **The SDKs must work without an account.** Every client answers from the
|
|
21
|
+
published open dataset by default (**dataset mode**) and calls the hosted API
|
|
22
|
+
only where the API has something the dataset does not (**API mode**).
|
|
23
|
+
|
|
24
|
+
| | package | repository |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| Ruby | [`vehicles`](https://rubygems.org/gems/vehicles) | [vehiclesdb/vehicles](https://github.com/vehiclesdb/vehicles) — **the reference implementation**; its vocabulary is the one to match |
|
|
27
|
+
| JavaScript / TypeScript | [`@vehiclesdb/client`](https://www.npmjs.com/package/@vehiclesdb/client) | [vehiclesdb/vehiclesdb-js](https://github.com/vehiclesdb/vehiclesdb-js) |
|
|
28
|
+
| Python | [`vehiclesdb`](https://pypi.org/project/vehiclesdb/) | [vehiclesdb/vehiclesdb-python](https://github.com/vehiclesdb/vehiclesdb-python) |
|
|
29
|
+
| Dataset | CC-BY 4.0 | [vehiclesdb/vehiclesdb](https://github.com/vehiclesdb/vehiclesdb) (`SCHEMA.md`, `RESOLUTION.md`, `conformance/`) |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Dataset mode and API mode
|
|
34
|
+
|
|
35
|
+
| | dataset mode (default) | API mode |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| needs a key | no | yes |
|
|
38
|
+
| answers from | the published CC-BY dataset, `https://cdn.jsdelivr.net/gh/vehiclesdb/vehiclesdb@{version}` | `https://vehiclesdb.com/api/v1` |
|
|
39
|
+
| methods | `makes` `models` `model` `byId`/`by_id` `successor` `catalog` `modelMatch`/`model_match` `resolve` `search`, the colour/kind/body-type labels | `images` |
|
|
40
|
+
|
|
41
|
+
- **Dataset mode** reads the same release files the Ruby gem refreshes from,
|
|
42
|
+
so all three SDKs read the same bytes. Constructing a client makes no
|
|
43
|
+
request. The light dataset (`dist/vehicles.json`) is fetched once, lazily,
|
|
44
|
+
on the first question, and memoized. Only `model()` reads a second file,
|
|
45
|
+
`catalog/{kind}/models.json`, which carries the per-country popularity,
|
|
46
|
+
sources and crosswalks.
|
|
47
|
+
- **API mode** is used only by `images()`. Vehicle imagery is not part of the
|
|
48
|
+
open dataset, so there is no local answer to fall back to. Without a key the
|
|
49
|
+
method raises a configuration error naming the missing option. It never
|
|
50
|
+
returns a placeholder.
|
|
51
|
+
- `version` pins a release tag (for example `2026.11.1`); `latest` follows the
|
|
52
|
+
newest one. Pin it when answers must be reproducible.
|
|
53
|
+
- A result's `source` is `"dataset"` or `"api"`, so a caller can always see
|
|
54
|
+
which one answered.
|
|
55
|
+
|
|
56
|
+
### Surface
|
|
57
|
+
|
|
58
|
+
| method | returns | dataset-mode behaviour |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `makes(kind?)` | list of Make | filter the published make list |
|
|
61
|
+
| `models(make, kind?, body_type?)` | list of Model | alias-aware make lookup, then filter; an unknown make gives an empty list |
|
|
62
|
+
| `model(id)` / `model(kind, make, slug)` | Model or null | id lookup that honours `former_ids` |
|
|
63
|
+
| `modelMatch(make, model, …)` / `model_match(make, model, …)` | Resolution or null | the pair resolution ladder |
|
|
64
|
+
| `resolve(text, kind?, country?)` | Resolution or null | the text resolution ladder |
|
|
65
|
+
| `search(query, kind?, limit=25)` | ranked list of Model | local ranked substring match |
|
|
66
|
+
| `byId(id, follow=true, kinds?)` / `by_id(...)` | Model (light) or null | exact id, then (with `follow`) the record a former id moved to; no catalog fetch |
|
|
67
|
+
| `successor(id)` | id string or null | the live id for a stored id: itself, its successor, or null |
|
|
68
|
+
| `catalog(kind?, kinds?, country?)` | list of `{make, models[]}` | picker data: name-ordered, filtered by kind(s) and register evidence in `country` |
|
|
69
|
+
| `colors(locale?)`, `colorOptions`/`color_options(locale?)`, `color(query, locale?)` | palette | the 14-colour palette; names in `en`/`es`; `color()` reads slugs and English/Spanish names |
|
|
70
|
+
| `kindLabel`/`kind_label(kind, locale?)`, `bodyTypeLabel`/`body_type_label(...)` | string or null | display labels in `en`/`es` |
|
|
71
|
+
| `images(id, color?, format?)` | the endpoint's JSON, verbatim | **API only** |
|
|
72
|
+
|
|
73
|
+
Endpoints that have not shipped (`stats`, `markets`, `plates`, `vin`,
|
|
74
|
+
`resolve/batch`) are deliberately **absent**. A method that throws "not
|
|
75
|
+
implemented yet" invites integrations onto semantics that do not exist yet.
|
|
76
|
+
Methods are added when their endpoint is live.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Field naming
|
|
81
|
+
|
|
82
|
+
Field names come from the published schema
|
|
83
|
+
([`SCHEMA.md`](https://github.com/vehiclesdb/vehiclesdb/blob/main/SCHEMA.md)).
|
|
84
|
+
Do not invent fields and do not rename them. The only change allowed is
|
|
85
|
+
language-idiomatic casing: `bodyType` / `formerIds` / `globalDecile` in
|
|
86
|
+
JavaScript, `body_type` / `former_ids` / `global_decile` in Python. The
|
|
87
|
+
*concepts* and the *values* must match.
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
Make { id, slug, name, kinds[], countries[]?, aliases[], former_slugs[] }
|
|
91
|
+
Model { id, make_id, make_name, slug, name, kind, body_type|body_types[],
|
|
92
|
+
aliases[], forms[], former_ids[], global_decile|popularity{},
|
|
93
|
+
mass_decile, registration_years{first,last}?, availability[],
|
|
94
|
+
regions[] }
|
|
95
|
+
Resolution { id?, kind?, make?, model?, method, confidence, confident, source,
|
|
96
|
+
match, alternates[], candidates[], ambiguous, via[] }
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- `id` is always the canonical `kind/make_slug/model_slug`.
|
|
100
|
+
- Array fields are `[]` when the release has none (never null), in every SDK.
|
|
101
|
+
- `registration_years` is a **hint**: the first and last first-registration
|
|
102
|
+
year seen in the registers, not production years, never a validation bound.
|
|
103
|
+
Null until the release publishes it.
|
|
104
|
+
- `confident` = not ambiguous and `method` is not `fuzzy`: the recommended
|
|
105
|
+
threshold for applying an answer to stored data without a human.
|
|
106
|
+
- `body_type`/`body_types` and `global_decile`/`popularity` are the two
|
|
107
|
+
published projections. The light `dist/vehicles.json` carries the primary
|
|
108
|
+
body type and the global decile, while the per-kind catalog carries the full
|
|
109
|
+
list and the per-country ranks. `model()` fills in both.
|
|
110
|
+
- `availability` is a list of country codes in the light file and a list of
|
|
111
|
+
`{country, evidence, source}` objects in the catalog. These are the files'
|
|
112
|
+
own shapes. They agree by construction.
|
|
113
|
+
- The schema's **absence rule** is binding: an absent optional field means
|
|
114
|
+
"not catalogued yet", never "no".
|
|
115
|
+
- The `images()` response is returned verbatim, snake_case included. It is a
|
|
116
|
+
documented wire contract (<https://vehiclesdb.com/api>).
|
|
117
|
+
|
|
118
|
+
Two shape traps:
|
|
119
|
+
|
|
120
|
+
- **`Make.countries` is absent in dataset mode.** `dist/vehicles.json` does not
|
|
121
|
+
carry it; only `catalog/{kind}/makes.json` does. Leave it null rather than
|
|
122
|
+
deriving it, because a derived value could disagree with the catalog.
|
|
123
|
+
- **`former_ids` are fully kind-qualified** (`car/alfa-romeo/1750gtv`) even in
|
|
124
|
+
`catalog/{kind}/models.json`, where the record's own `id` is only
|
|
125
|
+
`make/model`. Rebuild the three-part id before comparing them.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Resolution
|
|
130
|
+
|
|
131
|
+
`resolve(text, …)` and `modelMatch(make, model, …)` / `model_match(...)`
|
|
132
|
+
implement
|
|
133
|
+
[`RESOLUTION.md`](https://github.com/vehiclesdb/vehiclesdb/blob/main/RESOLUTION.md)
|
|
134
|
+
in the dataset repo, and must pass its language-neutral conformance suite,
|
|
135
|
+
[`conformance/resolve.json`](https://github.com/vehiclesdb/vehiclesdb/blob/main/conformance/resolve.json).
|
|
136
|
+
Knowledge comes only from published data, with no hardcoded vehicle names.
|
|
137
|
+
|
|
138
|
+
| order | method | confidence | evidence |
|
|
139
|
+
|---|---|---|---|
|
|
140
|
+
| 1 | `exact` | 1.00 | verbatim canonical id (text only) |
|
|
141
|
+
| 2 | `former_id` | 0.98 | full published former id (text only) |
|
|
142
|
+
| 3 | `fold` | 0.97 | normalized name/slug, spacing-blind name, then `Serie N` → `N Series` |
|
|
143
|
+
| 4 | `alias` | 0.93 | published model alias within the make |
|
|
144
|
+
| 5 | `form` | 0.92 | curated spelling within the make |
|
|
145
|
+
| 6 | `alias` | 0.90 | whole text is a unique alias, including name collision checks |
|
|
146
|
+
| 7 | `cleaned` | 0.90 | peel leading new-fillers / complete make echoes, retry 3–5 |
|
|
147
|
+
| 8 | `fuzzy` | 0.80 | bounded word-by-word edit distance |
|
|
148
|
+
|
|
149
|
+
Confidences label rungs. They are not probabilities.
|
|
150
|
+
|
|
151
|
+
- **Normalization:** NFKD, then remove `Mn` marks, lowercase, collapse runs of
|
|
152
|
+
non-`[a-z0-9]` to single spaces, and trim. Pair lookups also keep raw
|
|
153
|
+
lowercase equality, for native-script aliases.
|
|
154
|
+
- **Uniqueness:** spacing-blind names, aliases and forms must identify one
|
|
155
|
+
nameplate (make + model slug; kind variants count as one). Aliases and forms
|
|
156
|
+
are make-scoped. An ambiguous rung stops the ladder.
|
|
157
|
+
- **Kind variants** (RESOLUTION.md §3a): when a rung's winning candidates are
|
|
158
|
+
one nameplate in several kinds, pick by lowest `mass_decile` (unranked
|
|
159
|
+
last), then kind precedence van, car, bus, truck, moped, motorcycle, then id
|
|
160
|
+
(ordinal). Only the records the rung matched compete. `kind` scopes the name
|
|
161
|
+
rungs (an explicit id still answers); `kinds` is a hard filter on every
|
|
162
|
+
rung, ids included (`[]` matches nothing); `country` restricts availability.
|
|
163
|
+
- **Make former slugs:** a make input equal to a published `former_slugs`
|
|
164
|
+
value lands on the successor make (`via` `former_make_slug:old→new`).
|
|
165
|
+
- **Typos** apply to human-shaped input only. Paths, underscores, `+`,
|
|
166
|
+
backslashes, edge or double hyphens and single-case hyphenated slugs disable
|
|
167
|
+
them for the whole text.
|
|
168
|
+
- Make typos use whole-string optimal string alignment: one edit for 4–5
|
|
169
|
+
characters, two from six. A tie between closest makes means no match.
|
|
170
|
+
- Model typos compare equal word counts with matching initials. A differing
|
|
171
|
+
word must have no digits and at least four letters. One edit is allowed per
|
|
172
|
+
word, or two from nine letters. A tie between nameplates is ambiguous;
|
|
173
|
+
a tie between kinds of one nameplate is a kind variant (above).
|
|
174
|
+
- A make typo caps the answer at `fuzzy` / 0.80, and a model typo never
|
|
175
|
+
stacks on top of it.
|
|
176
|
+
- **Result shape:** `id`, `kind`, `make`, `model`, `confidence`, `source`,
|
|
177
|
+
`method`, `match` (`{id, name, make:{id,name}, kind, confidence, method}`),
|
|
178
|
+
`alternates`, `candidates`, `ambiguous` and `via`, the audit trail (for
|
|
179
|
+
example `make_alias:vw→volkswagen` or `form:2008 allure→2008`). No match
|
|
180
|
+
returns null / `None`. An ambiguous result has a null `match`/`id`,
|
|
181
|
+
confidence 0 and the competing records in `alternates`. `matchedOn` /
|
|
182
|
+
`matched_on` is a deprecated alias of `method`.
|
|
183
|
+
|
|
184
|
+
Answers depend on the corpus. For example, `Rabbit` resolves to the Golf on the
|
|
185
|
+
capped test fixtures, but is ambiguous on a full release that also has a
|
|
186
|
+
`car/volkswagen/rabbit` record. What must never differ is two SDKs answering
|
|
187
|
+
over the same corpus.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Cross-language parity
|
|
192
|
+
|
|
193
|
+
The Ruby gem [`vehicles`](https://github.com/vehiclesdb/vehicles) is the
|
|
194
|
+
reference implementation. JavaScript and Python follow its vocabulary and its
|
|
195
|
+
answers, and parity is checked mechanically:
|
|
196
|
+
|
|
197
|
+
- **Shared fixtures.** Each repo carries `fixtures/`, a verbatim subset of a
|
|
198
|
+
real release (12 makes, 289 models, release `2026.07.6`) in the exact CDN
|
|
199
|
+
layout (`manifest.json`, `dist/vehicles.json`,
|
|
200
|
+
`catalog/{kind}/{makes,models}.json`). The two copies are
|
|
201
|
+
**byte-identical**. They are cut by `tools/make_fixtures.py` from a checkout
|
|
202
|
+
of the public dataset repo, never written by hand:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
git clone https://github.com/vehiclesdb/vehiclesdb ../vehiclesdb
|
|
206
|
+
git -C ../vehiclesdb checkout v2026.07.6
|
|
207
|
+
python3 tools/make_fixtures.py --data-repo ../vehiclesdb
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
After regenerating, copy `fixtures/` to the other SDK repo unchanged.
|
|
211
|
+
- **Conformance.** Both test suites run
|
|
212
|
+
[`conformance/resolve.json`](https://github.com/vehiclesdb/vehiclesdb/blob/main/conformance/resolve.json)
|
|
213
|
+
against a full release. The Ruby gem runs the same file.
|
|
214
|
+
- **Parity check.** `tools/parity_check.sh`, which is identical in both repos,
|
|
215
|
+
runs the same resolve and pair cases through both SDKs over the same bytes.
|
|
216
|
+
It fails on any difference in id, method, confidence, trail, ambiguity or
|
|
217
|
+
candidates. Run it with the other SDK checked out next to this one:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
bash tools/parity_check.sh # against fixtures/
|
|
221
|
+
bash tools/parity_check.sh ../vehiclesdb # against a full release
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
- **Offline tests.** No test may touch the network. The HTTP layer is
|
|
225
|
+
injected (a `fetch`-shaped function in JS, a transport callable in Python),
|
|
226
|
+
and the test transport raises on any URL it has no file for.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Attribution
|
|
231
|
+
|
|
232
|
+
The dataset is CC-BY 4.0, and **visible credit with a link is a condition of
|
|
233
|
+
the licence** (§3(a)). It is not optional. Every SDK documents the notice and
|
|
234
|
+
exposes it programmatically, so an integrator can render it without copying
|
|
235
|
+
prose:
|
|
236
|
+
|
|
237
|
+
> Vehicle data by [VehiclesDB](https://vehiclesdb.com)
|
|
238
|
+
|
|
239
|
+
Upstream register notices (KBA's `dl-de/by-2-0`, RDW's terms, Traficom's
|
|
240
|
+
CC-BY, and others) apply under every licence. See
|
|
241
|
+
[`ATTRIBUTION.md`](https://github.com/vehiclesdb/vehiclesdb/blob/main/ATTRIBUTION.md),
|
|
242
|
+
and link to it instead of paraphrasing a licence statement.
|
|
243
|
+
|
|
244
|
+
The SDK **code** is MIT.
|
vehiclesdb-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VehiclesDB
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
vehiclesdb-0.2.0/NOTICE
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
vehiclesdb
|
|
2
|
+
Code: MIT (see LICENSE). Data: CC-BY 4.0 (see below).
|
|
3
|
+
|
|
4
|
+
The MIT licence in LICENSE covers the CODE of this package only.
|
|
5
|
+
|
|
6
|
+
The vehicle DATA this package reads is a separate work under a separate
|
|
7
|
+
licence: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Free for
|
|
8
|
+
any use, including commercial. Visible credit with a link is a CONDITION of
|
|
9
|
+
that licence (§3(a)), not a courtesy:
|
|
10
|
+
|
|
11
|
+
Vehicle data by VehiclesDB (https://vehiclesdb.com)
|
|
12
|
+
|
|
13
|
+
Upstream register notices (KBA's dl-de/by-2-0, RDW's terms, Traficom's CC-BY,
|
|
14
|
+
and others) apply under every licence for this data, the commercial one
|
|
15
|
+
included. They are the registers' own terms, not VehiclesDB's to waive. See
|
|
16
|
+
https://github.com/vehiclesdb/vehiclesdb/blob/main/ATTRIBUTION.md
|