From c87565c5ff1a3422e651f369fe4b2f848a9010ed Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 03:07:50 -0800 Subject: quick_tour - "Logging" updates for cookiecutter - fix line numbering - add new src files that were never included --- docs/quick_tour.rst | 28 ++-- docs/quick_tour/logging/.coveragerc | 3 + docs/quick_tour/logging/CHANGES.txt | 4 + docs/quick_tour/logging/MANIFEST.in | 2 + docs/quick_tour/logging/README.txt | 29 ++++ docs/quick_tour/logging/development.ini | 59 ++++++++ docs/quick_tour/logging/hello_world/__init__.py | 12 ++ .../logging/hello_world/static/pyramid-16x16.png | Bin 0 -> 1319 bytes .../logging/hello_world/static/pyramid.png | Bin 0 -> 12901 bytes .../logging/hello_world/static/theme.css | 154 +++++++++++++++++++++ .../logging/hello_world/templates/layout.jinja2 | 64 +++++++++ .../hello_world/templates/mytemplate.jinja2 | 8 ++ docs/quick_tour/logging/hello_world/tests.py | 29 ++++ docs/quick_tour/logging/hello_world/views.py | 9 ++ docs/quick_tour/logging/production.ini | 53 +++++++ docs/quick_tour/logging/pytest.ini | 3 + docs/quick_tour/logging/setup.py | 51 +++++++ 17 files changed, 492 insertions(+), 16 deletions(-) create mode 100644 docs/quick_tour/logging/.coveragerc create mode 100644 docs/quick_tour/logging/CHANGES.txt create mode 100644 docs/quick_tour/logging/MANIFEST.in create mode 100644 docs/quick_tour/logging/README.txt create mode 100644 docs/quick_tour/logging/development.ini create mode 100644 docs/quick_tour/logging/hello_world/__init__.py create mode 100644 docs/quick_tour/logging/hello_world/static/pyramid-16x16.png create mode 100644 docs/quick_tour/logging/hello_world/static/pyramid.png create mode 100644 docs/quick_tour/logging/hello_world/static/theme.css create mode 100644 docs/quick_tour/logging/hello_world/templates/layout.jinja2 create mode 100644 docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 create mode 100644 docs/quick_tour/logging/hello_world/tests.py create mode 100644 docs/quick_tour/logging/hello_world/views.py create mode 100644 docs/quick_tour/logging/production.ini create mode 100644 docs/quick_tour/logging/pytest.ini create mode 100644 docs/quick_tour/logging/setup.py (limited to 'docs') diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index fd35ba419..f5f722053 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -749,38 +749,34 @@ It's important to know what is going on inside our web application. In development we might need to collect some output. In production we might need to detect situations when other people use the site. We need *logging*. -Fortunately Pyramid uses the normal Python approach to logging. The scaffold -generated in your ``development.ini`` has a number of lines that configure the +Fortunately Pyramid uses the normal Python approach to logging. The ``development.ini`` file for your project has a number of lines that configure the logging for you to some reasonable defaults. You then see messages sent by Pyramid (for example, when a new request comes in). Maybe you would like to log messages in your code? In your Python module, -import and set up the logging: +import and set up the logging in your ``views.py``: -.. literalinclude:: quick_tour/package/hello_world/views.py +.. literalinclude:: quick_tour/logging/hello_world/views.py :language: python - :linenos: - :lineno-start: 3 + :lineno-match: :lines: 3-4 You can now, in your code, log messages: -.. literalinclude:: quick_tour/package/hello_world/views.py +.. literalinclude:: quick_tour/logging/hello_world/views.py :language: python - :linenos: - :lineno-start: 9 - :lines: 9-10 + :lineno-match: + :lines: 7-8 :emphasize-lines: 2 -This will log ``Some Message`` at a ``debug`` log level to the +This will log ``Some Message`` at a ``DEBUG`` log level to the application-configured logger in your ``development.ini``. What controls that? These emphasized sections in the configuration file: -.. literalinclude:: quick_tour/package/development.ini +.. literalinclude:: quick_tour/logging/development.ini :language: ini - :linenos: - :lineno-start: 36 - :lines: 36-52 + :lineno-match: + :lines: 34-50 :emphasize-lines: 1-2,14-17 Our application, a package named ``hello_world``, is set up as a logger and @@ -789,7 +785,7 @@ http://localhost:6543, your console will now show: .. code-block:: text - 2016-01-18 13:55:55,040 DEBUG [hello_world.views:10][waitress] Some Message + 2016-12-25 03:03:57,059 DEBUG [hello_world.views:8][waitress] Some Message .. seealso:: See also: :ref:`Quick Tutorial Logging ` and :ref:`logging_chapter`. diff --git a/docs/quick_tour/logging/.coveragerc b/docs/quick_tour/logging/.coveragerc new file mode 100644 index 000000000..128e26410 --- /dev/null +++ b/docs/quick_tour/logging/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = hello_world +omit = hello_world/test* diff --git a/docs/quick_tour/logging/CHANGES.txt b/docs/quick_tour/logging/CHANGES.txt new file mode 100644 index 000000000..14b902fd1 --- /dev/null +++ b/docs/quick_tour/logging/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version. diff --git a/docs/quick_tour/logging/MANIFEST.in b/docs/quick_tour/logging/MANIFEST.in new file mode 100644 index 000000000..a75da6dad --- /dev/null +++ b/docs/quick_tour/logging/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/quick_tour/logging/README.txt b/docs/quick_tour/logging/README.txt new file mode 100644 index 000000000..fb7bde0a7 --- /dev/null +++ b/docs/quick_tour/logging/README.txt @@ -0,0 +1,29 @@ +hello_world +=============================== + +Getting Started +--------------- + +- Change directory into your newly created project. + + cd hello_world + +- Create a Python virtual environment. + + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/quick_tour/logging/development.ini b/docs/quick_tour/logging/development.ini new file mode 100644 index 000000000..1f19e373d --- /dev/null +++ b/docs/quick_tour/logging/development.ini @@ -0,0 +1,59 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_world + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.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#main +listen = 127.0.0.1:6543 [::1]:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_hello_world] +level = DEBUG +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/logging/hello_world/__init__.py b/docs/quick_tour/logging/hello_world/__init__.py new file mode 100644 index 000000000..49dde36d4 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/__init__.py @@ -0,0 +1,12 @@ +from pyramid.config import Configurator + + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + config = Configurator(settings=settings) + config.include('pyramid_jinja2') + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() + return config.make_wsgi_app() diff --git a/docs/quick_tour/logging/hello_world/static/pyramid-16x16.png b/docs/quick_tour/logging/hello_world/static/pyramid-16x16.png new file mode 100644 index 000000000..979203112 Binary files /dev/null and b/docs/quick_tour/logging/hello_world/static/pyramid-16x16.png differ diff --git a/docs/quick_tour/logging/hello_world/static/pyramid.png b/docs/quick_tour/logging/hello_world/static/pyramid.png new file mode 100644 index 000000000..4ab837be9 Binary files /dev/null and b/docs/quick_tour/logging/hello_world/static/pyramid.png differ diff --git a/docs/quick_tour/logging/hello_world/static/theme.css b/docs/quick_tour/logging/hello_world/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/quick_tour/logging/hello_world/templates/layout.jinja2 b/docs/quick_tour/logging/hello_world/templates/layout.jinja2 new file mode 100644 index 000000000..916127267 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/templates/layout.jinja2 @@ -0,0 +1,64 @@ + + + + + + + + + + + Cookiecutter Starter project for the Pyramid Web Framework + + + + + + + + + + + + + +
+
+
+
+ +
+
+ {% block content %} +

