Skip to content

Commit bfa11cd

Browse files
committed
implement feedback, use f-strings
1 parent f418e38 commit bfa11cd

1 file changed

Lines changed: 41 additions & 42 deletions

File tree

sdk/basyx/aas/adapter/aasx.py

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import itertools
2929
import logging
3030
import os
31-
import re
3231
from typing import Dict, Tuple, IO, Union, List, Set, Optional, Iterable, Iterator
3332

3433
from .xml import read_aas_xml_file, write_aas_xml_file
@@ -45,7 +44,7 @@
4544
RELATIONSHIP_TYPE_AAS_SUPL = "http://admin-shell.io/aasx/relationships/aas-suppl"
4645

4746

48-
class AASXReader():
47+
class AASXReader:
4948
"""
5049
An AASXReader wraps an existing AASX package file to allow reading its contents and metadata.
5150
@@ -74,14 +73,14 @@ def __init__(self, file: Union[os.PathLike, str, IO], failsafe: bool = True):
7473
:raises FileNotFoundError: If the file does not exist
7574
:raises ValueError: If the file is not a valid OPC zip package
7675
"""
77-
self.failsafe = failsafe
76+
self.failsafe: bool = failsafe
7877
try:
79-
logger.debug("Opening {} as AASX pacakge for reading ...".format(file))
78+
logger.debug(f"Opening {file} as AASX package for reading ...")
8079
self.reader = pyecma376_2.ZipPackageReader(file)
8180
except FileNotFoundError:
8281
raise
8382
except Exception as e:
84-
raise ValueError("{} is not a valid ECMA376-2 (OPC) file: {}".format(file, e)) from e
83+
raise ValueError(f"{file} is not a valid ECMA376-2 (OPC) file: {e}") from e
8584

