Pesquisa de site

Como criar páginas da Web dinâmicas com modelos Jinja em FastAPI


Os modelos Jinja oferecem uma linguagem poderosa que você pode usar para criar páginas da web dinâmicas com facilidade.

A integração do Jinja com FastAPI permite criar páginas da web dinâmicas que combinam perfeitamente o código Python com HTML, permitindo separar a camada de apresentação do seu aplicativo da camada lógica. Com páginas da web dinâmicas, você pode gerar conteúdo personalizado e baseado em dados, melhorando a experiência do usuário.

O que é Jinja?

Jinja é um mecanismo de modelo robusto e rico em recursos para Python que gera páginas da web dinâmicas. Jinja Templating oferece suporte a herança, instruções condicionais, loops e vários recursos que simplificam a criação de páginas da web dinâmicas.

Você pode combinar FastAPI e Jinja para criar páginas da web com um layout consistente que pode exibir dados em tempo real e lidar com entradas do usuário. Você também pode conseguir a separação de interesses, tornando seu código mais fácil de manter e entender.

Configure um projeto FastAPI

Para começar, você precisará configurar um projeto FastAPI.

  1. Crie e ative um ambiente virtual usando estes comandos de terminal:

    python -m venv env
    # On Unix/MacOS: 
    source venv/bin/activate
    # On Windows:
    .\venv\Scripts\activate
    
  2. Instale FastAPI e as dependências necessárias.

    pip install "fastapi[all]"
    
  3. Crie um diretório de projeto meu_blog.
  4. Crie um arquivo Python main.py no diretório do seu projeto.
  5. Adicione o seguinte código ao arquivo main.py:

    from fastapi import FastAPI
    fake_posts_db = [{
        'title': 'First Blog Post',
        'content': 'Content of the first blog post.',
        'author': 'John Doe',
        'publication_date': '2023-06-20',
        'comments': [
            {'author': 'Alice', 'content': 'Great post!'},
            {'author': 'Bob', 'content': 'Intresting read.'}
        ],
        'status': 'published'
    },{
        'title': 'Second Blog Post',
        'content': 'Content of the second blog post.',
        'author': 'Jane Smith',
        'publication_date': None,
        'comments': [],
        'status': 'draft'
    }]
    app = FastAPI()
    @app.get("/about")
    def about():
        return "All you need to know about Simple Blog"
  6. Execute o servidor.

    uvicorn main:app --reload
    

Visite http://localhost:8000/about no seu navegador para ver a resposta do servidor.

Integrando modelos Jinja

Depois de configurar seu projeto com sucesso, agora você pode adicionar modelos Jinja a ele.

  1. No arquivo main.py, importe os seguintes módulos:

    from fastapi.templating import Jinja2Templates
      from fastapi.staticfiles import StaticFiles
    
  2. Abaixo da variável app, crie uma instância da classe Jinja2Templates e passe o diretório que conterá seus templates.

    templates = Jinja2Templates(directory="templates")
    
  3. Após a variável templates, adicione a seguinte linha de código:

    app.mount("/static", StaticFiles(directory="static"), name="static")
    
  4. No diretório meu_blog crie dois diretórios, modelos para armazenar arquivos HTML e estático que conterá todos os arquivos estáticos.

Com essas etapas concluídas, você integrou com sucesso o Jinja Templating ao seu projeto.

Criando uma página da Web dinâmica com Jinja

Jinja fornece um rico conjunto de sintaxe e recursos para criar modelos dinâmicos.

Nesta seção, você verá como usar a sintaxe de modelo Jinja para criar páginas da web dinâmicas.

Tags de modelo

Coloque as tags de modelo entre chaves e símbolo de porcentagem em ambos os lados. Você pode usar essas tags para executar fluxo de controle e operações lógicas no modelo. Algumas tags de modelo comumente usadas incluem:

  • Condição: executa o bloco de código se a condição for verdadeira.

    {% if condition %}...{% endif %}
    
  • Loop: Itera sobre um iterável e executa o bloco de código para cada item.

    {% for item in iterable %}...{% endfor %}
    
  • Incluir: Inclui outro modelo dentro do modelo atual.

    {% include 'template_name.html' %}
    
  • Bloco: define um bloco que os modelos filhos podem substituir usando herança.

    {% block block_name %}...{% endblock %}
    
  • Estender: permite que o modelo filho herde e estenda o modelo pai.

    {% extend parent_temp.html %}
    