No content

+ {% endblock content %} +
+
+ +
+ +
+
+
+ + + + + + + + diff --git a/docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 b/docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 new file mode 100644 index 000000000..cf2d7f996 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
+

Pyramid Starter project

+

Welcome to hello_world, a Pyramid application generated by
Cookiecutter.

+
+{% endblock content %} diff --git a/docs/quick_tour/logging/hello_world/tests.py b/docs/quick_tour/logging/hello_world/tests.py new file mode 100644 index 000000000..ee9745685 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/tests.py @@ -0,0 +1,29 @@ +import unittest + +from pyramid import testing + + +class ViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['project'], 'hello_world') + + +class FunctionalTests(unittest.TestCase): + def setUp(self): + from hello_world import main + app = main({}) + from webtest import TestApp + self.testapp = TestApp(app) + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'Pyramid' in res.body) diff --git a/docs/quick_tour/logging/hello_world/views.py b/docs/quick_tour/logging/hello_world/views.py new file mode 100644 index 000000000..a648d6ba3 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/views.py @@ -0,0 +1,9 @@ +from pyramid.view import view_config + +import logging +log = logging.getLogger(__name__) + +@view_config(route_name='home', renderer='templates/mytemplate.jinja2') +def my_view(request): + log.debug('Some Message') + return {'project': 'hello_world'} diff --git a/docs/quick_tour/logging/production.ini b/docs/quick_tour/logging/production.ini new file mode 100644 index 000000000..9c12bc4ec --- /dev/null +++ b/docs/quick_tour/logging/production.ini @@ -0,0 +1,53 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_world + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = *:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_hello_world] +level = WARN +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/logging/pytest.ini b/docs/quick_tour/logging/pytest.ini new file mode 100644 index 000000000..f707d54e4 --- /dev/null +++ b/docs/quick_tour/logging/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = hello_world +python_files = *.py diff --git a/docs/quick_tour/logging/setup.py b/docs/quick_tour/logging/setup.py new file mode 100644 index 000000000..e32aecacd --- /dev/null +++ b/docs/quick_tour/logging/setup.py @@ -0,0 +1,51 @@ +import os + +from setuptools import setup, find_packages + +here = 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 = [ + 'pyramid', + 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', +] + +tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', + 'pytest-cov', +] + +setup( + name='hello_world', + version='0.0', + description='hello_world', + 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 = hello_world:main', + ], + }, +) -- cgit v1.2.3