Azure Functions – Mais agilidade, menos complexidade

Num cenário em que as exigências tecnológicas crescem de forma contínua, as organizações procuram soluções simples, eficientes e adaptáveis para responder a novos desafios.

É precisamente aqui que entram as Azure Functions: uma solução de computação serverless do Microsoft Azure que permite executar blocos de código de forma simples, escalável e sem a necessidade de gerir servidores ou infraestrutura.

Onde é que as Azure Functions podem realmente fazer a diferença?

As Azure Functions destacam-se por reduzirem a complexidade ao eliminar a necessidade de gerir servidores, uma vez que toda a infraestrutura é gerida automaticamente pelo Azure. As Azure Functions permitem desenvolver aplicações ou micro-serviços leves, modulares e escaláveis, tendo por base eventos como pedidos HTTP, alterações em bases de dados, mensagens em filas de espera ou tarefas agendadas. Além disso, permitem a integração com outros serviços do ecossistema Azure e com APIs externas suportando várias linguagens de programação como C#, JavaScript e Python, facilitando assim a adaptação por parte das equipas de desenvolvimento.

Python e Azure Functions: A Parceria Ideal para Soluções Inovadoras

No contexto do desenvolvimento das Azure Functions recorrendo-se à programação em Python, o código é criado localmente com ferramentas como Visual Studio Code, PyCharm ou através do terminal (através das Azure Functions Core Tools), sendo posteriormente publicado na cloud da Azure.

A integração nativa com plataformas como GitHub, Azure DevOps ou GitLab assegura um fluxo contínuo de desenvolvimento, testes e publicação. A utilização de pipelines de CI/CD (processos que integram, testam e entregam código de forma contínua) facilita a automatização de tarefas essenciais, desde a verificação até à publicação das versões atualizadas, garantindo assim maior consistência e rapidez.

Paralelamente, o Azure recolhe logs e métricas em tempo real, fornecendo visibilidade total sobre o comportamento das funções, o que simplifica significativamente a monitorização e o diagnóstico de problemas.

Estruturas de programação em Azure Functions

Modelo v1 vs. Modelo v2

O desenvolvimento de Azure Functions em Python pode seguir dois modelos principais: o v1 e o v2. O modelo v1, mais antigo, é baseado no .NET Framework, uma tecnologia dependente do sistema operativo Windows, e recorre fortemente a ficheiros de configuração externos, como o function.json resultando numa menor integração entre configuração e código.

Por outro lado, o modelo v2 apresenta uma abordagem mais moderna e centrada no código, permitindo definir funções diretamente através de métodos “main”. Esta evolução simplifica a estrutura dos projetos e proporciona uma melhor experiência de desenvolvimento. A escolha entre os dois modelos deve ter em consideração fatores como a complexidade da aplicação, o grau de personalização necessário e a preferência por uma abordagem mais declarativa (v1) ou mais orientada ao código (v2).

Modelo v1

No Modelo v1, cada função é implementada numa pasta própria, contendo dois ficheiros principais: o ficheiro __init.py__, onde está escrita a lógica da função em Python, e o ficheiro function.json, que define a configuração da função, nomeadamente os triggers and bindings.

Segue-se uma estrutura típica de um projeto com o Modelo v1:

MyFunctionApp/
│── host.json
│── local.settings.json
│
├── HttpTriggerFunction/
│   ├── __init__.py
│   └── function.json
│
└── XXXXXXXXFunction2/
    ├── __init__.py
    └── function.json

O exemplo seguinte ilustra como implementar uma função HTTP simples no Modelo v1, apresentando de forma clara a implementação do código nos ficheiros __init.py__ and function.json.

Este modelo é particularmente útil em protótipos ou projetos de pequena dimensão, permitindo um desenvolvimento rápido e simples, sobretudo quando a equipa de desenvolvimento é reduzida e a estrutura do código não exige uma modularização complexa.

Contudo, à medida que a complexidade do projeto aumenta, ou seja, com múltiplas funções, lógica partilhada e testes automáticos, o Modelo v1 pode revelar-se limitado. Nesses casos, recomenda-se a utilização o Modelo v2, que oferece uma arquitetura modular e escalável.

Modelo v2

