Skip to content

Commit

Permalink
Fix/fix prod api (#748)
Browse files Browse the repository at this point in the history
* test: print bearer token

* fix: remove jwt test for add run endpoint

* fix: remove access token from emissions_tracker.py

* fix: various fixes

* fix(codecarbon) add back the bearer cli auth ; avoid 2 auths in //

* fix(codecarbon) fix show_config not using auth

* test(codecarbon) add missing mock

---------

Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
SaboniAmine and prmths128 authored Dec 18, 2024
1 parent b911e77 commit 54578d8
Show file tree
Hide file tree
Showing 15 changed files with 30 additions and 96 deletions.
28 changes: 0 additions & 28 deletions carbonserver/carbonserver/api/dependencies.py

This file was deleted.

5 changes: 1 addition & 4 deletions carbonserver/carbonserver/api/routers/emissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from fastapi_pagination.default import Params as BaseParams
from starlette import status

from carbonserver.api.dependencies import get_token_header
from carbonserver.api.schemas import AccessLevel, Emission, EmissionCreate
from carbonserver.api.services.emissions_service import EmissionService
from carbonserver.api.services.project_token_service import ProjectTokenService
Expand All @@ -29,9 +28,7 @@ class Page(BasePage[T], Generic[T]): # noqa: F811

EMISSIONS_ROUTER_TAGS = ["Emissions"]

router = APIRouter(
dependencies=[Depends(get_token_header)],
)
router = APIRouter()


@router.post(
Expand Down
5 changes: 1 addition & 4 deletions carbonserver/carbonserver/api/routers/organizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from pydantic import BaseModel, EmailStr
from starlette import status

from carbonserver.api.dependencies import get_token_header
from carbonserver.api.schemas import (
Organization,
OrganizationCreate,
Expand All @@ -27,9 +26,7 @@

ORGANIZATIONS_ROUTER_TAGS = ["Organizations"]

router = APIRouter(
dependencies=[Depends(get_token_header)],
)
router = APIRouter()


@router.post(
Expand Down
6 changes: 1 addition & 5 deletions carbonserver/carbonserver/api/routers/project_api_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@
from fastapi import APIRouter, Depends
from starlette import status

from carbonserver.api.dependencies import get_token_header
from carbonserver.api.schemas import ProjectToken, ProjectTokenCreate

PROJECTS_TOKENS_ROUTER_TAGS = ["Project tokens"]

router = APIRouter(
dependencies=[Depends(get_token_header)],
)
# TODO: Add authentication to the endpoints
router = APIRouter()


# Create project token
Expand Down
26 changes: 8 additions & 18 deletions carbonserver/carbonserver/api/routers/runs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@
from fastapi import APIRouter, Depends, Header
from starlette import status

from carbonserver.api.dependencies import get_token_header
from carbonserver.api.errors import EmptyResultException
from carbonserver.api.schemas import AccessLevel, Empty, Run, RunCreate, RunReport
from carbonserver.api.services.auth_service import (
OptionalUserWithAuthDependency,
UserWithAuthDependency,
)
from carbonserver.api.services.project_token_service import ProjectTokenService
from carbonserver.api.services.run_service import RunService
from carbonserver.api.usecases.run.experiment_sum_by_run import (
Expand All @@ -23,9 +18,7 @@

RUNS_ROUTER_TAGS = ["Runs"]

router = APIRouter(
dependencies=[Depends(get_token_header)],
)
router = APIRouter()
runs_temp_db = []


Expand All @@ -42,18 +35,15 @@ def add_run(
project_token_service: ProjectTokenService = Depends(
Provide[ServerContainer.project_token_service]
),
auth_user: UserWithAuthDependency = Depends(OptionalUserWithAuthDependency),
x_api_token: Optional[str] = Header(None),
) -> Run:
if x_api_token and x_api_token != "api_key": # ignore dummy value
# use project-specific token if available
project_token_service.project_token_has_access(
AccessLevel.WRITE.value,
experiment_id=run.experiment_id,
project_token=x_api_token,
)
return run_service.add_run(run)
return run_service.add_run(run, user=auth_user.db_user)

project_token_service.project_token_has_access(
AccessLevel.WRITE.value,
experiment_id=run.experiment_id,
project_token=x_api_token,
)
return run_service.add_run(run)


@router.get(
Expand Down
5 changes: 1 addition & 4 deletions carbonserver/carbonserver/api/routers/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@
from dependency_injector.wiring import Provide, inject
from fastapi import APIRouter, Depends, status

from carbonserver.api.dependencies import get_token_header
from carbonserver.api.schemas import User
from carbonserver.api.services.user_service import UserService

USERS_ROUTER_TAGS = ["Users"]

router = APIRouter(
dependencies=[Depends(get_token_header)],
)
router = APIRouter()


@router.get(
Expand Down
9 changes: 0 additions & 9 deletions carbonserver/carbonserver/api/services/run_service.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from typing import List
from uuid import UUID

from carbonserver.api.errors import NotAllowedError, NotAllowedErrorEnum, UserException
from carbonserver.api.infra.repositories.repository_runs import SqlAlchemyRepository
from carbonserver.api.schemas import Run, RunCreate, User
from carbonserver.api.services.auth_context import AuthContext
Expand All @@ -17,14 +16,6 @@ def __init__(
self._auth_context = auth_context

def add_run(self, run: RunCreate, user: User = None) -> Run:
if user:
if not self._auth_context.can_create_run(run.experiment_id, user):
raise UserException(
NotAllowedError(
code=NotAllowedErrorEnum.OPERATION_NOT_ALLOWED,
message="Operation not authorized on experiment",
)
)
created_run = self._repository.add_run(run)
return created_run

Expand Down
4 changes: 1 addition & 3 deletions carbonserver/main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from container import ServerContainer, settings
from fastapi import Depends, FastAPI
from fastapi import FastAPI
from fastapi_pagination import add_pagination
from pydantic import ValidationError
from starlette.middleware.cors import CORSMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse

from carbonserver.api.dependencies import get_query_token
from carbonserver.api.errors import DBException, UserException, get_http_exception
from carbonserver.api.infra.database import sql_models
from carbonserver.api.routers import (
Expand Down Expand Up @@ -82,7 +81,6 @@ def init_server(container):
servers=[
{"url": "/api/"},
],
dependencies=[Depends(get_query_token)],
)
server.container = container
server.include_router(users.router)
Expand Down
6 changes: 2 additions & 4 deletions codecarbon/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def show_config(path: Path = Path("./.codecarbon.config")) -> None:
d = get_config(path)
api_endpoint = get_api_endpoint(path)
api = ApiClient(endpoint_url=api_endpoint)
api.set_access_token(_get_access_token())
print("Current configuration : \n")
print("Config file content : ")
print(d)
Expand Down Expand Up @@ -317,17 +318,14 @@ def monitor(
api (Annotated[bool, typer.Option, optional): Choose to call Code Carbon API or not. Defaults to True.
"""
experiment_id = get_existing_local_exp_id()
token = None
if api:
if experiment_id is None:
print("ERROR: No experiment id, call 'codecarbon init' first.", err=True)
token = _get_access_token()
print("ERROR: No experiment id, call 'codecarbon config' first.", err=True)
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,
access_token=token,
) as tracker:
# Infinite loop
while True:
Expand Down
17 changes: 8 additions & 9 deletions codecarbon/core/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,23 @@ def __init__(
stacklevel=2,
)

def set_access_token(self, token: str):
"""This method sets the access token to be used for the API. For now it is not used.
Args:
token (str): access token to be used for the API
"""
self.access_token = token

def _get_headers(self):
headers = {"Content-Type": "application/json"}
if self.api_key:
print(type(self.api_key))
# set the x-api-token header
headers["x-api-token"] = self.api_key
if self.access_token:
elif self.access_token:
headers["Authorization"] = f"Bearer {self.access_token}"
return headers

def set_access_token(self, token: str):
"""This method sets the access token to be used for the API.
Args:
token (str): access token to be used for the API
"""
self.access_token = token

def get_list_organizations(self):
"""
List all organizations
Expand Down
6 changes: 2 additions & 4 deletions codecarbon/emissions_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ def __init__(
api_call_interval: Optional[int] = _sentinel,
api_endpoint: Optional[str] = _sentinel,
api_key: Optional[str] = _sentinel,
access_token: Optional[str] = _sentinel,
output_dir: Optional[str] = _sentinel,
output_file: Optional[str] = _sentinel,
save_to_file: Optional[bool] = _sentinel,
Expand Down Expand Up @@ -349,9 +348,9 @@ def __init__(
self._emissions: Emissions = Emissions(
self._data_source, self._co2_signal_api_token
)
self._init_output_methods(api_key=self._api_key, access_token=access_token)
self._init_output_methods(api_key=self._api_key)

def _init_output_methods(self, *, api_key: str = None, access_token: str = None):
def _init_output_methods(self, *, api_key: str = None):
"""
Prepare the different output methods
"""
Expand All @@ -375,7 +374,6 @@ def _init_output_methods(self, *, api_key: str = None, access_token: str = None)
endpoint_url=self._api_endpoint,
experiment_id=self._experiment_id,
api_key=api_key,
access_token=access_token,
conf=self._conf,
)
self.run_id = cc_api__out.run_id
Expand Down
2 changes: 0 additions & 2 deletions codecarbon/output_methods/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,12 @@ def __init__(
experiment_id: str,
api_key: str,
conf,
access_token: str = None,
):
self.endpoint_url: str = endpoint_url
self.api = ApiClient(
experiment_id=experiment_id,
endpoint_url=endpoint_url,
api_key=api_key,
access_token=access_token,
conf=conf,
)
self.run_id = self.api.run_id
Expand Down
1 change: 1 addition & 0 deletions examples/api_call_debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@track_emissions(
measure_power_secs=2,
api_call_interval=2,
api_key="",
save_to_api=True,
)
def train_model():
Expand Down
2 changes: 1 addition & 1 deletion examples/api_call_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@track_emissions(
# api_endpoint="http://your api if you want",
# experiment_id="3a202149-8be2-408c-a3d8-baeae2de2987",
# api_key=" not used yet",
api_key="",
save_to_api=True,
)
def train_model():
Expand Down
4 changes: 3 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ def side_effect_wrapper(*args, **kwargs):
result.stdout,
)

@patch("codecarbon.cli.main._get_access_token")
@patch("codecarbon.cli.main.Path.exists")
@patch("codecarbon.cli.main.get_config")
@patch("codecarbon.cli.main.questionary_prompt")
def test_init_use_local(
self, mock_prompt, mock_config, mock_path_exists, MockApiClient
self, mock_prompt, mock_config, mock_path_exists, mock_token, MockApiClient
):
mock_prompt.return_value = "~/.codecarbon.config"
mock_config.return_value = {
Expand All @@ -111,6 +112,7 @@ def test_init_use_local(
"project_id": "133",
"experiment_id": "yolo123",
}
mock_token.return_value = "mock_token"

def side_effect_wrapper(*args, **kwargs):
"""Side effect wrapper to simulate the first call to path.exists to avoid picking up global config"""
Expand Down

0 comments on commit 54578d8

Please sign in to comment.