Essas tags fornecem uma maneira flexível e expressiva de gerar conteúdo HTML baseado em dados dinâmicos e controlar a lógica de sua aplicação.

Herança de modelo

Jinja Templating oferece suporte à herança de modelos. Isso permite definir um modelo base (pai) com um layout comum e seções que um modelo filho pode estender ou substituir. Um modelo filho pode usar a tag Extend para herdar e estender o modelo pai.

Crie um arquivo base.html no diretório templates com o código a seguir.

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}Simple Blog{% endblock %}</title>
</head>
<body>
    <h1>{% block heading %}Simple Blog{% endblock %}</h1>
    {% block content %}
    {% endblock %}
    {% include "footer.html" %}
</body>
</html>

Dessa forma, você tem um modelo pai que contém o código comum para todos os seus modelos, permitindo que o modelo filho o herde e estenda conforme necessário.

No diretório templates crie um arquivo footer.html com o seguinte código.

<footer>
    <p>&copy; 2023 Simple Blog. All rights reserved.</p>
    <a href="{{ url_for('about') }}">About</a>
</footer>

footer.html é um modelo incluído que contém o código HTML para a seção de rodapé. Você pode reutilizá-lo em várias páginas incluindo-o no modelo base usando a tag Incluir.

No diretório templates crie um arquivo blog.html com o seguinte código.

{% extends "base.html" %}
{% block title %}Simple Blog - Blog Page{% endblock %}
{% block heading %}Simple Blog - Blog Page{% endblock %}
{% block content %}
    <h2>Total Number of Posts: {{ posts|length }}</h2>
    {% for post in posts %}
        <div class="post">
            {% if post.status == 'published' %}
                <h3>{{ post.title }}</h3>
                <p>{{ post.content|truncate }}</p>
                <p>Published on: {{ post.publication_date }}</p>
                <h4>Comments:</h4>
                <ul>
                    {% for comment in post.comments %}
                        <li class="comment">{{ comment.author }}-: {{ comment.content }}</li>
                        
                    {% endfor %}
                </ul>
            {% else %}
                <p>This post is still in draft mode.</p>
            {% endif %}
        </div>
        <hr>
    {% endfor %}
{% endblock %}

Este modelo filho herda de base.html usando a tag Extend. Ele substitui blocos específicos definidos no modelo base para fornecer conteúdo personalizado para a página do blog. Também inclui a lógica e a iteração necessárias para exibir uma postagem e comentários associados.

Expressões

Jinja oferece suporte a uma ampla variedade de expressões, incluindo operações aritméticas, comparações e operações lógicas. Por exemplo:

{{2 + 2}} // output: 4

Substituição de Variável

Para gerar variáveis no modelo, coloque-as entre chaves duplas. Por exemplo:

{{post.title}} // output: 'First Blog Post'

Filtros

Os filtros modificam a saída de uma variável. Você pode adicionar um após uma variável usando o símbolo de barra vertical (|). Por exemplo:

{{post|length}} // output: 2

Comentários

Você pode adicionar comentários embutidos e comentários multilinhas em seus modelos. Jinja irá ignorar esses comentários durante a renderização do modelo, portanto eles são úteis para adicionar explicações dentro de um modelo.

