Published on

Plausible helper

Authors

The following is the python codes, it's easy to understand and easy to refactor to fill new requirements


from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
import httpx
import asyncio
import logging

app = FastAPI()
logger = logging.getLogger(__name__)

PLAUSIBLE_SERVICE_URL = "http://host:port/api/event"

async def send_monitoring_request(request: Request, endpoint: str):
    user_agent = request.headers.get("User-Agent", "")
    x_forwarded_for = request.headers.get("X-Forwarded-For", "")

    monitoring_data = {
        "name": "pageview",
        "url": f"http://{request.url.netloc}{endpoint}",
        "domain": request.url.netloc
    }

    headers = {
        "User-Agent": user_agent,
        "X-Forwarded-For": x_forwarded_for,
        "Content-Type": "application/json"
    }
    logger.debug('got request %s from %s', endpoint, x_forwarded_for)
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(PLAUSIBLE_SERVICE_URL, json=monitoring_data, headers=headers)
            response.raise_for_status()
        except httpx.HTTPError as e:
            print(f"Error sending monitoring request: {e}")

@app.post("/v1/chat/completions")
async def chat_completions(request: Request):
    print('/v1/chat/completions')
    asyncio.create_task(send_monitoring_request(request, "/v1/chat/completions"))
    return JSONResponse(
        content={
            "status": "success",
        },
        status_code=200
    )

@app.post("/v1/completions")
async def completions(request: Request):
    print('/v1/completions')
    asyncio.create_task(send_monitoring_request(request, "/v1/completions"))
    return JSONResponse(
        content={
            "status": "success",
        },
        status_code=200
    )

def setup_logging():
    from logging.handlers import RotatingFileHandler
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    # Create a handler for the console
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)

    # Create a handler that rotates the file
    file_handler = RotatingFileHandler('access.log', maxBytes=50*1024*1024, backupCount=5)
    file_handler.setLevel(logging.DEBUG)

    # Create a formatter and add it to the handler
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)
    # Add the handlers to the logger
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)

if __name__ == "__main__":
    import logging
    import uvicorn
    setup_logging()
    uvicorn.run(app, host="0.0.0.0", port=9000)