- Introducción
- Instalación
- Hola Mundo
- Estructura del Proyecto
- Rutas y Vistas
- Plantillas Jinja2
- Formularios
- Manejo de Errores
- Archivos Estáticos
- Configuración
- Archivo
requirements.txt - Despliegue en Producción
- Autenticación y Autorización
- Bases de Datos
- API RESTful
- Gestión de Archivos
- Internacionalización y Localización (i18n & l10n)
- Despliegue y Escalabilidad
- Testing y Calidad del Código
- Optimización y Buenas Prácticas
Flask es un microframework para Python basado en Werkzeug y Jinja2. Está diseñado con una estructura simple pero extensible. Esta guía te ayudará a comenzar con Flask y te mostrará cómo desarrollar una aplicación web básica.
Primero, asegúrate de tener Python instalado. Puedes verificarlo ejecutando:
python --versionPara instalar Flask, usa pip:
pip install FlaskCrea un archivo llamado app.py y añade el siguiente código:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)Ejecuta tu aplicación:
python app.pyAhora, visita http://127.0.0.1:5000/ en tu navegador para ver tu aplicación en acción.
Es una buena práctica organizar tu proyecto Flask en una estructura clara y manejable. Aquí tienes un ejemplo:
my_flask_app/
│
├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── models.py
│ ├── templates/
│ │ └── index.html
│ └── static/
│ ├── css/
│ └── js/
│
├── venv/
├── config.py
├── requirements.txt
└── run.py
Las rutas son la forma en que defines las URL en tu aplicación Flask. Las vistas son las funciones que devuelven las respuestas a esas URL.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Home Page'
@app.route('/about')
def about():
return 'About Page'
if __name__ == '__main__':
app.run(debug=True)Jinja2 es un motor de plantillas moderno para Python. Flask usa Jinja2 para renderizar plantillas HTML.
Crea un archivo index.html en el directorio templates:
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ heading }}</h1>
<p>{{ content }}</p>
</body>
</html>En tu aplicación Flask, renderiza la plantilla:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html', title='Home', heading='Welcome', content='This is the home page.')
if __name__ == '__main__':
app.run(debug=True)Jinja2 permite usar estructuras de control de flujo como condicionales y bucles.
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ heading }}</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>@app.route('/')
def home():
items = ['Item 1', 'Item 2', 'Item 3']
return render_template('index.html', title='Home', heading='Welcome', items=items)Para manejar formularios en aplicaciones Flask, Flask-WTF es una excelente extensión que simplifica el proceso de validación y renderización de formularios HTML. Aquí hay una guía básica sobre cómo usar Flask-WTF para manejar formularios en tu aplicación Flask.
Para instalar Flask-WTF, simplemente ejecuta el siguiente comando en tu terminal:
pip install flask-wtfPrimero, necesitas importar las clases necesarias de Flask-WTF y configurar una clave secreta en tu aplicación Flask. Aquí tienes un ejemplo de cómo hacerlo:
from flask import Flask, render_template, flash, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secretkey'En este ejemplo, estamos importando FlaskForm de Flask-WTF para definir nuestro formulario y algunos campos de formulario (StringField y SubmitField) de WTForms. También estamos importando el validador DataRequired para asegurarnos de que se ingrese algún dato en el campo de nombre.
Luego, necesitas definir tu formulario como una clase que herede de FlaskForm. Aquí está cómo se vería en el ejemplo:
class MyForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
submit = SubmitField('Submit')En este formulario, estamos definiendo un campo de texto para el nombre y un botón de enviar. El validador DataRequired garantiza que el campo de nombre no esté vacío al enviar el formulario.
Ahora, necesitas definir una ruta para la página donde se renderizará el formulario y manejar la lógica de envío del formulario. Aquí tienes un ejemplo de cómo hacerlo:
@app.route('/', methods=['GET', 'POST'])
def index():
form = MyForm()
if form.validate_on_submit():
flash(f'Form submitted with name: {form.name.data}')
return redirect(url_for('index'))
return render_template('index.html', form=form)En esta función de vista, estamos creando una instancia del formulario MyForm. Si el formulario se envía y pasa la validación, mostramos un mensaje flash con el nombre ingresado y redirigimos al usuario de nuevo a la misma página. Si el formulario no se envía o no pasa la validación, simplemente renderizamos la plantilla index.html con el formulario.
Finalmente, necesitas crear una plantilla HTML para renderizar el formulario. Aquí está un ejemplo básico de cómo podría verse:
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Form Example</title>
</head>
<body>
<form method="POST" action="/">
{{ form.hidden_tag() }}
<p>
{{ form.name.label }}<br>
{{ form.name(size=32) }}<br>
{{ form.submit() }}
</p>
</form>
{% for message in get_flashed_messages() %}
<p>{{ message }}</p>
{% endfor %}
</body>
</html>En esta plantilla, estamos utilizando Jinja2 para renderizar el formulario y los mensajes flash. El método hidden_tag() se utiliza para incluir campos ocultos necesarios para protección CSRF.
- Descripción: El formulario básico es simple y común, consiste en campos de entrada de datos y un botón de enviar.
- Cómo usarlo: Úsalo para formularios simples que requieren pocos campos de entrada.
- Cuándo usarlo: Por ejemplo, un formulario de contacto con campos para nombre, correo electrónico y mensaje.
<form method="POST" action="/">
<input type="text" name="name" placeholder="Nombre">
<input type="email" name="email" placeholder="Correo Electrónico">
<textarea name="message" placeholder="Mensaje"></textarea>
<button type="submit">Enviar</button>
</form>- Descripción: Campos de entrada y etiquetas en la misma línea para un diseño compacto y horizontal.
- Cómo usarlo: A través de clases específicas para lograr la disposición horizontal.
- Cuándo usarlo: Útil para formularios con varios campos que necesitan ocupar menos espacio vertical.
<form class="form-horizontal" method="POST" action="/">
<div class="form-group">
<label class="control-label col-sm-2" for="name">Nombre:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" name="name" placeholder="Nombre">
</div>
</div>
<!-- Otros campos... -->
</form>- Descripción: Campos de entrada y etiquetas en la misma línea sin espacio entre ellos.
- Cómo usarlo: A través de clases específicas o estilos para reducir el espacio entre elementos.
- Cuándo usarlo: Para formularios simples donde se desea minimizar el espacio utilizado.
<form class="form-inline" method="POST" action="/">
<label class="sr-only" for="name">Nombre:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Nombre">
<!-- Otros campos... -->
</form>- Descripción: Campos de entrada agrupados en secciones lógicas con encabezados o títulos.
- Cómo usarlo: Mediante el uso de etiquetas HTML adicionales para agrupar los campos relacionados.
- Cuándo usarlo: En formularios largos o complejos con varios conjuntos de datos relacionados.
<form method="POST" action="/">
<fieldset>
<legend>Detalles Personales</legend>
<input type="text" name="first_name" placeholder="Nombre">
<input type="text" name="last_name" placeholder="Apellido">
</fieldset>
<!-- Otros grupos de campos... -->
</form>- Descripción: Altamente personalizable, te permite diseñar completamente el aspecto y la disposición del formulario.
- Cómo usarlo: Utilizando HTML y CSS para diseñar el formulario según tus necesidades.
- Cuándo usarlo: Cuando necesites un diseño único o funcionalidades personalizadas en tu formulario.
<form method="POST" action="/" class="custom-form">
<!-- Personaliza el diseño y los estilos según sea necesario -->
</form>La elección de la plantilla adecuada depende de tus necesidades específicas de diseño y funcionalidad. Experimenta con diferentes estilos y encuentra el que mejor se adapte a tu aplicación y preferencias.
Flask permite manejar errores personalizados usando decoradores.
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500Crea las plantillas 404.html y 500.html en el directorio templates.
Flask facilita el uso de archivos estáticos como CSS y JavaScript. Guarda tus archivos estáticos en el directorio static.
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Static Files</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h1>Static Files</h1>
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
</body>
</html>En una aplicación Flask, es común tener una serie de configuraciones que pueden variar según el entorno de desarrollo, pruebas o producción. Para manejar estas configuraciones de manera eficiente y organizada, Flask permite utilizar un archivo Python dedicado para definir todas las variables de configuración necesarias. Este archivo, comúnmente llamado config.py, proporciona un lugar centralizado para gestionar todas las configuraciones de la aplicación.
config.py es un archivo Python que contiene una clase de configuración para tu aplicación Flask. En esta clase, puedes definir todas las variables de configuración necesarias para tu aplicación, como claves secretas, URI de la base de datos, configuraciones de correo electrónico, entre otras.
En config.py, defines una clase llamada Config (o cualquier otro nombre descriptivo que prefieras) que contendrá todas las configuraciones necesarias para tu aplicación Flask. Aquí hay un ejemplo básico de cómo podría verse config.py:
# config.py
class Config:
"""
Clase de configuración base para la aplicación Flask.
"""
# Clave secreta para proteger tus datos
SECRET_KEY = 'your_secret_key'
# URI de la base de datos SQLite
SQLALCHEMY_DATABASE_URI = 'sqlite:///site.db'
# Configuraciones adicionales opcionales...En este ejemplo:
SECRET_KEY: Esta es una cadena aleatoria utilizada para cifrar sesiones y otros datos sensibles. Es importante mantenerlo seguro y único para tu aplicación.SQLALCHEMY_DATABASE_URI: Esta es la URI de la base de datos que Flask usará para conectarse a tu base de datos. En este caso, se está utilizando una base de datos SQLite, pero puedes cambiarla a cualquier otra base de datos compatible con SQLAlchemy.- Puedes añadir otras configuraciones opcionales según las necesidades de tu aplicación.
Para usar las configuraciones definidas en config.py en tu aplicación Flask, simplemente importa la clase Config y llama al método from_object en el objeto de la aplicación. Aquí hay un ejemplo de cómo hacerlo en tu archivo principal de la aplicación (app.py):
# app.py
from flask import Flask
from config import Config # Importa la clase de configuración desde config.py
app = Flask(__name__)
app.config.from_object(Config) # Carga la configuración desde la clase Config
# Resto del código de tu aplicación Flask...El archivo config.py puede incluir una variedad de configuraciones para adaptarse a las necesidades específicas de tu aplicación Flask. Aquí hay algunas otras configuraciones comunes que podrías incluir:
Puedes definir diferentes URIs de bases de datos para entornos de desarrollo, pruebas y producción:
class Config:
"""
Clase de configuración base para la aplicación Flask.
"""
# ...
# URI de la base de datos SQLite para desarrollo
SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db'
# Configuraciones adicionales opcionales...
class ProductionConfig(Config):
"""
Configuraciones específicas para el entorno de producción.
"""
# URI de la base de datos para producción
SQLALCHEMY_DATABASE_URI = 'postgresql://user:password@localhost/mydatabase'
# Otras configuraciones específicas para producción...Puedes configurar la duración de las sesiones y otras opciones relacionadas con la seguridad de la sesión:
class Config:
"""
Clase de configuración base para la aplicación Flask.
"""
# ...
# Duración de la sesión en segundos (por ejemplo, 30 minutos)
PERMANENT_SESSION_LIFETIME = 1800
# Nombre de la cookie de sesión
SESSION_COOKIE_NAME = 'session_cookie'
# Configuraciones adicionales opcionales...Si tu aplicación se ejecuta en un entorno de producción, es importante configurar HTTPS para proteger la comunicación entre el cliente y el servidor:
class Config:
"""
Clase de configuración base para la aplicación Flask.
"""
# ...
# Habilita HTTPS
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
# Configuraciones adicionales opcionales...Puedes configurar parámetros de servidor SMTP para enviar correos electrónicos desde tu aplicación:
class Config:
"""
Clase de configuración base para la aplicación Flask.
"""
# ...
# Configuración del servidor SMTP para enviar correos electrónicos
MAIL_SERVER = 'smtp.example.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = 'your_email@example.com'
MAIL_PASSWORD = 'your_email_password'
# Configuraciones adicionales opcionales...Puedes configurar CSP para mitigar ataques de inyección de contenido:
class Config:
"""
Clase de configuración base para la aplicación Flask.
"""
# ...
# Configuración de Content Security Policy (CSP)
CSP_POLICY = {
'default-src': "'self'",
'script-src': "'self' https://cdnjs.cloudflare.com",
'style-src': "'self' https://fonts.googleapis.com",
'font-src': "'self' https://fonts.gstatic.com",
'img-src': "'self' data:",
'object-src': "'none'",
}
# Configuraciones adicionales opcionales...Estas son solo algunas de las configuraciones comunes que puedes incluir en tu archivo config.py. Puedes ajustar y expandir estas configuraciones según las necesidades específicas de tu aplicación. Recuerda que la clave es mantener tu archivo config.py organizado y fácil de entender para facilitar la gestión de la configuración de tu aplicación Flask.
Para facilitar la instalación de dependencias en otros entornos, crea un archivo requirements.txt:
pip freeze > requirements.txtPara desplegar tu aplicación Flask en producción, usa un servidor de aplicaciones como Gunicorn.
pip install gunicorngunicorn -w 4 app:appLa autenticación y autorización son componentes fundamentales en el desarrollo de aplicaciones web seguras. Flask ofrece varias opciones para implementar estos componentes de manera efectiva, entre las que se destacan Flask-Login y JWT Authentication. A continuación, ampliaremos la información y teoría sobre ambas opciones:
Flask-Login es una extensión de Flask que gestiona la autenticación del usuario. Proporciona una forma sencilla de manejar la autenticación, el registro de usuarios y la gestión de sesiones de usuario de forma segura.
- Instalación: Se instala a través de pip:
pip install flask-login- Configuración Básica: Se inicializa y configura en la aplicación Flask:
from flask import Flask
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secretkey'
login_manager = LoginManager()
login_manager.init_app(app)
class User(UserMixin):
def __init__(self, id):
self.id = id
@login_manager.user_loader
def load_user(user_id):
return User(user_id)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
user_id = request.form.get('user_id')
user = User(user_id)
login_user(user)
return redirect(url_for('protected'))
return render_template('login.html')
@app.route('/protected')
@login_required
def protected():
return f'Logged in as: {current_user.id}'
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
if __name__ == '__main__':
app.run(debug=True)<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Login</title>
</head>
<body>
<form method="POST">
<label for="user_id">User ID:</label>
<input type="text" id="user_id" name="user_id" required>
<button type="submit">Login</button>
</form>
</body>
</html>JSON Web Token (JWT) es un estándar abierto que define una forma compacta y autónoma de transmitir información de forma segura entre dos partes. En el contexto de Flask, JWT se utiliza para la autenticación basada en tokens.
- Instalación: Se instala a través de pip:
pip install pyjwt- Configuración Básica: Se implementa la lógica de generación y verificación de tokens JWT en la aplicación Flask:
from flask import Flask, request, jsonify
import jwt
import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secretkey'
@app.route('/login', methods=['POST'])
def login():
auth = request.form
if auth and auth['username'] == 'user' and auth['password'] == 'pass':
token = jwt.encode({'user': auth['username'], 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)}, app.config['SECRET_KEY'])
return jsonify({'token': token})
return 'Unauthorized', 401
@app.route('/protected')
def protected():
token = request.headers.get('x-access-tokens')
if not token:
return 'Token is missing', 403
try:
data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"])
except:
return 'Token is invalid', 403
return f'Logged in as: {data["user"]}'
if __name__ == '__main__':
app.run(debug=True)- El cliente envía credenciales de inicio de sesión (nombre de usuario y contraseña) al servidor a través de una solicitud POST a
/login. - El servidor verifica las credenciales y, si son válidas, genera un token JWT con una duración de validez específica y lo devuelve al cliente.
- El cliente almacena el token JWT y lo incluye en las cabeceras de las solicitudes posteriores al servidor.
- El servidor valida el token JWT recibido en las solicitudes entrantes para asegurarse de que el usuario esté autenticado y autorizado.
La autenticación basada en tokens JWT es útil para aplicaciones RESTful y API, ya que elimina la necesidad de mantener sesiones de usuario en el servidor, lo que simplifica la gestión de la autenticación y la escalabilidad de la aplicación.
Flask, como framework web, ofrece una amplia gama de herramientas para trabajar con bases de datos de manera eficiente y organizada. Dos de las extensiones más populares para este propósito son SQLAlchemy y Flask-Migrate.
SQLAlchemy simplifica la interacción con bases de datos relacionales al proporcionar una capa de abstracción que permite a los desarrolladores trabajar con objetos Python en lugar de escribir sentencias SQL directas. Esto facilita la gestión de datos y la creación de modelos de manera más intuitiva y orientada a objetos.
Flask-Migrate es una extensión que facilita la administración de migraciones de base de datos en proyectos Flask que utilizan SQLAlchemy. Con Flask-Migrate, los desarrolladores pueden realizar cambios en la estructura de la base de datos de manera controlada y automatizada, lo que garantiza la integridad y la coherencia de los datos a lo largo del tiempo.
Al combinar SQLAlchemy para el mapeo objeto-relacional y Flask-Migrate para la gestión de migraciones, los desarrolladores pueden construir aplicaciones Flask robustas y escalables con una base de datos bien estructurada y mantenible.
SQLAlchemy es una biblioteca de mapeo objeto-relacional (ORM) para Python que facilita la interacción con bases de datos relacionales. Permite a los desarrolladores trabajar con bases de datos utilizando objetos Python en lugar de sentencias SQL directas.
- Instalación: Se instala a través de pip:
pip install flask-sqlalchemy- Configuración Básica: Se inicializa y configura en la aplicación Flask, estableciendo la URI de la base de datos y definiendo modelos de datos como clases:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
def __repr__(self):
return f'<User {self.username}>'
@app.route('/')
def index():
users = User.query.all()
return ', '.join([user.username for user in users])
if __name__ == '__main__':
app.run(debug=True)Flask-Migrate es una extensión de Flask que facilita la administración de migraciones de base de datos con SQLAlchemy. Permite a los desarrolladores realizar cambios en la estructura de la base de datos de manera controlada y automatizada.
- Instalación: Se instala a través de pip:
pip install flask-migrate- Configuración Básica: Se inicializa y configura en la aplicación Flask, junto con SQLAlchemy. Luego, se crea una instancia de la clase
Migratepasando la aplicación Flask y la instancia de la base de datos SQLAlchemy:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
def __repr__(self):
return f'<User {self.username}>'
if __name__ == '__main__':
app.run(debug=True)Flask-Migrate proporciona comandos de línea de comandos para gestionar las migraciones de base de datos. Algunos de los comandos más utilizados son:
flask db init: Inicializa las migraciones en el proyecto.flask db migrate -m "Mensaje": Crea una migración con el mensaje especificado.flask db upgrade: Aplica las migraciones pendientes a la base de datos.
Estos comandos son esenciales para gestionar los cambios en el esquema de la base de datos de manera ordenada y controlada.
Una API RESTful (Representational State Transfer) es un estilo arquitectónico para el diseño de servicios web que se basa en la transferencia de representaciones de recursos a través del protocolo HTTP. Este enfoque se centra en la simplicidad, la escalabilidad y la interoperabilidad entre sistemas distribuidos. Las APIs RESTful permiten a los clientes acceder y manipular recursos de forma uniforme mediante operaciones CRUD (Crear, Leer, Actualizar, Eliminar) utilizando métodos HTTP estándar.
Flask-RESTful es una extensión de Flask que simplifica el desarrollo de APIs RESTful en Flask al proporcionar una abstracción intuitiva para definir recursos y endpoints. Permite a los desarrolladores crear APIs web de manera rápida y eficiente, siguiendo las mejores prácticas de diseño RESTful.
- Instalación: Flask-RESTful se instala fácilmente a través de pip:
pip install flask-restful- Configuración Básica: Una vez instalado, se puede integrar en una aplicación Flask existente. Se define una clase que hereda de
Resourcepara cada recurso y se implementan los métodos HTTP necesarios:
from flask import Flask, jsonify, request
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
def post(self):
data = request.get_json()
return {'you sent': data}, 201
api.add_resource(HelloWorld, '/')
if __name__ == '__main__':
app.run(debug=True)En este ejemplo, se define un recurso HelloWorld con métodos GET y POST. El método GET devuelve un saludo simple en formato JSON, mientras que el método POST espera datos JSON y los devuelve en la respuesta junto con un código de estado 201 (Creado).
- Sencillez de Uso: Flask-RESTful simplifica el proceso de creación de APIs RESTful al proporcionar una interfaz clara y fácil de entender.
- Flexibilidad: Permite definir recursos y endpoints de manera flexible, adaptándose a los requisitos específicos de cada aplicación.
- Integración con Flask: Se integra perfectamente con Flask, aprovechando todas las características y funcionalidades de esta popular biblioteca.
En resumen, Flask-RESTful es una herramienta poderosa y versátil para desarrollar APIs web en Flask, permitiendo a los desarrolladores crear servicios web RESTful de forma rápida y eficiente, lo que facilita la comunicación entre clientes y servidores en aplicaciones distribuidas.
from flask import Flask, request, redirect, url_for
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = '/path/to/upload'
app.config['ALLOWED_EXTENSIONS'] = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file', filename=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''
@app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == '__main__':
app.run(debug=True)pip install flask-babelfrom flask import Flask, render_template
from flask_babel import Babel
app = Flask(__name__)
app.config['BABEL_DEFAULT_LOCALE'] = 'es'
babel = Babel(app)
@babel.localeselector
def get_locale():
return 'es'
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>{{ _("Hello, World!") }}</title>
</head>
<body>
<h1>{{ _("Hello, World!") }}</h1>
</body>
</html># Inicializa las traducciones
pybabel extract -F babel.cfg -o messages.pot .
# Inicializa el archivo de traducción para un nuevo idioma
pybabel init -i messages.pot -d translations -l es
# Compila las traducciones
pybabel compile -d translations
# Actualiza las traducciones
pybabel update -i messages.pot -d translationsPrimero, instala la Heroku CLI desde Heroku Dev Center.
Asegúrate de que tu aplicación tenga un Procfile y un requirements.txt.
Procfile:
web: gunicorn app:apprequirements.txt:
Flask==2.0.1
gunicorn==20.1.0# Inicia sesión en Heroku
heroku login
# Crea una nueva aplicación en Heroku
heroku create your-app-name
# Inicializa un repositorio Git (si aún no lo tienes)
git init
git add .
git commit -m "Initial commit"
# Despliega tu aplicación en Heroku
git push heroku master
# Abre tu aplicación en el navegador
heroku openCrea un archivo de pruebas para tu aplicación Flask:
import unittest
from app import app
class BasicTests(unittest.TestCase):
def setUp(self):
# Crea un cliente de prueba
self.app = app.test_client()
self.app.testing = True
def test_home_page(self):
# Envia una solicitud GET a la página principal
result = self.app.get('/')
# Verifica que la solicitud devuelve un código 200 (OK)
self.assertEqual(result.status_code, 200)
if __name__ == "__main__":
unittest
.main()python -m unittest discoverAquí hay algunas prácticas recomendadas para mejorar la seguridad de tu aplicación Flask:
- Usar HTTPS: Asegúrate de que tu aplicación utiliza HTTPS para proteger la información sensible.
- Configurar Content Security Policy (CSP): Implementa CSP para mitigar ataques de inyección de contenido.
- Proteger Contra CSRF: Usa Flask-WTF para proteger tus formularios contra ataques Cross-Site Request Forgery (CSRF).
- Validar y Sanear la Entrada de Usuario: Siempre valida y limpia los datos ingresados por el usuario para prevenir inyecciones SQL y XSS.
- Gestión de Configuración Segura: No incluyas claves secretas o contraseñas en tu código fuente. Usa variables de entorno para la configuración sensible.
from flask_wtf.csrf import CSRFProtect
app = Flask(__name__)
csrf = CSRFProtect(app)
app.config['SECRET_KEY'] = 'your_secret_key'