mirror of
https://github.com/shadoll/scatcher.git
synced 2025-12-20 03:26:59 +00:00
Refactor webhook namespace handling and add support for storing requests in different namespaces
This commit is contained in:
57
app.py
57
app.py
@@ -1,21 +1,32 @@
|
|||||||
from fastapi import FastAPI, Request, Response, status
|
from fastapi import FastAPI, Request, Response, status
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
HISTORY_LIMIT = 10
|
HISTORY_LIMIT = 10
|
||||||
HISTORY_FILE = "storage/requests.json"
|
HISTORY_STORAGE = "storage"
|
||||||
|
|
||||||
|
|
||||||
def store_last_request(last_request, filename=HISTORY_FILE):
|
def store_last_request(
|
||||||
|
request_data,
|
||||||
|
namespace="requests"
|
||||||
|
):
|
||||||
|
|
||||||
|
# Check if the directory exists, if not, create it
|
||||||
|
if not os.path.exists(HISTORY_STORAGE):
|
||||||
|
os.makedirs(HISTORY_STORAGE)
|
||||||
|
|
||||||
|
filename = f"{HISTORY_STORAGE}/{namespace}.json"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(filename, "r") as f:
|
with open(filename, "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
except (FileNotFoundError, json.JSONDecodeError):
|
except (FileNotFoundError, json.JSONDecodeError):
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
data.append(last_request)
|
data.append(request_data)
|
||||||
|
|
||||||
if len(data) > HISTORY_LIMIT:
|
if len(data) > HISTORY_LIMIT:
|
||||||
data.pop(0)
|
data.pop(0)
|
||||||
@@ -30,7 +41,14 @@ def store_last_request(last_request, filename=HISTORY_FILE):
|
|||||||
@app.patch("/", status_code=status.HTTP_200_OK)
|
@app.patch("/", status_code=status.HTTP_200_OK)
|
||||||
@app.options("/", status_code=status.HTTP_200_OK)
|
@app.options("/", status_code=status.HTTP_200_OK)
|
||||||
@app.head("/", status_code=status.HTTP_200_OK)
|
@app.head("/", status_code=status.HTTP_200_OK)
|
||||||
async def webhook_handler(request: Request, response: Response):
|
@app.get("/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
@app.post("/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
@app.put("/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
@app.delete("/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
@app.patch("/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
@app.options("/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
@app.head("/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
async def webhook_namespace_handler(request: Request, response: Response, namespace: str = "requests"):
|
||||||
try:
|
try:
|
||||||
json = await request.json()
|
json = await request.json()
|
||||||
except:
|
except:
|
||||||
@@ -43,55 +61,70 @@ async def webhook_handler(request: Request, response: Response):
|
|||||||
"headers": dict(request.headers),
|
"headers": dict(request.headers),
|
||||||
"time": datetime.now().isoformat(),
|
"time": datetime.now().isoformat(),
|
||||||
}
|
}
|
||||||
store_last_request(last_request)
|
store_last_request(request_data=last_request, namespace=namespace)
|
||||||
|
|
||||||
response.status_code = status.HTTP_200_OK
|
response.status_code = status.HTTP_200_OK
|
||||||
|
|
||||||
return {"status": "ok", "message": "Request catched."}
|
return {"status": "ok", "message": "Request catched."}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/__help", status_code=status.HTTP_200_OK)
|
@app.get("/api/__help", status_code=status.HTTP_200_OK)
|
||||||
def help():
|
def help():
|
||||||
return {
|
return {
|
||||||
"message": "This is a simple webhook service. It stores the last 10 requests and returns them on demand.",
|
"message": "This is a simple webhook service. It stores the last 10 requests and returns them on demand.",
|
||||||
"endpoints": {
|
"endpoints": {
|
||||||
"/": "Accepts a webhook request and stores it.",
|
"/": "Accepts a webhook request and stores it.",
|
||||||
|
"/{namespace}": "Accepts a webhook request and stores it in the given namespace.",
|
||||||
"/docs": "Swagger UI for the API.",
|
"/docs": "Swagger UI for the API.",
|
||||||
"/redoc": "ReDoc UI for the API.",
|
"/redoc": "ReDoc UI for the API.",
|
||||||
"/api/__last_request": "GET: Returns the last request received.",
|
"/api/__last_request": "GET: Returns the last request received.",
|
||||||
|
"/api/__last_request/{namespace}": "GET: Returns the last request received for the given namespace.",
|
||||||
"/api/__history": "GET: Returns the last 10 requests received.",
|
"/api/__history": "GET: Returns the last 10 requests received.",
|
||||||
|
"/api/__history/{namespace}": "GET: Returns the last 10 requests received for the given namespace.",
|
||||||
"/api/__history/{id}": "GET: Returns the request with the given ID.",
|
"/api/__history/{id}": "GET: Returns the request with the given ID.",
|
||||||
|
"/api/__history/{namespace}/{id}": "GET: Returns the request with the given ID for the given namespace.",
|
||||||
"/api/__clear": "GET: Clears the request history.",
|
"/api/__clear": "GET: Clears the request history.",
|
||||||
|
"/api/__clear/{namespace}": "GET: Clears the request history for the given namespace.",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@app.get("/api/__last_request", status_code=status.HTTP_200_OK)
|
@app.get("/api/__last_request", status_code=status.HTTP_200_OK)
|
||||||
async def last_requests():
|
@app.get("/api/__last_request/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
async def last_requests(namespace: str = "requests"):
|
||||||
|
filename = f"{HISTORY_STORAGE}/{namespace}.json"
|
||||||
try:
|
try:
|
||||||
with open(HISTORY_FILE, "r") as f:
|
with open(filename, "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
except (FileNotFoundError, json.JSONDecodeError):
|
except (FileNotFoundError, json.JSONDecodeError):
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
|
if len(data) == 0:
|
||||||
|
return {"status": "error", "message": "No requests found."}
|
||||||
return data[-1]
|
return data[-1]
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/__history/{id}", status_code=status.HTTP_200_OK)
|
@app.get("/api/__history/{id}", status_code=status.HTTP_200_OK)
|
||||||
@app.get("/api/__history", status_code=status.HTTP_200_OK)
|
@app.get("/api/__history", status_code=status.HTTP_200_OK)
|
||||||
async def history(id: int = None):
|
@app.get("/api/__history/{namespace}/{id}", status_code=status.HTTP_200_OK)
|
||||||
|
@app.get("/api/__history/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
|
async def history(id: int = None, namespace: str = "requests"):
|
||||||
|
filename = f"{HISTORY_STORAGE}/{namespace}.json"
|
||||||
try:
|
try:
|
||||||
with open(HISTORY_FILE, "r") as f:
|
with open(filename, "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
except (FileNotFoundError, json.JSONDecodeError):
|
except (FileNotFoundError, json.JSONDecodeError):
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
if id is not None:
|
if id is not None:
|
||||||
|
if len(data) == 0:
|
||||||
|
return {"status": "error", "message": "No requests found."}
|
||||||
return data[-id]
|
return data[-id]
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@app.get("/api/__clear", status_code=status.HTTP_200_OK)
|
@app.get("/api/__clear", status_code=status.HTTP_200_OK)
|
||||||
async def clear_history():
|
@app.get("/api/__clear/{namespace}", status_code=status.HTTP_200_OK)
|
||||||
with open(HISTORY_FILE, "w") as f:
|
async def clear_history(namespace: str = "requests"):
|
||||||
|
filename = f"{HISTORY_STORAGE}/{namespace}.json"
|
||||||
|
with open(filename, "w") as f:
|
||||||
json.dump([], f)
|
json.dump([], f)
|
||||||
|
|
||||||
return {"status": "ok", "message": "History cleared."}
|
return {"status": "ok", "message": "History cleared."}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ GET https://catcher.rs.shadoll.dev/api/__help
|
|||||||
###
|
###
|
||||||
GET https://catcher.rs.shadoll.dev/api/__last_request
|
GET https://catcher.rs.shadoll.dev/api/__last_request
|
||||||
###
|
###
|
||||||
GET https://catcher.rs.shadoll.dev/__history__
|
GET https://catcher.rs.shadoll.dev/api/__history
|
||||||
###
|
###
|
||||||
GET https://catcher.rs.shadoll.dev/__history__/1
|
GET https://catcher.rs.shadoll.dev/api/__history/1
|
||||||
###
|
###
|
||||||
GET https://catcher.rs.shadoll.dev/api/__clear
|
GET https://catcher.rs.shadoll.dev/api/__clear
|
||||||
###
|
###
|
||||||
POST https://catcher.rs.shadoll.dev/
|
POST https://catcher.rs.shadoll.dev
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user