3

I have a FastAPI app with some routes working fine if I move around them manually (i.e., by changing the /<path> in the browser's address bar). For example, this is one of them:

@task.get('/tasks', response_model=list[Task], tags=["Tasks"])
def find_all_tasks():
    print("\n[*] Showing all Tasks\n")
    return tasksEntity(conn.local.task.find())

My /<root> route loads an index.html file that displays a button. What I want to do is whenever I click the button to have the above route added to the url (e.g., http://127.0.0.1/tasks).

I use Jinja2Templates to render data in the HTML from different routes of the API, but I dont know how to move around them from the frontend HTML buttons.

Chris
  • 18,724
  • 6
  • 46
  • 80
lazlomeli
  • 61
  • 7

2 Answers2

3

Backend

Your /tasks endpoint (i.e., find_all_tasks function) should return a new Jinja2 TemplateResponse with the list of tasks. For instance:

@app.get('/tasks')
def find_all_tasks(request: Request):
    tasks = ['task 1', 'task 2', 'task 3']
    return templates.TemplateResponse("tasks.html", {"request": request, 'tasks': tasks})

Frontend

1. Click on the URL to get to the tasks page

In index.html, you can use the url_for() function to get the URL for an endpoint and allow the user to click on it, for example:

<a href="{{ url_for('find_all_tasks') }}">Click me</a>

or

<form action="{{ url_for('find_all_tasks') }}">  
   <button>Click me</button>  
</form>

or

<button onclick="location.href='{{ url_for('find_all_tasks') }}';">Click me</button>

or

<input type="button" onclick="location.href='{{ url_for('find_all_tasks') }}';" value="Click me"/>

Alternatively, you can use relative paths, as described here and here, passing the name of the route and any required path/query parameters. For example:

<a href="/tasks">Click me</a>

If your endpoint contains path and/or query parameters, please have a look at this answer and this answer on how to include those as well.

2. Display tasks

In tasks.html template, you can loop through and output the tasks inside braces, as shown in this answer and below:

<!DOCTYPE html>
<html>
    <body>
        {% for task in tasks %}
            <tr>
                <td>{{ task }}</td><br>
            </tr>
        {% endfor %}
    </body>
</html>
Chris
  • 18,724
  • 6
  • 46
  • 80
0

As per this answer you can use app.url_path_for('find_all_tasks') to get the url of your route. You can pass this as a parameter to Jinja and then in your temlate you want something like

<form action="{{ find_all_tasks_route }}">
    <input type="submit" value="Go to all tasks" />
</form>

( taken here )

where find_all_tasks_route was the parameter you passed to the renderer.

Taek
  • 1,004
  • 7
  • 20