Python入门实战:Python的项目部署

385 阅读9分钟

1.背景介绍

近年来,Python在数据科学、机器学习等领域的应用越来越广泛。随着云计算、容器化、微服务架构、DevOps等技术的发展,基于Python的项目部署也成为许多开发人员关注的方向之一。部署Python项目需要面临的问题主要有以下几点:

  1. 文件部署:不同环境中的配置文件、静态文件、数据库脚本等资源的部署;
  2. 配置项部署:设置不同运行环境下的配置项,如服务器地址、数据库信息等;
  3. 依赖包部署:除了项目自身的代码外,还需要处理一些第三方依赖库,如Django等;
  4. 服务启动及初始化:启动服务进程及执行初始化操作;
  5. 流程控制:自动化部署过程中可能存在复杂的依赖关系,需要解决流程依赖问题。 本文将介绍如何利用Python部署一个Web应用项目,并进行相应的配置和部署工作,最终达到项目从开发到测试、预发布、生产环境中全生命周期的部署。

2.核心概念与联系

首先我们先了解一下本文所涉及到的几个核心概念,它们分别是:项目目录结构、虚拟环境、requirements.txt文件和pip。

  1. 项目目录结构:Python项目的目录结构一般遵循如下约定规则:

    ├── README.md                 # 项目说明文档
    ├── app                       # 项目源码所在文件夹
    │   └── main.py               # 主模块文件
    ├── config                    # 配置文件文件夹
    │   ├── base_config.ini       # 基础配置
    │   ├── prod_config.ini       # 生产环境配置
    │   └── dev_config.ini        # 开发环境配置
    ├── db                        # 数据库相关文件
    ├── deploy                    # 自动化部署相关文件
    ├── dist                      # 打包生成的文件
    ├── requirements.txt          # pip安装依赖文件
    ├── setup.cfg                 # setuptools打包配置
    ├── setup.py                  # setuptools打包入口
    └── tests                     # 单元测试相关文件
    

    上述目录结构是一个典型的Web应用项目的目录结构。其中,app文件夹下存放了项目源码文件,config文件夹存储了配置信息,db文件夹存储了数据库相关文件,deploy文件夹存储了自动化部署相关脚本,dist文件夹用于存放编译后的Python包文件。requirements.txt文件记录了项目所依赖的Python包,setup.cfg文件和setup.py文件则用来进行打包。tests文件夹存放了单元测试文件。

  2. 虚拟环境:虚拟环境(Virtual Environment)是一个独立于系统Python解释器之外的Python环境,它能够帮助我们管理不同版本的Python和其对应的依赖包。如果没有虚拟环境,我们往往会遇到不同的Python版本或依赖包的兼容性问题。为此,我们可以创建多个虚拟环境,每个环境都只装有自己指定的Python版本和依赖包,避免出现不必要的麻烦。

  3. requirements.txt文件:当我们要把项目部署到其他人的计算机上时,我们就需要共享给他们一份完整的项目环境。而这个项目环境包括Python版本和所有依赖包。为了方便共享,我们可以把这些依赖包都放在requirements.txt文件里,这样其他人只需运行一条命令就可以完成项目环境的安装。

  4. pip:pip(The Python Package Installer)是一个用Python编写的包管理工具。它可以实现自动安装、卸载、管理各种包。通常,我们可以通过pip install命令来安装依赖包,也可以通过pip freeze命令来获取当前环境的所有已安装包的信息。

3.核心算法原理和具体操作步骤以及数学模型公式详细讲解

3.1 准备环境

第一步,安装并配置好Python3.x环境,创建一个新项目目录,并进入该目录。

mkdir myproject && cd myproject

第二步,创建一个virtualenv环境,并激活该环境。

python -m venv env    # 创建名为env的虚拟环境
source env/bin/activate     # 激活虚拟环境

第三步,创建一个setup.py文件,并配置项目信息。

touch setup.py

编辑setup.py文件,添加以下内容:

from setuptools import setup, find_packages

setup(
   name='myproject',         # 项目名称
   version='1.0',           # 版本号
   description='My Project',      # 描述信息
   author='<NAME>',    # 作者姓名
   url='',                   # 项目链接
   packages=find_packages(),     # 指定包含的包列表,默认为空
   entry_points={
        'console_scripts': [
           'myproject = myproject.__main__:run' # 可执行的主函数入口,默认为空
        ]
    }
)

第四步,创建一个README.md文件,用于描述项目的基本信息。

touch README.md

编辑README.md文件,添加以下内容:

# MyProject

这是我的第一个Python项目。

第五步,创建一个requirements.txt文件,用于记录项目所依赖的Python包。

touch requirements.txt

编辑requirements.txt文件,添加以下内容:

Flask==1.1.2
SQLAlchemy==1.3.19
Werkzeug==1.0.1

第六步,安装项目依赖包。

pip install --requirement requirements.txt

第七步,创建app目录,用于存放项目源码文件。

mkdir app
touch app/__init__.py

编辑__init__.py文件,添加以下内容:

print('hello world')

第八步,创建config目录,用于存放配置文件。

mkdir config
touch config/__init__.py

编辑__init__.py文件,添加以下内容:

import os
class Config:
    DEBUG = True if os.environ.get("DEBUG") == "True" else False
    SECRET_KEY = '<secret key>'

class ProdConfig(Config):
    pass

class DevConfig(Config):
    DEVELOPMENT = True

第九步,修改项目源码文件。

编辑app/main.py文件,添加以下内容:

from flask import Flask
from.config import Config

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    
    return app

if __name__ == '__main__':
    app = create_app()
    app.run()

第十步,运行项目。

export FLASK_APP=app
flask run

3.2 操作配置文件

第一步,打开config/base_config.ini文件,设置如下内容:

