Search code examples
pythongunicorn

How to return a jpg / jpeg with gunicorn


I can return an html file with gunicorn, but I am trying to return an image file being referenced in an <img> tag. The image is not rendering in the browser, and in fact I see no response being returned in the browser tools for the image.

This is my gunicorn code:

def render_jpeg(filename):
    encoded_string = ""
    with open(filename, "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read())
        return encoded_string

def app(environ, start_response):
    path = environ.get("PATH_INFO")
    data = ""
    encode = "utf-8"
    content_type = 'text/html'
    
    if path.endswith(".jpeg"):
        content_type = 'image/jpeg'
        encode = "byte"
        data = render_jpeg(path)
    else:
        context = {"path": path, "pageTitle": "home"}
        data = template("template.html", context)

    if encode.endswith("utf-8"):
        data = data.encode(encode)

    status = '200 OK'
    response_headers = [
        ('Content-type', content_type),
        ('Content-Length', str(len(data)))
    ]
    start_response(status, response_headers)
    return iter([data])

This is my command

gunicorn --workers=2 test:app --reload --log-file log.txt --log-level 'debug'

This is my log output

[2022-07-08 14:28:21 -0400] [91974] [INFO] Starting gunicorn 20.1.0
[2022-07-08 14:28:21 -0400] [91974] [DEBUG] Arbiter booted
[2022-07-08 14:28:21 -0400] [91974] [INFO] Listening at: http://127.0.0.1:8000 (91974)
[2022-07-08 14:28:21 -0400] [91974] [INFO] Using worker: sync
[2022-07-08 14:28:21 -0400] [91976] [INFO] Booting worker with pid: 91976
[2022-07-08 14:28:21 -0400] [91977] [INFO] Booting worker with pid: 91977
[2022-07-08 14:28:21 -0400] [91974] [DEBUG] 2 workers
[2022-07-08 14:28:47 -0400] [91977] [DEBUG] GET /media/zombie1.jpeg
[2022-07-08 14:28:47 -0400] [91977] [DEBUG] GET /favicon.ico
[2022-07-08 14:30:33 -0400] [91974] [INFO] Handling signal: int
[2022-07-08 14:30:33 -0400] [91976] [INFO] Worker exiting (pid: 91976)
[2022-07-08 14:30:33 -0400] [91977] [INFO] Worker exiting (pid: 91977)
[2022-07-08 14:30:33 -0400] [91974] [INFO] Shutting down: Master

Where am I going wrong?


Solution

  • As @tripleee noted, my issue was the base64 encoding. No encoding required! Corrected code:

    def render_jpeg(filename):
        data = ""
        with open(filename, "rb") as image_file:
            data = image_file.read()
            return data
    
    def app(environ, start_response):
        path = environ.get("PATH_INFO")
        data = ""
        encode = "utf-8"
        content_type = 'text/html'
        
        if path.endswith(".jpeg"):
            content_type = 'image/jpeg'
            encode = ""
            filename = get_filename_from_path(path)
            data = render_jpeg(filename)
        else:
            context = {"path": path, "pageTitle": "home"}
            data = template("template.html", context)
    
        if encode.endswith("utf-8"):
            data = data.encode(encode)
    
        status = '200 OK'
        response_headers = [
            ('Content-type', content_type),
            ('Content-Length', str(len(data)))
        ]
        start_response(status, response_headers)
        return iter([data])