pyramid框架学习之(三)——建立一个Pyramid项目

来源:互联网 发布:主人网络和访客网络 编辑:程序博客网 时间:2024/05/16 05:01

建立一个Pyramid项目

来自:http://blog.csdn.net/qq_25362095/article/details/76588630
正如我们在第一篇文章中看到的那样,你完全可以手动建立一个Pyramid应用。但是,通过cookiecutter来建立一个pyramid项目会更加的便捷。

所谓项目是一个包含了至少一个Python包的文件目录。你将使用cookiecutter工具来创建一个项目,cookiecutter是一个快速建立项目并便于你开发的模板工具(顾名思义,像是生产蛋糕的模具),它将您的代码按功能以包分类。即便您的项目是非常简单的,通过包来分类管理代码依然是很有用的,因为包更容易扩展,分发和部署。

Pylons项目提供了几个Pyramid的cookiecutters模板,您可以用来他们生成一个项目。每个cookiecutter都对您要构造的应用程序类型做出了不同的默认配置。

如果您已经安装了cookiecutter的话,您可以通过cookiecutter指令来调用这些cookiecutters。

安装很简单,一行指令:
pip install cookiecutter

1.Pyramid的cookiecutter工具

Pyramid的不同cookiecutter工具在某些方面有些区别:

  • 他们提供不同的数据库支持(无支持,基于SQlite的SQLAlchemy 或是ZODB)
  • 他们将URL映射带代码的方式不同(URL分派或者遍历方式)
  • 不同的页面模板库(Jinja2,Chameleon或是Mako)

下面介绍三种主要的cookiecutter模板:

  • pyramid-cookiecutter-starter
    拥有URL分发的路由方式; Jinja2,Chameleon或是Mako三种页面模板。
  • pyramid-cookiecutter-alchemy
    拥有URL分发的路由方式;Jinja2的页面模板;SQLite和SQLAlchemy 持久化存储
  • pyramid-cookiecutter-zodb
    ZODB的称呼就花存储;遍历的路由方式;Chameleon页面模板

2.创建项目

我们使用pyramid-cookiecutter-starter模板来创建我们的项目。
我使用的是CENTOS7.3 + python2.7.13的环境。
首先运行python虚拟环境

yum install git     //安装git(cookiecutter需要)mkdir -p /opt/ENV13  //创建存放虚拟环境的目录virtualenv /opt/ENV13 //指定虚拟环境目录source /opt/ENV13/bin/activate //进入虚拟环境mkdir -p /root/project //创建项目目录cd /root/project  //进入项目目录cookiecutter gh:Pylons/pyramid-cookiecutter-starter --checkout 1.9-branch   //使用cookiecutter创建项目

此时会看到如下界面

You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.Is it okay to delete and re-clone it? [yes]: yes            //从git上克隆项目到本地project_name [Pyramid Scaffold]: myproject1     //设置项目名称repo_name [myproject]: myproject1  //设置资源名称Select template_language:  //选择页面模板语言1 - jinja22 - chameleon3 - makoChoose from 1, 2, 3 [1]: 1   //选择jinja2

此时,我们可以看到project目录中多了一个project1项目文件夹,让我们看一下这个项目中有些什么。

setup.py文件用于分发开发或是安装部署你的项目。

development.ini配置文件用于配置server服务来启动或调试你的应用,它包含了交互式调试器和一些应用设置的配置信息。

production.ini文件则包含了禁用交互式调试器的配置,并禁用了一些调试设置(防止调试信息被暴露和访问)。你可以在将你的应用正式上线时使用这个配置文件。

这个project1项目文件中还包含了一个同名的project1子目录。它包含了一些最简单的Pyramid示例代码。这里是你编辑你的应用代码和页面模板的地方。

项目中各个文件的作用会在后面有更详细的介绍。

3.安装您新创建的项目用于开发

你需要在你刚刚创建的项目目录下(/root/project/project1)调用pip install -e .(不要忽略最后这个点)指令来完成您项目的安装。
安装完成后会看到如下信息:

