diff --git a/app.py b/app.py index 10fa772..6720e49 100644 --- a/app.py +++ b/app.py @@ -1,18 +1,30 @@ import io import logging +import os import re import logfire -from fastapi import FastAPI, HTTPException +from fastapi import Depends, FastAPI, Header, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse, StreamingResponse from pydantic import BaseModel, Field from weasyprint import HTML +from weasyprint.text.fonts import FontConfiguration # Initialize logging logfire.configure() logging.basicConfig(level=logging.INFO) logging.basicConfig(handlers=[logfire.LogfireLoggingHandler()]) +logger = logging.getLogger("weasyprint") +logger.handlers.clear() +logger.setLevel(logging.DEBUG) +logger.addHandler(logfire.LogfireLoggingHandler()) + +# Load secret from environment variable +SECRET_KEY = os.getenv("SECRET_KEY") + +if not SECRET_KEY: + raise RuntimeError("SECRET_KEY environment variable is not set") class PdfRequest(BaseModel): @@ -66,7 +78,21 @@ async def pdf_generator(byte_string: bytes): chunk = byte_stream.read(4096) -@app.post("/pdf") +def verify_secret_key(x_secret_key: str = Header(...)): + """ + Dependency to verify the secret key from the request header. + + Args: + x_secret_key (str): The secret key from the request header. + + Raises: + HTTPException: If the secret key is invalid. + """ + if x_secret_key != SECRET_KEY: + raise HTTPException(status_code=401, detail="Invalid secret key") + + +@app.post("/pdf", dependencies=[Depends(verify_secret_key)]) async def pdf(body: PdfRequest): """ Endpoint to convert HTML content to a PDF file. @@ -78,8 +104,9 @@ async def pdf(body: PdfRequest): StreamingResponse: A streaming response with the generated PDF file. """ logging.info("Received request to generate PDF") + font_config = FontConfiguration() try: - byte_string = HTML(string=body.html).write_pdf() + byte_string = HTML(string=body.html).write_pdf(font_config=font_config) except Exception as e: logging.error(f"Error generating PDF: {e}") raise HTTPException(status_code=400, detail="Invalid HTML input") from e diff --git a/poetry.lock b/poetry.lock index 3fb5f6a..6643725 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1813,32 +1813,6 @@ pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] -[[package]] -name = "ruff" -version = "0.0.289" -description = "An extremely fast Python linter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.0.289-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:c9a89d748e90c840bac9c37afe90cf13a5bfd460ca02ea93dad9d7bee3af03b4"}, - {file = "ruff-0.0.289-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:7f7396c6ea01ba332a6ad9d47642bac25d16bd2076aaa595b001f58b2f32ff05"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7180de86c8ecd39624dec1699136f941c07e723201b4ce979bec9e7c67b40ad2"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73f37c65508203dd01a539926375a10243769c20d4fcab3fa6359cd3fbfc54b7"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c14abcd7563b5c80be2dd809eeab20e4aa716bf849860b60a22d87ddf19eb88"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:91b6d63b6b46d4707916472c91baa87aa0592e73f62a80ff55efdf6c0668cfd6"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6479b8c4be3c36046c6c92054762b276fa0fddb03f6b9a310fbbf4c4951267fd"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5424318c254bcb091cb67e140ec9b9f7122074e100b06236f252923fb41e767"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4daa90865796aedcedf0d8897fdd4cd09bf0ddd3504529a4ccf211edcaff3c7d"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8057e8ab0016c13b9419bad119e854f881e687bd96bc5e2d52c8baac0f278a44"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7eebfab2e6a6991908ff1bf82f2dc1e5095fc7e316848e62124526837b445f4d"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ebc7af550018001a7fb39ca22cdce20e1a0de4388ea4a007eb5c822f6188c297"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6e4e6eccb753efe760ba354fc8e9f783f6bba71aa9f592756f5bd0d78db898ed"}, - {file = "ruff-0.0.289-py3-none-win32.whl", hash = "sha256:bbb3044f931c09cf17dbe5b339896eece0d6ac10c9a86e172540fcdb1974f2b7"}, - {file = "ruff-0.0.289-py3-none-win_amd64.whl", hash = "sha256:6d043c5456b792be2615a52f16056c3cf6c40506ce1f2d6f9d3083cfcb9eeab6"}, - {file = "ruff-0.0.289-py3-none-win_arm64.whl", hash = "sha256:04a720bcca5e987426bb14ad8b9c6f55e259ea774da1cbeafe71569744cfd20a"}, - {file = "ruff-0.0.289.tar.gz", hash = "sha256:2513f853b0fc42f0339b7ab0d2751b63ce7a50a0032d2689b54b2931b3b866d7"}, -] - [[package]] name = "shellingham" version = "1.5.4" @@ -2448,4 +2422,4 @@ test = ["pytest"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "66cbb12603e0d88dfa1bb766130cf82545db47bc4bd93a2f9320d8ed60a7f189" +content-hash = "607f15adf3b52bd6f9a1fb613ef0bbf94db4dd3fe501450d5c8cd8876a2191a8" diff --git a/pyproject.toml b/pyproject.toml index 74d013a..a279d1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ logfire = {extras = ["fastapi"], version = "^2.1.2"} pytest = "^8.3.3" httpx = "^0.27.2" pytest-cov = "^4.0.0" -ruff = "^0.0.289" pre-commit = "^3.4.0" [build-system]