Cómo desplegar una función de Azure Functions con FastAPI y GitHub

  • Imagen de redactor Daniel J. Saldaña
  • 2 de agosto de 2024
Cómo desplegar una función de Azure Functions con FastAPI y GitHub

En este post, te explicaré cómo crear y desplegar una función de Azure Functions manualmente utilizando FastAPI y cómo integrar el proceso de creación con un repositorio de código de GitHub.

Paso 1: Configuración inicial de Azure Functions

  1. Crea una cuenta de Azure: Si no tienes una cuenta de Azure, puedes crear una en azure.com.

  2. Instala las herramientas de Azure:

Paso 2: Crear una función de Azure Functions desde el portal de Azure

  1. Inicia sesión en el Portal de Azure.

  2. Crea un nuevo recurso de Azure Functions:

    • Navega a “Crear un recurso” y busca “Function App”.
    • Haz clic en “Crear”.
  3. Configura la aplicación de funciones:

    • Detalles del proyecto: Selecciona tu suscripción y crea un nuevo grupo de recursos si no tienes uno.
    • Detalles de la instancia: Proporciona un nombre único para tu aplicación de funciones.
    • Publicación: Selecciona “Código”.
    • Pila de tiempo de ejecución: Selecciona “Python” y la versión que prefieras.
    • Región: Selecciona la región más cercana a ti o la que prefieras.
  4. Configuración del hosting:

    • Selecciona un plan de hosting y configuración del almacenamiento.
    • Configura las opciones de red si es necesario.
  5. Configuración de supervisión:

    • Configura Application Insights si deseas monitorear el rendimiento de tu función.
  6. Configuración de implementación continua:

    • Habilita la configuración de implementación continua para desplegar el código desde GitHub utilizando GitHub Actions.

Paso 3: Configurar la implementación continua desde GitHub

  1. Configuración de GitHub:

    • Cuenta de GitHub: Conecta tu cuenta de GitHub.
    • Organización: Selecciona la organización.
    • Repositorio: Selecciona el repositorio donde se encuentra tu código.
    • Rama: Selecciona la rama desde la cual deseas desplegar.
  2. Configuración del flujo de trabajo:

    • Haz clic en el botón para obtener una vista previa del archivo de flujo de trabajo de GitHub Actions.
    • Asegúrate de que el flujo de trabajo se vea correcto y luego confirma la configuración.
  3. Configuración de autenticación:

    • Autenticación básica: Puedes habilitar o deshabilitar la autenticación básica según tus necesidades.

Paso 4: Integrar FastAPI con Azure Functions

  1. Código de FastAPI: Asegúrate de que tu archivo main.py contenga el siguiente código:
