zs-yaml 0.3.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.
zs_yaml-0.3.0/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, NDS e.V. Association
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,26 @@
1
+ # Explicitly include specific files from the root directory
2
+ include README.md
3
+ include requirements.txt
4
+ include LICENSE
5
+
6
+ # Include all Python files in the package directory and subdirectories
7
+ recursive-include zs_yaml *.py
8
+
9
+ # Include all documentation resources
10
+ recursive-include docs *
11
+
12
+ # Exclude cache directories
13
+ prune **/__pycache__
14
+ prune **/.cache
15
+
16
+ # Exclude version control directories
17
+ prune .git
18
+
19
+ # Exclude test directories
20
+ prune **/tests
21
+
22
+ # Exclude development and IDE-specific files
23
+ global-exclude .DS_Store
24
+ global-exclude *.swp
25
+ global-exclude .vscode
26
+ global-exclude .idea
zs_yaml-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.1
2
+ Name: zs-yaml
3
+ Version: 0.3.0
4
+ Summary: A package that allows using yaml to define zserio objects.
5
+ Home-page: https://github.com/ndsev/zs_yaml
6
+ Author: Navigation Data Standard e.V.
7
+ Author-email: support@nds-association.org
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: PyYAML~=6.0
15
+ Requires-Dist: zserio~=2.12
16
+
17
+ # `zs-yaml`
18
+
19
+ *Your Easy Path to zserio Test Data*
20
+
21
+ <img src="doc/zs-yaml.png" alt="" height="100">
22
+
23
+ **zs-yaml** adds YAML as a text format to be used with zserio in order to improve the user experience when manually creating or analyzing test data for zserio.
24
+
25
+ - **YAML Format**: Uses YAML's human-readable format instead of JSON as the primary format for editing, making data handling and transformation more intuitive and less cluttered.
26
+ - **Metadata Inclusion**: Automatically includes metadata in the YAML, eliminating the need for users to manually identify the correct type when importing JSON data, ensuring seamless (de-)serialization.
27
+ - **Custom Transformations**: Allows for hooking in custom transformations so that users can work with familiar formats (e.g., dates or coordinate representations) instead of thinking in unfamiliar formats.
28
+
29
+ ## Example
30
+
31
+ ### Zserio Schema Module Creation
32
+
33
+ 1. **Create the Zserio schema**:
34
+ - Create a file named `person.zs` with the following content:
35
+
36
+ ```zserio
37
+ package person;
38
+
39
+ struct Person
40
+ {
41
+ string name;
42
+ string birthdate;
43
+ string birth_location;
44
+ string current_job;
45
+ int32 income;
46
+ RoleExperience experience[];
47
+ };
48
+
49
+ struct RoleExperience
50
+ {
51
+ string role;
52
+ int32 years;
53
+ };
54
+ ```
55
+
56
+ 2. **Compile the Zserio schema and generate Python APIs**:
57
+ - Run the following command to compile the schema and generate Python sources:
58
+
59
+ ```sh
60
+ # Generated sources needs type infos so that 'json <-> bin'
61
+ # conversion works, which is utilized by zs-yaml
62
+ zserio person.zs -withTypeInfoCode -python zs_gen_api
63
+ ```
64
+
65
+ 3. **Ensure that the schema modules are available in the Python environment**:
66
+ - Export the `PYTHONPATH` to include the directory containing the generated Python sources:
67
+
68
+ ```sh
69
+ export PYTHONPATH="zs_gen_api"
70
+ ```
71
+
72
+ ### Use zs-yaml to create data
73
+
74
+ Using **zs-yaml**, you can define the same data in a more human-readable YAML format and include necessary metadata along with a custom transformation for the birthdate:
75
+
76
+ ```yaml
77
+ # 1) Metadata is used to specify the type needed for
78
+ # (de-)serialization and custom transform functions
79
+ # 2) User are free to use their preferred date format
80
+ # for the birth data as the a normalization function
81
+ # get invoked.
82
+ # 3) Yaml allows avoiding clutter and adding comments
83
+ # like this one :)
84
+
85
+ _meta:
86
+ schema_module: person.api
87
+ schema_type: Person
88
+ transformation_module: "./transformations.py"
89
+
90
+ name: John Doe
91
+
92
+ birthdate:
93
+ _f: normalize_date
94
+ _a: "01/01/1990"
95
+ birth_location: Springfield, USA
96
+
97
+ current_job: Software Engineer
98
+ income: 75000
99
+
100
+ experience:
101
+ - role: Intern
102
+ years: 1
103
+ - role: Junior Developer
104
+ years: 2
105
+ - role: Senior Developer
106
+ years: 3
107
+ ```
108
+
109
+ #### Example Transformation Module (transformations.py)
110
+
111
+ ```python
112
+ def normalize_date(date_str):
113
+ from datetime import datetime
114
+ for fmt in ("%Y-%m-%d", "%d/%m/%Y", "%m/%d/%Y"):
115
+ try:
116
+ return datetime.strptime(date_str, fmt).strftime("%Y-%m-%d")
117
+ except ValueError:
118
+ pass
119
+ raise ValueError(f"Date {date_str} is not in a recognized format")
120
+ ```
121
+
122
+ #### Creating the Binary Representation
123
+
124
+ After you have installed `zs-yaml`, call `zs-yaml` to convert your YAML file to a binary representation:
125
+
126
+ ```sh
127
+ # Install zs-yaml if not already installed.
128
+
129
+ # Create the binary representation from the YAML file
130
+ zs-yaml person.yaml person.bin
131
+ ```
132
+
133
+ ## Installation
134
+
135
+ Currently, the Python package is only available at test.pypi. Once the official release is available,
136
+ you can install the package without specifying an index URL.
137
+
138
+ ```bash
139
+ python -m pip install --upgrade zs-yaml
140
+ ```
141
+
142
+ ## Usage
143
+
144
+ The main entry point for the application is `main.py`. It accepts arguments for specifying the input and output file paths. You can run the application as follows:
145
+
146
+ ```bash
147
+ zs-yaml input.yaml output.bin
148
+ zs-yaml input.bin output.yaml
149
+ ```
150
+
151
+ ### Notes
152
+
153
+ - You have to use the exact same order of field in the yaml as defined by the zserio schema, because zserio expects this
154
+ - When converting from binary to YAML, the target YAML file must already exist and contain the necessary metadata.
155
+ - The minimal metadata content in the target YAML file should be:
156
+
157
+ ```yaml
158
+ _meta:
159
+ schema_module: <module_name>
160
+ schema_type: <type_name>
161
+ ```
162
+
163
+ ### Future Considerations
164
+
165
+ In the future, we may consider using YAML tags for a more integrated approach to handling transformations directly within the YAML files, simplifying syntax and enhancing readability.
166
+
167
+ ## Project Structure
168
+
169
+ - `setup.py`: Script for setting up the project and installing dependencies.
170
+ - `zs_yaml/`: Directory containing the actual `zs-yaml` implementation.
171
+
172
+ ## Reference
173
+
174
+ This project references the zserio serialization framework. For more information about zserio, visit the [zserio GitHub project](https://github.com/ndsev/zserio).
@@ -0,0 +1,158 @@
1
+ # `zs-yaml`
2
+
3
+ *Your Easy Path to zserio Test Data*
4
+
5
+ <img src="doc/zs-yaml.png" alt="" height="100">
6
+
7
+ **zs-yaml** adds YAML as a text format to be used with zserio in order to improve the user experience when manually creating or analyzing test data for zserio.
8
+
9
+ - **YAML Format**: Uses YAML's human-readable format instead of JSON as the primary format for editing, making data handling and transformation more intuitive and less cluttered.
10
+ - **Metadata Inclusion**: Automatically includes metadata in the YAML, eliminating the need for users to manually identify the correct type when importing JSON data, ensuring seamless (de-)serialization.
11
+ - **Custom Transformations**: Allows for hooking in custom transformations so that users can work with familiar formats (e.g., dates or coordinate representations) instead of thinking in unfamiliar formats.
12
+
13
+ ## Example
14
+
15
+ ### Zserio Schema Module Creation
16
+
17
+ 1. **Create the Zserio schema**:
18
+ - Create a file named `person.zs` with the following content:
19
+
20
+ ```zserio
21
+ package person;
22
+
23
+ struct Person
24
+ {
25
+ string name;
26
+ string birthdate;
27
+ string birth_location;
28
+ string current_job;
29
+ int32 income;
30
+ RoleExperience experience[];
31
+ };
32
+
33
+ struct RoleExperience
34
+ {
35
+ string role;
36
+ int32 years;
37
+ };
38
+ ```
39
+
40
+ 2. **Compile the Zserio schema and generate Python APIs**:
41
+ - Run the following command to compile the schema and generate Python sources:
42
+
43
+ ```sh
44
+ # Generated sources needs type infos so that 'json <-> bin'
45
+ # conversion works, which is utilized by zs-yaml
46
+ zserio person.zs -withTypeInfoCode -python zs_gen_api
47
+ ```
48
+
49
+ 3. **Ensure that the schema modules are available in the Python environment**:
50
+ - Export the `PYTHONPATH` to include the directory containing the generated Python sources:
51
+
52
+ ```sh
53
+ export PYTHONPATH="zs_gen_api"
54
+ ```
55
+
56
+ ### Use zs-yaml to create data
57
+
58
+ Using **zs-yaml**, you can define the same data in a more human-readable YAML format and include necessary metadata along with a custom transformation for the birthdate:
59
+
60
+ ```yaml
61
+ # 1) Metadata is used to specify the type needed for
62
+ # (de-)serialization and custom transform functions
63
+ # 2) User are free to use their preferred date format
64
+ # for the birth data as the a normalization function
65
+ # get invoked.
66
+ # 3) Yaml allows avoiding clutter and adding comments
67
+ # like this one :)
68
+
69
+ _meta:
70
+ schema_module: person.api
71
+ schema_type: Person
72
+ transformation_module: "./transformations.py"
73
+
74
+ name: John Doe
75
+
76
+ birthdate:
77
+ _f: normalize_date
78
+ _a: "01/01/1990"
79
+ birth_location: Springfield, USA
80
+
81
+ current_job: Software Engineer
82
+ income: 75000
83
+
84
+ experience:
85
+ - role: Intern
86
+ years: 1
87
+ - role: Junior Developer
88
+ years: 2
89
+ - role: Senior Developer
90
+ years: 3
91
+ ```
92
+
93
+ #### Example Transformation Module (transformations.py)
94
+
95
+ ```python
96
+ def normalize_date(date_str):
97
+ from datetime import datetime
98
+ for fmt in ("%Y-%m-%d", "%d/%m/%Y", "%m/%d/%Y"):
99
+ try:
100
+ return datetime.strptime(date_str, fmt).strftime("%Y-%m-%d")
101
+ except ValueError:
102
+ pass
103
+ raise ValueError(f"Date {date_str} is not in a recognized format")
104
+ ```
105
+
106
+ #### Creating the Binary Representation
107
+
108
+ After you have installed `zs-yaml`, call `zs-yaml` to convert your YAML file to a binary representation:
109
+
110
+ ```sh
111
+ # Install zs-yaml if not already installed.
112
+
113
+ # Create the binary representation from the YAML file
114
+ zs-yaml person.yaml person.bin
115
+ ```
116
+
117
+ ## Installation
118
+
119
+ Currently, the Python package is only available at test.pypi. Once the official release is available,
120
+ you can install the package without specifying an index URL.
121
+
122
+ ```bash
123
+ python -m pip install --upgrade zs-yaml
124
+ ```
125
+
126
+ ## Usage
127
+
128
+ The main entry point for the application is `main.py`. It accepts arguments for specifying the input and output file paths. You can run the application as follows:
129
+
130
+ ```bash
131
+ zs-yaml input.yaml output.bin
132
+ zs-yaml input.bin output.yaml
133
+ ```
134
+
135
+ ### Notes
136
+
137
+ - You have to use the exact same order of field in the yaml as defined by the zserio schema, because zserio expects this
138
+ - When converting from binary to YAML, the target YAML file must already exist and contain the necessary metadata.
139
+ - The minimal metadata content in the target YAML file should be:
140
+
141
+ ```yaml
142
+ _meta:
143
+ schema_module: <module_name>
144
+ schema_type: <type_name>
145
+ ```
146
+
147
+ ### Future Considerations
148
+
149
+ In the future, we may consider using YAML tags for a more integrated approach to handling transformations directly within the YAML files, simplifying syntax and enhancing readability.
150
+
151
+ ## Project Structure
152
+
153
+ - `setup.py`: Script for setting up the project and installing dependencies.
154
+ - `zs_yaml/`: Directory containing the actual `zs-yaml` implementation.
155
+
156
+ ## Reference
157
+
158
+ This project references the zserio serialization framework. For more information about zserio, visit the [zserio GitHub project](https://github.com/ndsev/zserio).
zs_yaml-0.3.0/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.3
Binary file
@@ -0,0 +1,90 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
3
+ viewBox="0 0 76.940711 22.655753"
4
+ id="zserio-logo"
5
+ version="1.1"
6
+ sodipodi:docname="zs-yaml.svg"
7
+ width="76.940712"
8
+ height="22.655754"
9
+ inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
10
+ xml:space="preserve"
11
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ xmlns:svg="http://www.w3.org/2000/svg"
15
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
16
+ xmlns:cc="http://creativecommons.org/ns#"
17
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
18
+ id="metadata21"><rdf:RDF><cc:Work
19
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
20
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
21
+ id="defs19" /><sodipodi:namedview
22
+ pagecolor="#ffffff"
23
+ bordercolor="#666666"
24
+ borderopacity="1"
25
+ objecttolerance="10"
26
+ gridtolerance="10"
27
+ guidetolerance="10"
28
+ inkscape:pageopacity="0"
29
+ inkscape:pageshadow="2"
30
+ inkscape:window-width="1920"
31
+ inkscape:window-height="935"
32
+ id="namedview17"
33
+ showgrid="false"
34
+ inkscape:zoom="5.6462916"
35
+ inkscape:cx="29.134167"
36
+ inkscape:cy="0.79698329"
37
+ inkscape:window-x="0"
38
+ inkscape:window-y="32"
39
+ inkscape:window-maximized="1"
40
+ inkscape:showpageshadow="2"
41
+ inkscape:pagecheckerboard="0"
42
+ inkscape:deskcolor="#d1d1d1"
43
+ inkscape:current-layer="zserio-logo" /><rect
44
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.444658"
45
+ id="rect3"
46
+ width="76.940712"
47
+ height="22.655754"
48
+ x="0"
49
+ y="0" /><g
50
+ id="zserio-logo-serio"
51
+ fill="currentColor"
52
+ transform="matrix(0.96869663,0,0,0.96869663,5.4172856,2.76989)"><path
53
+ d="m 21.733415,11.886839 q 0,1.508249 -1.251904,2.474278 -1.242093,0.966048 -3.400868,0.966048 -1.222375,0 -2.24756,-0.285874 -1.015376,-0.295725 -1.705339,-0.640746 v -2.079999 h 0.09857 q 0.877324,0.660455 1.951776,1.054813 1.074434,0.38445 2.06028,0.38445 1.222375,0 1.912339,-0.394309 0.689963,-0.394309 0.690033,-1.242094 0,-0.650605 -0.37459,-0.985767 -0.37459,-0.335162 -1.439184,-0.571739 -0.394309,-0.08872 -1.035094,-0.207009 -0.630886,-0.118294 -1.153309,-0.256297 -1.449092,-0.384449 -2.06028,-1.1237795 -0.601318,-0.74918 -0.601318,-1.8335618 0,-0.6801737 0.276016,-1.2815312 0.285874,-0.6013179 0.857614,-1.0744331 0.552031,-0.4633054 1.399746,-0.7294612 0.857614,-0.2760152 1.912338,-0.2760152 0.985757,0 1.991214,0.2464369 1.015375,0.2365873 1.68562,0.5815989 V 6.593252 h -0.09857 Q 20.491193,6.0707998 19.475886,5.7159287 18.460511,5.3511981 17.484672,5.3511981 q -1.015375,0 -1.715248,0.394309 -0.699893,0.3844494 -0.699893,1.1533088 0,0.6801737 0.423878,1.0251853 0.414018,0.3450117 1.340589,0.5618801 0.512592,0.1182937 1.143499,0.2365873 0.640745,0.1182937 1.064623,0.2168685 1.291341,0.2957242 1.991214,1.0153751 0.699893,0.7294608 0.699893,1.9320578 z"
54
+ inkscape:connector-curvature="0"
55
+ id="path5" /></g><path
56
+ id="zserio-logo-z"
57
+ d="M 16.939948,17.513033 H 6.5404496 V 15.235944 L 12.376159,9.0354854 H 6.7770766 V 6.442894 H 16.831742 v 2.2376514 l -5.747023,6.1905486 h 5.855427 z"
58
+ inkscape:connector-curvature="0"
59
+ style="fill:#ff0000" /><g
60
+ id="g2"
61
+ transform="matrix(0.08129594,0,0,0.08129594,82.698086,11.100326)"><g
62
+ id="g1"
63
+ transform="matrix(1.3333333,0,0,1.3333333,-558.97901,-69.293599)"><polygon
64
+ points="1,109 73,1 258,1 258,19 318,109 "
65
+ style="fill:#ffffff;stroke:#000000;stroke-width:1"
66
+ id="polygon1" /><polygon
67
+ points="1,109 37,55 1,1 25,1 49,37 73,1 97,1 25,109 "
68
+ style="fill:#000000;stroke:#000000;stroke-width:1"
69
+ id="polygon2" /><polygon
70
+ points="127,1 103,1 31,109 55,109 103,37 103,109 127,109 "
71
+ style="fill:#000000;stroke:#000000;stroke-width:1"
72
+ id="polygon3" /><polygon
73
+ points="228,1 198,1 180,37 156,1 132,1 132,109 156,109 156,37 180,73 204,37 204,109 228,109 "
74
+ style="fill:#000000;stroke:#000000;stroke-width:1"
75
+ id="polygon4" /><polygon
76
+ points="318,109 302,85 258,85 258,1 234,1 234,109 "
77
+ style="fill:#000000;stroke:#000000;stroke-width:1"
78
+ id="polygon5" /></g></g><rect
79
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.784084"
80
+ id="rect2"
81
+ width="6.5856104"
82
+ height="1.8180964"
83
+ x="29.616592"
84
+ y="10.931295" /><rect
85
+ style="fill:none;fill-opacity:1;stroke:#311620;stroke-width:0.721635;stroke-opacity:0.642554"
86
+ id="rect4"
87
+ width="73.180183"
88
+ height="19.131836"
89
+ x="2.0607479"
90
+ y="1.8520763" /></svg>
@@ -0,0 +1,2 @@
1
+ PyYAML~=6.0
2
+ zserio~=2.12
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
zs_yaml-0.3.0/setup.py ADDED
@@ -0,0 +1,78 @@
1
+ import os
2
+ from setuptools import setup, find_packages
3
+ import subprocess
4
+
5
+
6
+ # Utility function to read file content into a string
7
+ def read(fname):
8
+ return open(os.path.join(os.path.dirname(__file__), fname),
9
+ 'r', encoding='utf-8').read()
10
+
11
+ # DOCUMENTATION
12
+ def read_for_pypi(fname):
13
+ """Read a file and replace relative image URLs with absolute URLs."""
14
+ content = read(fname)
15
+ # Replace relative image URLs with absolute URLs
16
+ # Adjust the base URL to where your images are actually hosted
17
+ base_url = "https://raw.githubusercontent.com/ndsev/zs_yaml/main/"
18
+ content = content.replace("](images/", f"]({base_url}images/")
19
+ return content
20
+
21
+
22
+ # REQUIREMENTS
23
+ def read_requirements(fname):
24
+ return [line.strip() for line in read(fname).splitlines() if line.strip() and not line.startswith('#')]
25
+
26
+ # VERSION INFO
27
+ def get_version_info():
28
+ version_file = os.path.join(os.path.dirname(__file__), 'zs_yaml', '_version.py')
29
+ version_info = {}
30
+ with open(version_file, 'r', encoding='utf-8') as f:
31
+ exec(f.read(), version_info)
32
+
33
+ # Get the Git commit ID if possible
34
+ try:
35
+ commit_id = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('ascii').strip()
36
+ version_info['__commit_id__'] = commit_id
37
+ except:
38
+ pass # If Git is not available or not a Git repository, use the default "unknown"
39
+
40
+ return version_info
41
+
42
+ version_info = get_version_info()
43
+
44
+ # Write the updated version info back to the file
45
+ with open(os.path.join('zs_yaml', '_version.py'), 'w', encoding='utf-8') as f:
46
+ f.write(f"__version__ = '{version_info['__version__']}'\n")
47
+ f.write(f"__commit_id__ = '{version_info['__commit_id__']}'\n")
48
+
49
+
50
+ setup(
51
+ name='zs-yaml',
52
+ version=version_info['__version__'],
53
+ author="Navigation Data Standard e.V.",
54
+ author_email="support@nds-association.org",
55
+ description='A package that allows using yaml to define zserio objects.',
56
+ long_description=read_for_pypi('README.md'),
57
+ long_description_content_type="text/markdown",
58
+ url="https://github.com/ndsev/zs_yaml",
59
+ packages=find_packages(),
60
+ install_requires=read_requirements('requirements.txt'),
61
+ classifiers=[
62
+ "Programming Language :: Python :: 3",
63
+ "License :: OSI Approved :: MIT License",
64
+ "Operating System :: OS Independent",
65
+ ],
66
+ python_requires='>=3.8',
67
+ entry_points={
68
+ 'console_scripts': [
69
+ 'zs-yaml=zs_yaml.main:main'
70
+ ],
71
+ },
72
+ include_package_data=True,
73
+ package_data={
74
+ 'zs_yaml': ['images/*'],
75
+ },
76
+ ext_modules=[],
77
+ cmdclass={}
78
+ )
@@ -0,0 +1,6 @@
1
+ from .convert import yaml_to_json, yaml_to_bin, bin_to_yaml, json_to_yaml
2
+ from .yaml_transformer import YamlTransformer
3
+ from ._version import __version__, __commit_id__
4
+
5
+ def get_version_info():
6
+ return f"{__version__} (commit: {__commit_id__})"
@@ -0,0 +1,2 @@
1
+ __version__ = '0.3.0'
2
+ __commit_id__ = 'a89ec0a'
@@ -0,0 +1,75 @@
1
+ import json
2
+ import importlib
3
+ import zserio
4
+ import yaml
5
+ import copy
6
+
7
+ def insert_yaml_as_extern(transformer, file, template_args=None):
8
+ """
9
+ Include external YAML by transforming it to JSON and using zserio.
10
+
11
+ Args:
12
+ transformer (YamlTransformer): The transformer instance.
13
+ file (str): Path to the external YAML file.
14
+ template_args (dict, optional): A dictionary of template arguments for placeholder replacement.
15
+
16
+ Returns:
17
+ dict: A dictionary containing the binary data and its bit size.
18
+ """
19
+ abs_path = transformer.resolve_path(file)
20
+ external_transformer = transformer.__class__(abs_path, template_args, initial_transformations=transformer.transformations)
21
+ processed_data = external_transformer.transform()
22
+ meta = external_transformer.get_meta()
23
+
24
+ schema_module = meta.get('schema_module')
25
+ schema_type = meta.get('schema_type')
26
+
27
+ if not schema_module or not schema_type:
28
+ raise ValueError(f"Error: schema_module and schema_type must be specified in the _meta section of the YAML file: {file}")
29
+
30
+ json_string = json.dumps(processed_data)
31
+
32
+ # Convert JSON to binary using zserio
33
+ module = importlib.import_module(schema_module)
34
+ ImportedType = getattr(module, schema_type)
35
+ zserio_object = zserio.from_json_string(ImportedType, json_string)
36
+ writer = zserio.BitStreamWriter()
37
+ zserio_object.write(writer)
38
+ bits = zserio.BitBuffer(writer.byte_array, writer.bitposition)
39
+
40
+ # Encode the binary data
41
+ encoded_bytes = list(bits.buffer)
42
+ data = {"buffer": encoded_bytes, "bitSize": bits.bitsize}
43
+
44
+ return data
45
+
46
+ def insert_yaml(transformer, file, template_args=None):
47
+ """
48
+ Insert YAML content directly without converting to binary.
49
+
50
+ Args:
51
+ transformer (YamlTransformer): The transformer instance.
52
+ file (str): Path to the external YAML file.
53
+ template_args (dict, optional): A dictionary of template arguments for placeholder replacement.
54
+
55
+ Returns:
56
+ dict: The processed YAML data.
57
+ """
58
+ abs_path = transformer.resolve_path(file)
59
+ external_transformer = transformer.__class__(abs_path, template_args, initial_transformations=transformer.transformations)
60
+ processed_data = external_transformer.transform()
61
+ return processed_data
62
+
63
+ def repeat_node(transformer, node, count):
64
+ """
65
+ Repeat a specific node n times and return as a list.
66
+
67
+ Args:
68
+ transformer (YamlTransformer): The transformer instance.
69
+ node: The node to be repeated.
70
+ count (int): The number of times to repeat the node.
71
+
72
+ Returns:
73
+ list: A list containing the repeated node.
74
+ """
75
+ return [copy.deepcopy(node) for _ in range(count)]
@@ -0,0 +1,164 @@
1
+ """
2
+ This module contains the logic to cover the following conversions:
3
+ - yaml to bin: Converts a YAML file to a binary file using zserio serialization.
4
+ Custom transformations can be applied to the YAML data before conversion.
5
+ - bin to yaml: Converts a binary file to a YAML file using zserio deserialization.
6
+ The conversion requires the schema module and type information to be
7
+ specified in the _meta section of the YAML file.
8
+ - json to yaml: Converts a JSON file to a YAML file. This is a plain conversion without
9
+ applying any transformations.
10
+ - yaml to json: Converts a YAML file to a JSON file. Custom transformations can be applied
11
+ to the YAML data before conversion.
12
+ """
13
+
14
+ import yaml
15
+ import json
16
+ import importlib
17
+ import zserio
18
+ import tempfile
19
+ import os
20
+
21
+ from .yaml_transformer import YamlTransformer
22
+
23
+ def _json_to_zs_bin(json_input_path, bin_output_path, module_name, type_name):
24
+ """
25
+ Converts a JSON file to a binary file using Zserio serialization.
26
+
27
+ Args:
28
+ json_input_path (str): Path to the input JSON file.
29
+ bin_output_path (str): Path to the output binary file.
30
+ module_name (str): Name of the Zserio module containing the schema.
31
+ type_name (str): Name of the Zserio type to be used for serialization.
32
+
33
+ Raises:
34
+ ValueError: If the specified Zserio type is not found in the module.
35
+ """
36
+ module = importlib.import_module(module_name)
37
+ ImportedType = getattr(module, type_name)
38
+ if ImportedType is None:
39
+ raise ValueError(f"Type {type_name} not found in module {module_name}")
40
+ zserio_object = zserio.from_json_file(ImportedType, json_input_path)
41
+ zserio.serialize_to_file(zserio_object, bin_output_path)
42
+
43
+ def yaml_to_yaml(yaml_input_path, yaml_output_path=None):
44
+ """
45
+ Applies all transformations and template substitution to
46
+ the input YAML to come up with the output YAML.
47
+
48
+ Args:
49
+ yaml_input_path (str): Path to the input YAML file.
50
+ yaml_output_path (str): Path to the output YAML file.
51
+ """
52
+ transformer = YamlTransformer(yaml_input_path)
53
+ transformed_data = transformer.transform()
54
+ meta = transformer.get_meta()
55
+
56
+ if yaml_output_path:
57
+ output_data = {'_meta': meta}
58
+ output_data.update(transformed_data)
59
+ with open(yaml_output_path, 'w') as yaml_file:
60
+ yaml.dump(output_data, yaml_file, default_flow_style=False, sort_keys=False)
61
+
62
+ return transformed_data, meta
63
+
64
+
65
+ def yaml_to_json(yaml_input_path, json_output_path):
66
+ """
67
+ Converts a YAML file to a JSON file.
68
+
69
+ Args:
70
+ yaml_input_path (str): Path to the input YAML file.
71
+ json_output_path (str): Path to the output JSON file.
72
+
73
+ Returns:
74
+ dict: The _meta section from the YAML file, if present.
75
+ """
76
+ transformed_data, meta = yaml_to_yaml(yaml_input_path)
77
+
78
+ with open(json_output_path, 'w') as json_file:
79
+ json.dump(transformed_data, json_file, indent=2)
80
+
81
+ return meta
82
+
83
+
84
+ def json_to_yaml(json_input_path, yaml_output_path):
85
+ """
86
+ Converts a JSON file to a YAML file. This is a plain conversion without applying
87
+ any transformations.
88
+
89
+ Args:
90
+ json_input_path (str): Path to the input JSON file.
91
+ yaml_output_path (str): Path to the output YAML file.
92
+ """
93
+ with open(json_input_path, 'r') as json_file:
94
+ data = json.load(json_file)
95
+ with open(yaml_output_path, 'w') as yaml_file:
96
+ yaml.safe_dump(data, yaml_file, default_flow_style=False, sort_keys=False)
97
+
98
+
99
+ def yaml_to_bin(yaml_input_path, bin_output_path):
100
+ """
101
+ Converts a YAML file to a binary file using Zserio serialization.
102
+
103
+ Args:
104
+ yaml_input_path (str): Path to the input YAML file.
105
+ bin_output_path (str): Path to the output binary file.
106
+
107
+ Raises:
108
+ ValueError: If schema_module and schema_type are not specified in the _meta
109
+ section of the YAML file.
110
+ """
111
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as temp_json_file:
112
+ temp_json_path = temp_json_file.name
113
+
114
+ try:
115
+ meta = yaml_to_json(yaml_input_path, temp_json_path)
116
+
117
+ schema_module = meta.get('schema_module')
118
+ schema_type = meta.get('schema_type')
119
+
120
+ if not schema_module or not schema_type:
121
+ raise ValueError("Error: schema_module and schema_type must be specified in the _meta section for binary output")
122
+
123
+ _json_to_zs_bin(temp_json_path, bin_output_path, schema_module, schema_type)
124
+ finally:
125
+ os.remove(temp_json_path)
126
+
127
+
128
+ def bin_to_yaml(bin_input_path, yaml_output_path):
129
+ """
130
+ Converts a binary file to a YAML file using Zserio deserialization.
131
+
132
+ Args:
133
+ bin_input_path (str): Path to the input binary file.
134
+ yaml_output_path (str): Path to the output YAML file.
135
+
136
+ Raises:
137
+ ValueError: If schema_module and schema_type are not specified in the _meta
138
+ section of the YAML file, or if the specified Zserio type is not found
139
+ in the module.
140
+ """
141
+ with open(yaml_output_path, 'r') as yaml_file:
142
+ meta = yaml.safe_load(yaml_file)
143
+
144
+ schema_module = meta.get('_meta', {}).get('schema_module')
145
+ schema_type = meta.get('_meta', {}).get('schema_type')
146
+ if not schema_module or not schema_type:
147
+ raise ValueError("Error: schema_module and schema_type must be specified in the _meta section of the YAML file")
148
+
149
+ module = importlib.import_module(schema_module)
150
+ ImportedType = getattr(module, schema_type)
151
+ if ImportedType is None:
152
+ raise ValueError(f"Type {schema_type} not found in module {schema_module}")
153
+
154
+ zserio_object = zserio.deserialize_from_file(ImportedType, bin_input_path)
155
+ json_data = zserio.to_json_string(zserio_object)
156
+
157
+ data = json.loads(json_data)
158
+
159
+ # Create a new dictionary to ensure _meta comes first
160
+ final_data = {'_meta': meta['_meta']}
161
+ final_data.update(data)
162
+
163
+ with open(yaml_output_path, 'w') as yaml_file:
164
+ yaml.safe_dump(final_data, yaml_file, default_flow_style=False, sort_keys=False)
@@ -0,0 +1,119 @@
1
+ import argparse
2
+ import traceback
3
+ import sys
4
+ import os
5
+ from zs_yaml.convert import (
6
+ yaml_to_bin,
7
+ bin_to_yaml,
8
+ yaml_to_json,
9
+ json_to_yaml,
10
+ yaml_to_yaml
11
+ )
12
+ from zs_yaml import get_version_info
13
+ import time
14
+
15
+ def parse_arguments():
16
+ parser = argparse.ArgumentParser(
17
+ formatter_class=argparse.RawTextHelpFormatter,
18
+
19
+ description=
20
+ f'%(prog)s {get_version_info()}\n\n'
21
+ 'Converts between YAML, JSON, and binary formats. '
22
+ 'To convert from binary to YAML, the target YAML file must already exist with metadata. '
23
+ 'The metadata is required to identify the correct Python type for deserialization.\n\n'
24
+ 'The minimal metadata content in the target YAML file should be:\n'
25
+ ' _meta:\n'
26
+ ' schema_module: <module_name>\n'
27
+ ' schema_type: <type_name>',
28
+
29
+ usage='%(prog)s <input_path> [output_path]\n\n'
30
+ 'Example usage:\n'
31
+ ' %(prog)s input.yaml output.bin\n'
32
+ ' %(prog)s input.bin output.yaml\n'
33
+ ' %(prog)s input.yaml output.json\n'
34
+ ' %(prog)s input.json output.yaml\n'
35
+ ' %(prog)s input.yaml (output will be inferred as binary if not specified)'
36
+ )
37
+ parser.add_argument('input_path', type=str, help='Path to the input file (YAML, JSON, or binary)')
38
+ parser.add_argument('output_path', type=str, nargs='?', help='Path to the output file (YAML, JSON, or binary)')
39
+ parser.add_argument('--version', action='version', version=f'%(prog)s {get_version_info()}')
40
+
41
+ if len(sys.argv) < 2:
42
+ parser.print_help(sys.stderr)
43
+ sys.exit(1)
44
+
45
+ return parser.parse_args()
46
+
47
+ def process_yaml_input(input_path, output_path):
48
+ if not output_path:
49
+ output_extension = '.bin'
50
+ output_path = os.path.splitext(input_path)[0] + output_extension
51
+ else:
52
+ output_extension = os.path.splitext(output_path)[1].lower()
53
+
54
+ if output_extension == '.bin' or output_extension == '':
55
+ yaml_to_bin(input_path, output_path)
56
+ elif output_extension == '.json':
57
+ yaml_to_json(input_path, output_path)
58
+ elif output_extension == '.yaml':
59
+ yaml_to_yaml(input_path, output_path)
60
+ else:
61
+ raise ValueError("Unsupported output file extension for YAML input")
62
+
63
+ return output_path
64
+
65
+ def process_binary_input(input_path, output_path):
66
+ if not output_path:
67
+ raise ValueError("Output path must be specified for binary input")
68
+ bin_to_yaml(input_path, output_path)
69
+ return output_path
70
+
71
+ def process_json_input(input_path, output_path):
72
+ if not output_path:
73
+ output_extension = '.yaml'
74
+ output_path = os.path.splitext(input_path)[0] + output_extension
75
+ else:
76
+ output_extension = os.path.splitext(output_path)[1].lower()
77
+
78
+ if output_extension == '.yaml':
79
+ json_to_yaml(input_path, output_path)
80
+ else:
81
+ raise ValueError("Unsupported output file extension for JSON input")
82
+
83
+ return output_path
84
+
85
+ def get_file_size(file_path):
86
+ return os.path.getsize(file_path)
87
+
88
+ def print_summary(start_time, output_path):
89
+ end_time = time.time()
90
+ execution_time = end_time - start_time
91
+ output_size = get_file_size(output_path)
92
+ print(f"Generated {output_path} (size: {output_size/1024.0:.0f}KB) in {execution_time:.2f} seconds.")
93
+
94
+ def main():
95
+ args = parse_arguments()
96
+
97
+ input_extension = os.path.splitext(args.input_path)[1].lower()
98
+
99
+ start_time = time.time()
100
+
101
+ try:
102
+ if input_extension == '.yaml':
103
+ output_path = process_yaml_input(args.input_path, args.output_path)
104
+ elif input_extension == '.bin' or input_extension == '':
105
+ output_path = process_binary_input(args.input_path, args.output_path)
106
+ elif input_extension == '.json':
107
+ output_path = process_json_input(args.input_path, args.output_path)
108
+ else:
109
+ raise ValueError("Unsupported input file extension")
110
+
111
+ print_summary(start_time, output_path)
112
+
113
+ except Exception as e:
114
+ print(f"Error processing file: {e}")
115
+ traceback.print_exc()
116
+ sys.exit(1)
117
+
118
+ if __name__ == "__main__":
119
+ main()
@@ -0,0 +1,112 @@
1
+ import importlib
2
+ import importlib.util
3
+ import json
4
+ import os
5
+ import yaml
6
+ import zs_yaml.built_in_transformations
7
+ from string import Template
8
+
9
+ class YamlTransformer:
10
+ """
11
+ Encapsulates the transformation of yaml data using
12
+ invocations of registered transformation functions.
13
+ """
14
+
15
+ # Class-level cache for loaded modules
16
+ _loaded_modules = {}
17
+
18
+ def __init__(self, yaml_file_path, template_args=None, initial_transformations=None):
19
+ self.yaml_file_path = yaml_file_path
20
+ self.yaml_dir = os.path.dirname(os.path.abspath(yaml_file_path))
21
+ self.transformations = initial_transformations or {}
22
+ self._load_functions(zs_yaml.built_in_transformations)
23
+ self.meta = {}
24
+ self.template_args = template_args
25
+ self.yaml_data = None
26
+
27
+ def resolve_path(self, path):
28
+ if os.path.isabs(path):
29
+ return path
30
+ return os.path.normpath(os.path.join(self.yaml_dir, path))
31
+
32
+ def transform(self):
33
+ if self.yaml_data is None:
34
+ self._load_yaml()
35
+
36
+ transformation_module = self.meta.get('transformation_module')
37
+
38
+ if transformation_module:
39
+ self._load_functions(transformation_module)
40
+
41
+ return self._process(self.yaml_data)
42
+
43
+ def to_json(self):
44
+ processed_data = self.transform()
45
+ return json.dumps(processed_data, indent=2)
46
+
47
+ def get_meta(self):
48
+ if self.yaml_data is None:
49
+ self._load_yaml()
50
+ return self.meta
51
+
52
+ @classmethod
53
+ def _load_module_from_file(cls, module_name, file_path):
54
+ abs_path = os.path.abspath(file_path)
55
+ if abs_path in cls._loaded_modules:
56
+ return cls._loaded_modules[abs_path]
57
+
58
+ spec = importlib.util.spec_from_file_location(module_name, abs_path)
59
+ module = importlib.util.module_from_spec(spec)
60
+ spec.loader.exec_module(module)
61
+ cls._loaded_modules[abs_path] = module
62
+ return module
63
+
64
+ def _load_functions(self, transformation_module):
65
+ if isinstance(transformation_module, str):
66
+ if transformation_module.endswith('.py'):
67
+ abs_path = self.resolve_path(transformation_module)
68
+ transformation_module = self._load_module_from_file('custom_transformations', abs_path)
69
+ else:
70
+ transformation_module = importlib.import_module(transformation_module)
71
+
72
+ for name, func in vars(transformation_module).items():
73
+ if callable(func):
74
+ self._register_function(name, func)
75
+
76
+ def _register_function(self, name, func):
77
+ if name in self.transformations:
78
+ if self.transformations[name] != func:
79
+ raise ValueError(f"Attempting to register a different function with an existing name: {name}")
80
+ else:
81
+ self.transformations[name] = func
82
+
83
+ def _get_function(self, name):
84
+ return self.transformations.get(name)
85
+
86
+ def _process(self, data):
87
+ if isinstance(data, list):
88
+ return [self._process(item) for item in data]
89
+ elif isinstance(data, dict):
90
+ if '_f' in data and '_a' in data:
91
+ func = self._get_function(data['_f'])
92
+ args = data['_a']
93
+ if func and callable(func):
94
+ if isinstance(args, dict):
95
+ return func(self, **args)
96
+ else:
97
+ return func(self, args)
98
+ else:
99
+ raise ValueError(f"Function {data['_f']} not found or is not callable")
100
+ else:
101
+ return {key: self._process(value) for key, value in data.items()}
102
+ return data
103
+
104
+ def _load_yaml(self):
105
+ with open(self.yaml_file_path, 'r') as yaml_file:
106
+ content = yaml_file.read()
107
+
108
+ if self.template_args:
109
+ content = Template(content).safe_substitute(self.template_args)
110
+
111
+ self.yaml_data = yaml.safe_load(content)
112
+ self.meta = self.yaml_data.pop('_meta', {})
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.1
2
+ Name: zs-yaml
3
+ Version: 0.3.0
4
+ Summary: A package that allows using yaml to define zserio objects.
5
+ Home-page: https://github.com/ndsev/zs_yaml
6
+ Author: Navigation Data Standard e.V.
7
+ Author-email: support@nds-association.org
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: PyYAML~=6.0
15
+ Requires-Dist: zserio~=2.12
16
+
17
+ # `zs-yaml`
18
+
19
+ *Your Easy Path to zserio Test Data*
20
+
21
+ <img src="doc/zs-yaml.png" alt="" height="100">
22
+
23
+ **zs-yaml** adds YAML as a text format to be used with zserio in order to improve the user experience when manually creating or analyzing test data for zserio.
24
+
25
+ - **YAML Format**: Uses YAML's human-readable format instead of JSON as the primary format for editing, making data handling and transformation more intuitive and less cluttered.
26
+ - **Metadata Inclusion**: Automatically includes metadata in the YAML, eliminating the need for users to manually identify the correct type when importing JSON data, ensuring seamless (de-)serialization.
27
+ - **Custom Transformations**: Allows for hooking in custom transformations so that users can work with familiar formats (e.g., dates or coordinate representations) instead of thinking in unfamiliar formats.
28
+
29
+ ## Example
30
+
31
+ ### Zserio Schema Module Creation
32
+
33
+ 1. **Create the Zserio schema**:
34
+ - Create a file named `person.zs` with the following content:
35
+
36
+ ```zserio
37
+ package person;
38
+
39
+ struct Person
40
+ {
41
+ string name;
42
+ string birthdate;
43
+ string birth_location;
44
+ string current_job;
45
+ int32 income;
46
+ RoleExperience experience[];
47
+ };
48
+
49
+ struct RoleExperience
50
+ {
51
+ string role;
52
+ int32 years;
53
+ };
54
+ ```
55
+
56
+ 2. **Compile the Zserio schema and generate Python APIs**:
57
+ - Run the following command to compile the schema and generate Python sources:
58
+
59
+ ```sh
60
+ # Generated sources needs type infos so that 'json <-> bin'
61
+ # conversion works, which is utilized by zs-yaml
62
+ zserio person.zs -withTypeInfoCode -python zs_gen_api
63
+ ```
64
+
65
+ 3. **Ensure that the schema modules are available in the Python environment**:
66
+ - Export the `PYTHONPATH` to include the directory containing the generated Python sources:
67
+
68
+ ```sh
69
+ export PYTHONPATH="zs_gen_api"
70
+ ```
71
+
72
+ ### Use zs-yaml to create data
73
+
74
+ Using **zs-yaml**, you can define the same data in a more human-readable YAML format and include necessary metadata along with a custom transformation for the birthdate:
75
+
76
+ ```yaml
77
+ # 1) Metadata is used to specify the type needed for
78
+ # (de-)serialization and custom transform functions
79
+ # 2) User are free to use their preferred date format
80
+ # for the birth data as the a normalization function
81
+ # get invoked.
82
+ # 3) Yaml allows avoiding clutter and adding comments
83
+ # like this one :)
84
+
85
+ _meta:
86
+ schema_module: person.api
87
+ schema_type: Person
88
+ transformation_module: "./transformations.py"
89
+
90
+ name: John Doe
91
+
92
+ birthdate:
93
+ _f: normalize_date
94
+ _a: "01/01/1990"
95
+ birth_location: Springfield, USA
96
+
97
+ current_job: Software Engineer
98
+ income: 75000
99
+
100
+ experience:
101
+ - role: Intern
102
+ years: 1
103
+ - role: Junior Developer
104
+ years: 2
105
+ - role: Senior Developer
106
+ years: 3
107
+ ```
108
+
109
+ #### Example Transformation Module (transformations.py)
110
+
111
+ ```python
112
+ def normalize_date(date_str):
113
+ from datetime import datetime
114
+ for fmt in ("%Y-%m-%d", "%d/%m/%Y", "%m/%d/%Y"):
115
+ try:
116
+ return datetime.strptime(date_str, fmt).strftime("%Y-%m-%d")
117
+ except ValueError:
118
+ pass
119
+ raise ValueError(f"Date {date_str} is not in a recognized format")
120
+ ```
121
+
122
+ #### Creating the Binary Representation
123
+
124
+ After you have installed `zs-yaml`, call `zs-yaml` to convert your YAML file to a binary representation:
125
+
126
+ ```sh
127
+ # Install zs-yaml if not already installed.
128
+
129
+ # Create the binary representation from the YAML file
130
+ zs-yaml person.yaml person.bin
131
+ ```
132
+
133
+ ## Installation
134
+
135
+ Currently, the Python package is only available at test.pypi. Once the official release is available,
136
+ you can install the package without specifying an index URL.
137
+
138
+ ```bash
139
+ python -m pip install --upgrade zs-yaml
140
+ ```
141
+
142
+ ## Usage
143
+
144
+ The main entry point for the application is `main.py`. It accepts arguments for specifying the input and output file paths. You can run the application as follows:
145
+
146
+ ```bash
147
+ zs-yaml input.yaml output.bin
148
+ zs-yaml input.bin output.yaml
149
+ ```
150
+
151
+ ### Notes
152
+
153
+ - You have to use the exact same order of field in the yaml as defined by the zserio schema, because zserio expects this
154
+ - When converting from binary to YAML, the target YAML file must already exist and contain the necessary metadata.
155
+ - The minimal metadata content in the target YAML file should be:
156
+
157
+ ```yaml
158
+ _meta:
159
+ schema_module: <module_name>
160
+ schema_type: <type_name>
161
+ ```
162
+
163
+ ### Future Considerations
164
+
165
+ In the future, we may consider using YAML tags for a more integrated approach to handling transformations directly within the YAML files, simplifying syntax and enhancing readability.
166
+
167
+ ## Project Structure
168
+
169
+ - `setup.py`: Script for setting up the project and installing dependencies.
170
+ - `zs_yaml/`: Directory containing the actual `zs-yaml` implementation.
171
+
172
+ ## Reference
173
+
174
+ This project references the zserio serialization framework. For more information about zserio, visit the [zserio GitHub project](https://github.com/ndsev/zserio).
@@ -0,0 +1,20 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ VERSION
5
+ requirements.txt
6
+ setup.py
7
+ doc/zs-yaml.png
8
+ doc/zs-yaml.svg
9
+ zs_yaml/__init__.py
10
+ zs_yaml/_version.py
11
+ zs_yaml/built_in_transformations.py
12
+ zs_yaml/convert.py
13
+ zs_yaml/main.py
14
+ zs_yaml/yaml_transformer.py
15
+ zs_yaml.egg-info/PKG-INFO
16
+ zs_yaml.egg-info/SOURCES.txt
17
+ zs_yaml.egg-info/dependency_links.txt
18
+ zs_yaml.egg-info/entry_points.txt
19
+ zs_yaml.egg-info/requires.txt
20
+ zs_yaml.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ zs-yaml = zs_yaml.main:main
@@ -0,0 +1,2 @@
1
+ PyYAML~=6.0
2
+ zserio~=2.12
@@ -0,0 +1 @@
1
+ zs_yaml