From 0d379ec590d2adc2a5acd3f175be415214eec437 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Tue, 29 Jul 2025 14:32:07 +0530 Subject: [PATCH 1/2] created api to enqueue states and create states --- api-server/app/main.py | 5 +- .../controllers/register_satellite.py | 62 ------------- .../app/satellite/models/access_types.py | 5 -- .../models/register_satellite_request.py | 15 ---- .../models/register_satellite_response.py | 22 ----- .../models/satellite_database_model.py | 86 ------------------- api-server/app/satellite/routes.py | 27 ------ state-manager/app/controller/__init__.py | 0 state-manager/app/controller/create_states.py | 42 +++++++++ .../app/controller/enqueue_states.py | 53 ++++++++++++ state-manager/app/main.py | 15 +++- state-manager/app/models/__init__.py | 0 state-manager/app/models/create_models.py | 26 ++++++ state-manager/app/models/db/__init__.py | 0 state-manager/app/models/db/base.py | 15 ++++ state-manager/app/models/db/namespace.py | 8 ++ state-manager/app/models/db/state.py | 14 +++ state-manager/app/models/enqueue_request.py | 6 ++ state-manager/app/models/enqueue_response.py | 19 ++++ state-manager/app/models/state_status_enum.py | 14 +++ state-manager/app/routes.py | 55 ++++++++++++ state-manager/app/utils/check_secret.py | 2 +- 22 files changed, 266 insertions(+), 225 deletions(-) delete mode 100644 api-server/app/satellite/controllers/register_satellite.py delete mode 100644 api-server/app/satellite/models/access_types.py delete mode 100644 api-server/app/satellite/models/register_satellite_request.py delete mode 100644 api-server/app/satellite/models/register_satellite_response.py delete mode 100644 api-server/app/satellite/models/satellite_database_model.py delete mode 100644 api-server/app/satellite/routes.py create mode 100644 state-manager/app/controller/__init__.py create mode 100644 state-manager/app/controller/create_states.py create mode 100644 state-manager/app/controller/enqueue_states.py create mode 100644 state-manager/app/models/__init__.py create mode 100644 state-manager/app/models/create_models.py create mode 100644 state-manager/app/models/db/__init__.py create mode 100644 state-manager/app/models/db/base.py create mode 100644 state-manager/app/models/db/namespace.py create mode 100644 state-manager/app/models/db/state.py create mode 100644 state-manager/app/models/enqueue_request.py create mode 100644 state-manager/app/models/enqueue_response.py create mode 100644 state-manager/app/models/state_status_enum.py create mode 100644 state-manager/app/routes.py diff --git a/api-server/app/main.py b/api-server/app/main.py index 56a86f0c..08a909fa 100644 --- a/api-server/app/main.py +++ b/api-server/app/main.py @@ -21,13 +21,11 @@ # injecting databases from .user.models.user_database_model import User from .project.models.project_database_model import Project -from .satellite.models.satellite_database_model import Satellite # injecting routers from .user.routes import router as user_router from .auth.routes import router as auth_router from .project.routes import router as project_router -from .satellite.routes import router as satellite_router load_dotenv() @@ -46,7 +44,7 @@ async def lifespan(app: FastAPI): # os.getenv can return None, which is not valid for dictionary-style access db_name = os.getenv("MONGO_DATABASE_NAME", "exosphere-api-server") db = client[db_name] - await init_beanie(db, document_models=[User, Project, Satellite]) + await init_beanie(db, document_models=[User, Project]) logger.info("beanie dbs initialized") # main logic of the server @@ -87,4 +85,3 @@ def health() -> dict: app.include_router(user_router) app.include_router(auth_router) app.include_router(project_router) -app.include_router(satellite_router) diff --git a/api-server/app/satellite/controllers/register_satellite.py b/api-server/app/satellite/controllers/register_satellite.py deleted file mode 100644 index 07aa3ae1..00000000 --- a/api-server/app/satellite/controllers/register_satellite.py +++ /dev/null @@ -1,62 +0,0 @@ -from beanie import Link -from bson import ObjectId -from pymongo.errors import DuplicateKeyError -from fastapi.responses import JSONResponse - -from ..models.register_satellite_request import RegisterSatelliteRequest -from ..models.register_satellite_response import RegisterSatelliteResponse -from ..models.satellite_database_model import Satellite - -from app.auth.models.token_claims import TokenClaims -from app.project.models.project_database_model import Project -from app.singletons.logs_manager import LogsManager - -logger = LogsManager().get_logger() - - -async def register_satellite(request: RegisterSatelliteRequest, project_id: str, claims: TokenClaims, x_exosphere_request_id: str) -> RegisterSatelliteResponse: - - try: - logger.info("Registering satellite", x_exosphere_request_id=x_exosphere_request_id, project_id=project_id, name=request.name) - - satellite = Satellite( - name=request.name, - friendly_name=request.friendly_name, - description=request.description, - access_type=request.access_type, - configs=request.configs, - inputs=request.inputs, - metrics=request.metrics, - outputs=request.outputs, - project=Link(ObjectId(project_id), Project), - project_name=project_id, - image_uri=request.image_uri, - timeout=request.timeout - ) - await satellite.insert() - logger.info("Satellite registered", x_exosphere_request_id=x_exosphere_request_id, project_id=project_id, name=request.name) - - return RegisterSatelliteResponse( - id=str(satellite.id), - name=satellite.name, - friendly_name=satellite.friendly_name, - description=satellite.description, - access_type=satellite.access_type, - configs=satellite.configs, - inputs=satellite.inputs, - metrics=satellite.metrics, - outputs=satellite.outputs, - project=project_id, - project_name=satellite.project_name, - image_uri=satellite.image_uri, - timeout=satellite.timeout, - created_at=satellite.created_at, - updated_at=satellite.updated_at - ) - except DuplicateKeyError as e: - logger.error("Error registering satellite", x_exosphere_request_id=x_exosphere_request_id, project_id=project_id, name=request.name, error=e) - return JSONResponse(status_code=400, content={"message": "Satellite already exists", "success": False}) - - except Exception as e: - logger.error("Error registering satellite", x_exosphere_request_id=x_exosphere_request_id, project_id=project_id, name=request.name, error=e) - raise e \ No newline at end of file diff --git a/api-server/app/satellite/models/access_types.py b/api-server/app/satellite/models/access_types.py deleted file mode 100644 index 93b6aca3..00000000 --- a/api-server/app/satellite/models/access_types.py +++ /dev/null @@ -1,5 +0,0 @@ -from enum import Enum - -class AccessTypeEnum(str, Enum): - PUBLIC = "PUBLIC" - PRIVATE = "PRIVATE" diff --git a/api-server/app/satellite/models/register_satellite_request.py b/api-server/app/satellite/models/register_satellite_request.py deleted file mode 100644 index 9618250f..00000000 --- a/api-server/app/satellite/models/register_satellite_request.py +++ /dev/null @@ -1,15 +0,0 @@ -from pydantic import BaseModel -from .access_types import AccessTypeEnum -from typing import Any, Optional - -class RegisterSatelliteRequest(BaseModel): - name: str - friendly_name: str - description: str - access_type: AccessTypeEnum - image_uri: Optional[str] = None - timeout: Optional[int] = None - configs: dict[str, Any] - inputs: dict[str, Any] - metrics: dict[str, Any] - outputs: dict[str, Any] \ No newline at end of file diff --git a/api-server/app/satellite/models/register_satellite_response.py b/api-server/app/satellite/models/register_satellite_response.py deleted file mode 100644 index c8d71ec7..00000000 --- a/api-server/app/satellite/models/register_satellite_response.py +++ /dev/null @@ -1,22 +0,0 @@ -from pydantic import BaseModel -from .access_types import AccessTypeEnum -from typing import Any, Optional -from datetime import datetime - - -class RegisterSatelliteResponse(BaseModel): - id: str - name: str - friendly_name: str - description: str - access_type: AccessTypeEnum - configs: dict[str, Any] - inputs: dict[str, Any] - metrics: dict[str, Any] - outputs: dict[str, Any] - project: str - project_name: str - created_at: datetime - updated_at: datetime - image_uri: Optional[str] = None - timeout: Optional[int] = None \ No newline at end of file diff --git a/api-server/app/satellite/models/satellite_database_model.py b/api-server/app/satellite/models/satellite_database_model.py deleted file mode 100644 index a889a119..00000000 --- a/api-server/app/satellite/models/satellite_database_model.py +++ /dev/null @@ -1,86 +0,0 @@ -import jsonschema - -from beanie import Document, before_event, Replace, Save, Link -from datetime import datetime -from pydantic import Field, field_validator -from .access_types import AccessTypeEnum -from docker_image import reference -from typing import Optional, Any -from pymongo import IndexModel, ASCENDING - -from app.project.models.project_database_model import Project - - -class Satellite(Document): - - name: str = Field(..., description="Name of the satellite") - - friendly_name: str = Field(..., description="Friendly name of the satellite") - - description: str = Field(..., description="Description of the satellite") - - access_type: AccessTypeEnum = Field(..., description="Access type of the satellite") - - configs: dict[str, Any] = Field(..., description="Configurations of the satellite, a valid jsonschema object for the configs") - - inputs: dict[str, Any] = Field(..., description="Input data fothe satellite, a valid jsonschema object for the inputs") - - metrics: dict[str, Any] = Field(..., description="Metrics of the satellite, a valid jsonschema object for the metrics") - - outputs: dict[str, Any] = Field(..., description="Outputs of the satellite, a valid jsonschema object for the outputs") - - project: Link[Project] = Field(..., description="Project of the satellite") - - project_name: str = Field(..., description="Name of the project of the satellite") - - created_at: datetime = Field(default_factory=datetime.now, description="Date and time when the satellite was created") - - updated_at: datetime = Field(default_factory=datetime.now, description="Date and time when the satellite was last updated") - - image_uri: Optional[str] = Field(None, description="OCI/Docker image URI for the satellite, if not provided autoscalling and dynamic scaling would not be available") - - timeout: Optional[int] = Field(None, description="Timeout of the satellite in seconds") - - @field_validator("configs", "inputs", "metrics", "outputs") - def validate_jsonschema(cls, v: dict[str, Any]) -> dict[str, Any]: - validator = jsonschema.validators.validator_for(v) - - try: - validator.check_schema(v) - except jsonschema.exceptions.SchemaError as e: - raise ValueError(f"Invalid JSON schema: {e.message}") - - return v - - @field_validator("image_uri") - def validate_image_uri(cls, v: str) -> str: - if not v: - return v - try: - reference.Reference.parse(v) - except Exception as e: - raise ValueError(f"Invalid image URI: {e.message}") - return v - - @field_validator("name") - def validate_name(cls, v: str) -> str: - - not_allowed_chars = ["/", ".", " "] - - if not v: - raise ValueError("Name cannot be empty") - if len(v) > 100: - raise ValueError("Name cannot be longer than 100 characters") - if any(char in not_allowed_chars for char in v): - raise ValueError("Name cannot contain the following characters: /, ., or whitespace") - return v - - class Settings: - name = "Satellites" - indexes = [ - IndexModel([("name", ASCENDING), ("project", ASCENDING)], unique=True) - ] - - @before_event([Save, Replace]) - def update_updated_at(self): - self.updated_at = datetime.now() \ No newline at end of file diff --git a/api-server/app/satellite/routes.py b/api-server/app/satellite/routes.py deleted file mode 100644 index 546590c9..00000000 --- a/api-server/app/satellite/routes.py +++ /dev/null @@ -1,27 +0,0 @@ -from fastapi import APIRouter, status, Request, Depends -from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials -from typing import Annotated -from fastapi.responses import JSONResponse - -from app.auth.services.get_token_claims import get_token_claims -from .controllers.register_satellite import register_satellite - -from .models.register_satellite_request import RegisterSatelliteRequest -from .models.register_satellite_response import RegisterSatelliteResponse - -router = APIRouter(prefix="/v0/project/{project_id}/satellite", tags=["satellite"]) - -@router.post( - "/", - response_model=RegisterSatelliteResponse, - status_code=status.HTTP_201_CREATED, - response_description="Satellite registered successfully" -) -async def register_satellite_route(project_id: str, body: RegisterSatelliteRequest, request: Request, token: Annotated[HTTPAuthorizationCredentials, Depends(HTTPBearer())]): - x_exosphere_request_id = getattr(request.state, "x_exosphere_request_id", None) - claims = await get_token_claims(token.credentials, x_exosphere_request_id) - - if claims is None or claims.project != project_id: - return JSONResponse(status_code=401, content={"message": "Invalid token", "success": False}) - - return await register_satellite(body, project_id, claims, x_exosphere_request_id) \ No newline at end of file diff --git a/state-manager/app/controller/__init__.py b/state-manager/app/controller/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/state-manager/app/controller/create_states.py b/state-manager/app/controller/create_states.py new file mode 100644 index 00000000..ad9177e1 --- /dev/null +++ b/state-manager/app/controller/create_states.py @@ -0,0 +1,42 @@ +from app.singletons.logs_manager import LogsManager +from app.models.create_models import CreateRequestModel, CreateResponseModel, ResponseStateModel +from app.models.state_status_enum import StateStatusEnum +from app.models.db.state import State + +from beanie.operators import In +from bson import ObjectId + +logger = LogsManager().get_logger() + +async def create_states(namespace_name: str, body: CreateRequestModel, x_exosphere_request_id: str) -> CreateResponseModel: + try: + states = [] + logger.info(f"Creating states for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id) + + for state in body.states: + states.append( + State( + node_name=state.node_name, + namespace_name=namespace_name, + status=StateStatusEnum.CREATED, + inputs=state.inputs, + outputs={} + ) + ) + + inserted_states = await State.insert_many(states) + + logger.info(f"Created states: {inserted_states.inserted_ids}", x_exosphere_request_id=x_exosphere_request_id) + + newStates = await State.find( + In(State.id, [ObjectId(id) for id in inserted_states.inserted_ids]) + ).to_list() + + return CreateResponseModel( + status=StateStatusEnum.CREATED, + states=[ResponseStateModel(state_id=str(state.id), node_name=state.node_name, inputs=state.inputs, created_at=state.created_at) for state in newStates] + ) + + except Exception as e: + logger.error(f"Error creating states for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id) + raise e \ No newline at end of file diff --git a/state-manager/app/controller/enqueue_states.py b/state-manager/app/controller/enqueue_states.py new file mode 100644 index 00000000..e028d44a --- /dev/null +++ b/state-manager/app/controller/enqueue_states.py @@ -0,0 +1,53 @@ +from beanie.operators import In + +from ..models.enqueue_request import EnqueueRequestModel +from ..models.enqueue_response import EnqueueResponseModel, StateModel +from ..models.db.state import State +from ..models.state_status_enum import StateStatusEnum + +from app.singletons.logs_manager import LogsManager + +logger = LogsManager().get_logger() + + +async def enqueue_states(namespace_name: str, body: EnqueueRequestModel, x_exosphere_request_id: str) -> EnqueueResponseModel: + + try: + logger.info(f"Enqueuing states for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id) + + states = await State.find( + State.namespace_name == namespace_name, + State.status == StateStatusEnum.CREATED, + In(State.node_name, body.nodes) + ).limit( + body.batch_size + ).to_list() + + if states: + await State.find( + In(State.id, [state.id for state in states]) + ).set( + { + "status": StateStatusEnum.QUEUED, + } + ) # type: ignore + + response = EnqueueResponseModel( + count=len(states), + namespace=namespace_name, + status=StateStatusEnum.QUEUED, + states=[ + StateModel( + state_id=str(state.id), + node_name=state.node_name, + inputs=state.inputs, + created_at=state.created_at + ) + for state in states + ] + ) + return response + + except Exception as e: + logger.error(f"Error enqueuing states for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id, error=e) + raise e \ No newline at end of file diff --git a/state-manager/app/main.py b/state-manager/app/main.py index 2e250ced..1fa99ddf 100644 --- a/state-manager/app/main.py +++ b/state-manager/app/main.py @@ -16,6 +16,13 @@ UnhandledExceptionsMiddleware, ) from .middlewares.request_id_middleware import RequestIdMiddleware + +# injecting models +from .models.db.state import State +from .models.db.namespace import Namespace + +# injecting routes +from .routes import router load_dotenv() @@ -27,8 +34,8 @@ async def lifespan(app: FastAPI): # initializing beanie client = AsyncMongoClient(os.getenv("MONGO_URI")) - db = client[os.getenv("MONGO_DATABASE_NAME")] - await init_beanie(db, document_models=[]) + db = client[os.getenv("MONGO_DATABASE_NAME", "exosphere-state-manager")] + await init_beanie(db, document_models=[State, Namespace]) logger.info("beanie dbs initialized") # initialize secret @@ -66,4 +73,6 @@ async def lifespan(app: FastAPI): @app.get("/health") def health() -> dict: - return {"message": "OK"} \ No newline at end of file + return {"message": "OK"} + +app.include_router(router) \ No newline at end of file diff --git a/state-manager/app/models/__init__.py b/state-manager/app/models/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/state-manager/app/models/create_models.py b/state-manager/app/models/create_models.py new file mode 100644 index 00000000..08390138 --- /dev/null +++ b/state-manager/app/models/create_models.py @@ -0,0 +1,26 @@ +from pydantic import BaseModel, Field +from typing import Any +from .state_status_enum import StateStatusEnum +from typing import Any +from datetime import datetime + + +class RequestStateModel(BaseModel): + node_name: str = Field(..., description="Name of the node of the state") + inputs: dict[str, Any] = Field(..., description="Inputs of the state") + + +class ResponseStateModel(BaseModel): + state_id: str = Field(..., description="ID of the state") + node_name: str = Field(..., description="Name of the node of the state") + inputs: dict[str, Any] = Field(..., description="Inputs of the state") + created_at: datetime = Field(..., description="Date and time when the state was created") + + +class CreateRequestModel(BaseModel): + states: list[RequestStateModel] = Field(..., description="List of states") + + +class CreateResponseModel(BaseModel): + status: StateStatusEnum = Field(..., description="Status of the state") + states: list[ResponseStateModel] = Field(..., description="List of states") \ No newline at end of file diff --git a/state-manager/app/models/db/__init__.py b/state-manager/app/models/db/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/state-manager/app/models/db/base.py b/state-manager/app/models/db/base.py new file mode 100644 index 00000000..e29fa7a5 --- /dev/null +++ b/state-manager/app/models/db/base.py @@ -0,0 +1,15 @@ +from abc import ABC +from beanie import Document, before_event, Replace, Save +from datetime import datetime +from pydantic import Field + + +class BaseDatabaseModel(ABC, Document): + + created_at: datetime = Field(default_factory=datetime.now, description="Date and time when the model was created") + + updated_at: datetime = Field(default_factory=datetime.now, description="Date and time when the model was last updated") + + @before_event([Save, Replace]) + def update_updated_at(self): + self.updated_at = datetime.now() \ No newline at end of file diff --git a/state-manager/app/models/db/namespace.py b/state-manager/app/models/db/namespace.py new file mode 100644 index 00000000..1e5d9416 --- /dev/null +++ b/state-manager/app/models/db/namespace.py @@ -0,0 +1,8 @@ +from .base import BaseDatabaseModel +from pydantic import Field +from beanie import Indexed + + +class Namespace(BaseDatabaseModel): + + name: Indexed(str, unique=True) = Field(..., description="Name of the namespace") \ No newline at end of file diff --git a/state-manager/app/models/db/state.py b/state-manager/app/models/db/state.py new file mode 100644 index 00000000..d573ddfc --- /dev/null +++ b/state-manager/app/models/db/state.py @@ -0,0 +1,14 @@ +from .base import BaseDatabaseModel +from ..state_status_enum import StateStatusEnum +from pydantic import Field +from pymongo import IndexModel, ASCENDING +from typing import Any + + +class State(BaseDatabaseModel): + + node_name: str = Field(..., description="Name of the node of the state") + namespace_name: str = Field(..., description="Name of the namespace of the state") + status: StateStatusEnum = Field(..., description="Status of the state") + inputs: dict[str, Any] = Field(..., description="Inputs of the state") + outputs: dict[str, Any] = Field(..., description="Outputs of the state") \ No newline at end of file diff --git a/state-manager/app/models/enqueue_request.py b/state-manager/app/models/enqueue_request.py new file mode 100644 index 00000000..cee96bc3 --- /dev/null +++ b/state-manager/app/models/enqueue_request.py @@ -0,0 +1,6 @@ +from pydantic import BaseModel, Field + + +class EnqueueRequestModel(BaseModel): + nodes: list[str] = Field(..., description="Names of the nodes of the states") + batch_size: int = Field(..., description="Batch size of the states") \ No newline at end of file diff --git a/state-manager/app/models/enqueue_response.py b/state-manager/app/models/enqueue_response.py new file mode 100644 index 00000000..62fbe814 --- /dev/null +++ b/state-manager/app/models/enqueue_response.py @@ -0,0 +1,19 @@ +from pydantic import BaseModel, Field +from .state_status_enum import StateStatusEnum +from typing import Any +from datetime import datetime + + +class StateModel(BaseModel): + state_id: str = Field(..., description="ID of the state") + node_name: str = Field(..., description="Name of the node of the state") + inputs: dict[str, Any] = Field(..., description="Inputs of the state") + created_at: datetime = Field(..., description="Date and time when the state was created") + + +class EnqueueResponseModel(BaseModel): + + count: int = Field(..., description="Count of states") + namespace: str = Field(..., description="ID of the namespace") + status: str = Field(..., description="Status of the state") + states: list[StateModel] = Field(..., description="List of states") diff --git a/state-manager/app/models/state_status_enum.py b/state-manager/app/models/state_status_enum.py new file mode 100644 index 00000000..a536b880 --- /dev/null +++ b/state-manager/app/models/state_status_enum.py @@ -0,0 +1,14 @@ +from enum import Enum + + +class StateStatusEnum(str, Enum): + + CREATED = 'CREATED' + QUEUED = 'QUEUED' + EXECUTED = 'EXECUTED' + NEXT_CREATED = 'NEXT_CREATED' + RETRY_CREATED = 'RETRY_CREATED' + TIMEDOUT = 'TIMEDOUT' + ERRORED = 'ERRORED' + CANCELLED = 'CANCELLED' + SUCCESS = 'SUCCESS' \ No newline at end of file diff --git a/state-manager/app/routes.py b/state-manager/app/routes.py new file mode 100644 index 00000000..0a0f242f --- /dev/null +++ b/state-manager/app/routes.py @@ -0,0 +1,55 @@ +from fastapi import APIRouter, status, Request, Depends, HTTPException +from uuid import uuid4 + +from app.utils.check_secret import check_api_key +from app.singletons.logs_manager import LogsManager + +from .models.enqueue_response import EnqueueResponseModel +from .models.enqueue_request import EnqueueRequestModel +from .controller.enqueue_states import enqueue_states + +from .models.create_models import CreateRequestModel, CreateResponseModel +from .controller.create_states import create_states + + +logger = LogsManager().get_logger() + +router = APIRouter(prefix="/v0/namespace/{namespace_name}/states", tags=["state"]) + + +@router.post( + "/enqueue", + response_model=EnqueueResponseModel, + status_code=status.HTTP_200_OK, + response_description="State enqueued on node queue successfully" +) +async def enqueue_state(namespace_name: str, body: EnqueueRequestModel, request: Request, api_key: str = Depends(check_api_key)): + + x_exosphere_request_id = getattr(request.state, "x_exosphere_request_id", str(uuid4())) + + if api_key: + logger.info(f"API key is valid for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id) + else: + logger.error(f"API key is invalid for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id) + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid API key") + + return await enqueue_states(namespace_name, body, x_exosphere_request_id) + + +@router.post( + "/create", + response_model=CreateResponseModel, + status_code=status.HTTP_200_OK, + response_description="States created successfully" +) +async def create_state(namespace_name: str, body: CreateRequestModel, request: Request, api_key: str = Depends(check_api_key)): + + x_exosphere_request_id = getattr(request.state, "x_exosphere_request_id", str(uuid4())) + + if api_key: + logger.info(f"API key is valid for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id) + else: + logger.error(f"API key is invalid for namespace {namespace_name}", x_exosphere_request_id=x_exosphere_request_id) + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid API key") + + return await create_states(namespace_name, body, x_exosphere_request_id) \ No newline at end of file diff --git a/state-manager/app/utils/check_secret.py b/state-manager/app/utils/check_secret.py index 42a0e04b..86649b42 100644 --- a/state-manager/app/utils/check_secret.py +++ b/state-manager/app/utils/check_secret.py @@ -12,7 +12,7 @@ api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False) -async def get_api_key(api_key_header: str = Depends(api_key_header)): +async def check_api_key(api_key_header: str = Depends(api_key_header)): if api_key_header == API_KEY: return api_key_header else: From dc05be2786e342fb9e7dac0b9eae3d954d94e86d Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Tue, 29 Jul 2025 14:43:44 +0530 Subject: [PATCH 2/2] ruff fixes --- state-manager/app/models/create_models.py | 1 - state-manager/app/models/db/state.py | 1 - state-manager/app/models/enqueue_response.py | 1 - 3 files changed, 3 deletions(-) diff --git a/state-manager/app/models/create_models.py b/state-manager/app/models/create_models.py index 08390138..3bc1c018 100644 --- a/state-manager/app/models/create_models.py +++ b/state-manager/app/models/create_models.py @@ -1,7 +1,6 @@ from pydantic import BaseModel, Field from typing import Any from .state_status_enum import StateStatusEnum -from typing import Any from datetime import datetime diff --git a/state-manager/app/models/db/state.py b/state-manager/app/models/db/state.py index d573ddfc..40a4773b 100644 --- a/state-manager/app/models/db/state.py +++ b/state-manager/app/models/db/state.py @@ -1,7 +1,6 @@ from .base import BaseDatabaseModel from ..state_status_enum import StateStatusEnum from pydantic import Field -from pymongo import IndexModel, ASCENDING from typing import Any diff --git a/state-manager/app/models/enqueue_response.py b/state-manager/app/models/enqueue_response.py index 62fbe814..65b46aaa 100644 --- a/state-manager/app/models/enqueue_response.py +++ b/state-manager/app/models/enqueue_response.py @@ -1,5 +1,4 @@ from pydantic import BaseModel, Field -from .state_status_enum import StateStatusEnum from typing import Any from datetime import datetime