Skip to content

Commit 02fd42c

Browse files
tsmathisesoteric-ephemera
authored andcommitted
add auto arrow compatibility tests
1 parent 026d278 commit 02fd42c

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

mpcontribs-lux/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Once a staff member from MP reviews and approves your data schema, your receive
1111

1212
To expedite the process of review, follow [these instructions](https://docs.github.com/en/repositories/creating-and-managing-repositories/duplicating-a-repository) to make a private copy (not a fork, which cannot be private) of the `MPContribs` repo.
1313
Suppose you name your new repository `PrivateMPContribs` and your username is `<username>`, you would run these commands from a terminal:
14+
1415
```console
1516
git clone --bare https://github.com/materialsproject/MPContribs.git
1617
cd MPContribs
@@ -26,6 +27,7 @@ When you're ready to make your data public, you will also have to make a public
2627
<span style="color:red"><b>But my CSV/JSON/YAML/etc. file isn't complicated. Why do I need to upload a schema?</b></span>
2728

2829
Schemas are important for ensuring accessibility, interoperability, and reproducibility, and for ensuring that you are fully aware of possible errors in your dataset.
30+
2931
If you are not comfortable mimicking the example `pydantic` schemas in `mpcontribs.lux.projects.examples`, you can either use the schema autogeneration features in `mpcontribs.lux.autogen`:
3032

3133
```py
@@ -36,4 +38,7 @@ pydantic_model = schema_gen.pydantic_schema
3638
print(pydantic_model.model_fields)
3739
```
3840

39-
...or reach out to the maintainers!
41+
...or reach out to the maintainers!
42+
43+
The test suite for MPContribs-lux will automatically test your `pydantic` models for arrow/parquet compatibility using the [arrowize](https://github.com/materialsproject/emmet/blob/74194bbf8c7b32ce15141bb1c9ee0527a0fc6c45/emmet-core/emmet/core/arrow.py#L40) utility from `emmet-core` (MP's production data model and data pipeline repository).
44+
Schemas submitted to MPContribs-lux do not necessarily need to be parquet/arrow compatlible, the `@arrow_incompatible` decorator from `emmet-core`'s [utils](https://github.com/materialsproject/emmet/blob/74194bbf8c7b32ce15141bb1c9ee0527a0fc6c45/emmet-core/emmet/core/utils.py#L104) module can be used to mark a `pydantic` model to be skipped during arrow compatibility testing.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import importlib
2+
import inspect
3+
import itertools
4+
import os
5+
from pathlib import Path
6+
7+
import pyarrow as pa
8+
import pytest
9+
from emmet.core.arrow import arrowize
10+
from pydantic._internal._model_construction import ModelMetaclass
11+
12+
13+
def import_models():
14+
lux_path = Path(__file__).parent.parent.joinpath("mpcontribs/lux")
15+
lux_models = []
16+
for root, dirs, files in os.walk(lux_path):
17+
if "__pycache__" in dirs:
18+
dirs.remove("__pycache__")
19+
20+
parent_module = ".".join(
21+
[
22+
"mpcontribs",
23+
"lux",
24+
*list(
25+
itertools.takewhile(lambda x: x != "lux", reversed(root.split("/")))
26+
)[::-1],
27+
]
28+
)
29+
30+
for file in files:
31+
if file not in ["__init__.py", "__pycache__"]:
32+
if file[-3:] != ".py":
33+
continue
34+
35+
file_name = file[:-3]
36+
module_name = f"{parent_module}.{file_name}"
37+
38+
for name, obj in inspect.getmembers(
39+
importlib.import_module(module_name), inspect.isclass
40+
):
41+
if (
42+
obj.__module__ == module_name
43+
and isinstance(obj, ModelMetaclass)
44+
and not hasattr(obj, "arrow_incompatible")
45+
):
46+
lux_models.append(obj)
47+
48+
return lux_models
49+
50+
51+
@pytest.mark.parametrize("model", import_models())
52+
def test_document_models_for_arrow_compatibility(model):
53+
assert isinstance(arrowize(model), pa.DataType)

0 commit comments

Comments
 (0)