创建一个 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版本。