8685
def get_core_properties(self) -> pyecma376_2.OPCCoreProperties:
8786
"""
@@ -135,7 +134,7 @@ def read_into(self, object_store: model.AbstractObjectStore,
135134
objects from the AASX file to
136135
:param file_store: A :class:`SupplementaryFileContainer <.AbstractSupplementaryFileContainer>` to add the
137136
embedded supplementary files to
138-
:param override_existing: If ``True``, existing objects in the object store are overridden with objects from the
137+
:param override_existing: If ``True``, existing objects in the ObjectStore are overridden with objects from the
139138
AASX that have the same :class:`~basyx.aas.model.base.Identifier`. Default behavior is to skip those objects
140139
from the AASX.
141140
:return: A set of the :class:`Identifiers <basyx.aas.model.base.Identifier>` of all
@@ -198,23 +197,23 @@ def _read_aas_part_into(self, part_name: str,
198197
from a File object of this part
199198
:param read_identifiables: A set of Identifiers of objects which have already been read. New objects'
200199
Identifiers are added to this set. Objects with already known Identifiers are skipped silently.
201-
:param override_existing: If True, existing objects in the object store are overridden with objects from the
200+
:param override_existing: If True, existing objects in the ObjectStore are overridden with objects from the
202201
AASX that have the same Identifier. Default behavior is to skip those objects from the AASX.
203202
"""
204203
for obj in self._parse_aas_part(part_name, **kwargs):
205204
if obj.id in read_identifiables:
206205
continue
207206
if obj.id in object_store:
208207
if override_existing:
209-
logger.info("Overriding existing object in ObjectStore with {} ...".format(obj))
208+
logger.info(f"Overriding existing object in ObjectStore with {obj} ...")
210209
object_store.discard(obj)
211210
else:
212211
if self.failsafe:
213-
logger.warning("Skipping {}, since an object with the same id is already contained in the "
214-
"ObjectStore".format(obj))
212+
logger.warning(f"Skipping {obj}, since an object with the same id is already contained in the "
213+
"ObjectStore")
215214
continue
216215
else:
217-
raise ValueError("Object with id {} is already contained in the ObjectStore".format(obj))
216+
raise ValueError(f"Object with id {obj} is already contained in the ObjectStore")
218217
object_store.add(obj)
219218
read_identifiables.add(obj.id)
220219
if isinstance(obj, model.Submodel):
@@ -232,17 +231,17 @@ def _parse_aas_part(self, part_name: str, **kwargs) -> model.DictObjectStore:
232231
content_type = self.reader.get_content_type(part_name)
233232
extension = part_name.split("/")[-1].split(".")[-1]
234233
if content_type.split(";")[0] in ("text/xml", "application/xml") or content_type == "" and extension == "xml":
235-
logger.debug("Parsing AAS objects from XML stream in OPC part {} ...".format(part_name))
234+
logger.debug(f"Parsing AAS objects from XML stream in OPC part {part_name} ...")
236235
with self.reader.open_part(part_name) as p:
237236
return read_aas_xml_file(p, failsafe=self.failsafe, **kwargs)
238237
elif content_type.split(";")[0] in ("text/json", "application/json") \
239238
or content_type == "" and extension == "json":
240-
logger.debug("Parsing AAS objects from JSON stream in OPC part {} ...".format(part_name))
239+
logger.debug(f"Parsing AAS objects from JSON stream in OPC part {part_name} ...")
241240
with self.reader.open_part(part_name) as p:
242241
return read_aas_json_file(io.TextIOWrapper(p, encoding='utf-8-sig'), failsafe=self.failsafe, **kwargs)
243242
else:
244-
error_message = ("Could not determine part format of AASX part {} (Content Type: {}, extension: {}"
245-
.format(part_name, content_type, extension))
243+
error_message = (f"Could not determine part format of AASX part {part_name} (Content Type: {content_type},"
244+
f" extension: {extension}")
246245
if self.failsafe:
247246
logger.error(error_message)
248247
else:
@@ -255,7 +254,7 @@ def _collect_supplementary_files(self, part_name: str, submodel: model.Submodel,
255254
Helper function to search File objects within a single parsed Submodel, extract the referenced supplementary
256255
files and update the File object's values with the absolute path.
257256
258-
:param part_name: The OPC part name of the part the submodel has been parsed from. This is used to resolve
257+
:param part_name: The OPC part name of the part the Submodel has been parsed from. This is used to resolve
259258
relative file paths.
260259
:param submodel: The Submodel to process
261260
:param file_store: The SupplementaryFileContainer to add the extracted supplementary files to
@@ -268,17 +267,17 @@ def _collect_supplementary_files(self, part_name: str, submodel: model.Submodel,
268267
# to refer to files within the AASX package. Thus, we must skip all other types of URIs (esp. absolute
269268
# URIs and network-path references)
270269
if element.value.startswith('//') or ':' in element.value.split('/')[0]:
271-
logger.info("Skipping supplementary file %s, since it seems to be an absolute URI or network-path "
272-
"URI reference", element.value)
270+
logger.info(f"Skipping supplementary file {element.value}, since it seems to be an absolute URI or "
271+
f"network-path URI reference")
273272
continue
274273
absolute_name = pyecma376_2.package_model.part_realpath(element.value, part_name)
275-
logger.debug("Reading supplementary file {} from AASX package ...".format(absolute_name))
274+
logger.debug(f"Reading supplementary file {absolute_name} from AASX package ...")
276275
with self.reader.open_part(absolute_name) as p:
277276
final_name = file_store.add_file(absolute_name, p, self.reader.get_content_type(absolute_name))
278277
element.value = final_name
279278

280279

281-
class AASXWriter():
280+
class AASXWriter:
282281
"""
283282
An AASXWriter wraps a new AASX package file to write its contents to it piece by piece.
284283
@@ -320,7 +319,7 @@ def __init__(self, file: Union[os.PathLike, str, IO], failsafe: bool = True):
320319
logged instead of causing exceptions. Defect objects are skipped.
321320
:param file: filename, path, or binary file handle opened for writing
322321
"""
323-
self.failsafe = failsafe
322+
self.failsafe: bool = failsafe
324323
# names of aas-spec parts, used by `_write_aasx_origin_relationships()`
325324
self._aas_part_names: List[str] = []
326325
# name of the thumbnail part (if any)
@@ -380,7 +379,7 @@ def write_aas(self,
380379
:param write_json: If ``True``, JSON parts are created for the AAS and each
381380
:class:`~basyx.aas.model.submodel.Submodel` in the AASX package file instead of XML parts.
382381
Defaults to ``False``.
383-
:raises KeyError: If one of the AAS could not be retrieved from the object store (unresolvable
382+
:raises KeyError: If one of the AAS could not be retrieved from the ObjectStore (unresolvable
384383
:class:`Submodels <basyx.aas.model.submodel.Submodel>` and
385384
:class:`ConceptDescriptions <basyx.aas.model.concept.ConceptDescription>` are skipped, logging a
386385
warning/info message)
@@ -413,10 +412,10 @@ def write_aas(self,
413412
submodel = submodel_ref.resolve(object_store)
414413
except KeyError:
415414
if self.failsafe:
416-
logger.warning("Could not find submodel %s. Skipping it.", str(submodel_ref))
415+
logger.warning(f"Could not find Submodel {submodel_ref}. Skipping it.")
417416
continue
418417
else:
419-
raise KeyError(f"Could not find submodel {submodel_ref!r}")
418+
raise KeyError(f"Could not find Submodel {submodel_ref!r}")
420419
objects_to_be_written.add(submodel)
421420

422421
# Traverse object tree and check if semanticIds are referencing to existing ConceptDescriptions in the
@@ -433,15 +432,15 @@ def write_aas(self,
433432
cd = semantic_id.resolve(object_store)
434433
except KeyError:
435434
if self.failsafe:
436-
logger.warning("ConceptDescription for semanticId %s not found in object store. Skipping it.",
437-
str(semantic_id))
435+
logger.warning(f"ConceptDescription for semanticId {semantic_id} not found in ObjectStore. "
436+
f"Skipping it.")
438437
continue
439438
else:
440-
raise KeyError(f"ConceptDescription for semanticId {semantic_id!r} not found in object store.")
439+
raise KeyError(f"ConceptDescription for semanticId {semantic_id!r} not found in ObjectStore.")
441440
except model.UnexpectedTypeError as e:
442441
if self.failsafe:
443-
logger.error("semanticId %s resolves to %s, which is not a ConceptDescription. Skipping it.",
444-
str(semantic_id), e.value)
442+
logger.error(f"semanticId {semantic_id} resolves to {e.value}, "
443+
f"which is not a ConceptDescription. Skipping it.")
445444
continue
446445
else:
447446
raise TypeError(f"semanticId {semantic_id!r} resolves to {e.value!r}, which is not a"
@@ -469,7 +468,7 @@ def write_aas_objects(self,
469468
This method takes the AAS's :class:`~basyx.aas.model.base.Identifier` (as ``aas_id``) to retrieve it
470469
from the given object_store. If the list of written objects includes :class:`~basyx.aas.model.submodel.Submodel`
471470
objects, Supplementary files which are referenced by :class:`~basyx.aas.model.submodel.File` objects within
472-
those submodels, are also added to the AASX package.
471+
those Submodels, are also added to the AASX package.
473472
474473
.. attention::
475474
@@ -494,7 +493,7 @@ def write_aas_objects(self,
494493
:param additional_relationships: Optional OPC/ECMA376 relationships which should originate at the AAS object
495494
part to be written, in addition to the aas-suppl relationships which are created automatically.
496495
"""
497-
logger.debug("Writing AASX part {} with AAS objects ...".format(part_name))
496+
logger.debug(f"Writing AASX part {part_name} with AAS objects ...")
498497

499498
objects: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
500499

@@ -504,7 +503,7 @@ def write_aas_objects(self,
504503
the_object = object_store.get_identifiable(identifier)
505504
except KeyError:
506505
if self.failsafe:
507-
logger.error("Could not find object {} in ObjectStore".format(identifier))
506+
logger.error(f"Could not find object {identifier} in ObjectStore")
508507
continue
509508
else:
510509
raise KeyError(f"Could not find object {identifier!r} in ObjectStore")
@@ -548,7 +547,7 @@ def write_all_aas_objects(self,
548547
:param additional_relationships: Optional OPC/ECMA376 relationships which should originate at the AAS object
549548
part to be written, in addition to the aas-suppl relationships which are created automatically.
550549
"""
551-
logger.debug("Writing AASX part {} with AAS objects ...".format(part_name))
550+
logger.debug(f"Writing AASX part {part_name} with AAS objects ...")
552551
supplementary_files: List[str] = []
553552

554553
# Retrieve objects and scan for referenced supplementary files
@@ -575,36 +574,36 @@ def write_all_aas_objects(self,
575574
else:
576575
write_aas_xml_file(p, objects)
577576

578-
# Write submodel's supplementary files to AASX file
577+
# Write Submodel's supplementary files to AASX file
579578
supplementary_file_names = []
580579
for file_name in supplementary_files:
581580
try:
582581
content_type = file_store.get_content_type(file_name)
583582
hash = file_store.get_sha256(file_name)
584583
except KeyError:
585584
if self.failsafe:
586-
logger.warning("Could not find file {} in file store.".format(file_name))
585+
logger.warning(f"Could not find file {file_name} in FileStore.")
587586
continue
588587
else:
589-
raise KeyError(f"Could not find file {file_name} in file store.")
588+
raise KeyError(f"Could not find file {file_name} in FileStore.")
590589
# Check if this supplementary file has already been written to the AASX package or has a name conflict
591590
if self._supplementary_part_names.get(file_name) == hash:
592591
continue
593592
elif file_name in self._supplementary_part_names:
594593
if self.failsafe:
595-
logger.error("Trying to write supplementary file {} to AASX twice with different contents"
596-
.format(file_name))
594+
logger.error(f"Trying to write supplementary file {file_name} to AASX "
595+
f"twice with different contents")
597596
else:
598597
raise ValueError(f"Trying to write supplementary file {file_name} to AASX twice with"
599598
f" different contents")
600-
logger.debug("Writing supplementary file {} to AASX package ...".format(file_name))
599+
logger.debug(f"Writing supplementary file {file_name} to AASX package ...")
601600
with self.writer.open_part(file_name, content_type) as p:
602601
file_store.write_file(file_name, p)
603602
supplementary_file_names.append(pyecma376_2.package_model.normalize_part_name(file_name))
604603
self._supplementary_part_names[file_name] = hash
605604

606-
# Add relationships from submodel to supplementary parts
607-
logger.debug("Writing aas-suppl relationships for AAS object part {} to AASX package ...".format(part_name))
605+
# Add relationships from Submodel to supplementary parts
606+
logger.debug(f"Writing aas-suppl relationships for AAS object part {part_name} to AASX package ...")
608607
self.writer.write_relationships(
609608
itertools.chain(
610609
(pyecma376_2.OPCRelationship("r{}".format(i),
@@ -643,7 +642,7 @@ def write_thumbnail(self, name: str, data: bytearray, content_type: str):
643642
:param content_type: OPC content type (MIME type) of the image file
644643
"""
645644
if self._thumbnail_part is not None:
646-
raise RuntimeError("package thumbnail has already been written to {}.".format(self._thumbnail_part))
645+
raise RuntimeError(f"package thumbnail has already been written to {self._thumbnail_part}.")
647646
with self.writer.open_part(name, content_type) as p:
648647
p.write(data)
649648
self._thumbnail_part = name

0 commit comments

Comments
 (0)