Running setup.py bdist_wheel for Mako ... done  Stored in directory: /root/.cache/pip/wheels/f2/5d/a3/7f044e8344fee52973a485d73bbe03cbc1d9e9716d6ac62c5eSuccessfully built pyramid-mako MakoInstalling collected packages: MarkupSafe, Jinja2, pyramid-jinja2, ipaddress, Pygments, Mako, pyramid-mako, pyramid-debugtoolbar, waitress, project1  Running setup.py develop for project1Successfully installed Jinja2-2.9.6 Mako-1.0.7 MarkupSafe-1.0 Pygments-2.2.0 ipaddress-1.0.18 project1 pyramid-debugtoolbar-4.3 pyramid-jinja2-2.7 pyramid-mako-1.0.2 waitress-1.0.2

这会运行项目中的setup.py文件,它会从您的程序入口开始(后面会提到的project1#main)遍历你项目寻找所需的所有依赖库,并下载安装他们到你的虚拟环境中,这些依赖库文件也可以被其他的脚本编译器运行,例如pshell,pserve等。

4.测试你的项目

在你进行单元测试之前,你当然需要先安装测试依赖库。
pip install -e ".[testing]"
安装完测试的依赖库之后,你就可以通过运行py.test指令来进行测试了。
py.test -q
linux系统会得到如下的输入:
2 passed in 0.47 seconds
如果你想看到覆盖率,使用:
py.test --cov -q

5.运行你的项目

项目一旦安装完成,你就可以通过pserve指令来执行你项目中的.ini文件来运行你的项目,这里我们的文件名为development.ini

pserve development.iniStarting server in PID 77171.Serving on http://localhost:6543Serving on http://localhost:6543

现在你已经可以通过本地的浏览器访问Pyramid应用了。但是如果你希望来自其他网络的用户也能访问你的应用,则需要修改development.ini中[server:main]中的内容,将它从localhost:6543 to *:6543改为*:6543(这个0.0.0.0:6543是等价的)

[server:main]use = egg:waitress#mainlisten = *:6543

现在你可以使用pserve再次启动你的应用,它现在会监听来自所有ip地址的请求,不仅仅只是监听本地ip。举个栗子,你的系统ip是192.168.1.50,你既可以用本地浏览器访问127.0.0.1:6543或192.168.1.50:6543来访问应用,来自其他网络的用户也可以通过192.168.1.50:6543来访问你的应用。

当然你也可以修改启动应用的端口,例如只需要将localhost:6543修改为localhost:8080即可从8080端口启动你的应用,不再赘述。

当你需要停止通过pserve指令启动的server服务时,可以使用CTRL+C快捷键

当你运行一个有cookiecutter创建的模板项目时,使用pserve会启动一个叫waitress的server服务器。waitress会在你通过pserve启动项目时通过简单的文本的形式打印服务内容到控制台。在项目开发时期选择waitress是非常不错的因为它足够简单。它也完全能够胜任轻量级项目的发布。本文不推荐您在没有使用过waitress之前,去使用其他的server服务器,特别是在您没有Python web开发经验的情况下。另外,几乎所有的python web服务器都是相似的,所以,如果你能使用waitress来运行你的项目,那么其他服务器也可以。所以你完全不用现在担心使用什么服务器的问题。

关于更多的启动服务的内容,参见官网的启动项目文档或参见后面的文章。

6.重载代码

在开发过程中,使用pserve--reload选项是十分有用的。当--reload跟在pserve后面时,你对项目中代码进行更改时,pserve都会自动重启你的项目让更改生效。这和每次都手动重启相比,使得开发更加方便了。

举个栗子,在linux系统上:

pserve development.ini --reloadStarting subprocess with file monitorStarting server in PID 16601.Serving on http://localhost:6543Serving on http://localhost:6543

现在,如果你更改了你项目中的任意.py或者.ini文件,你可以看到服务器自动重启了:

development.ini changed; reloading...-------------------- Restarting --------------------Starting server in PID 16602.Serving on http://localhost:6543Serving on http://localhost:6543

对于页面模板文件的修改(例如.pt或者.mak文件)不会导致服务器重启。但你可以通过在devlopment.ini文件中将pyramid.reload_templates setting选项配置为true。这样,页面模板文件出现改动时,不需要重启服务器就会立刻生效。

7.应用视图

当你通过pserve启动了你的应用以后,你就可以通过在浏览器内输入配置的ip和端口来访问你的应用页面了,如localhost:6543。你会在你的浏览器中看到这样的页面。
这里写图片描述

这是你使用cookiecutter创建项目的默认页面。如果你是在本地浏览器访问了这个页面,还可以通过这里写图片描述这样一个图标来启动调试工具,
界面如下:这里写图片描述

这与各种浏览器自带的调试工具功能大同小异,不再赘述。

8.项目结构

我们可以通过tree指令查看project1箱的结构,在project1项目中包含了一个同名的子文件夹。
这里写图片描述

我们的project1目录是你应用分发和部署的地方,它既包含了你的应用代码文件,也包含了用于分发部署和测试你应用的文件。让我们来看看各个文件的用处

 1..coveragerc用于配置测试时的覆盖率。(隐藏文件,使用ls -a 可以看到) 2. CHANGES.txt用于描述你对应用所做的更改。它通常是命令行格式的。 3. MANIFEST.in是一个分发“清单“文件,记录了当`python setup.py sdist`指令运行时应该将哪些文件包含进来。 4. README.txt从总体上描述了整个应用,它通常是命令行格式的。 5. develoment.ini是一个用于在开发过程中启动你的应用的配置文件 6. production.ini是一个在你将应用正式发布时启动你应用的配置文件 7. pytest.ini是一个测试的配置文件 8. setup.py是一个你可以用来测试和分发你的项目的文件。他是一个标准的setuptools setup.py文件。

8.1 development.ini

development.ini文件是一个PasteDeploy配置文件,支持WSGI组件。
它的目的是在你调用pserve指令时,启动并完成应用的部署配置。
一个development.ini文件大致上看起来是这样的:

#### app configuration# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html###[app:main]use = egg:project1pyramid.reload_templates = truepyramid.debug_authorization = falsepyramid.debug_notfound = falsepyramid.debug_routematch = falsepyramid.default_locale_name = enpyramid.includes =    pyramid_debugtoolbar# By default, the toolbar only appears for clients from IP addresses# '127.0.0.1' and '::1'.# debugtoolbar.hosts = 127.0.0.1 ::1#### wsgi server configuration###[server:main]use = egg:waitress#mainlisten = 0.0.0.0:6543#### logging configuration# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html###[loggers]keys = root, project1[handlers]keys = console[formatters]keys = generic[logger_root]level = INFOhandlers = console[logger_project1]level = DEBUGhandlers =qualname = project1[handler_console]class = StreamHandlerargs = (sys.stderr,)level = NOTSETformatter = generic[formatter_generic]format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s

这个文件包含了几个部分,包括[app:main],[server:main],以及其他几个和日志配置有关的部分。

[app:main]部分代表了你的Pyramid应用的配置。use选项是唯一一个在[app:main]中必须要设置的选项。他的默认配置是use=egg:project1,这其实是use=egg:peoject1#main的简写,你在setup.py文件中的entry_points属性中也能找到这句配置。它们的作用是一致的:用于标识我们应用的入口函数peoject1#main实际上是一种Python定义的使用字符串来映射python对象的方式,当我们使用pserve运行ini文件启动项目时,pserve会根据这个字符串映射去找到project1项目中的__init__.py文件中的main函数去执行(运行setup.py文件时也会去找到这个main函数作为应用入口)。这里的egg前缀是程序入口标识符。

[app:main]此部分中添加的其他设置将作为关键字参数传递给程序入口:__init__.py的main函数。例如pyramid.includes = pyramid_debugtoolbar 告诉pyramid需要导入debbugtoolbar,pyramid.reload_templates = true告诉pyramid动态加载页面模板。

简单来说:
[app:main]配置了你的项目的程序入口,在你调用pserve运行ini文件时,会根据这行配置找到__init__.py文件的main函数并返回一个应用的实例来启动你的应用。

[server:main] 的配置和[app:main]的配置非常相似,[server:main]
use = egg:waitress#main
listen = localhost:6543

表示使用waitress服务器启动应用,并监听本地ip的6543端口。

后面包含logger的配置项代表了python的logging日志标准库中的一些设置。当pserve运行了ini文件,这些设置会应用于项目日志输出。默认是将debug级别的日志输出到你的控制台。

8.2 production.ini

它几乎和development.ini是一样的,区别在于,它禁用了浏览器调试工具,过滤了所有warn级别以下的日志信息,并且关闭了页面模板自动重载功能。当您需要将应用正式发布时,适合使用production.ini来启动应用。

8.3 MANIFEST.in

用于标识您启动项目时,应该加载哪些非python文件,例如.txt .pt .html .js .css文件等,如果没有MANIFEST.in文件,项目只会加载.py结尾的纯python文件。

8.4 setup.py

import osfrom setuptools import setup, find_packageshere = os.path.abspath(os.path.dirname(__file__))with open(os.path.join(here, 'README.txt')) as f:    README = f.read()with open(os.path.join(here, 'CHANGES.txt')) as f:    CHANGES = f.read()requires = [    'plaster_pastedeploy',    'pyramid',    'pyramid_jinja2',    'pyramid_debugtoolbar',    'waitress',]tests_require = [    'WebTest >= 1.3.1',  # py3 compat    'pytest',    'pytest-cov',]setup(    name='project1',    version='0.0',    description='project1',    long_description=README + '\n\n' + CHANGES,    classifiers=[        'Programming Language :: Python',        'Framework :: Pyramid',        'Topic :: Internet :: WWW/HTTP',        'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',    ],    author='',    author_email='',    url='',    keywords='web pyramid pylons',    packages=find_packages(),    include_package_data=True,    zip_safe=False,    extras_require={        'testing': tests_require,    },    install_requires=requires,    entry_points={        'paste.app_factory': [            'main = project1:main',        ],    },)

我们项目中的setup.py文件如上所示,setup.py运行时会调用setuptools工具的setup方法,它会将文件中的参数传递给pip完成项目依赖库的安装。
你可以在文件中设置项目名称,版本等信息。
通常情况下,您只有在需要将项目分发给其他人的时候需要去修改setup.py中的属性。
当你调用
python setup.py sdist时,会在应用目录下生成一个dist目录,里面有个名为project1-0.0.tar.gz的tar.gz包。你可以将这个包分发给他人来安装应用。

8.5 project1 子文件夹

同名子文件夹中有几个文件夹和文件:

  1. __init__.py是一个用于启动应用的python文件,它包含了一个表示程序入口的用于被pserve或pshell等调用的main函数。

  2. templates目录,顾名思义,存放的是页面模板文件,这里的jinja2模板是以.pt结尾。

  3. tests.py是用于测试应用的代码

  4. views.py是处理http请求,返回响应的python文件
  5. static目录包含了一些静态文件,比如项目中的图片或是css样式文件

9.自定义包结构

不对cookiecutter工具创建的模板的默认布局做太多的更改在很多时候是不错的,这样其他的开发者能够能容易的理解您的代码。但是按照模板的布局来存放代码,并不是必须的,你也可以按照你认为好的方式来修改代码布局。

举个例子,add_view()方法需要你指定一个Python方法名或一个对象来作为一个视图。默认情况下,ciikiecutter模板会将你所有的视图方法都添加到views.py文件中。但是,如果您也可以创建一个views目录,并且为每一个视图都创建一个单独的文件。

如果你的项目包为project1,并且你想将所有的视图都放到子文件views里,那么你需要做如下3步:

  • 在你的project1包内建立一个名叫views的文件目录(和原来的views.py同级)
  • 在views目录内建立一个__init__.py文件。这个文件可以是空的,只是用于告诉Python这个目录是一个包
  • 将views.py的内容移动到views文件夹的blog.py文件内,由于页面模板文件templates还是在project1目录下,因此blog.py中的模板的引用必须使用绝对路径(project1:templates/mytemplate.jinja2)

现在你可以继续在views目录添加其他的.py文件用于响应视图的请求,也可以继续在blog.py中继续添加其他方法来响应不同的视图请求。

10.总结

这篇文档详细介绍了如何创建一个Pyramid项目,以及项目内文件的用途,项目的安装,分发运行。内容很多,可以截取需要的信息查看,或查看官方文档

阅读全文
0 0
原创粉丝点击