1414
1515import croud .api
1616import yaml
17+ from boltons .typeutils import classproperty
1718from croud .config .configuration import Configuration
1819
1920import cratedb_toolkit
@@ -151,24 +152,6 @@ def invoke_capturing(self, fun: t.Callable, *args: t.List[t.Any], **kwargs: t.Di
151152 buffer .seek (0 )
152153 return buffer .read ()
153154
154- @property
155- def headless_config (self ) -> Configuration :
156- cfg = Configuration ("croud.yaml" )
157- if cfg ._file_path .exists () and "CRATEDB_CLOUD_API_KEY" not in os .environ :
158- return cfg
159-
160- tmp_file = NamedTemporaryFile ()
161- tmp_path = Path (tmp_file .name )
162- config = Configuration ("headless.yaml" , tmp_path )
163-
164- # Get credentials from the environment.
165- config .profile ["key" ] = os .environ .get ("CRATEDB_CLOUD_API_KEY" )
166- config .profile ["secret" ] = os .environ .get ("CRATEDB_CLOUD_API_SECRET" )
167- config .profile ["organization-id" ] = os .environ .get ("CRATEDB_CLOUD_ORGANIZATION_ID" )
168- # config.profile["endpoint"] = os.environ.get("CRATEDB_CLOUD_ENDPOINT") # noqa: ERA001
169-
170- return config
171-
172155 def run_croud_fun (self , fun : t .Callable , with_exceptions : bool = True ):
173156 """
174157 Wrapper function to call into `croud`, for catching and converging error messages.
@@ -200,14 +183,13 @@ def print_fun(levelname: str, *args, **kwargs):
200183 # https://stackoverflow.com/a/46481946
201184 levels = ["debug" , "info" , "warning" , "error" , "success" ]
202185 with contextlib .ExitStack () as stack :
203- # Patch all `print_*` functions.
186+ # Patch all `print_*` functions, as they would obstruct the output .
204187 for level in levels :
205188 p = patch (f"croud.printer.print_{ level } " , functools .partial (print_fun , level ))
206189 stack .enter_context (p )
207190
208191 # Patch configuration.
209- p = patch ("croud.config._CONFIG" , self .headless_config )
210- stack .enter_context (p )
192+ stack .enter_context (headless_config ())
211193
212194 # TODO: When aiming to disable wait-for-completion.
213195 """
@@ -219,6 +201,15 @@ def print_fun(levelname: str, *args, **kwargs):
219201 return fun ()
220202
221203
204+ @contextlib .contextmanager
205+ def headless_config ():
206+ """
207+ Patch the `croud.config` module to use a headless configuration.
208+ """
209+ with patch ("croud.config._CONFIG" , CroudClient .get_headless_config ):
210+ yield
211+
212+
222213class CroudClient (croud .api .Client ):
223214 """
224215 A slightly modified `croud.api.Client` class, to inject a custom User-Agent header.
@@ -229,6 +220,42 @@ def __init__(self, *args, **kwargs):
229220 ua = f"{ cratedb_toolkit .__appname__ } /{ cratedb_toolkit .__version__ } Python/{ python_version ()} "
230221 self .session .headers ["User-Agent" ] = ua
231222
223+ @staticmethod
224+ def create () -> "croud.api.Client" :
225+ """
226+ Canonical factory method for creating a `croud.api.Client` instance.
227+ """
228+ with headless_config ():
229+ from croud .config import CONFIG
230+
231+ return croud .api .Client (
232+ CONFIG .endpoint ,
233+ token = CONFIG .token ,
234+ on_token = CONFIG .set_current_auth_token ,
235+ key = CONFIG .key ,
236+ secret = CONFIG .secret ,
237+ region = CONFIG .region ,
238+ sudo = False ,
239+ )
240+
241+ @classproperty
242+ def get_headless_config (cls ) -> Configuration :
243+ cfg = Configuration ("croud.yaml" )
244+ if cfg ._file_path .exists () and "CRATEDB_CLOUD_API_KEY" not in os .environ :
245+ return cfg
246+
247+ tmp_file = NamedTemporaryFile ()
248+ tmp_path = Path (tmp_file .name )
249+ config = Configuration ("headless.yaml" , tmp_path )
250+
251+ # Get credentials from the environment.
252+ config .profile ["key" ] = os .environ .get ("CRATEDB_CLOUD_API_KEY" )
253+ config .profile ["secret" ] = os .environ .get ("CRATEDB_CLOUD_API_SECRET" )
254+ config .profile ["organization-id" ] = os .environ .get ("CRATEDB_CLOUD_ORGANIZATION_ID" )
255+ # config.profile["endpoint"] = os.environ.get("CRATEDB_CLOUD_ENDPOINT") # noqa: ERA001
256+
257+ return config
258+
232259
233260croud .api .Client = CroudClient
234261
0 commit comments