Add a new `/dbapi` router package providing a generic database API over `dataset`, restricted to admin sessions, admin API keys, and the internal gateway key. Includes: - `tables.py`: list all tables and inspect table schemas - `crud.py`: full CRUD operations (GET, POST, PATCH, DELETE) with soft-delete awareness, born-live inserts, `?include_deleted`, `.../restore`, and `?hard=true` purge - `query.py`: validated read-only SELECT execution via sqlglot parsing, classification, and EXPLAIN dry-run; async query jobs with WebSocket streaming via `DbApiJobService` - `nl.py`: natural-language-to-SQL conversion using the platform AI gateway with re-prompting until validation passes Also register `DbApiJobService` and `PubSubService` in the service manager, add `DBAPI_DIR` to config data paths, and force cleartext `http://` connections to HTTP/1.1 in `curl_transport` to fix large request failures against uvicorn's HTTP/1.1-only internal gateway.
37 lines
1.1 KiB
Python
37 lines
1.1 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
|
|
from __future__ import annotations
|
|
|
|
from devplacepy.services.base import BaseService, ConfigField
|
|
|
|
from .hub import pubsub
|
|
|
|
|
|
class PubSubService(BaseService):
|
|
title = "Pub/Sub"
|
|
description = (
|
|
"In-process publish/subscribe bus over websockets. Lets the frontend, services and "
|
|
"Devii broadcast and receive messages on named topics. Database-free and ephemeral; "
|
|
"served on the service lock owner so every subscriber converges on one worker."
|
|
)
|
|
default_enabled = True
|
|
|
|
def __init__(self):
|
|
super().__init__(name="pubsub", interval_seconds=3600)
|
|
self.config_fields = [
|
|
ConfigField(
|
|
"pubsub_allow_guests",
|
|
"Allow guests",
|
|
type="bool",
|
|
default=False,
|
|
help="Allow unauthenticated guests to subscribe to public.* topics.",
|
|
group="Pub/Sub",
|
|
),
|
|
]
|
|
|
|
async def run_once(self) -> None:
|
|
return None
|
|
|
|
def collect_metrics(self) -> dict:
|
|
return {"topics": len(pubsub.topics())}
|