[DEFAULT]
ENV=DEV
SERVER_PORT=5000
DB_URL=<your database url>

第二步,打开config/dev_config.ini文件,设置如下内容:

[DEFAULT]
ENV=DEV
SERVER_PORT=5000
DB_URL=<your development database url>

第三步,打开config/prod_config.ini文件,设置如下内容:

[DEFAULT]
ENV=PROD
SERVER_PORT=80
DB_URL=<your production database url>

第四步,修改项目源码文件。

编辑app/main.py文件,读取配置文件,并根据配置创建Flask对象。

from flask import Flask
from configparser import ConfigParser

def create_app():
    app = Flask(__name__)
    
    parser = ConfigParser()
    filename = os.path.join(os.getcwd(), 'config', f'{app.env}.ini')
    print(filename)
    parser.read(filename)
    
    app.env = parser['DEFAULT']['ENV']
    app.port = int(parser['DEFAULT']['SERVER_PORT'])
    app.url = parser['DEFAULT']['DB_URL']
    
    return app

第五步,测试项目。

将FLASK_ENV变量设置为对应环境的值,然后运行项目。

export FLASK_APP=app
export FLASK_ENV=development
flask run

访问http://localhost:5000/查看输出结果。

3.3 安装第三方依赖包

如果你的项目依赖了外部的Python包,你可以直接用pip安装到你的虚拟环境里面。

例如,假设你的项目需要安装requests模块,那么可以在requirements.txt文件添加requests的条目,然后运行:

pip install requests

如果你的项目依赖的包比较多,你可以直接批量安装。例如,假设你的项目需要安装numpy、pandas和matplotlib模块,那么你可以在requirements.txt文件中添加相应的条目,然后运行:

pip install -r requirements.txt

3.4 自动化部署

部署Python项目有很多种方式,常见的有手动上传、拷贝文件、git推送等。但无论采用哪一种方式,都需要大量的人工操作,费时费力。所以,自动化部署显然是最佳方案。

一般来说,自动化部署可以分成以下几个阶段:

  1. 构建:编译项目源码,生成可运行的部署包;
  2. 集成测试:部署前进行集成测试;
  3. 分发:将部署包分发到目标服务器;
  4. 启动:启动服务进程,执行初始化操作。

3.4.1 使用Make工具进行自动化部署

Make工具是一个自动化工具,它的主要作用就是用来管理工程文件和自动执行任务的。在部署Python项目时,我们可以使用Makefile来定义自动化部署任务。

3.4.1.1 安装Make工具

Make工具可以用来管理工程文件和自动执行任务,确保部署成功率。在Linux系统中,我们可以直接使用apt-get命令安装:

sudo apt-get install make

在Mac OS X系统中,我们可以用brew命令安装:

brew install make

3.4.1.2 定义部署任务

首先,在项目根目录下创建一个名为Makefile的文件。

然后,在Makefile文件中定义以下任务:

build: clean compile pack
    echo "Build successful!"

clean:
    rm -rf build/*
    mkdir build/logs

compile:
    python setup.py sdist bdist_wheel

pack:
    cp dist/*.whl build/
    cp app/config/*.ini build/config/

test:
    pytest./tests/unittests

deploy: test build copy start stop restart status

copy:
    scp build/myproject-1.0-py3-none-any.whl <remote server>:<directory>/

start:
    ssh <remote server> nohup /usr/local/bin/gunicorn myproject:create_app() -w 4 -b :$(PORT) &

stop:
    ssh <remote server> killall gunicorn

restart:
    $(MAKE) stop; $(MAKE) start
    
status:
    ssh <remote server> ps aux|grep myproject | grep -v grep

这里,我们定义了10个任务:

  • build:完成一次完整的部署过程,包括清除旧的编译文件、编译项目源码、打包项目、复制配置文件、运行单元测试、部署到远程服务器、启动服务进程。
  • clean:删除之前编译生成的可执行文件和日志文件。
  • compile:编译项目源码,生成可运行的部署包。
  • pack:将编译好的可执行文件、配置文件拷贝到指定位置。
  • test:运行单元测试。
  • deploy:调用testbuildcopystartstoprestart等任务。
  • copy:使用scp命令将部署包拷贝到远程服务器指定位置。
  • start:使用ssh命令启动远程服务器上的服务进程。
  • stop:停止远程服务器上的服务进程。
  • restart:先停止远程服务器上的服务进程,再重新启动。
  • status:检查远程服务器上的服务进程状态。

3.4.1.3 执行部署任务

部署任务可以通过以下命令来执行:

make deploy PORT=<server port number> REMOTE_USER=<username on remote server> REMOTE_HOST=<remote host address> REMOTE_DIR=<deployment directory on remote server>

参数说明:

  • PORT:指定运行服务的端口号。
  • REMOTE_USER:指定远程服务器用户名。
  • REMOTE_HOST:指定远程服务器地址。
  • REMOTE_DIR:指定远程服务器上的部署目录。

例如,假设我们的远程服务器地址为example.com,用户名为john,部署目录为/home/john/myproject,并且端口号为5000。我们可以执行以下命令:

make deploy PORT=5000 REMOTE_USER=john REMOTE_HOST=example.com REMOTE_DIR=/home/john/myproject

然后,Make工具就会自动地完成一次完整的部署过程。

3.5 小结

本文介绍了Python的项目部署。首先介绍了Python项目的目录结构、虚拟环境、requirements.txt文件和pip。然后,详细介绍了如何利用Python部署一个Web应用项目,并进行相应的配置和部署工作,最终达到项目从开发到测试、预发布、生产环境中全生命周期的部署。最后,介绍了自动化部署的概念、Make工具的安装、任务定义、执行等方面的内容。希望能对读者有所帮助!