创建一个 Pyramid 项目¶
正如我们看到的 创建您的第一个 Pyramid 应用 ,可以创建一个 Pyramid 完全手动应用。但是,使用我们的 cookiecutter 生成基本 Pyramid project .
项目是至少包含一个python的目录 package . 你会使用 Pyramid CookiCutter创建一个项目,您将在项目内部的包中创建应用程序逻辑。即使您的应用程序非常简单,也可以将驱动应用程序的代码放在包中,因为(1)包更容易用新代码扩展,(2)包中的应用程序也可以比不在包中的应用程序更容易分发。
塔架项目提供了 Pyramid 可用于生成项目的CookieCutter。我们的cookiecutter允许多个配置选项来生成您试图构建的应用程序类型。
使用 cookiecutter 可以安装的命令。
参见
创建项目¶
在 安装 Pyramid ,您通过 venv 命令。我们称之为虚拟环境目录 env 并设置环境变量 VENV 走向它的道路。
我们假设你 previously installed cookiecutter ,遵循其安装说明。
当我们调用 cookiecutter ,它将创建一个表示项目的目录。
我们假设我们当前的工作目录是 VENV .
在所有平台上,使用cookiecutter生成一个项目。
cookiecutter gh:Pylons/pyramid-cookiecutter-starter --checkout main
If prompted for the first item, accept the default yes 按回车键。
You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: myproject
repo_name [myproject]: myproject
Select template_language:
1 - jinja2
2 - chameleon
3 - mako
Choose from 1, 2, 3 [1]: 1
Select backend:
1 - none
2 - sqlalchemy
3 - zodb
Choose from 1, 2, 3 [1]: 1
然后我们运行以下命令。
在UNIX上:
# Reset our environment variable for a new virtual environment.
export VENV=~/env/myproject/env
# Change directory into your newly created project.
cd myproject
# Create a new virtual environment...
python3 -m venv $VENV
# ...where we upgrade packaging tools.
$VENV/bin/pip install --upgrade pip setuptools
或在Windows上:
# Reset our environment variable for a new virtual environment.
set VENV=c:\env\myproject\env
# Change directory into your newly created project.
cd myproject
# Create a new virtual environment...
python -m venv %VENV%
# ...where we upgrade packaging tools.
%VENV%\Scripts\pip install --upgrade pip setuptools
由于调用 cookiecutter 命令,一个名为 myproject 创建。那个目录是 project 目录。这个 setup.py 该目录中的文件可用于分发应用程序,或安装应用程序进行部署或开发。
安 .ini 文件命名 development.ini 将在项目目录中创建。你要用这个 .ini 用于配置服务器、运行应用程序和调试应用程序的文件。它包含启用交互式调试器和 settings 为发展而优化。
另一 .ini 文件命名 production.ini 也将在项目目录中创建。它包含禁用任何交互式调试器的配置(以防止不适当的访问和泄漏),并关闭许多调试设置。您可以使用此文件将应用程序投入生产。
这个 myproject 项目目录包含名为 myproject 代表一条 Python package 这很简单 Pyramid 示例代码。在这里您将编辑应用程序的python代码和模板。
我们在虚拟环境目录旁边的目录中创建了这个项目。但是,请注意,这不是强制性的。项目目录可以或多或少地放到文件系统的任何地方。您不需要将它放在一个特殊的“Web服务器”目录中。您可以将它放在虚拟环境目录中。作者主要使用Linux,并倾向于将他创建的项目目录放在 ~/projects 目录。在Windows上,最好将项目目录放在不包含空格字符的目录中,这样做是明智的。 避免 包含,即, My Documents . 因此,作者在使用Windows时,只需将项目放入 C:\projects .
警告
你需要避免使用 cookiecutter 创建与Python标准库组件同名的项目。特别是,这意味着您应该避免使用这些名称 site 或 test ,两者都与Python标准库包冲突。你也应该避免使用这个名字 pyramid 这将与金字塔本身发生冲突。
安装新创建的用于开发的项目¶
要安装新创建的用于开发的项目,您应该 cd 到新创建的项目目录,并使用来自 virtual environment 创建时间: 安装 Pyramid 调用命令 pip install -e . ,以开发模式安装项目 (-e 用于“可编辑”)进入当前目录 (. )
命名文件 setup.py 将在cookiecutter生成的项目目录的根目录中。这个 python 你在召唤的应该是生活在 bin (或) Scripts 在Windows上)虚拟python环境的目录。您终端的当前工作目录 must 是新创建的项目目录。
在UNIX上:
$VENV/bin/pip install -e .
或在Windows上:
%VENV%\Scripts\pip install -e .
在Unix上运行此命令的已删除输出如下所示:
Running setup.py develop for myproject
Successfully installed Jinja2-2.11.2 Mako-1.1.3 MarkupSafe-1.1.1 PasteDeploy-2.1.1 Pygments-2.7.3 hupper-1.10.2 myproject plaster-1.0 plaster-pastedeploy-0.7 pyramid-1.10.5 pyramid-debugtoolbar-4.9 pyramid-jinja2-2.8 pyramid-mako-1.1.0 repoze.lru-0.7 translationstring-1.4 venusian-3.0.0 waitress-1.4.4 webob-1.8.6 zope.deprecation-4.4.0 zope.interface-5.2.0
这将安装一个 distribution 将项目表示为虚拟环境解释器的库集,以便 import 语句和其他控制台脚本,如 pserve , pshell , proutes 和 pviews .
为应用程序运行测试¶
要为应用程序运行单元测试,必须首先安装测试依赖项。
在UNIX上:
$VENV/bin/pip install -e ".[testing]"
在Windows上:
%VENV%\Scripts\pip install -e ".[testing]"
一旦安装了测试需求,就可以使用 pytest 刚安装在 bin 虚拟环境的目录。
在UNIX上:
$VENV/bin/pytest -q
在Windows上:
%VENV%\Scripts\pytest -q
以下是在Unix上运行测试的示例输出:
$VENV/bin/pytest -q
....
4 passed in 0.31s
测试本身在 tests 在您的 cookiecutter -生成的项目。在这个由 pyramid-cookiecutter-starter cookiecutter,只有几个样本测试存在。
备注
这个 -q 选项传递给 pytest 命令将输出限制为点流。如果你不通过 -q 您将看到详细的测试结果输出(这通常不是很有用)。
或者,如果您希望看到测试覆盖率,请通过 --cov 选择权 pytest :
$VENV/bin/pytest --cov -q
cookiecutters包括的配置默认值 pytest 测试覆盖率。这些配置文件是 pytest.ini 和 .coveragerc ,位于包的根目录。如果没有这些默认值,我们将需要指定要在其上运行测试和覆盖率的模块的路径。
$VENV/bin/pytest --cov=myproject myproject tests -q
参见
见 pytest 的文档 How to invoke pytest 或调用 pytest -h 查看它的全部选项。
运行项目应用程序¶
参见
另见输出 pserve --help .
一旦为开发安装了项目,就可以使用 pserve 针对生成的配置文件的命令。在我们的例子中,这个文件名为 development.ini .
在UNIX上:
$VENV/bin/pserve development.ini
在Windows上:
%VENV%\Scripts\pserve development.ini
以下是运行 pserve 在UNIX上:
$VENV/bin/pserve development.ini
Starting server in PID 77171.
Serving on http://localhost:6543
Serving on http://localhost:6543
访问受到限制,只有运行在与金字塔相同机器上的浏览器才能访问金字塔应用程序。但是,如果要打开对同一网络上其他计算机的访问,请编辑 development.ini 文件,并替换 listen 价值在 [server:main] 节,将其从 localhost:6543 到 *:6543 (这相当于 0.0.0.0:6543 [::]:6543 )例如:
[server:main]
use = egg:waitress#main
listen = *:6543
现在当你使用 pserve 要启动应用程序,它将响应上的请求 all 您的系统拥有的IP地址,而不仅仅是请求 localhost . 这就是 0.0.0.0 在里面 serving on http://0.0.0.0:6543 手段。服务器将响应对 127.0.0.1 以及任何外部IP地址。例如,您的系统可能被配置为具有外部IP地址 192.168.1.50 . 如果是这样的话,如果你使用一个与金字塔运行在同一系统上的浏览器,它将能够通过 http://127.0.0.1:6543/ 以及通过 http://192.168.1.50:6543/ . 然而, 其他人 在同一网络上的其他计算机上,也可以通过访问访问访问浏览器中的金字塔应用程序。 http://192.168.1.50:6543/ . 如果使用ipv6,情况也是如此。 [::] 意思与 0.0.0.0 但是对于ipv6协议。
您可以更改服务器运行的端口,方法是更改 development.ini 文件。例如,您可以更改 listen = localhost:6543 线在 development.ini 文件的 [server:main] 截面至 listen = localhost:8080 在端口8080而不是端口6543上运行服务器。
您可以通过按关闭以这种方式启动的服务器 Ctrl-C (或) Ctrl-Break 在Windows上)。
当从cookiecutter创建项目时,用于运行金字塔应用程序的默认服务器命名为 Waitress . 这个服务器就是打印 Serving on... 运行时排队 pserve . 在开发过程中使用这个服务器是个好主意,因为它非常简单。它也可以用于轻型生产。在默认服务器下完成一些开发工作之前,不建议在其他服务器下设置应用程序,特别是在您还没有使用PythonWeb开发经验的情况下。python web服务器的设置可能很复杂,在试图优化它或使它“更像生产”之前,您应该对应用程序在默认环境中工作有一定的信心。在几个小时内尝试设置一个非默认服务器,而实际上却没有开始进行任何开发,这非常容易被偏离轨道。关于python web服务器的一个好处是它们在很大程度上是可互换的,所以如果您的应用程序在默认服务器下工作,那么如果您最终选择使用不同的服务器,它几乎肯定会在生产中的任何其他服务器下工作。现在别担心。
有关启动过程的详细信息,请参阅 启动 . 有关影响启动和运行时行为的环境变量和配置文件设置的详细信息,请参阅 环境变量和 .ini 文件设置 .
再装入代码¶
在开发过程中,运行 pserve 利用其 --reload 选择权。什么时候? --reload 传递给 pserve ,对项目使用的任何python模块的更改都将导致服务器重新启动。这通常使开发更容易,因为在 Pyramid 在服务器重新启动之前,应用程序不会生效。
例如,在UNIX上:
$VENV/bin/pserve development.ini --reload
Starting monitor for PID 36224.
Starting server in PID 36224.
Serving on http://localhost:6543
Serving on http://localhost:6543
现在,如果您对任何项目的 .py 文件或 .ini 文件,您将看到服务器自动重新启动:
/file-path-to/myproject/development.ini changed; reloading ...
Gracefully killing the server.
Starting monitor for PID 36286.
Starting server in PID 36286.
Serving on http://localhost:6543
Serving on http://localhost:6543
对模板文件的更改(例如 .pt 或 .mak 文件)不会导致服务器重新启动。对模板文件的更改不需要重新启动服务器,只要 pyramid.reload_templates 设置在 development.ini 文件是 true . 当此设置为 true 将在不重新启动服务器的情况下立即生效。
查看应用程序¶
一旦您的应用程序运行通过 pserve 你可以参观一下 http://localhost:6543/ 在您的浏览器中。您将在浏览器中看到以下图像中显示的内容:
这是访问未修改的 cookiecutter 生成 pyramid-cookiecutter-starter 浏览器中的应用程序。
调试工具栏¶
如果你点击 Pyramid logo位于页面右上角,将打开一个新的目标窗口,显示一个调试工具栏,在您开发时提供各种细节。此徽标将浮动在 Pyramid 当您开发一个应用程序时,并允许您根据需要显示工具栏。
If you don't see the Pyramid logo on the top right of the page, it means you're
browsing from a system that does not have debugging access. By default, for
security reasons, only a browser originating from localhost (127.0.0.1)
can see the debug toolbar. To allow your browser on a remote system to access
the server, add a line within the [app:main] section of the
development.ini file in the form debugtoolbar.hosts = X.X.X.X. For
example, if your Pyramid application is running on a remote system, and you're
browsing from a host with the IP address 192.168.1.1, you'd add something
like this to enable the toolbar when your system contacts Pyramid:
[app:main]
# ... other settings ...
debugtoolbar.hosts = 192.168.1.1
有关调试工具栏允许您执行的操作的详细信息,请参阅 documentation for pyramid_debugtoolbar .
当您使用 production.ini 文件而不是 development.ini 运行应用程序的ini文件。
您还可以通过编辑来关闭调试工具栏。 development.ini 并发表评论。例如,而不是:
1[app:main]
2# ... elided configuration
3pyramid.includes =
4 pyramid_debugtoolbar
在 pyramid_debugtoolbar 线:
1[app:main]
2# ... elided configuration
3pyramid.includes =
4# pyramid_debugtoolbar
然后重新启动应用程序以查看工具栏是否已关闭。
请注意,如果您对 pyramid_debugtoolbar 线 # must 在第一列。如果您将它放在其他地方,然后尝试重新启动应用程序,您将收到一个以如下方式结束的错误:
ImportError: No module named #pyramid_debugtoolbar
项目结构¶
这个 pyramid-cookiecutter-starter CookiCutter生成了一个 project (命名) myproject ,其中包含一条 Python package . 包装是 also 已命名 myproject ;cookiecutter生成一个包含共享其名称的包的项目。
所有 Pyramid cookiecutter -生成的项目具有相似的结构。这个 myproject 我们生成的项目具有以下目录结构:
myproject
├── .coveragerc
├── .gitignore
├── CHANGES.txt
├── MANIFEST.in
├── README.txt
├── development.ini
├── myproject
│ ├── __init__.py
│ ├── routes.py
│ ├── static
│ │ ├── pyramid-16x16.png
│ │ ├── pyramid.png
│ │ └── theme.css
│ ├── templates
│ │ ├── 404.jinja2
│ │ ├── layout.jinja2
│ │ └── mytemplate.jinja2
│ └── views
│ ├── __init__.py
│ ├── default.py
│ └── notfound.py
├── production.ini
├── pytest.ini
├── setup.py
├── testing.ini
└── tests
├── __init__.py
├── conftest.py
├── test_functional.py
└── test_views.py
tests 套餐¶
这个 conftest.py , test_functional.py 和 test_views.py 中的模块 tests 包中包含应用程序的测试。
1import os
2from pyramid.paster import get_appsettings
3from pyramid.scripting import prepare
4from pyramid.testing import DummyRequest, testConfig
5import pytest
6import webtest
7
8from myproject import main
9
10
11def pytest_addoption(parser):
12 parser.addoption('--ini', action='store', metavar='INI_FILE')
13
14@pytest.fixture(scope='session')
15def ini_file(request):
16 # potentially grab this path from a pytest option
17 return os.path.abspath(request.config.option.ini or 'testing.ini')
18
19@pytest.fixture(scope='session')
20def app_settings(ini_file):
21 return get_appsettings(ini_file)
22
23@pytest.fixture(scope='session')
24def app(app_settings):
25 return main({}, **app_settings)
26
27@pytest.fixture
28def testapp(app):
29 testapp = webtest.TestApp(app, extra_environ={
30 'HTTP_HOST': 'example.com',
31 })
32
33 return testapp
34
35@pytest.fixture
36def app_request(app):
37 """
38 A real request.
39
40 This request is almost identical to a real request but it has some
41 drawbacks in tests as it's harder to mock data and is heavier.
42
43 """
44 with prepare(registry=app.registry) as env:
45 request = env['request']
46 request.host = 'example.com'
47 yield request
48
49@pytest.fixture
50def dummy_request():
51 """
52 A lightweight dummy request.
53
54 This request is ultra-lightweight and should be used only when the request
55 itself is not a large focus in the call-stack. It is much easier to mock
56 and control side-effects using this object, however:
57
58 - It does not have request extensions applied.
59 - Threadlocals are not properly pushed.
60
61 """
62 request = DummyRequest()
63 request.host = 'example.com'
64
65 return request
66
67@pytest.fixture
68def dummy_config(dummy_request):
69 """
70 A dummy :class:`pyramid.config.Configurator` object. This allows for
71 mock configuration, including configuration for ``dummy_request``, as well
72 as pushing the appropriate threadlocals.
73
74 """
75 with testConfig(request=dummy_request) as config:
76 yield config
1def test_root(testapp):
2 res = testapp.get('/', status=200)
3 assert b'Pyramid' in res.body
4
5def test_notfound(testapp):
6 res = testapp.get('/badurl', status=404)
7 assert res.status_code == 404
1from myproject.views.default import my_view
2from myproject.views.notfound import notfound_view
3
4
5def test_my_view(app_request):
6 info = my_view(app_request)
7 assert app_request.response.status_int == 200
8 assert info['project'] == 'myproject'
9
10def test_notfound_view(app_request):
11 info = notfound_view(app_request)
12 assert app_request.response.status_int == 404
13 assert info == {}
样品 conftest.py 配置和文件包含fixture。样品 test_functional.py 文件中定义了两个功能测试。样品 test_views.py 文件中定义了两个单元测试。这些测试在运行时执行 pytest -q . 在构建应用程序时,可以在此处添加更多测试。您不需要编写要使用的测试 Pyramid . 提供这些文件只是为了方便和举例。
见 单元、集成和功能测试 关于写作的更多信息 Pyramid 单元测试。
这个 myproject Project¶
这个 myproject project 目录是应用程序的分发和部署包装。它包含两个 myproject package 表示应用程序以及用于描述、运行和测试应用程序的文件。
.coveragerc配置运行测试时的覆盖率。.gitignore告诉Git从源代码版本控制中忽略哪些文件和目录。CHANGES.txt描述您对应用程序所做的更改。它是按惯例写的 reStructuredText 格式。MANIFEST.in是一个 distutils “manifest”文件,命名包的源分发中应包含哪些文件python setup.py sdist运行。README.txt一般描述应用程序。它是按惯例写的 reStructuredText 格式。development.ini是一个 PasteDeploy 可用于在开发期间执行应用程序的配置文件。production.ini是一个 PasteDeploy 可用于在生产配置中执行应用程序的配置文件。pytest.ini是用于运行测试的配置文件。setup.py是用于测试和分发应用程序的文件。这是一个标准 Setuptoolssetup.py文件。testing.ini是一个 PasteDeploy 可用于执行应用程序测试的配置文件。tests包含应用程序的单元和功能测试代码的包。
development.ini¶
这个 development.ini 文件是 PasteDeploy 配置文件。其目的是指定在调用时要运行的应用程序 pserve 以及提供给该应用程序的部署设置。
生成的 development.ini 文件如下:
1###
2# app configuration
3# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
4###
5
6[app:main]
7use = egg:myproject
8
9pyramid.reload_templates = true
10pyramid.debug_authorization = false
11pyramid.debug_notfound = false
12pyramid.debug_routematch = false
13pyramid.default_locale_name = en
14pyramid.includes =
15 pyramid_debugtoolbar
16
17# By default, the toolbar only appears for clients from IP addresses
18# '127.0.0.1' and '::1'.
19# debugtoolbar.hosts = 127.0.0.1 ::1
20
21###
22# wsgi server configuration
23###
24
25[server:main]
26use = egg:waitress#main
27listen = localhost:6543
28
29###
30# logging configuration
31# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
32###
33
34[loggers]
35keys = root, myproject
36
37[handlers]
38keys = console
39
40[formatters]
41keys = generic
42
43[logger_root]
44level = INFO
45handlers = console
46
47[logger_myproject]
48level = DEBUG
49handlers =
50qualname = myproject
51
52[handler_console]
53class = StreamHandler
54args = (sys.stderr,)
55level = NOTSET
56formatter = generic
57
58[formatter_generic]
59format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
此文件包含几个部分,包括 [app:main] , [server:main] 以及与日志配置相关的其他几个部分。
这个 [app:main] 部分表示您的 Pyramid 应用。这个 use 设置是在 [app:main] 部分。它的默认值, egg:myproject ,指示我们的MyProject项目包含应提供服务的应用程序。添加到此节的其他设置将作为关键字参数传递给名为 main 在我们的包裹里 __init__.py 模块。通过向该部分添加更多设置,可以向应用程序提供启动时间配置参数。
参见
见 入口点和PasteDeploy .ini 文件夹 有关 use = egg:myproject 此部分中的值。
这个 pyramid.reload_templates 设置在 [app:main] 截面是 Pyramid -传入框架的特定设置。如果它存在,它的值是 true ,支持的模板更改将不需要检测到应用程序重新启动。见 自动重新加载模板 更多信息。
警告
这个 pyramid.reload_templates 对于生产应用程序,应关闭选项,因为打开模板时,模板呈现速度会减慢。
这个 pyramid.includes 设置在 [app:main] 部分告诉金字塔从另一个包“包括”配置。在这种情况下, pyramid.includes = pyramid_debugtoolbar 告诉金字塔包含来自 pyramid_debugtoolbar 包裹。这将在开发模式下打开调试面板,可通过单击打开该面板。 Pyramid 屏幕右上角的徽标。包含调试工具栏还可以在发生错误时交互式调试异常。
本节中可能存在各种其他设置,这些设置与调试或影响 Pyramid 应用。见 环境变量和 .ini 文件设置 有关这些设置的详细信息。
名字 main 在里面 [app:main] 表示这是由运行的默认应用程序 pserve 当针对该配置文件调用它时。名字 main 是PasteDeploy使用的约定,表示它是默认应用程序。
这个 [server:main] 配置文件的部分配置在TCP端口6543上侦听的wsgi服务器。它被配置为只在本地主机上侦听 (127.0.0.1 )
后面的部分 # logging configuration 表示python的标准库 logging 应用程序的模块配置。默认配置将应用程序日志记录输出发送到终端的标准错误输出。有关详细信息,请参阅 登录 .
见 PasteDeploy 有关您可以放入其中的其他类型内容的详细信息,请参阅文档。 .ini 文件,如其他应用程序, middleware 交替 WSGI 服务器实现。
production.ini¶
这个 production.ini 文件是 PasteDeploy 配置文件的用途与 development.ini . 但是,它禁用调试工具栏,并筛选除警告级别以上的日志消息以外的所有日志消息。它还关闭模板开发选项,这样在更改模板时不会自动重新加载模板,并关闭所有调试选项。此文件适合使用,而不是 development.ini 当您将应用程序投入生产时。
使用它很重要 production.ini (和 not development.ini )对应用程序进行基准测试并将其投入生产。 development.ini 使用调试工具栏配置系统,该工具栏有助于开发,但包含此工具栏会将页面呈现时间降低一个数量级以上。如果配置不正确,调试工具栏也是一个潜在的安全风险。
testing.ini¶
这个 testing.ini 文件是 PasteDeploy 配置文件的用途与 development.ini . 它类似于 development.ini ,但经过优化以减少测试执行时间。它禁用调试工具栏和模板的自动重新加载,因为这会减慢测试执行速度。此文件适用于代替 development.ini 当您运行应用程序的测试时。
MANIFEST.in¶
这个 MANIFEST.in 文件是 distutils 配置文件,指定在 distribution 在运行时创建金字塔项目的 python setup.py sdist . 由于默认值中包含的信息 MANIFEST.in ,金字塔项目的列表将包括 .txt 文件夹, .ini 文件夹, .rst 文件、图形文件和模板文件,以及 .py 文件夹。请参阅Python打包权威的Python打包用户指南 Including files in source distributions with MANIFEST.in 有关的语法和用法的详细信息 MANIFEST.in .
不存在 MANIFEST.in 文件或不将源代码签入版本控制存储库, setup.py sdist 仅限地点 python源文件 (文件结尾为 .py 扩展)到由 python setup.py sdist . 这意味着,例如,如果您的项目没有签入与SetupTools兼容的源代码管理系统,并且您的项目目录没有包含 MANIFEST.in 文件告诉 sdist 机械包括 *.pt 文件 myproject/templates/mytemplate.pt 文件不会包含在生成的tarball中。
金字塔炊事员生成的项目包括默认 MANIFEST.in 文件。这个 MANIFEST.in 文件包含的声明告诉它包含类似 *.pt , *.css 和 *.js 在生成的tarball中。如果包含扩展名不是项目的 MANIFEST.in 如果不使用与安装工具兼容的版本控制系统,则需要编辑 MANIFEST.in 归档并包含包含新文件所需的语句。在前面提到的《Python打包用户指南》中,请参见 MANIFEST.in commands 有关如何执行此操作的详细信息。
您也可以删除 MANIFEST.in 从你的项目中 Setuptools 一种功能,只需将检入版本控制系统的所有文件放入生成的tarball中即可。要实现这一点,请将您希望与应用程序的python文件一起分发的所有文件检查到Subversion中。在你这样做之后,当你重新运行 setup.py sdist ,签入版本控制系统的所有文件将包含在tarball中。如果不使用Subversion,而是使用其他版本控制系统,则可能需要安装 Setuptools 附加如 setuptools-git 或 setuptools-hg 以使此行为正常工作。
setup.py¶
这个 setup.py 文件是 Setuptools 安装文件。它用于定义安装包和测试依赖项以及分发应用程序的需求。
备注
setup.py 实际上是Python开发人员用来分发可重用代码的标准。你可以阅读更多关于 setup.py 文件及其在 Python Packaging User Guide 和 Setuptools documentation .
我们生成的 setup.py 如下所示:
1import os
2
3from setuptools import setup, find_packages
4
5here = os.path.abspath(os.path.dirname(__file__))
6with open(os.path.join(here, 'README.txt')) as f:
7 README = f.read()
8with open(os.path.join(here, 'CHANGES.txt')) as f:
9 CHANGES = f.read()
10
11requires = [
12 'plaster_pastedeploy',
13 'pyramid',
14 'pyramid_jinja2',
15 'pyramid_debugtoolbar',
16 'waitress',
17]
18
19tests_require = [
20 'WebTest',
21 'pytest',
22 'pytest-cov',
23]
24
25setup(
26 name='myproject',
27 version='0.0',
28 description='myproject',
29 long_description=README + '\n\n' + CHANGES,
30 classifiers=[
31 'Programming Language :: Python',
32 'Framework :: Pyramid',
33 'Topic :: Internet :: WWW/HTTP',
34 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
35 ],
36 author='',
37 author_email='',
38 url='',
39 keywords='web pyramid pylons',
40 packages=find_packages(exclude=['tests']),
41 include_package_data=True,
42 zip_safe=False,
43 extras_require={
44 'testing': tests_require,
45 },
46 install_requires=requires,
47 entry_points={
48 'paste.app_factory': [
49 'main = myproject:main',
50 ],
51 },
52)
这个 setup.py 文件调用 Setuptools setup 函数,根据传递给 pip 在命令行上。
在该函数调用的参数中,保存有关应用程序的信息。尽管这超出了本文档的范围,但要解释有关 Setuptools 设置文件,我们将提供本节中此文件中存在的内容的旋风式教程。
应用程序的名称可以是任何字符串;它在 name 字段。版本号在 version 价值。简要说明见 description 字段。这个 long_description 通常是 README 和 CHANGES 附加在一起的文件。这个 classifiers 字段是 Trove classifiers 描述您的应用程序。 author 和 author_email 是可能不需要任何描述的文本字段。 url 应该指向应用程序项目的URL(如果有)的字段。 keywords 是描述您的项目的关键字。 packages=find_packages(exclude=['tests']) 使打包应用程序时找到项目中的所有包。 include_package_data 如果将这些文件签入版本控制,则在打包应用程序时将包括非python文件。 zip_safe=False 表示此包作为压缩鸡蛋使用不安全;相反,它将始终作为目录解包,这更方便。 extras_require 是一个Python字典,它定义运行测试所需安装的内容。 install_requires 指示此包依赖于 pyramid 包裹。我们检查了 entry_points 在我们的讨论中 development.ini 文件;此文件定义 main 表示项目应用程序的入口点。
通常你只需要考虑 setup.py 当将应用程序分发给其他人、添加python包依赖项或为自己的使用对应用程序进行版本控制时,文件。为了好玩,您现在可以尝试以下命令:
$VENV/bin/python setup.py sdist
这将在 dist 名为的子目录 myproject-0.0.tar.gz . 你可以把这个tarball发送给其他想要安装和使用你的应用程序的人。
这个 myproject Package¶
这个 myproject package 住在里面 myproject project . 它包含:
安
__init__.py文件表示这是一个python package . 它还包含帮助用户运行应用程序的代码,包括main用作命令入口点的函数,例如pserve,pshell,pviews以及其他。A
templates目录,其中包含 Jinja2 (或其他类型)模板。A
routes.py模块,其中包含应用程序的路由代码。A
views包,其中包含应用程序的视图代码。A
static目录,其中包含静态文件,包括图像和CSS。
这些纯粹是厨师制定的惯例。 Pyramid 不要坚持用任何特殊的方式命名事物。然而,遵循金字塔标准来命名通常是个好主意,这样其他金字塔开发人员就可以在需要帮助时快速地了解您的代码。
__init__.py¶
我们需要一个小的python模块来配置我们的应用程序,并为我们的 PasteDeploy .ini 文件。这是名为 __init__.py . 存在 __init__.py 同时通知python包含它的目录是 包裹 .
1from pyramid.config import Configurator
2
3
4def main(global_config, **settings):
5 """ This function returns a Pyramid WSGI application.
6 """
7 with Configurator(settings=settings) as config:
8 config.include('pyramid_jinja2')
9 config.include('.routes')
10 config.scan()
11 return config.make_wsgi_app()
第1行导入 Configurator 类从
pyramid.config我们以后会用到的。第4-11行定义了一个名为
main返回一个 Pyramid WSGi应用程序。此函数将由 PasteDeploy 运行后的框架pserve.这个
main函数配置应用程序。第7行打开一个上下文管理器,其中包含 Configurator .
第8行添加了对jinja2模板绑定的支持,允许我们使用
.jinja2延伸。第9行包括
routes.py模块。第10行调用
config.scan(),它获取包中其他位置声明的视图注册(在本例中,在views.py模块)。第11行返回 WSGI 应用于函数调用方(金字塔的pserver)。
routes.py¶
这个 routes.py 模块包含在 main 在我们的功能 __init__.py . 它注册一个视图和一个路由。
1def includeme(config):
2 config.add_static_view('static', 'static', cache_max_age=3600)
3 config.add_route('home', '/')
第2行注册一个静态视图,它将从 myproject:static asset specification (the static 目录 myproject 包装)。
第3行增加了 route 到配置。此路由稍后由中的视图使用 views 模块。
views 包裹¶
在一个 Pyramid 应用程序由 查看可调用 . 一 view callable 是一个 Pyramid Web应用程序开发人员;它是接受 request 它返回一个 response .
我们的项目有一个 views 包,因为它是包含 __init__.py 文件。这个 __init__.py 文件碰巧没有内容,尽管它可以作为一个项目开发。
我们有两个视图模块 views 包裹。让我们来看一看 default.py .
1from pyramid.view import view_config
2
3
4@view_config(route_name='home', renderer='myproject:templates/mytemplate.jinja2')
5def my_view(request):
6 return {'project': 'myproject'}
第4-6行定义并注册A view callable 已命名 my_view. The function named my_view is decorated with a view_config decorator (which is processed by the config.scan() line in our __init__.py). The view_config decorator asserts that this view be found when a route named home is matched. In our case, because our routes.py maps the route named home to the URL pattern /, this route will match when a visitor visits the root URL. The view_config decorator also names a `` 呈现器``,在本例中,它是一个模板,将用于呈现可调用视图的结果。此特定视图声明指向 myproject:templates/mytemplate.jinja2 ,这是一个 asset specification 它指定了 mytemplate.jinja2 文件内 templates 目录 myproject 包裹。还有第二种形式的资产规范:相对资产规范。在某些情况下,可以在包的名称中省略“在某些情况下,可以省略包的绝对名称”。例如,您可以使用 ../templates/mytemplate.jinja2 . 指向的模板文件是 Jinja2 模板文件 (templates/mytemplate.jinja2 )
这个视图可调用函数被传递一条信息: request . 这个 请求 是的实例 WebOb Request 类,表示浏览器对服务器的请求。
此视图配置为调用 renderer 在模板上。视图返回的字典(第6行)提供了生成HTML时呈现器替换到模板中的值。然后,渲染器返回 response .
备注
字典提供的值 template S
现在让我们看看 notfound.py .
1from pyramid.view import notfound_view_config
2
3
4@notfound_view_config(renderer='myproject:templates/404.jinja2')
5def notfound_view(request):
6 request.response.status = 404
7 return {}
此文件类似于 default.py . 它只返回一个 404 对模板的响应状态和空字典位于 myproject:templates/404.jinja2 .
备注
当应用程序与cookiecutter一起运行时 default development.ini 配置, logging is set up 帮助调试。如果引发异常,则在 the console running the server . 阿尔索 print() 语句可以插入到应用程序中进行调试,以便将输出发送到此控制台。
备注
development.ini 具有控制如何重新加载模板的设置, pyramid.reload_templates .
当设置为
True(就像在厨房里一样)development.ini,更改后的模板将自动重新加载,而无需重新启动服务器。这在开发时很方便,但会降低模板渲染速度。当设置为
False(默认值),更改模板需要重新启动服务器才能重新加载模板。生产应用程序应使用pyramid.reload_templates = False.
参见
也见 正在写入使用渲染器的视图可调用文件 有关视图、渲染器和模板如何关联和协作的详细信息。
参见
金字塔还可以动态重新加载更改后的python文件。也见 再装入代码 .
参见
也见 调试工具栏 它提供了对应用程序内部的交互访问,并且,如果发生异常,允许交互访问从Python解释器返回的执行堆栈帧。
static¶
此目录包含支持 layout.jinja2 模板。它包括CSS和图像。
templates/layout.jinja2¶
这是基本布局内容。它包含内容块的单个标记。其他模板继承其内容,为Web应用程序提供布局。它的内容太长,无法在此显示,但这里有一个摘录:
34 <div class="col-md-10">
35 {% block content %}
36 <p>No content</p>
37 {% endblock content %}
38 </div>
templates/mytemplate.jinja2¶
这是内容 Jinja2 项目中存在的模板。它被调用引用 @view_config 作为 renderer 的 my_view 在中查看可调用 views/default.py 文件。见 正在写入使用渲染器的视图可调用文件 有关渲染器的详细信息。它继承(“扩展”)所提供的HTML layout.jinja2 ,将内容块替换为其自己的内容。
1{% extends "layout.jinja2" %}
2
3{% block content %}
4<div class="content">
5 <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1>
6 <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, a Pyramid application generated by<br><span class="font-normal">Cookiecutter</span>.</p>
7</div>
8{% endblock content %}
模板由视图配置访问和使用,有时由视图函数本身访问和使用。见 直接使用模板 和 通过配置用作呈现器的模板 .
templates/404.jinja2¶
此模板类似于 mytemplate.jinja2 但是有一些不同。它被调用引用 @notfound_view_config 作为 renderer 的 notfound_view 在中查看可调用 views/notfound.py 文件。它继承了由提供的HTML layout.jinja2 ,将内容块替换为其自己的内容。
1{% extends "layout.jinja2" %}
2
3{% block content %}
4<div class="content">
5 <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1>
6 <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p>
7</div>
8{% endblock content %}
修改包结构¶
对于您的应用程序的代码布局来说,最好不要过分偏离可接受的金字塔cookiecutter默认值。如果您不经常改变事情,其他金字塔编码器将能够更快地理解您的应用程序。然而,Cookiecutter为您所做的代码布局选择绝不是不可思议的或必需的。尽管任何Cookiecutter都为您做出了选择,但是您可以决定以任何您认为合适的方式来布局代码。
例如,名为 add_view() 要求您通过 dotted Python name 或直接对象引用,作为要用作视图的类或函数。默认情况下, starter CookiCutter会让你创建一个 views 目录,并为每个视图或相关视图集合添加一个文件。但是,创建一个 views.py 在包中进行模块化,并向其中添加视图函数。
无论您喜欢什么结构,只要您使用 @view_config 与一起注册视图的指令 config.scan() ,它们将在应用程序重新启动时自动提取。
使用交互式shell¶
可以使用 pshell 命令加载具有类似配置的python解释器提示,如果通过 pserve . 这是一个有用的调试工具。见 pshell :交互式Shell 了解更多详细信息。
这是什么 pserve 事情¶
由a生成的代码 Pyramid cookiecutter假定您将使用 pserve 命令在进行开发时启动应用程序。 pserve 是一个读取 PasteDeploy .ini 文件(例如, development.ini ,并将服务器配置为 Pyramid 基于文件中数据的应用程序。
pserve 决不是唯一的启动和服务 Pyramid 应用。正如我们看到的 创建您的第一个 Pyramid 应用 , pserve 根本不需要调用来运行 Pyramid 应用。使用 pserve 运行一个 Pyramid 应用程序是纯常规的,基于它的CookieCutter的输出。但我们强烈建议使用 pserve 在开发应用程序时,因为许多其他方便的自省命令(例如 pviews , prequest , proutes 以及其他)的配置可用性 .ini 文件格式。它还配置金字塔日志,并提供 --reload 切换以方便在代码更改时重新启动服务器。
使用备用wsgi服务器¶
金字塔炊事员生成使用 Waitress WSGI服务器。服务生是一个适合开发和轻生产使用的服务器。它既不是最快的,也不是最有特色的wsgi服务器。相反,它的主要功能是在金字塔需要运行的所有平台上工作,从金字塔的开发人员的角度来看,它是默认服务器的一个很好的选择。
任何wsgi服务器都可以运行 Pyramid 应用。但我们建议您坚持使用默认的服务器进行开发,并等待研究其他服务器选项,直到您准备好将应用程序部署到生产环境。除非出于某种原因需要在非本地系统上开发,否则在准备部署之前,研究备用服务器选项通常会分散您的注意力。但是我们建议在您完全控制的本地系统上使用默认配置进行开发;它将提供最佳的开发体验。
与默认的服务生服务器相比,一个流行的产品替代方案是 mod_wsgi . 你可以使用 mod_wsgi 为你服务 Pyramid 应用程序使用的是ApacheWeb服务器,而不是像服务生那样的任何“纯Python”服务器。它既快又有特点。见 运行一个 Pyramid 申请 mod_wsgi 有关详细信息。
另一个好的生产选择是 gunicorn 。它比女服务员更快,配置也比 mod_wsgi ,尽管在其默认配置中,它依赖于前面有一个缓冲HTTP代理。在撰写本文时,它不能在Windows上运行。
自动重新加载代码¶
在开发过程中,在进行更改时自动重新启动Web服务器非常有用。 pserve 有一个 --reload 切换以启用此功能。它使用 hupper 包以启用此行为。当代码崩溃时, hupper 将等待另一个更改或 SIGHUP 重新启动前发出信号。
肌力支持¶
默认情况下 hupper 将轮询文件系统以查看对所有Python代码的更改。在较大的项目中,这可能是非常低效的。为了更好地使用硬盘,您应该安装 watchman 或 watchdog 正在开发包。 hupper 将使用,以效率优先顺序,如果可用, watchman , watchdog ,或最后轮询以检测文件系统的更改。
监视自定义文件¶
默认情况下, pserve --reload 将监视所有导入的python代码(所有 sys.modules )以及传递给 pserve (例如, development.ini )你可以指导 pserve 通过定义 [pserve] 配置文件中的节。例如,假设您的应用程序加载 favicon.ico 启动时的文件,并将其存储在内存中,以有效地多次提供服务。当你改变它,你想要 pserve 重新启动:
[pserve]
watch_files =
myproject/static/favicon.ico
路径可以是绝对路径,也可以是相对于配置文件的路径。它们也可能是 asset specification . 这些路径被传递到 hupper 它对全局搜索有一些基本支持。可接受的全局模式取决于所使用的Python版本。