maus.models package
Submodules
maus.models.anwendungshandbuch module
This module contains classes that are required to model “Anwendungshandbücher” (AHB). There are two kinds of AHBs: 1. the “flat” AHB is very similar to the flat structure scraped from the official PDF files. It has no deep structure. 2. the “nested” AHB which contains structural information (e.g. that a segment group is contained in another segment group)
- class maus.models.anwendungshandbuch.AhbLine(*, guid: UUID | None, segment_group_key: str | None, segment_code: str | None, data_element: str | None, value_pool_entry: str | None, name: str | None, ahb_expression: str | None, section_name: str | None = None, index: int | None = None)[source]
Bases:
objectAn AhbLine is a single line inside the machine-readable, flat AHB.
- ahb_expression: str | None
a requirement indicator + an optional condition (“ahb expression”), e.g. ‘Muss [123] O [456]’
- get_discriminator(include_name: bool = True) str[source]
Generate a unique yet readable discriminator for this given line. This discriminator is generated just from the line itself without any information on where it occurs. It does neither know its position inside the AHB nor parent or sub groups.
- holds_any_information() bool[source]
Returns true iff the line holds any information exception for just a GUID. This is useful to filter out empty lines which are artefacts remaining from the scraping process.
- index: int | None
index is a number that describes the position of the AHBLine inside the original PDF- and FlatAnwendungshandbuch.
- name: str | None
the name, e.g. ‘Meldepunkt’. It can be both the description of a field but also its meaning
- class maus.models.anwendungshandbuch.AhbLineSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA schema to (de-)serialize
AhbLine- deserialize(data, **kwargs) AhbLine[source]
Converts the barely typed data dictionary into an actual
AhbLine
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.anwendungshandbuch.AhbMetaInformation(*, pruefidentifikator: str, maus_version: str | None = '0.3.0', description: str | None = None, direction: str | None = None)[source]
Bases:
objectMeta information about an AHB like e.g. its title, Prüfidentifikator, possible sender and receiver roles
- description: str | None
an optional description of the purpose of the pruefidentifikator; e.g. ‘Anmeldung MSB’ for 11042
- class maus.models.anwendungshandbuch.AhbMetaInformationSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA schema to (de-)serialize
AhbMetaInformation- deserialize(data, **kwargs) AhbMetaInformation[source]
Converts the barely typed data dictionary into an actual
AhbMetaInformation
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.anwendungshandbuch.DeepAhbInputReplacement(*, replacement_found: bool, input_replacement: str | None)[source]
Bases:
objectA container class that models replacements of inputs in the DeepAnwendungshandbuch
- class maus.models.anwendungshandbuch.DeepAnwendungshandbuch(*, meta: AhbMetaInformation, lines: List[SegmentGroup])[source]
Bases:
objectThe data of the AHB nested as described in the MIG.
- find_segment_groups(predicate: Callable[[SegmentGroup], bool]) List[SegmentGroup][source]
recursively search for segment group in this ahb that meets the predicate. :return: list of segment groups that match the predicate; empty list otherwise
- find_segments(group_predicate: ~typing.Callable[[~maus.models.edifact_components.SegmentGroup], bool] = <function DeepAnwendungshandbuch.<lambda>>, segment_predicate: ~typing.Callable[[~maus.models.edifact_components.Segment], bool] = <function DeepAnwendungshandbuch.<lambda>>) List[Segment][source]
recursively search for segment characterised by the segment_predicate inside a group characterised by the group_predicate. :return: list of matching segments, empty list if nothing was found
- get_all_expressions() List[str][source]
recursively iterate through the deep ahb and return all distinct expressions found
- get_all_value_pools() List[DataElementValuePool][source]
recursively find all value pools in the deep ahb :return: a list of all value pools
- lines: List[SegmentGroup]
the nested data
- meta: AhbMetaInformation
information about this AHB
- class maus.models.anwendungshandbuch.DeepAnwendungshandbuchSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA schema to (de-)serialize
DeepAnwendungshandbuch- deserialize(data, **kwargs) DeepAnwendungshandbuch[source]
Converts the barely typed data dictionary into an actual
DeepAnwendungshandbuch
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.anwendungshandbuch.FlatAnwendungshandbuch(*, meta: AhbMetaInformation, lines: List[AhbLine])[source]
Bases:
objectA flat Anwendungshandbuch (AHB) models an Anwendungshandbuch as combination of some meta data and an ordered list of .class:.FlatAhbLine s. Basically a flat Anwendungshandbuch is the result of a simple scraping approach. You can create instances of this class without knowing anything about the “under the hood” structure of AHBs or MIGs
- get_segment_groups() List[str | None][source]
- Returns:
a set with all segment groups in this AHB in the order in which they occur
- meta: AhbMetaInformation
information about this AHB
- class maus.models.anwendungshandbuch.FlatAnwendungshandbuchSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA schema to (de-)serialize
FlatAnwendungshandbuch- deserialize(data, **kwargs) FlatAnwendungshandbuch[source]
Converts the barely typed data dictionary into an actual
FlatAnwendungshandbuch
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
maus.models.edifact_components module
EDIFACT components are data structures on different hierarchical levels inside an EDIFACT message. Components contain not only EDIFACT composits but also segments and segment groups.
- class maus.models.edifact_components.DataElement(*, discriminator: str | None, data_element_id: str, entered_input: str | None, value_type: DataElementDataType | None = None)[source]
Bases:
ABCA data element holds specific kinds of data. It is defined in EDIFACT. At least for the German energy market communication any data element has a 4 digit key. For example in UTILMD the data element that holds the 13 digit market partner ID is data element ‘3039’
- discriminator: str | None
The discriminator uniquely identifies the data element. The discriminator is None if the data element was not found in the MIG.
- entered_input: str | None
If the message which is evaluated contains data for this data element, this is set to a value which is not None. The field can either carry a free text or an element from a value pool (depending on the value_type)
- value_type: DataElementDataType | None
The value_type allows to describe which type of data we’re expecting to be used within this data element. The value_type does not discriminate the type of the data element itself.
- class maus.models.edifact_components.DataElementDataType(value)[source]
-
The Data Element Data Type describes with which kind of data element we’re dealing with in a data element. This information is set but not used anywhere inside MAUS directly but more of a “service” to downstream code.
- DATETIME = 'DATETIME'
a datetime string, usually as RFC3339
- TEXT = 'TEXT'
plain text, e.g. a name
- VALUE_POOL = 'VALUE_POOL'
the user can choose between different possible values
- class maus.models.edifact_components.DataElementFreeText(*, discriminator: str | None, data_element_id: str, entered_input: str | None, value_type: DataElementDataType | None = DataElementDataType.TEXT, ahb_expression: str)[source]
Bases:
DataElementA DataElementFreeText is a data element that allows entering arbitrary data. This is the main difference to the
DataElementValuePoolwhich has a finite set of allowed values attached.- ahb_expression: str
any freetext data element has an ahb expression attached. Could be ‘X’ but also ‘M [13]’
- value_type: DataElementDataType | None
The value_type allows to describe which type of data we’re expecting to be used within this data element. The value_type does not discriminate the type of the data element itself.
- class maus.models.edifact_components.DataElementFreeTextSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
DataElementSchemaA Schema to serialize DataElementFreeTexts
- deserialize(data, **kwargs) DataElementFreeText[source]
Converts the barely typed data dictionary into an actual
DataElementFreeText
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.edifact_components.DataElementSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA Schema to (de-)serialize DataElements
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.edifact_components.DataElementValuePool(*, discriminator: str | None, data_element_id: str, entered_input: str | None, value_type: DataElementDataType | None = DataElementDataType.VALUE_POOL, value_pool: List[ValuePoolEntry])[source]
Bases:
DataElementA DataElementValuePool is a data element with a finite set of allowed values. These allowed values are referred to as keys of the “value pool”. The value pool is defined both on MIG level and AHB level The set of values allowed according to the AHB is always a subset of the values allowed according to the MIG.
- has_value_pool_which_is_subset_of(entries: Iterable[str]) bool[source]
returns true iff all qualifiers from the data elements value pool are found in entries
- replace_value_pool(edifact_to_domain_mapping: Mapping[str, str], meaning_qualifier_merger: Callable[[str, str], str] | None = None) None[source]
If your data model comes from another domain than edifact the value pool from the AHBs, you can, in general, not use the same keys. Think e.g. of the Transaktionsgrund in UTILMD. In EDIFACT you might have the values: Edifact Domain: - E01 = Einzug/Auszug - E03 = Wechsel - Z33 = Auszug/Stilllegung … But if, in your application, you’re modelling these values with other values (think e.g. of readable enums): Application Domain: - EINZUG = Einzug/Auszug - WECHSEL = Wechsel - STILLLEGUNG = Auszug/Stilllegung … You need to transform the value pool from edifact to something that matches the domain from your application. To do so, provide this method with an edifact_to_domain_mapping: {“E01”: “EINZUG”,”E02”: “WECHSEL”,”E03”: “STILLLEGUNG”} where each entry represents the mapping of an edifact qualifier to your application domain.
This method replaces the keys of the ValuePoolEntries if they are found in the mapping. By doing so, it allows transforming checks against value pools from the edifact to your application domain. This problem does not occur for free text data elements.
Provide an optional meaning_qualifier_merger that allows you to ‘store’ the old qualifier in the meaning. This is an _unstructured_ way to save the information that is lost with the replacement.
- value_pool: List[ValuePoolEntry]
The value pool contains at least one value
ValuePoolEntry
- value_type: DataElementDataType | None
type of the value, if known
- class maus.models.edifact_components.DataElementValuePoolSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
DataElementSchemaA Schema to serialize DataElementValuePool
- deserialize(data, **kwargs) DataElementValuePool[source]
Converts the barely typed data dictionary into an actual
DataElementValuePool
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.edifact_components.EdifactStack(*, levels: List[EdifactStackLevel])[source]
Bases:
objectThe EdifactStack describes where inside an EDIFACT message data are found. The stack is independent of the actual implementation used to create the EDIFACT (be it XML, JSON whatever).
- static from_json_path(json_path: str) EdifactStack[source]
reads a json path as it is created by “to_json_path” and returns the corresponding edifact stack
- is_parent_of(other: EdifactStack) bool[source]
Returns true iff this other stack is a sub stack of self.
- is_sub_stack_of(other: EdifactStack) bool[source]
Returns true iff this (self) stack is a sub stack of the other provided stack. ([Foo][0][Bar]).is_sub_stack_of([Foo][0]) is true.
- levels: List[EdifactStackLevel]
levels describe the nesting inside an edifact message
- class maus.models.edifact_components.EdifactStackLevel(*, name: str, is_groupable: bool, index: int | None = None)[source]
Bases:
objectThe EDIFACT stack level describes the hierarchy level of information inside an EDIFACT message.
- class maus.models.edifact_components.Segment(*, discriminator: str, ahb_expression: str, ahb_line_index: int | None = None, data_elements: List[DataElement], section_name: str | None = None)[source]
Bases:
SegmentLevelA Segment contains multiple data elements.
- data_elements: List[DataElement]
- get_all_value_pools() List[DataElementValuePool][source]
find all value pools in this segment :return: a list of all value pools
- section_name: str | None
For the MIG matching it might be necessary to know the section in which the data element occured in the AHB. This might be necessary to e.g. distinguish gas and electricity fields which look the same otherwise. See e.g. UTILMD ‘Geplante Turnusablesung des MSB (Strom)’ vs. ‘Geplante Turnusablesung des NB (Gas)’
- class maus.models.edifact_components.SegmentGroup(*, discriminator: str, ahb_expression: str, ahb_line_index: int | None = None, segments: List[Segment] | None = None, segment_groups: List[SegmentGroup] | None = None)[source]
Bases:
SegmentLevelA segment group that contains segments and nested groups. On root level of a message there might be a “virtual” segment group of all segments that formally don’t have a group This group has the key “root”.
- find_segments(predicate: Callable[[Segment], bool], search_recursively: bool = True) List[Segment][source]
Search for a segment that matches the predicate (in this group and subgroups if ‘search_recursively’ is set), Return results, if found. Return empty list otherwise.
- get_all_value_pools() List[DataElementValuePool][source]
recursively find all value pools in this segmentgroup :return: a list of all value pools
- reset_ahb_line_index() None[source]
sets the ahb_line_index to None. This is to allow comparisons regardless of the index
- segment_groups: List[SegmentGroup] | None
groups that are nested into this group
- class maus.models.edifact_components.SegmentGroupSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SegmentLevelSchemaA Schema to serialize SegmentGroups.
- deserialize(data, **kwargs) SegmentGroup[source]
Converts the barely typed data dictionary into an actual
SegmentGroup
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.edifact_components.SegmentLevel(*, discriminator: str, ahb_expression: str, ahb_line_index: int | None = None)[source]
Bases:
ABCSegmentLevel describes @annika: what does it describe?
- class maus.models.edifact_components.SegmentLevelSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA Schema to serialize SegmentLevels
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.edifact_components.SegmentSchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SegmentLevelSchemaA Schema to serialize Segments
- deserialize(data, **kwargs) Segment[source]
Converts the barely typed data dictionary into an actual
Segment
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- class maus.models.edifact_components.ValuePoolEntry(*, qualifier: str, meaning: str, ahb_expression: str)[source]
Bases:
objectA value pool entry contains the EDIFACT qualifier, a meaning (German text) and an ahb expression. A value pool consists of 1 to n ValuePoolEntries. The data element 3055 in UTILMD is a good example for a value pool. It is used in the segments NAD+MS and NAD+MR. Its ValuePoolEntries are: - (key: “9”, meaning: “GS1”, ahb_expression: “X”) - (key: “293”, meaning: “DE, BDEW”, ahb_expression: “X”) - (key: “332”, meaning: “DE, DVGW”, ahb_expression: “X”)
- class maus.models.edifact_components.ValuePoolEntrySchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA Schema to serialize ValuePoolEntries
- deserialize(data, **kwargs) ValuePoolEntry[source]
Converts the barely typed data dictionary into an actual
ValuePoolEntry
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
- maus.models.edifact_components.derive_data_type_from_segment_code(segment_code: str) DataElementDataType | None[source]
derives the expected data type from the segment code, e.g. DATETIME for DTM segments :return: The DataType if it can be derived without any doubt, None otherwise
- maus.models.edifact_components.gabi_edifact_qualifier_pattern = re.compile('^(?!MP-ID)(GABi)?[A-Z\\d\\-]+(RLM(o|m)T)?$')
They contain with “-” and lower case “i”/”o”/”n”
- Type:
a pattern that matches the GABi qualifiers
maus.models.message_implementation_guide module
Contains classes to Model Message Implementation Guides (MIG)
- class maus.models.message_implementation_guide.SegmentGroupHierarchy(*, segment_group: str | None, opening_segment: str, sub_hierarchy: List[SegmentGroupHierarchy] | None)[source]
Bases:
objectModels the hierarchy of segment groups within an EDIFACT format. Therefore each segment group is modeled together with its respective first segment inside the group. This is not a full representation of the EDIFACT formats structure but enough to understand the basic hierarchy. The Segment Group Hierarchy (SGH) is what allows us to transform a flat AHB into a NestedAhb that has a structure. This information / the SGH can be (manually) extracted form the diagrams in the MIG PDFs or generated from another source (which the BDEW does not provide, sadly). See the unit tests for working examples for UTILMD and MSCONS. It’ll make sense then.
- flattened() List[Tuple[str | None, str]][source]
Returns the segment groups and opening tuples in the order in which they are expected to occur in an AHB. This is useful to match this deep structure with a flat AHB.
- is_hierarchically_below(segment_group_key: str | None) bool[source]
returns true iff the segment_group provided is a (direct or indirect) sub group of self.
- sg_is_hierarchically_below(segment_group_key_x: str | None, segment_group_key_y: str | None) bool[source]
returns true iff segment group with segment_group_key_x is hierarchically below the segment_group with key_y :param segment_group_key_x: :param segment_group_key_y: :return:
- sub_hierarchy: List[SegmentGroupHierarchy] | None
segment groups below this level, e.g.[(SG5, LOG), (SG6,RFF), (SG8, SEQ), …]
- class maus.models.message_implementation_guide.SegmentGroupHierarchySchema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)[source]
Bases:
SchemaA schema to (de-)serialize
SegmentGroupHierarchy- deserialize(data, **kwargs) SegmentGroupHierarchy[source]
Converts the barely typed data dictionary into an actual
SegmentGroupHierarchy
- opts: SchemaOpts = <marshmallow.schema.SchemaOpts object>
Module contents
models are the data classes used to store information from e.g. ahbs. This module contains methods available to all methods in the package.