data_pipeline_api 0.8.0__py3-none-any.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.
@@ -0,0 +1,218 @@
1
+ import logging
2
+ import os
3
+
4
+ from data_pipeline_api import fdp_utils
5
+
6
+
7
+ def link_write(handle: dict, data_product: str) -> str:
8
+ """Reads write information in config file, updates handle with relevant
9
+ metadata and returns path to write data product to.
10
+
11
+ Args:
12
+ | data_product: Specified name of data product in config.
13
+
14
+ Returns:
15
+ | path: Path to write data product to.
16
+ """
17
+
18
+ # Get metadata from handle
19
+ run_metadata = handle["yaml"]["run_metadata"]
20
+ datastore = run_metadata["write_data_store"]
21
+
22
+ index = 0
23
+
24
+ if "write" not in handle["yaml"].keys():
25
+ raise ValueError(
26
+ "Error: Write has not been specified in the given config file"
27
+ )
28
+
29
+ # If multiple write blocks exist, find corresponding index for given DP
30
+ for i in enumerate(handle["yaml"]["write"]):
31
+ if i[1]["data_product"] == data_product:
32
+ index = i[0]
33
+
34
+ # Get metadata from config
35
+ write = handle["yaml"]["write"][index]
36
+ write_data_product = write["data_product"]
37
+ write_version = write["use"]["version"]
38
+ file_type = write["file_type"]
39
+ description = write["description"]
40
+ write_namespace = run_metadata["default_output_namespace"]
41
+ write_public = run_metadata["public"]
42
+
43
+ # Create filename for path
44
+ filename = "dat-" + fdp_utils.random_hash() + "." + file_type
45
+
46
+ # Get path
47
+ path = os.path.join(
48
+ datastore, write_namespace, write_data_product, filename
49
+ ).replace("\\", "/")
50
+
51
+ # Create directory structure if it doesn't exist
52
+ directory = os.path.dirname(path)
53
+
54
+ if not os.path.exists(directory):
55
+ os.makedirs(directory)
56
+
57
+ # Create metadata dict
58
+ output_dict = {
59
+ "data_product": data_product,
60
+ "use_data_product": write_data_product,
61
+ "use_component": None,
62
+ "use_version": write_version,
63
+ "use_namespace": write_namespace,
64
+ "path": path,
65
+ "data_product_description": description,
66
+ "component_description": None,
67
+ "public": write_public,
68
+ }
69
+
70
+ # If output exists in handle, append new metadata, otherwise create dict
71
+ if "output" in handle:
72
+ key = "output_" + str(len(handle["output"]))
73
+ handle["output"][key] = output_dict
74
+ else:
75
+ handle["output"] = {}
76
+ handle["output"]["output_0"] = output_dict
77
+
78
+ return path
79
+
80
+
81
+ def link_read(handle: dict, data_product: str) -> str:
82
+ """Reads 'read' information in config file, updates handle with relevant
83
+ metadata and returns path to write data product to.
84
+
85
+ Args:
86
+ | data_product: Specified name of data product in config.
87
+
88
+ Returns:
89
+ | path: Path to write data product to.
90
+ """
91
+
92
+ # If data product is already in handle, return path
93
+ if "input" in handle:
94
+ for index in handle["input"].keys():
95
+ if handle["input"][index]["data_product"] == data_product:
96
+ return handle["input"][index]["path"]
97
+ if "read" not in handle["yaml"].keys():
98
+ raise ValueError(
99
+ "Error: Read has not been specified in the given config file"
100
+ )
101
+
102
+ # Check if data product is in config yaml
103
+ read_list = [
104
+ i[1]["data_product"] for i in enumerate(handle["yaml"]["read"])
105
+ ]
106
+
107
+ if data_product not in read_list:
108
+ logging.info("Read information for data product not in config")
109
+
110
+ index = 0
111
+ # Get index for given data product
112
+ for i in enumerate(handle["yaml"]["read"]):
113
+ if i[1]["data_product"] == data_product:
114
+ index = i[0]
115
+
116
+ # Get read info from config
117
+ read = handle["yaml"]["read"][index]
118
+
119
+ use = read["use"] if "use" in read else None
120
+
121
+ registry_url = handle["yaml"]["run_metadata"]["local_data_registry_url"]
122
+ namespace = handle["yaml"]["run_metadata"]["default_input_namespace"]
123
+ api_version = handle["yaml"]["run_metadata"]["api_version"]
124
+
125
+ if "namespace" in use:
126
+ if use["namespace"]:
127
+ namespace = use["namespace"]
128
+
129
+ # Get namespace url and extract id
130
+ namespace_url = fdp_utils.get_entry(
131
+ url=registry_url,
132
+ endpoint="namespace",
133
+ query={"name": namespace},
134
+ api_version=api_version,
135
+ )[0]["url"]
136
+
137
+ namespace_id = fdp_utils.extract_id(namespace_url)
138
+
139
+ if "data_product" in use:
140
+ if use["data_product"]:
141
+ data_product = use["data_product"]
142
+
143
+ version = use["version"] if "version" in use else "0.0.1"
144
+
145
+ # Get data_product metadata and extract object id
146
+ data_product_response = fdp_utils.get_entry(
147
+ url=registry_url,
148
+ endpoint="data_product",
149
+ query={
150
+ "name": data_product,
151
+ "version": version,
152
+ "namespace": namespace_id,
153
+ },
154
+ api_version=api_version,
155
+ )
156
+
157
+ object_response = fdp_utils.get_entity(
158
+ url=registry_url,
159
+ endpoint="object",
160
+ id=int(fdp_utils.extract_id(data_product_response[0]["object"])),
161
+ )
162
+
163
+ object_id = fdp_utils.extract_id(object_response["url"])
164
+
165
+ # Get component url and storage metadata
166
+ component_url = fdp_utils.get_entry(
167
+ url=registry_url,
168
+ endpoint="object_component",
169
+ query={"object": object_id},
170
+ api_version=api_version,
171
+ )[0]["url"]
172
+
173
+ storage_location_response = fdp_utils.get_entity(
174
+ url=registry_url,
175
+ endpoint="storage_location",
176
+ id=int(fdp_utils.extract_id(object_response["storage_location"])),
177
+ api_version=api_version,
178
+ )
179
+
180
+ storage_root = fdp_utils.get_entity(
181
+ url=registry_url,
182
+ endpoint="storage_root",
183
+ id=int(
184
+ fdp_utils.extract_id(storage_location_response["storage_root"])
185
+ ),
186
+ api_version=api_version,
187
+ )["root"]
188
+ tmp_sl = storage_location_response["path"]
189
+ # remove leading character from path if it is eithe / or \
190
+ if ("\\" in tmp_sl[0]) or "/" in tmp_sl[0]:
191
+ tmp_sl = tmp_sl[1:]
192
+
193
+ # remove file:// from storage root
194
+ storage_root = fdp_utils.remove_local_from_root(storage_root)
195
+
196
+ # Get path of data product
197
+ path = os.path.normpath(os.path.join(storage_root, tmp_sl))
198
+ component = use["component"] if "component" in use else None
199
+
200
+ # Write to handle and return path
201
+ input_dict = {
202
+ "data_product": data_product,
203
+ "use_data_product": data_product,
204
+ "use_component": component,
205
+ "use_version": version,
206
+ "use_namespace": namespace,
207
+ "path": path,
208
+ "component_url": component_url,
209
+ }
210
+
211
+ if "input" in handle:
212
+ index = "input_" + str(len(handle["input"]))
213
+ handle["input"][index] = input_dict
214
+ else:
215
+ handle["input"] = {}
216
+ handle["input"]["input_0"] = input_dict
217
+
218
+ return path