This commit is contained in:
9qeklajc
2025-10-24 15:56:03 +02:00
parent f3e8718660
commit 05f3ce1a43
-431
View File
@@ -1513,437 +1513,6 @@ class ModelUpdate(BaseModel):
enabled: bool = True
class ModelIdentifier(BaseModel):
model_id: str
provider_id: int | None = None
class ModelGetRequest(BaseModel):
model_id: str
provider_id: int | None = None
class ModelDeleteRequest(BaseModel):
model_id: str
provider_id: int | None = None
class ModelUpdateRequest(BaseModel):
model_id: str
provider_id: int | None = None
name: str
description: str
created: int
context_length: int
architecture: dict[str, object]
pricing: dict[str, object]
per_request_limits: dict[str, object] | None = None
top_provider: dict[str, object] | None = None
enabled: bool = True
class ModelCreateRequest(BaseModel):
model_id: str
provider_id: int | None = None
name: str
description: str
created: int
context_length: int
architecture: dict[str, object]
pricing: dict[str, object]
per_request_limits: dict[str, object] | None = None
top_provider: dict[str, object] | None = None
enabled: bool = True
@admin_router.get("/api/models", dependencies=[Depends(require_admin_api)])
async def get_all_models() -> list[dict[str, object]]:
async with create_session() as session:
models = await list_models(session=session, include_disabled=True)
return [m.dict() for m in models]
@admin_router.get(
"/api/models/{model_id:path}", dependencies=[Depends(require_admin_api)]
)
async def get_model(model_id: str) -> dict[str, object]:
async with create_session() as session:
result = await session.exec(
select(ModelRow).where(
ModelRow.id == model_id, ModelRow.upstream_provider_id.is_(None)
)
)
row = result.first()
if not row:
raise HTTPException(status_code=404, detail="Model not found")
return _row_to_model(row, apply_provider_fee=False).dict()
@admin_router.post("/api/models", dependencies=[Depends(require_admin_api)])
async def create_model(payload: ModelCreate) -> dict[str, object]:
async with create_session() as session:
exists = await session.get(ModelRow, (payload.id, None))
if exists:
raise HTTPException(
status_code=409, detail="Model with this ID already exists"
)
row = ModelRow(
id=payload.id,
name=payload.name,
description=payload.description,
created=int(payload.created),
context_length=int(payload.context_length),
architecture=json.dumps(payload.architecture),
pricing=json.dumps(payload.pricing),
sats_pricing=None,
per_request_limits=(
json.dumps(payload.per_request_limits)
if payload.per_request_limits is not None
else None
),
top_provider=(
json.dumps(payload.top_provider) if payload.top_provider else None
),
upstream_provider_id=None,
enabled=payload.enabled,
)
session.add(row)
await session.commit()
await session.refresh(row)
await refresh_model_maps()
return _row_to_model(row, apply_provider_fee=False).dict()
@admin_router.patch(
"/api/models/{model_id:path}", dependencies=[Depends(require_admin_api)]
)
async def update_model(model_id: str, payload: ModelUpdate) -> dict[str, object]:
if payload.id != model_id:
raise HTTPException(status_code=400, detail="Path id does not match payload id")
async with create_session() as session:
row = await session.get(ModelRow, (model_id, None))
if not row:
raise HTTPException(status_code=404, detail="Model not found")
row.name = payload.name
row.description = payload.description
row.created = int(payload.created)
row.context_length = int(payload.context_length)
row.architecture = json.dumps(payload.architecture)
row.pricing = json.dumps(payload.pricing)
row.sats_pricing = None
row.per_request_limits = (
json.dumps(payload.per_request_limits)
if payload.per_request_limits is not None
else None
)
row.top_provider = (
json.dumps(payload.top_provider) if payload.top_provider else None
)
row.enabled = payload.enabled
session.add(row)
await session.commit()
await session.refresh(row)
await refresh_model_maps()
return _row_to_model(row, apply_provider_fee=False).dict()
@admin_router.put(
"/api/models/{model_id:path}", dependencies=[Depends(require_admin_api)]
)
async def update_model_put(model_id: str, payload: ModelUpdate) -> dict[str, object]:
return await update_model(model_id, payload)
@admin_router.delete(
"/api/models/{model_id:path}", dependencies=[Depends(require_admin_api)]
)
async def delete_model(model_id: str) -> dict[str, object]:
async with create_session() as session:
row = await session.get(ModelRow, (model_id, None))
if not row:
raise HTTPException(status_code=404, detail="Model not found")
await session.delete(row)
await session.commit()
await refresh_model_maps()
return {"ok": True, "deleted_id": model_id}
@admin_router.delete("/api/models", dependencies=[Depends(require_admin_api)])
async def delete_all_models() -> dict[str, object]:
async with create_session() as session:
result = await session.exec(
select(ModelRow).where(ModelRow.upstream_provider_id.is_(None))
)
rows = result.all()
for row in rows:
await session.delete(row)
await session.commit()
await refresh_model_maps()
return {"ok": True, "deleted": len(rows)}
class BatchModelsRequest(BaseModel):
models: list[ModelCreate]
@admin_router.post("/api/models/batch", dependencies=[Depends(require_admin_api)])
async def batch_add_models(payload: BatchModelsRequest) -> dict[str, object]:
async with create_session() as session:
created_models = []
for model_data in payload.models:
exists = await session.get(ModelRow, (model_data.id, None))
if exists:
continue
row = ModelRow(
id=model_data.id,
name=model_data.name,
description=model_data.description,
created=int(model_data.created),
context_length=int(model_data.context_length),
architecture=json.dumps(model_data.architecture),
pricing=json.dumps(model_data.pricing),
sats_pricing=None,
per_request_limits=(
json.dumps(model_data.per_request_limits)
if model_data.per_request_limits is not None
else None
),
top_provider=(
json.dumps(model_data.top_provider)
if model_data.top_provider
else None
),
upstream_provider_id=None,
enabled=model_data.enabled,
)
session.add(row)
created_models.append(model_data.id)
await session.commit()
await refresh_model_maps()
return {"ok": True, "created": len(created_models), "model_ids": created_models}
@admin_router.post("/api/models/get", dependencies=[Depends(require_admin_api)])
async def get_model_by_id(payload: ModelGetRequest) -> dict[str, object]:
print(payload)
from ..upstream import _instantiate_provider
async with create_session() as session:
if payload.provider_id is None:
result = await session.exec(
select(ModelRow).where(
ModelRow.id == payload.model_id,
ModelRow.upstream_provider_id.is_(None),
)
)
row = result.first()
if not row:
raise HTTPException(status_code=404, detail="Model not found")
return _row_to_model(row, apply_provider_fee=False).dict()
else:
provider = await session.get(UpstreamProviderRow, payload.provider_id)
if not provider:
raise HTTPException(status_code=404, detail="Provider not found")
row = await session.get(ModelRow, (payload.model_id, payload.provider_id))
if row:
return _row_to_model(
row, apply_provider_fee=True, provider_fee=provider.provider_fee
).dict()
upstream_instance = _instantiate_provider(provider)
if upstream_instance:
try:
remote_models = await upstream_instance.fetch_models()
for model in remote_models:
if model.id == payload.model_id:
model_with_fee = upstream_instance._apply_provider_fee_to_model(model)
return model_with_fee.dict()
except Exception as e:
logger.error(
f"Failed to fetch models from {provider.provider_type}: {e}"
)
raise HTTPException(
status_code=404, detail="Model not found for this provider"
)
@admin_router.post("/api/models/create", dependencies=[Depends(require_admin_api)])
async def create_model_v2(payload: ModelCreateRequest) -> dict[str, object]:
async with create_session() as session:
if payload.provider_id is None:
exists = await session.get(ModelRow, (payload.model_id, None))
if exists:
raise HTTPException(
status_code=409, detail="Model with this ID already exists"
)
row = ModelRow(
id=payload.model_id,
name=payload.name,
description=payload.description,
created=int(payload.created),
context_length=int(payload.context_length),
architecture=json.dumps(payload.architecture),
pricing=json.dumps(payload.pricing),
sats_pricing=None,
per_request_limits=(
json.dumps(payload.per_request_limits)
if payload.per_request_limits is not None
else None
),
top_provider=(
json.dumps(payload.top_provider) if payload.top_provider else None
),
upstream_provider_id=None,
enabled=payload.enabled,
)
session.add(row)
await session.commit()
await session.refresh(row)
await refresh_model_maps()
return _row_to_model(row, apply_provider_fee=False).dict()
else:
provider = await session.get(UpstreamProviderRow, payload.provider_id)
if not provider:
raise HTTPException(status_code=404, detail="Provider not found")
exists = await session.get(ModelRow, (payload.model_id, payload.provider_id))
if exists:
raise HTTPException(
status_code=409,
detail="Model with this ID already exists for this provider",
)
row = ModelRow(
id=payload.model_id,
name=payload.name,
description=payload.description,
created=int(payload.created),
context_length=int(payload.context_length),
architecture=json.dumps(payload.architecture),
pricing=json.dumps(payload.pricing),
sats_pricing=None,
per_request_limits=(
json.dumps(payload.per_request_limits)
if payload.per_request_limits is not None
else None
),
top_provider=(
json.dumps(payload.top_provider) if payload.top_provider else None
),
upstream_provider_id=payload.provider_id,
enabled=payload.enabled,
)
session.add(row)
await session.commit()
await session.refresh(row)
await refresh_model_maps()
return _row_to_model(
row, apply_provider_fee=True, provider_fee=provider.provider_fee
).dict()
@admin_router.post("/api/models/update", dependencies=[Depends(require_admin_api)])
async def update_model_v2(payload: ModelUpdateRequest) -> dict[str, object]:
async with create_session() as session:
if payload.provider_id is None:
row = await session.get(ModelRow, (payload.model_id, None))
if not row:
raise HTTPException(status_code=404, detail="Model not found")
row.name = payload.name
row.description = payload.description
row.created = int(payload.created)
row.context_length = int(payload.context_length)
row.architecture = json.dumps(payload.architecture)
row.pricing = json.dumps(payload.pricing)
row.sats_pricing = None
row.per_request_limits = (
json.dumps(payload.per_request_limits)
if payload.per_request_limits is not None
else None
)
row.top_provider = (
json.dumps(payload.top_provider) if payload.top_provider else None
)
row.enabled = payload.enabled
session.add(row)
await session.commit()
await session.refresh(row)
await refresh_model_maps()
return _row_to_model(row, apply_provider_fee=False).dict()
else:
provider = await session.get(UpstreamProviderRow, payload.provider_id)
if not provider:
raise HTTPException(status_code=404, detail="Provider not found")
row = await session.get(ModelRow, (payload.model_id, payload.provider_id))
if not row:
raise HTTPException(
status_code=404, detail="Model not found for this provider"
)
row.name = payload.name
row.description = payload.description
row.created = int(payload.created)
row.context_length = int(payload.context_length)
row.architecture = json.dumps(payload.architecture)
row.pricing = json.dumps(payload.pricing)
row.sats_pricing = None
row.per_request_limits = (
json.dumps(payload.per_request_limits)
if payload.per_request_limits is not None
else None
)
row.top_provider = (
json.dumps(payload.top_provider) if payload.top_provider else None
)
row.enabled = payload.enabled
session.add(row)
await session.commit()
await session.refresh(row)
await refresh_model_maps()
return _row_to_model(
row, apply_provider_fee=True, provider_fee=provider.provider_fee
).dict()
@admin_router.post("/api/models/delete", dependencies=[Depends(require_admin_api)])
async def delete_model_v2(payload: ModelDeleteRequest) -> dict[str, object]:
async with create_session() as session:
if payload.provider_id is None:
row = await session.get(ModelRow, (payload.model_id, None))
if not row:
raise HTTPException(status_code=404, detail="Model not found")
await session.delete(row)
await session.commit()
await refresh_model_maps()
return {"ok": True, "deleted_id": payload.model_id}
else:
row = await session.get(ModelRow, (payload.model_id, payload.provider_id))
if not row:
raise HTTPException(
status_code=404, detail="Model not found for this provider"
)
await session.delete(row)
await session.commit()
await refresh_model_maps()
return {"ok": True, "deleted_id": payload.model_id}
@admin_router.get("/models", response_class=HTMLResponse)
async def admin_models(request: Request) -> str:
if is_admin_authenticated(request):