Skip to main content

Overview

TaskForge API uses a class-based configuration system defined in app/config.py. Three configuration classes inherit from a shared Config base:
ClassFLASK_ENV valueUse case
DevelopmentConfigdevelopmentLocal development with SQL echo enabled
TestingConfigtestingPytest suite — uses in-memory SQLite, disables rate limiting
ProductionConfigproductionAzure App Service deployment
The active configuration is selected by the FLASK_ENV environment variable via get_config() in app/config.py:111.

Environment file setup

Copy .env.example to .env before running the application:
cp .env.example .env
Then open .env and update each value for your environment.

Variable reference

VariableDefaultDescription
FLASK_APPrun.pyEntry point for the Flask CLI
FLASK_ENVdevelopmentActive configuration class (development, testing, production)
SECRET_KEY(insecure placeholder)Flask session signing key — must be random in production
JWT_SECRET_KEY(insecure placeholder)JWT signing key — must be random in production
VariableDefaultDescription
AZURE_SQL_SERVERFully qualified server hostname, e.g. server.database.windows.net
AZURE_SQL_DATABASEtaskforge_dbDatabase name
AZURE_SQL_USERSQL login username
AZURE_SQL_PASSWORDSQL login password
AZURE_SQL_PORT1433TCP port (standard SQL Server port)
When any of AZURE_SQL_SERVER, AZURE_SQL_USER, or AZURE_SQL_PASSWORD is absent, the application falls back to a local SQLite file (taskforge.db). See Database configuration below.
VariableDefaultDescription
JWT_ACCESS_TOKEN_EXPIRES3600Access token lifetime in seconds (1 hour)
JWT_REFRESH_TOKEN_EXPIRES2592000Refresh token lifetime in seconds (30 days)
Tokens are expected in the Authorization: Bearer <token> header. The identity claim is stored under the sub key.
VariableDefaultDescription
RATELIMIT_ENABLEDtrueEnable or disable rate limiting globally
RATELIMIT_STORAGE_URLmemory://Storage backend for counters. Use a Redis URL in multi-worker deployments.
RATELIMIT_DEFAULT200 per day;50 per hourDefault limits applied to all endpoints
Rate limit headers (X-RateLimit-*) are always included in responses when limiting is enabled.
VariableDefaultDescription
CORS_ORIGINShttp://localhost:3000,http://localhost:5173Comma-separated list of allowed origins
Allowed methods are GET, POST, PUT, PATCH, DELETE, and OPTIONS. Allowed headers are Content-Type and Authorization.
VariableDefaultDescription
LOG_LEVELINFOPython logging level (DEBUG, INFO, WARNING, ERROR)
LOG_FORMATjsonLog output format (json or text)
VariableDefaultDescription
APP_NAMETaskForge APIApplication name returned in health check responses
APP_VERSION1.0.0Application version string

Full .env.example

.env.example
# Configuración de la Aplicación
FLASK_APP=run.py
FLASK_ENV=development
SECRET_KEY=tu-clave-secreta-aqui-cambiar-en-produccion
JWT_SECRET_KEY=tu-clave-jwt-secreta-aqui-cambiar-en-produccion

# Configuración de Azure SQL Database
AZURE_SQL_SERVER=tuservidor.database.windows.net
AZURE_SQL_DATABASE=taskforge_db
AZURE_SQL_USER=tuusuario
AZURE_SQL_PASSWORD=TuPassword123
AZURE_SQL_PORT=1433

# Cadena de Conexión de Base de Datos
# Se construirá automáticamente a partir de las variables anteriores
# Formato: mssql+pyodbc://user:password@server:port/database?driver=ODBC+Driver+17+for+SQL+Server

# Configuración JWT
JWT_ACCESS_TOKEN_EXPIRES=3600        # 1 hora en segundos
JWT_REFRESH_TOKEN_EXPIRES=2592000    # 30 días en segundos

# Rate Limiting
RATELIMIT_ENABLED=true
RATELIMIT_STORAGE_URL=memory://
RATELIMIT_DEFAULT=200 per day;50 per hour

# Configuración CORS
CORS_ORIGINS=http://localhost:3000,http://localhost:5173

# Paginación
DEFAULT_PAGE_SIZE=10
MAX_PAGE_SIZE=100

# Logging
LOG_LEVEL=INFO
LOG_FORMAT=json

# Información de la Aplicación
APP_NAME=TaskForge API
APP_VERSION=1.0.0

Database configuration

The connection string is assembled in app/config.py:31-38. When all four Azure SQL variables are present, the application connects using the mssql+pyodbc driver with ODBC Driver 17 for SQL Server:
mssql+pyodbc://<user>:<password>@<server>:<port>/<database>?driver=ODBC+Driver+17+for+SQL+Server
When any of those variables is absent, the application falls back to a local SQLite file:
sqlite:///taskforge.db
The TestingConfig class always overrides the database URI to sqlite:///:memory: regardless of environment variables, so tests never connect to a real database.
For local development without Azure SQL, omit all AZURE_SQL_* variables from your .env and the SQLite fallback is used automatically. Initialize the schema with:
flask init-db
For Azure SQL, run scripts/init_db_azure.sql against your database using Azure Data Studio or SQL Server Management Studio before starting the application.

Production security checklist

The default values for SECRET_KEY and JWT_SECRET_KEY in .env.example are placeholders. Deploying with these values exposes your application to session forgery and token spoofing attacks.
Before going to production, verify each of the following:
SettingRequired value
SECRET_KEYCryptographically random string (at least 32 bytes)
JWT_SECRET_KEYCryptographically random string (at least 32 bytes)
FLASK_ENVproduction
DEBUGMust be False — enforced by ProductionConfig
AZURE_SQL_*All four variables set — SQLite is not suitable for production
Generate random keys using Python:
python -c "import secrets; print(secrets.token_hex(32))"
Run this twice to produce independent values for SECRET_KEY and JWT_SECRET_KEY.

Build docs developers (and LLMs) love