laterite 0.5.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.
- laterite-0.5.0/LICENSE +34 -0
- laterite-0.5.0/PKG-INFO +87 -0
- laterite-0.5.0/README.md +52 -0
- laterite-0.5.0/pyproject.toml +96 -0
- laterite-0.5.0/python/laterite/README-cli.md +97 -0
- laterite-0.5.0/python/laterite/__init__.py +1374 -0
- laterite-0.5.0/python/laterite/_cli.py +283 -0
- laterite-0.5.0/python/laterite/_compat_desc.py +352 -0
- laterite-0.5.0/python/laterite/_errors.py +77 -0
- laterite-0.5.0/python/laterite/_frames.py +109 -0
- laterite-0.5.0/python/laterite/_laterite_native.pyi +8749 -0
- laterite-0.5.0/python/laterite/ags4.py +300 -0
- laterite-0.5.0/python/laterite/ags_types.py +83 -0
- laterite-0.5.0/python/laterite/compat.py +1660 -0
- laterite-0.5.0/python/laterite/dynamic.py +186 -0
- laterite-0.5.0/python/laterite/py.typed +0 -0
- laterite-0.5.0/python/laterite/registry.py +144 -0
- laterite-0.5.0/python/laterite/transport.py +173 -0
- laterite-0.5.0/rust-packages/Cargo.lock +3867 -0
- laterite-0.5.0/rust-packages/Cargo.toml +59 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/Cargo.toml +75 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/data/ags_dictionary.json +62639 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/data/recipes.md +190 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/data/sensitive_headings.json +2148 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/src/ags4_codec.rs +270 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/src/error.rs +97 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/src/index.rs +786 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/src/keychain.rs +324 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/src/lib.rs +31 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/src/registry.rs +411 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/src/transport.rs +163 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/byte_offset_ground_truth.rs +57 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/error_mapping.rs +39 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/fixtures/.gitattributes +6 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/fixtures/leading_blank.ags +12 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/fixtures/quoted_newline.ags +11 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/fixtures/two_group_bom.ags +10 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/fixtures/two_group_crlf.ags +10 -0
- laterite-0.5.0/rust-packages/laterite-ags4-core/tests/fixtures/two_group_lf.ags +10 -0
- laterite-0.5.0/rust-packages/laterite-ags4-diff/Cargo.toml +39 -0
- laterite-0.5.0/rust-packages/laterite-ags4-diff/src/lib.rs +417 -0
- laterite-0.5.0/rust-packages/laterite-ags4-emit/Cargo.toml +51 -0
- laterite-0.5.0/rust-packages/laterite-ags4-emit/src/arrow_in.rs +124 -0
- laterite-0.5.0/rust-packages/laterite-ags4-emit/src/emit.rs +394 -0
- laterite-0.5.0/rust-packages/laterite-ags4-emit/src/error.rs +39 -0
- laterite-0.5.0/rust-packages/laterite-ags4-emit/src/lib.rs +24 -0
- laterite-0.5.0/rust-packages/laterite-ags4-emit/src/writer.rs +158 -0
- laterite-0.5.0/rust-packages/laterite-ags4-parse/Cargo.toml +27 -0
- laterite-0.5.0/rust-packages/laterite-ags4-parse/src/lib.rs +532 -0
- laterite-0.5.0/rust-packages/laterite-ags4-parse/tests/byte_walk.rs +191 -0
- laterite-0.5.0/rust-packages/laterite-ags4-parse/tests/dep_graph.rs +59 -0
- laterite-0.5.0/rust-packages/laterite-ags4-parse/tests/split_field.rs +135 -0
- laterite-0.5.0/rust-packages/laterite-ags4-parse/tests/strict_structure.rs +73 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/Cargo.toml +91 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/README.md +82 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/benches/validate_large_fixture.rs +38 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/build.rs +390 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/data/PROVENANCE.md +79 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/data/Standard_dictionary_v4_0_3.ags +3088 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/data/Standard_dictionary_v4_0_4.ags +3095 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/data/Standard_dictionary_v4_1.ags +6396 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/data/Standard_dictionary_v4_1_1.ags +6393 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/data/Standard_dictionary_v4_2.ags +7225 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/data/rules_meta.json +412 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/catalogue.rs +150 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/dict.rs +347 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/error.rs +80 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/findings.rs +241 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/fixes.rs +1451 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/lib.rs +462 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/parse.rs +188 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/dictionary.rs +305 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/groups.rs +1043 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/line_format.rs +466 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/mod.rs +56 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/naming.rs +298 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/references.rs +613 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/relational.rs +1094 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/structure.rs +455 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/src/rules/typed_values.rs +977 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/clean_minimal.ags +25 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule10a_dup_key.ags +6 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule10c_orphan_child.ags +12 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule11c_bad_rl.ags +17 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule13_no_proj.ags +17 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule15_unit_undef.ags +31 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule16_fyi_nonstandard_abbr.ags +23 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule17_no_type.ags +17 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule18_malformed_dict.ags +12 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule19_bad_group_name.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule19a_bad_heading.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule19b_bad_prefix.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule19b_borrowed_bad.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule1_non_ascii.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule20_undefined_fset.ags +11 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule2_no_data_rows.ags +10 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule2b_unit_missing.ags +4 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule3_bad_descriptor.ags +6 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule4_field_count.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule5_unquoted.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule7_out_of_order.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule8_dp_wrong_precision.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule8_dt_bad.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule8_dt_empty_unit.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule8_dt_out_of_range.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/rule9_unknown_heading.ags +5 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/fixtures/synthetic_multigroup.ags +91 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/lean_dep_graph.rs +75 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/line_contract.rs +91 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/parse_parity.rs +146 -0
- laterite-0.5.0/rust-packages/laterite-ags4-validator/tests/regression.rs +579 -0
- laterite-0.5.0/rust-packages/laterite-excel/Cargo.toml +37 -0
- laterite-0.5.0/rust-packages/laterite-excel/src/lib.rs +784 -0
- laterite-0.5.0/rust-packages/laterite-py/Cargo.toml +104 -0
- laterite-0.5.0/rust-packages/laterite-py/build.rs +283 -0
- laterite-0.5.0/rust-packages/laterite-py/src/ags_types_fns.rs +176 -0
- laterite-0.5.0/rust-packages/laterite-py/src/emit.rs +69 -0
- laterite-0.5.0/rust-packages/laterite-py/src/emit_typed.rs +206 -0
- laterite-0.5.0/rust-packages/laterite-py/src/excel_fns.rs +69 -0
- laterite-0.5.0/rust-packages/laterite-py/src/lib.rs +1017 -0
- laterite-0.5.0/rust-packages/laterite-py/src/registry_fns.rs +80 -0
- laterite-0.5.0/rust-packages/laterite-py/src/transport_fns.rs +102 -0
- laterite-0.5.0/rust-packages/laterite-py/src/typed_graph/mod.rs +41 -0
- laterite-0.5.0/rust-packages/laterite-types/Cargo.toml +51 -0
- laterite-0.5.0/rust-packages/laterite-types/src/arrow_cols.rs +128 -0
- laterite-0.5.0/rust-packages/laterite-types/src/ipc.rs +83 -0
- laterite-0.5.0/rust-packages/laterite-types/src/lib.rs +967 -0
laterite-0.5.0/LICENSE
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 niko86
|
|
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.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Third-party data notice:
|
|
26
|
+
|
|
27
|
+
The AGS4 standard data dictionaries bundled under
|
|
28
|
+
`rust-packages/laterite-ags4-validator/data/` (`Standard_dictionary_v4_1.ags`,
|
|
29
|
+
`Standard_dictionary_v4_2.ags`) are © The Association of Geotechnical and
|
|
30
|
+
Geoenvironmental Specialists (AGS), all rights reserved. They are reference
|
|
31
|
+
data for the published AGS4 transfer-format standard, redistributed here as
|
|
32
|
+
a documented decision — see that directory's `PROVENANCE.md`. This MIT
|
|
33
|
+
licence covers the source code of this repository; it does not purport to
|
|
34
|
+
relicense the AGS dictionary data.
|
laterite-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: laterite
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Classifier: Development Status :: 3 - Alpha
|
|
5
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
9
|
+
Classifier: Programming Language :: Rust
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering
|
|
11
|
+
Classifier: Typing :: Typed
|
|
12
|
+
Requires-Dist: polars>=1.40.1
|
|
13
|
+
Requires-Dist: duckdb>=1.4.0
|
|
14
|
+
Requires-Dist: pandas<3 ; extra == 'all'
|
|
15
|
+
Requires-Dist: pyarrow>=24.0.0 ; extra == 'all'
|
|
16
|
+
Requires-Dist: pandas<3 ; extra == 'compat'
|
|
17
|
+
Requires-Dist: pandas<3 ; extra == 'pandas'
|
|
18
|
+
Requires-Dist: pyarrow>=24.0.0 ; extra == 'pyarrow'
|
|
19
|
+
Provides-Extra: all
|
|
20
|
+
Provides-Extra: compat
|
|
21
|
+
Provides-Extra: pandas
|
|
22
|
+
Provides-Extra: pyarrow
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Summary: Rust-backed AGS4 reader/writer/validator — a fast, drop-in replacement for python-ags4 with born-typed polars/pandas reads (pyarrow-free)
|
|
25
|
+
Keywords: ags,ags4,geotechnical,ground-investigation,validator,parser,rust,polars,pandas,duckdb
|
|
26
|
+
Author-email: niko86 <me@niko86.com>
|
|
27
|
+
License-Expression: MIT
|
|
28
|
+
Requires-Python: >=3.12
|
|
29
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
30
|
+
Project-URL: Changelog, https://github.com/niko86/laterite/blob/main/CHANGELOG.md
|
|
31
|
+
Project-URL: Homepage, https://github.com/niko86/laterite
|
|
32
|
+
Project-URL: Issues, https://github.com/niko86/laterite/issues
|
|
33
|
+
Project-URL: Repository, https://github.com/niko86/laterite
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="https://raw.githubusercontent.com/niko86/laterite/main/assets/laterite-social-preview-white.png" alt="laterite — a Rust-backed AGS4 reader, writer and validator" width="600" />
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
# laterite
|
|
40
|
+
|
|
41
|
+
A Rust-backed AGS4 reader, writer and validator for Python.
|
|
42
|
+
|
|
43
|
+
A faster drop-in for
|
|
44
|
+
[`python-ags4`](https://gitlab.com/ags-data-format-wg/ags-python-library)'s
|
|
45
|
+
`AGS4` module (1.2.0 parity-pinned, 122/131 tests) — swap
|
|
46
|
+
`from python_ags4 import AGS4` for `from laterite import compat as AGS4`.
|
|
47
|
+
The native API returns born-typed **polars** frames by default (or
|
|
48
|
+
**pandas** with `read(..., backend="pandas")`) — both **pyarrow-free**,
|
|
49
|
+
read back from a Python-owned in-memory DuckDB engine.
|
|
50
|
+
|
|
51
|
+
[](https://github.com/niko86/laterite/actions/workflows/ci.yml)
|
|
52
|
+
[](https://codecov.io/gh/niko86/laterite)
|
|
53
|
+
[](https://codecov.io/gh/niko86/laterite)
|
|
54
|
+
[](https://codecov.io/gh/niko86/laterite)
|
|
55
|
+
[](https://pypi.org/project/laterite/)
|
|
56
|
+
[](https://pypi.org/project/laterite/)
|
|
57
|
+
[](LICENSE)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install laterite # base AGS4 (polars + duckdb, pyarrow-free)
|
|
61
|
+
pip install "laterite[compat]" # + pandas (python-ags4 drop-in)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import laterite
|
|
66
|
+
|
|
67
|
+
result = laterite.validate("delivery.ags")
|
|
68
|
+
for rule, findings in result.by_rule().items():
|
|
69
|
+
print(rule, len(findings))
|
|
70
|
+
|
|
71
|
+
# python-ags4 drop-in
|
|
72
|
+
from laterite import compat as AGS4
|
|
73
|
+
tables, _ = AGS4.AGS4_to_dataframe("delivery.ags")
|
|
74
|
+
|
|
75
|
+
# Or a typed view of the file
|
|
76
|
+
from laterite.ags4 import read_typed
|
|
77
|
+
proj = read_typed("delivery.ags")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The validator engine is clean-room from the AGS4 spec. python-ags4
|
|
81
|
+
is LGPL-3.0; the clean-room separation lets laterite ship under MIT.
|
|
82
|
+
|
|
83
|
+
Requires Python ≥ 3.12.
|
|
84
|
+
|
|
85
|
+
Full docs, parity catalogue and observations at
|
|
86
|
+
<https://github.com/niko86/laterite>.
|
|
87
|
+
|
laterite-0.5.0/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/niko86/laterite/main/assets/laterite-social-preview-white.png" alt="laterite — a Rust-backed AGS4 reader, writer and validator" width="600" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# laterite
|
|
6
|
+
|
|
7
|
+
A Rust-backed AGS4 reader, writer and validator for Python.
|
|
8
|
+
|
|
9
|
+
A faster drop-in for
|
|
10
|
+
[`python-ags4`](https://gitlab.com/ags-data-format-wg/ags-python-library)'s
|
|
11
|
+
`AGS4` module (1.2.0 parity-pinned, 122/131 tests) — swap
|
|
12
|
+
`from python_ags4 import AGS4` for `from laterite import compat as AGS4`.
|
|
13
|
+
The native API returns born-typed **polars** frames by default (or
|
|
14
|
+
**pandas** with `read(..., backend="pandas")`) — both **pyarrow-free**,
|
|
15
|
+
read back from a Python-owned in-memory DuckDB engine.
|
|
16
|
+
|
|
17
|
+
[](https://github.com/niko86/laterite/actions/workflows/ci.yml)
|
|
18
|
+
[](https://codecov.io/gh/niko86/laterite)
|
|
19
|
+
[](https://codecov.io/gh/niko86/laterite)
|
|
20
|
+
[](https://codecov.io/gh/niko86/laterite)
|
|
21
|
+
[](https://pypi.org/project/laterite/)
|
|
22
|
+
[](https://pypi.org/project/laterite/)
|
|
23
|
+
[](LICENSE)
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install laterite # base AGS4 (polars + duckdb, pyarrow-free)
|
|
27
|
+
pip install "laterite[compat]" # + pandas (python-ags4 drop-in)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import laterite
|
|
32
|
+
|
|
33
|
+
result = laterite.validate("delivery.ags")
|
|
34
|
+
for rule, findings in result.by_rule().items():
|
|
35
|
+
print(rule, len(findings))
|
|
36
|
+
|
|
37
|
+
# python-ags4 drop-in
|
|
38
|
+
from laterite import compat as AGS4
|
|
39
|
+
tables, _ = AGS4.AGS4_to_dataframe("delivery.ags")
|
|
40
|
+
|
|
41
|
+
# Or a typed view of the file
|
|
42
|
+
from laterite.ags4 import read_typed
|
|
43
|
+
proj = read_typed("delivery.ags")
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The validator engine is clean-room from the AGS4 spec. python-ags4
|
|
47
|
+
is LGPL-3.0; the clean-room separation lets laterite ship under MIT.
|
|
48
|
+
|
|
49
|
+
Requires Python ≥ 3.12.
|
|
50
|
+
|
|
51
|
+
Full docs, parity catalogue and observations at
|
|
52
|
+
<https://github.com/niko86/laterite>.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "laterite"
|
|
3
|
+
version = "0.5.0"
|
|
4
|
+
description = "Rust-backed AGS4 reader/writer/validator — a fast, drop-in replacement for python-ags4 with born-typed polars/pandas reads (pyarrow-free)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "niko86", email = "me@niko86.com" }]
|
|
9
|
+
keywords = [
|
|
10
|
+
"ags",
|
|
11
|
+
"ags4",
|
|
12
|
+
"geotechnical",
|
|
13
|
+
"ground-investigation",
|
|
14
|
+
"validator",
|
|
15
|
+
"parser",
|
|
16
|
+
"rust",
|
|
17
|
+
"polars",
|
|
18
|
+
"pandas",
|
|
19
|
+
"duckdb",
|
|
20
|
+
]
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Development Status :: 3 - Alpha",
|
|
23
|
+
"License :: OSI Approved :: MIT License",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Programming Language :: Rust",
|
|
28
|
+
"Topic :: Scientific/Engineering",
|
|
29
|
+
"Typing :: Typed",
|
|
30
|
+
]
|
|
31
|
+
requires-python = ">=3.12"
|
|
32
|
+
# Mandatory runtime deps:
|
|
33
|
+
# polars — the default frame backend; the read boundary hands Rust-built
|
|
34
|
+
# Arrow over zero-copy (a pyo3-arrow capsule), loaded into DuckDB,
|
|
35
|
+
# and materialised back pyarrow-free into born-typed polars frames.
|
|
36
|
+
# duckdb — the Python-owned in-memory engine: read() loads each group into a
|
|
37
|
+
# born-typed DuckDB table, so ags[code] / ags.sql(...) run real
|
|
38
|
+
# cross-group joins + filter pushdown. NOT bundled in the wheel (the
|
|
39
|
+
# CLI keeps its own); needs no pinned storage version. Floor >=1.4.0
|
|
40
|
+
# (LTS line, in-memory COMPRESS).
|
|
41
|
+
# narwhals is GONE — the core returns polars / pandas directly and `compat`
|
|
42
|
+
# branches on the native frame; nothing imports narwhals at runtime.
|
|
43
|
+
# pyarrow is NOT a laterite dependency anywhere — not base, not the [compat] extra.
|
|
44
|
+
# The polars path uses the Arrow C-stream capsule; the pandas path (core AND compat)
|
|
45
|
+
# uses DuckDB's NumPy `.df()`; both are pyarrow-free. An Arrow table is only reachable
|
|
46
|
+
# via `ags.connection` (or the explicit `pyarrow` backend/extra) with the user's own
|
|
47
|
+
# pyarrow. pandas is an optional extra; a python-ags4 install pulls pandas in
|
|
48
|
+
# unconditionally, laterite does not.
|
|
49
|
+
dependencies = [
|
|
50
|
+
"polars>=1.40.1",
|
|
51
|
+
"duckdb>=1.4.0",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[project.urls]
|
|
55
|
+
Homepage = "https://github.com/niko86/laterite"
|
|
56
|
+
Repository = "https://github.com/niko86/laterite"
|
|
57
|
+
Issues = "https://github.com/niko86/laterite/issues"
|
|
58
|
+
Changelog = "https://github.com/niko86/laterite/blob/main/CHANGELOG.md"
|
|
59
|
+
|
|
60
|
+
# `compat` is the python-ags4 drop-in surface — it defaults to returning
|
|
61
|
+
# pandas frames, so `pip install laterite[compat]` is what most callers
|
|
62
|
+
# want when porting from python_ags4. `pandas` is retained as a
|
|
63
|
+
# back-compat alias (same set). `set_backend("polars")` (or
|
|
64
|
+
# LATERITE_COMPAT_BACKEND=polars) removes the pandas requirement entirely.
|
|
65
|
+
[project.optional-dependencies]
|
|
66
|
+
# compat (the python-ags4 drop-in, pandas by default) is now pyarrow-free: its pandas
|
|
67
|
+
# output goes polars -> pandas via DuckDB's NumPy `.df()` (the same trick the core
|
|
68
|
+
# uses), so the extra is just pandas. `pandas` is a back-compat alias of `compat`;
|
|
69
|
+
# `pyarrow` stays for callers who explicitly want the Arrow backend (the only thing
|
|
70
|
+
# that pulls pyarrow).
|
|
71
|
+
compat = ["pandas<3"]
|
|
72
|
+
pandas = ["pandas<3"]
|
|
73
|
+
pyarrow = ["pyarrow>=24.0.0"]
|
|
74
|
+
# The experimental DuckDB-backed `.ags5db` surface was decoupled from the
|
|
75
|
+
# shipped AGS4 product (#177) — it now lives in the dormant `ags5/` holding
|
|
76
|
+
# folder and is no longer installable as an extra. The future AGS5 strand
|
|
77
|
+
# will publish it as a separate library.
|
|
78
|
+
all = ["pandas<3", "pyarrow>=24.0.0"]
|
|
79
|
+
|
|
80
|
+
[project.scripts]
|
|
81
|
+
# Deliberately named `lat-check` (not `laterite`/`ags4`) so the command,
|
|
82
|
+
# its flags, JSON/NDJSON shape and exit codes are byte-faithful to the
|
|
83
|
+
# Rust `lat-check` binary. This is the Python face of the same CLI.
|
|
84
|
+
lat-check = "laterite._cli:main"
|
|
85
|
+
|
|
86
|
+
[build-system]
|
|
87
|
+
requires = ["maturin>=1.7,<2"]
|
|
88
|
+
build-backend = "maturin"
|
|
89
|
+
|
|
90
|
+
[tool.maturin]
|
|
91
|
+
module-name = "laterite._laterite_native"
|
|
92
|
+
manifest-path = "rust-packages/laterite-py/Cargo.toml"
|
|
93
|
+
python-source = "python"
|
|
94
|
+
# abi3 (cp312-abi3): laterite-py/Cargo.toml sets `abi3-py312` on pyo3, so
|
|
95
|
+
# maturin emits ONE `cp312-abi3` wheel per platform that runs on Python 3.12+.
|
|
96
|
+
# (The old "pinned to 3.14 / pyo3-polars couples the wheel" note was wrong — the
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# lat-check
|
|
2
|
+
|
|
3
|
+
A clean-room Rust validator for the **AGS4** geotechnical
|
|
4
|
+
transfer-format — the capability `python-ags4`'s `AGS4.check_file()`
|
|
5
|
+
provides, with no Python at runtime. Reports the numbered AGS Format
|
|
6
|
+
Rule violations in a file.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
lat-check <file.ags> [options]
|
|
11
|
+
lat-check --readme # this document
|
|
12
|
+
|
|
13
|
+
## Options
|
|
14
|
+
|
|
15
|
+
--dict-version <V> bundled dictionary edition:
|
|
16
|
+
auto (default — picked from the file's
|
|
17
|
+
TRAN_AGS) | 4.0.3 | 4.0.4 | 4.1 | 4.1.1 | 4.2
|
|
18
|
+
--dict <path> external dictionary override (not supported)
|
|
19
|
+
--json machine-readable findings (pretty JSON)
|
|
20
|
+
--ndjson one flat JSON object per finding per line
|
|
21
|
+
--out <path> write the active format to <path> instead of
|
|
22
|
+
stdout (prints a one-line confirmation)
|
|
23
|
+
--json-out <path> also tee the JSON report to <path>
|
|
24
|
+
--fix mechanically repair the file: apply the SAFE
|
|
25
|
+
fixes (CRLF / BOM / embedded-CR / short-row pad /
|
|
26
|
+
numeric reformat / TRAN delimiter+concatenator
|
|
27
|
+
rows) and write the result. Non-destructive —
|
|
28
|
+
writes a sibling <file>.fixed.ags by default.
|
|
29
|
+
Exit 0 if the repaired file is clean, 1 if
|
|
30
|
+
findings remain that can't be auto-fixed.
|
|
31
|
+
--fix-risky like --fix but ALSO applies the intent-guessing
|
|
32
|
+
fixes (duplicate-heading rename, dd/mm date
|
|
33
|
+
canonicalisation, smart-quote→ASCII typography)
|
|
34
|
+
--in-place with --fix: overwrite the source file in place
|
|
35
|
+
--fix-out <path> with --fix: write the repaired file to <path>
|
|
36
|
+
--diff <other.ags> compare the input file against <other> and print the
|
|
37
|
+
KEY-aware/type-aware revision delta (per-group
|
|
38
|
+
+added -removed ~changed; --json for the full delta)
|
|
39
|
+
--no-warnings errors only — suppress the WARNING tier, which is
|
|
40
|
+
shown by default (malformed DICT, nonstandard
|
|
41
|
+
abbreviations, unrecognised TRAN_AGS edition)
|
|
42
|
+
--show-fyi include FYI-severity findings (e.g. Rule 1)
|
|
43
|
+
--check-files also run Rule 20's on-disk check: the sidecar
|
|
44
|
+
FILE/<fset>/<name> tree must exist next to the
|
|
45
|
+
.ags. Default OFF — data-level Rule 20 is
|
|
46
|
+
path-independent (the library default); enable
|
|
47
|
+
for a packaging/QA pass on a real delivery.
|
|
48
|
+
--encoding <name> source text encoding for legacy extended-ASCII
|
|
49
|
+
files: utf-8 (default) | cp1252 | latin1 |
|
|
50
|
+
iso-8859-1 | iso-8859-15. latin1 / iso-8859-1
|
|
51
|
+
map to Windows-1252 (the CP1252 superset
|
|
52
|
+
python-ags4 uses by default).
|
|
53
|
+
--list-rules print the AGS4 rule catalogue (title / severity /
|
|
54
|
+
fixable / cited observations) and exit; add --json
|
|
55
|
+
for the full machine-readable form. No input file.
|
|
56
|
+
--quiet suppress the progress spinner
|
|
57
|
+
--tui interactive findings browser (needs the
|
|
58
|
+
`tui` build feature + an interactive terminal)
|
|
59
|
+
--readme print this document and exit
|
|
60
|
+
-h, --help short usage
|
|
61
|
+
|
|
62
|
+
## Dictionary auto-selection
|
|
63
|
+
|
|
64
|
+
By default the edition is chosen **per file from its `TRAN_AGS`**:
|
|
65
|
+
an exact bundled match wins (`4.0.3/4.0.4/4.1/4.1.1/4.2`), else the
|
|
66
|
+
newest bundled patch of that `major.minor` (`4.0`→4.0.4, `4.1.5`→
|
|
67
|
+
4.1.1), else a fallback to 4.1.1 (matching python-ags4's
|
|
68
|
+
`LATEST_DICT_VERSION`). AGS 3.x is refused (exit 4) rather than
|
|
69
|
+
silently validated against an AGS4 schema. `--dict-version` forces
|
|
70
|
+
one edition regardless.
|
|
71
|
+
|
|
72
|
+
## Output
|
|
73
|
+
|
|
74
|
+
Human table on a TTY (coloured unless `NO_COLOR`); `--json` for a
|
|
75
|
+
nested `{file, findings:{rule:[{line,group,desc}]}}` document;
|
|
76
|
+
`--ndjson` for a stream. Progress is on stderr; the report on stdout.
|
|
77
|
+
|
|
78
|
+
## Exit codes
|
|
79
|
+
|
|
80
|
+
0 clean (no findings)
|
|
81
|
+
1 findings present
|
|
82
|
+
3 file not found / unreadable
|
|
83
|
+
4 not UTF-8 / not an AGS4 file / unsupported AGS edition (3.x)
|
|
84
|
+
5 bad arguments / bad dictionary
|
|
85
|
+
|
|
86
|
+
## Examples
|
|
87
|
+
|
|
88
|
+
lat-check delivery.ags # human table
|
|
89
|
+
lat-check delivery.ags --json | jq . # machine-readable
|
|
90
|
+
lat-check delivery.ags --dict-version 4.2 # force an edition
|
|
91
|
+
lat-check delivery.ags --show-fyi --out report.txt
|
|
92
|
+
lat-check delivery.ags --fix # → delivery.fixed.ags
|
|
93
|
+
lat-check delivery.ags --fix --in-place # repair in place
|
|
94
|
+
lat-check delivery.ags --fix-risky --fix-out clean.ags
|
|
95
|
+
|
|
96
|
+
> The clean-room boundary, licence, and bundled-dictionary provenance
|
|
97
|
+
> are documented in the crate's `README.md` and `data/PROVENANCE.md`.
|