Skip to content

CLI can be called in offline mode without and API endpoint #782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 48 additions & 16 deletions codecarbon/cli/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import signal
import sys
import time
from pathlib import Path
Expand All @@ -23,7 +24,7 @@
)
from codecarbon.core.api_client import ApiClient, get_datetime_with_timezone
from codecarbon.core.schemas import ExperimentCreate, OrganizationCreate, ProjectCreate
from codecarbon.emissions_tracker import EmissionsTracker
from codecarbon.emissions_tracker import EmissionsTracker, OfflineEmissionsTracker

AUTH_CLIENT_ID = os.environ.get(
"AUTH_CLIENT_ID",
Expand Down Expand Up @@ -336,28 +337,55 @@ def monitor(
api: Annotated[
bool, typer.Option(help="Choose to call Code Carbon API or not")
] = True,
offline: Annotated[bool, typer.Option(help="Run in offline mode")] = False,
country_iso_code: Annotated[
str, typer.Option(help="3-letter country ISO code for offline mode")
] = None,
region: Annotated[
str, typer.Option(help="Region/province for offline mode")
] = None,
):
"""Monitor your machine's carbon emissions.
"""Monitor your machine's carbon emissions."""
if offline:
if not country_iso_code:
print(
"ERROR: country_iso_code is required for offline mode", file=sys.stderr
)
raise typer.Exit(1)

Args:
measure_power_secs (Annotated[int, typer.Argument, optional): Interval between two measures. Defaults to 10.
api_call_interval (Annotated[int, typer.Argument, optional): Number of measures before calling API. Defaults to 30.
api (Annotated[bool, typer.Option, optional): Choose to call Code Carbon API or not. Defaults to True.
"""
experiment_id = get_existing_local_exp_id()
if api:
if experiment_id is None:
tracker = OfflineEmissionsTracker(
measure_power_secs=measure_power_secs,
country_iso_code=country_iso_code,
region=region,
)
else:
experiment_id = get_existing_local_exp_id()
if api and experiment_id is None:
print(
"ERROR: No experiment id, call 'codecarbon config' first.",
file=sys.stderr,
)
raise typer.Exit(1)

tracker = EmissionsTracker(
measure_power_secs=measure_power_secs,
api_call_interval=api_call_interval,
save_to_api=api,
)

def signal_handler(signum, frame):
print("\nReceived signal to stop. Saving emissions data...")
tracker.stop()
sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

print("CodeCarbon is going in an infinite loop to monitor this machine.")
with EmissionsTracker(
measure_power_secs=measure_power_secs,
api_call_interval=api_call_interval,
save_to_api=api,
) as tracker:
# Infinite loop
print("Press Ctrl+C to stop and save emissions data.")

tracker.start()
try:
while True:
if (
hasattr(tracker, "_another_instance_already_running")
Expand All @@ -366,6 +394,10 @@ def monitor(
print("Another instance of CodeCarbon is already running. Exiting.")
break
time.sleep(300)
except Exception as e:
print(f"\nError occurred: {e}")
tracker.stop()
raise e


def questionary_prompt(prompt, list_options, default):
Expand Down
17 changes: 11 additions & 6 deletions docs/edit/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ Command line
~~~~~~~~~~~~


Create a minimal configuration file (just follow the prompts) :
Create a minimal configuration file (just follow the prompts) :

.. code-block:: console

codecarbon config
codecarbon config

.. image:: https://asciinema.org/a/667970.svg
:align: center
:alt: Init config
:target: https://asciinema.org/a/667970

You can use the same command to modify an existing config :

.. image:: https://asciinema.org/a/667971.svg
Expand All @@ -38,12 +38,12 @@ If you want to track the emissions of a computer without having to modify your c

.. code-block:: console

codecarbon monitor
codecarbon monitor

You have to stop the monitoring manually with ``Ctrl+C``.

In the following example you will see how to use the CLI to monitor all the emissions of you computer and sending everything
to an API running on "localhost:8008" (Or you can start a private local API with "docker-compose up"). Using the public API with
In the following example you will see how to use the CLI to monitor all the emissions of you computer and sending everything
to an API running on "localhost:8008" (Or you can start a private local API with "docker-compose up"). Using the public API with
this is not supported yet (coming soon!)

.. image:: https://asciinema.org/a/667984.svg
Expand All @@ -52,6 +52,11 @@ this is not supported yet (coming soon!)
:target: https://asciinema.org/a/667984


The command line could also works without internet by providing the country code like this:

.. code-block:: console

codecarbon monitor --offline --country-iso-code FRA

Implementing CodeCarbon in your code allows you to track the emissions of a specific block of code.

Expand Down
Loading