分享一个python启动文件脚本(django示例)

今天给大家分享一个python启动文件脚本

在日常开发中,我们常常需要运行多条命令来完成“静态收集”“数据库迁移”“启动服务”……如果把这些命令整合到一个脚本里就好了

一、整体流程概览

collect_static
upgrade_db
dev
dev
start
start
启动脚本 main.py
环境准备
Django 初始化
action
收集静态
数据库迁移
开发模式启动
生产模式启动

二、脚本

import argparse
import logging
import os
import sys
import timeimport django
from django.core import management# 获取当前脚本所在的目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 定义应用代码所在的目录为 'apps' 子目录
APP_DIR = os.path.join(BASE_DIR, 'apps')# 将当前工作目录切换到脚本所在的目录
os.chdir(BASE_DIR)
# 将 'apps' 目录添加到 Python 的模块搜索路径中,这样可以方便地导入 'apps' 目录下的模块
sys.path.insert(0, APP_DIR)
# 设置 Django 的 settings 模块。这是 Django 项目的核心配置文件。
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smartdoc.settings")
# 初始化 Django 环境,只有初始化后才能使用 Django 的各种功能,比如模型、管理命令等。
django.setup()def collect_static():"""收集静态文件到指定目录本项目主要是将前端 vue/dist 的前端项目放到静态目录下面:return:"""logging.info("Collect static files")try:# 调用 Django 的 'collectstatic' 管理命令,用于将各个 app 中的静态文件收集到一个统一的目录中。# '--no-input':禁止用户交互式输入。# '-c':清除之前收集的静态文件。# verbosity=0:设置命令输出的详细程度,0 表示不输出额外信息。# interactive=False:进一步确保非交互式执行。management.call_command('collectstatic', '--no-input', '-c', verbosity=0, interactive=False)logging.info("Collect static files done")except:# 如果收集静态文件过程中发生任何异常,则忽略(pass),不影响后续流程。passdef perform_db_migrate():"""初始化数据库表"""logging.info("Check database structure change ...")logging.info("Migrate model change to database ...")try:# 调用 Django 的 'migrate' 管理命令,用于将 Django 模型的变化同步到数据库中,创建或更新数据库表结构。management.call_command('migrate')except Exception as e:# 如果数据库迁移过程中发生异常,记录错误日志并退出程序。logging.error('Perform migrate failed, exit', exc_info=True)sys.exit(11)def start_services():# 从命令行参数中获取要启动的服务列表,如果 'args.services' 是一个列表则直接使用,否则将其包装成一个列表。services = args.services if isinstance(args.services, list) else [args.services]start_args = []# 如果命令行参数中包含 '--daemon',则将其添加到启动参数列表中,表示以守护进程模式运行。if args.daemon:start_args.append('--daemon')# 如果命令行参数中包含 '--force',则将其添加到启动参数列表中,可能用于强制执行某些操作。if args.force:start_args.append('--force')# 如果命令行参数中包含 '--worker',则将其值(worker 数量)添加到启动参数列表中。if args.worker:start_args.extend(['--worker', str(args.worker)])else:# 如果命令行参数中没有指定 worker 数量,则尝试从环境变量 'CORE_WORKER' 中获取。worker = os.environ.get('CORE_WORKER')# 如果环境变量 'CORE_WORKER' 存在且是数字,则将其添加到启动参数列表中。if isinstance(worker, str) and worker.isdigit():start_args.extend(['--worker', worker])try:# 调用 Django 的管理命令来启动指定的服务。这里的 'action' 变量在主程序中根据命令行参数确定。# '*services' 和 '*start_args' 用于将列表中的元素作为独立的参数传递给 'call_command'。management.call_command(action, *services, *start_args)except KeyboardInterrupt:# 如果用户按下 Ctrl+C 中断程序,则记录信息并等待 2 秒后退出。logging.info('Cancel ...')time.sleep(2)except Exception as exc:# 如果启动服务过程中发生其他异常,记录错误日志并等待 2 秒后退出。logging.error("Start service error {}: {}".format(services, exc))time.sleep(2)def dev():# 从命令行参数中获取要运行的服务,与 'start_services' 类似。services = args.services if isinstance(args.services, list) else args.services# 如果要运行的服务包含 'web',则调用 Django 的 'runserver' 管理命令启动开发服务器,监听 0.0.0.0:8080。if services.__contains__('web'):management.call_command('runserver', "0.0.0.0:8080")# 如果要运行的服务包含 'celery',则调用 Django 的 'celery' 管理命令启动 Celery worker。elif services.__contains__('celery'):management.call_command('celery', 'celery')# 如果要运行的服务包含 'local_model',则设置环境变量 'SERVER_NAME' 为 'local_model',# 并从 'smartdoc.const' 模块的 'CONFIG' 字典中获取本地模型服务的主机和端口,# 然后调用 'runserver' 启动开发服务器监听指定的地址。elif services.__contains__('local_model'):os.environ.setdefault('SERVER_NAME', 'local_model')from smartdoc.const import CONFIGbind = f'{CONFIG.get("LOCAL_MODEL_HOST")}:{CONFIG.get("LOCAL_MODEL_PORT")}'management.call_command('runserver', bind)# 这是 Python 的主程序入口点,当脚本直接运行时会执行这里的代码。
if __name__ == '__main__':# 设置环境变量 'HF_HOME',这可能与脚本中使用的某个库(如 Hugging Face Transformers)有关,指定其配置文件的存储路径。os.environ['HF_HOME'] = '/opt/maxkb/model/base'# 创建一个 ArgumentParser 对象,用于解析命令行参数。parser = argparse.ArgumentParser(description="""qabot service control tools;Example: \r\n%(prog)s start all -d;""")# 添加一个名为 'action' 的位置参数,用户必须提供这个参数来指定要执行的操作。# 'type=str':指定参数类型为字符串。# 'choices':限定了 'action' 参数的可选值,包括 'start'(启动服务)、'dev'(开发模式)、'upgrade_db'(升级数据库)、'collect_static'(收集静态文件)。# 'help':参数的帮助信息。parser.add_argument('action', type=str,choices=("start", "dev", "upgrade_db", "collect_static"),help="Action to run")# 解析已知的命令行参数,将解析结果存储在 'args' 中,并将未知的参数存储在 'e' 中。args, e = parser.parse_known_args()# 根据不同的 'action' 值,为 'services' 参数设置不同的默认值和可选值。# 如果 'action' 是 'start',则 'services' 参数的默认值为 'all',可选值为 'all'、'web'、'task'。# 否则(如果 'action' 是 'dev'),则 'services' 参数的默认值为 'web',可选值为 'web'、'celery'、'local_model'。# 'nargs="*"':表示 'services' 参数可以接受零个或多个值,这些值将被存储在一个列表中。parser.add_argument("services", type=str, default='all' if args.action == 'start' else 'web', nargs="*",choices=("all", "web", "task") if args.action == 'start' else ("web", "celery", 'local_model'),help="The service to start",)# 添加可选参数 '-d' 或 '--daemon',用于指定是否以守护进程模式运行。'nargs="?"' 表示该参数可以有零个或一个值,'const=True' 表示如果只指定了该参数而没有提供值,则其值为 True。parser.add_argument('-d', '--daemon', nargs="?", const=True)# 添加可选参数 '-w' 或 '--worker',用于指定 worker 的数量。'type=int' 表示参数类型为整数,'nargs="?"' 与 '--daemon' 类似。parser.add_argument('-w', '--worker', type=int, nargs="?")# 添加可选参数 '-f' 或 '--force',用于指定是否强制执行某些操作,与 '--daemon' 类似。parser.add_argument('-f', '--force', nargs="?", const=True)# 解析所有的命令行参数,将最终的解析结果存储在 'args' 中。args = parser.parse_args()# 将解析得到的 'action' 参数的值赋给变量 'action'。action = args.action# 根据 'action' 的值执行相应的操作。if action == "upgrade_db":# 如果 'action' 是 'upgrade_db',则调用 'perform_db_migrate' 函数来执行数据库迁移。perform_db_migrate()elif action == "collect_static":# 如果 'action' 是 'collect_static',则调用 'collect_static' 函数来收集静态文件。collect_static()elif action == 'dev':# 如果 'action' 是 'dev',则先收集静态文件,然后执行数据库迁移,最后调用 'dev' 函数启动开发服务。collect_static()perform_db_migrate()dev()else:# 如果 'action' 不是以上任何值(通常是 'start'),则先收集静态文件,然后执行数据库迁移,最后调用 'start_services' 函数启动指定的服务。collect_static()perform_db_migrate()start_services()

