mxm-types 0.2.0__tar.gz → 0.2.1__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.
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Money Ex Machina
3
+ Copyright (c) 2025-2026 Money Ex Machina
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the “Software”), to deal
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: mxm-types
3
+ Version: 0.2.1
4
+ Summary: Shared foundational types and representation adapters for Money Ex Machina.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: money-ex-machina,types,typing,timestamps,numpy,pandas,json,pep561
8
+ Author: mxm
9
+ Author-email: contact@moneyexmachina.com
10
+ Requires-Python: >=3.13,<3.15
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: numpy (>=2.4.4,<3.0.0)
20
+ Requires-Dist: pandas (>=3.0.2,<4.0.0)
21
+ Project-URL: Homepage, https://github.com/moneyexmachina/mxm-types
22
+ Project-URL: Issues, https://github.com/moneyexmachina/mxm-types/issues
23
+ Project-URL: Repository, https://github.com/moneyexmachina/mxm-types
24
+ Description-Content-Type: text/markdown
25
+
26
+ # `mxm-types`
27
+
28
+ ![Version](https://img.shields.io/github/v/release/moneyexmachina/mxm-types)
29
+ ![License](https://img.shields.io/github/license/moneyexmachina/mxm-types)
30
+ ![Python](https://img.shields.io/badge/python-3.13+-blue)
31
+ [![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/)
32
+
33
+ ## Purpose
34
+
35
+ `mxm-types` provides shared foundational types and representation adapters for the Money Ex Machina ecosystem.
36
+
37
+ It defines a small, stable, representation-focused layer for:
38
+
39
+ - cross-package type definitions
40
+ - canonical data representations
41
+ - explicit boundary adapters between representations
42
+
43
+ The package is intentionally domain-agnostic.
44
+ Domain models and business semantics belong in their respective packages.
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install mxm-types
50
+ ```
51
+
52
+ ## Overview
53
+
54
+ `mxm-types` defines:
55
+
56
+ - **Strict JSON tree types** for configuration, metadata, requests, and portable data structures
57
+ - **Lightweight aliases** for common cross-package patterns such as path-like values and HTTP headers
58
+ - **Micro-protocols** for cross-cutting interfaces
59
+ - **A canonical MXM timestamp substrate** based on `np.datetime64[ns]`
60
+ - **Explicit representation bridges** from canonical MXM timestamps to:
61
+ - integer epoch nanoseconds
62
+ - strict canonical UTC strings
63
+ - pandas `Timestamp` / `DatetimeIndex`
64
+ - **PEP 561 typing support** (`py.typed` included in the wheel)
65
+
66
+ The package is intentionally small and stable, but it is no longer dependency-free:
67
+ the pandas boundary adapter layer depends on `pandas`.
68
+
69
+ ## Public API
70
+
71
+ The following names form the stable public API of `mxm-types`.
72
+ All other names are private and may change across releases.
73
+
74
+ ### General Types
75
+
76
+ | Name | Description |
77
+ |------|-------------|
78
+ | `JSONScalar` | `str \| int \| float \| bool \| None` |
79
+ | `JSONValue` | Strict recursive JSON tree |
80
+ | `JSONLike` | Permissive tree for accepting general inputs |
81
+ | `JSONObj` | `Mapping[str, JSONValue]` |
82
+ | `JSONMap` | `dict[str, JSONValue]` |
83
+ | `HeadersLike` | Canonical alias for HTTP header mappings |
84
+ | `StrPath` | `str \| PathLike[str]` |
85
+
86
+ ### Protocols and TypedDicts
87
+
88
+ | Name | Description |
89
+ |------|-------------|
90
+ | `KVReadable` | Minimal protocol for key-value access |
91
+ | `CLIFormatOptions` | CLI output formatting hints |
92
+
93
+ ### Canonical Timestamp Substrate
94
+
95
+ | Name | Description |
96
+ |------|-------------|
97
+ | `TSNSScalar` | Canonical timestamp scalar (`np.datetime64[ns]`) |
98
+ | `TSNSArray` | Canonical timestamp array |
99
+ | `Int64Array` | Integer array for epoch nanoseconds |
100
+ | `TS_NS_DTYPE` | Canonical timestamp dtype |
101
+ | `INT64_DTYPE` | Canonical integer dtype |
102
+ | `EPOCH_TS_NS` | Unix epoch constant |
103
+ | `NAT_TS_NS` | Canonical `NaT` sentinel |
104
+
105
+ #### Timestamp Predicates and Assertions
106
+
107
+ | Name | Description |
108
+ |------|-------------|
109
+ | `is_ts_ns` | Predicate for canonical timestamp scalars |
110
+ | `assert_ts_ns` | Assert canonical timestamp scalar |
111
+ | `is_nat` | Predicate for `NaT` |
112
+ | `assert_not_nat` | Assert not `NaT` |
113
+ | `is_ts_ns_array` | Predicate for timestamp arrays |
114
+ | `assert_ts_ns_array` | Assert timestamp array |
115
+ | `has_nat` | Detect `NaT` in array |
116
+ | `assert_no_nat` | Assert no `NaT` |
117
+ | `assert_monotonic_increasing_ts_ns_array` | Assert monotonic timestamps |
118
+
119
+ #### Timestamp Bridges
120
+
121
+ | Name | Description |
122
+ |------|-------------|
123
+ | `ts_ns_from_int` | From integer epoch nanoseconds |
124
+ | `ts_ns_to_int` | To integer epoch nanoseconds |
125
+ | `ts_ns_from_str` | From canonical string |
126
+ | `ts_ns_to_str` | To canonical string |
127
+
128
+ ### Pandas Timestamp Adapters
129
+
130
+ | Name | Description |
131
+ |------|-------------|
132
+ | `is_pd_timestamp_for_ts_ns` | Predicate for pandas scalar |
133
+ | `assert_pd_timestamp_for_ts_ns` | Assert pandas scalar |
134
+ | `is_pd_datetimeindex_for_ts_ns_array` | Predicate for pandas index |
135
+ | `assert_pd_datetimeindex_for_ts_ns_array` | Assert pandas index |
136
+ | `ts_ns_from_pd_timestamp` | Convert from pandas |
137
+ | `ts_ns_to_pd_timestamp` | Convert to pandas |
138
+ | `ts_ns_array_from_pd_datetimeindex` | Convert index to array |
139
+ | `ts_ns_array_to_pd_datetimeindex` | Convert array to index |
140
+
141
+ ---
142
+
143
+ ## Usage
144
+
145
+ ### General shared types
146
+
147
+ ```python
148
+ from mxm.types import JSONObj, StrPath
149
+
150
+ def load_metadata(path: StrPath) -> JSONObj:
151
+ ...
152
+ ```
153
+
154
+ ### Canonical timestamp substrate
155
+
156
+ ```python
157
+ from mxm.types import TSNSScalar, assert_not_nat, ts_ns_from_str, ts_ns_to_int
158
+
159
+ def parse_created_ts(text: str) -> int:
160
+ ts: TSNSScalar = ts_ns_from_str(text)
161
+ ts = assert_not_nat(ts)
162
+ return ts_ns_to_int(ts)
163
+ ```
164
+
165
+ ### Pandas boundary adapter
166
+
167
+ ```python
168
+ import pandas as pd
169
+ from mxm.types import ts_ns_array_from_pd_datetimeindex, ts_ns_to_pd_timestamp
170
+ from mxm.types.timestamps import ts_ns_from_str
171
+
172
+ idx = pd.DatetimeIndex(
173
+ ["2026-03-25 10:14:03.123456789", "2026-03-25 10:14:04.123456789"],
174
+ tz="Europe/Amsterdam",
175
+ )
176
+
177
+ arr = ts_ns_array_from_pd_datetimeindex(idx)
178
+
179
+ ts = ts_ns_from_str("2026-03-25T10:14:03.123456789Z")
180
+ pd_ts = ts_ns_to_pd_timestamp(ts)
181
+ ```
182
+
183
+ ## Timestamp Design
184
+
185
+ MXM adopts a single canonical internal timestamp representation:
186
+
187
+ ```python
188
+ np.datetime64[ns]
189
+ ```
190
+
191
+ Canonical timestamps:
192
+
193
+ - are timezone-naive NumPy timestamps interpreted as UTC
194
+ - represent instants on a linear time axis
195
+ - have nanosecond precision
196
+ - use explicit boundary adapters for external systems
197
+
198
+ Canonical string format:
199
+
200
+ ```text
201
+ YYYY-MM-DDTHH:MM:SS.fffffffffZ
202
+ ```
203
+
204
+ ## Design Principles
205
+
206
+ - **Single canonical representation**
207
+ - **Explicit boundary adapters**
208
+ - **Representation-focused scope**
209
+ - **Stable cross-package surface**
210
+ - **Strict static typing**
211
+
212
+ ## Development
213
+
214
+ ```bash
215
+ make check
216
+ ```
217
+
218
+ ## License
219
+
220
+ MIT License. See [LICENSE](LICENSE).
221
+
@@ -0,0 +1,195 @@
1
+ # `mxm-types`
2
+
3
+ ![Version](https://img.shields.io/github/v/release/moneyexmachina/mxm-types)
4
+ ![License](https://img.shields.io/github/license/moneyexmachina/mxm-types)
5
+ ![Python](https://img.shields.io/badge/python-3.13+-blue)
6
+ [![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/)
7
+
8
+ ## Purpose
9
+
10
+ `mxm-types` provides shared foundational types and representation adapters for the Money Ex Machina ecosystem.
11
+
12
+ It defines a small, stable, representation-focused layer for:
13
+
14
+ - cross-package type definitions
15
+ - canonical data representations
16
+ - explicit boundary adapters between representations
17
+
18
+ The package is intentionally domain-agnostic.
19
+ Domain models and business semantics belong in their respective packages.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ pip install mxm-types
25
+ ```
26
+
27
+ ## Overview
28
+
29
+ `mxm-types` defines:
30
+
31
+ - **Strict JSON tree types** for configuration, metadata, requests, and portable data structures
32
+ - **Lightweight aliases** for common cross-package patterns such as path-like values and HTTP headers
33
+ - **Micro-protocols** for cross-cutting interfaces
34
+ - **A canonical MXM timestamp substrate** based on `np.datetime64[ns]`
35
+ - **Explicit representation bridges** from canonical MXM timestamps to:
36
+ - integer epoch nanoseconds
37
+ - strict canonical UTC strings
38
+ - pandas `Timestamp` / `DatetimeIndex`
39
+ - **PEP 561 typing support** (`py.typed` included in the wheel)
40
+
41
+ The package is intentionally small and stable, but it is no longer dependency-free:
42
+ the pandas boundary adapter layer depends on `pandas`.
43
+
44
+ ## Public API
45
+
46
+ The following names form the stable public API of `mxm-types`.
47
+ All other names are private and may change across releases.
48
+
49
+ ### General Types
50
+
51
+ | Name | Description |
52
+ |------|-------------|
53
+ | `JSONScalar` | `str \| int \| float \| bool \| None` |
54
+ | `JSONValue` | Strict recursive JSON tree |
55
+ | `JSONLike` | Permissive tree for accepting general inputs |
56
+ | `JSONObj` | `Mapping[str, JSONValue]` |
57
+ | `JSONMap` | `dict[str, JSONValue]` |
58
+ | `HeadersLike` | Canonical alias for HTTP header mappings |
59
+ | `StrPath` | `str \| PathLike[str]` |
60
+
61
+ ### Protocols and TypedDicts
62
+
63
+ | Name | Description |
64
+ |------|-------------|
65
+ | `KVReadable` | Minimal protocol for key-value access |
66
+ | `CLIFormatOptions` | CLI output formatting hints |
67
+
68
+ ### Canonical Timestamp Substrate
69
+
70
+ | Name | Description |
71
+ |------|-------------|
72
+ | `TSNSScalar` | Canonical timestamp scalar (`np.datetime64[ns]`) |
73
+ | `TSNSArray` | Canonical timestamp array |
74
+ | `Int64Array` | Integer array for epoch nanoseconds |
75
+ | `TS_NS_DTYPE` | Canonical timestamp dtype |
76
+ | `INT64_DTYPE` | Canonical integer dtype |
77
+ | `EPOCH_TS_NS` | Unix epoch constant |
78
+ | `NAT_TS_NS` | Canonical `NaT` sentinel |
79
+
80
+ #### Timestamp Predicates and Assertions
81
+
82
+ | Name | Description |
83
+ |------|-------------|
84
+ | `is_ts_ns` | Predicate for canonical timestamp scalars |
85
+ | `assert_ts_ns` | Assert canonical timestamp scalar |
86
+ | `is_nat` | Predicate for `NaT` |
87
+ | `assert_not_nat` | Assert not `NaT` |
88
+ | `is_ts_ns_array` | Predicate for timestamp arrays |
89
+ | `assert_ts_ns_array` | Assert timestamp array |
90
+ | `has_nat` | Detect `NaT` in array |
91
+ | `assert_no_nat` | Assert no `NaT` |
92
+ | `assert_monotonic_increasing_ts_ns_array` | Assert monotonic timestamps |
93
+
94
+ #### Timestamp Bridges
95
+
96
+ | Name | Description |
97
+ |------|-------------|
98
+ | `ts_ns_from_int` | From integer epoch nanoseconds |
99
+ | `ts_ns_to_int` | To integer epoch nanoseconds |
100
+ | `ts_ns_from_str` | From canonical string |
101
+ | `ts_ns_to_str` | To canonical string |
102
+
103
+ ### Pandas Timestamp Adapters
104
+
105
+ | Name | Description |
106
+ |------|-------------|
107
+ | `is_pd_timestamp_for_ts_ns` | Predicate for pandas scalar |
108
+ | `assert_pd_timestamp_for_ts_ns` | Assert pandas scalar |
109
+ | `is_pd_datetimeindex_for_ts_ns_array` | Predicate for pandas index |
110
+ | `assert_pd_datetimeindex_for_ts_ns_array` | Assert pandas index |
111
+ | `ts_ns_from_pd_timestamp` | Convert from pandas |
112
+ | `ts_ns_to_pd_timestamp` | Convert to pandas |
113
+ | `ts_ns_array_from_pd_datetimeindex` | Convert index to array |
114
+ | `ts_ns_array_to_pd_datetimeindex` | Convert array to index |
115
+
116
+ ---
117
+
118
+ ## Usage
119
+
120
+ ### General shared types
121
+
122
+ ```python
123
+ from mxm.types import JSONObj, StrPath
124
+
125
+ def load_metadata(path: StrPath) -> JSONObj:
126
+ ...
127
+ ```
128
+
129
+ ### Canonical timestamp substrate
130
+
131
+ ```python
132
+ from mxm.types import TSNSScalar, assert_not_nat, ts_ns_from_str, ts_ns_to_int
133
+
134
+ def parse_created_ts(text: str) -> int:
135
+ ts: TSNSScalar = ts_ns_from_str(text)
136
+ ts = assert_not_nat(ts)
137
+ return ts_ns_to_int(ts)
138
+ ```
139
+
140
+ ### Pandas boundary adapter
141
+
142
+ ```python
143
+ import pandas as pd
144
+ from mxm.types import ts_ns_array_from_pd_datetimeindex, ts_ns_to_pd_timestamp
145
+ from mxm.types.timestamps import ts_ns_from_str
146
+
147
+ idx = pd.DatetimeIndex(
148
+ ["2026-03-25 10:14:03.123456789", "2026-03-25 10:14:04.123456789"],
149
+ tz="Europe/Amsterdam",
150
+ )
151
+
152
+ arr = ts_ns_array_from_pd_datetimeindex(idx)
153
+
154
+ ts = ts_ns_from_str("2026-03-25T10:14:03.123456789Z")
155
+ pd_ts = ts_ns_to_pd_timestamp(ts)
156
+ ```
157
+
158
+ ## Timestamp Design
159
+
160
+ MXM adopts a single canonical internal timestamp representation:
161
+
162
+ ```python
163
+ np.datetime64[ns]
164
+ ```
165
+
166
+ Canonical timestamps:
167
+
168
+ - are timezone-naive NumPy timestamps interpreted as UTC
169
+ - represent instants on a linear time axis
170
+ - have nanosecond precision
171
+ - use explicit boundary adapters for external systems
172
+
173
+ Canonical string format:
174
+
175
+ ```text
176
+ YYYY-MM-DDTHH:MM:SS.fffffffffZ
177
+ ```
178
+
179
+ ## Design Principles
180
+
181
+ - **Single canonical representation**
182
+ - **Explicit boundary adapters**
183
+ - **Representation-focused scope**
184
+ - **Stable cross-package surface**
185
+ - **Strict static typing**
186
+
187
+ ## Development
188
+
189
+ ```bash
190
+ make check
191
+ ```
192
+
193
+ ## License
194
+
195
+ MIT License. See [LICENSE](LICENSE).
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "mxm-types"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "Shared foundational types and representation adapters for Money Ex Machina."
5
5
  authors = ["mxm <contact@moneyexmachina.com>"]
6
6
  license = "MIT"
@@ -53,16 +53,7 @@ pyright = "^1.1.407"
53
53
  [build-system]
54
54
  requires = ["poetry-core>=2.0.0,<3.0.0"]
55
55
  build-backend = "poetry.core.masonry.api"
56
-
57
- [tool.ruff]
58
- line-length = 88
59
- target-version = "py313"
60
- exclude = ["build", "dist", ".venv"]
61
-
62
- [tool.ruff.lint]
63
- select = ["E","F","B","UP","C90","RUF"]
64
- ignore = ["E203","E501","I001","I002"]
65
-
56
+ # ---- Tooling (package-local, MXM defaults) ----
66
57
  [tool.black]
67
58
  line-length = 88
68
59
  target-version = ["py313"]
@@ -72,8 +63,17 @@ profile = "black"
72
63
  line_length = 88
73
64
  known_first_party = ["mxm"]
74
65
  combine_as_imports = true
75
- force_sort_within_sections = true
76
- lines_between_types = 1
66
+
67
+ [tool.ruff]
68
+ line-length = 88
69
+ target-version = "py313"
70
+
71
+ [tool.ruff.lint]
72
+ select = ["E","F","I","B","UP","C90","RUF"]
73
+ ignore = ["E203","E501"]
74
+
75
+ [tool.ruff.lint.isort]
76
+ known-first-party = ["mxm"]
77
77
 
78
78
  [tool.pytest.ini_options]
79
79
  addopts = "-q"
@@ -2,8 +2,13 @@ from __future__ import annotations
2
2
 
3
3
  from collections.abc import Mapping, Sequence
4
4
  from os import PathLike
5
- from typing import Any, Protocol, TypedDict, runtime_checkable
6
- from typing import Literal # stricter options for CLIFormatOptions.format
5
+ from typing import (
6
+ Any,
7
+ Literal,
8
+ Protocol,
9
+ TypedDict,
10
+ runtime_checkable,
11
+ )
7
12
 
8
13
  # JSON types ---------------------------------------------------------------------------
9
14
 
mxm_types-0.2.0/PKG-INFO DELETED
@@ -1,243 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mxm-types
3
- Version: 0.2.0
4
- Summary: Shared foundational types and representation adapters for Money Ex Machina.
5
- License: MIT
6
- License-File: LICENSE
7
- Keywords: money-ex-machina,types,typing,timestamps,numpy,pandas,json,pep561
8
- Author: mxm
9
- Author-email: contact@moneyexmachina.com
10
- Requires-Python: >=3.13,<3.15
11
- Classifier: Development Status :: 3 - Alpha
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.13
16
- Classifier: Programming Language :: Python :: 3.14
17
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
- Classifier: Typing :: Typed
19
- Requires-Dist: numpy (>=2.4.4,<3.0.0)
20
- Requires-Dist: pandas (>=3.0.2,<4.0.0)
21
- Project-URL: Homepage, https://github.com/moneyexmachina/mxm-types
22
- Project-URL: Issues, https://github.com/moneyexmachina/mxm-types/issues
23
- Project-URL: Repository, https://github.com/moneyexmachina/mxm-types
24
- Description-Content-Type: text/markdown
25
-
26
- # `mxm-types`
27
-
28
- ![Version](https://img.shields.io/github/v/release/moneyexmachina/mxm-types)
29
- ![License](https://img.shields.io/github/license/moneyexmachina/mxm-types)
30
- ![Python](https://img.shields.io/badge/python-3.13+-blue)
31
- [![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/)
32
-
33
- Shared foundational types and representation adapters for the Money Ex Machina ecosystem.
34
-
35
- `mxm-types` provides a small, stable package for cross-package MXM type definitions and canonical representation bridges.
36
-
37
- It currently includes:
38
-
39
- - general shared aliases and micro-protocols
40
- - the canonical MXM timestamp substrate
41
- - explicit pandas boundary adapters for the canonical timestamp model
42
-
43
- The package is intentionally representation-focused and domain-agnostic.
44
- Domain models and business semantics belong in their respective packages.
45
-
46
- ## Install
47
-
48
- ```bash
49
- pip install mxm-types
50
- ```
51
-
52
- ## Overview
53
-
54
- `mxm-types` defines:
55
-
56
- - **Strict JSON tree types** for configuration, metadata, requests, and portable data structures.
57
- - **Lightweight aliases** for common cross-package patterns such as path-like values and HTTP headers.
58
- - **Micro-protocols** for cross-cutting interfaces.
59
- - **A canonical MXM timestamp substrate** based on `np.datetime64[ns]`.
60
- - **Explicit representation bridges** from canonical MXM timestamps to:
61
- - integer epoch nanoseconds
62
- - strict canonical UTC strings
63
- - pandas `Timestamp` / `DatetimeIndex`
64
- - **PEP 561 typing support** (`py.typed` included in the wheel).
65
-
66
- The package is intentionally small and stable, but it is no longer dependency-free:
67
- the pandas boundary adapter layer depends on `pandas`.
68
-
69
- ## Public API
70
-
71
- The following names form the stable public API of `mxm-types`.
72
- All other names are private and may change across releases.
73
-
74
- ### General Types
75
-
76
- | Name | Description |
77
- |------|-------------|
78
- | `JSONScalar` | `str \| int \| float \| bool \| None` |
79
- | `JSONValue` | Strict recursive JSON tree: scalars, `list[JSONValue]`, `dict[str, JSONValue]` |
80
- | `JSONLike` | Permissive tree for accepting general `Sequence` / `Mapping` inputs |
81
- | `JSONObj` | `Mapping[str, JSONValue]` — preferred for function parameters |
82
- | `JSONMap` | `dict[str, JSONValue]` — preferred for concrete, mutable results |
83
- | `HeadersLike` | Canonical alias for HTTP header mappings |
84
- | `StrPath` | `str \| PathLike[str]` |
85
-
86
- ### Protocols and TypedDicts
87
-
88
- | Name | Description |
89
- |------|-------------|
90
- | `KVReadable` | Minimal protocol for objects exposing `get(key, default)` |
91
- | `CLIFormatOptions` | Optional formatting hints for CLI output (`"plain" \| "rich" \| "json"`) |
92
-
93
- ### Canonical Timestamp Substrate
94
-
95
- | Name | Description |
96
- |------|-------------|
97
- | `TSNSScalar` | Canonical MXM timestamp scalar (`np.datetime64[ns]`) |
98
- | `TSNSArray` | Canonical MXM timestamp array (`ndarray[datetime64[ns]]`) |
99
- | `Int64Array` | `ndarray[int64]` alias used alongside canonical timestamp bridges |
100
- | `TS_NS_DTYPE` | Canonical NumPy timestamp dtype constant |
101
- | `INT64_DTYPE` | Canonical integer dtype constant for epoch nanoseconds |
102
- | `EPOCH_TS_NS` | Unix epoch constant in canonical MXM timestamp form |
103
- | `NAT_TS_NS` | Canonical NumPy `NaT` sentinel in `datetime64[ns]` form |
104
-
105
- #### Timestamp Predicates and Assertions
106
-
107
- | Name | Description |
108
- |------|-------------|
109
- | `is_ts_ns` | Predicate for canonical timestamp scalars |
110
- | `assert_ts_ns` | Assert and return canonical timestamp scalar |
111
- | `is_nat` | Predicate for canonical `NaT` scalar |
112
- | `assert_not_nat` | Assert scalar is not `NaT` |
113
- | `is_ts_ns_array` | Predicate for canonical timestamp arrays |
114
- | `assert_ts_ns_array` | Assert and return canonical timestamp array |
115
- | `has_nat` | Detect `NaT` in a canonical timestamp array |
116
- | `assert_no_nat` | Assert canonical timestamp array contains no `NaT` |
117
- | `assert_monotonic_increasing_ts_ns_array` | Assert 1D, non-`NaT`, monotonic-increasing canonical timestamp array |
118
-
119
- #### Timestamp Bridges
120
-
121
- | Name | Description |
122
- |------|-------------|
123
- | `ts_ns_from_int` | Construct canonical timestamp from integer epoch nanoseconds |
124
- | `ts_ns_to_int` | Convert canonical timestamp to integer epoch nanoseconds |
125
- | `ts_ns_from_str` | Parse canonical UTC string into canonical timestamp |
126
- | `ts_ns_to_str` | Format canonical timestamp as canonical UTC string |
127
-
128
- ### Pandas Timestamp Adapters
129
-
130
- | Name | Description |
131
- |------|-------------|
132
- | `is_pd_timestamp_for_ts_ns` | Predicate for approved pandas scalar normal form |
133
- | `assert_pd_timestamp_for_ts_ns` | Assert pandas scalar normal form |
134
- | `is_pd_datetimeindex_for_ts_ns_array` | Predicate for approved pandas array normal form |
135
- | `assert_pd_datetimeindex_for_ts_ns_array` | Assert pandas array normal form |
136
- | `ts_ns_from_pd_timestamp` | Convert pandas `Timestamp` to canonical timestamp |
137
- | `ts_ns_to_pd_timestamp` | Convert canonical timestamp to UTC pandas `Timestamp` |
138
- | `ts_ns_array_from_pd_datetimeindex` | Convert pandas `DatetimeIndex` to canonical timestamp array |
139
- | `ts_ns_array_to_pd_datetimeindex` | Convert canonical timestamp array to UTC pandas `DatetimeIndex` |
140
-
141
- ---
142
-
143
- ## Usage
144
-
145
- ### General shared types
146
-
147
- ```python
148
- from mxm.types import (
149
- JSONLike,
150
- JSONObj,
151
- JSONValue,
152
- StrPath,
153
- )
154
-
155
- def load_metadata(path: StrPath) -> JSONObj:
156
- ...
157
- ```
158
-
159
- ### Canonical timestamp substrate
160
-
161
- ```python
162
- from mxm.types import (
163
- TSNSScalar,
164
- assert_not_nat,
165
- ts_ns_from_str,
166
- ts_ns_to_int,
167
- )
168
-
169
- def parse_created_ts(text: str) -> int:
170
- ts: TSNSScalar = ts_ns_from_str(text)
171
- ts = assert_not_nat(ts)
172
- return ts_ns_to_int(ts)
173
- ```
174
-
175
- ### Pandas boundary adapter
176
-
177
- ```python
178
- import pandas as pd
179
-
180
- from mxm.types import (
181
- ts_ns_array_from_pd_datetimeindex,
182
- ts_ns_to_pd_timestamp,
183
- )
184
- from mxm.types.timestamps import ts_ns_from_str
185
-
186
- idx = pd.DatetimeIndex(
187
- ["2026-03-25 10:14:03.123456789", "2026-03-25 10:14:04.123456789"],
188
- tz="Europe/Amsterdam",
189
- )
190
-
191
- arr = ts_ns_array_from_pd_datetimeindex(idx)
192
-
193
- ts = ts_ns_from_str("2026-03-25T10:14:03.123456789Z")
194
- pd_ts = ts_ns_to_pd_timestamp(ts)
195
- ```
196
-
197
- ## Timestamp Design
198
-
199
- MXM adopts a single canonical internal timestamp representation:
200
-
201
- ```python
202
- np.datetime64[ns]
203
- ```
204
-
205
- Under MXM policy, canonical timestamps:
206
-
207
- - are timezone-naive NumPy timestamps interpreted strictly as UTC
208
- - represent instants on a POSIX-style linear time axis
209
- - have nanosecond precision
210
- - use explicit boundary adapters for pandas and other external systems
211
-
212
- The canonical textual bridge format is:
213
-
214
- ```text
215
- YYYY-MM-DDTHH:MM:SS.fffffffffZ
216
- ```
217
-
218
- with exactly 9 fractional digits and mandatory trailing `Z`.
219
-
220
- ## Design Principles
221
-
222
- - **One canonical timestamp model**: shared across MXM packages.
223
- - **Explicit representation bridges**: conversions to strings, integers, and pandas stay visible.
224
- - **Representation-focused scope**: this package owns types and adapters, not domain semantics.
225
- - **Stable cross-package surface**: suitable for low-level shared usage.
226
- - **Strict static typing**: Pyright-clean, test-covered, and PEP 561 compliant.
227
-
228
- ## Development
229
-
230
- ```bash
231
- poetry install
232
- poetry run ruff check .
233
- poetry run black --check .
234
- poetry run pyright
235
- poetry run pytest -q
236
- poetry build
237
- ```
238
-
239
- ## License
240
-
241
- MIT License. See [LICENSE](LICENSE).
242
-
243
-
mxm_types-0.2.0/README.md DELETED
@@ -1,217 +0,0 @@
1
- # `mxm-types`
2
-
3
- ![Version](https://img.shields.io/github/v/release/moneyexmachina/mxm-types)
4
- ![License](https://img.shields.io/github/license/moneyexmachina/mxm-types)
5
- ![Python](https://img.shields.io/badge/python-3.13+-blue)
6
- [![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/)
7
-
8
- Shared foundational types and representation adapters for the Money Ex Machina ecosystem.
9
-
10
- `mxm-types` provides a small, stable package for cross-package MXM type definitions and canonical representation bridges.
11
-
12
- It currently includes:
13
-
14
- - general shared aliases and micro-protocols
15
- - the canonical MXM timestamp substrate
16
- - explicit pandas boundary adapters for the canonical timestamp model
17
-
18
- The package is intentionally representation-focused and domain-agnostic.
19
- Domain models and business semantics belong in their respective packages.
20
-
21
- ## Install
22
-
23
- ```bash
24
- pip install mxm-types
25
- ```
26
-
27
- ## Overview
28
-
29
- `mxm-types` defines:
30
-
31
- - **Strict JSON tree types** for configuration, metadata, requests, and portable data structures.
32
- - **Lightweight aliases** for common cross-package patterns such as path-like values and HTTP headers.
33
- - **Micro-protocols** for cross-cutting interfaces.
34
- - **A canonical MXM timestamp substrate** based on `np.datetime64[ns]`.
35
- - **Explicit representation bridges** from canonical MXM timestamps to:
36
- - integer epoch nanoseconds
37
- - strict canonical UTC strings
38
- - pandas `Timestamp` / `DatetimeIndex`
39
- - **PEP 561 typing support** (`py.typed` included in the wheel).
40
-
41
- The package is intentionally small and stable, but it is no longer dependency-free:
42
- the pandas boundary adapter layer depends on `pandas`.
43
-
44
- ## Public API
45
-
46
- The following names form the stable public API of `mxm-types`.
47
- All other names are private and may change across releases.
48
-
49
- ### General Types
50
-
51
- | Name | Description |
52
- |------|-------------|
53
- | `JSONScalar` | `str \| int \| float \| bool \| None` |
54
- | `JSONValue` | Strict recursive JSON tree: scalars, `list[JSONValue]`, `dict[str, JSONValue]` |
55
- | `JSONLike` | Permissive tree for accepting general `Sequence` / `Mapping` inputs |
56
- | `JSONObj` | `Mapping[str, JSONValue]` — preferred for function parameters |
57
- | `JSONMap` | `dict[str, JSONValue]` — preferred for concrete, mutable results |
58
- | `HeadersLike` | Canonical alias for HTTP header mappings |
59
- | `StrPath` | `str \| PathLike[str]` |
60
-
61
- ### Protocols and TypedDicts
62
-
63
- | Name | Description |
64
- |------|-------------|
65
- | `KVReadable` | Minimal protocol for objects exposing `get(key, default)` |
66
- | `CLIFormatOptions` | Optional formatting hints for CLI output (`"plain" \| "rich" \| "json"`) |
67
-
68
- ### Canonical Timestamp Substrate
69
-
70
- | Name | Description |
71
- |------|-------------|
72
- | `TSNSScalar` | Canonical MXM timestamp scalar (`np.datetime64[ns]`) |
73
- | `TSNSArray` | Canonical MXM timestamp array (`ndarray[datetime64[ns]]`) |
74
- | `Int64Array` | `ndarray[int64]` alias used alongside canonical timestamp bridges |
75
- | `TS_NS_DTYPE` | Canonical NumPy timestamp dtype constant |
76
- | `INT64_DTYPE` | Canonical integer dtype constant for epoch nanoseconds |
77
- | `EPOCH_TS_NS` | Unix epoch constant in canonical MXM timestamp form |
78
- | `NAT_TS_NS` | Canonical NumPy `NaT` sentinel in `datetime64[ns]` form |
79
-
80
- #### Timestamp Predicates and Assertions
81
-
82
- | Name | Description |
83
- |------|-------------|
84
- | `is_ts_ns` | Predicate for canonical timestamp scalars |
85
- | `assert_ts_ns` | Assert and return canonical timestamp scalar |
86
- | `is_nat` | Predicate for canonical `NaT` scalar |
87
- | `assert_not_nat` | Assert scalar is not `NaT` |
88
- | `is_ts_ns_array` | Predicate for canonical timestamp arrays |
89
- | `assert_ts_ns_array` | Assert and return canonical timestamp array |
90
- | `has_nat` | Detect `NaT` in a canonical timestamp array |
91
- | `assert_no_nat` | Assert canonical timestamp array contains no `NaT` |
92
- | `assert_monotonic_increasing_ts_ns_array` | Assert 1D, non-`NaT`, monotonic-increasing canonical timestamp array |
93
-
94
- #### Timestamp Bridges
95
-
96
- | Name | Description |
97
- |------|-------------|
98
- | `ts_ns_from_int` | Construct canonical timestamp from integer epoch nanoseconds |
99
- | `ts_ns_to_int` | Convert canonical timestamp to integer epoch nanoseconds |
100
- | `ts_ns_from_str` | Parse canonical UTC string into canonical timestamp |
101
- | `ts_ns_to_str` | Format canonical timestamp as canonical UTC string |
102
-
103
- ### Pandas Timestamp Adapters
104
-
105
- | Name | Description |
106
- |------|-------------|
107
- | `is_pd_timestamp_for_ts_ns` | Predicate for approved pandas scalar normal form |
108
- | `assert_pd_timestamp_for_ts_ns` | Assert pandas scalar normal form |
109
- | `is_pd_datetimeindex_for_ts_ns_array` | Predicate for approved pandas array normal form |
110
- | `assert_pd_datetimeindex_for_ts_ns_array` | Assert pandas array normal form |
111
- | `ts_ns_from_pd_timestamp` | Convert pandas `Timestamp` to canonical timestamp |
112
- | `ts_ns_to_pd_timestamp` | Convert canonical timestamp to UTC pandas `Timestamp` |
113
- | `ts_ns_array_from_pd_datetimeindex` | Convert pandas `DatetimeIndex` to canonical timestamp array |
114
- | `ts_ns_array_to_pd_datetimeindex` | Convert canonical timestamp array to UTC pandas `DatetimeIndex` |
115
-
116
- ---
117
-
118
- ## Usage
119
-
120
- ### General shared types
121
-
122
- ```python
123
- from mxm.types import (
124
- JSONLike,
125
- JSONObj,
126
- JSONValue,
127
- StrPath,
128
- )
129
-
130
- def load_metadata(path: StrPath) -> JSONObj:
131
- ...
132
- ```
133
-
134
- ### Canonical timestamp substrate
135
-
136
- ```python
137
- from mxm.types import (
138
- TSNSScalar,
139
- assert_not_nat,
140
- ts_ns_from_str,
141
- ts_ns_to_int,
142
- )
143
-
144
- def parse_created_ts(text: str) -> int:
145
- ts: TSNSScalar = ts_ns_from_str(text)
146
- ts = assert_not_nat(ts)
147
- return ts_ns_to_int(ts)
148
- ```
149
-
150
- ### Pandas boundary adapter
151
-
152
- ```python
153
- import pandas as pd
154
-
155
- from mxm.types import (
156
- ts_ns_array_from_pd_datetimeindex,
157
- ts_ns_to_pd_timestamp,
158
- )
159
- from mxm.types.timestamps import ts_ns_from_str
160
-
161
- idx = pd.DatetimeIndex(
162
- ["2026-03-25 10:14:03.123456789", "2026-03-25 10:14:04.123456789"],
163
- tz="Europe/Amsterdam",
164
- )
165
-
166
- arr = ts_ns_array_from_pd_datetimeindex(idx)
167
-
168
- ts = ts_ns_from_str("2026-03-25T10:14:03.123456789Z")
169
- pd_ts = ts_ns_to_pd_timestamp(ts)
170
- ```
171
-
172
- ## Timestamp Design
173
-
174
- MXM adopts a single canonical internal timestamp representation:
175
-
176
- ```python
177
- np.datetime64[ns]
178
- ```
179
-
180
- Under MXM policy, canonical timestamps:
181
-
182
- - are timezone-naive NumPy timestamps interpreted strictly as UTC
183
- - represent instants on a POSIX-style linear time axis
184
- - have nanosecond precision
185
- - use explicit boundary adapters for pandas and other external systems
186
-
187
- The canonical textual bridge format is:
188
-
189
- ```text
190
- YYYY-MM-DDTHH:MM:SS.fffffffffZ
191
- ```
192
-
193
- with exactly 9 fractional digits and mandatory trailing `Z`.
194
-
195
- ## Design Principles
196
-
197
- - **One canonical timestamp model**: shared across MXM packages.
198
- - **Explicit representation bridges**: conversions to strings, integers, and pandas stay visible.
199
- - **Representation-focused scope**: this package owns types and adapters, not domain semantics.
200
- - **Stable cross-package surface**: suitable for low-level shared usage.
201
- - **Strict static typing**: Pyright-clean, test-covered, and PEP 561 compliant.
202
-
203
- ## Development
204
-
205
- ```bash
206
- poetry install
207
- poetry run ruff check .
208
- poetry run black --check .
209
- poetry run pyright
210
- poetry run pytest -q
211
- poetry build
212
- ```
213
-
214
- ## License
215
-
216
- MIT License. See [LICENSE](LICENSE).
217
-