1

I read a list of files with os.listdir to display each of the file names in an html page. But when I run this code I get "127.0.0.1:53765 - "GET / HTTP/1.1" 422 Unprocessable Entity."

main.py :

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
import os

app = FastAPI()

templates = Jinja2Templates(directory="templates")

@app.get("/", response_class=HTMLResponse)
def print_files(request: Request, dir_files: list):
    proj_dir = "D:\Project_Dir/"
    dir_files = os.listdir(proj_dir)
    dir_files.sort()
    dir_files = dir_files[:20]
    return templates.TemplateResponse("file_listing.html", {"request": request, dir_files:  list})

file_listing.html :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>code_listing</title>
</head>

<body>
<h1>List of files with comments</h1>
    {% for line in data.get("dir_files") %}
        <p>{{ line }}</p>
    {% end-for %}
</body>
</html>

I decided to simplify and pass just a simple list: dir_files = [ "File1", "FIle2", "File3", File4" ] but I got the same error.

A 422 error means "The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity but was unable to process the contained instructions."

This is my first time looping through a list with FastAPI, so I hope there is a simple solution.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
RTC222
  • 2,025
  • 1
  • 20
  • 53
  • 1
    How do you pass it? It should be passed as `/?dir_files=File1&dir_files=File2...` – sudden_appearance Apr 18 '23 at 18:28
  • 1
    Does this answer your question? [How to set Swagger UI to use List fields in query parameters using FastAPI?](https://stackoverflow.com/questions/73066794/how-to-set-swagger-ui-to-use-list-fields-in-query-parameters-using-fastapi) – Chris Apr 18 '23 at 18:52
  • 1
    Please have a look at **Option 2** of [this answer](https://stackoverflow.com/a/73982479/17865804) as well. In short, you would need to define the query parameter explicitly with `Query()` – Chris Apr 18 '23 at 18:53
  • Thanks for all three comments. It looks like it should be passed as an element of a class or as part of a dictionary (a similar solution I just saw). I will work that out and post back to tell you what happens. – RTC222 Apr 18 '23 at 19:31

1 Answers1

0

I worked this out. I needed to make the list part of a dictionary – I think the same thing would work by passing a class. What you have to do is pass the dictionary by name, then extract the named items within the dictionary. Here’s the working code:

main.py :

    from fastapi import FastAPI, Request
    from fastapi.responses import HTMLResponse
    from fastapi.templating import Jinja2Templates
    import os
    
    app = FastAPI()
    
    templates = Jinja2Templates(directory="templates")
    
    @app.get("/", response_class=HTMLResponse)
    def print_files(request: Request):
        proj_dir = "D:\Project_Dir/"
        dir_files = os.listdir(proj_dir)
        dir_files.sort()
        dir_files = dir_files[:20]
        # Create a dictionary
        data = {"p_name": "File Listing", "file_names": dir_files}
        return templates.TemplateResponse("file_listing.html", {"request": request, "data": data})

file_listing.html :

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>code_listing</title>
    </head>
    
    <body>
    <h1>List of files with comments</h1>
    <h2>Name: {{ data.get('p_name') }} </h2>
        {% for line in data.get("file_names") %}
            <p>{{ line }}</p>
        {% endfor %}
    </body>
    </html>

So the html file references the p_name and file_names from the dictionary.

Thanks again for the helpful comments.

Bastien B
  • 1,018
  • 8
  • 25
RTC222
  • 2,025
  • 1
  • 20
  • 53