{# #} // inline
{% comment %} ... {% end comment %} // multiline

URLs

Para permitir que você gere hiperlinks corretos para outras páginas do aplicativo, o contexto do modelo Jinja inclui uma função url_for. Por exemplo:

<a href="{{ url_for('about') }}">About</a>

O código acima se torna http://localhost:8000/about. Você também verá como usar a função url_for para obter caminhos de arquivos estáticos posteriormente.

Estes são apenas alguns dos aspectos fundamentais da sintaxe do Jinja Templating. Jinja Templating oferece muitos mais recursos e funcionalidades, como macros, contexto de modelo e muito mais, para tornar a criação e personalização de modelos eficiente e flexível.

Passando dados para modelos

Agora que você tem seus modelos prontos, você precisa passar os dados dos seus endpoints FastAPI para os modelos para renderização.

Adicione o seguinte código ao arquivo main.py:

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
@app.get("/", response_class=HTMLResponse)
async def read_posts(request: Request):
    return templates.TemplateResponse("blog.html", {"request": request, 
                                                    "posts": fake_posts_db})

O código define um endpoint FastAPI que trata uma solicitação GET para o URL raiz ("/") e retorna um HTMLResponse gerado a partir do modelo blog.html. Ele passa um dicionário de contexto, contendo o objeto de solicitação atual e o fake_posts_db, para o modelo. Dessa forma, o Jinja pode renderizar dados precisos e dinâmicos.

Visite http://localhost:8000/ no seu navegador e você verá algo assim:

Você transmitiu dados com sucesso para os modelos para renderização.

Servindo arquivos estáticos

Além de renderizar modelos dinâmicos, FastAPI também fornece funcionalidade para servir arquivos estáticos, como arquivos CSS, arquivos JavaScript e imagens.

Você usará CSS para melhorar a aparência da página.

No diretório static, crie um arquivo styles.css com o código a seguir.

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: #f5f5f5;
}
h1, h2, h3, h4 {
    color: #333;
}
.post {
    background-color: #fff;
    padding: 20px;
    margin-bottom: 20px;
    border-radius: 5px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.post h3 {
    margin-top: 0;
}
.post p {
    margin-bottom: 10px;
}
.post ul {
    list-style-type: none;
    padding-left: 0;
}
.comment {
    margin-bottom: 10px;
    padding: 10px;
    background-color: #f9f9f9;
    border-radius: 5px;
}
footer {
    background-color: #f2f2f2;
    padding: 10px;
    text-align: center;
}

Modifique o elemento head do modelo base.html da seguinte maneira:

<head>
    <title>{% block title %}Simple Blog{% endblock %}</title>
    <link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
</head>

A função url_for() gera uma URL (caminho) para o arquivo styles.css (/static/styles.css) no diretório static que é então servido automaticamente pelo FastAPI .

Visite http://localhost:8000/ no seu navegador.

Os mesmos procedimentos se aplicam à veiculação de arquivos de imagem e JavaScript.

Lembre-se de seguir as melhores práticas

Ao trabalhar com Jinja Templating no FastAPI, é importante seguir algumas práticas recomendadas para garantir uma base de código bem organizada e eficiente.

  • Organize os modelos em um diretório dedicado e considere usar subdiretórios para modelos relacionados.
  • Utilize a herança de modelos para criar modelos básicos reutilizáveis e estendê-los para conteúdo específico.
  • Selecione cuidadosamente os dados a serem transmitidos aos modelos, mantendo a carga útil leve, e use processadores de contexto ou middleware para dados comumente usados.
  • Faça uso dos recursos do Jinja Templating, como macros, filtros e estruturas de controle para melhorar a reutilização e legibilidade do código.
  • Otimize o desempenho implementando estratégias de cache para modelos estáticos, usando cabeçalhos de cache HTTP e criando perfis para gargalos de desempenho.

Seguindo essas práticas recomendadas, você pode manter um projeto estruturado, otimizar o desempenho de renderização e aproveitar com eficiência os recursos do Jinja Templating em seus aplicativos FastAPI.

Usando FastAPI para construir RestAPIs

Além de construir aplicativos que requerem modelos de renderização. FastAPI se destaca na construção de RestAPIs devido ao seu alto desempenho, sintaxe fácil de usar, geração automática de documentação e escalabilidade. Esses recursos tornam o FastAPI ideal para o desenvolvimento eficiente de APIs web robustas.

Artigos relacionados: