44import attr
55from typing import Any , Dict , Optional , Union
66
7+ from superstac ._logging import logger
78from superstac .enums import CatalogOutputFormat
89from superstac .exceptions import (
910 CatalogConfigFileNotFound ,
1617
1718@attr .s (auto_attribs = True )
1819class CatalogManager :
20+ logger .info ("Initialized superstac" )
1921 catalogs : Dict [str , CatalogEntry ] = attr .Factory (dict )
2022
2123 def register_catalog (
@@ -41,10 +43,19 @@ def register_catalog(
4143 Returns:
4244 CatalogEntry: The registered STAC catalog.
4345 """
46+ logger .info (f"Registering catalog: { name } " )
47+ logger .debug (
48+ f"Params - url: { url } , is_private: { is_private } , summary: { summary } , auth: { auth } "
49+ )
4450 if is_private and auth is None :
51+ logger .error (
52+ f"Private catalog '{ name } ' requires authentication but none was provided."
53+ )
4554 raise InvalidCatalogSchemaError (
4655 f"Authentication parameters is required for private catalogs. If this is a mistake, you can set 'is_private' to False or provide the { AuthInfo .__annotations__ } parameters."
4756 )
57+
58+ logger .info (f"Catalog '{ name } ' registered successfully." )
4859 self .catalogs [name ] = CatalogEntry (
4960 name = name ,
5061 url = url ,
@@ -65,56 +76,86 @@ def get_available_catalogs(
6576 Returns:
6677 list[CatalogEntry]: The list of all available STAC catalogs.
6778 """
79+ logger .info ("Retrieving available catalogs." )
6880 if isinstance (format , str ):
6981 try :
7082 format = CatalogOutputFormat (format .lower ())
7183 except ValueError :
84+ logger .error (f"Invalid output format: { format } " )
7285 raise ValueError (f"Invalid format: { format } " )
7386
74- return [
87+ available = [
7588 c .as_dict () if format == CatalogOutputFormat .DICT else c .as_json ()
7689 for c in self .catalogs .values ()
7790 if c .is_available
7891 ]
7992
93+ logger .info (f"{ len (available )} catalogs available in format '{ format .value } '." )
94+ return available
95+
8096 def load_catalogs_from_config (
8197 self , file : Union [str , Path , None ] = None
8298 ) -> Dict [str , CatalogEntry ]:
99+ """Load catalogs from configuration file.
100+
101+ Args:
102+ file (Union[str, Path, None], optional): Path to the configuration file. Defaults to None.
103+
104+ Raises:
105+ CatalogConfigFileNotFound: Raised when the catalog config file is not founds.
106+ InvalidCatalogYAMLError: Raised when the yaml file is invalid.
107+ InvalidCatalogSchemaError: Raised when there is a schema error in the provided config file.
108+
109+ Returns:
110+ Dict[str, CatalogEntry]: The registered catalogs.
111+ """
112+ logger .info ("Loading catalogs from configuration file." )
83113 if file is None :
84114 base_dir = Path (__file__ ).parent
85115 file = base_dir / ".superstac.yml"
86116
87117 path = Path (file ).expanduser ().resolve ()
118+ logger .debug (f"Resolved config path: { path } " )
88119
89120 if not path .exists ():
121+ logger .error (f"Config file not found at path: { path } " )
90122 raise CatalogConfigFileNotFound (f"Config file not found at { path } " )
91123
92124 try :
93125 with open (path , "r" ) as f :
94126 data = yaml .safe_load (f ) or {}
127+ logger .info (f"Successfully loaded YAML config from: { path } " )
95128 except yaml .YAMLError as e :
129+ logger .exception ("YAML parsing failed." )
96130 raise InvalidCatalogYAMLError (f"YAML parsing failed: { e } " ) from e
97131 except Exception as e :
132+ logger .exception ("Unexpected error while reading config." )
98133 raise InvalidCatalogYAMLError (
99134 f"Unexpected error reading config: { e } "
100135 ) from e
101136
102137 catalogs = data .get ("catalogs" )
103138 if not isinstance (catalogs , dict ):
139+ logger .error (
140+ f"Missing or invalid 'catalogs' section in config file: { path } "
141+ )
104142 raise InvalidCatalogSchemaError (
105143 f"Missing or invalid 'catalogs' section in config file: { path } "
106144 )
107145
108- # Register each catalog
146+ logger . info ( f"Found { len ( catalogs ) } catalogs to register." )
109147 for name , spec in catalogs .items ():
110- self .register_catalog (
111- name = name ,
112- url = spec .get ("url" ),
113- is_private = spec .get ("is_private" , False ),
114- summary = spec .get ("summary" ),
115- auth = AuthInfo (** spec ["auth" ]) if "auth" in spec else None ,
116- )
117-
148+ try :
149+ self .register_catalog (
150+ name = name ,
151+ url = spec .get ("url" ),
152+ is_private = spec .get ("is_private" , False ),
153+ summary = spec .get ("summary" ),
154+ auth = AuthInfo (** spec ["auth" ]) if "auth" in spec else None ,
155+ )
156+ except Exception as e :
157+ logger .warning (f"Failed to register catalog '{ name } ': { e } " )
158+ logger .info ("All catalogs loaded and registered." )
118159 return self .catalogs
119160
120161
0 commit comments