tickerdata 0.1.0__py3-none-any.whl

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.
tickerdata/reader.py ADDED
@@ -0,0 +1,99 @@
1
+ from copy import deepcopy
2
+ from importlib.resources import files
3
+ import json
4
+ import re
5
+
6
+
7
+ _IDENTIFIER = re.compile(r"[a-z][a-z0-9]*(?:-[a-z0-9]+)*")
8
+ _MIC = re.compile(r"[A-Z0-9]{4}")
9
+
10
+
11
+ def _read_json(name):
12
+ return json.loads(files("tickerdata").joinpath("data", name).read_text(encoding="utf-8"))
13
+
14
+
15
+ _manifest = _read_json("manifest.json")
16
+ _instruments_payload = _read_json("instruments.json")
17
+ _index_payload = _read_json("symbol-index.json")
18
+
19
+ if (
20
+ _manifest["schema_version"] != "4.0.0"
21
+ or _instruments_payload["schema_version"] != _manifest["schema_version"]
22
+ or _index_payload["schema_version"] != _manifest["schema_version"]
23
+ or _instruments_payload["data_version"] != _manifest["data_version"]
24
+ or _index_payload["data_version"] != _manifest["data_version"]
25
+ ):
26
+ raise RuntimeError("The embedded tickerdata snapshot has inconsistent versions")
27
+
28
+ _records = {record["id"]: record for record in _instruments_payload["instruments"]}
29
+ _entries_by_symbol = {}
30
+ for _entry in _index_payload["entries"]:
31
+ _entries_by_symbol.setdefault(_entry["symbol"], []).append(_entry)
32
+
33
+
34
+ class UnknownSymbolError(LookupError):
35
+ def __init__(self, symbol, mic, provider, include_inactive):
36
+ self.symbol = symbol
37
+ super().__init__(
38
+ "Unknown symbol {!r} (MIC={!r}, provider={!r}, active_only={})".format(
39
+ symbol, mic, provider, not include_inactive
40
+ )
41
+ )
42
+
43
+
44
+ class AmbiguousSymbolError(LookupError):
45
+ def __init__(self, symbol, candidates):
46
+ self.symbol = symbol
47
+ self.candidates = candidates
48
+ detail = ", ".join(
49
+ "{} ({})".format(item["instrument_id"], item["mic"] or "no MIC")
50
+ for item in candidates
51
+ )
52
+ super().__init__("Ambiguous symbol {!r}: {}".format(symbol, detail))
53
+
54
+
55
+ def lookup(symbol, *, mic=None, provider=None, include_inactive=True):
56
+ if not isinstance(symbol, str) or not symbol.strip():
57
+ raise TypeError("symbol must be a non-empty string")
58
+ normalized = symbol.strip().upper()
59
+ if mic is not None:
60
+ if not isinstance(mic, str):
61
+ raise TypeError("mic must be a string or None")
62
+ mic = mic.strip().upper()
63
+ if _MIC.fullmatch(mic) is None:
64
+ raise ValueError("mic must be a four-character MIC")
65
+ if provider is not None:
66
+ if not isinstance(provider, str):
67
+ raise TypeError("provider must be a string or None")
68
+ provider = provider.strip().lower()
69
+ if len(provider) > 100 or _IDENTIFIER.fullmatch(provider) is None:
70
+ raise ValueError("provider must be a lowercase identifier")
71
+ if not isinstance(include_inactive, bool):
72
+ raise TypeError("include_inactive must be a boolean")
73
+
74
+ candidates = {}
75
+ for entry in _entries_by_symbol.get(normalized, []):
76
+ record = _records.get(entry["instrument_id"])
77
+ if record is None:
78
+ raise RuntimeError(
79
+ "Snapshot index references missing instrument {}".format(entry["instrument_id"])
80
+ )
81
+ if mic is not None and entry["mic"] != mic:
82
+ continue
83
+ if provider is not None and entry["provider"] not in (None, provider):
84
+ continue
85
+ if not include_inactive and record["listing_status"] != "active":
86
+ continue
87
+ candidates[record["id"]] = record
88
+
89
+ if not candidates:
90
+ raise UnknownSymbolError(normalized, mic, provider, include_inactive)
91
+ if len(candidates) > 1:
92
+ raise AmbiguousSymbolError(
93
+ normalized,
94
+ [
95
+ {"instrument_id": identifier, "mic": candidates[identifier]["symbol"]["mic"]}
96
+ for identifier in sorted(candidates)
97
+ ],
98
+ )
99
+ return deepcopy(next(iter(candidates.values())))
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: tickerdata
3
+ Version: 0.1.0
4
+ Summary: Offline, versioned ticker metadata lookup
5
+ Author: tickerdata contributors
6
+ License-Expression: MIT AND ODC-By-1.0
7
+ Project-URL: Repository, https://github.com/udlrdotai/tickerdata
8
+ Keywords: ticker,symbol,metadata,offline
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE-MIT
14
+ License-File: LICENSE-ODC-BY
15
+ License-File: NOTICE.md
16
+ Dynamic: license-file
17
+
18
+ # tickerdata
19
+
20
+ Offline, versioned ticker metadata lookup for Python. The package contains a
21
+ fixed snapshot of reviewed metadata and never accesses the network.
22
+
23
+ ```python
24
+ from tickerdata import lookup
25
+
26
+ instrument = lookup(
27
+ "BRK-B",
28
+ mic="XNYS",
29
+ provider="yahoo",
30
+ include_inactive=False,
31
+ )
32
+ ```
33
+
34
+ `lookup` does not rewrite punctuation or guess between ambiguous listings.
35
+ Unknown and ambiguous queries raise `UnknownSymbolError` and
36
+ `AmbiguousSymbolError`.
37
+
38
+ This package provides metadata only. It does not provide market data, trading,
39
+ portfolio management, or investment advice.
40
+
41
+ The reader code is MIT licensed. Database rights in the maintained compilation
42
+ are licensed under ODC-By 1.0 subject to `NOTICE.md`; individual contents and
43
+ external materials may remain subject to their own terms.
@@ -0,0 +1,13 @@
1
+ tickerdata/__init__.py,sha256=MYcsglhQQUMyXn9ID4BmDrogjeUNp2ZWv4BHCfA_nhA,137
2
+ tickerdata/reader.py,sha256=iXplJqTjVYA7Ku9GNx8yQfjusN8QD-aqJuI4cOVz7mI,3768
3
+ tickerdata/data/instruments.json,sha256=yo4haed6E8wE8OakFAm2p3-nV4IzOEPZz-1d-UvIOzY,85971
4
+ tickerdata/data/manifest.json,sha256=BWedDXbVpNXQ8Co21mRqjXCwSzq3rxPKu5XPNc2c6DA,658
5
+ tickerdata/data/symbol-index.json,sha256=jyexys7H_qQ4dH-iN3xC9in_PYZcWqA-o5YMl3tscOY,10806
6
+ tickerdata/data/vocabulary.json,sha256=BtHR6FN9u_xyiUI8_RsQSHxh_GYdQ9V--pBqq1KstZ0,38305
7
+ tickerdata-0.1.0.dist-info/licenses/LICENSE-MIT,sha256=tbdwlRoRYcIX0Yx_k7Jc0Pll69nZxiyyWL_yOkDEKwg,1267
8
+ tickerdata-0.1.0.dist-info/licenses/LICENSE-ODC-BY,sha256=wBbrDc4y9WcKpTDHqMYdsvJ7WTfZbBPftovQw43gaec,275
9
+ tickerdata-0.1.0.dist-info/licenses/NOTICE.md,sha256=036AQCQE7gy-dO3RbtRNtDEtikt4LADcB5giFiBmrMg,1080
10
+ tickerdata-0.1.0.dist-info/METADATA,sha256=V1YTtsgQkkVyrpDhO-s3KRTPhsW3LFdPBy_GbK_H_2M,1359
11
+ tickerdata-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
12
+ tickerdata-0.1.0.dist-info/top_level.txt,sha256=j585Eymece4xgYEjfsDwH0fRnqZWgJa-oW2x77SOTWw,11
13
+ tickerdata-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,25 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tickerdata contributors
4
+
5
+ This license applies to the software code in this project. Data, vocabulary
6
+ content, suggestions, and third-party materials are excluded; see
7
+ docs/licensing.md for their separate terms.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ Open Data Commons Attribution License 1.0 (ODC-By-1.0)
2
+
3
+ Canonical license URI:
4
+
5
+ https://opendatacommons.org/licenses/by/1-0/
6
+
7
+ This URI is supplied under Section 4.2(b) of ODC-By-1.0. The attribution and
8
+ rights notices for this database distribution are in PACKAGE-NOTICE.md.
@@ -0,0 +1,25 @@
1
+ # tickerdata package notice
2
+
3
+ The reader software is provided under the MIT License.
4
+
5
+ To the extent the tickerdata contributors hold copyright or database rights in
6
+ the selection and arrangement of the maintained database, that database is
7
+ made available under the Open Data Commons Attribution License 1.0
8
+ (ODC-By-1.0).
9
+
10
+ Required attribution for public use:
11
+
12
+ > Contains information from tickerdata, made available under the Open Data
13
+ > Commons Attribution License: https://opendatacommons.org/licenses/by/1-0/
14
+
15
+ ODC-By licenses database rights and does not automatically license every
16
+ individual item of content. Security names and trademarks belong to their
17
+ respective owners. External classifications and source-derived facts may be
18
+ subject to separate terms. See:
19
+
20
+ - https://github.com/udlrdotai/tickerdata/blob/main/docs/licensing.md
21
+ - https://github.com/udlrdotai/tickerdata/blob/main/docs/industry-classification.md
22
+
23
+ This metadata is provided as-is and may be incomplete or incorrect. It is not
24
+ market data, trading functionality, portfolio management, or investment
25
+ advice.
@@ -0,0 +1 @@
1
+ tickerdata