Добавил поддержку webhook
This commit is contained in:
87
app/api.py
87
app/api.py
@@ -10,6 +10,8 @@ except ImportError:
|
||||
HTTPException = None
|
||||
BaseModel = object
|
||||
|
||||
from sqlalchemy import text
|
||||
|
||||
from .config import Config
|
||||
from .queue import migration_queue
|
||||
from .table_config_repository import TableConfigRepository
|
||||
@@ -45,6 +47,16 @@ class ScheduleRequest(BaseModel):
|
||||
initial_force_full: bool = False
|
||||
|
||||
|
||||
class WebhookCreate(BaseModel):
|
||||
url: str
|
||||
secret: Optional[str] = None
|
||||
label: Optional[str] = None
|
||||
|
||||
|
||||
class WebhookToggle(BaseModel):
|
||||
active: bool
|
||||
|
||||
|
||||
def create_app():
|
||||
"""Создание FastAPI приложения."""
|
||||
if FastAPI is None:
|
||||
@@ -57,12 +69,29 @@ def create_app():
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
config = Config()
|
||||
_shared['engine'] = create_engine(
|
||||
engine = create_engine(
|
||||
config.POSTGRES_CONNECTION_STRING,
|
||||
pool_pre_ping=True,
|
||||
pool_recycle=1800,
|
||||
)
|
||||
_shared['engine'] = engine
|
||||
_shared['config'] = config
|
||||
|
||||
schema = f'"{config.REPLICATOR_SCHEMA}"'
|
||||
with engine.connect() as conn:
|
||||
conn.execute(text(f'CREATE SCHEMA IF NOT EXISTS {schema}'))
|
||||
conn.execute(text(f"""
|
||||
CREATE TABLE IF NOT EXISTS {schema}.webhook_subscriptions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
url TEXT NOT NULL,
|
||||
secret TEXT,
|
||||
label TEXT,
|
||||
active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now()
|
||||
)
|
||||
"""))
|
||||
conn.commit()
|
||||
|
||||
if Config.START_API_WORKER:
|
||||
migration_queue.start()
|
||||
|
||||
@@ -169,6 +198,62 @@ def create_app():
|
||||
|
||||
return {"status": "scheduled", "schedule": schedule}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Webhooks
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
_WEBHOOKS_TABLE = f'"{Config.REPLICATOR_SCHEMA}".webhook_subscriptions'
|
||||
|
||||
@api.get("/webhooks")
|
||||
def list_webhooks():
|
||||
with _shared['engine'].connect() as conn:
|
||||
rows = conn.execute(
|
||||
text(f"SELECT id, url, secret, label, active, created_at FROM {_WEBHOOKS_TABLE} ORDER BY id")
|
||||
).mappings().all()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
@api.post("/webhooks", status_code=201)
|
||||
def create_webhook(body: WebhookCreate):
|
||||
with _shared['engine'].connect() as conn:
|
||||
row = conn.execute(
|
||||
text(f"""
|
||||
INSERT INTO {_WEBHOOKS_TABLE} (url, secret, label)
|
||||
VALUES (:url, :secret, :label)
|
||||
RETURNING id, url, secret, label, active, created_at
|
||||
"""),
|
||||
{'url': body.url, 'secret': body.secret, 'label': body.label},
|
||||
).mappings().first()
|
||||
conn.commit()
|
||||
return dict(row)
|
||||
|
||||
@api.patch("/webhooks/{webhook_id}")
|
||||
def toggle_webhook(webhook_id: int, body: WebhookToggle):
|
||||
with _shared['engine'].connect() as conn:
|
||||
row = conn.execute(
|
||||
text(f"""
|
||||
UPDATE {_WEBHOOKS_TABLE}
|
||||
SET active = :active
|
||||
WHERE id = :id
|
||||
RETURNING id, url, secret, label, active, created_at
|
||||
"""),
|
||||
{'active': body.active, 'id': webhook_id},
|
||||
).mappings().first()
|
||||
conn.commit()
|
||||
if not row:
|
||||
raise HTTPException(status_code=404, detail="Webhook not found")
|
||||
return dict(row)
|
||||
|
||||
@api.delete("/webhooks/{webhook_id}", status_code=204)
|
||||
def delete_webhook(webhook_id: int):
|
||||
with _shared['engine'].connect() as conn:
|
||||
result = conn.execute(
|
||||
text(f"DELETE FROM {_WEBHOOKS_TABLE} WHERE id = :id"),
|
||||
{'id': webhook_id},
|
||||
)
|
||||
conn.commit()
|
||||
if result.rowcount == 0:
|
||||
raise HTTPException(status_code=404, detail="Webhook not found")
|
||||
|
||||
return api
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user