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.
Files changed (41) hide show
  1. vehiclesdb-0.2.0/CHANGELOG.md +70 -0
  2. vehiclesdb-0.2.0/CONTRACT.md +244 -0
  3. vehiclesdb-0.2.0/LICENSE +21 -0
  4. vehiclesdb-0.2.0/MANIFEST.in +4 -0
  5. vehiclesdb-0.2.0/NOTICE +16 -0
  6. vehiclesdb-0.2.0/PKG-INFO +406 -0
  7. vehiclesdb-0.2.0/README.md +373 -0
  8. vehiclesdb-0.2.0/fixtures/catalog/bus/makes.json +109 -0
  9. vehiclesdb-0.2.0/fixtures/catalog/bus/models.json +327 -0
  10. vehiclesdb-0.2.0/fixtures/catalog/car/makes.json +283 -0
  11. vehiclesdb-0.2.0/fixtures/catalog/car/models.json +23521 -0
  12. vehiclesdb-0.2.0/fixtures/catalog/moped/makes.json +61 -0
  13. vehiclesdb-0.2.0/fixtures/catalog/moped/models.json +609 -0
  14. vehiclesdb-0.2.0/fixtures/catalog/motorcycle/makes.json +35 -0
  15. vehiclesdb-0.2.0/fixtures/catalog/motorcycle/models.json +969 -0
  16. vehiclesdb-0.2.0/fixtures/catalog/truck/makes.json +103 -0
  17. vehiclesdb-0.2.0/fixtures/catalog/truck/models.json +1003 -0
  18. vehiclesdb-0.2.0/fixtures/catalog/van/makes.json +154 -0
  19. vehiclesdb-0.2.0/fixtures/catalog/van/models.json +3435 -0
  20. vehiclesdb-0.2.0/fixtures/dist/vehicles.json +7129 -0
  21. vehiclesdb-0.2.0/fixtures/manifest.json +81 -0
  22. vehiclesdb-0.2.0/pyproject.toml +75 -0
  23. vehiclesdb-0.2.0/setup.cfg +4 -0
  24. vehiclesdb-0.2.0/src/vehiclesdb/__init__.py +68 -0
  25. vehiclesdb-0.2.0/src/vehiclesdb/_labels.py +60 -0
  26. vehiclesdb-0.2.0/src/vehiclesdb/_normalize.py +19 -0
  27. vehiclesdb-0.2.0/src/vehiclesdb/_resolution.py +284 -0
  28. vehiclesdb-0.2.0/src/vehiclesdb/client.py +900 -0
  29. vehiclesdb-0.2.0/src/vehiclesdb/errors.py +114 -0
  30. vehiclesdb-0.2.0/src/vehiclesdb/models.py +230 -0
  31. vehiclesdb-0.2.0/src/vehiclesdb/py.typed +0 -0
  32. vehiclesdb-0.2.0/src/vehiclesdb.egg-info/PKG-INFO +406 -0
  33. vehiclesdb-0.2.0/src/vehiclesdb.egg-info/SOURCES.txt +39 -0
  34. vehiclesdb-0.2.0/src/vehiclesdb.egg-info/dependency_links.txt +1 -0
  35. vehiclesdb-0.2.0/src/vehiclesdb.egg-info/requires.txt +3 -0
  36. vehiclesdb-0.2.0/src/vehiclesdb.egg-info/top_level.txt +1 -0
  37. vehiclesdb-0.2.0/tests/helpers.py +114 -0
  38. vehiclesdb-0.2.0/tests/test_client.py +804 -0
  39. vehiclesdb-0.2.0/tests/test_dogfood.py +174 -0
  40. vehiclesdb-0.2.0/tests/test_full_release.py +148 -0
  41. 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.
@@ -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.
@@ -0,0 +1,4 @@
1
+ # The sdist carries what it takes to run the offline test suite.
2
+ include CHANGELOG.md CONTRACT.md NOTICE
3
+ recursive-include tests *.py
4
+ recursive-include fixtures *.json
@@ -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