O segundo modelo surge como uma versão melhorada do Modelo v1 de forma a colmatar a insuficiência desta primeira versão do modelo face ao crescimento da complexidade dos projetos. Esta segunda versão simplifica a criação de funções, permitindo que múltiplas funções coexistam num único ficheiro Python. Neste modelo, os triggers and bindings são declarados diretamente no código através de decorators, eliminando a necessidade de ficheiros como function.json separados para cada função. Esta abordagem torna o projeto mais organizado e o código mais legível, facilitando a manutenção do mesmo. É possível observar no exemplo que se segue da estrutura do projeto, que todo o código é implementado no ficheiro function_app.py:


MyFunctionApp/
│── host.json
│── local.settings.json
│── function_app.py
│── requirements.txt

No exemplo seguinte, a função acionada por um Timer Trigger é definida através de um decorator, que especifica a sua agenda de execução. Dentro da função main, implementa-se a lógica que será executada sempre que o trigger dispara.

Utiliza-se logging.info() para registar mensagens nos logs, uma prática fundamental em aplicações serverless, onde não existe uma interface direta para ver o output. Os logs permitem monitorizar a execução, detetar erros e manter informações de auditoria. Neste caso, cada disparo do Timer Trigger regista a mensagem “Hello World! A função Timer Trigger foi executada.”, confirmando que a função correu corretamente.


import azure.functions as func
import logging

# Criar a Function App (obrigatório no V2)
app = func.FunctionApp()

# Função Timer Trigger no Modelo V2
# Executa a cada 5 minutos
@app.timer_trigger(schedule="0 */5 * * * *", arg_name="mytimer")
def timer_main(mytimer: func.TimerRequest) -> None:
    """
    Função Timer Trigger que escreve 'Hello World' nos logs a cada 5 minutos.
    """
    logging.info("Hello World! A função Timer Trigger foi executada.")

Caso tenha por objetivo adicionar uma função, por exemplo, com HTTP Trigger, a seguir é possível observar como seria a implementação da mesma:


import azure.functions as func
import logging

app = func.FunctionApp()

# Função Timer Trigger que executa a cada 5 minutos
@app.timer_trigger(schedule="0 */5 * * * *", arg_name="mytimer")
def timer_main(mytimer: func.TimerRequest) -> None:
    logging.info("Hello World! Timer Trigger executada.")

# Função HTTP Trigger que responde a pedidos HTTP (GET/POST)
@app.route(route="hello", methods=["GET", "POST"])
def http_main(req: func.HttpRequest) -> func.HttpResponse:
    name = req.params.get("name")
    if not name:
        try:
            body = req.get_json()
            if isinstance(body, dict):
                name = body.get("name")
        except ValueError:
            name = None

    if name:
        return func.HttpResponse(f"Olá, {name}!", status_code=200)

    return func.HttpResponse(
        "Por favor, envia o parâmetro 'name' na query ou no corpo.",
        status_code=400,
    )

Como é possível analisar, as duas funções são definidas no mesmo ficheiro, sendo cada uma independente e acionada pelo runtime conforme o trigger especificado. A função timer_main é executada automaticamente a cada 5 minutos, registando uma mensagem nos logs, enquanto a função http_main responde a pedidos HTTP, permitindo receber opcionalmente um parâmetro name para personalizar a resposta. Esta abordagem simplifica a organização do código e mostra como múltiplas funções podem coexistir num único ficheiro sem necessidade de um main central.

Blueprint

No Modelo V2 das Azure Functions em Python, os blueprints constituem uma forma de modularizar e organizar funções fora do núcleo da aplicação. Um blueprint é uma classe que permite o registo independente das funções, sendo posteriormente associado à aplicação principal para que o runtime as reconheça.

Os principais benefícios dos blueprints incluem:

  • Divisão da aplicação em componentes modulares, permitindo distribuir funções por vários ficheiros Python.
  • Criação de interfaces públicas extensíveis, possibilitando a reutilização de APIs e de lógica comum.
  • Organização do código facilitada, tornando-o mais limpo e fácil de manter.

Segue-se uma representação da estrutura de uma Azure Function desenvolvida com Blueprints.

