18
18
import networkx as nx
19
19
from jinja2 import Environment , PackageLoader
20
20
21
- from pyatlan .model .typedef import EntityDef , EnumDef , TypeDefResponse
22
- from pyatlan .model .utils import to_snake_case
21
+ from pyatlan .model .typedef import EntityDef , EnumDef , RelationshipDef , TypeDefResponse
22
+ from pyatlan .model .utils import to_python_class_name , to_snake_case
23
23
24
24
REFERENCEABLE = "Referenceable"
25
25
TYPE_DEF_FILE = Path (os .getenv ("TMPDIR" , "/tmp" )) / "typedefs.json"
80
80
# across Python versions (e.g: 3.8 and 3.9).
81
81
PARENT = Path (__file__ ).resolve ().parent
82
82
ASSETS_DIR = PARENT .parent / "model" / "assets"
83
+ ASSETS_RELATIONS_DIR = PARENT .parent / "model" / "assets" / "relations"
83
84
CORE_ASSETS_DIR = PARENT .parent / "model" / "assets" / "core"
84
85
MODEL_DIR = PARENT .parent / "model"
85
86
DOCS_DIR = PARENT .parent / "documentation"
@@ -450,6 +451,29 @@ def create_modules(cls):
450
451
cls ._CORE_ASSETS .add (related_asset .super_class )
451
452
452
453
454
+ class RelationshipDefInfo :
455
+ module_name : str
456
+ relationship_def_infos : List ["RelationshipDefInfo" ] = []
457
+
458
+ def __init__ (self , name : str , relationship_def : RelationshipDef ):
459
+ self .module_name = to_snake_case (name )
460
+ self .relationship_def = relationship_def
461
+
462
+ @classmethod
463
+ def create (cls , relationship_defs : List [RelationshipDef ]):
464
+ for rel_def in relationship_defs :
465
+ # Only pick `atlas_core` enums, not user-created ones.
466
+ if rel_def .attribute_defs :
467
+ cls .relationship_def_infos .append (
468
+ RelationshipDefInfo (
469
+ name = to_snake_case (rel_def .name ), relationship_def = rel_def
470
+ )
471
+ )
472
+ # if rel_def.name == "UserDefRelationship":
473
+ # import ipdb; ipdb.set_trace()
474
+ # print(to_python_class_name(rel_def.name))
475
+
476
+
453
477
class AttributeType (Enum ):
454
478
PRIMITIVE = "PRIMITIVE"
455
479
ENUM = "ENUM"
@@ -664,6 +688,7 @@ def __init__(self) -> None:
664
688
)
665
689
self .environment .filters ["to_snake_case" ] = to_snake_case
666
690
self .environment .filters ["get_type" ] = get_type
691
+ self .environment .filters ["to_cls_name" ] = to_python_class_name
667
692
self .environment .filters ["get_search_type" ] = get_search_type
668
693
self .environment .filters ["get_mapped_type" ] = get_mapped_type
669
694
self .environment .filters ["get_class_var_for_attr" ] = get_class_var_for_attr
@@ -719,6 +744,21 @@ def render_module(self, asset_info: AssetInfo, enum_defs: List["EnumDefInfo"]):
719
744
with (ASSETS_DIR / f"{ asset_info .module_name } .py" ).open ("w" ) as script :
720
745
script .write (content )
721
746
747
+ def render_custom_relationship_module (
748
+ self , relationship_def_info : RelationshipDefInfo
749
+ ):
750
+ template = self .environment .get_template ("custom_relationship.jinja2" )
751
+ content = template .render (
752
+ {
753
+ "relationship_info" : relationship_info .relationship_def ,
754
+ "templates_path" : TEMPLATES_DIR .absolute ().as_posix (),
755
+ }
756
+ )
757
+ with (ASSETS_RELATIONS_DIR / f"{ relationship_def_info .module_name } .py" ).open (
758
+ "w"
759
+ ) as script :
760
+ script .write (content )
761
+
722
762
def render_core_module (self , asset_info : AssetInfo , enum_defs : List ["EnumDefInfo" ]):
723
763
template = self .environment .get_template ("module.jinja2" )
724
764
content = template .render (
@@ -769,6 +809,22 @@ def render_mypy_init(self, assets: List[AssetInfo]):
769
809
with init_path .open ("w" ) as script :
770
810
script .write (content )
771
811
812
+ def render_relations_init (self , relation_def_infos : List [RelationshipDefInfo ]):
813
+ template = self .environment .get_template ("relations_init.jinja2" )
814
+ content = template .render ({"relation_def_infos" : relation_def_infos })
815
+
816
+ init_path = ASSETS_RELATIONS_DIR / "__init__.py"
817
+ with init_path .open ("w" ) as script :
818
+ script .write (content )
819
+
820
+ def render_relations_mypy_init (self , relation_def_infos : List [RelationshipDefInfo ]):
821
+ template = self .environment .get_template ("relations_mypy_init.jinja2" )
822
+ content = template .render ({"relation_def_infos" : relation_def_infos })
823
+
824
+ init_path = ASSETS_RELATIONS_DIR / "__init__.pyi"
825
+ with init_path .open ("w" ) as script :
826
+ script .write (content )
827
+
772
828
def render_structs (self , struct_defs ):
773
829
template = self .environment .get_template ("structs.jinja2" )
774
830
content = template .render ({"struct_defs" : struct_defs })
@@ -933,8 +989,10 @@ def filter_attributes_of_custom_entity_type():
933
989
filter_attributes_of_custom_entity_type ()
934
990
AssetInfo .sub_type_names_to_ignore = type_defs .custom_entity_def_names
935
991
AssetInfo .set_entity_defs (type_defs .reserved_entity_defs )
992
+ RelationshipDefInfo .create (type_defs .relationship_defs )
936
993
AssetInfo .update_all_circular_dependencies ()
937
994
AssetInfo .create_modules ()
995
+
938
996
for file in (ASSETS_DIR ).glob ("*.py" ):
939
997
file .unlink ()
940
998
for file in (CORE_ASSETS_DIR ).glob ("*.py" ):
@@ -944,14 +1002,28 @@ def filter_attributes_of_custom_entity_type():
944
1002
file .unlink ()
945
1003
generator = Generator ()
946
1004
EnumDefInfo .create (type_defs .enum_defs )
1005
+
947
1006
for asset_info in ModuleInfo .assets .values ():
948
1007
if asset_info .is_core_asset or asset_info .name in asset_info ._CORE_ASSETS :
949
1008
generator .render_core_module (asset_info , EnumDefInfo .enum_def_info )
950
1009
else :
951
1010
generator .render_module (asset_info , EnumDefInfo .enum_def_info )
1011
+
1012
+ for file in (ASSETS_RELATIONS_DIR ).glob ("*.py" ):
1013
+ # Remove all files in the core assets
1014
+ # directory except `relationship_attributes.py`
1015
+ if file .name == "relationship_attributes.py" :
1016
+ continue
1017
+ file .unlink ()
1018
+
1019
+ for relationship_info in RelationshipDefInfo .relationship_def_infos :
1020
+ generator .render_custom_relationship_module (relationship_info )
1021
+
952
1022
generator .render_init (ModuleInfo .assets .values ()) # type: ignore
953
1023
generator .render_core_init (ModuleInfo .assets .values ()) # type: ignore
954
1024
generator .render_mypy_init (ModuleInfo .assets .values ()) # type: ignore
1025
+ generator .render_relations_init (RelationshipDefInfo .relationship_def_infos ) # type: ignore
1026
+ generator .render_relations_mypy_init (RelationshipDefInfo .relationship_def_infos ) # type: ignore
955
1027
generator .render_structs (type_defs .struct_defs )
956
1028
generator .render_enums (EnumDefInfo .enum_def_info )
957
1029
generator .render_docs_struct_snippets (type_defs .struct_defs )
0 commit comments