@@ -702,3 +702,80 @@ def dict_to_sn(d: Any, defaults: dict = None, ns: str = "") -> SimpleNamespace:
702702datacat .__setattr__ ("__namespace_list__" , dataset_namespaces )
703703reportcat = SimpleNamespace (** combined_reports_dict )
704704reportcat .__setattr__ ("__namespace_list__" , report_namespaces )
705+
706+
707+ def _attach_schema_mock_functions (
708+ datacat : SimpleNamespace , catalogs : list
709+ ) -> None :
710+ """Recursively walk the datacat namespace and attach mock_data functions to
711+ the extract and load BlobEndpoints of each DatasetEndpoint, sourced from
712+ a schema module co-located with the dataset.
713+
714+ The schema module is expected to live at:
715+ {catalog_namespace}.{catalog_name}.datasets.{team_path}.schemas.{dataset_name}
716+
717+ where ``team_path`` is the namespace path segment(s) between the catalog
718+ name and the dataset name (for example, ``stf`` in
719+ ``public.stf.nhsn_hrd_prelim``), and ``dataset_name`` is the dataset's
720+ namespace name (for example, ``nhsn_hrd_prelim``).
721+
722+ The schema module should define one or both of:
723+ - extract_mock_data() -> pd.DataFrame
724+ - load_mock_data() -> pd.DataFrame
725+
726+ These are then accessible as:
727+ datacat.<catalog>.<team_path_segments>.<dataset>.extract.mock_data()
728+ datacat.<catalog>.<team_path_segments>.<dataset>.load.mock_data()
729+
730+ Args:
731+ datacat (SimpleNamespace): the top-level datacat namespace
732+ catalogs (list): list of (catalog_namespace, catalog_name, catalog_path)
733+ tuples from get_all_catalogs()
734+ """
735+
736+ def _walk (ns : SimpleNamespace ) -> None :
737+ for val in vars (ns ).values ():
738+ if isinstance (val , DatasetEndpoint ):
739+ # __ns_str__ is e.g. "public.stf.nhsn_hrd_prelim";
740+ # the last segment is used as the schema module name
741+ dataset_name = val .__ns_str__ .split ("." )[- 1 ]
742+ for cns , cat_name , _ in catalogs :
743+ # __ns_str__ is e.g. "public.stf.nhsn_hrd_prelim"
744+ # strip cat_name prefix -> "stf.nhsn_hrd_prelim"
745+ # then split into team ("stf") and dataset ("nhsn_hrd_prelim")
746+ # so the schema lives at: datasets.stf.schemas.nhsn_hrd_prelim
747+ ns_within_datasets = val .__ns_str__ .removeprefix (
748+ f"{ cat_name } ."
749+ )
750+ ns_parts = ns_within_datasets .rsplit ("." , 1 )
751+ team_path = ns_parts [0 ] if len (ns_parts ) > 1 else ""
752+ schema_mod_path = (
753+ f"{ cns } .{ cat_name } .datasets"
754+ f".{ team_path } .schemas.{ dataset_name } "
755+ if team_path
756+ else f"{ cns } .{ cat_name } .datasets.schemas.{ dataset_name } "
757+ )
758+ try :
759+ mod = import_module (schema_mod_path )
760+ except ModuleNotFoundError :
761+ # No schema module for this dataset — skip silently
762+ continue
763+ # Attach to the already-existing BlobEndpoint on .extract / .load
764+ for stage , func_name in [
765+ ("extract" , "extract_mock_data" ),
766+ ("load" , "load_mock_data" ),
767+ ]:
768+ if hasattr (val , stage ):
769+ if hasattr (mod , func_name ):
770+ setattr (
771+ getattr (val , stage ),
772+ "mock_data" ,
773+ getattr (mod , func_name ),
774+ )
775+ elif isinstance (val , SimpleNamespace ):
776+ _walk (val )
777+
778+ _walk (datacat )
779+
780+
781+ _attach_schema_mock_functions (datacat , all_catalogs )
0 commit comments