Skip to content
Open
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
35 changes: 35 additions & 0 deletions astrbot/core/db/po.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,41 @@ class CommandConflict(SQLModel, table=True):
)


class ApiKey(SQLModel, table=True):
"""API Key table for external API access."""

__tablename__ = "api_keys" # type: ignore

id: int | None = Field(
default=None, primary_key=True, sa_column_kwargs={"autoincrement": True}
)
key_id: str = Field(
max_length=36,
nullable=False,
unique=True,
default_factory=lambda: str(uuid.uuid4()),
index=True,
)
api_key: str = Field(nullable=False, max_length=255, index=True)
"""The actual API key (hashed)"""
username: str = Field(nullable=False, max_length=255)
"""WebUI username who created this API key"""
name: str | None = Field(default=None, max_length=255)
"""Optional name/description for the API key"""
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
expires_at: datetime | None = Field(default=None)
"""Expiration time (not implemented yet)"""
last_used_at: datetime | None = Field(default=None)
"""Last time this API key was used"""

__table_args__ = (
UniqueConstraint(
"key_id",
name="uix_api_key_id",
),
)


@dataclass
class Conversation:
"""LLM 对话类
Expand Down
21 changes: 21 additions & 0 deletions astrbot/dashboard/entities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from pydantic.dataclasses import dataclass


@dataclass
class Response:
status: str | None = None
message: str | None = None
data: dict | list | None = None

def error(self, message: str):
self.status = "error"
self.message = message
return self

def ok(self, data: dict | list | None = None, message: str | None = None):
self.status = "ok"
if data is None:
data = {}
self.data = data
self.message = message
return self
2 changes: 2 additions & 0 deletions astrbot/dashboard/routes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .api_key import ApiKeyRoute
from .auth import AuthRoute
from .chat import ChatRoute
from .command import CommandRoute
Expand All @@ -16,6 +17,7 @@
from .update import UpdateRoute

__all__ = [
"ApiKeyRoute",
"AuthRoute",
"ChatRoute",
"CommandRoute",
Expand Down
24 changes: 24 additions & 0 deletions astrbot/dashboard/routes/api_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
from astrbot.core.db import BaseDatabase

from ..services.api_key import ApiKeyService
from .route import Route, RouteContext


class ApiKeyRoute(Route):
def __init__(
self,
context: RouteContext,
core_lifecycle: AstrBotCoreLifecycle,
db: BaseDatabase,
):
super().__init__(context)
self.api_key_service = ApiKeyService(core_lifecycle, db)
self.routes = {
"/api-key": [
("POST", self.api_key_service.create_api_key),
("GET", self.api_key_service.list_api_keys),
],
"/api-key/<key_id>": [("DELETE", self.api_key_service.delete_api_key)],
}
self.register_routes()
Loading