Skip to content

Commit 8999d5b

Browse files
Add function for writing domain graphs to CSV files (#132)
1 parent b40bd1c commit 8999d5b

5 files changed

Lines changed: 673 additions & 0 deletions

File tree

src/elimity_insights_client/csv.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
"""Utilities for writing domain graph schemas to CSV files."""
2+
3+
from collections.abc import Iterable
4+
from csv import writer
5+
from json import dumps, loads
6+
7+
from elimity_insights_client._decode_domain_graph_schema import (
8+
decode_domain_graph_schema,
9+
)
10+
from elimity_insights_client._domain_graph_schema import DomainGraphSchema
11+
from elimity_insights_client._elimity_insights_client import (
12+
BooleanValue,
13+
DateTimeValue,
14+
DateValue,
15+
DomainGraph,
16+
Entity,
17+
NumberValue,
18+
Relationship,
19+
StringValue,
20+
Value,
21+
)
22+
23+
24+
def write_domain_graph(filename: str, graph: DomainGraph, schema_json: str) -> None:
25+
"""Serialize the given domain graph to an importable CSV file at the given path."""
26+
schema_dict = loads(schema_json)
27+
schema = decode_domain_graph_schema(schema_dict)
28+
with open(filename, "w", newline="") as file:
29+
wri = writer(file)
30+
rows = _rows(graph, schema)
31+
wri.writerows(rows)
32+
33+
34+
def _rows(graph: DomainGraph, schema: DomainGraphSchema) -> Iterable[Iterable[str]]:
35+
yield _headers(schema)
36+
for entity in graph.entities:
37+
yield _entity_cells(entity, schema)
38+
for relationship in graph.relationships:
39+
yield _relationship_cells(relationship, schema)
40+
41+
42+
def _headers(schema: DomainGraphSchema) -> Iterable[str]:
43+
for entity_type in schema.entity_types:
44+
id = entity_type.id
45+
yield from [id + ": id", id + ": name"]
46+
for attribute_type in schema.attribute_types:
47+
yield f"{attribute_type.entity_type}: {attribute_type.id}"
48+
49+
50+
def _entity_cells(entity: Entity, schema: DomainGraphSchema) -> Iterable[str]:
51+
type = entity.type
52+
for entity_type in schema.entity_types:
53+
yield from [entity.id, entity.name] if entity_type.id == type else ["", ""]
54+
values = {
55+
assignment.attribute_type_id: assignment.value
56+
for assignment in entity.attribute_assignments
57+
}
58+
for attribute_type in schema.attribute_types:
59+
value = values.get(attribute_type.id)
60+
yield "" if attribute_type.entity_type != type or value is None else _cell(
61+
value
62+
)
63+
64+
65+
def _relationship_cells(
66+
relationship: Relationship, schema: DomainGraphSchema
67+
) -> Iterable[str]:
68+
for type in schema.entity_types:
69+
dict = {
70+
relationship.from_entity_type: relationship.from_entity_id,
71+
relationship.to_entity_type: relationship.to_entity_id,
72+
}
73+
yield dict.get(type.id, "")
74+
yield ""
75+
yield from [""] * len(schema.attribute_types)
76+
77+
78+
def _cell(value: Value) -> str:
79+
if isinstance(value, BooleanValue):
80+
return "true" if value.value else "false"
81+
82+
elif isinstance(value, DateValue):
83+
return f"{value.year:04}-{value.month:02}-{value.day:02}"
84+
85+
elif isinstance(value, DateTimeValue):
86+
val = value.value
87+
return f"{val.year:04}-{val.month:02}-{val.day:02} {val.hour:02}:{val.minute:02}:{val.second:02}.0"
88+
89+
elif isinstance(value, NumberValue):
90+
return dumps(value.value)
91+
92+
elif isinstance(value, StringValue):
93+
return value.value
94+
95+
else:
96+
return f"{value.hour:02}:{value.minute:02}:{value.second:02}.0"

tests/graph.csv

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
user: id,user: name,group: id,group: name,computer: id,computer: name,user: accountExpires,user: accountType,user: badPwdCount,user: cn,user: company,user: countryCode,user: department,user: departmentNumber,user: description,user: disabled,user: distinguishedName,user: displayName,user: division,user: employeeID,user: givenName,user: initials,user: isDeleted,user: l,user: lastLogon,user: lockedOut,user: logonCount,user: mail,user: manager,user: objectClass,user: objectSid,user: passwordExpired,user: passwdNotreqd,user: pwdLastSet,user: sAMAccountName,user: telephoneNumber,user: userPrincipalName,user: whenChanged,user: whenCreated,group: isDeleted,group: description,group: distinguishedName,group: displayName,group: lastLogon,group: logonCount,group: managedBy,group: objectClass,group: objectSid,group: sAMAccountName,group: whenChanged,group: whenCreated,computer: accountExpires,computer: accountType,computer: badPwdCount,computer: cn,computer: description,computer: disabled,computer: distinguishedName,computer: displayName,computer: isDeleted,computer: lockedOut,computer: objectClass,computer: objectSid,computer: operatingSystem,computer: operatingSystemPack,computer: operatingSystemVersion,computer: pwdLastSet,computer: sAMAccountName,computer: whenChanged,computer: whenCreated
2+
"cn=Amy Wong+sn=Kroker,ou=people,dc=planetexpress,dc=com",Amy Wong,,,,,,,,Amy Wong,,,,,Human,,,,,,Amy,,,,,,,amy@planetexpress.com,,top/user/organizationalPerson/inetOrgPerson,,,,,,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
3+
"cn=Bender Bending Rodríguez,ou=people,dc=planetexpress,dc=com",Bender Bending Rodríguez,,,,,,,,Bender Bending Rodríguez,,,,,Robot,,,Bender,,,Bender,,,,,,,bender@planetexpress.com,,inetOrgPerson/organizationalPerson/user/top,,,,,,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
4+
"cn=Philip J. Fry,ou=people,dc=planetexpress,dc=com",Philip J. Fry,,,,,,,,Philip J. Fry,,,,,Human,,,Fry,,,Philip,,,,,,,fry@planetexpress.com,,inetOrgPerson/organizationalPerson/user/top,,,,,,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
5+
"cn=Hermes Conrad,ou=people,dc=planetexpress,dc=com",Hermes Conrad,,,,,,,,Hermes Conrad,,,,,Human,,,,,,Hermes,,,,,,,hermes@planetexpress.com,,top/user/organizationalPerson/inetOrgPerson,,,,,,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
6+
"cn=Turanga Leela,ou=people,dc=planetexpress,dc=com",Turanga Leela,,,,,,,,Turanga Leela,,,,,Mutant,,,,,,Leela,,,,,,,leela@planetexpress.com,,inetOrgPerson/organizationalPerson/user/top,,,,,,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
7+
"cn=Hubert J. Farnsworth,ou=people,dc=planetexpress,dc=com",Hubert J. Farnsworth,,,,,,,,Hubert J. Farnsworth,,,,,Human,,,Professor Farnsworth,,,Hubert,,,,,,,professor@planetexpress.com/hubert@planetexpress.com,,inetOrgPerson/organizationalPerson/user/top,,,,,,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
8+
"cn=John A. Zoidberg,ou=people,dc=planetexpress,dc=com",John A. Zoidberg,,,,,,,,John A. Zoidberg,,,,,Decapodian,,,Zoidberg,,,John,,,,,,,zoidberg@planetexpress.com,,top/user/organizationalPerson/inetOrgPerson,,,,,,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
9+
,,"cn=admin_staff,ou=people,dc=planetexpress,dc=com",admin_staff,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,group/top,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,
10+
,,"cn=ship_crew,ou=people,dc=planetexpress,dc=com",ship_crew,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,group/top,,,2021-03-11 13:28:53.0,2021-03-11 13:28:53.0,,,,,,,,,,,,,,,,,,,
11+
"cn=Hermes Conrad,ou=people,dc=planetexpress,dc=com",,"cn=admin_staff,ou=people,dc=planetexpress,dc=com",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
12+
"cn=Hubert J. Farnsworth,ou=people,dc=planetexpress,dc=com",,"cn=admin_staff,ou=people,dc=planetexpress,dc=com",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
13+
"cn=Bender Bending Rodríguez,ou=people,dc=planetexpress,dc=com",,"cn=ship_crew,ou=people,dc=planetexpress,dc=com",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
14+
"cn=Turanga Leela,ou=people,dc=planetexpress,dc=com",,"cn=ship_crew,ou=people,dc=planetexpress,dc=com",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
15+
"cn=Philip J. Fry,ou=people,dc=planetexpress,dc=com",,"cn=ship_crew,ou=people,dc=planetexpress,dc=com",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

tests/graph.pickle

4.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)