|
|
from datetime import datetime, timezone |
|
|
from typing import TYPE_CHECKING |
|
|
from uuid import UUID, uuid4 |
|
|
|
|
|
from pydantic import field_validator |
|
|
from sqlmodel import Column, DateTime, Field, Relationship, SQLModel, func |
|
|
|
|
|
if TYPE_CHECKING: |
|
|
from langflow.services.database.models.user import User |
|
|
|
|
|
|
|
|
def utc_now(): |
|
|
return datetime.now(timezone.utc) |
|
|
|
|
|
|
|
|
class ApiKeyBase(SQLModel): |
|
|
name: str | None = Field(index=True, nullable=True, default=None) |
|
|
last_used_at: datetime | None = Field(default=None, nullable=True) |
|
|
total_uses: int = Field(default=0) |
|
|
is_active: bool = Field(default=True) |
|
|
|
|
|
|
|
|
class ApiKey(ApiKeyBase, table=True): |
|
|
id: UUID = Field(default_factory=uuid4, primary_key=True, unique=True) |
|
|
created_at: datetime | None = Field( |
|
|
default=None, sa_column=Column(DateTime(timezone=True), server_default=func.now(), nullable=False) |
|
|
) |
|
|
api_key: str = Field(index=True, unique=True) |
|
|
|
|
|
|
|
|
user_id: UUID = Field(index=True, foreign_key="user.id") |
|
|
user: "User" = Relationship( |
|
|
back_populates="api_keys", |
|
|
) |
|
|
|
|
|
|
|
|
class ApiKeyCreate(ApiKeyBase): |
|
|
api_key: str | None = None |
|
|
user_id: UUID | None = None |
|
|
created_at: datetime | None = Field(default_factory=utc_now) |
|
|
|
|
|
@field_validator("created_at", mode="before") |
|
|
@classmethod |
|
|
def set_created_at(cls, v): |
|
|
return v or utc_now() |
|
|
|
|
|
|
|
|
class UnmaskedApiKeyRead(ApiKeyBase): |
|
|
id: UUID |
|
|
api_key: str = Field() |
|
|
user_id: UUID = Field() |
|
|
|
|
|
|
|
|
class ApiKeyRead(ApiKeyBase): |
|
|
id: UUID |
|
|
api_key: str = Field(schema_extra={"validate_default": True}) |
|
|
user_id: UUID = Field() |
|
|
created_at: datetime = Field() |
|
|
|
|
|
@field_validator("api_key") |
|
|
@classmethod |
|
|
def mask_api_key(cls, v) -> str: |
|
|
|
|
|
return f"{v[:8]}{'*' * (len(v) - 8)}" |
|
|
|