、收益

运维同学只需记住一条命令。
CI/CD 管道中,只需执行一次脚本即可完成全部准备工作。
后续只要在脚本中新增命令分支,即可支持新的功能。

📌 作者:叫我DPT
📅 日期:2025 年
🔗 原创整理,可自由转载,请注明出处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/79390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes》》K8S》》Pod的健康检查

K8s概念总结 》》》Pod的生命周期阶段 Pod的生命周期可以简单描述:首先Pod被创建,紧接着Pod被调度到Node节点进行部署。 Pod是非常忠诚的,一旦被分配到Node节点后,就不会离开这个Node节点,直到它被删除,删除…

bininote: 使用AI将视频转换了Markdown笔记

GitHub:https://github.com/JefferyHcool/BiliNote 更多AI开源软件:发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI BiliNote 是一个开源的 AI 视频笔记助手,支持通过哔哩哔哩、YouTube 等视频链接,自动提取内容并生…

鸿蒙NEXT开发文件预览工具类(ArkTs)

import { uniformTypeDescriptor } from kit.ArkData; import { filePreview } from kit.PreviewKit; import { FileUtil } from ./FileUtil; import { AppUtil } from ./AppUtil; import { WantUtil } from ./WantUtil;/*** 文件预览工具类* 提供文件预览、加载、判断等功能。…

MySQL常用SQL语句的示例

概述 MySQL 常用 SQL 语句的示例,涵盖数据定义、操作、查询等常见场景 一、数据库操作 创建数据库 CREATE DATABASE mydb;选择数据库 USE mydb;删除数据库 DROP DATABASE mydb;二、表操作 创建表 CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,name VAR…

智算启新篇 安全筑新基 ——中国移动举办智算基础设施及安全分论坛

4月10日,2025中国移动云智算大会智算基础设施及安全分论坛在苏州金鸡湖国际会议中心揭幕。 在数字经济浪潮奔涌向前的时代坐标下,中国移动锚定“创世界一流信息服务科技创新公司”定位,持续推进智算基础设施建设,持续提升网信安全…

MySQL——游标(cursor)

一、什么是游标? 游标(Cursor) 是MySQL中用于逐行处理查询结果集的数据库对象。它类似于指针,允许开发者在结果集中逐行移动,并对每一行数据进行特定操作。游标将传统的集合操作转换为面向过程的记录处理方式&#xf…

异步编程——微信小程序

1. 前言 引用来自:微信小程序开发中的多线程处理与异步编程_微信小程序 多线程-CSDN博客 微信小程序是基于JavaScript开发的,与浏览器JavaScript不同,小程序运行在WebView内部,没有多线程的概念。小程序的 JavaScript 是单线程的…

HarmonyOS-ArkUI V2状态-PersistenceV2:持久化存储UI状态

PersistenceV2类是一个与AppStorageV2类用法非常相似的类。因为它俩是子类和父类的关系。如果不了解AppStorageV2,可以先跳转至了解一下这个类。 HarmonyOS-ArkUI V2工具类:AppStorageV2:应用全局UI状态存储-CSDN博客 PersistenceV2相比于其父类AppStorageV2而言,它存储的…

《Mycat核心技术》第22章:搭建Mycat+Zookeeper+HAProxy+Keepalived+MySQL高可用架构

作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 星球项目地址:https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀&#xff0c…

Aosp13 文件应用点击apk无反应的处理

最近遇到一个问题,在A13上,打开文件管理应用时,点击apk 无反应或者启动安装进程后安装完成或取消安装进程,再次点击apk 无反应。在此记录该问题。 做一下修改:root/package/ providers/DownloadProvider/下 jenkinsdel…

SQL刷题记录贴

1.题目:现在运营想要对用户的年龄分布开展分析,在分析时想要剔除没有获取到年龄的用户,请你取出所有年龄值不为空的用户的设备ID,性别,年龄,学校的信息。 错误:select device_id,gender,age,un…

【Windows本地部署n8n工作流自动平台结合内网穿透远程在线访问】

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

python爬虫降低IP封禁,python爬虫除了使用代理IP和降低请求频率,还有哪些方法可以应对IP封禁?

文章目录 前言1. 利用 CDN 节点2. 模拟真实用户行为3. 使用 IP 池轮换策略4. 处理 Cookie 和会话信息5. 分布式爬虫 前言 除了使用代理 IP 和降低请求频率,以下这些方法也能应对 IP 封禁: Python 3.13.2安装教程(附安装包)Python…

光谱相机的成像方式

光谱相机的成像方式决定了其如何获取物体的空间与光谱信息,核心在于分光技术与扫描模式的结合。以下是主要成像方式的分类解析: ‌一、滤光片切换型‌ ‌1. 滤光片轮(Filter Wheel)‌ ‌原理‌:通过旋转装有多个窄带…

AI在市场营销分析中的核心应用及价值,分场景详细说明

以下是 AI在市场营销分析中的核心应用及价值,分场景详细说明: 1. 客户行为分析与细分 AI技术应用: 机器学习:分析用户点击、购买、浏览等行为数据,识别消费模式(如高频购买时段、偏好品类)。聚…

浔川AI翻译v7.0更新预告

亲爱的浔川AI翻译用户: 感谢您一直以来的支持!浔川AI翻译自推出以来,已迭代6个版本,其中**v2.0和v4.0因技术问题(翻译结果显示异常、注册失败、密码找回功能失效等)**被迫下架。我们深知这些问题影响了您…

LabVIEW中二维数组转换为彩色图

在 LabVIEW 编程环境下,有用户想把二维数组转化为彩色图片。通过附件的程序示例,给出了具体实现方法,包括对数据的处理以及颜色映射的设置等内容,还涉及解决数据范围与颜色映射不匹配等问题。公司官网有源码 程序功能及细节 功能&…

【模型常见评价指标(分类)】

目录 常见指标 其他的评估指标 3.1 BLEU 3.2 ROUGE 3.3 困惑度PPL(perplexity) 常见指标 其他的评估指标 3.1 BLEU BLEU(Bilingual Evaluation Understudy,双语评估替补)分数是评估一种语言翻译成另一种语言的文本质量的指标。它将“质…

期货数据API对接实战指南

一、期货数据接口概述 StockTV提供全球主要期货市场的实时行情与历史数据接口,覆盖以下品种: 商品期货:原油、黄金、白银、铜、天然气、农产品等金融期货:股指期货、国债期货特色品种:马棕油、铁矿石等区域特色期货 …

TCP连接建立:为什么是三次握手?

接下来,以三个方面分析三次握手的原因: 1、三次握手才可以阻止重复历史连接的初始化(主要原因) 2、三次握手才可以同步双方的初始化序列号 3、三次握手才可以避免资源浪费 原因一:避免历史连接 简单来说&#xff0…