def to_api_dict(self, full=True, api_version: ComparableVersion = None) -> dict: """ API-version-aware conversion of batch job metadata to jsonable openEO API compatible dict. see https://openeo.org/documentation/1.0/developers/api/reference.html#operation/describe-job """ # Basic/full fields to export fields = ["id", "title", "description", "status", "progress", "created", "updated", "plan", "costs", "budget"] if full: fields.extend(["process"]) result = {f: getattr(self, f) for f in fields} # Additional cleaning and massaging. result["created"] = rfc3339.datetime(self.created) if self.created else None result["updated"] = rfc3339.datetime(self.updated) if self.updated else None if full: usage = self.usage or {} if self.cpu_time: usage["cpu"] = {"value": int(round(self.cpu_time.total_seconds())), "unit": "cpu-seconds"} if self.duration: usage["duration"] = {"value": int(round(self.duration.total_seconds())), "unit": "seconds"} if self.memory_time_megabyte: usage["memory"] = {"value": int(round(self.memory_time_megabyte.total_seconds())), "unit": "mb-seconds"} if usage: result["usage"] = usage if api_version and api_version.below("1.0.0"): result["process_graph"] = result.pop("process", {}).get("process_graph") result["submitted"] = result.pop("created", None) # TODO wider status checking coverage? if result["status"] == "created": result["status"] = "submitted" return dict_no_none(result)
def test_comparable_version_right_referencing(): v = ComparableVersion('1.2.3') assert v.equals('1.2.3') assert v.above('0') assert v.above('0.1') assert v.above('0.1.2') assert v.above('1.2') assert v.above('1.2.2') assert v.above('1.2.2b') assert v.above('1.2.3') is False assert v.above('1.2.20') is False assert v.above('1.2.4') is False assert v.above('1.10.4') is False assert v.at_least('0') assert v.at_least('1') assert v.at_least('1.1') assert v.at_least('1.10') is False assert v.at_least('1.2') assert v.at_least('1.02') assert v.at_least('1.2.2') assert v.at_least('1.2.3') assert v.at_least('1.2.3a') is False assert v.at_least('1.2.4') is False assert v.at_least('1.3') is False assert v.at_least('2') is False assert v.below('2') assert v.below('1.3') assert v.below('1.2.4') assert v.below('1.2.3b') assert v.below('1.2.3') is False assert v.below('1.2') is False assert v.at_most('2') assert v.at_most('1.3') assert v.at_most('1.2.3c') assert v.at_most('1.2.3') assert v.at_most('1.02.03') assert v.at_most('1.2.2b') is False assert v.at_most('1.2') is False assert v.at_most('1.10') assert v.above(ComparableVersion('1.2')) assert v.at_least(ComparableVersion('1.2.3a')) is False assert v.at_most(ComparableVersion('1.02.03'))
def _normalize_collection_metadata(metadata: dict, api_version: ComparableVersion, full=False) -> dict: """ Make sure the given collection metadata roughly complies to desirec version of OpenEO spec. """ # Make copy and remove all "private" fields metadata = copy.deepcopy(metadata) metadata = {k: v for (k, v) in metadata.items() if not k.startswith('_')} # Metadata should at least contain an id. if "id" not in metadata: _log.error("Collection metadata should have 'id' field: {m!r}".format(m=metadata)) raise KeyError("id") collection_id = metadata["id"] # Version dependent metadata conversions cube_dims_100 = deep_get(metadata, "cube:dimensions", default=None) cube_dims_040 = deep_get(metadata, "properties", "cube:dimensions", default=None) eo_bands_100 = deep_get(metadata, "summaries", "eo:bands", default=None) eo_bands_040 = deep_get(metadata, "properties", "eo:bands", default=None) if api_version.below("1.0.0"): if full and not cube_dims_040 and cube_dims_100: metadata.setdefault("properties", {}) metadata["properties"]["cube:dimensions"] = cube_dims_100 if full and not eo_bands_040 and eo_bands_100: metadata.setdefault("properties", {}) metadata["properties"]["eo:bands"] = eo_bands_100 else: if full and not cube_dims_100 and cube_dims_040: _log.warning("Collection metadata 'cube:dimensions' in API 0.4 style instead of 1.0 style") metadata["cube:dimensions"] = cube_dims_040 if full and not eo_bands_100 and eo_bands_040: _log.warning("Collection metadata 'eo:bands' in API 0.4 style instead of 1.0 style") metadata.setdefault("summaries", {}) metadata["summaries"]["eo:bands"] = eo_bands_040 # Make sure some required fields are set. metadata.setdefault("stac_version", "0.9.0" if api_version.at_least("1.0.0") else "0.6.2") metadata.setdefault("links", []) metadata.setdefault("description", collection_id) metadata.setdefault("license", "proprietary") # Warn about missing fields where simple defaults are not feasible. fallbacks = { "extent": {"spatial": [0, 0, 0, 0], "temporal": [None, None]}, } if full: if api_version.at_least("1.0.0"): fallbacks["cube:dimensions"] = {} fallbacks["summaries"] = {} else: fallbacks["properties"] = {} fallbacks["other_properties"] = {} for key, value in fallbacks.items(): if key not in metadata: _log.warning("Collection {c!r} metadata does not have field {k!r}.".format(c=collection_id, k=key)) metadata[key] = value if not full: basic_keys = [ "stac_version", "stac_extensions", "id", "title", "description", "keywords", "version", "deprecated", "license", "providers", "extent", "links" ] metadata = {k: v for k, v in metadata.items() if k in basic_keys} return metadata