__init__.py
import azure.functions as func
from typing import Any, List, Union, Optional
from fastapi import FastAPI, Body
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field
app = FastAPI()
app.title = "API de Daniel J. Saldaña"
app.version = "0.0.1"
class ExampleUpdateRequest(BaseModel):
date: int
class Education(BaseModel):
name: str
description: Union[str, None] = None
score: float = Field(description="Calificación obtenida", ge=0, le=10)
education = {
"1": {"name": "Experto Universitario en Cloud Computing. Arquitecturas y Soluciones (AWS y Azure)", "description": "La Unir", "score": 9.0},
"2": {"name": "Experto Universitario en Devops & Cloud", "description": "La Unir", "score": 9.0},
}
class Experience(BaseModel):
name: str
description: Union[str, None] = None
time: Union[str, None] = None
experience = {
"5": {"name": "Software Arquitect", "description": "Toma decisiones de diseño de alto nivel y dicta estándares técnicos 📋, incluyendo estándares de codificación de software, herramientas y plataformas. Dirijo el diseño y desarrollo de la arquitectura tecnológica de un sistema 🏗️, aplicación o plataforma. Para ello, me encargo de seleccionar el software adecuado para cada función, vigilar la implementación y coordinar la resolución de los problemas técnicos que puedan surgir, planificando técnicamente cada paso a seguir en la construcción de esa arquitectura 💬.", "time": "📆 2022 - Actualidad"},
"4": {"name": "Site Reliability Engineering", "description": "Automatización de tareas operativas, creación de pipeline 🚀, diseño level design para garantizar la disponibilidad de las aplicaciones 🏗️, explotación de métricas e identificar, diagnosticar y resolver los problemas de aplicaciones 🧪.", "time": "📆 2022 - 2022"},
"3": {"name": "DevOps Engineer", "description": "Desarrollo automatizaciones en la solución CI/CD interna 🔧. Cooperación con los equipos de Arquitectura en la fase de design thinking así como en las distintas fases de desarrollo de evolutivo 🗒️. Miembro del equipo de estrategia del Dominio de Ingeniera para definir nuevos procedimientos y modelos de trabajo ✍️.", "time": "📆 2020 - 2022"},
"2": {"name": "SysAdmin Linux", "description": "Resolución de incidencias 🔴, automatización de procedimientos, creación y configuración de máquinas virtuales 🖥️, gestión de todo la infraestructura interna de la organización 🧮.", "time": "📆 2020 - 2020"},
"1": {"name": "SysAdmin Linux/Windows", "description": "Intervenciones en máquinas físicas y virtuales y entornos de servidores compartidos ☁️, gestión en clusters de correo ✉️, implementación de reglas de seguridad 🔐.", "time": "📆 2016 - 2019"},
}
class Certifications(BaseModel):
id: Optional[int] = None
name: str
description: Union[str, None] = None
provider: Union[str, None] = None
validity: Union[str, None] = None
certifications = {
"1": {"name": "Microsoft Certified: Azure Network Engineer Associate", "description": "Earning Azure Network Engineer Associate validates skills and subject matter expertise in planning, implementing, and maintaining Azure networking solutions, including hybrid networking, connectivity, routing, security, and private access to Azure services. Professionals in this role deploy networking solutions using Azure Portal and other methods, including PowerShell, Azure Command-Line Interface (CLI), and Azure Resource Manager templates (ARM templates).", "provider": "Microsoft", "validity": "📆 2023 - 2024"},
"2": {"name": "AWS Cloud Quest: Cloud Practitioner", "description": "Earners of this badge have demonstrated basic solution building knowledge using AWS services and have a fundamental understanding of AWS Cloud concepts. Badge earners have acquired hands-on experience with compute, networking, database and security services.", "provider": "AWS", "validity": "📆 Does not expire"},
}
@app.get("/hello-world/{date}", tags=["Example"], response_model=dict)
async def get_hello_world(date: int) -> dict:
return {"message": f"Soy Goliat y tengo {date} años."}
@app.put("/hello-world/{date}", tags=["Example"], response_model=dict)
async def update_hello_world(date: int, request: ExampleUpdateRequest) -> dict:
return {"message": f"Hola {request.date}, bienvenido a mi API."}
@app.post("/hello-world", tags=["Example"], response_model=dict)
async def create_hello_world(name: str = "Goliat") -> dict:
return {"message": f"¡Hola {name}!"}
@app.get("/", tags=["Home"], response_model=dict)
def get_index() -> dict:
return JSONResponse(content="Bienvenidos a la API de Daniel J. Saldaña")
@app.get("/aboutme", tags=["About me"], response_model=dict)
def get_aboutme() -> dict:
return JSONResponse(content="Soy Cloud Arquitect🔥, con un background de DevOp,SRE,SysAdmin y especializado en provedores Cloud como AWS, Azure y GCP. Dispongo de un fuerte dominio de Arquitectura Cloud y Diseño de modelos de CI/CD. Vivo en Almería, España 🌍 tengo 30 años")
@app.get("/education", tags=["Education"], response_model=List[Education])
async def get_education() -> List[Education]:
return JSONResponse(content=education)
@app.get("/education/{id}", tags=["Education"], response_model=Education)
async def get_education_by_id(id: str) -> Education:
return JSONResponse(content=education[id])
@app.get("/experience", tags=["Experience"],response_model=List[Experience])
async def get_experience() -> List[Experience]:
return JSONResponse(content=experience)
@app.get("/experience/{id}", tags=["Experience"], response_model=Certifications)
async def get_experience_by_id(id: str) -> Certifications:
return JSONResponse(content=experience[id])
@app.get("/certifications", tags=["Certifications"], response_model=List[Certifications])
async def get_certifications() -> List[Certifications]:
return JSONResponse(content=certifications)
@app.get("/certifications/{id}", tags=["Certifications"], response_model=Certifications)
async def get_education_by_id(id: str) -> Certifications:
return JSONResponse(content=certifications[id])
@app.get("/certifications/", tags=["Certifications"], response_model=List[Certifications])
async def get_certifications_provider(provider: str) -> List[Certifications]:
result = []
for certification in certifications.values():
if certification["provider"] == provider:
result.append(certification)
return JSONResponse(content=result)
  1. Archivo function_app.py: Crea un archivo function_app.py con el siguiente contenido:

    function_app.py
    import azure.functions as func
    from WrapperFunction import app as fastapi_app
    app = func.AsgiFunctionApp(app=fastapi_app, http_auth_level=func.AuthLevel.ANONYMOUS)
  2. Estructura de archivos: Asegúrate de que tu proyecto tenga la siguiente estructura de archivos:

    .
    ├── WrapperFunction
    │ └── __init__.py
    ├── function_app.py
    ├── host.json
    └── requirements.txt
  3. Archivo host.json: Asegúrate de que tu archivo host.json tenga la siguiente configuración:

    host.json
    {
    "version": "2.0",
    "extensions": {
    "http": {
    "routePrefix": ""
    }
    }
    }
  4. Archivo requirements.txt: Asegúrate de que tu archivo requirements.txt incluya las dependencias necesarias:

    requirements.txt
    fastapi
    uvicorn[standard]
    pyJWT
    python-decouple
    pydantic[email]
    gunicorn
    azure-functions

Paso 5: Desplegar la función

Formulario interactivo

  1. Empuja el código a GitHub: Asegúrate de que todo tu código esté empujado a la rama seleccionada en GitHub.

  2. Verifica la implementación: GitHub Actions se encargará de desplegar automáticamente tu aplicación de funciones en Azure cada vez que realices cambios en el repositorio. Puedes monitorear el progreso desde la pestaña de Actions en tu repositorio de GitHub.

  3. Probar la función:

¡Y eso es todo! Ahora tienes una función de Azure Functions desplegada con FastAPI y GitHub Actions.

¡Suscríbete y recibe actualizaciones sobre tecnología, diseño, productividad, programación y mucho más!
0
0