prelude-parser 0.5.0__cp38-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prelude_parser/__init__.py +4 -0
- prelude_parser/_prelude_parser.cp38-win_amd64.pyd +0 -0
- prelude_parser/_prelude_parser.pyi +23 -0
- prelude_parser/pandas.py +42 -0
- prelude_parser/parser.py +61 -0
- prelude_parser/polars.py +33 -0
- prelude_parser/py.typed +0 -0
- prelude_parser/types.py +5 -0
- prelude_parser-0.5.0.dist-info/METADATA +106 -0
- prelude_parser-0.5.0.dist-info/RECORD +12 -0
- prelude_parser-0.5.0.dist-info/WHEEL +4 -0
- prelude_parser-0.5.0.dist-info/license_files/LICENSE +21 -0
|
Binary file
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from prelude_parser._prelude_parser import SubjectNative # type: ignore[attr-defined]
|
|
6
|
+
from prelude_parser.types import FlatFormInfo
|
|
7
|
+
|
|
8
|
+
def _parse_flat_file_to_dict(
|
|
9
|
+
xml_file: str | Path, short_names: bool
|
|
10
|
+
) -> dict[str, FlatFormInfo]: ...
|
|
11
|
+
def _parse_flat_file_to_pandas_dict(
|
|
12
|
+
xml_file: str | Path, short_names: bool
|
|
13
|
+
) -> dict[str, FlatFormInfo]: ...
|
|
14
|
+
def parse_subject_native_file(xml_file: str | Path) -> SubjectNative: ...
|
|
15
|
+
|
|
16
|
+
class FileNotFoundError(Exception):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
class InvalidFileTypeError(Exception):
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
class ParsingError(Exception):
|
|
23
|
+
pass
|
prelude_parser/pandas.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from prelude_parser._prelude_parser import _parse_flat_file_to_pandas_dict
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class UnsupportedPythonVersionError(Exception):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
import pandas as pd
|
|
15
|
+
except ImportError as e: # pragma: no cover
|
|
16
|
+
if sys.version_info < (3, 9): # pargma: no cover
|
|
17
|
+
raise UnsupportedPythonVersionError("Pandas only supports Python 3.9+") from e
|
|
18
|
+
|
|
19
|
+
raise ImportError(
|
|
20
|
+
"prelude-parser must be installed with the pandas or all extra to use pandas"
|
|
21
|
+
) from e
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def to_dataframe(xml_file: str | Path, *, short_names: bool = False) -> pd.DataFrame:
|
|
25
|
+
"""Parse a Prelude flat XML file into a Pandas DataFrame.
|
|
26
|
+
|
|
27
|
+
This works for Prelude flat XML files that were exported with the "write tables to seperate
|
|
28
|
+
files" option.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
xml_file: The path to the XML file to parser.
|
|
32
|
+
short_names: Set to True if short names were used in the export.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
A Pandas DataFrame the data from the XML file.
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
>>> from prelude_parser.pandas import to_dataframe
|
|
39
|
+
>>> df = to_dataframe("physical_examination.xml")
|
|
40
|
+
"""
|
|
41
|
+
data = _parse_flat_file_to_pandas_dict(xml_file, short_names)
|
|
42
|
+
return pd.DataFrame.from_dict(data)
|
prelude_parser/parser.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from camel_converter import to_pascal
|
|
7
|
+
|
|
8
|
+
from prelude_parser._prelude_parser import _parse_flat_file_to_dict
|
|
9
|
+
from prelude_parser.types import FieldInfo, FlatFormInfo
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class _MetaCls(type):
|
|
13
|
+
def __new__(
|
|
14
|
+
cls, clsname: str, superclasses: tuple[type, ...], attributedict: dict[str, FieldInfo]
|
|
15
|
+
) -> _MetaCls:
|
|
16
|
+
return super().__new__(cls, clsname, superclasses, attributedict)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def parse_to_dict(xml_file: str | Path, *, short_names: bool = False) -> dict[str, FlatFormInfo]:
|
|
20
|
+
"""Parse a Prelude flat XML file into a dict.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
xml_file: The path to the XML file to parser.
|
|
24
|
+
short_names: Set to True if short names were used in the export.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
A Python dictionary containing the data from the XML file.
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
>>> from prelude_parser import parse_to_dict
|
|
31
|
+
>>> data = parse_to_dict("physical_examination.xml")
|
|
32
|
+
"""
|
|
33
|
+
return _parse_flat_file_to_dict(xml_file, short_names)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def parse_to_classes(xml_file: str | Path, short_names: bool = False) -> list[Any]:
|
|
37
|
+
"""Parse a Prelude flat XML file into a list of Python class.
|
|
38
|
+
|
|
39
|
+
The name of the class is taken from the form name node in the XML file converted to pascal case.
|
|
40
|
+
For example a <physical_examination> node will result in a PhysicalExamination class being
|
|
41
|
+
created.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
xml_file: The path to the XML file to parser.
|
|
45
|
+
short_names: Set to True if short names were used in the export.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
A list of Python classes containing the data from the XML file.
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
>>> from prelude_parser import parse_to_classes
|
|
52
|
+
>>> data = parse_to_classes("physical_examination.xml")
|
|
53
|
+
"""
|
|
54
|
+
parsed = parse_to_dict(xml_file, short_names=short_names)
|
|
55
|
+
formatted: list[Any] = []
|
|
56
|
+
for form, data in parsed.items():
|
|
57
|
+
class_name = to_pascal(form)
|
|
58
|
+
for d in data:
|
|
59
|
+
formatted.append(_MetaCls(class_name, (object,), d))
|
|
60
|
+
|
|
61
|
+
return formatted
|
prelude_parser/polars.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from prelude_parser._prelude_parser import _parse_flat_file_to_pandas_dict
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
import polars as pl
|
|
9
|
+
except ImportError as e: # pragma: no cover
|
|
10
|
+
raise ImportError(
|
|
11
|
+
"prelude-parser must be installed with the polars or all extra to use pandas"
|
|
12
|
+
) from e
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def to_dataframe(xml_file: str | Path, *, short_names: bool = False) -> pl.DataFrame:
|
|
16
|
+
"""Parse a Prelude flat XML file into a Polars DataFrame.
|
|
17
|
+
|
|
18
|
+
This works for Prelude flat XML files that were exported with the "write tables to seperate
|
|
19
|
+
files" option.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
xml_file: The path to the XML file to parser.
|
|
23
|
+
short_names: Set to True if short names were used in the export.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
A Polars DataFrame the data from the XML file.
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
>>> from prelude_parser.polars import to_dataframe
|
|
30
|
+
>>> df = to_dataframe("physical_examination.xml")
|
|
31
|
+
"""
|
|
32
|
+
data = _parse_flat_file_to_pandas_dict(xml_file, short_names)
|
|
33
|
+
return pl.from_dict(data)
|
prelude_parser/py.typed
ADDED
|
File without changes
|
prelude_parser/types.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: prelude-parser
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Dist: camel-converter >=3.0.0
|
|
14
|
+
Requires-Dist: pandas >=2.1.0 ; python_version > '3.8' and extra == 'pandas'
|
|
15
|
+
Requires-Dist: polars >=0.17.14 ; extra == 'polars'
|
|
16
|
+
Requires-Dist: pandas >=2.1.0 ; python_version > '3.8' and extra == 'all'
|
|
17
|
+
Requires-Dist: polars >=0.17.14 ; extra == 'all'
|
|
18
|
+
Provides-Extra: pandas
|
|
19
|
+
Provides-Extra: polars
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Summary: Parses XML files exported from Prelude EDC into formats usable by Python.
|
|
23
|
+
Keywords: parser,prelude-edc,xml,pandas,polars
|
|
24
|
+
Home-Page: https://github.com/pbs-data-solutions/prelude-parser
|
|
25
|
+
Author-email: Paul Sanders <paul@pbsdatasolutions.com>
|
|
26
|
+
License: MIT
|
|
27
|
+
Requires-Python: >=3.8
|
|
28
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
29
|
+
Project-URL: Source Code, https://github.com/pbs-data-solutions/prelude-parser
|
|
30
|
+
|
|
31
|
+
# Prelude Parser
|
|
32
|
+
|
|
33
|
+
[](https://github.com/pbs-data-solutions/prelude-parser/actions?query=workflow%3ATesting+branch%3Amain+event%3Apush)
|
|
34
|
+
[](https://results.pre-commit.ci/latest/github/pbs-data-solutions/prelude-parser/main)
|
|
35
|
+
[](https://codecov.io/gh/pbs-data-solutions/prelude-parser)
|
|
36
|
+
[](https://badge.fury.io/py/prelude-parser)
|
|
37
|
+
[](https://github.com/pbs-data-solutions/prelude-parser)
|
|
38
|
+
|
|
39
|
+
Parses XML files exported from [Prelude EDC](https://preludeedc.com/) into formats Python can use.
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
pip install prelude-parser
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Optionally the `pandas` extra can be installed to parse to a Pandas `DataFrame`
|
|
48
|
+
|
|
49
|
+
Note: Pandas only supports Python 3.9+ so this is not available in Python 3.8.
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
pip install prelude-parser[pandas]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Optionally the `polars` extra can be installed to parse to a Polars `DataFrame`
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
pip install prelude-parser[polars]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
All extras can be install with
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
pip install prelude-parser[all]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
Parse a Prelude flat XML file to a Python dictionary.
|
|
70
|
+
|
|
71
|
+
```py
|
|
72
|
+
from prelude_parser import parse_to_dict
|
|
73
|
+
data = parse_to_dict("physical_examination.xml")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Parse a Prelude flat XML file into a list of Python class. The name of the class is taken from the
|
|
77
|
+
form name node in the XML file converted to pascal case. For example a <physical_examination> node
|
|
78
|
+
will result in a PhysicalExamination class being created.
|
|
79
|
+
|
|
80
|
+
```py
|
|
81
|
+
from prelude_parser import parse_to_classes
|
|
82
|
+
data = parse_to_classes("physical_examination.xml")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Parse a Prelude flat XML file into a Pandas DataFrame. This works for Prelude flat XML files that
|
|
86
|
+
were exported with the "write tables to seperate files" option. In order to use this option
|
|
87
|
+
`prelude-parser` either needs to be installed with the `pandas` extra or the `all` extras.
|
|
88
|
+
|
|
89
|
+
```py
|
|
90
|
+
from prelude_parser.pandas import to_dataframe
|
|
91
|
+
df = to_dataframe("physical_examination.xml")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Parse a Prelude flat XML file into a Polars DataFrame. This works for Prelude flat XML files that
|
|
95
|
+
were exported with the "write tables to seperate files" option. In order to use this option
|
|
96
|
+
`prelude-parser` either needs to be installed with the `polars` extra or the `all` extras.
|
|
97
|
+
|
|
98
|
+
```py
|
|
99
|
+
from prelude_parser.polars import to_dataframe
|
|
100
|
+
df = to_dataframe("physical_examination.xml")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Contributing
|
|
104
|
+
|
|
105
|
+
Contributions to this project are welcome. If you are interesting in contributing please see our [contributing guide](CONTRIBUTING.md)
|
|
106
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
prelude_parser-0.5.0.dist-info/METADATA,sha256=poG7a-fylhAH74To1Fxp5BjiioKUosdOzDuzRqFQXpw,4272
|
|
2
|
+
prelude_parser-0.5.0.dist-info/WHEEL,sha256=lTVQXmazV4_utY20nrWmfqVmjb3H_3iP6bNgox5pvtU,94
|
|
3
|
+
prelude_parser-0.5.0.dist-info/license_files/LICENSE,sha256=nPoa6xHUnYfbIECNiUa6tbFxR6anYAG_v_D7Zc3f4FI,1101
|
|
4
|
+
prelude_parser/pandas.py,sha256=GDat5_S7Qvb_lsgHPUtj_3BgoP9WFNXcnIbLHLtwfx4,1308
|
|
5
|
+
prelude_parser/parser.py,sha256=ohiAfA25KIwKn9wt25-J07SHjsTV1j9XY5aXaem489o,2110
|
|
6
|
+
prelude_parser/polars.py,sha256=RozgFUgfmXAAAD3SNaGQofk5woOduFjXT5Ams7WtFCY,1076
|
|
7
|
+
prelude_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
prelude_parser/types.py,sha256=Gd47nkP_Jg8Itek1L81XZfQgTUrfW9lHvzsMi0OJuc8,178
|
|
9
|
+
prelude_parser/_prelude_parser.pyi,sha256=agrMTe_kH4Fe9KfQNkRYU6OsiMqDAKkub2n2GeW4430,652
|
|
10
|
+
prelude_parser/__init__.py,sha256=uMcSIjxI5h1co4fCVIaoC97IR8cy8TRLjg9yNxjYK_c,217
|
|
11
|
+
prelude_parser/_prelude_parser.cp38-win_amd64.pyd,sha256=rNMncN8krldY-DAsRe9MkF0NaQzag2_P7OoNakH446c,881664
|
|
12
|
+
prelude_parser-0.5.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 PBS Data Solutions, LLC
|
|
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.
|