1515from linkml_runtime .dumpers import yaml_dumper
1616from linkml_runtime .linkml_model import Annotation , Example
1717from linkml_runtime .linkml_model .meta import SchemaDefinition , ClassDefinition , Prefix , \
18- SlotDefinition , EnumDefinition , PermissibleValue , SubsetDefinition , TypeDefinition , Element
18+ SlotDefinition , EnumDefinition , PermissibleValue , SubsetDefinition , TypeDefinition , Element , Setting
1919from linkml_runtime .utils .schema_as_dict import schema_as_dict
2020from linkml_runtime .utils .schemaview import SchemaView , re
2121
2222from schemasheets .schemasheet_datamodel import ColumnConfig , TableConfig , get_configmodel , get_metamodel , COL_NAME , \
2323 DESCRIPTOR , \
24- tmap , T_CLASS , T_PV , T_SLOT , T_SUBSET , T_SCHEMA , T_ENUM , T_PREFIX , T_TYPE , SchemaSheet
24+ tmap , T_CLASS , T_PV , T_SLOT , T_SUBSET , T_SCHEMA , T_ENUM , T_PREFIX , T_TYPE , SchemaSheet , T_SETTING
2525from schemasheets .conf .configschema import Cardinality
2626from schemasheets .utils .google_sheets import gsheets_download_url
2727from schemasheets .utils .prefixtool import guess_prefix_expansion
@@ -83,7 +83,6 @@ def _tidy_slot_usage(self):
8383 c .slots .remove (sn )
8484 del c .slot_usage [sn ]
8585
86-
8786 def merge_sheet (self , file_name : str , delimiter = '\t ' ) -> None :
8887 """
8988 Merge information from the given schema sheet into the current schema
@@ -93,15 +92,15 @@ def merge_sheet(self, file_name: str, delimiter='\t') -> None:
9392 :return:
9493 """
9594 logging .info (f'READING { file_name } D={ delimiter } ' )
96- #with self.ensure_file(file_name) as tsv_file:
95+ # with self.ensure_file(file_name) as tsv_file:
9796 # reader = csv.DictReader(tsv_file, delimiter=delimiter)
9897 with self .ensure_csvreader (file_name , delimiter = delimiter ) as reader :
9998 schemasheet = SchemaSheet .from_dictreader (reader )
10099 if self .table_config_path :
101100 schemasheet .load_table_config (self .table_config_path )
102101 line_num = schemasheet .start_line_number
103102 # TODO: check why this doesn't work
104- #while rows and all(x for x in rows[-1] if not x):
103+ # while rows and all(x for x in rows[-1] if not x):
105104 # print(f'TRIMMING: {rows[-1]}')
106105 # rows.pop()
107106 logging .info (f'ROWS={ len (schemasheet .rows )} ' )
@@ -118,21 +117,29 @@ def add_row(self, row: Dict[str, Any], table_config: TableConfig):
118117 name = element .prefix_prefix
119118 elif isinstance (element , PermissibleValue ):
120119 name = element .text
120+ elif isinstance (element , Setting ):
121+ # print(f"\n{element = }")
122+ name = element .setting_key
121123 else :
122124 logging .debug (f'EL={ element } in { row } ' )
123125 name = element .name
124126 logging .debug (f'ADDING: { row } // { name } ' )
125127 for k , v in row .items ():
128+ # print(f"\n{k = }")
126129 if k not in table_config .columns :
127130 raise ValueError (f'Expected to find { k } in { table_config .columns .keys ()} ' )
128131 cc = table_config .columns [k ]
132+ # print(f"{cc = }")
129133 v = self .normalize_value (v , cc )
130134 if v :
135+ # print(f"{v = }")
131136 # special case: class-context provided by settings
132137 if cc .settings .applies_to_class :
133138 actual_element = list (self .row_focal_element (row , table_config , column = k ))[0 ]
134139 else :
135140 actual_element = element
141+ # print(f"{cc.maps_to = }")
142+ # print(f"{cc = }")
136143 logging .debug (f'SETTING { name } { cc .maps_to } = { v } ' )
137144 if cc .maps_to == 'cardinality' :
138145 self .set_cardinality (actual_element , v )
@@ -172,9 +179,13 @@ def add_row(self, row: Dict[str, Any], table_config: TableConfig):
172179 curr_val = getattr (curr_obj , cc .settings .inner_key , None )
173180 else :
174181 curr_val = getattr (actual_element , cc .maps_to )
182+ # print(f"{curr_val = }")
183+ # print(f"{v = }")
184+
175185 if curr_val and curr_val != 'TEMP' and curr_val != v and \
176186 not isinstance (actual_element , SchemaDefinition ) and \
177- not isinstance (actual_element , Prefix ):
187+ not isinstance (actual_element , Prefix ) and \
188+ not isinstance (actual_element , Setting ):
178189 logging .warning (f'Overwriting value for { k } , was { curr_val } , now { v } ' )
179190 raise ValueError (f'Cannot reset value for { k } , was { curr_val } , now { v } ' )
180191 if cc .settings .inner_key :
@@ -288,17 +299,25 @@ def row_focal_element(self, row: Dict[str, Any], table_config: TableConfig,
288299 pfx = Prefix (vs [0 ], 'TODO' )
289300 self .schema .prefixes [pfx .prefix_prefix ] = pfx
290301 vmap [k ] = [pfx ]
302+ elif elt_cls == Setting :
303+ if len (vs ) != 1 :
304+ raise ValueError (f'Cardinality of setting col must be 1; got: { vs } ' )
305+ stg = Setting (vs [0 ], 'TODO' )
306+ self .schema .settings [stg .setting_key ] = stg
307+ vmap [k ] = [stg ]
291308 elif elt_cls == SchemaDefinition :
292309 if len (vs ) != 1 :
293310 raise ValueError (f'Cardinality of schema col must be 1; got: { vs } ' )
294311 self .schema .name = vs [0 ]
295312 vmap [k ] = [self .schema ]
296313 else :
297314 vmap [k ] = [self .get_current_element (elt_cls (v )) for v in vs ]
315+
298316 def check_excess (descriptors ):
299317 diff = set (vmap .keys ()) - set (descriptors + [T_SCHEMA ])
300318 if len (diff ) > 0 :
301319 raise ValueError (f'Excess slots: { diff } ' )
320+
302321 if column :
303322 cc = table_config .columns [column ]
304323 if cc .settings .applies_to_class :
@@ -351,7 +370,7 @@ def check_excess(descriptors):
351370 this_enum : EnumDefinition = vmap [T_ENUM ][0 ]
352371 if T_PV in vmap :
353372 for pv in vmap [T_PV ]:
354- #pv = PermissibleValue(text=v)
373+ # pv = PermissibleValue(text=v)
355374 this_enum .permissible_values [pv .text ] = pv
356375 yield pv
357376 else :
@@ -368,6 +387,9 @@ def check_excess(descriptors):
368387 elif T_SCHEMA in vmap :
369388 for main_elt in vmap [T_SCHEMA ]:
370389 yield main_elt
390+ elif T_SETTING in vmap :
391+ for main_elt in vmap [T_SETTING ]:
392+ yield main_elt
371393 else :
372394 raise ValueError (f'Could not find a focal element for { row } ' )
373395
@@ -419,7 +441,8 @@ def normalize_value(self, v: str, column_config: ColumnConfig = None) -> Any:
419441 v = None
420442 if column_config .settings .curie_prefix :
421443 if ':' in v :
422- logging .warning (f'Will not prefix { v } with { column_config .settings .curie_prefix } as it is already prefixed' )
444+ logging .warning (
445+ f'Will not prefix { v } with { column_config .settings .curie_prefix } as it is already prefixed' )
423446 else :
424447 v = f'{ column_config .settings .curie_prefix } :{ v } '
425448 if column_config .settings .prefix :
@@ -537,8 +560,8 @@ def repair_schema(self, schema: SchemaDefinition) -> SchemaDefinition:
537560 :return:
538561 """
539562 sv = SchemaView (schema )
540- #pfx = schema.default_prefix
541- #if pfx not in schema.prefixes:
563+ # pfx = schema.default_prefix
564+ # if pfx not in schema.prefixes:
542565 # schema.prefixes[pfx] = Prefix(pfx, f'http://example.org/{pfx}/')
543566 # logging.info(f'Set default prefix: {schema.prefixes[pfx]}')
544567 prefixes = set ()
@@ -622,7 +645,8 @@ def ensure_csvreader(self, file_name: str, delimiter=None) -> str:
622645 help = "Google sheets ID. If this is specified then the arguments MUST be sheet names" )
623646@click .option ("-v" , "--verbose" , count = True )
624647@click .argument ('tsv_files' , nargs = - 1 )
625- def convert (tsv_files , gsheet_id , output : TextIO , name , repair , table_config_path : str , use_attributes : bool , unique_slots : bool , verbose : int , sort_keys : bool ):
648+ def convert (tsv_files , gsheet_id , output : TextIO , name , repair , table_config_path : str , use_attributes : bool ,
649+ unique_slots : bool , verbose : int , sort_keys : bool ):
626650 """
627651 Convert schemasheets to a LinkML schema
628652
@@ -653,14 +677,8 @@ def convert(tsv_files, gsheet_id, output: TextIO, name, repair, table_config_pat
653677 schema = sm .repair_schema (schema )
654678 schema_dict = schema_as_dict (schema )
655679 output .write (yaml .dump (schema_dict , sort_keys = sort_keys ))
656- #output.write(yaml_dumper.dumps(schema))
680+ # output.write(yaml_dumper.dumps(schema))
657681
658682
659683if __name__ == '__main__' :
660684 convert ()
661-
662-
663-
664-
665-
666-
0 commit comments