<project_root>/
│
├── function_app.py          # Regista os blueprints
├── http_blueprint.py       # Blueprint com funções HTTP
├── outro_blueprint.py      # Outro módulo com funções específicas
├── host.json
├── local.settings.json
├── requirements.txt
├── .funcignore

A seguir está representado um Blueprint simples, que contém uma função HTTP que responde a pedidos de rota ‘/hello’.

http_blueprint.py

import azure.functions as func

bp = func.Blueprint()

@bp.route(route="hello")
def hello(req: func.HttpRequest) -> func.HttpResponse:
    user = req.params.get("user")
    return func.HttpResponse(f"Olá, {user or 'mundo'}!")

Aquando da definição do Blueprint, é necessário registá-lo na aplicação principal para que as rotas fiquem acessíveis pelo Azure Functions runtime. O exemplo seguinte mostra como importar o módulo onde o Blueprint está definido e registar as funções associadas ao mesmo numa instância da FunctionApp.

function_app.py

import azure.functions as func
from http_blueprint import bp

app = func.FunctionApp()
app.register_functions(bp)

O Modelo v2 é mais utilizado em projetos com múltiplas funções e complexidade crescente. É um modelo que traz vantagens especialmente para equipas maiores que precisam de trabalhar em paralelo e de organizar o código de forma clara e modular. Este modelo é também recomendado para aplicações que exigem escalabilidade e facilidade de manutenção, permitindo separar funcionalidades e responsabilidades em módulos distintos.

O Equilíbrio entre Azure Functions e Python: Vantagens e Desafios

É fundamental compreender as vantagens e limitações inerentes tanto à utilização das Azure Functions como à sua implementação em Python, de modo a possibilitar uma tomada de decisão informada e adequada aos requisitos técnicos do projeto.

Modelos de Pagamento

A Azure Functions disponibiliza dois modelos de pagamento do tipo “Pay As You Go”: o Consumption Plan, que é o modelo original, e o mais recente Flex Consumption Plan.

No Consumption Plan, o utilizador paga apenas pelo tempo de execução e pelo número total de execuções das funções, beneficiando de uma oferta gratuita mensal de 1 milhão de execuções and 400.000 GB-segundos. Este plano tem um limite de 1,5 GB de memória por instância e o tempo máximo de execução por função é, por defeito, de 5 minutos, podendo ser aumentado até 10 minutos através de configuração.

Por outro lado, o Flex Consumption Plan, embora ligeiramente mais caro, oferece funcionalidades adicionais como instâncias sempre prontas (Always Ready), maior flexibilidade na configuração da memória e integração com redes virtuais (VNET), sendo o plano recomendado pela Microsoft para cenários que exigem melhor desempenho e maior controlo sobre os recursos.

Na B2F foram desenvolvidos projetos que demonstram o valor desta abordagem, evidenciando não só o seu desempenho robusto e a flexibilidade intrínseca, como a capacidade de integrar, de forma simples e segura, inúmeras plataformas externas, nomeadamente através de REST APIs, para a execução de processos ETL (Extract, Transform and Load).

Esta integração fluída permitiu automatizar tarefas, interligar sistemas heterogéneos e impulsionar a transformação digital de forma escalável, contribuindo de forma significativa para a redução dos custos operacionais.

Investir em Azure Functions representa, assim, um passo decisivo para empresas que pretendem não apenas manter a competitividade, mas também ganhar agilidade operacional, reduzir custos com infraestruturas subutilizadas e acelerar o ciclo de inovação, transformando ideias em serviços escaláveis de forma rápida e eficiente.

Este é o momento ideal para aproveitar todo o potencial das Azure Functions, contando com a Business to Future como parceiro estratégico na transformação digital.

Ready to define a successful future?

Get in touch

Francisca Duarte

Business Intelligence Consultant
Share the Post

Related Posts

Business Intelligence

Power BI Modeling MCP: Moving from Intention to Modeling with Natural Language

11 Dec 2025

João Conde Pereira

João Conde Pereira

Head of Business Intelligence

Business Intelligence

Microsoft Copilot Studio

30 Oct 2025

Bruno Maranhão

Business Intelligence Consultant

Ready to define a successful future?

Get in touch

B2F Team
shape

Pedido de Contacto

Don't hesitate and get in touch with us.