33from types import SimpleNamespace
44
55import pytest
6+ import typer
67from typer .testing import CliRunner
78
89from codecarbon .cli import main as cli_main
@@ -34,8 +35,8 @@ def test_version_flag():
3435
3536def test_api_get_calls_api_and_prints (monkeypatch ):
3637 runner = CliRunner ()
37- monkeypatch .setattr (cli_main , " ApiClient" , FakeApiClient )
38- monkeypatch .setattr (cli_main , " get_access_token" , fake_get_access_token )
38+ monkeypatch .setattr ("codecarbon.core.api_client. ApiClient" , FakeApiClient )
39+ monkeypatch .setattr ("codecarbon.cli.auth. get_access_token" , fake_get_access_token )
3940
4041 result = runner .invoke (cli_main .codecarbon , ["test-api" ])
4142 assert result .exit_code == 0
@@ -51,11 +52,11 @@ def __init__(self, endpoint_url=None):
5152 super ().__init__ (endpoint_url = endpoint_url )
5253
5354 runner = CliRunner ()
54- monkeypatch .setattr (cli_main , " ApiClient" , CustomApiClient )
55+ monkeypatch .setattr ("codecarbon.core.api_client. ApiClient" , CustomApiClient )
5556 monkeypatch .setattr (
5657 cli_main , "get_api_endpoint" , lambda : "https://custom.codecarbon.io"
5758 )
58- monkeypatch .setattr (cli_main , " get_access_token" , fake_get_access_token )
59+ monkeypatch .setattr ("codecarbon.cli.auth. get_access_token" , fake_get_access_token )
5960
6061 result = runner .invoke (cli_main .codecarbon , ["test-api" ])
6162 assert result .exit_code == 0
@@ -85,7 +86,7 @@ def get_detected_hardware(self):
8586 "gpu_ids" : None ,
8687 }
8788
88- monkeypatch .setattr (cli_main , " EmissionsTracker" , FakeTracker )
89+ monkeypatch .setattr ("codecarbon.emissions_tracker. EmissionsTracker" , FakeTracker )
8990 runner = CliRunner ()
9091 result = runner .invoke (cli_main .codecarbon , ["detect" ])
9192 assert result .exit_code == 0
@@ -115,7 +116,7 @@ def set_access_token(self, token):
115116 def fake_get_access_token ():
116117 raise ValueError ("Not able to retrieve the access token, please run login." )
117118
118- monkeypatch .setattr (cli_main , " ApiClient" , FakeApiClient )
119+ monkeypatch .setattr ("codecarbon.core.api_client. ApiClient" , FakeApiClient )
119120 monkeypatch .setattr (
120121 cli_main ,
121122 "get_config" ,
@@ -129,7 +130,7 @@ def fake_get_access_token():
129130 monkeypatch .setattr (
130131 cli_main , "get_api_endpoint" , lambda path : "https://api.codecarbon.io"
131132 )
132- monkeypatch .setattr (cli_main , " get_access_token" , fake_get_access_token )
133+ monkeypatch .setattr ("codecarbon.cli.auth. get_access_token" , fake_get_access_token )
133134
134135 cli_main .show_config (tmp_path / ".codecarbon.config" )
135136 captured = capsys .readouterr ()
@@ -165,16 +166,15 @@ def set_access_token(self, token):
165166 def check_auth (self ):
166167 calls ["check_auth" ] += 1
167168
168- monkeypatch .setattr (cli_main , " ApiClient" , FakeApiClient )
169+ monkeypatch .setattr ("codecarbon.core.api_client. ApiClient" , FakeApiClient )
169170 monkeypatch .setattr (
170- cli_main ,
171- "authorize" ,
171+ "codecarbon.cli.auth.authorize" ,
172172 lambda : calls .__setitem__ ("authorize" , calls ["authorize" ] + 1 ),
173173 )
174174 monkeypatch .setattr (
175175 cli_main , "get_api_endpoint" , lambda : "https://custom-login.codecarbon.io"
176176 )
177- monkeypatch .setattr (cli_main , " get_access_token" , lambda : "login-token" )
177+ monkeypatch .setattr ("codecarbon.cli.auth. get_access_token" , lambda : "login-token" )
178178
179179 runner = CliRunner ()
180180 result = runner .invoke (cli_main .codecarbon , ["login" ])
@@ -198,8 +198,8 @@ def fake_post(url, json, headers):
198198 captured ["headers" ] = headers
199199 return FakeResponse ()
200200
201- monkeypatch .setattr (cli_main , " get_access_token" , lambda : "access-token" )
202- monkeypatch .setattr (cli_main . requests , " post" , fake_post )
201+ monkeypatch .setattr ("codecarbon.cli.auth. get_access_token" , lambda : "access-token" )
202+ monkeypatch .setattr ("requests. post" , fake_post )
203203
204204 token = cli_main .get_api_key ("proj-123" )
205205 assert token == "project-api-token"
@@ -235,8 +235,8 @@ def get_project(self, project_id):
235235 def get_experiment (self , experiment_id ):
236236 return {"id" : experiment_id }
237237
238- monkeypatch .setattr (cli_main , " ApiClient" , FakeApiClient )
239- monkeypatch .setattr (cli_main , " get_access_token" , lambda : "fake-token" )
238+ monkeypatch .setattr ("codecarbon.core.api_client. ApiClient" , FakeApiClient )
239+ monkeypatch .setattr ("codecarbon.cli.auth. get_access_token" , lambda : "fake-token" )
240240 monkeypatch .setattr (
241241 cli_main , "get_api_endpoint" , lambda path : "https://api.codecarbon.io"
242242 )
@@ -289,7 +289,9 @@ def start(self):
289289 def stop (self ):
290290 return None
291291
292- monkeypatch .setattr (cli_main , "OfflineEmissionsTracker" , FakeOfflineTracker )
292+ monkeypatch .setattr (
293+ "codecarbon.emissions_tracker.OfflineEmissionsTracker" , FakeOfflineTracker
294+ )
293295 monkeypatch .setattr (cli_main .signal , "signal" , lambda * args , ** kwargs : None )
294296
295297 runner = CliRunner ()
@@ -311,7 +313,7 @@ def fake_run_and_monitor(ctx, offline=False, **kwargs):
311313 captured ["kwargs" ] = kwargs
312314 return "ok"
313315
314- monkeypatch .setattr (cli_main , " run_and_monitor" , fake_run_and_monitor )
316+ monkeypatch .setattr ("codecarbon.cli.monitor. run_and_monitor" , fake_run_and_monitor )
315317
316318 ctx = SimpleNamespace (args = ["python" , "-c" , "print(1)" ])
317319 result = cli_main .monitor (
@@ -332,7 +334,7 @@ def fake_run_and_monitor(ctx, offline=False, **kwargs):
332334 captured ["kwargs" ] = kwargs
333335 return "ok"
334336
335- monkeypatch .setattr (cli_main , " run_and_monitor" , fake_run_and_monitor )
337+ monkeypatch .setattr ("codecarbon.cli.monitor. run_and_monitor" , fake_run_and_monitor )
336338 monkeypatch .setattr (cli_main , "get_existing_exp_id" , lambda : "exp-1" )
337339
338340 ctx = SimpleNamespace (args = ["python" , "train.py" ])
@@ -350,7 +352,7 @@ def fake_run_and_monitor(ctx, **kwargs):
350352 captured ["kwargs" ] = kwargs
351353 return "ok"
352354
353- monkeypatch .setattr (cli_main , " run_and_monitor" , fake_run_and_monitor )
355+ monkeypatch .setattr ("codecarbon.cli.monitor. run_and_monitor" , fake_run_and_monitor )
354356 monkeypatch .setattr (cli_main , "get_existing_exp_id" , lambda : "exp-1" )
355357
356358 ctx = SimpleNamespace (args = ["python" , "train.py" ])
@@ -368,11 +370,39 @@ def fake_run_and_monitor(ctx, offline=False, **kwargs):
368370 captured ["kwargs" ] = kwargs
369371 return "ok"
370372
371- monkeypatch .setattr (cli_main , " run_and_monitor" , fake_run_and_monitor )
373+ monkeypatch .setattr ("codecarbon.cli.monitor. run_and_monitor" , fake_run_and_monitor )
372374 monkeypatch .setattr (cli_main , "get_existing_exp_id" , lambda : None )
373375
374376 ctx = SimpleNamespace (args = ["python" , "train.py" ])
375377 result = cli_main .monitor (ctx = ctx , api = False )
376378 assert result == "ok"
377379 assert captured ["offline" ] is False
378380 assert captured ["kwargs" ]["save_to_api" ] is False
381+
382+
383+ def test_monitor_passes_log_level_to_run_and_monitor (monkeypatch ):
384+ captured = {}
385+
386+ def fake_run_and_monitor (ctx , offline = False , ** kwargs ):
387+ captured ["kwargs" ] = kwargs
388+
389+ monkeypatch .setattr ("codecarbon.cli.monitor.run_and_monitor" , fake_run_and_monitor )
390+
391+ ctx = SimpleNamespace (args = ["echo" , "hello" ])
392+ cli_main .monitor (
393+ ctx = ctx ,
394+ offline = True ,
395+ country_iso_code = "FRA" ,
396+ log_level = "debug" ,
397+ )
398+
399+ assert captured ["kwargs" ]["log_level" ] == "debug"
400+
401+
402+ def test_monitor_online_requires_experiment_id_for_wrapped_command (monkeypatch ):
403+ monkeypatch .setattr (cli_main , "get_existing_exp_id" , lambda : None )
404+
405+ ctx = SimpleNamespace (args = ["echo" , "hi" ])
406+ with pytest .raises (typer .Exit ) as exc_info :
407+ cli_main .monitor (ctx = ctx , offline = False , api = True )
408+ assert exc_info .value .exit_code == 1
0 commit comments