Flask - Common Application Deployment Solutions

Introduction During development and debugging, Flask applications are typically run directly using app.run(). However, the built-in WSGI server in Flask is not known for high performance. For production environments, gunicorn is commonly used. For legacy projects that don’t require high performance and rely heavily on in-process shared variables, using gunicorn might affect inter-request communication, so you may consider using gevent directly. Before Docker became popular, Flask applications in production were typically deployed using virtualenv + gunicorn + supervisor. After Docker gained widespread adoption, the deployment approach shifted to gunicorn + Docker. Without container orchestration services, a reverse proxy like nginx is typically placed in front of the backend services. When using Kubernetes, services are typically exposed via Service + Ingress (or Istio, etc.). ...

February 14, 2026 · 12 min · Rainux He

Executing Asynchronous Scheduled Tasks with Database-Based Distributed Locking in FastAPI

Introduction When implementing scheduled tasks in FastAPI applications, Celery is often the go-to choice. However, Celery is relatively heavyweight and requires dependencies like Redis or RabbitMQ as message brokers. For smaller-scale services that don’t already utilize Redis or RabbitMQ, introducing these dependencies solely for scheduled task functionality adds unnecessary operational overhead. Another popular Python scheduling framework is APScheduler, but it presents two significant challenges in practice: Duplicate Execution in Multi-Process Environments: When running with Uvicorn’s multi-process mode, each worker process independently executes scheduled tasks, leading to duplicate executions. Poor Asynchronous Function Compatibility: Although APScheduler provides AsyncIOScheduler, its support for asynchronous functions is incomplete. The official documentation explicitly states: “If you’re running an asynchronous web framework like aiohttp, you probably want to use a different scheduler in order to take some advantage of the asynchronous nature of the framework.” For APScheduler users facing these issues, potential solutions include: ...

February 8, 2026 · 14 min · Rainux He

Using UPSERT in SQLAlchemy

Introduction Both SQLite and PostgreSQL support UPSERT operations, which means “update if exists, insert if not.” The conflict column must have a unique constraint. Syntax: PostgreSQL: INSERT ... ON CONFLICT (column) DO UPDATE/NOTHING SQLite: INSERT ... ON CONFLICT(column) DO UPDATE/NOTHING (note the parentheses position) Scenario PostgreSQL SQLite Notes Basic UPSERT ON CONFLICT (col) DO UPDATE SET ... ON CONFLICT(col) DO UPDATE SET ... Slight difference in parentheses placement Conflict Ignore ON CONFLICT (col) DO NOTHING ON CONFLICT(col) DO NOTHING Same syntax Reference New Values EXCLUDED.col excluded.col PostgreSQL uses uppercase, SQLite uses lowercase Return Results RETURNING * RETURNING * Same syntax Conditional Update WHERE condition WHERE not supported SQLite limitation Key Considerations The conflict column must have a unique constraint PostgreSQL and SQLite syntax is similar but has subtle differences. Pay attention when using raw SQL. SQLite does not support WHERE clauses in UPSERT operations; use CASE expressions or application-level filtering instead. SQLite version 3.35+ is required for RETURNING support. EXCLUDED and RETURNING EXCLUDED EXCLUDED represents the new values that were intercepted due to a conflict. ...

February 8, 2026 · 10 min · Rainux He

Exploring the Official MCP Go SDK

Introduction I previously noticed on the MCP official website that an official Go SDK was available. Recently, after developing MCP Servers in Python environments for a while, I decided to try something different and explore Go. From my personal experience, Go demonstrates significant advantages in concurrent processing: there’s no need to worry about complex concurrency issues like synchronous blocking, asynchronous event loops, or inter-process/thread communication—goroutines handle it all elegantly. Additionally, Go offers convenient deployment; the compiled static binary files have excellent portability and can run directly across different environments. ...

February 7, 2026 · 14 min · Rainux He

Flask - Design and Implementation of tracking_id

Introduction In actual business scenarios, tracing the complete processing path of a request based on tracking_id is a common requirement. With the help of Flask’s built-in global object g and hook functions, it’s easy to add a tracking_id to each request and automatically log it. Main topics: How to add tracking_id to each request How to automatically log tracking_id How to customize response classes, implement unified response formats, and add tracking_id to response headers View function unit testing examples Gunicorn configuration Project Structure Although it appears complex, the implementation of tracking_id is actually quite simple. This article organizes the code according to production project standards, adding Gunicorn configuration and unit testing code, as well as standardizing log formats and JSON response formats. ...

January 17, 2026 · 10 min · Rainux He

FastAPI - Calling Synchronous Methods in FastAPI Asynchronous Methods

Introduction Directly calling synchronous methods within asynchronous methods blocks the entire event loop, preventing the application from handling any other concurrent requests while executing the synchronous method. This severely impacts the overall performance and responsiveness of the service. To address this issue, the core approach is to delegate synchronous methods to external thread pools or process pools for execution, thereby avoiding blocking the main event loop. Method 1: Using asyncio.to_thread Python 3.9 and later versions provide the asyncio.to_thread method, which runs synchronous functions in a separate thread and returns a coroutine object that can be awaited. ...

January 6, 2026 · 2 min · Rainux He

MCP-01: Introduction and Core Concepts

Preface All example code has been uploaded to a Git repository. Feel free to clone it directly if needed: https://github.com/rainuxhe/mcp-examples Introduction MCP (Model Context Protocol) is a standardized protocol designed for managing context in large language model interactions. Its core objective is to establish a structured, controllable, and extensible semantic execution environment for models, enabling them to perform task scheduling, tool invocation, resource collaboration, and state persistence within a unified context management framework. This approach overcomes the limitations of traditional Prompt Engineering in multi-turn interactions, instruction composition, and behavioral stability. ...

December 25, 2025 · 6 min · Rainux He