From 2c6e2d5e8a4218bbee1c0959837dd71b604201b5 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 20 Mar 2024 18:35:02 -0700 Subject: [PATCH] feat: webhook backend --- backend/apps/web/main.py | 2 ++ backend/apps/web/routers/auths.py | 13 ++++++++++++- backend/config.py | 1 + backend/constants.py | 7 +++++++ backend/main.py | 28 +++++++++++++++++++++++++++- backend/utils/webhook.py | 11 +++++++++++ 6 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 backend/utils/webhook.py diff --git a/backend/apps/web/main.py b/backend/apps/web/main.py index bd14f4bda..dd5c0c704 100644 --- a/backend/apps/web/main.py +++ b/backend/apps/web/main.py @@ -19,6 +19,7 @@ from config import ( DEFAULT_USER_ROLE, ENABLE_SIGNUP, USER_PERMISSIONS, + WEBHOOK_URL, ) app = FastAPI() @@ -32,6 +33,7 @@ app.state.DEFAULT_MODELS = DEFAULT_MODELS app.state.DEFAULT_PROMPT_SUGGESTIONS = DEFAULT_PROMPT_SUGGESTIONS app.state.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE app.state.USER_PERMISSIONS = USER_PERMISSIONS +app.state.WEBHOOK_URL = WEBHOOK_URL app.add_middleware( diff --git a/backend/apps/web/routers/auths.py b/backend/apps/web/routers/auths.py index 3db2d0ad2..0f9704974 100644 --- a/backend/apps/web/routers/auths.py +++ b/backend/apps/web/routers/auths.py @@ -27,7 +27,8 @@ from utils.utils import ( create_token, ) from utils.misc import parse_duration, validate_email_format -from constants import ERROR_MESSAGES +from utils.webhook import post_webhook +from constants import ERROR_MESSAGES, WEBHOOK_MESSAGES router = APIRouter() @@ -155,6 +156,16 @@ async def signup(request: Request, form_data: SignupForm): ) # response.set_cookie(key='token', value=token, httponly=True) + if request.app.state.WEBHOOK_URL: + post_webhook( + request.app.state.WEBHOOK_URL, + { + "action": "signup", + "message": WEBHOOK_MESSAGES.USER_SIGNUP(user.name), + "user": user.model_dump_json(exclude_none=True), + }, + ) + return { "token": token, "token_type": "Bearer", diff --git a/backend/config.py b/backend/config.py index b5e7a5394..e99e248c5 100644 --- a/backend/config.py +++ b/backend/config.py @@ -302,6 +302,7 @@ MODEL_FILTER_ENABLED = os.environ.get("MODEL_FILTER_ENABLED", False) MODEL_FILTER_LIST = os.environ.get("MODEL_FILTER_LIST", "") MODEL_FILTER_LIST = [model.strip() for model in MODEL_FILTER_LIST.split(";")] +WEBHOOK_URL = os.environ.get("WEBHOOK_URL", "") #################################### # WEBUI_VERSION diff --git a/backend/constants.py b/backend/constants.py index 994b8caf7..42c5c85eb 100644 --- a/backend/constants.py +++ b/backend/constants.py @@ -5,6 +5,13 @@ class MESSAGES(str, Enum): DEFAULT = lambda msg="": f"{msg if msg else ''}" +class WEBHOOK_MESSAGES(str, Enum): + DEFAULT = lambda msg="": f"{msg if msg else ''}" + USER_SIGNUP = lambda username="": ( + f"New user signed up: {username}" if username else "New user signed up" + ) + + class ERROR_MESSAGES(str, Enum): def __str__(self) -> str: return super().__str__() diff --git a/backend/main.py b/backend/main.py index 253227182..35f405e69 100644 --- a/backend/main.py +++ b/backend/main.py @@ -38,6 +38,7 @@ from config import ( FRONTEND_BUILD_DIR, MODEL_FILTER_ENABLED, MODEL_FILTER_LIST, + WEBHOOK_URL, ) from constants import ERROR_MESSAGES @@ -58,6 +59,9 @@ app = FastAPI(docs_url="/docs" if ENV == "dev" else None, redoc_url=None) app.state.MODEL_FILTER_ENABLED = MODEL_FILTER_ENABLED app.state.MODEL_FILTER_LIST = MODEL_FILTER_LIST +app.state.WEBHOOK_URL = WEBHOOK_URL + + origins = ["*"] @@ -178,7 +182,7 @@ class ModelFilterConfigForm(BaseModel): @app.post("/api/config/model/filter") -async def get_model_filter_config( +async def update_model_filter_config( form_data: ModelFilterConfigForm, user=Depends(get_admin_user) ): @@ -197,6 +201,28 @@ async def get_model_filter_config( } +@app.get("/api/webhook") +async def get_webhook_url(user=Depends(get_admin_user)): + return { + "url": app.state.WEBHOOK_URL, + } + + +class UrlForm(BaseModel): + url: str + + +@app.post("/api/webhook") +async def update_webhook_url(form_data: UrlForm, user=Depends(get_admin_user)): + app.state.WEBHOOK_URL = form_data.url + + webui_app.state.WEBHOOK_URL = app.state.WEBHOOK_URL + + return { + "url": app.state.WEBHOOK_URL, + } + + @app.get("/api/version") async def get_app_config(): diff --git a/backend/utils/webhook.py b/backend/utils/webhook.py new file mode 100644 index 000000000..c1d03ac71 --- /dev/null +++ b/backend/utils/webhook.py @@ -0,0 +1,11 @@ +import requests + + +def post_webhook(url: str, json: dict) -> bool: + try: + r = requests.post(url, json=json) + r.raise_for_status() + return True + except Exception as e: + print(e) + return False