From 30f8e8b81a175f0aac94335e28998e5a43662eda Mon Sep 17 00:00:00 2001 From: sHa Date: Tue, 12 Mar 2024 22:03:09 +0000 Subject: [PATCH] Add webhook endpoints and update Docker configuration --- app.py | 57 ++++++++++++++++++++++++++++++++++++++++++--------- compose.yml | 3 ++- requests.http | 27 +++++++++++++++++++++++- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/app.py b/app.py index 2eb82cc..6b3a03a 100644 --- a/app.py +++ b/app.py @@ -23,27 +23,49 @@ def store_last_request(last_request, filename=HISTORY_FILE): with open(filename, "w") as f: json.dump(data, f) - +@app.get("/", status_code=status.HTTP_200_OK) @app.post("/", status_code=status.HTTP_200_OK) +@app.put("/", status_code=status.HTTP_200_OK) +@app.delete("/", status_code=status.HTTP_200_OK) +@app.patch("/", status_code=status.HTTP_200_OK) +@app.options("/", status_code=status.HTTP_200_OK) +@app.head("/", status_code=status.HTTP_200_OK) async def webhook_handler(request: Request, response: Response): - - payload = await request.body() + try: + json = await request.json() + except: + json = {"invalid": "json"} last_request = { + "data": json, "method": request.method, - "data": payload.decode("utf-8"), + "url": str(request.url), "headers": dict(request.headers), - "url": request.url, "time": datetime.now().isoformat(), } store_last_request(last_request) response.status_code = status.HTTP_200_OK - return {"status": "ok"} + return {"status": "ok", "message": "Request catched."} -@app.get("/__last_request__", status_code=status.HTTP_200_OK) +@app.get("/api/__help", status_code=status.HTTP_200_OK) +def help(): + return { + "message": "This is a simple webhook service. It stores the last 10 requests and returns them on demand.", + "endpoints": { + "/": "Accepts a webhook request and stores it.", + "/docs": "Swagger UI for the API.", + "/redoc": "ReDoc UI for the API.", + "/api/__last_request": "GET: Returns the last request received.", + "/api/__history": "GET: Returns the last 10 requests received.", + "/api/__history/{id}": "GET: Returns the request with the given ID.", + "/api/__clear": "GET: Clears the request history.", + }, + } + +@app.get("/api/__last_request", status_code=status.HTTP_200_OK) async def last_requests(): try: with open(HISTORY_FILE, "r") as f: @@ -51,15 +73,30 @@ async def last_requests(): except (FileNotFoundError, json.JSONDecodeError): data = [] - return data[-1:] + return data[-1] -@app.get("/__history__", status_code=status.HTTP_200_OK) -async def history(): +@app.get("/api/__history/{id}", status_code=status.HTTP_200_OK) +@app.get("/api/__history", status_code=status.HTTP_200_OK) +async def history(id: int = None): try: with open(HISTORY_FILE, "r") as f: data = json.load(f) except (FileNotFoundError, json.JSONDecodeError): data = [] + if id is not None: + return data[-id] return data + +@app.get("/api/__clear", status_code=status.HTTP_200_OK) +async def clear_history(): + with open(HISTORY_FILE, "w") as f: + json.dump([], f) + + return {"status": "ok", "message": "History cleared."} + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/compose.yml b/compose.yml index 25f0366..21a5424 100644 --- a/compose.yml +++ b/compose.yml @@ -10,6 +10,7 @@ services: context: . dockerfile: Dockerfile volumes: + - ./app.py:/app/app.py - ./storage:/app/storage networks: - "apps-proxy" @@ -20,5 +21,5 @@ services: traefik.http.routers.catcher.rule: Host(`catcher.rs.shadoll.dev`) traefik.http.routers.catcher.tls: true traefik.http.routers.catcher.tls.certresolver: letsencrypt - traefik.http.services.catcher.loadbalancer.server.port: 5000 + traefik.http.services.catcher.loadbalancer.server.port: 8000 diff --git a/requests.http b/requests.http index 77f1a63..34cf73a 100644 --- a/requests.http +++ b/requests.http @@ -1 +1,26 @@ -GET https://catcher.rs.shadoll.dev/__last_request__ \ No newline at end of file +GET https://catcher.rs.shadoll.dev/api/__help +### +GET https://catcher.rs.shadoll.dev/api/__last_request +### +GET https://catcher.rs.shadoll.dev/__history__ +### +GET https://catcher.rs.shadoll.dev/__history__/1 +### +GET https://catcher.rs.shadoll.dev/api/__clear +### +POST https://catcher.rs.shadoll.dev/ +Content-Type: application/json + +{ + "message": "Hello, World!", + "level": "info", + "tags": [ + "example", + "hello-world" + ], + "extra": { + "key": "value", + } +} +### +GET https://catcher.rs.shadoll.dev?message=Hello%2C%20World%21&level=info&tags=example&tags=hello-world&extra[key]=value \ No newline at end of file