@@ -25,7 +25,7 @@ def generate_python_name(json_name, allow_multiple=False):
2525 python_name = re .sub ("(.)([A-Z][a-z]+)" , r"\1_\2" , json_name .strip ())
2626 python_name = re .sub ("([a-z0-9])([A-Z])" , r"\1_\2" , python_name ).lower ()
2727 replacements = [
28- ("-" , "_" ), ("." , "_" ), ("+" , "plus" ), ("#" , "sharp" ), ("," , "comma" ), ("(" , "" ), (")" , "" )
28+ ("-" , "_" ), ("." , "_" ),( "'" , "_prime_" ), ("+" , "plus" ), ("#" , "sharp" ), ("," , "comma" ), ("(" , "" ), (")" , "" )
2929 ]
3030 for before , after in replacements :
3131 python_name = python_name .replace (before , after )
@@ -57,14 +57,19 @@ class PythonBuilder(object):
5757
5858 def __init__ (self , schema_file_path : str , root_path : str , instances : Optional [dict ] = None ,
5959 additional_methods : Optional [dict ] = None ):
60- self .template_name = "src/module_template.py.txt"
6160 self .env = Environment (
6261 loader = FileSystemLoader (os .path .dirname (os .path .realpath (__file__ ))), autoescape = select_autoescape ()
6362 )
6463 _relative_path_without_extension = (
6564 schema_file_path [len (root_path ) + 1 :].replace (".schema.omi.json" , "" ).split ("/" )
6665 )
6766 self .version = _relative_path_without_extension [0 ]
67+ self .template_name = "src/module_template.py.txt"
68+ if self .version in ["v3.0" , "v2.0" , "v1.0" ]:
69+ self .context_vocab = "https://openminds.ebrains.eu/vocab/"
70+ else :
71+ self .context_vocab = "https://openminds.om-i.org/props/"
72+
6873 self .relative_path_without_extension = [
6974 generate_python_name (part ) for part in _relative_path_without_extension [1 :]
7075 ]
@@ -83,7 +88,7 @@ def _version_module(self):
8388 def _target_file_without_extension (self ) -> str :
8489 return os .path .join (self ._version_module , "/" .join (self .relative_path_without_extension ))
8590
86- def translate (self , embedded = None ):
91+ def translate (self , embedded = None , class_to_module_map = None ):
8792 def get_type (property ):
8893 type_map = {
8994 "string" : "str" ,
@@ -100,17 +105,23 @@ def get_type(property):
100105 if "_linkedTypes" in property :
101106 types = []
102107 for item in property ["_linkedTypes" ]:
103- openminds_module , class_name = item .split ("/" )[- 2 :]
104- openminds_module = generate_python_name (openminds_module )
108+ openminds_module_from_type , class_name = item .split ("/" )[- 2 :]
109+ if isinstance (class_to_module_map ,dict ) and (class_name in class_to_module_map ):
110+ openminds_module = generate_python_name (class_to_module_map [class_name ])
111+ else :
112+ openminds_module = generate_python_name (openminds_module_from_type )
105113 types .append (f"openminds.{ self ._version_module } .{ openminds_module } .{ class_name } " )
106114 if len (types ) == 1 :
107115 types = f'"{ types [0 ]} "'
108116 return types
109117 elif "_embeddedTypes" in property :
110118 types = []
111119 for item in property ["_embeddedTypes" ]:
112- openminds_module , class_name = item .split ("/" )[- 2 :]
113- openminds_module = generate_python_name (openminds_module )
120+ openminds_module_from_type , class_name = item .split ("/" )[- 2 :]
121+ if isinstance (class_to_module_map ,dict ) and (class_name in class_to_module_map ):
122+ openminds_module = generate_python_name (class_to_module_map [class_name ])
123+ else :
124+ openminds_module = generate_python_name (openminds_module_from_type )
114125 types .append (f"openminds.{ self ._version_module } .{ openminds_module } .{ class_name } " )
115126 if len (types ) == 1 :
116127 types = f'"{ types [0 ]} "'
@@ -201,6 +212,7 @@ def filter_instance(instance):
201212 "class_name" : class_name ,
202213 "openminds_type" : openminds_type ,
203214 "schema_version" : self .version ,
215+ "context_vocab" : self .context_vocab ,
204216 "properties" : properties ,
205217 "additional_methods" : "" ,
206218 "instances" : instances
@@ -233,11 +245,11 @@ def filter_instance(instance):
233245 if extra_imports :
234246 self .context ["preamble" ] = "\n " .join (sorted (extra_imports ))
235247
236- def build (self , embedded = None ):
248+ def build (self , embedded = None , class_to_module_map = None ):
237249 target_file_path = os .path .join ("target" , "openminds" , f"{ self ._target_file_without_extension ()} .py" )
238250 os .makedirs (os .path .dirname (target_file_path ), exist_ok = True )
239251
240- self .translate (embedded = embedded )
252+ self .translate (embedded = embedded , class_to_module_map = class_to_module_map )
241253
242254 with open (target_file_path , "w" ) as target_file :
243255 contents = self .env .get_template (self .template_name ).render (self .context )
@@ -252,3 +264,32 @@ def get_edges(self):
252264 embedded .update (property .get ("_embeddedTypes" , []))
253265 linked .update (property .get ("_linkedTypes" , []))
254266 return embedded , linked
267+
268+ def update_class_to_module_map (self ,class_to_module_map ):
269+ """
270+ Updates a dictionary with the class name and its corresponding module based on the schemas.
271+
272+ This method extracts the class name and module from the `_schema_payload` attribute
273+ and updates the provided dictionary (`class_to_module_map`) with a mapping of
274+ the class name to its module. If the `_module` key exists in `_schema_payload`
275+ (which was introduced in version 4 of openMINDS), its value is used as the module.
276+ Otherwise, the module is derived from the second-to-last component of the `_type`
277+ field in `_schema_payload`.
278+
279+ Args:
280+ class_to_module_map (dict): A dictionary where keys are class names and values
281+ are their corresponding modules.
282+
283+ Returns:
284+ dict: The updated dictionary with the class name and module mapping.
285+ """
286+ schema_type = self ._schema_payload ["_type" ]
287+ class_name = schema_type .split ("/" )[- 1 ]
288+ if "_module" in self ._schema_payload :
289+ module = self ._schema_payload ["_module" ]
290+ else :
291+ module = schema_type .split ("/" )[- 2 ]
292+
293+ class_to_module_map [class_name ]= module
294+
295+ return class_to_module_map
0 commit comments