2 Commits

Author SHA1 Message Date
a09424b2aa Merge branch 'main' of git.nice.net.nz:hads/hinpdof
Some checks failed
Build and Publish Docker Image / build (push) Failing after 35s
2024-12-12 13:45:27 +13:00
22608a1179 Add ruff and secret key 2024-12-12 13:44:37 +13:00
3 changed files with 90 additions and 4 deletions

33
app.py
View File

@@ -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

2
poetry.lock generated
View File

@@ -2450,4 +2450,4 @@ test = ["pytest"]
[metadata]
lock-version = "2.0"
python-versions = "^3.12"
content-hash = "5197a27c39a98a2cf8715ba4fff5002f3da3d12e72e9168cf0667f8cae41c3a2"
content-hash = "66cbb12603e0d88dfa1bb766130cf82545db47bc4bd93a2f9320d8ed60a7f189"

59
test.py Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""
Opens the `test.j2` HTML template and sends it to the hinpdof API service to convert
it to a PDF file and saves the result to the `test.pdf` file.
"""
import requests
from jinja2 import Environment, FileSystemLoader
# hinpdof API service openapi url: https://hinpdof.huna.me/openapi.json
def render_template(template_name, context):
"""Render the Jinja2 template with the given context."""
env = Environment(loader=FileSystemLoader("."))
template = env.get_template(template_name)
return template.render(context)
def convert_html_to_pdf(html_content):
"""Send the HTML content to the hinpdof API service to convert it to a PDF file."""
api_url = "https://hinpdof.huna.me/pdf"
api_url = "http://localhost:8000/pdf"
headers = {
"Content-Type": "application/json",
"x-secret-key": "foo",
}
data = {
"html": html_content,
}
response = requests.post(api_url, json=data, headers=headers)
response.raise_for_status()
return response.content
def save_pdf(pdf_content, output_path):
"""Save the PDF content to a file."""
with open(output_path, "wb") as pdf_file:
pdf_file.write(pdf_content)
def main():
# Render the Jinja2 template
template_name = "test.j2"
context = {} # Add any context variables needed for the template
html_content = render_template(template_name, context)
# Convert the HTML content to a PDF file
pdf_content = convert_html_to_pdf(html_content)
# Save the PDF file
output_path = "test.pdf"
save_pdf(pdf_content, output_path)
print(f"PDF file saved to {output_path}")
if __name__ == "__main__":
main()