Flask应用实战经验总结:使用工厂函数创建app与uWSGI服务部署启动失败解决方案
在 Flask 应用开发中,使用工厂函数创建应用实例,并借助 uWSGI 服务进行部署,是常见且高效的组合。
然而,在实际操作过程中,uWSGI 配置文件与应用启动函数之间的关系复杂,容易引发各种问题。
本文将详细探讨其中的关键要点和注意事项,帮助开发者顺利完成 Flask 应用的部署。
一、Flask 应用工厂函数简介
Flask 应用工厂函数是一种创建 Flask 应用实例的设计模式。通过将应用的创建逻辑封装在函数中,我们可以实现更灵活的配置和复用。例如:
from flask import Flask# 创建Flask应用
def create_app():app = Flask(__name__)# 加载配置app.config.from_object('config.Config')# 初始化扩展from models import dbdb.init_app(app)# 注册蓝图from api import register_blueprintsregister_blueprints(app)@app.route('/')def index():return "Hello, Flask!"return appif __name__ == '__main__':app = create_app()app.run()
在上述代码中,create_app函数负责创建 Flask 应用实例,配置应用,初始化数据库,并注册蓝图。这种方式使得应用的创建和配置分离,便于管理和维护。
二、uWSGI 配置文件详解
uWSGI 是一个高性能的 Web 服务器,支持多种协议和功能。在部署 Flask 应用时,需要正确配置 uWSGI 配置文件(通常为.ini格式)。以下是一个典型的 uWSGI 配置文件示例:
[uwsgi] # 项目根目录 chdir = /home/flask_pro # 应用模块和可调用对象 module = app:create_app callable = app # 进程和线程设置 master = true processes = 4 threads = 2 # 网络设置 socket = 127.0.0.1:5000 # 其他设置 vacuum = true harakiri = 60 pidfile = uwsgi.pid daemonize = uwsgi.log
chdir:指定项目的根目录,uWSGI 会在该目录下查找应用模块。module:指定要加载的应用模块和可调用对象。格式为<模块名>:<可调用对象>,这里的app是包含create_app函数的 Python 模块名,create_app是创建 Flask 应用实例的函数。callable:指定module中返回的可调用对象,即 Flask 应用实例。在上述示例中,create_app函数返回的 Flask 应用实例名为app。master:设置为true时,uWSGI 会启动一个主进程来管理子进程,提高稳定性。processes和threads:分别设置 uWSGI 的进程数和每个进程的线程数,用于控制应用的并发处理能力。socket:指定 uWSGI 监听的 IP 地址和端口号,用于接收外部请求。vacuum:设置为true时,uWSGI 在退出时会自动清理环境,如删除临时文件。harakiri:设置请求的超时时间,单位为秒。pidfile和daemonize:分别指定 uWSGI 进程 ID 文件和日志文件的路径,用于记录进程信息和日志。
三、uWSGI 配置文件与 app 启动函数的关系
- 入口函数的匹配:uWSGI 通过
module和callable配置来定位 Flask 应用的入口函数。module指定包含应用创建逻辑的模块,callable指定模块中返回 Flask 应用实例的函数或对象。在使用工厂函数创建应用时,callable通常是工厂函数返回的应用实例。 - 参数传递问题:在配置 uWSGI 时,容易混淆应用创建函数和 WSGI 应用接口。WSGI 规范要求应用入口函数接受
environ和start_response两个参数,但 Flask 应用工厂函数通常不需要这两个参数。如果在工厂函数中错误地添加了这两个参数,可能会导致 “TypeError: 'Flask' object is not iterable” 错误。因为工厂函数返回的 Flask 应用实例本身不是可迭代的,而 WSGI 期望的是一个可迭代对象来生成响应内容。正确的做法是,在工厂函数中返回 Flask 应用实例,然后通过 uWSGI 的配置来正确调用应用。 - 应用配置与环境变量:uWSGI 配置文件中的
chdir和 Flask 应用工厂函数中的配置加载逻辑密切相关。chdir指定的项目根目录决定了 Flask 应用查找配置文件、静态文件和模板文件的路径。在工厂函数中,通常会使用app.config.from_object方法加载配置,配置文件的路径和名称应与项目结构和 uWSGI 配置相匹配。此外,还可以通过环境变量来传递配置信息,提高应用的灵活性和可扩展性。
四、部署过程中的问题及解决方法
通常根据网上经验,按照根据上面的app代码和uWSGI配置文件部署应该没有问题,但是实际部署到服务器上,启动后发现app并没有正确启动成功,日志显示报错如下:
错误信息 “TypeError: create_app() takes 0 positional arguments but 2 were given”,
表示 create_app() 函数被调用时传入了两个位置参数,但该函数不接受任何位置参数。
在 uWSGI 中,如果 callable 参数指定的函数不接受任何参数,那么在配置文件中就不应该提供任何额外的参数。
uWSGI 默认会将 environ 和 start_response 两个参数传递给 WSGI 应用程序。这可能是导致错误的原因。
[INFO] bound built-in connection pool when new client. maxsize=10,10 WSGI app 0 (mountpoint='') ready in 4 seconds on interpreter 0x26ced20 pid: 3592 (default app) *** uWSGI is running in multiple interpreter mode *** spawned uWSGI master process (pid: 3592) spawned uWSGI worker 1 (pid: 3595, cores: 2) spawned uWSGI worker 2 (pid: 3596, cores: 2) spawned uWSGI worker 3 (pid: 3597, cores: 2) spawned uWSGI worker 4 (pid: 3598, cores: 2) TypeError: create_app() takes 0 positional arguments but 2 were given
然而不是随便将将 environ 和 start_response 两个参数加入到create_app(environ,)函数中的,这样修改,使用uWSGI启动后,又会出现新的报错:start_response
“TypeError: 'Flask' object is not iterable” 错误。
因为工厂函数返回的 Flask 应用实例本身不是可迭代的,而 WSGI 期望的是一个可迭代对象来生成响应内容。
经过查询网上资料以及多个AI平台分析问题,多次测试验证,最终解决方案如下:
1、修改flask应用启动代码:
增加一个符合 WSGI 规范的应用入口函数。
from flask import Flask# 创建Flask应用
def create_app():print("开始创建Flask应用...")app = Flask(__name__)# 加载配置app.config.from_object('config.Config')# 初始化扩展from models import dbdb.init_app(app)# 注册蓝图from api import register_blueprintsregister_blueprints(app)@app.route('/')def index():return "Hello, Flask!"return app# 定义一个符合 WSGI 规范的应用入口函数
def application(environ, start_response):app = create_app()return app.wsgi_app(environ, start_response)if __name__ == '__main__':app = create_app()app.run()
2、修改uWSGI 配置文件:
修改 module:指定要加载的应用模块和可调用对象。格式为<模块名>:<可调用对象>。
修改 callable:指定module中返回的可调用对象。
[uwsgi] # 这里是你的项目根目录路径 chdir = /home/项目根目录路径 # 模块名,这里用 app;app:application 是指定一个 Python 的可执行文件,它包括符合 WSGI 规范的代码 module = app:application # 因为 application 是启动整个服务的入口,所以是 application callable = application # ... 其他配置不变 ...
3、使用uWSGI启动app:
================uwsgi========================== # 启动 uwsgi 命令 cd /home/flask_pro # 项目文件夹,uwsgi.ini 配置文件 下执行 uwsgi --ini uwsgi.ini # 停止 uwsgi 命令 uwsgi --stop uwsgi.pid # 查端是否启动成功 ps -ef|grep uwsgi ================uwsgi==========================
启动成功,打开网址验证下你的服务接口。
[INFO] generate built-in connection pool success. maxsize=10,10 [INFO] bound built-in connection pool when new client. maxsize=10,10 [INFO] bound built-in connection pool when new client. maxsize=10,10 [INFO] bound built-in connection pool when new client. maxsize=10,10 [INFO] bound built-in connection pool when new client. maxsize=10,10 [INFO] bound built-in connection pool when new client. maxsize=10,10 WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x2656cf0 pid: 3772 (default app) *** uWSGI is running in multiple interpreter mode *** spawned uWSGI master process (pid: 3772) spawned uWSGI worker 1 (pid: 3775, cores: 2) spawned uWSGI worker 2 (pid: 3776, cores: 2) spawned uWSGI worker 3 (pid: 3777, cores: 2) spawned uWSGI worker 4 (pid: 3778, cores: 2) 开始创建Flask应用...
五、总结
在 Flask 应用开发中,使用工厂函数创建应用实例并结合 uWSGI 进行部署,可以提高应用的灵活性、可维护性和性能。
在配置 uWSGI 时,需要特别注意配置文件与应用启动函数之间的关系,确保正确指定应用入口函数、处理参数传递问题,并合理设置进程、线程和网络参数。
同时,通过查看日志和解决常见问题,可以快速完成应用的部署和调试。希望本文对您在 Flask 应用部署方面有所帮助,祝您开发顺利!
如果你觉得文章内容对你有所启发,不妨点赞、关注支持一下。要是你在实际操作中遇到了不一样的情况,或是有独特的见解和经验,欢迎在评论区分享交流,大家共同进步。
相关文章:
Flask应用实战经验总结:使用工厂函数创建app与uWSGI服务部署启动失败解决方案
在 Flask 应用开发中,使用工厂函数创建应用实例,并借助 uWSGI 服务进行部署,是常见且高效的组合。 然而,在实际操作过程中,uWSGI 配置文件与应用启动函数之间的关系复杂,容易引发各种问题。 本文将详细探…...
基于Spring Boot的党员学习交流平台设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
TCP/IP的分层结构、各层的典型协议,以及与ISO七层模型的差别
1. TCP/IP的分层结构 TCP/IP模型是一个四层模型,主要用于网络通信的设计和实现。它的分层结构如下: (1) 应用层(Application Layer) 功能:提供应用程序之间的通信服务,处理特定的应用细节。 典型协议&am…...
【2025-02-25】基础算法:二分查找(一)
📝前言说明: ●本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,主要跟随B站博主灵茶山的视频进行学习,专栏中的每一篇文章对应B站博主灵茶山的一个视频 ●题目主要为B站视频内涉及的题目以及B站视频中提到的“课后作业”。…...
WebRTC解析
一、WebRTC 协议概述 WebRTC(Web Real-Time Communication)是由 Google 发起并成为 W3C 标准的实时音视频通信技术,核心特点: 零插件:浏览器原生支持端到端加密(SRTP DTLS)P2P 优先架构&…...
BERT模型详解及代码复现
架构设计 BERT模型的架构设计是其成功的关键之一,它巧妙地融合了Transformer架构的优势,并针对自然语言处理任务进行了优化。具体来说,BERT的架构主要由三个模块组成: Embedding模块 :负责将输入的文本转换为模型可处理的向量表示。该模块由三种Embedding组成: Token Em…...
如何在 SpringBoot 项目使用 Redis 的 Pipeline 功能
本文是博主在批量存储聊天中用户状态和登陆信息到 Redis 缓存中时,使用到了 Pipeline 功能,并对此做出了整理。 一、Redis Pipeline 是什么 Redis 的 Pipeline 功能可以显著提升 Redis 操作的性能,性能提升的原因在于可以批量执行命令。当我…...
Python Django系列—入门实例
我们假定你已经阅读了 安装 Django。你能知道 Django 已被安装,且安装的是哪个版本,通过在命令提示行输入命令(由 $ 前缀)。 $ python -m django --version 如果这行命令输出了一个版本号,证明你已经安装了此版本的…...
2024年第十五届蓝桥杯青少 图形化编程(Scratch)省赛中级组真题——截取递增数
截取递增数 背景信息 递增数:如果一个大于9的正整数各个数位上的数,从左到右是逐渐变大的,那么就称这个数为递增数。 例如124、248 是递增数。 给你一个不含0的九位数,请找出从这个九位数中能截取出的所有递增数。例如:115367…...
【ECMAScript6】
【ECMAScript6】 01. ES6介绍02. let和const命令03. 模板字符串04. 函数之默认值、剩余参数05. 函数之扩展运算符、箭头函数06. 箭头函数this指向和注意事项07. 解构赋值08. 扩展的对象的功能(简写)09. Symbol类型10. Set集合数据类型11. Map数据类型12.…...
WebUI 部署 Ollama 可视化对话界面
文章目录 一、Node.js 安装1.系统环境查询2.官网下载nodejs 安装包3.安装 Node.js 并配置环境变量4.验证安装是否正确 二、ollama-webui 安装与配置1.代码库下载2.依赖安装3.运行 三、遇到问题与解决 一、Node.js 安装 1.系统环境查询 ubuntu20.04 系统,x86-64架构…...
BMS应用软件开发 — 17 上下电控制与诊断开发 (Simulink)
目录 17.1 上下电控制流程 17.1.1 上下电流程 17.1.2 下电过程的电机放电 17.1.3 继电器状态检测 17.2 预充继电器状态判断 17.1 上下电控制流程 17.1.1 上下电流程 高压上电是指动力电池为车辆提供高压,使高压回路导通,为车辆的各个高压部件供电&…...
UE5 Gameplay框架及继承关系详解
文章目录 前言一、核心类及其继承关系二、核心类的职责与协作2.1 Actor & Pawn2.2 Controller2.3 GameMode & GameState2.4 PlayerState2.5 HUD & UI 三、协作流程示例总结 前言 Unreal Engine 5(UE5)的 Gameplay 框架 是一个高度模块化的系…...
html - 手工添加上次阅读的位置, 方便下次阅读
文章目录 html - 手工添加上次阅读的位置, 方便下次阅读概述笔记END html - 手工添加上次阅读的位置, 方便下次阅读 概述 在看一本电子书,有pdf格式的,但是比较喜欢看html格式的(复制比较方便)。 但是有个缺点,如果看到一半,关掉…...
JavaSE学习笔记26-集合(Collection)
集合 Java 中的集合(Collection)是 Java 标准库中非常重要的一部分,用于存储和操作一组对象。Java 集合框架(Java Collections Framework)提供了一套丰富的接口和类,用于处理各种数据结构,如列…...
使用Open WebUI下载的模型文件(Model)默认存放在哪里?
🏡作者主页:点击! 🤖Ollama部署LLM专栏:点击! ⏰️创作时间:2025年2月21日21点21分 🀄️文章质量:95分 文章目录 使用CMD安装存放位置 默认存放路径 Open WebUI下…...
Django数据库操作
1、ORM 创建、删除、修改数据库的表中的数据,但不能创建数据库往数据库表中写入数据 表名:app名称_类名的小写 2、操作表数据 from django.db import modelsclass Department(models.Model):title models.CharField(verbose_name"部门", …...
005:Cesium.viewer 知识详解、示例代码
查看本专栏目录 - 本文是第 005个API内容详解 vue+cesium 示例教程200+目录 文章目录 一、Cesium.Viewer 知识详解1. 主要用途2. 构造函数与参数3. 常用属性(1)`viewer.scene`(2)`viewer.camera`(3)`viewer.entities`(4)`viewer.clock`4. 常用方法(1)`viewer.zoomTo(…...
蓝桥杯单片机组第十二届省赛第二批次
前言 第十二届省赛涉及知识点:NE555频率数据读取,NE555频率转换周期,PCF8591同时测量光敏电阻和电位器的电压、按键长短按判断。 本试题涉及模块较少,题目不难,基本上准备充分的都能完整的实现每一个功能,并…...
AI客服-接入deepseek大模型到微信(本地部署deepseek集成微信自动收发消息)
1.本地部署 1.1 ollama Ollama软件通过其高度优化的推理引擎和先进的内存管理机制,显著提升了大型语言模型在本地设备上的运行效率。其核心采用了量化技术(Quantization)以降低模型的计算复杂度和存储需求,同时结合张量并行计算&…...
Git 常用指令及其说明
配置相关 # 配置全局用户名 git config --global user.name "YourUsername"# 配置全局邮箱 git config --global user.email "your.emailexample.com"说明:这两条命令用于设置 Git 全局的用户名和邮箱,在提交代码时,这些…...
华为2025年技术发布会:智能汽车核心技术大爆发
近日,华为在鸿蒙智行尊界技术发布会上发布了多项智能汽车核心技术,涵盖智能驾驶、安全防护、通信系统、座舱交互及电池技术等领域,标志着其从“被动智能”向“自主智能”的战略升级。 以下是核心技术的综合梳理: 六大核心创新 途…...
SeaCMS V9海洋影视管理系统报错注入
漏洞背景 SQL 注入攻击是当前网络安全中最常见的一种攻击方式,攻击者可以利用该漏洞访问或操作数据库,造成数据泄露或破坏。通常发生在开发人员未能正确处理用户输入时。 在 SeaCMS V9 中,用户输入(如登录、评论、分页、ID 等&a…...
vue3父子组件props传值,defineprops怎么用?(组合式)
目录 1.基础用法 2.使用解构赋值的方式定义props 3.使用toRefs的方式解构props (1).通过ref响应式变量,修改对象本身不会触发响应式 1.基础用法 父组件通过在子组件上绑定子组件中定义的props(:props“”)传递数据给子组件 <!-- 父组件…...
Django-Vue 学习-VUE
主组件中有多个Vue组件 是指在Vue.js框架中,主组件是一个父组件,它包含了多个子组件(Vue组件)。这种组件嵌套的方式可以用于构建复杂的前端应用程序,通过拆分功能和视图,使代码更加模块化、可复用和易于维…...
Ollama部署本地大模型DeepSeek-R1-Distill-Llama-70B
文章目录 一、下模二、转模1. 下载转换工具2. 安装环境依赖3. llama.cpp1. 转换脚本依赖2. llama.cpp安装依赖包3. llama.cpp编译安装4. 格式转换 三、Ollama部署1. 安装启动Ollama2. 添加模型3. 测试运行 一、下模 #模型下载 from modelscope import snapshot_download model…...
Zabbix问题记录2--踩坑HttpRequest,header添加无效
背景 在试图尝试通过Zabbix接入DeepSeek API的时候,由于使用了HTTP的方式,所以需要使用Zabbix 自带的HttpRequest库进行请求,产生了下面的问题 问题 curl curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completio…...
MTK Android12 预装apk可卸载
文章目录 需求解决方法1、device/mediatek/mt6761/device.mk2、/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt3、路径:4、Android.mk 需求 近期,客户需要预装一个apk,同时该apk要可卸载。解…...
Redis 集群的三种模式:一主一从、一主多从和多主多从
本文记述了博主在学习 Redis 在大型项目下的使用方式,包括如何设置Redis主从节点,应对突发状况如何处理。在了解了Redis的集群搭建和相关的主从复制以及哨兵模式的知识以后,进而想要了解 Redis 集群如何使用,如何正确使用…...
网络工程知识笔记
1. 什么是网络? 网络是由多个节点(如计算机、打印机、路由器等)通过物理或逻辑连接组成的系统,用于数据的传输和共享。这些节点可以通过有线(如以太网)或无线(如 Wi-Fi)方式进行连接…...
