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.
- {mxm_types-0.2.0 → mxm_types-0.2.1}/LICENSE +1 -1
- mxm_types-0.2.1/PKG-INFO +221 -0
- mxm_types-0.2.1/README.md +195 -0
- {mxm_types-0.2.0 → mxm_types-0.2.1}/pyproject.toml +13 -13
- {mxm_types-0.2.0 → mxm_types-0.2.1}/src/mxm/types/general.py +7 -2
- mxm_types-0.2.0/PKG-INFO +0 -243
- mxm_types-0.2.0/README.md +0 -217
- {mxm_types-0.2.0 → mxm_types-0.2.1}/src/mxm/types/__init__.py +0 -0
- {mxm_types-0.2.0 → mxm_types-0.2.1}/src/mxm/types/pandas_timestamps.py +0 -0
- {mxm_types-0.2.0 → mxm_types-0.2.1}/src/mxm/types/py.typed +0 -0
- {mxm_types-0.2.0 → mxm_types-0.2.1}/src/mxm/types/timestamps.py +0 -0
mxm_types-0.2.1/PKG-INFO
ADDED
|
@@ -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
|
+

|
|
29
|
+

|
|
30
|
+

|
|
31
|
+
[](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
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](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.
|
|
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
|
-
|
|
76
|
-
|
|
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
|
|
6
|
-
|
|
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
|
-

|
|
29
|
-

|
|
30
|
-

|
|
31
|
-
[](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
|
-

|
|
4
|
-

|
|
5
|
-

|
|
6
|
-
[](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
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|