Merge pull request #2468 from Pylons/docs/easy-install-to-pip.2104
Docs: easy install to pip
17 files deleted
37 files added
146 files modified
| | |
| | | unreleased |
| | | ========== |
| | | |
| | | - A complete overhaul of the docs: |
| | | |
| | | - Use pip instead of easy_install. |
| | | - Become opinionated by preferring Python 3.4 or greater to simplify |
| | | installation of Python and its required packaging tools. |
| | | - Use venv for the tool, and virtual environment for the thing created, |
| | | instead of virtualenv. |
| | | - Use py.test and pytest-cov instead of nose and coverage. |
| | | - Further updates to the scaffolds as well as tutorials and their src files. |
| | | |
| | | See https://github.com/Pylons/pyramid/pull/2468 |
| | | |
| | | - A complete overhaul of the ``alchemy`` scaffold as well as the |
| | | Wiki2 SQLAlchemy + URLDispatch tutorial to introduce more modern features |
| | | into the usage of SQLAlchemy with Pyramid and provide a better starting |
| | |
| | | 'deform': ('http://docs.pylonsproject.org/projects/deform/en/latest', None), |
| | | 'jinja2': ('http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/', None), |
| | | 'pylonswebframework': ('http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/', None), |
| | | 'python': ('http://docs.python.org', None), |
| | | 'python3': ('http://docs.python.org/3', None), |
| | | 'python': ('https://docs.python.org/3', None), |
| | | 'sqla': ('http://docs.sqlalchemy.org/en/latest', None), |
| | | 'tm': ('http://docs.pylonsproject.org/projects/pyramid-tm/en/latest/', None), |
| | | 'toolbar': ('http://docs.pylonsproject.org/projects/pyramid-debugtoolbar/en/latest', None), |
| | |
| | | |
| | | $ $VENV/bin/nosetests |
| | | |
| | | (See :term:`virtualenv` for the meaning of ``$VENV``) |
| | | (See :term:`venv` for the meaning of ``$VENV``) |
| | | |
| | | Example blocks representing Windows ``cmd.exe`` commands are prefixed with a |
| | | drive letter and/or a directory name, e.g.: |
| | |
| | | |
| | | c:\examples> %VENV%\Scripts\nosetests |
| | | |
| | | (See :term:`virtualenv` for the meaning of ``%VENV%``) |
| | | (See :term:`venv` for the meaning of ``%VENV%``) |
| | | |
| | | Sometimes, when it's unknown which directory is current, Windows ``cmd.exe`` |
| | | example block commands are prefixed only with a ``>`` character, e.g.: |
| | |
| | | request before it returns a :term:`context` resource. |
| | | |
| | | virtualenv |
| | | A term referring both to an isolated Python environment, |
| | | or `the leading tool <http://www.virtualenv.org>`_ that allows one to |
| | | create such environments. |
| | | The `virtualenv tool <https://virtualenv.pypa.io/en/latest/>`_ that allows |
| | | one to create virtual environments. In Python 3.3 and greater, |
| | | :term:`venv` is the preferred tool. |
| | | |
| | | Note: whenever you encounter commands prefixed with ``$VENV`` (Unix) |
| | | or ``%VENV`` (Windows), know that that is the environment variable whose |
| | |
| | | |
| | | console script |
| | | A script written to the ``bin`` (on UNIX, or ``Scripts`` on Windows) |
| | | directory of a Python installation or :term:`virtualenv` as the result of |
| | | running ``setup.py install`` or ``setup.py develop``. |
| | | directory of a Python installation or :term:`virtual environment` as the |
| | | result of running ``pip install`` or ``pip install -e .``. |
| | | |
| | | introspector |
| | | An object with the methods described by |
| | |
| | | implementing the :class:`pyramid.interfaces.IViewDeriver` interface. |
| | | Examples of built-in derivers including view mapper, the permission |
| | | checker, and applying a renderer to a dictionary returned from the view. |
| | | |
| | | pip |
| | | The `Python Packaging Authority's <https://www.pypa.io/>`_ recommended |
| | | tool for installing Python packages. |
| | | |
| | | pyvenv |
| | | The Python Packaging Authority formerly recommended using this command |
| | | for `creating virtual environments on Python 3.4 and 3.5 |
| | | <https://packaging.python.org/en/latest/installing/#creating-virtual-environments>`_, |
| | | but it is deprecated in 3.6 in favor of ``python3 -m venv`` on UNIX or |
| | | ``python -m venv`` on Windows, which is backward compatible on Python |
| | | 3.3 and greater. |
| | | |
| | | virtual environment |
| | | An isolated Python environment that allows packages to be installed for |
| | | use by a particular application, rather than being installed system wide. |
| | | |
| | | venv |
| | | The `Python Packaging Authority's <https://www.pypa.io/>`_ recommended |
| | | tool for creating virtual environments on Python 3.3 and greater. |
| | | |
| | | Note: whenever you encounter commands prefixed with ``$VENV`` (Unix) |
| | | or ``%VENV`` (Windows), know that that is the environment variable whose |
| | | value is the root of the virtual environment in question. |
| | |
| | | MyProject README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | <div class="col-md-10"> |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.6b2</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li class="current-version">Generated by v1.6b2</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.6-branch/">Docs</a></li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | |
| | | |
| | | def test_root(self): |
| | | res = self.testapp.get('/', status=200) |
| | | self.assertTrue('Pyramid' in res.body) |
| | | self.assertTrue(b'Pyramid' in res.body) |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | 'waitress', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='MyProject', |
| | | version='0.0', |
| | | description='MyProject', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="myproject", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = myproject:main |
| | |
| | | |
| | | .. seealso:: See also the output of :ref:`pshell --help <pshell_script>`. |
| | | |
| | | Once you've installed your program for development using ``setup.py develop``, |
| | | Once you've installed your program for development using ``pip install -e .``, |
| | | you can use an interactive Python shell to execute expressions in a Python |
| | | environment exactly like the one that will be used when your application runs |
| | | "for real". To do so, use the ``pshell`` command line utility. |
| | |
| | | python |
| | | |
| | | If you want to use a shell that isn't supported out of the box, you can |
| | | introduce a new shell by registering an entry point in your setup.py: |
| | | introduce a new shell by registering an entry point in your ``setup.py``: |
| | | |
| | | .. code-block:: python |
| | | |
| | |
| | | .. versionadded:: 1.5 |
| | | |
| | | Each of Pyramid's console scripts (``pserve``, ``pviews``, etc.) can be run |
| | | directly using ``python -m``, allowing custom arguments to be sent to the |
| | | directly using ``python3 -m``, allowing custom arguments to be sent to the |
| | | Python interpreter at runtime. For example:: |
| | | |
| | | python -3 -m pyramid.scripts.pserve development.ini |
| | | python3 -m pyramid.scripts.pserve development.ini |
| | | |
| | | |
| | | .. index:: |
| | |
| | | ---------------------------------------- |
| | | |
| | | A "console script" is :term:`setuptools` terminology for a script that gets |
| | | installed into the ``bin`` directory of a Python :term:`virtualenv` (or "base" |
| | | Python environment) when a :term:`distribution` which houses that script is |
| | | installed. Because it's installed into the ``bin`` directory of a virtualenv |
| | | when the distribution is installed, it's a convenient way to package and |
| | | distribute functionality that you can call from the command-line. It's often |
| | | more convenient to create a console script than it is to create a ``.py`` |
| | | script and instruct people to call it with the "right" Python interpreter. A |
| | | console script generates a file that lives in ``bin``, and when it's invoked it |
| | | will always use the "right" Python environment, which means it will always be |
| | | invoked in an environment where all the libraries it needs (such as Pyramid) |
| | | are available. |
| | | installed into the ``bin`` directory of a Python :term:`virtual environment` |
| | | (or "base" Python environment) when a :term:`distribution` which houses that |
| | | script is installed. Because it's installed into the ``bin`` directory of a |
| | | virtual environment when the distribution is installed, it's a convenient way |
| | | to package and distribute functionality that you can call from the |
| | | command-line. It's often more convenient to create a console script than it is |
| | | to create a ``.py`` script and instruct people to call it with the "right" |
| | | Python interpreter. A console script generates a file that lives in ``bin``, |
| | | and when it's invoked it will always use the "right" Python environment, which |
| | | means it will always be invoked in an environment where all the libraries it |
| | | needs (such as Pyramid) are available. |
| | | |
| | | In general, you can make your script into a console script by doing the |
| | | following: |
| | |
| | | distribution which creates a mapping between a script name and a dotted name |
| | | representing the callable you added to your distribution. |
| | | |
| | | - Run ``setup.py develop``, ``setup.py install``, or ``easy_install`` to get |
| | | your distribution reinstalled. When you reinstall your distribution, a file |
| | | representing the script that you named in the last step will be in the |
| | | ``bin`` directory of the virtualenv in which you installed the distribution. |
| | | It will be executable. Invoking it from a terminal will execute your |
| | | callable. |
| | | - Run ``pip install -e .`` or ``pip install .`` to get your distribution |
| | | reinstalled. When you reinstall your distribution, a file representing the |
| | | script that you named in the last step will be in the ``bin`` directory of |
| | | the virtual environment in which you installed the distribution. It will be |
| | | executable. Invoking it from a terminal will execute your callable. |
| | | |
| | | As an example, let's create some code that can be invoked by a console script |
| | | that prints the deployment settings of a Pyramid application. To do so, we'll |
| | |
| | | |
| | | requires = ['pyramid', 'pyramid_debugtoolbar'] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='MyProject', |
| | | version='0.0', |
| | | description='My project', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pylons", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="myproject", |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | entry_points = """\ |
| | | [paste.app_factory] |
| | | main = myproject:main |
| | | """, |
| | | ) |
| | | |
| | | We're going to change the setup.py file to add a ``[console_scripts]`` section |
| | | within the ``entry_points`` string. Within this section, you should specify a |
| | | ``scriptname = dotted.path.to:yourfunction`` line. For example:: |
| | | We're going to change the ``setup.py`` file to add a ``[console_scripts]`` |
| | | section within the ``entry_points`` string. Within this section, you should |
| | | specify a ``scriptname = dotted.path.to:yourfunction`` line. For example: |
| | | |
| | | [console_scripts] |
| | | show_settings = myproject.scripts:settings_show |
| | | .. code-block:: ini |
| | | |
| | | [console_scripts] |
| | | show_settings = myproject.scripts:settings_show |
| | | |
| | | The ``show_settings`` name will be the name of the script that is installed |
| | | into ``bin``. The colon (``:``) between ``myproject.scripts`` and |
| | |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | :emphasize-lines: 43-44 |
| | | |
| | | import os |
| | | |
| | |
| | | |
| | | requires = ['pyramid', 'pyramid_debugtoolbar'] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='MyProject', |
| | | version='0.0', |
| | | description='My project', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pylons", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="myproject", |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | entry_points = """\ |
| | | [paste.app_factory] |
| | | main = myproject:main |
| | |
| | | """, |
| | | ) |
| | | |
| | | Once you've done this, invoking ``$$VENV/bin/python setup.py develop`` will |
| | | install a file named ``show_settings`` into the ``$somevirtualenv/bin`` |
| | | directory with a small bit of Python code that points to your entry point. It |
| | | will be executable. Running it without any arguments will print an error and |
| | | exit. Running it with a single argument that is the path of a config file will |
| | | print the settings. Running it with an ``--omit=foo`` argument will omit the |
| | | settings that have keys that start with ``foo``. Running it with two "omit" |
| | | options (e.g., ``--omit=foo --omit=bar``) will omit all settings that have keys |
| | | that start with either ``foo`` or ``bar``:: |
| | | Once you've done this, invoking ``$VENV/bin/pip install -e .`` will install a |
| | | file named ``show_settings`` into the ``$somevenv/bin`` directory with a |
| | | small bit of Python code that points to your entry point. It will be |
| | | executable. Running it without any arguments will print an error and exit. |
| | | Running it with a single argument that is the path of a config file will print |
| | | the settings. Running it with an ``--omit=foo`` argument will omit the settings |
| | | that have keys that start with ``foo``. Running it with two "omit" options |
| | | (e.g., ``--omit=foo --omit=bar``) will omit all settings that have keys that |
| | | start with either ``foo`` or ``bar``: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar |
| | | debug_routematch False |
| | |
| | | elements, such as templates and static assets as necessary. |
| | | |
| | | - Install the new package into the same Python environment as the original |
| | | application (e.g., ``$VENV/bin/python setup.py develop`` or |
| | | ``$VENV/bin/python setup.py install``). |
| | | application (e.g., ``$VENV/bin/pip install -e .`` or ``$VENV/bin/pip install |
| | | .``). |
| | | |
| | | - Change the ``main`` function in the new package's ``__init__.py`` to include |
| | | the original :app:`Pyramid` application's configuration functions via |
| | |
| | | package name is almost always ``gettext``. For example on a Debian or Ubuntu |
| | | system run this command: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ sudo apt-get install gettext |
| | | |
| | | Installing Lingua is done with the Python packaging tools. If the |
| | | :term:`virtualenv` into which you've installed your :app:`Pyramid` application |
| | | lives in ``/my/virtualenv``, you can install Lingua like so: |
| | | :term:`virtual environment` into which you've installed your :app:`Pyramid` |
| | | application lives at the environment variable ``$VENV``, you can install Lingua |
| | | like so: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ cd /my/virtualenv |
| | | $ $VENV/bin/easy_install lingua |
| | | $ $VENV/bin/pip install lingua |
| | | |
| | | Installation on Windows |
| | | +++++++++++++++++++++++ |
| | |
| | | ``$PATH``. |
| | | |
| | | Installing Lingua is done with the Python packaging tools. If the |
| | | :term:`virtualenv` into which you've installed your :app:`Pyramid` application |
| | | lives in ``C:\my\virtualenv``, you can install Lingua like so: |
| | | :term:`virtual environment` into which you've installed your :app:`Pyramid` |
| | | application lives at the environment variable ``%VENV%``, you can install |
| | | Lingua like so: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | C> %VENV%\Scripts\easy_install lingua |
| | | C> %VENV%\Scripts\pip install lingua |
| | | |
| | | |
| | | .. index:: |
| | |
| | | code and :term:`Chameleon` templates which reside in your :app:`Pyramid` |
| | | application. You run a ``pot-create`` command to extract the messages: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ cd /place/where/myapplication/setup.py/lives |
| | | $ cd /file/path/to/myapplication_setup.py |
| | | $ mkdir -p myapplication/locale |
| | | $ $VENV/bin/pot-create -o myapplication/locale/myapplication.pot src |
| | | |
| | |
| | | Initialize a ``.po`` file for a specific locale from a pre-generated ``.pot`` |
| | | template by using the ``msginit`` command from Gettext: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ cd /place/where/myapplication/setup.py/lives |
| | | $ cd /file/path/to/myapplication_setup.py |
| | | $ cd myapplication/locale |
| | | $ mkdir -p es/LC_MESSAGES |
| | | $ msginit -l es -o es/LC_MESSAGES/myapplication.po |
| | |
| | | First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. Then use |
| | | the ``msgmerge`` command from Gettext. |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ cd /place/where/myapplication/setup.py/lives |
| | | $ cd /file/path/to/myapplication_setup.py |
| | | $ cd myapplication/locale |
| | | $ msgmerge --update es/LC_MESSAGES/myapplication.po myapplication.pot |
| | | |
| | |
| | | compile ``.po`` files to ``.mo`` files using the ``msgfmt`` command from |
| | | Gettext: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ cd /place/where/myapplication/setup.py/lives |
| | | $ cd /file/path/to/myapplication_setup.py |
| | | $ msgfmt -o myapplication/locale/es/LC_MESSAGES/myapplication.mo \ |
| | | myapplication/locale/es/LC_MESSAGES/myapplication.po |
| | | |
| | |
| | | Installing :app:`Pyramid` |
| | | ========================= |
| | | |
| | | .. note:: |
| | | |
| | | This installation guide emphasizes the use of Python 3.4 and greater for |
| | | simplicity. |
| | | |
| | | |
| | | .. index:: |
| | | single: install preparation |
| | | |
| | | Before You Install |
| | | ------------------ |
| | | Before You Install Pyramid |
| | | -------------------------- |
| | | |
| | | You will need `Python <http://python.org>`_ version 2.6 or better to run |
| | | :app:`Pyramid`. |
| | | Install Python version 3.4 or greater for your operating system, and satisfy |
| | | the :ref:`requirements-for-installing-packages`, as described in |
| | | the following sections. |
| | | |
| | | .. sidebar:: Python Versions |
| | | |
| | |
| | | does not run under any version of Python before 2.6. |
| | | |
| | | :app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, |
| | | Mac OS X, and FreeBSD as well as on Windows platforms. It is also known to run |
| | | on :term:`PyPy` (1.9+). |
| | | Mac OS X, and FreeBSD, as well as on Windows platforms. It is also known to |
| | | run on :term:`PyPy` (1.9+). |
| | | |
| | | :app:`Pyramid` installation does not require the compilation of any C code, so |
| | | you need only a Python interpreter that meets the requirements mentioned. |
| | | :app:`Pyramid` installation does not require the compilation of any C code. |
| | | However, some :app:`Pyramid` dependencies may attempt to build binary |
| | | extensions from C code for performance speed ups. If a compiler or Python |
| | | headers are unavailable, the dependency will fall back to using pure Python |
| | | instead. |
| | | |
| | | Some :app:`Pyramid` dependencies may attempt to build C extensions for |
| | | performance speedups. If a compiler or Python headers are unavailable the |
| | | dependency will fall back to using pure Python instead. |
| | | .. note:: |
| | | |
| | | If you see any warnings or errors related to failing to compile the binary |
| | | extensions, in most cases you may safely ignore those errors. If you wish to |
| | | use the binary extensions, please verify that you have a functioning |
| | | compiler and the Python header files installed for your operating system. |
| | | |
| | | |
| | | .. _for-mac-os-x-users: |
| | | |
| | | For Mac OS X Users |
| | | ~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Python comes pre-installed on Mac OS X, but due to Apple's release cycle, it is |
| | | often out of date. Unless you have a need for a specific earlier version, it is |
| | | recommended to install the latest 2.x or 3.x version of Python. |
| | | recommended to install the latest 3.x version of Python. |
| | | |
| | | You can install the latest verion of Python for Mac OS X from the binaries on |
| | | `python.org <https://www.python.org/downloads/mac-osx/>`_. |
| | |
| | | |
| | | .. code-block:: text |
| | | |
| | | # for python 2.7 |
| | | $ brew install python |
| | | |
| | | # for python 3.5 |
| | | # for python 3.x |
| | | $ brew install python3 |
| | | |
| | | If you use an installer for your Python, then you can skip to the section |
| | | :ref:`installing_unix`. |
| | | |
| | | |
| | | .. _if-you-don-t-yet-have-a-python-interpreter-unix: |
| | | |
| | | If You Don't Yet Have a Python Interpreter (UNIX) |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | |
| | | can install Python from source fairly easily on any UNIX system that has |
| | | development tools. |
| | | |
| | | .. index:: |
| | | pair: install; Python (from package, UNIX) |
| | | .. seealso:: See the official Python documentation :ref:`Using Python on Unix |
| | | platforms <python:using-on-unix>` for full details. |
| | | |
| | | Package Manager Method |
| | | ++++++++++++++++++++++ |
| | | |
| | | You can use your system's "package manager" to install Python. Each package |
| | | manager is slightly different, but the "flavor" of them is usually the same. |
| | | |
| | | For example, on a Debian or Ubuntu system, use the following command: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ sudo apt-get install python2.7-dev |
| | | |
| | | This command will install both the Python interpreter and its development |
| | | header files. Note that the headers are required by some (optional) C |
| | | extensions in software depended upon by Pyramid, not by Pyramid itself. |
| | | |
| | | Once these steps are performed, the Python interpreter will usually be |
| | | invokable via ``python2.7`` from a shell prompt. |
| | | |
| | | .. index:: |
| | | pair: install; Python (from source, UNIX) |
| | | |
| | | Source Compile Method |
| | | +++++++++++++++++++++ |
| | | |
| | | It's useful to use a Python interpreter that *isn't* the "system" Python |
| | | interpreter to develop your software. The authors of :app:`Pyramid` tend not |
| | | to use the system Python for development purposes; always a self-compiled one. |
| | | Compiling Python is usually easy, and often the "system" Python is compiled |
| | | with options that aren't optimal for web development. For an explanation, see |
| | | https://github.com/Pylons/pyramid/issues/747. |
| | | |
| | | To compile software on your UNIX system, typically you need development tools. |
| | | Often these can be installed via the package manager. For example, this works |
| | | to do so on an Ubuntu Linux system: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ sudo apt-get install build-essential |
| | | |
| | | On Mac OS X, installing `XCode <http://developer.apple.com/tools/xcode/>`_ has |
| | | much the same effect. |
| | | |
| | | Once you've got development tools installed on your system, you can install a |
| | | Python 2.7 interpreter from *source*, on the same system, using the following |
| | | commands: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ cd ~ |
| | | $ mkdir tmp |
| | | $ mkdir opt |
| | | $ cd tmp |
| | | $ wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz |
| | | $ tar xvzf Python-2.7.3.tgz |
| | | $ cd Python-2.7.3 |
| | | $ ./configure --prefix=$HOME/opt/Python-2.7.3 |
| | | $ make && make install |
| | | |
| | | Once these steps are performed, the Python interpreter will be invokable via |
| | | ``$HOME/opt/Python-2.7.3/bin/python`` from a shell prompt. |
| | | |
| | | .. index:: |
| | | pair: install; Python (from package, Windows) |
| | | |
| | | .. _if-you-don-t-yet-have-a-python-interpreter-windows: |
| | | |
| | | If You Don't Yet Have a Python Interpreter (Windows) |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | If your Windows system doesn't have a Python interpreter, you'll need to |
| | | install it by downloading a Python 2.7-series interpreter executable from |
| | | install it by downloading a Python 3.x-series interpreter executable from |
| | | `python.org's download section <http://python.org/download/>`_ (the files |
| | | labeled "Windows Installer"). Once you've downloaded it, double click on the |
| | | executable and accept the defaults during the installation process. You may |
| | | also need to download and install the Python for Windows extensions. |
| | | |
| | | .. seealso:: See the official Python documentation :ref:`Using Python on |
| | | Windows <python:using-on-windows>` for full details. |
| | | |
| | | .. seealso:: Download and install the `Python for Windows extensions |
| | | <http://sourceforge.net/projects/pywin32/files/pywin32/>`_. Carefully read |
| | | the README.txt file at the end of the list of builds, and follow its |
| | | directions. Make sure you get the proper 32- or 64-bit build and Python |
| | | version. |
| | | |
| | | .. warning:: |
| | | |
| | | After you install Python on Windows, you may need to add the ``C:\Python27`` |
| | | directory to your environment's ``Path`` in order to make it possible to |
| | | invoke Python from a command prompt by typing ``python``. To do so, right |
| | | click ``My Computer``, select ``Properties`` --> ``Advanced Tab`` --> |
| | | ``Environment Variables`` and add that directory to the end of the ``Path`` |
| | | environment variable. |
| | | After you install Python on Windows, you may need to add the ``C:\Python3x`` |
| | | directory to your environment's ``Path``, where ``x`` is the minor version |
| | | of installed Python, in order to make it possible to invoke Python from a |
| | | command prompt by typing ``python``. To do so, right click ``My Computer``, |
| | | select ``Properties`` --> ``Advanced Tab`` --> ``Environment Variables`` and |
| | | add that directory to the end of the ``Path`` environment variable. |
| | | |
| | | .. seealso:: See `Configuring Python (on Windows) |
| | | <https://docs.python.org/3/using/windows.html#configuring-python>`_ for |
| | | full details. |
| | | |
| | | |
| | | .. index:: |
| | | single: requirements for installing packages |
| | | |
| | | .. _requirements-for-installing-packages: |
| | | |
| | | Requirements for Installing Packages |
| | | ------------------------------------ |
| | | |
| | | Use :term:`pip` for installing packages and ``python3 -m venv env`` for |
| | | creating a virtual environment. A virtual environment is a semi-isolated Python |
| | | environment that allows packages to be installed for use by a particular |
| | | application, rather than being installed system wide. |
| | | |
| | | .. seealso:: See the Python Packaging Authority's (PyPA) documention |
| | | `Requirements for Installing Packages |
| | | <https://packaging.python.org/en/latest/installing/#requirements-for-installing-packages>`_ |
| | | for full details. |
| | | |
| | | |
| | | .. index:: |
| | | single: installing on UNIX |
| | | single: installing on Mac OS X |
| | | |
| | | .. _installing_unix: |
| | | |
| | | Installing :app:`Pyramid` on a UNIX System |
| | | ------------------------------------------ |
| | | |
| | | It is best practice to install :app:`Pyramid` into a "virtual" Python |
| | | environment in order to obtain isolation from any "system" packages you've got |
| | | installed in your Python version. This can be done by using the |
| | | :term:`virtualenv` package. Using a virtualenv will also prevent |
| | | :app:`Pyramid` from globally installing versions of packages that are not |
| | | compatible with your system Python. |
| | | After installing Python as described previously in :ref:`for-mac-os-x-users` or |
| | | :ref:`if-you-don-t-yet-have-a-python-interpreter-unix`, and satisfying the |
| | | :ref:`requirements-for-installing-packages`, you can now install Pyramid. |
| | | |
| | | To set up a virtualenv in which to install :app:`Pyramid`, first ensure that |
| | | :term:`setuptools` is installed. To do so, invoke ``import setuptools`` within |
| | | the Python interpreter you'd like to run :app:`Pyramid` under. |
| | | #. Make a :term:`virtual environment` workspace: |
| | | |
| | | The following command will not display anything if setuptools is already |
| | | installed: |
| | | .. code-block:: bash |
| | | |
| | | .. code-block:: text |
| | | $ export VENV=~/env |
| | | $ python3 -m venv $VENV |
| | | |
| | | $ python2.7 -c 'import setuptools' |
| | | You can either follow the use of the environment variable ``$VENV``, or |
| | | replace it with the root directory of the virtual environment. If you choose |
| | | the former approach, ensure that ``$VENV`` is an absolute path. In the |
| | | latter case, the ``export`` command can be skipped. |
| | | |
| | | Running the same command will yield the following output if setuptools is not |
| | | yet installed: |
| | | #. (Optional) Consider using ``$VENV/bin/activate`` to make your shell |
| | | environment wired to use the virtual environment. |
| | | |
| | | .. code-block:: text |
| | | #. Use ``pip`` to get :app:`Pyramid` and its direct dependencies installed: |
| | | |
| | | Traceback (most recent call last): |
| | | File "<stdin>", line 1, in <module> |
| | | ImportError: No module named setuptools |
| | | .. parsed-literal:: |
| | | |
| | | If ``import setuptools`` raises an :exc:`ImportError` as it does above, you |
| | | will need to install setuptools manually. |
| | | $ $VENV/bin/pip install "pyramid==\ |release|\ " |
| | | |
| | | If you are using a "system" Python (one installed by your OS distributor or a |
| | | third-party packager such as Fink or MacPorts), you can usually install the |
| | | setuptools package by using your system's package manager. If you cannot do |
| | | this, or if you're using a self-installed version of Python, you will need to |
| | | install setuptools "by hand". Installing setuptools "by hand" is always a |
| | | reasonable thing to do, even if your package manager already has a pre-chewed |
| | | version of setuptools for installation. |
| | | |
| | | Installing Setuptools |
| | | ~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | To install setuptools by hand under Python 2, first download `ez_setup.py |
| | | <https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py>`_ then invoke |
| | | it using the Python interpreter into which you want to install setuptools. |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ python ez_setup.py |
| | | |
| | | Once this command is invoked, setuptools should be installed on your system. |
| | | If the command fails due to permission errors, you may need to be the |
| | | administrative user on your system to successfully invoke the script. To |
| | | remediate this, you may need to do: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ sudo python ez_setup.py |
| | | |
| | | .. index:: |
| | | pair: install; virtualenv |
| | | |
| | | Installing the ``virtualenv`` Package |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Once you've got setuptools installed, you should install the :term:`virtualenv` |
| | | package. To install the :term:`virtualenv` package into your |
| | | setuptools-enabled Python interpreter, use the ``easy_install`` command. |
| | | |
| | | .. warning:: |
| | | |
| | | Python 3.3 includes ``pyvenv`` out of the box, which provides similar |
| | | functionality to ``virtualenv``. We however suggest using ``virtualenv`` |
| | | instead, which works well with Python 3.3. This isn't a recommendation made |
| | | for technical reasons; it's made because it's not feasible for the authors |
| | | of this guide to explain setup using multiple virtual environment systems. |
| | | We are aiming to not need to make the installation documentation |
| | | Turing-complete. |
| | | |
| | | If you insist on using ``pyvenv``, you'll need to understand how to install |
| | | software such as ``setuptools`` into the virtual environment manually, which |
| | | this guide does not cover. |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ easy_install virtualenv |
| | | |
| | | This command should succeed, and tell you that the virtualenv package is now |
| | | installed. If it fails due to permission errors, you may need to install it as |
| | | your system's administrative user. For example: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ sudo easy_install virtualenv |
| | | |
| | | .. index:: |
| | | single: virtualenv |
| | | pair: Python; virtual environment |
| | | |
| | | Creating the Virtual Python Environment |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Once the :term:`virtualenv` package is installed in your Python environment, |
| | | you can then create a virtual environment. To do so, invoke the following: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ export VENV=~/env |
| | | $ virtualenv $VENV |
| | | New python executable in /home/foo/env/bin/python |
| | | Installing setuptools.............done. |
| | | |
| | | You can either follow the use of the environment variable, ``$VENV``, or |
| | | replace it with the root directory of the :term:`virtualenv`. In that case, the |
| | | `export` command can be skipped. If you choose the former approach, ensure that |
| | | it's an absolute path. |
| | | |
| | | .. warning:: |
| | | |
| | | Avoid using the ``--system-site-packages`` option when creating the |
| | | virtualenv unless you know what you are doing. For versions of virtualenv |
| | | prior to 1.7, make sure to use the ``--no-site-packages`` option, because |
| | | this option was formerly not the default and may produce undesirable |
| | | results. |
| | | |
| | | .. warning:: |
| | | |
| | | *do not* use ``sudo`` to run the ``virtualenv`` script. It's perfectly |
| | | acceptable (and desirable) to create a virtualenv as a normal user. |
| | | |
| | | |
| | | Installing :app:`Pyramid` into the Virtual Python Environment |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | After you've got your virtualenv installed, you may install :app:`Pyramid` |
| | | itself using the following commands: |
| | | |
| | | .. parsed-literal:: |
| | | |
| | | $ $VENV/bin/easy_install "pyramid==\ |release|\ " |
| | | |
| | | The ``easy_install`` command will take longer than the previous ones to |
| | | complete, as it downloads and installs a number of dependencies. |
| | | |
| | | .. note:: |
| | | |
| | | If you see any warnings and/or errors related to failing to compile the C |
| | | extensions, in most cases you may safely ignore those errors. If you wish to |
| | | use the C extensions, please verify that you have a functioning compiler and |
| | | the Python header files installed. |
| | | |
| | | .. index:: |
| | | single: installing on Windows |
| | |
| | | Installing :app:`Pyramid` on a Windows System |
| | | --------------------------------------------- |
| | | |
| | | You can use Pyramid on Windows under Python 2 or 3. |
| | | After installing Python as described previously in |
| | | :ref:`if-you-don-t-yet-have-a-python-interpreter-windows`, and satisfying the |
| | | :ref:`requirements-for-installing-packages`, you can now install Pyramid. |
| | | |
| | | #. Download and install the most recent `Python 2.7.x or 3.3.x version |
| | | <http://www.python.org/download/>`_ for your system. |
| | | #. Make a :term:`virtual environment` workspace: |
| | | |
| | | #. Download and install the `Python for Windows extensions |
| | | <http://sourceforge.net/projects/pywin32/files/pywin32/>`_. Carefully read |
| | | the README.txt file at the end of the list of builds, and follow its |
| | | directions. Make sure you get the proper 32- or 64-bit build and Python |
| | | version. |
| | | |
| | | #. Install latest :term:`setuptools` distribution into the Python from step 1 |
| | | above: download `ez_setup.py |
| | | <https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py>`_ and run |
| | | it using the ``python`` interpreter of your Python 2.7 or 3.3 installation |
| | | using a command prompt: |
| | | |
| | | .. code-block:: text |
| | | |
| | | # modify the command according to the python version, e.g.: |
| | | # for Python 2.7: |
| | | c:\> c:\Python27\python ez_setup.py |
| | | # for Python 3.3: |
| | | c:\> c:\Python33\python ez_setup.py |
| | | |
| | | #. Install `virtualenv`: |
| | | |
| | | .. code-block:: text |
| | | |
| | | # modify the command according to the python version, e.g.: |
| | | # for Python 2.7: |
| | | c:\> c:\Python27\Scripts\easy_install virtualenv |
| | | # for Python 3.3: |
| | | c:\> c:\Python33\Scripts\easy_install virtualenv |
| | | |
| | | #. Make a :term:`virtualenv` workspace: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> set VENV=c:\env |
| | | # modify the command according to the python version, e.g.: |
| | | # for Python 2.7: |
| | | c:\> c:\Python27\Scripts\virtualenv %VENV% |
| | | # for Python 3.3: |
| | | c:\> c:\Python33\Scripts\virtualenv %VENV% |
| | | # replace "x" with your minor version of Python 3 |
| | | c:\> c:\Python3x\Scripts\python3 -m venv %VENV% |
| | | |
| | | You can either follow the use of the environment variable, ``%VENV%``, or |
| | | replace it with the root directory of the :term:`virtualenv`. In that case, |
| | | the `set` command can be skipped. If you choose the former approach, ensure |
| | | that it's an absolute path. |
| | | You can either follow the use of the environment variable ``%VENV%``, or |
| | | replace it with the root directory of the virtual environment. If you choose |
| | | the former approach, ensure that ``%VENV%`` is an absolute path. In the |
| | | latter case, the ``set`` command can be skipped. |
| | | |
| | | #. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell |
| | | environment wired to use the virtualenv. |
| | | environment wired to use the virtual environment. |
| | | |
| | | #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies |
| | | installed: |
| | | #. Use ``pip`` to get :app:`Pyramid` and its direct dependencies installed: |
| | | |
| | | .. parsed-literal:: |
| | | |
| | | c:\\env> %VENV%\\Scripts\\easy_install "pyramid==\ |release|\ " |
| | | c:\\env> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " |
| | | |
| | | |
| | | What Gets Installed |
| | | ------------------- |
| | | |
| | | When you ``easy_install`` :app:`Pyramid`, various other libraries such as |
| | | WebOb, PasteDeploy, and others are installed. |
| | | When you install :app:`Pyramid`, various libraries such as WebOb, PasteDeploy, |
| | | and others are installed. |
| | | |
| | | Additionally, as chronicled in :ref:`project_narr`, scaffolds will be |
| | | registered, which make it easy to start a new :app:`Pyramid` project. |
| | |
| | | .. seealso:: See also the output of :ref:`pcreate --help <pcreate_script>`. |
| | | |
| | | In :ref:`installing_chapter`, you created a virtual Python environment via the |
| | | ``virtualenv`` command. To start a :app:`Pyramid` :term:`project`, use the |
| | | ``pcreate`` command installed within the virtualenv. We'll choose the |
| | | ``venv`` command. To start a :app:`Pyramid` :term:`project`, use the |
| | | ``pcreate`` command installed within the virtual environment. We'll choose the |
| | | ``starter`` scaffold for this purpose. When we invoke ``pcreate``, it will |
| | | create a directory that represents our project. |
| | | |
| | | In :ref:`installing_chapter` we called the virtualenv directory ``env``. The |
| | | following commands assume that our current working directory is the ``env`` |
| | | directory. |
| | | In :ref:`installing_chapter` we called the virtual environment directory |
| | | ``env``. The following commands assume that our current working directory is |
| | | the ``env`` directory. |
| | | |
| | | The below example uses the ``pcreate`` command to create a project with the |
| | | ``starter`` scaffold. |
| | |
| | | .. code-block:: text |
| | | |
| | | > %VENV%\Scripts\pcreate -s starter MyProject |
| | | |
| | | Here's sample output from a run of ``pcreate`` on UNIX for a project we name |
| | | ``MyProject``: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pcreate -s starter MyProject |
| | | Creating template pyramid |
| | | Creating directory ./MyProject |
| | | # ... more output ... |
| | | Running /Users/chrism/projects/pyramid/bin/python setup.py egg_info |
| | | |
| | | As a result of invoking the ``pcreate`` command, a directory named |
| | | ``MyProject`` is created. That directory is a :term:`project` directory. The |
| | | ``setup.py`` file in that directory can be used to distribute your application, |
| | | or install your application for deployment or development. |
| | | |
| | | A ``.ini`` file named ``development.ini`` will be created in the project |
| | | An ``.ini`` file named ``development.ini`` will be created in the project |
| | | directory. You will use this ``.ini`` file to configure a server, to run your |
| | | application, and to debug your application. It contains configuration that |
| | | enables an interactive debugger and settings optimized for development. |
| | |
| | | which holds very simple :app:`Pyramid` sample code. This is where you'll edit |
| | | your application's Python code and templates. |
| | | |
| | | We created this project within an ``env`` virtualenv directory. However, note |
| | | that this is not mandatory. The project directory can go more or less anywhere |
| | | on your filesystem. You don't need to put it in a special "web server" |
| | | directory, and you don't need to put it within a virtualenv directory. The |
| | | author uses Linux mainly, and tends to put project directories which he creates |
| | | within his ``~/projects`` directory. On Windows, it's a good idea to put |
| | | project directories within a directory that contains no space characters, so |
| | | it's wise to *avoid* a path that contains, i.e., ``My Documents``. As a |
| | | result, the author, when he uses Windows, just puts his projects in |
| | | ``C:\projects``. |
| | | We created this project within an ``env`` virtual environment directory. |
| | | However, note that this is not mandatory. The project directory can go more or |
| | | less anywhere on your filesystem. You don't need to put it in a special "web |
| | | server" directory, and you don't need to put it within a virtual environment |
| | | directory. The author uses Linux mainly, and tends to put project directories |
| | | which he creates within his ``~/projects`` directory. On Windows, it's a good |
| | | idea to put project directories within a directory that contains no space |
| | | characters, so it's wise to *avoid* a path that contains, i.e., ``My |
| | | Documents``. As a result, the author, when he uses Windows, just puts his |
| | | projects in ``C:\projects``. |
| | | |
| | | .. warning:: |
| | | |
| | |
| | | |
| | | To install a newly created project for development, you should ``cd`` to the |
| | | newly created project directory and use the Python interpreter from the |
| | | :term:`virtualenv` you created during :ref:`installing_chapter` to invoke the |
| | | command ``python setup.py develop`` |
| | | :term:`virtual environment` you created during :ref:`installing_chapter` to |
| | | invoke the command ``pip install -e .``, which installs the project in |
| | | development mode (``-e`` is for "editable") into the current directory (``.``). |
| | | |
| | | The file named ``setup.py`` will be in the root of the pcreate-generated |
| | | project directory. The ``python`` you're invoking should be the one that lives |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd MyProject |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | Or on Windows: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | > cd MyProject |
| | | > %VENV%\Scripts\python.exe setup.py develop |
| | | > %VENV%\Scripts\pip install -e . |
| | | |
| | | Elided output from a run of this command on UNIX is shown below: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ cd MyProject |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | ... |
| | | Finished processing dependencies for MyProject==0.0 |
| | | Successfully installed Chameleon-2.24 Mako-1.0.4 MyProject \ |
| | | pyramid-chameleon-0.3 pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 |
| | | |
| | | This will install a :term:`distribution` representing your project into the |
| | | virtual environment interpreter's library set so it can be found by ``import`` |
| | |
| | | Running the Tests for Your Application |
| | | -------------------------------------- |
| | | |
| | | To run unit tests for your application, you should invoke them using the Python |
| | | interpreter from the :term:`virtualenv` you created during |
| | | :ref:`installing_chapter` (the ``python`` command that lives in the ``bin`` |
| | | directory of your virtualenv). |
| | | To run unit tests for your application, you must first install the testing |
| | | dependencies. |
| | | |
| | | On UNIX: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py test -q |
| | | $ $VENV/bin/pip install -e ".[testing]" |
| | | |
| | | Or on Windows: |
| | | On Windows: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | > %VENV%\Scripts\python.exe setup.py test -q |
| | | > %VENV%\Scripts\pip install -e ".[testing]" |
| | | |
| | | Once the testing requirements are installed, then you can run the tests using |
| | | the ``py.test`` command that was just installed in the ``bin`` directory of |
| | | your virtual environment. |
| | | |
| | | On UNIX: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/py.test myproject/tests.py -q |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | > %VENV%\Scripts\py.test myproject\tests.py -q |
| | | |
| | | Here's sample output from a test run on UNIX: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py test -q |
| | | running test |
| | | running egg_info |
| | | writing requirements to MyProject.egg-info/requires.txt |
| | | writing MyProject.egg-info/PKG-INFO |
| | | writing top-level names to MyProject.egg-info/top_level.txt |
| | | writing dependency_links to MyProject.egg-info/dependency_links.txt |
| | | writing entry points to MyProject.egg-info/entry_points.txt |
| | | reading manifest file 'MyProject.egg-info/SOURCES.txt' |
| | | reading manifest template 'MANIFEST.in' |
| | | warning: no files found matching '*.cfg' |
| | | warning: no files found matching '*.rst' |
| | | warning: no files found matching '*.ico' under directory 'myproject' |
| | | warning: no files found matching '*.gif' under directory 'myproject' |
| | | warning: no files found matching '*.jpg' under directory 'myproject' |
| | | warning: no files found matching '*.txt' under directory 'myproject' |
| | | warning: no files found matching '*.mak' under directory 'myproject' |
| | | warning: no files found matching '*.mako' under directory 'myproject' |
| | | warning: no files found matching '*.js' under directory 'myproject' |
| | | warning: no files found matching '*.html' under directory 'myproject' |
| | | warning: no files found matching '*.xml' under directory 'myproject' |
| | | writing manifest file 'MyProject.egg-info/SOURCES.txt' |
| | | running build_ext |
| | | . |
| | | ---------------------------------------------------------------------- |
| | | Ran 1 test in 0.008s |
| | | |
| | | OK |
| | | $ $VENV/bin/py.test myproject/tests.py -q |
| | | .. |
| | | 2 passed in 0.47 seconds |
| | | |
| | | The tests themselves are found in the ``tests.py`` module in your ``pcreate`` |
| | | generated project. Within a project generated by the ``starter`` scaffold, a |
| | | single sample test exists. |
| | | generated project. Within a project generated by the ``starter`` scaffold, |
| | | only two sample tests exist. |
| | | |
| | | .. note:: |
| | | |
| | | The ``-q`` option is passed to the ``setup.py test`` command to limit the |
| | | output to a stream of dots. If you don't pass ``-q``, you'll see more |
| | | verbose test result output (which normally isn't very useful). |
| | | The ``-q`` option is passed to the ``py.test`` command to limit the output |
| | | to a stream of dots. If you don't pass ``-q``, you'll see verbose test |
| | | result output (which normally isn't very useful). |
| | | |
| | | .. index:: |
| | | single: running an application |
| | |
| | | # .. other settings ... |
| | | debugtoolbar.hosts = 192.168.1.1 |
| | | |
| | | For more information about what the debug toolbar allows you to do, see `the |
| | | documentation for pyramid_debugtoolbar |
| | | <http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest/>`_. |
| | | For more information about what the debug toolbar allows you to do, see the |
| | | :ref:`documentation for pyramid_debugtoolbar <toolbar:overview>`. |
| | | |
| | | The debug toolbar will not be shown (and all debugging will be turned off) when |
| | | you use the ``production.ini`` file instead of the ``development.ini`` ini file |
| | |
| | | ~~~~~~~~~~~~ |
| | | |
| | | The ``setup.py`` file is a :term:`setuptools` setup file. It is meant to be |
| | | run directly from the command line to perform a variety of functions, such as |
| | | testing, packaging, and distributing your application. |
| | | used to define requirements for installing dependencies for your package and |
| | | testing, as well as distributing your application. |
| | | |
| | | .. note:: |
| | | |
| | | ``setup.py`` is the de facto standard which Python developers use to |
| | | distribute their reusable code. You can read more about ``setup.py`` files |
| | | and their usage in the `Setuptools documentation |
| | | <http://peak.telecommunity.com/DevCenter/setuptools>`_ and `Python Packaging |
| | | User Guide <https://packaging.python.org/en/latest/>`_. |
| | | and their usage in the `Python Packaging User Guide |
| | | <https://packaging.python.org/en/latest/>`_ and `Setuptools documentation |
| | | <http://pythonhosted.org/setuptools/>`_. |
| | | |
| | | Our generated ``setup.py`` looks like this: |
| | | |
| | |
| | | :linenos: |
| | | |
| | | The ``setup.py`` file calls the setuptools ``setup`` function, which does |
| | | various things depending on the arguments passed to ``setup.py`` on the command |
| | | various things depending on the arguments passed to ``pip`` on the command |
| | | line. |
| | | |
| | | Within the arguments to this function call, information about your application |
| | |
| | | Your application's name can be any string; it is specified in the ``name`` |
| | | field. The version number is specified in the ``version`` value. A short |
| | | description is provided in the ``description`` field. The ``long_description`` |
| | | is conventionally the content of the README and CHANGES file appended together. |
| | | The ``classifiers`` field is a list of `Trove |
| | | is conventionally the content of the ``README`` and ``CHANGES`` files appended |
| | | together. The ``classifiers`` field is a list of `Trove |
| | | <http://pypi.python.org/pypi?%3Aaction=list_classifiers>`_ classifiers |
| | | describing your application. ``author`` and ``author_email`` are text fields |
| | | which probably don't need any description. ``url`` is a field that should |
| | |
| | | causes all packages within the project to be found when packaging the |
| | | application. ``include_package_data`` will include non-Python files when the |
| | | application is packaged if those files are checked into version control. |
| | | ``zip_safe`` indicates that this package is not safe to use as a zipped egg; |
| | | instead it will always unpack as a directory, which is more convenient. |
| | | ``install_requires`` and ``tests_require`` indicate that this package depends |
| | | on the ``pyramid`` package. ``test_suite`` points at the package for our |
| | | application, which means all tests found in the package will be run when |
| | | ``setup.py test`` is invoked. We examined ``entry_points`` in our discussion |
| | | of the ``development.ini`` file; this file defines the ``main`` entry point |
| | | that represents our project's application. |
| | | ``zip_safe=False`` indicates that this package is not safe to use as a zipped |
| | | egg; instead it will always unpack as a directory, which is more convenient. |
| | | ``install_requires`` indicate that this package depends on the ``pyramid`` |
| | | package. ``extras_require`` is a Python dictionary that defines what is |
| | | required to be installed for running tests. We examined ``entry_points`` in our |
| | | discussion of the ``development.ini`` file; this file defines the ``main`` |
| | | entry point that represents our project's application. |
| | | |
| | | Usually you only need to think about the contents of the ``setup.py`` file when |
| | | distributing your application to other people, when adding Python package |
| | |
| | | $ $VENV/bin/python setup.py sdist |
| | | |
| | | This will create a tarball of your application in a ``dist`` subdirectory named |
| | | ``MyProject-0.1.tar.gz``. You can send this tarball to other people who want |
| | | ``MyProject-0.0.tar.gz``. You can send this tarball to other people who want |
| | | to install and use your application. |
| | | |
| | | .. index:: |
| | |
| | | |
| | | .. literalinclude:: MyProject/myproject/tests.py |
| | | :language: python |
| | | :lines: 1-17 |
| | | :linenos: |
| | | |
| | | This sample ``tests.py`` file has a single unit test defined within it. This |
| | | test is executed when you run ``python setup.py test``. You may add more tests |
| | | here as you build your application. You are not required to write tests to use |
| | | :app:`Pyramid`. This file is simply provided for convenience and example. |
| | | This sample ``tests.py`` file has one unit test and one functional test defined |
| | | within it. These tests are executed when you run ``py.test myproject/tests.py |
| | | -q``. You may add more tests here as you build your application. You are not |
| | | required to write tests to use :app:`Pyramid`. This file is simply provided for |
| | | convenience and example. |
| | | |
| | | See :ref:`testing_chapter` for more information about writing :app:`Pyramid` |
| | | unit tests. |
| | |
| | | |
| | | In the above example, we create a ``MyTest`` test case that inherits from |
| | | :class:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will |
| | | be found when ``setup.py test`` is run. It has two test methods. |
| | | be found when ``py.test`` is run. It has two test methods. |
| | | |
| | | The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when |
| | | the authentication policy forbids the current user the ``edit`` permission. Its |
| | |
| | | |
| | | In Pyramid, functional tests are typically written using the :term:`WebTest` |
| | | package, which provides APIs for invoking HTTP(S) requests to your application. |
| | | We also like ``py.test`` and ``pytest-cov`` to provide simple testing and |
| | | coverage reports. |
| | | |
| | | Regardless of which testing :term:`package` you use, ensure to add a |
| | | ``tests_require`` dependency on that package to your application's |
| | | ``setup.py`` file. Using the project ``MyProject`` generated by the starter |
| | | scaffold as described in :doc:`project`, we would insert the following code immediately following the |
| | | ``requires`` block in the file ``MyProject/setup.py``. |
| | | Regardless of which testing :term:`package` you use, be sure to add a |
| | | ``tests_require`` dependency on that package to your application's ``setup.py`` |
| | | file. Using the project ``MyProject`` generated by the starter scaffold as |
| | | described in :doc:`project`, we would insert the following code immediately |
| | | following the ``requires`` block in the file ``MyProject/setup.py``. |
| | | |
| | | .. code-block:: ini |
| | | .. literalinclude:: MyProject/setup.py |
| | | :language: python |
| | | :linenos: |
| | | :lines: 11-22 |
| | | :lineno-start: 11 |
| | | :emphasize-lines: 8- |
| | | |
| | | requires = [ |
| | | 'pyramid', |
| | | 'pyramid_chameleon', |
| | | 'pyramid_debugtoolbar', |
| | | 'waitress', |
| | | ] |
| | | |
| | | test_requires = [ |
| | | 'webtest', |
| | | ] |
| | | |
| | | Remember to change the dependency. |
| | | |
| | | .. code-block:: ini |
| | | .. literalinclude:: MyProject/setup.py |
| | | :language: python |
| | | :linenos: |
| | | :lineno-start: 39 |
| | | :emphasize-lines: 2 |
| | | :lines: 40-44 |
| | | :lineno-start: 40 |
| | | :emphasize-lines: 2-4 |
| | | |
| | | install_requires=requires, |
| | | tests_require=test_requires, |
| | | test_suite="myproject", |
| | | |
| | | As always, whenever you change your dependencies, make sure to run the |
| | | following command. |
| | | As always, whenever you change your dependencies, make sure to run the correct |
| | | ``pip install -e`` command. |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $VENV/bin/python setup.py develop |
| | | $VENV/bin/pip install -e ".[testing]" |
| | | |
| | | In your ``MyPackage`` project, your :term:`package` is named ``myproject`` |
| | | which contains a ``views`` module, which in turn contains a :term:`view` |
| | |
| | | |
| | | Once you have a standard Python environment setup, getting started with Pyramid |
| | | is a breeze. Unfortunately "standard" is not so simple in Python. For this |
| | | Quick Tour, it means `Python <https://www.python.org/downloads/>`_, a `virtual |
| | | environment <http://docs.python.org/dev/library/venv.html>`_ (or `virtualenv |
| | | for Python 2.7 <https://pypi.python.org/pypi/virtualenv>`_), and `setuptools |
| | | <https://pypi.python.org/pypi/setuptools/>`_. |
| | | Quick Tour, it means `Python <https://www.python.org/downloads/>`_, `venv |
| | | <https://packaging.python.org/en/latest/projects/#venv>`_ (or `virtualenv for |
| | | Python 2.7 <https://packaging.python.org/en/latest/projects/#virtualenv>`_), |
| | | `pip <https://packaging.python.org/en/latest/projects/#pip>`_, and `setuptools |
| | | <https://packaging.python.org/en/latest/projects/#easy-install>`_. |
| | | |
| | | As an example, for Python 3.3+ on Linux: |
| | | To save a little bit of typing and to be certain that we use the modules, |
| | | scripts, and packages installed in our virtual environment, we'll set an |
| | | environment variable, too. |
| | | |
| | | As an example, for Python 3.5+ on Linux: |
| | | |
| | | .. parsed-literal:: |
| | | |
| | | $ pyvenv env33 |
| | | $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | env33/bin/python |
| | | $ env33/bin/easy_install "pyramid==\ |release|\ " |
| | | # set an environment variable to where you want your virtual environment |
| | | $ export VENV=~/env |
| | | # create the virtual environment |
| | | $ python3 -m venv $VENV |
| | | # install pyramid |
| | | $ $VENV/bin/pip install pyramid |
| | | # or for a specific released version |
| | | $ $VENV/bin/pip install "pyramid==\ |release|\ " |
| | | |
| | | For Windows: |
| | | |
| | | .. parsed-literal:: |
| | | |
| | | # Use your browser to download: |
| | | # https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py |
| | | c:\\> c:\\Python33\\python -m venv env33 |
| | | c:\\> env33\\Scripts\\python ez_setup.py |
| | | c:\\> env33\\Scripts\\easy_install "pyramid==\ |release|\ " |
| | | # set an environment variable to where you want your virtual environment |
| | | c:\> set VENV=c:\env |
| | | # create the virtual environment |
| | | c:\\> c:\\Python35\\python3 -m venv %VENV% |
| | | # install pyramid |
| | | c:\\> %VENV%\\Scripts\\pip install pyramid |
| | | # or for a specific released version |
| | | c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " |
| | | |
| | | Of course Pyramid runs fine on Python 2.6+, as do the examples in this *Quick |
| | | Tour*. We're just showing Python 3 a little love (Pyramid had production |
| | | support for Python 3 in October 2011). |
| | | |
| | | .. note:: |
| | | |
| | | Why ``easy_install`` and not ``pip``? Some distributions upon which |
| | | Pyramid depends have optional C extensions for performance. ``pip`` cannot |
| | | install some binary Python distributions. With ``easy_install``, Windows |
| | | users are able to obtain binary Python distributions, so they get the |
| | | benefit of the C extensions without needing a C compiler. Also there can |
| | | be issues when ``pip`` and ``easy_install`` are used side-by-side in the |
| | | same environment, so we chose to recommend ``easy_install`` for the sake of |
| | | reducing the complexity of these instructions. |
| | | Tour*. We're showing Python 3 for simplicity. (Pyramid had production support |
| | | for Python 3 in October 2011.) Also for simplicity, the remaining examples will |
| | | show only UNIX commands. |
| | | |
| | | .. seealso:: See also: |
| | | :ref:`Quick Tutorial section on Requirements <qtut_requirements>`, |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ python ./app.py |
| | | $ $VENV/bin/python ./app.py |
| | | |
| | | Next open http://localhost:6543/ in a browser, and you will see the ``Hello |
| | | World!`` message. |
| | |
| | | |
| | | In this Pyramid view, we get the URL being visited from ``request.url``. Also |
| | | if you visited http://localhost:6543/?name=alice in a browser, the name is |
| | | included in the body of the response:: |
| | | included in the body of the response: |
| | | |
| | | .. code-block:: text |
| | | |
| | | URL http://localhost:6543/?name=alice with name: alice |
| | | |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ easy_install pyramid_chameleon |
| | | $ $VENV/bin/pip install pyramid_chameleon |
| | | |
| | | With the package installed, we can include the template bindings into our |
| | | configuration in ``app.py``: |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ easy_install pyramid_jinja2 |
| | | $ $VENV/bin/pip install pyramid_jinja2 |
| | | |
| | | With the package installed, we can include the template bindings into our |
| | | configuration: |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd hello_world |
| | | $ python ./setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | We are moving in the direction of a full-featured Pyramid project, with a |
| | | proper setup for Python standards (packaging) and Pyramid configuration. This |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ pserve development.ini |
| | | $ $VENV/bin/pserve development.ini |
| | | |
| | | Let's look at ``pserve`` and configuration in more depth. |
| | | |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ pserve development.ini --reload |
| | | $ $VENV/bin/pserve development.ini --reload |
| | | |
| | | The ``pserve`` command has a number of other options and operations. Most of |
| | | the work, though, comes from your project's wiring, as expressed in the |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ python ./setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | The ``pyramid_debugtoolbar`` package is a Pyramid add-on, which means we need |
| | | to include its configuration into our web application. The ``pyramid_jinja2`` |
| | |
| | | :ref:`Quick Tutorial pyramid_debugtoolbar <qtut_debugtoolbar>` and |
| | | :ref:`pyramid_debugtoolbar <toolbar:overview>` |
| | | |
| | | Unit tests and ``nose`` |
| | | ======================= |
| | | Unit tests and ``py.test`` |
| | | ========================== |
| | | |
| | | Yikes! We got this far and we haven't yet discussed tests. This is particularly |
| | | egregious, as Pyramid has had a deep commitment to full test coverage since |
| | | before its release. |
| | | |
| | | Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module with |
| | | one unit test in it. To run it, let's install the handy ``nose`` test runner by |
| | | editing ``setup.py``. While we're at it, we'll throw in the ``coverage`` tool |
| | | which yells at us for code that isn't tested. Edit line 36 so it becomes the |
| | | following: |
| | | one unit test in it. To run it, let's install the handy ``pytest`` test runner |
| | | by editing ``setup.py``. While we're at it, we'll throw in the ``pytest-cov`` |
| | | tool which yells at us for code that isn't tested. Insert and edit the |
| | | following lines as shown: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | :lineno-start: 36 |
| | | :lineno-start: 11 |
| | | :emphasize-lines: 8-12 |
| | | |
| | | tests_require={ |
| | | 'testing': ['nose', 'coverage'], |
| | | }, |
| | | requires = [ |
| | | 'pyramid', |
| | | 'pyramid_jinja2', |
| | | 'pyramid_debugtoolbar', |
| | | 'waitress', |
| | | ] |
| | | |
| | | We changed ``setup.py`` which means we need to rerun |
| | | ``python ./setup.py develop``. We can now run all our tests: |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | :lineno-start: 34 |
| | | :emphasize-lines: 2-4 |
| | | |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | |
| | | We changed ``setup.py`` which means we need to rerun ``$VENV/bin/pip install -e |
| | | ".[testing]"``. We can now run all our tests: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ nosetests hello_world/tests.py |
| | | . |
| | | Name Stmts Miss Cover Missing |
| | | --------------------------------------------------- |
| | | hello_world 11 8 27% 11-23 |
| | | hello_world.models 5 1 80% 8 |
| | | hello_world.tests 14 0 100% |
| | | hello_world.views 4 0 100% |
| | | --------------------------------------------------- |
| | | TOTAL 34 9 74% |
| | | ---------------------------------------------------------------------- |
| | | Ran 1 test in 0.009s |
| | | $ $VENV/bin/py.test --cov=hello_world --cov-report=term-missing hello_world/tests.py |
| | | |
| | | OK |
| | | This yields the following output. |
| | | |
| | | Our unit test passed. What did our test look like? |
| | | .. code-block:: text |
| | | |
| | | =========================== test session starts =========================== |
| | | platform darwin -- Python 3.5.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 |
| | | rootdir: /Users/stevepiercy/projects/hack-on-pyramid/hello_world, inifile: |
| | | plugins: cov-2.2.1 |
| | | collected 1 items |
| | | |
| | | hello_world/tests.py . |
| | | ------------- coverage: platform darwin, python 3.5.0-final-0 ------------- |
| | | Name Stmts Miss Cover Missing |
| | | -------------------------------------------------------- |
| | | hello_world/__init__.py 11 8 27% 11-23 |
| | | hello_world/resources.py 5 1 80% 8 |
| | | hello_world/tests.py 14 0 100% |
| | | hello_world/views.py 4 0 100% |
| | | -------------------------------------------------------- |
| | | TOTAL 34 9 74% |
| | | |
| | | ========================= 1 passed in 0.22 seconds ========================= |
| | | |
| | | Our unit test passed, although its coverage is incomplete. What did our test |
| | | look like? |
| | | |
| | | .. literalinclude:: quick_tour/package/hello_world/tests.py |
| | | :linenos: |
| | |
| | | |
| | | Our application, a package named ``hello_world``, is set up as a logger and |
| | | configured to log messages at a ``DEBUG`` or higher level. When you visit |
| | | http://localhost:6543, your console will now show:: |
| | | 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 |
| | | |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ pcreate --scaffold alchemy sqla_demo |
| | | $ $VENV/bin/pcreate --scaffold alchemy sqla_demo |
| | | $ cd sqla_demo |
| | | $ python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | We now have a working sample SQLAlchemy application with all dependencies |
| | | installed. The sample project provides a console script to initialize a SQLite |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ initialize_sqla_demo_db development.ini |
| | | $ pserve development.ini |
| | | $ $VENV/bin/initialize_sqla_demo_db development.ini |
| | | $ $VENV/bin/pserve development.ini |
| | | |
| | | The ORM eases the mapping of database structures into a programming language. |
| | | SQLAlchemy uses "models" for this mapping. The scaffold generated a sample |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_sqla_demo_db development.ini |
| | | |
| | |
| | | .. _qtut_authentication: |
| | | |
| | | ============================== |
| | | 20: Logins With Authentication |
| | | ============================== |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes authentication; cd authentication |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Put the security hash in the ``authentication/development.ini`` |
| | | configuration file as ``tutorial.secret`` instead of putting it in |
| | |
| | | .. _qtut_authorization: |
| | | |
| | | =========================================== |
| | | 21: Protecting Resources With Authorization |
| | | =========================================== |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r authentication authorization; cd authorization |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Start by changing ``authorization/tutorial/__init__.py`` to |
| | | specify a root factory to the :term:`configurator`: |
| | |
| | | |
| | | .. note:: |
| | | |
| | | We aren't yet doing ``$VENV/bin/python setup.py develop`` as we |
| | | We aren't yet doing ``$VENV/bin/pip install -e .`` as we |
| | | will change it later. |
| | | |
| | | #. Our configuration file at ``databases/development.ini`` wires |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. The script references some models in ``databases/tutorial/models.py``: |
| | | |
| | |
| | | |
| | | The ``initialize_tutorial_db`` is a nice example of framework support. |
| | | You point your setup at the location of some ``[console_scripts]`` and |
| | | these get generated into your virtualenv's ``bin`` directory. Our |
| | | these get generated into your virtual environment's ``bin`` directory. Our |
| | | console script follows the pattern of being fed a configuration file |
| | | with all the bootstrapping. It then opens SQLAlchemy and creates the |
| | | root of the wiki, which also makes the SQLite file. Note the |
| | |
| | | 04: Easier Development with ``debugtoolbar`` |
| | | ============================================ |
| | | |
| | | Error-handling and introspection using the ``pyramid_debugtoolbar`` |
| | | add-on. |
| | | Error handling and introspection using the ``pyramid_debugtoolbar`` add-on. |
| | | |
| | | Background |
| | | ========== |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r ini debugtoolbar; cd debugtoolbar |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/easy_install pyramid_debugtoolbar |
| | | $ $VENV/bin/pip install -e . |
| | | $ $VENV/bin/pip install pyramid_debugtoolbar |
| | | |
| | | #. Our ``debugtoolbar/development.ini`` gets a configuration entry for |
| | | ``pyramid.includes``: |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Register a static view in ``forms/tutorial/__init__.py`` for |
| | | Deform's CSS/JS etc. as well as our demo wikipage scenario's |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r unit_testing functional_testing; cd functional_testing |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/easy_install webtest |
| | | $ $VENV/bin/pip install -e . |
| | | $ $VENV/bin/pip install webtest |
| | | |
| | | #. Let's extend ``functional_testing/tutorial/tests.py`` to include a |
| | | functional test: |
| | |
| | | ================================ |
| | | |
| | | What's the simplest way to get started in Pyramid? A single-file module. |
| | | No Python packages, no ``setup.py``, no other machinery. |
| | | No Python packages, no ``pip install -e .``, no other machinery. |
| | | |
| | | Background |
| | | ========== |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Let's make a file ``ini/development.ini`` for our configuration: |
| | | |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes jinja2; cd jinja2 |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/easy_install pyramid_jinja2 |
| | | $ $VENV/bin/pip install -e . |
| | | $ $VENV/bin/pip install pyramid_jinja2 |
| | | |
| | | #. We need to include ``pyramid_jinja2`` in |
| | | ``jinja2/tutorial/__init__.py``: |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes json; cd json |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. We add a new route for ``hello_json`` in |
| | | ``json/tutorial/__init__.py``: |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes logging; cd logging |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Extend ``logging/tutorial/views.py`` to log a message: |
| | | |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r templating more_view_classes; cd more_view_classes |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Our route in ``more_view_classes/tutorial/__init__.py`` needs some |
| | | replacement patterns: |
| | |
| | | directory is on ``sys.path`` and has a special file named |
| | | ``__init__.py``, it is treated as a Python package. |
| | | |
| | | Packages can be bundled up, made available for installation, |
| | | and installed through a (muddled, but improving) toolchain oriented |
| | | around a ``setup.py`` file for a |
| | | `setuptools project <http://pythonhosted.org/setuptools/setuptools.html>`_. |
| | | Explaining it all in this |
| | | tutorial will induce madness. For this tutorial, this is all you need to |
| | | know: |
| | | Packages can be bundled up, made available for installation, and installed |
| | | through a toolchain oriented around a ``setup.py`` file. For this tutorial, |
| | | this is all you need to know: |
| | | |
| | | - We will have a directory for each tutorial step as a setuptools *project* |
| | | - We will have a directory for each tutorial step as a *project*. |
| | | |
| | | - This project will contain a ``setup.py`` which injects the features |
| | | of the setuptool's project machinery into the directory |
| | | - This project will contain a ``setup.py`` which injects the features of the |
| | | project machinery into the directory. |
| | | |
| | | - In this project we will make a ``tutorial`` subdirectory into a Python |
| | | *package* using an ``__init__.py`` Python module file |
| | | *package* using an ``__init__.py`` Python module file. |
| | | |
| | | - We will run ``python setup.py develop`` to install our project in |
| | | development mode |
| | | - We will run ``pip install -e .`` to install our project in development mode. |
| | | |
| | | In summary: |
| | | |
| | | - You'll do your development in a Python *package* |
| | | - You'll do your development in a Python *package*. |
| | | |
| | | - That package will be part of a setuptools *project* |
| | | - That package will be part of a *project*. |
| | | |
| | | Objectives |
| | | ========== |
| | | |
| | | - Make a Python "package" directory with an ``__init__.py`` |
| | | - Make a Python "package" directory with an ``__init__.py``. |
| | | |
| | | - Get a minimum Python "project" in place by making a ``setup.py`` |
| | | - Get a minimum Python "project" in place by making a ``setup.py``. |
| | | |
| | | - Install our ``tutorial`` project in development mode |
| | | - Install our ``tutorial`` project in development mode. |
| | | |
| | | Steps |
| | | ===== |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | $ mkdir tutorial |
| | | |
| | | #. Enter the following into ``package/tutorial/__init__.py``: |
| | |
| | | tries to capture how this stuff works a step at a time. It's generally a bad |
| | | idea to run a Python module inside a package directly as a script. |
| | | |
| | | .. seealso:: :ref:`Python Packages <python:tut-packages>`, |
| | | `setuptools Entry Points <http://pythonhosted.org/setuptools/pkg_resources.html#entry-points>`_ |
| | | .. seealso:: :ref:`Python Packages <python:tut-packages>` and `Working in |
| | | "Development Mode" |
| | | <https://packaging.python.org/en/latest/distributing/#working-in-development-mode>`_. |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes request_response; cd request_response |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Simplify the routes in ``request_response/tutorial/__init__.py``: |
| | | |
| | |
| | | Requirements |
| | | ============ |
| | | |
| | | Let's get our tutorial environment setup. Most of the setup work is in |
| | | standard Python development practices (install Python, |
| | | make an isolated environment, and setup packaging tools.) |
| | | Let's get our tutorial environment set up. Most of the set up work is in |
| | | standard Python development practices (install Python and make an isolated |
| | | environment.) |
| | | |
| | | .. note:: |
| | | |
| | |
| | | |
| | | This *Quick Tutorial* is based on: |
| | | |
| | | * **Python 3.3**. Pyramid fully supports Python 3.3+ and Python 2.6+. |
| | | This tutorial uses **Python 3.3** but runs fine under Python 2.7. |
| | | * **Python 3.5**. Pyramid fully supports Python 3.3+ and Python 2.6+. This |
| | | tutorial uses **Python 3.5** but runs fine under Python 2.7. |
| | | |
| | | * **pyvenv**. We believe in virtual environments. For this tutorial, |
| | | we use Python 3.3's built-in solution, the ``pyvenv`` command. |
| | | For Python 2.7, you can install ``virtualenv``. |
| | | * **venv**. We believe in virtual environments. For this tutorial, we use |
| | | Python 3.5's built-in solution ``venv``. For Python 2.7, you can install |
| | | ``virtualenv``. |
| | | |
| | | * **setuptools and easy_install**. We use |
| | | `setuptools <https://pypi.python.org/pypi/setuptools/>`_ |
| | | and its ``easy_install`` for package management. |
| | | * **pip**. We use ``pip`` for package management. |
| | | |
| | | * **Workspaces, projects, and packages.** Our home directory |
| | | will contain a *tutorial workspace* with our Python virtual |
| | |
| | | Steps |
| | | ===== |
| | | |
| | | #. :ref:`install-python-3.3-or-greater` |
| | | #. :ref:`install-python-3` |
| | | #. :ref:`create-a-project-directory-structure` |
| | | #. :ref:`set-an-environment-variable` |
| | | #. :ref:`create-a-virtual-environment` |
| | | #. :ref:`install-setuptools-(python-packaging-tools)` |
| | | #. :ref:`install-pyramid` |
| | | |
| | | .. _install-python-3.3-or-greater: |
| | | |
| | | Install Python 3.3 or greater |
| | | ----------------------------- |
| | | .. _install-python-3: |
| | | |
| | | Download the latest standard Python 3.3+ release (not development release) |
| | | from `python.org <https://www.python.org/downloads/>`_. |
| | | Install Python 3 |
| | | ---------------- |
| | | |
| | | Windows and Mac OS X users can download and run an installer. |
| | | |
| | | Download the latest standard Python 3 release (not development release) from |
| | | `python.org <https://www.python.org/downloads/>`_. |
| | | |
| | | Windows users should also install the `Python for Windows extensions |
| | | <http://sourceforge.net/projects/pywin32/files/pywin32/>`_. Carefully read the |
| | |
| | | directions. Make sure you get the proper 32- or 64-bit build and Python |
| | | version. |
| | | |
| | | Linux users can either use their package manager to install Python 3.3 |
| | | or may `build Python 3.3 from source |
| | | Linux users can either use their package manager to install Python 3 |
| | | or may `build Python 3 from source |
| | | <http://pyramid.readthedocs.org/en/master/narr/install.html#package-manager- |
| | | method>`_. |
| | | |
| | | .. seealso:: See also :ref:`For Mac OS X Users <for-mac-os-x-users>`, :ref:`If |
| | | You Don't Yet Have a Python Interpreter (UNIX) |
| | | <if-you-don-t-yet-have-a-python-interpreter-unix>`, and :ref:`If You Don't |
| | | Yet Have a Python Interpreter (Windows) |
| | | <if-you-don-t-yet-have-a-python-interpreter-windows>`. |
| | | |
| | | |
| | | .. _create-a-project-directory-structure: |
| | |
| | | Next within ``projects`` is your workspace directory, here named |
| | | ``quick_tutorial``. A workspace is a common term used by integrated |
| | | development environments (IDE) like PyCharm and PyDev that stores |
| | | isolated Python environments (virtualenvs) and specific project files |
| | | isolated Python environments (virtual environments) and specific project files |
| | | and repositories. |
| | | |
| | | |
| | |
| | | # Mac and Linux |
| | | $ export VENV=~/projects/quick_tutorial/env |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | # Windows |
| | | # TODO: This command does not work |
| | | c:\> set VENV=c:\projects\quick_tutorial\env |
| | |
| | | Create a Virtual Environment |
| | | ---------------------------- |
| | | |
| | | .. warning:: The current state of isolated Python environments using |
| | | ``pyvenv`` on Windows is suboptimal in comparison to Mac and Linux. See |
| | | http://stackoverflow.com/q/15981111/95735 for a discussion of the issue |
| | | and `PEP 453 <http://www.python.org/dev/peps/pep-0453/>`_ for a proposed |
| | | resolution. |
| | | |
| | | ``pyvenv`` is a tool to create isolated Python 3.3 environments, each |
| | | with its own Python binary and independent set of installed Python |
| | | packages in its site directories. Let's create one, using the location |
| | | we just specified in the environment variable. |
| | | ``venv`` is a tool to create isolated Python 3 environments, each with its own |
| | | Python binary and independent set of installed Python packages in its site |
| | | directories. Let's create one, using the location we just specified in the |
| | | environment variable. |
| | | |
| | | .. code-block:: bash |
| | | |
| | | # Mac and Linux |
| | | $ pyvenv $VENV |
| | | $ python3 -m venv $VENV |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | # Windows |
| | | c:\> c:\Python33\python -m venv %VENV% |
| | | c:\> c:\Python35\python3 -m venv %VENV% |
| | | |
| | | .. seealso:: See also Python 3's :mod:`venv module <python3:venv>`, |
| | | Python 2's `virtualenv <http://www.virtualenv.org/en/latest/>`_ |
| | | package, |
| | | :ref:`Installing Pyramid on a Windows System <installing_windows>` |
| | | |
| | | |
| | | .. _install-setuptools-(python-packaging-tools): |
| | | |
| | | Install ``setuptools`` (Python packaging tools) |
| | | ----------------------------------------------- |
| | | |
| | | The following command will download a script to install ``setuptools``, then |
| | | pipe it to your environment's version of Python. |
| | | |
| | | .. code-block:: bash |
| | | |
| | | # Mac and Linux |
| | | $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | $VENV/bin/python |
| | | |
| | | # Windows |
| | | # |
| | | # Use your web browser to download this file: |
| | | # https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py |
| | | # |
| | | # ...and save it to: |
| | | # c:\projects\quick_tutorial\ez_setup.py |
| | | # |
| | | # Then run the following command: |
| | | |
| | | c:\> %VENV%\Scripts\python ez_setup.py |
| | | |
| | | If ``wget`` complains with a certificate error, then run this command instead: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | # Mac and Linux |
| | | $ wget --no-check-certificate https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | $VENV/bin/python |
| | | .. seealso:: See also Python 3's :mod:`venv module <python:venv>` and Python |
| | | 2's `virtualenv <https://virtualenv.pypa.io/en/latest/>`_ package. |
| | | |
| | | |
| | | .. _install-pyramid: |
| | |
| | | .. parsed-literal:: |
| | | |
| | | # Mac and Linux |
| | | $ $VENV/bin/easy_install "pyramid==\ |release|\ " |
| | | $ $VENV/bin/pip install "pyramid==\ |release|\ " |
| | | |
| | | # Windows |
| | | c:\\> %VENV%\\Scripts\\easy_install "pyramid==\ |release|\ " |
| | | c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " |
| | | |
| | | Our Python virtual environment now has the Pyramid software available. |
| | | |
| | |
| | | .. code-block:: bash |
| | | |
| | | # Mac and Linux |
| | | $ $VENV/bin/easy_install nose webtest deform sqlalchemy \ |
| | | $ $VENV/bin/pip install nose webtest deform sqlalchemy \ |
| | | pyramid_chameleon pyramid_debugtoolbar waitress \ |
| | | pyramid_tm zope.sqlalchemy |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | # Windows |
| | | c:\> %VENV%\Scripts\easy_install nose webtest deform sqlalchemy pyramid_chameleon pyramid_debugtoolbar waitress pyramid_tm zope.sqlalchemy |
| | | |
| | | |
| | | .. note:: |
| | | |
| | | Why ``easy_install`` and not ``pip``? Pyramid encourages use of namespace |
| | | packages, for which ``pip``'s support is less-than-optimal. Also, Pyramid's |
| | | dependencies use some optional C extensions for performance: with |
| | | ``easy_install``, Windows users can get these extensions without needing |
| | | a C compiler (``pip`` does not support installing binary Windows |
| | | distributions, except for ``wheels``, which are not yet available for |
| | | all dependencies). |
| | | |
| | | .. seealso:: See also :ref:`installing_unix`. For instructions to set up your |
| | | Python environment for development using Windows or Python 2, see Pyramid's |
| | | :ref:`Before You Install <installing_chapter>`. |
| | | |
| | | See also Python 3's :mod:`venv module <python3:venv>`, the `setuptools |
| | | installation instructions |
| | | <https://pypi.python.org/pypi/setuptools/0.9.8#installation-instructions>`_, |
| | | and `easy_install help <https://pypi.python.org/pypi/setuptools/0.9.8#using-setuptools-and-easyinstall>`_. |
| | | c:\> %VENV%\Scripts\pip install nose webtest deform sqlalchemy pyramid_chameleon pyramid_debugtoolbar waitress pyramid_tm zope.sqlalchemy |
| | | |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes routing; cd routing |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Our ``routing/tutorial/__init__.py`` needs a route with a replacement |
| | | pattern: |
| | |
| | | ========== |
| | | |
| | | We're going to cover a lot in this tutorial, focusing on one topic at a |
| | | time and writing everything from scratch. As a warmup, though, |
| | | time and writing everything from scratch. As a warm up, though, |
| | | it sure would be nice to see some pixels on a screen. |
| | | |
| | | Like other web development frameworks, Pyramid provides a number of |
| | |
| | | |
| | | $ $VENV/bin/pcreate --scaffold starter scaffolds |
| | | |
| | | #. Use normal Python development to setup our project for development: |
| | | #. Install our project in editable mode for development in the current |
| | | directory: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ cd scaffolds |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Startup the application by pointing Pyramid's ``pserve`` command at |
| | | #. Start up the application by pointing Pyramid's ``pserve`` command at |
| | | the project's (generated) configuration file: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pserve development.ini --reload |
| | | |
| | | On startup, ``pserve`` logs some output: |
| | | On start up, ``pserve`` logs some output: |
| | | |
| | | .. code-block:: bash |
| | | |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes sessions; cd sessions |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Our ``sessions/tutorial/__init__.py`` needs a choice of session |
| | | factory to get registered with the :term:`configurator`: |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r view_classes static_assets; cd static_assets |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. We add a call ``config.add_static_view`` in |
| | | ``static_assets/tutorial/__init__.py``: |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. We need to connect ``pyramid_chameleon`` as a renderer by making a |
| | | call in the setup of ``templating/tutorial/__init__.py``: |
| | |
| | | To successfully run each step:: |
| | | |
| | | $ cd request_response |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | ...and repeat for each step you would like to work on. In most cases we |
| | | will start with the results of an earlier step. |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/easy_install nose |
| | | $ $VENV/bin/pip install -e . |
| | | $ $VENV/bin/pip install nose |
| | | |
| | | #. Now we write a simple unit test in ``unit_testing/tutorial/tests.py``: |
| | | |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r templating view_classes; cd view_classes |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Our ``view_classes/tutorial/views.py`` now has a view class with |
| | | our two views: |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd ..; cp -r functional_testing views; cd views |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Our ``views/tutorial/__init__.py`` gets a lot shorter: |
| | | |
| | |
| | | .. _modwsgi_tutorial: |
| | | |
| | | Running a :app:`Pyramid` Application under ``mod_wsgi`` |
| | | ========================================================== |
| | | ======================================================= |
| | | |
| | | :term:`mod_wsgi` is an Apache module developed by Graham Dumpleton. |
| | | It allows :term:`WSGI` programs to be served using the Apache web |
| | |
| | | system. If you do not, install Apache 2.X for your platform in |
| | | whatever manner makes sense. |
| | | |
| | | #. It is also assumed that you have satisfied the |
| | | :ref:`requirements-for-installing-packages`. |
| | | |
| | | #. Once you have Apache installed, install ``mod_wsgi``. Use the |
| | | (excellent) `installation instructions |
| | | <http://code.google.com/p/modwsgi/wiki/InstallationInstructions>`_ |
| | | for your platform into your system's Apache installation. |
| | | |
| | | #. Install :term:`virtualenv` into the Python which mod_wsgi will |
| | | run using the ``easy_install`` program. |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ sudo /usr/bin/easy_install-2.6 virtualenv |
| | | |
| | | This command may need to be performed as the root user. |
| | | |
| | | #. Create a :term:`virtualenv` which we'll use to install our |
| | | #. Create a :term:`virtual environment` which we'll use to install our |
| | | application. |
| | | |
| | | .. code-block:: text |
| | |
| | | $ cd ~ |
| | | $ mkdir modwsgi |
| | | $ cd modwsgi |
| | | $ /usr/local/bin/virtualenv env |
| | | $ python3 -m venv env |
| | | |
| | | #. Install :app:`Pyramid` into the newly created virtualenv: |
| | | #. Install :app:`Pyramid` into the newly created virtual environment: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ cd ~/modwsgi/env |
| | | $ $VENV/bin/easy_install pyramid |
| | | $ $VENV/bin/pip install pyramid |
| | | |
| | | #. Create and install your :app:`Pyramid` application. For the purposes of |
| | | this tutorial, we'll just be using the ``pyramid_starter`` application as |
| | |
| | | $ cd ~/modwsgi/env |
| | | $ $VENV/bin/pcreate -s starter myapp |
| | | $ cd myapp |
| | | $ $VENV/bin/python setup.py install |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | #. Within the virtualenv directory (``~/modwsgi/env``), create a |
| | | #. Within the virtual environment directory (``~/modwsgi/env``), create a |
| | | script named ``pyramid.wsgi``. Give it these contents: |
| | | |
| | | .. code-block:: python |
| | |
| | | configuration documentation |
| | | <http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines>`_ for |
| | | more in-depth configuration information. |
| | | |
| | |
| | | ==================== |
| | | |
| | | :app:`Pyramid` provides facilities for :term:`authentication` and |
| | | ::term:`authorization`. We'll make use of both features to provide security |
| | | :to our application. Our application currently allows anyone with access to |
| | | :the server to view, edit, and add pages to our wiki. We'll change that to |
| | | :allow only people who are members of a *group* named ``group:editors`` to add |
| | | :and edit wiki pages but we'll continue allowing anyone with access to the |
| | | :server to view pages. |
| | | :term:`authorization`. We'll make use of both features to provide security to |
| | | our application. Our application currently allows anyone with access to the |
| | | server to view, edit, and add pages to our wiki. We'll change that to allow |
| | | only people who are members of a *group* named ``group:editors`` to add and |
| | | edit wiki pages, but we'll continue allowing anyone with access to the server |
| | | to view pages. |
| | | |
| | | We will also add a login page and a logout link on all the pages. The login |
| | | page will be shown when a user is denied access to any of the views that |
| | |
| | | Add users and groups |
| | | ~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Create a new ``tutorial/tutorial/security.py`` module with the |
| | | Create a new ``tutorial/security.py`` module with the |
| | | following content: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/security.py |
| | |
| | | Add an ACL |
| | | ~~~~~~~~~~ |
| | | |
| | | Open ``tutorial/tutorial/models.py`` and add the following import |
| | | Open ``tutorial/models.py`` and add the following import |
| | | statement at the head: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/models.py |
| | |
| | | Add authentication and authorization policies |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Open ``tutorial/tutorial/__init__.py`` and add the highlighted import |
| | | Open ``tutorial/__init__.py`` and add the highlighted import |
| | | statements: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/__init__.py |
| | |
| | | |
| | | Add permission declarations |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | Open ``tutorial/tutorial/views.py`` and add a ``permission='edit'`` parameter |
| | | Open ``tutorial/views.py`` and add a ``permission='edit'`` parameter |
| | | to the ``@view_config`` decorators for ``add_page()`` and ``edit_page()``: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/views.py |
| | |
| | | redirect back to the front page. |
| | | |
| | | Add the following import statements to the head of |
| | | ``tutorial/tutorial/views.py``: |
| | | ``tutorial/views.py``: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/views.py |
| | | :lines: 6-17 |
| | |
| | | Add the ``login.pt`` Template |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Create ``tutorial/tutorial/templates/login.pt`` with the following content: |
| | | Create ``tutorial/templates/login.pt`` with the following content: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/templates/login.pt |
| | | :language: html |
| | |
| | | Return a ``logged_in`` flag to the renderer |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Open ``tutorial/tutorial/views.py`` again. Add a ``logged_in`` parameter to |
| | | Open ``tutorial/views.py`` again. Add a ``logged_in`` parameter to |
| | | the return value of ``view_page()``, ``add_page()``, and ``edit_page()`` as |
| | | follows: |
| | | |
| | |
| | | Add a "Logout" link when logged in |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Open ``tutorial/tutorial/templates/edit.pt`` and |
| | | ``tutorial/tutorial/templates/view.pt`` and add the following code as |
| | | Open ``tutorial/templates/edit.pt`` and |
| | | ``tutorial/templates/view.pt`` and add the following code as |
| | | indicated by the highlighted lines. |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/templates/edit.pt |
| | |
| | | Reviewing our changes |
| | | --------------------- |
| | | |
| | | Our ``tutorial/tutorial/__init__.py`` will look like this when we're done: |
| | | Our ``tutorial/__init__.py`` will look like this when we're done: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/__init__.py |
| | | :linenos: |
| | |
| | | |
| | | Only the highlighted lines need to be added or edited. |
| | | |
| | | Our ``tutorial/tutorial/models.py`` will look like this when we're done: |
| | | Our ``tutorial/models.py`` will look like this when we're done: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/models.py |
| | | :linenos: |
| | |
| | | |
| | | Only the highlighted lines need to be added or edited. |
| | | |
| | | Our ``tutorial/tutorial/views.py`` will look like this when we're done: |
| | | Our ``tutorial/views.py`` will look like this when we're done: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/views.py |
| | | :linenos: |
| | |
| | | |
| | | Only the highlighted lines need to be added or edited. |
| | | |
| | | Our ``tutorial/tutorial/templates/edit.pt`` template will look like this when |
| | | Our ``tutorial/templates/edit.pt`` template will look like this when |
| | | we're done: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/templates/edit.pt |
| | |
| | | |
| | | Only the highlighted lines need to be added or edited. |
| | | |
| | | Our ``tutorial/tutorial/templates/view.pt`` template will look like this when |
| | | Our ``tutorial/templates/view.pt`` template will look like this when |
| | | we're done: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/templates/view.pt |
| | |
| | | .. _wiki_background: |
| | | |
| | | ========== |
| | | Background |
| | | ========== |
| | |
| | | .. _wiki_basic_layout: |
| | | |
| | | ============ |
| | | Basic Layout |
| | | ============ |
| | |
| | | |
| | | A directory on disk can be turned into a Python :term:`package` by containing |
| | | an ``__init__.py`` file. Even if empty, this marks a directory as a Python |
| | | package. We use ``__init__.py`` both as a marker, indicating the directory |
| | | in which it's contained is a package, and to contain application configuration |
| | | package. We use ``__init__.py`` both as a marker, indicating the directory in |
| | | which it's contained is a package, and to contain application configuration |
| | | code. |
| | | |
| | | When you run the application using the ``pserve`` command using the |
| | | ``development.ini`` generated configuration file, the application |
| | | configuration points at a Setuptools *entry point* described as |
| | | configuration points at a setuptools *entry point* described as |
| | | ``egg:tutorial``. In our application, because the application's ``setup.py`` |
| | | file says so, this entry point happens to be the ``main`` function within the |
| | | file named ``__init__.py``. Let's take a look at the code and describe what |
| | | it does: |
| | | file named ``__init__.py``. |
| | | |
| | | .. literalinclude:: src/basiclayout/tutorial/__init__.py |
| | | :linenos: |
| | | :language: py |
| | | Open ``tutorial/__init__.py``. It should already contain the following: |
| | | |
| | | .. literalinclude:: src/basiclayout/tutorial/__init__.py |
| | | :linenos: |
| | | :language: py |
| | | |
| | | #. *Lines 1-3*. Perform some dependency imports. |
| | | |
| | |
| | | |
| | | Here is the source for ``models.py``: |
| | | |
| | | .. literalinclude:: src/basiclayout/tutorial/models.py |
| | | :linenos: |
| | | :language: py |
| | | .. literalinclude:: src/basiclayout/tutorial/models.py |
| | | :linenos: |
| | | :language: python |
| | | |
| | | #. *Lines 4-5*. The ``MyModel`` :term:`resource` class is implemented here. |
| | | Instances of this class are capable of being persisted in :term:`ZODB` |
| | |
| | | |
| | | Here is the source for ``views.py``: |
| | | |
| | | .. literalinclude:: src/basiclayout/tutorial/views.py |
| | | :linenos: |
| | | :language: py |
| | | .. literalinclude:: src/basiclayout/tutorial/views.py |
| | | :linenos: |
| | | :language: python |
| | | |
| | | Let's try to understand the components in this module: |
| | | |
| | |
| | | opposed to the tutorial :term:`package` directory) looks like this: |
| | | |
| | | .. literalinclude:: src/basiclayout/development.ini |
| | | :language: ini |
| | | :language: ini |
| | | |
| | | Note the existence of a ``[app:main]`` section which specifies our WSGI |
| | | application. Our ZODB database settings are specified as the |
| | |
| | | .. _wiki_defining_the_domain_model: |
| | | |
| | | ========================= |
| | | Defining the Domain Model |
| | | ========================= |
| | | |
| | | The first change we'll make to our stock pcreate-generated application will be |
| | | to define two :term:`resource` constructors, one representing a wiki page, |
| | | The first change we'll make to our stock ``pcreate``-generated application will |
| | | be to define two :term:`resource` constructors, one representing a wiki page, |
| | | and another representing the wiki as a mapping of wiki page names to page |
| | | objects. We'll do this inside our ``models.py`` file. |
| | | |
| | |
| | | or they may live in a Python subpackage of your application package named |
| | | ``models``, but this is only by convention. |
| | | |
| | | Open ``tutorial/tutorial/models.py`` file and edit it to look like the |
| | | following: |
| | | Open ``tutorial/models.py`` file and edit it to look like the following: |
| | | |
| | | .. literalinclude:: src/models/tutorial/models.py |
| | | :linenos: |
| | |
| | | .. _wiki_defining_views: |
| | | |
| | | ============== |
| | | Defining Views |
| | | ============== |
| | |
| | | package's ``setup.py`` file by assigning this dependency to the ``requires`` |
| | | parameter in the ``setup()`` function. |
| | | |
| | | Open ``tutorial/setup.py`` and edit it to look like the following: |
| | | Open ``setup.py`` and edit it to look like the following: |
| | | |
| | | .. literalinclude:: src/views/setup.py |
| | | :linenos: |
| | |
| | | |
| | | Only the highlighted line needs to be added. |
| | | |
| | | Running ``setup.py develop`` |
| | | |
| | | Running ``pip install -e .`` |
| | | ============================ |
| | | |
| | | Since a new software dependency was added, you will need to run ``python |
| | | setup.py develop`` again inside the root of the ``tutorial`` package to obtain |
| | | and register the newly added dependency distribution. |
| | | Since a new software dependency was added, you will need to run ``pip install |
| | | -e .`` again inside the root of the ``tutorial`` package to obtain and register |
| | | the newly added dependency distribution. |
| | | |
| | | Make sure your current working directory is the root of the project (the |
| | | directory in which ``setup.py`` lives) and execute the following command. |
| | | |
| | | On UNIX: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ cd tutorial |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut> cd tutorial |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . |
| | | |
| | | Success executing this command will end with a line to the console something |
| | | like:: |
| | | like: |
| | | |
| | | Finished processing dependencies for tutorial==0.0 |
| | | .. code-block:: text |
| | | |
| | | Successfully installed docutils-0.12 tutorial-0.0 |
| | | |
| | | |
| | | Adding view functions in ``views.py`` |
| | | ===================================== |
| | | |
| | | It's time for a major change. Open ``tutorial/tutorial/views.py`` and edit it |
| | | to look like the following: |
| | | It's time for a major change. Open ``tutorial/views.py`` and edit it to look |
| | | like the following: |
| | | |
| | | .. literalinclude:: src/views/tutorial/views.py |
| | | :linenos: |
| | |
| | | The ``view.pt`` template |
| | | ------------------------ |
| | | |
| | | Create ``tutorial/tutorial/templates/view.pt`` and add the following |
| | | Create ``tutorial/templates/view.pt`` and add the following |
| | | content: |
| | | |
| | | .. literalinclude:: src/views/tutorial/templates/view.pt |
| | |
| | | The ``edit.pt`` template |
| | | ------------------------ |
| | | |
| | | Create ``tutorial/tutorial/templates/edit.pt`` and add the following |
| | | content: |
| | | Create ``tutorial/templates/edit.pt`` and add the following content: |
| | | |
| | | .. literalinclude:: src/views/tutorial/templates/edit.pt |
| | | :linenos: |
| | |
| | | See :ref:`renderer_system_values` for information about other names that |
| | | are available by default when a template is used as a renderer. |
| | | |
| | | |
| | | Static assets |
| | | ------------- |
| | | |
| | |
| | | method ``static_url``, e.g., |
| | | ``request.static_url('<package>:static/foo.css')`` within templates. |
| | | |
| | | |
| | | Viewing the application in a browser |
| | | ==================================== |
| | | |
| | |
| | | .. _wiki_design: |
| | | |
| | | ====== |
| | | Design |
| | | ====== |
| | |
| | | .. _wiki_distributing_your_application: |
| | | |
| | | ============================= |
| | | Distributing Your Application |
| | | ============================= |
| | |
| | | Once your application works properly, you can create a "tarball" from it by |
| | | using the ``setup.py sdist`` command. The following commands assume your |
| | | current working directory is the ``tutorial`` package we've created and that |
| | | the parent directory of the ``tutorial`` package is a virtualenv representing |
| | | a :app:`Pyramid` environment. |
| | | the parent directory of the ``tutorial`` package is a virtual environment |
| | | representing a :app:`Pyramid` environment. |
| | | |
| | | On UNIX: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py sdist |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut> %VENV%\Scripts\python setup.py sdist |
| | | |
| | |
| | | .. code-block:: text |
| | | |
| | | running sdist |
| | | # .. more output .. |
| | | # more output |
| | | creating dist |
| | | tar -cf dist/tutorial-0.0.tar tutorial-0.0 |
| | | gzip -f9 dist/tutorial-0.0.tar |
| | | Creating tar archive |
| | | removing 'tutorial-0.0' (and everything under it) |
| | | |
| | | Note that this command creates a tarball in the "dist" subdirectory named |
| | | ``tutorial-0.0.tar.gz``. You can send this file to your friends to show them |
| | | your cool new application. They should be able to install it by pointing the |
| | | ``easy_install`` command directly at it. Or you can upload it to `PyPI |
| | | ``pip install .`` command directly at it. Or you can upload it to `PyPI |
| | | <http://pypi.python.org>`_ and share it with the rest of the world, where it |
| | | can be downloaded via ``easy_install`` remotely like any other package people |
| | | can be downloaded via ``pip install`` remotely like any other package people |
| | | download from PyPI. |
| | |
| | | authorization |
| | | tests |
| | | distributing |
| | | |
| | |
| | | .. _wiki_installation: |
| | | |
| | | ============ |
| | | Installation |
| | | ============ |
| | | |
| | | Before you begin |
| | | ================ |
| | | ---------------- |
| | | |
| | | This tutorial assumes that you have already followed the steps in |
| | | :ref:`installing_chapter`, except **do not create a virtualenv or install |
| | | Pyramid**. Thereby you will satisfy the following requirements. |
| | | :ref:`installing_chapter`, except **do not create a virtual environment or |
| | | install Pyramid**. Thereby you will satisfy the following requirements. |
| | | |
| | | * Python interpreter is installed on your operating system |
| | | * :term:`setuptools` or :term:`distribute` is installed |
| | | * :term:`virtualenv` is installed |
| | | * A Python interpreter is installed on your operating system. |
| | | * You've satisfied the :ref:`requirements-for-installing-packages`. |
| | | |
| | | |
| | | Create directory to contain the project |
| | | --------------------------------------- |
| | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ mkdir ~/pyramidtut |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> mkdir pyramidtut |
| | | |
| | | |
| | | Create and use a virtual Python environment |
| | | ------------------------------------------- |
| | | |
| | | Next let's create a `virtualenv` workspace for our project. We will |
| | | use the `VENV` environment variable instead of the absolute path of the |
| | | virtual environment. |
| | | Next let's create a virtual environment workspace for our project. We will use |
| | | the ``VENV`` environment variable instead of the absolute path of the virtual |
| | | environment. |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ export VENV=~/pyramidtut |
| | | $ virtualenv $VENV |
| | | New python executable in /home/foo/env/bin/python |
| | | Installing setuptools.............done. |
| | | $ python3 -m venv $VENV |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> set VENV=c:\pyramidtut |
| | | |
| | | Versions of Python use different paths, so you will need to adjust the |
| | | Each version of Python uses different paths, so you will need to adjust the |
| | | path to the command for your Python version. |
| | | |
| | | Python 2.7: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> c:\Python27\Scripts\virtualenv %VENV% |
| | | |
| | | Python 3.3: |
| | | Python 3.5: |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> c:\Python33\Scripts\virtualenv %VENV% |
| | | c:\> c:\Python35\Scripts\python -m venv %VENV% |
| | | |
| | | Install Pyramid and tutorial dependencies into the virtual Python environment |
| | | ----------------------------------------------------------------------------- |
| | | |
| | | Upgrade ``pip`` and ``setuptools`` in the virtual environment |
| | | ------------------------------------------------------------- |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/easy_install docutils pyramid_tm pyramid_zodbconn \ |
| | | pyramid_debugtoolbar nose coverage |
| | | $ $VENV/bin/pip install --upgrade pip setuptools |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> %VENV%\Scripts\easy_install docutils pyramid_tm pyramid_zodbconn \ |
| | | pyramid_debugtoolbar nose coverage |
| | | c:\> %VENV%\Scripts\pip install --upgrade pip setuptools |
| | | |
| | | Change Directory to Your Virtual Python Environment |
| | | |
| | | Install Pyramid into the virtual Python environment |
| | | --------------------------------------------------- |
| | | |
| | | Change directory to the ``pyramidtut`` directory. |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pip install pyramid |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> %VENV%\Scripts\pip install pyramid |
| | | |
| | | Change directory to your virtual Python environment |
| | | --------------------------------------------------- |
| | | |
| | | Change directory to the ``pyramidtut`` directory, which is both your workspace |
| | | and your virtual environment. |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ cd pyramidtut |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> cd pyramidtut |
| | | |
| | | .. _making_a_project: |
| | | |
| | | Making a project |
| | | ================ |
| | | ---------------- |
| | | |
| | | Your next step is to create a project. For this tutorial, we will use |
| | | the :term:`scaffold` named ``zodb``, which generates an application |
| | | that uses :term:`ZODB` and :term:`traversal`. |
| | | |
| | | :app:`Pyramid` supplies a variety of scaffolds to generate sample |
| | | projects. We will use `pcreate`—a script that comes with Pyramid to |
| | | quickly and easily generate scaffolds, usually with a single command—to |
| | | create the scaffold for our project. |
| | | :app:`Pyramid` supplies a variety of scaffolds to generate sample projects. We |
| | | will use ``pcreate``, a script that comes with Pyramid, to create our project |
| | | using a scaffold. |
| | | |
| | | By passing `zodb` into the `pcreate` command, the script creates |
| | | the files needed to use ZODB. By passing in our application name |
| | | `tutorial`, the script inserts that application name into all the |
| | | required files. |
| | | By passing ``zodb`` into the ``pcreate`` command, the script creates the files |
| | | needed to use ZODB. By passing in our application name ``tutorial``, the script |
| | | inserts that application name into all the required files. |
| | | |
| | | The below instructions assume your current working directory is "pyramidtut". |
| | | |
| | | On UNIX |
| | | ------- |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pcreate -s zodb tutorial |
| | | |
| | | On Windows |
| | | ---------- |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut> %VENV%\Scripts\pcreate -s zodb tutorial |
| | | |
| | | .. note:: If you are using Windows, the ``zodb`` |
| | | scaffold may not deal gracefully with installation into a |
| | | location that contains spaces in the path. If you experience |
| | | startup problems, try putting both the virtualenv and the project |
| | | into directories that do not contain spaces in their paths. |
| | | .. note:: If you are using Windows, the ``zodb`` scaffold may not deal |
| | | gracefully with installation into a location that contains spaces in the |
| | | path. If you experience startup problems, try putting both the virtual |
| | | environment and the project into directories that do not contain spaces in |
| | | their paths. |
| | | |
| | | |
| | | .. _installing_project_in_dev_mode_zodb: |
| | | |
| | | Installing the project in development mode |
| | | ========================================== |
| | | ------------------------------------------ |
| | | |
| | | In order to do development on the project easily, you must "register" |
| | | the project as a development egg in your workspace using the |
| | | ``setup.py develop`` command. In order to do so, cd to the `tutorial` |
| | | directory you created in :ref:`making_a_project`, and run the |
| | | ``setup.py develop`` command using the virtualenv Python interpreter. |
| | | In order to do development on the project easily, you must "register" the |
| | | project as a development egg in your workspace using the ``pip install -e .`` |
| | | command. In order to do so, change directory to the ``tutorial`` directory that |
| | | you created in :ref:`making_a_project`, and run the ``pip install -e .`` |
| | | command using the virtual environment Python interpreter. |
| | | |
| | | On UNIX |
| | | ------- |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ cd tutorial |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | On Windows |
| | | ---------- |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut> cd tutorial |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . |
| | | |
| | | The console will show `setup.py` checking for packages and installing |
| | | missing packages. Success executing this command will show a line like |
| | | the following:: |
| | | The console will show ``pip`` checking for packages and installing missing |
| | | packages. Success executing this command will show a line like the following: |
| | | |
| | | Finished processing dependencies for tutorial==0.0 |
| | | .. code-block:: bash |
| | | |
| | | Successfully installed BTrees-4.2.0 Chameleon-2.24 Mako-1.0.4 \ |
| | | MarkupSafe-0.23 Pygments-2.1.3 ZConfig-3.1.0 ZEO-4.2.0b1 ZODB-4.2.0 \ |
| | | ZODB3-3.11.0 mock-2.0.0 pbr-1.8.1 persistent-4.1.1 pyramid-chameleon-0.3 \ |
| | | pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 pyramid-tm-0.12.1 \ |
| | | pyramid-zodbconn-0.7 six-1.10.0 transaction-1.4.4 tutorial waitress-0.8.10 \ |
| | | zc.lockfile-1.1.0 zdaemon-4.1.0 zodbpickle-0.6.0 zodburi-2.0 |
| | | |
| | | |
| | | .. _install-testing-requirements_zodb: |
| | | |
| | | Install testing requirements |
| | | ---------------------------- |
| | | |
| | | In order to run tests, we need to install the testing requirements. This is |
| | | done through our project's ``setup.py`` file, in the ``tests_require`` and |
| | | ``extras_require`` stanzas, and by issuing the command below for your |
| | | operating system. |
| | | |
| | | .. literalinclude:: src/installation/setup.py |
| | | :language: python |
| | | :linenos: |
| | | :lineno-start: 22 |
| | | :lines: 22-26 |
| | | |
| | | .. literalinclude:: src/installation/setup.py |
| | | :language: python |
| | | :linenos: |
| | | :lineno-start: 45 |
| | | :lines: 45-47 |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pip install -e ".[testing]" |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e ".[testing]" |
| | | |
| | | |
| | | .. _running_tests: |
| | | |
| | | Run the tests |
| | | ============= |
| | | ------------- |
| | | |
| | | After you've installed the project in development mode, you may run |
| | | the tests for the project. |
| | | After you've installed the project in development mode as well as the testing |
| | | requirements, you may run the tests for the project. |
| | | |
| | | On UNIX |
| | | ------- |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py test -q |
| | | $ $VENV/bin/py.test tutorial/tests.py -q |
| | | |
| | | On Windows |
| | | ---------- |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\py.test tutorial\tests.py -q |
| | | |
| | | For a successful test run, you should see output that ends like this:: |
| | | For a successful test run, you should see output that ends like this: |
| | | |
| | | . |
| | | ---------------------------------------------------------------------- |
| | | Ran 1 test in 0.094s |
| | | |
| | | OK |
| | | .. code-block:: bash |
| | | |
| | | . |
| | | 1 passed in 0.24 seconds |
| | | |
| | | |
| | | Expose test coverage information |
| | | ================================ |
| | | -------------------------------- |
| | | |
| | | You can run the ``nosetests`` command to see test coverage |
| | | information. This runs the tests in the same way that ``setup.py |
| | | test`` does but provides additional "coverage" information, exposing |
| | | which lines of your project are "covered" (or not covered) by the |
| | | You can run the ``py.test`` command to see test coverage information. This |
| | | runs the tests in the same way that ``py.test`` does, but provides additional |
| | | "coverage" information, exposing which lines of your project are covered by the |
| | | tests. |
| | | |
| | | We've already installed the ``pytest-cov`` package into our virtual |
| | | environment, so we can run the tests with coverage. |
| | | |
| | | On UNIX |
| | | ------- |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/nosetests --cover-package=tutorial --cover-erase --with-coverage |
| | | $ $VENV/bin/py.test --cov=tutorial --cov-report=term-missing tutorial/tests.py |
| | | |
| | | On Windows |
| | | ---------- |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\nosetests --cover-package=tutorial \ |
| | | --cover-erase --with-coverage |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ |
| | | --cov-report=term-missing tutorial\tests.py |
| | | |
| | | If successful, you will see output something like this:: |
| | | If successful, you will see output something like this: |
| | | |
| | | . |
| | | Name Stmts Miss Cover Missing |
| | | -------------------------------------------------- |
| | | tutorial.py 12 7 42% 7-8, 14-18 |
| | | tutorial/models.py 10 6 40% 9-14 |
| | | tutorial/views.py 4 0 100% |
| | | -------------------------------------------------- |
| | | TOTAL 26 13 50% |
| | | ---------------------------------------------------------------------- |
| | | Ran 1 test in 0.392s |
| | | .. code-block:: bash |
| | | |
| | | OK |
| | | ======================== test session starts ======================== |
| | | platform Python 3.5.1, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 |
| | | rootdir: /Users/stevepiercy/projects/pyramidtut/tutorial, inifile: |
| | | plugins: cov-2.2.1 |
| | | collected 1 items |
| | | |
| | | Looks like our package doesn't quite have 100% test coverage. |
| | | tutorial/tests.py . |
| | | ------------------ coverage: platform Python 3.5.1 ------------------ |
| | | Name Stmts Miss Cover Missing |
| | | ---------------------------------------------------- |
| | | tutorial/__init__.py 12 7 42% 7-8, 14-18 |
| | | tutorial/models.py 10 6 40% 9-14 |
| | | tutorial/tests.py 12 0 100% |
| | | tutorial/views.py 4 0 100% |
| | | ---------------------------------------------------- |
| | | TOTAL 38 13 66% |
| | | |
| | | ===================== 1 passed in 0.31 seconds ====================== |
| | | |
| | | Our package doesn't quite have 100% test coverage. |
| | | |
| | | |
| | | .. _wiki-start-the-application: |
| | | |
| | | Start the application |
| | | ===================== |
| | | --------------------- |
| | | |
| | | Start the application. |
| | | |
| | | On UNIX |
| | | ------- |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pserve development.ini --reload |
| | | |
| | | On Windows |
| | | ---------- |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: text |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload |
| | | |
| | |
| | | Your OS firewall, if any, may pop up a dialog asking for authorization |
| | | to allow python to accept incoming network connections. |
| | | |
| | | If successful, you will see something like this on your console:: |
| | | If successful, you will see something like this on your console: |
| | | |
| | | .. code-block:: text |
| | | |
| | | Starting subprocess with file monitor |
| | | Starting server in PID 95736. |
| | | serving on http://0.0.0.0:6543 |
| | | serving on http://127.0.0.1:6543 |
| | | |
| | | This means the server is ready to accept requests. |
| | | |
| | | Visit the application in a browser |
| | | ================================== |
| | | |
| | | In a browser, visit `http://localhost:6543/ <http://localhost:6543>`_. You |
| | | will see the generated application's default page. |
| | | Visit the application in a browser |
| | | ---------------------------------- |
| | | |
| | | In a browser, visit http://localhost:6543/. You will see the generated |
| | | application's default page. |
| | | |
| | | One thing you'll notice is the "debug toolbar" icon on right hand side of the |
| | | page. You can read more about the purpose of the icon at |
| | | :ref:`debug_toolbar`. It allows you to get information about your |
| | | application while you develop. |
| | | |
| | | |
| | | Decisions the ``zodb`` scaffold has made for you |
| | | ================================================ |
| | | ------------------------------------------------ |
| | | |
| | | Creating a project using the ``zodb`` scaffold makes the following |
| | | assumptions: |
| | | |
| | | - you are willing to use :term:`ZODB` as persistent storage |
| | | - You are willing to use :term:`ZODB` as persistent storage. |
| | | |
| | | - you are willing to use :term:`traversal` to map URLs to code |
| | | - You are willing to use :term:`traversal` to map URLs to code. |
| | | |
| | | .. note:: |
| | | |
| | |
| | | 0.0 |
| | | --- |
| | | |
| | | - Initial version |
| | | |
| | | - Initial version |
| | |
| | | tutorial README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | [server:main] |
| | | use = egg:waitress#main |
| | | host = 0.0.0.0 |
| | | host = 127.0.0.1 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | 'docutils', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="tutorial", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = tutorial:main |
| | |
| | | self.data = data |
| | | |
| | | def appmaker(zodb_root): |
| | | if not 'app_root' in zodb_root: |
| | | if 'app_root' not in zodb_root: |
| | | app_root = Wiki() |
| | | frontpage = Page('This is the front page') |
| | | app_root['FrontPage'] = frontpage |
| | |
| | | <div class="col-md-10"> |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | |
| | | |
| | | from pyramid import testing |
| | | |
| | | class PageModelTests(unittest.TestCase): |
| | | |
| | | def _getTargetClass(self): |
| | | from .models import Page |
| | | return Page |
| | | class ViewTests(unittest.TestCase): |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
| | | |
| | | def _makeOne(self, data=u'some data'): |
| | | return self._getTargetClass()(data=data) |
| | | def tearDown(self): |
| | | testing.tearDown() |
| | | |
| | | def test_constructor(self): |
| | | instance = self._makeOne() |
| | | self.assertEqual(instance.data, u'some data') |
| | | |
| | | class WikiModelTests(unittest.TestCase): |
| | | |
| | | def _getTargetClass(self): |
| | | from .models import Wiki |
| | | return Wiki |
| | | |
| | | def _makeOne(self): |
| | | return self._getTargetClass()() |
| | | |
| | | def test_it(self): |
| | | wiki = self._makeOne() |
| | | self.assertEqual(wiki.__parent__, None) |
| | | self.assertEqual(wiki.__name__, None) |
| | | |
| | | class AppmakerTests(unittest.TestCase): |
| | | |
| | | def _callFUT(self, zodb_root): |
| | | from .models import appmaker |
| | | return appmaker(zodb_root) |
| | | |
| | | def test_it(self): |
| | | root = {} |
| | | self._callFUT(root) |
| | | self.assertEqual(root['app_root']['FrontPage'].data, |
| | | 'This is the front page') |
| | | |
| | | class ViewWikiTests(unittest.TestCase): |
| | | def test_it(self): |
| | | from .views import view_wiki |
| | | context = testing.DummyResource() |
| | | def test_my_view(self): |
| | | from .views import my_view |
| | | request = testing.DummyRequest() |
| | | response = view_wiki(context, request) |
| | | self.assertEqual(response.location, 'http://example.com/FrontPage') |
| | | |
| | | class ViewPageTests(unittest.TestCase): |
| | | def _callFUT(self, context, request): |
| | | from .views import view_page |
| | | return view_page(context, request) |
| | | |
| | | def test_it(self): |
| | | wiki = testing.DummyResource() |
| | | wiki['IDoExist'] = testing.DummyResource() |
| | | context = testing.DummyResource(data='Hello CruelWorld IDoExist') |
| | | context.__parent__ = wiki |
| | | context.__name__ = 'thepage' |
| | | request = testing.DummyRequest() |
| | | info = self._callFUT(context, request) |
| | | self.assertEqual(info['page'], context) |
| | | self.assertEqual( |
| | | info['content'], |
| | | '<div class="document">\n' |
| | | '<p>Hello <a href="http://example.com/add_page/CruelWorld">' |
| | | 'CruelWorld</a> ' |
| | | '<a href="http://example.com/IDoExist/">' |
| | | 'IDoExist</a>' |
| | | '</p>\n</div>\n') |
| | | self.assertEqual(info['edit_url'], |
| | | 'http://example.com/thepage/edit_page') |
| | | |
| | | |
| | | class AddPageTests(unittest.TestCase): |
| | | def _callFUT(self, context, request): |
| | | from .views import add_page |
| | | return add_page(context, request) |
| | | |
| | | def test_it_notsubmitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest() |
| | | request.subpath = ['AnotherPage'] |
| | | info = self._callFUT(context, request) |
| | | self.assertEqual(info['page'].data,'') |
| | | self.assertEqual( |
| | | info['save_url'], |
| | | request.resource_url(context, 'add_page', 'AnotherPage')) |
| | | |
| | | def test_it_submitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest({'form.submitted':True, |
| | | 'body':'Hello yo!'}) |
| | | request.subpath = ['AnotherPage'] |
| | | self._callFUT(context, request) |
| | | page = context['AnotherPage'] |
| | | self.assertEqual(page.data, 'Hello yo!') |
| | | self.assertEqual(page.__name__, 'AnotherPage') |
| | | self.assertEqual(page.__parent__, context) |
| | | |
| | | class EditPageTests(unittest.TestCase): |
| | | def _callFUT(self, context, request): |
| | | from .views import edit_page |
| | | return edit_page(context, request) |
| | | |
| | | def test_it_notsubmitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest() |
| | | info = self._callFUT(context, request) |
| | | self.assertEqual(info['page'], context) |
| | | self.assertEqual(info['save_url'], |
| | | request.resource_url(context, 'edit_page')) |
| | | |
| | | def test_it_submitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest({'form.submitted':True, |
| | | 'body':'Hello yo!'}) |
| | | response = self._callFUT(context, request) |
| | | self.assertEqual(response.location, 'http://example.com/') |
| | | self.assertEqual(context.data, 'Hello yo!') |
| | | info = my_view(request) |
| | | self.assertEqual(info['project'], 'tutorial') |
| | |
| | | view_url = request.resource_url(page) |
| | | return '<a href="%s">%s</a>' % (view_url, word) |
| | | else: |
| | | add_url = request.application_url + '/add_page/' + word |
| | | add_url = request.application_url + '/add_page/' + word |
| | | return '<a href="%s">%s</a>' % (add_url, word) |
| | | |
| | | content = publish_parts(context.data, writer_name='html')['html_body'] |
| | | content = wikiwords.sub(check, content) |
| | | edit_url = request.resource_url(context, 'edit_page') |
| | | |
| | | return dict(page = context, content = content, edit_url = edit_url, |
| | | logged_in = request.authenticated_userid) |
| | | return dict(page=context, content=content, edit_url=edit_url, |
| | | logged_in=request.authenticated_userid) |
| | | |
| | | @view_config(name='add_page', context='.models.Wiki', |
| | | renderer='templates/edit.pt', |
| | |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | context[pagename] = page |
| | | return HTTPFound(location = request.resource_url(page)) |
| | | return HTTPFound(location=request.resource_url(page)) |
| | | save_url = request.resource_url(context, 'add_page', pagename) |
| | | page = Page('') |
| | | page.__name__ = pagename |
| | |
| | | def edit_page(context, request): |
| | | if 'form.submitted' in request.params: |
| | | context.data = request.params['body'] |
| | | return HTTPFound(location = request.resource_url(context)) |
| | | return HTTPFound(location=request.resource_url(context)) |
| | | |
| | | return dict(page=context, |
| | | save_url=request.resource_url(context, 'edit_page'), |
| | |
| | | login_url = request.resource_url(request.context, 'login') |
| | | referrer = request.url |
| | | if referrer == login_url: |
| | | referrer = '/' # never use the login form itself as came_from |
| | | referrer = '/' # never use the login form itself as came_from |
| | | came_from = request.params.get('came_from', referrer) |
| | | message = '' |
| | | login = '' |
| | |
| | | password = request.params['password'] |
| | | if USERS.get(login) == password: |
| | | headers = remember(request, login) |
| | | return HTTPFound(location = came_from, |
| | | headers = headers) |
| | | return HTTPFound(location=came_from, |
| | | headers=headers) |
| | | message = 'Failed login' |
| | | |
| | | return dict( |
| | | message = message, |
| | | url = request.application_url + '/login', |
| | | came_from = came_from, |
| | | login = login, |
| | | password = password, |
| | | ) |
| | | message=message, |
| | | url=request.application_url + '/login', |
| | | came_from=came_from, |
| | | login=login, |
| | | password=password, |
| | | ) |
| | | |
| | | |
| | | @view_config(context='.models.Wiki', name='logout') |
| | | def logout(request): |
| | | headers = forget(request) |
| | | return HTTPFound(location = request.resource_url(request.context), |
| | | headers = headers) |
| | | return HTTPFound(location=request.resource_url(request.context), |
| | | headers=headers) |
| | |
| | | tutorial README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | [server:main] |
| | | use = egg:waitress#main |
| | | host = 0.0.0.0 |
| | | host = 127.0.0.1 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | 'waitress', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="tutorial", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = tutorial:main |
| | |
| | | |
| | | |
| | | def appmaker(zodb_root): |
| | | if not 'app_root' in zodb_root: |
| | | if 'app_root' not in zodb_root: |
| | | app_root = MyModel() |
| | | zodb_root['app_root'] = app_root |
| | | import transaction |
| | |
| | | <div class="col-md-10"> |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | |
| | | |
| | | from pyramid import testing |
| | | |
| | | |
| | | class ViewTests(unittest.TestCase): |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
New file |
| | |
| | | 0.0 |
| | | --- |
| | | |
| | | - Initial version |
New file |
| | |
| | | include *.txt *.ini *.cfg *.rst |
| | | recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml |
New file |
| | |
| | | tutorial README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
New file |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | | use = egg:tutorial |
| | | |
| | | 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 |
| | | pyramid_zodbconn |
| | | pyramid_tm |
| | | |
| | | tm.attempts = 3 |
| | | zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 |
| | | |
| | | # 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 |
| | | host = 127.0.0.1 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | | keys = root, tutorial |
| | | |
| | | [handlers] |
| | | keys = console |
| | | |
| | | [formatters] |
| | | keys = generic |
| | | |
| | | [logger_root] |
| | | level = INFO |
| | | handlers = console |
| | | |
| | | [logger_tutorial] |
| | | level = DEBUG |
| | | handlers = |
| | | qualname = tutorial |
| | | |
| | | [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 |
New file |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | | use = egg:tutorial |
| | | |
| | | pyramid.reload_templates = false |
| | | pyramid.debug_authorization = false |
| | | pyramid.debug_notfound = false |
| | | pyramid.debug_routematch = false |
| | | pyramid.default_locale_name = en |
| | | pyramid.includes = |
| | | pyramid_tm |
| | | pyramid_zodbconn |
| | | |
| | | tm.attempts = 3 |
| | | zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 |
| | | |
| | | ### |
| | | # wsgi server configuration |
| | | ### |
| | | |
| | | [server:main] |
| | | use = egg:waitress#main |
| | | host = 0.0.0.0 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | | keys = root, tutorial |
| | | |
| | | [handlers] |
| | | keys = console |
| | | |
| | | [formatters] |
| | | keys = generic |
| | | |
| | | [logger_root] |
| | | level = WARN |
| | | handlers = console |
| | | |
| | | [logger_tutorial] |
| | | level = WARN |
| | | handlers = |
| | | qualname = tutorial |
| | | |
| | | [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 |
New file |
| | |
| | | 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_chameleon', |
| | | 'pyramid_debugtoolbar', |
| | | 'pyramid_tm', |
| | | 'pyramid_zodbconn', |
| | | 'transaction', |
| | | 'ZODB3', |
| | | 'waitress', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | 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 pylons pyramid', |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = tutorial:main |
| | | """, |
| | | ) |
New file |
| | |
| | | from pyramid.config import Configurator |
| | | from pyramid_zodbconn import get_connection |
| | | from .models import appmaker |
| | | |
| | | |
| | | def root_factory(request): |
| | | conn = get_connection(request) |
| | | return appmaker(conn.root()) |
| | | |
| | | |
| | | def main(global_config, **settings): |
| | | """ This function returns a Pyramid WSGI application. |
| | | """ |
| | | config = Configurator(root_factory=root_factory, settings=settings) |
| | | config.include('pyramid_chameleon') |
| | | config.add_static_view('static', 'static', cache_max_age=3600) |
| | | config.scan() |
| | | return config.make_wsgi_app() |
New file |
| | |
| | | from persistent.mapping import PersistentMapping |
| | | |
| | | |
| | | class MyModel(PersistentMapping): |
| | | __parent__ = __name__ = None |
| | | |
| | | |
| | | def appmaker(zodb_root): |
| | | if 'app_root' not in zodb_root: |
| | | app_root = MyModel() |
| | | zodb_root['app_root'] = app_root |
| | | import transaction |
| | | transaction.commit() |
| | | return zodb_root['app_root'] |
New file |
| | |
| | | @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; |
| | | } |
| | | } |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="${request.locale_name}"> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | | <meta name="description" content="pyramid web application"> |
| | | <meta name="author" content="Pylons Project"> |
| | | <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> |
| | | |
| | | <title>ZODB Scaffold for The Pyramid Web Framework</title> |
| | | |
| | | <!-- Bootstrap core CSS --> |
| | | <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> |
| | | |
| | | <!-- Custom styles for this scaffold --> |
| | | <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> |
| | | |
| | | <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> |
| | | <!--[if lt IE 9]> |
| | | <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> |
| | | <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> |
| | | <![endif]--> |
| | | </head> |
| | | |
| | | <body> |
| | | |
| | | <div class="starter-template"> |
| | | <div class="container"> |
| | | <div class="row"> |
| | | <div class="col-md-2"> |
| | | <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> |
| | | </div> |
| | | <div class="col-md-10"> |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="copyright"> |
| | | Copyright © Pylons Project |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | |
| | | <!-- Bootstrap core JavaScript |
| | | ================================================== --> |
| | | <!-- Placed at the end of the document so the pages load faster --> |
| | | <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> |
| | | <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> |
| | | </body> |
| | | </html> |
New file |
| | |
| | | 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'], 'tutorial') |
New file |
| | |
| | | from pyramid.view import view_config |
| | | from .models import MyModel |
| | | |
| | | |
| | | @view_config(context=MyModel, renderer='templates/mytemplate.pt') |
| | | def my_view(request): |
| | | return {'project': 'tutorial'} |
| | |
| | | 0.0 |
| | | --- |
| | | |
| | | - Initial version |
| | | - Initial version |
| | |
| | | tutorial README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | [server:main] |
| | | use = egg:waitress#main |
| | | host = 0.0.0.0 |
| | | host = 127.0.0.1 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | 'waitress', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="tutorial", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = tutorial:main |
| | |
| | | self.data = data |
| | | |
| | | def appmaker(zodb_root): |
| | | if not 'app_root' in zodb_root: |
| | | if 'app_root' not in zodb_root: |
| | | app_root = Wiki() |
| | | frontpage = Page('This is the front page') |
| | | app_root['FrontPage'] = frontpage |
| | |
| | | <div class="col-md-10"> |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | |
| | | |
| | | from pyramid import testing |
| | | |
| | | class PageModelTests(unittest.TestCase): |
| | | |
| | | def _getTargetClass(self): |
| | | from .models import Page |
| | | return Page |
| | | |
| | | def _makeOne(self, data=u'some data'): |
| | | return self._getTargetClass()(data=data) |
| | | |
| | | def test_constructor(self): |
| | | instance = self._makeOne() |
| | | self.assertEqual(instance.data, u'some data') |
| | | |
| | | class WikiModelTests(unittest.TestCase): |
| | | |
| | | def _getTargetClass(self): |
| | | from .models import Wiki |
| | | return Wiki |
| | | |
| | | def _makeOne(self): |
| | | return self._getTargetClass()() |
| | | |
| | | def test_it(self): |
| | | wiki = self._makeOne() |
| | | self.assertEqual(wiki.__parent__, None) |
| | | self.assertEqual(wiki.__name__, None) |
| | | |
| | | class AppmakerTests(unittest.TestCase): |
| | | |
| | | def _callFUT(self, zodb_root): |
| | | from .models import appmaker |
| | | return appmaker(zodb_root) |
| | | |
| | | def test_no_app_root(self): |
| | | root = {} |
| | | self._callFUT(root) |
| | | self.assertEqual(root['app_root']['FrontPage'].data, |
| | | 'This is the front page') |
| | | |
| | | def test_w_app_root(self): |
| | | app_root = object() |
| | | root = {'app_root': app_root} |
| | | self._callFUT(root) |
| | | self.assertTrue(root['app_root'] is app_root) |
| | | |
| | | class ViewTests(unittest.TestCase): |
| | | def setUp(self): |
| | |
| | | 0.0 |
| | | --- |
| | | |
| | | - Initial version |
| | | |
| | | - Initial version |
| | |
| | | tutorial README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | [server:main] |
| | | use = egg:waitress#main |
| | | host = 0.0.0.0 |
| | | host = 127.0.0.1 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | 'ZODB3', |
| | | 'waitress', |
| | | 'docutils', |
| | | 'WebTest', # add this |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="tutorial", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = tutorial:main |
| | |
| | | 'sosecret', callback=groupfinder, hashalg='sha512') |
| | | authz_policy = ACLAuthorizationPolicy() |
| | | config = Configurator(root_factory=root_factory, settings=settings) |
| | | config.include('pyramid_chameleon') |
| | | config.set_authentication_policy(authn_policy) |
| | | config.set_authorization_policy(authz_policy) |
| | | config.include('pyramid_chameleon') |
| | | config.add_static_view('static', 'static', cache_max_age=3600) |
| | | config.scan() |
| | | return config.make_wsgi_app() |
| | |
| | | self.data = data |
| | | |
| | | def appmaker(zodb_root): |
| | | if not 'app_root' in zodb_root: |
| | | if 'app_root' not in zodb_root: |
| | | app_root = Wiki() |
| | | frontpage = Page('This is the front page') |
| | | app_root['FrontPage'] = frontpage |
| | |
| | | <div class="col-md-10"> |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | |
| | | res = self.testapp.get('/SomePage', status=404) |
| | | self.assertTrue(b'Not Found' in res.body) |
| | | |
| | | def test_referrer_is_login(self): |
| | | res = self.testapp.get('/login', status=200) |
| | | self.assertTrue(b'name="came_from" value="/"' in res.body) |
| | | |
| | | def test_successful_log_in(self): |
| | | res = self.testapp.get( self.viewer_login, status=302) |
| | | self.assertEqual(res.location, 'http://localhost/FrontPage') |
| | |
| | | view_url = request.resource_url(page) |
| | | return '<a href="%s">%s</a>' % (view_url, word) |
| | | else: |
| | | add_url = request.application_url + '/add_page/' + word |
| | | add_url = request.application_url + '/add_page/' + word |
| | | return '<a href="%s">%s</a>' % (add_url, word) |
| | | |
| | | content = publish_parts(context.data, writer_name='html')['html_body'] |
| | | content = wikiwords.sub(check, content) |
| | | edit_url = request.resource_url(context, 'edit_page') |
| | | |
| | | return dict(page = context, content = content, edit_url = edit_url, |
| | | logged_in = request.authenticated_userid) |
| | | return dict(page=context, content=content, edit_url=edit_url, |
| | | logged_in=request.authenticated_userid) |
| | | |
| | | @view_config(name='add_page', context='.models.Wiki', |
| | | renderer='templates/edit.pt', |
| | |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | context[pagename] = page |
| | | return HTTPFound(location = request.resource_url(page)) |
| | | return HTTPFound(location=request.resource_url(page)) |
| | | save_url = request.resource_url(context, 'add_page', pagename) |
| | | page = Page('') |
| | | page.__name__ = pagename |
| | |
| | | def edit_page(context, request): |
| | | if 'form.submitted' in request.params: |
| | | context.data = request.params['body'] |
| | | return HTTPFound(location = request.resource_url(context)) |
| | | return HTTPFound(location=request.resource_url(context)) |
| | | |
| | | return dict(page=context, |
| | | save_url=request.resource_url(context, 'edit_page'), |
| | |
| | | login_url = request.resource_url(request.context, 'login') |
| | | referrer = request.url |
| | | if referrer == login_url: |
| | | referrer = '/' # never use the login form itself as came_from |
| | | referrer = '/' # never use the login form itself as came_from |
| | | came_from = request.params.get('came_from', referrer) |
| | | message = '' |
| | | login = '' |
| | |
| | | password = request.params['password'] |
| | | if USERS.get(login) == password: |
| | | headers = remember(request, login) |
| | | return HTTPFound(location = came_from, |
| | | headers = headers) |
| | | return HTTPFound(location=came_from, |
| | | headers=headers) |
| | | message = 'Failed login' |
| | | |
| | | return dict( |
| | | message = message, |
| | | url = request.application_url + '/login', |
| | | came_from = came_from, |
| | | login = login, |
| | | password = password, |
| | | ) |
| | | message=message, |
| | | url=request.application_url + '/login', |
| | | came_from=came_from, |
| | | login=login, |
| | | password=password, |
| | | ) |
| | | |
| | | |
| | | @view_config(context='.models.Wiki', name='logout') |
| | | def logout(request): |
| | | headers = forget(request) |
| | | return HTTPFound(location = request.resource_url(request.context), |
| | | headers = headers) |
| | | return HTTPFound(location=request.resource_url(request.context), |
| | | headers=headers) |
| | |
| | | 0.1 |
| | | 0.0 |
| | | --- |
| | | |
| | | Initial version |
| | | - Initial version |
| | |
| | | tutorial README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | [server:main] |
| | | use = egg:waitress#main |
| | | host = 0.0.0.0 |
| | | host = 127.0.0.1 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | formatter = generic |
| | | |
| | | [formatter_generic] |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
| | | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s |
| | |
| | | 'docutils', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="tutorial", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = tutorial:main |
| | |
| | | self.data = data |
| | | |
| | | def appmaker(zodb_root): |
| | | if not 'app_root' in zodb_root: |
| | | if 'app_root' not in zodb_root: |
| | | app_root = Wiki() |
| | | frontpage = Page('This is the front page') |
| | | app_root['FrontPage'] = frontpage |
| | |
| | | <div class="col-md-10"> |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | |
| | | |
| | | from pyramid import testing |
| | | |
| | | class PageModelTests(unittest.TestCase): |
| | | |
| | | def _getTargetClass(self): |
| | | from .models import Page |
| | | return Page |
| | | class ViewTests(unittest.TestCase): |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
| | | |
| | | def _makeOne(self, data=u'some data'): |
| | | return self._getTargetClass()(data=data) |
| | | def tearDown(self): |
| | | testing.tearDown() |
| | | |
| | | def test_constructor(self): |
| | | instance = self._makeOne() |
| | | self.assertEqual(instance.data, u'some data') |
| | | |
| | | class WikiModelTests(unittest.TestCase): |
| | | |
| | | def _getTargetClass(self): |
| | | from .models import Wiki |
| | | return Wiki |
| | | |
| | | def _makeOne(self): |
| | | return self._getTargetClass()() |
| | | |
| | | def test_it(self): |
| | | wiki = self._makeOne() |
| | | self.assertEqual(wiki.__parent__, None) |
| | | self.assertEqual(wiki.__name__, None) |
| | | |
| | | class AppmakerTests(unittest.TestCase): |
| | | |
| | | def _callFUT(self, zodb_root): |
| | | from .models import appmaker |
| | | return appmaker(zodb_root) |
| | | |
| | | def test_it(self): |
| | | root = {} |
| | | self._callFUT(root) |
| | | self.assertEqual(root['app_root']['FrontPage'].data, |
| | | 'This is the front page') |
| | | |
| | | class ViewWikiTests(unittest.TestCase): |
| | | def test_it(self): |
| | | from .views import view_wiki |
| | | context = testing.DummyResource() |
| | | def test_my_view(self): |
| | | from .views import my_view |
| | | request = testing.DummyRequest() |
| | | response = view_wiki(context, request) |
| | | self.assertEqual(response.location, 'http://example.com/FrontPage') |
| | | |
| | | class ViewPageTests(unittest.TestCase): |
| | | def _callFUT(self, context, request): |
| | | from .views import view_page |
| | | return view_page(context, request) |
| | | |
| | | def test_it(self): |
| | | wiki = testing.DummyResource() |
| | | wiki['IDoExist'] = testing.DummyResource() |
| | | context = testing.DummyResource(data='Hello CruelWorld IDoExist') |
| | | context.__parent__ = wiki |
| | | context.__name__ = 'thepage' |
| | | request = testing.DummyRequest() |
| | | info = self._callFUT(context, request) |
| | | self.assertEqual(info['page'], context) |
| | | self.assertEqual( |
| | | info['content'], |
| | | '<div class="document">\n' |
| | | '<p>Hello <a href="http://example.com/add_page/CruelWorld">' |
| | | 'CruelWorld</a> ' |
| | | '<a href="http://example.com/IDoExist/">' |
| | | 'IDoExist</a>' |
| | | '</p>\n</div>\n') |
| | | self.assertEqual(info['edit_url'], |
| | | 'http://example.com/thepage/edit_page') |
| | | |
| | | |
| | | class AddPageTests(unittest.TestCase): |
| | | def _callFUT(self, context, request): |
| | | from .views import add_page |
| | | return add_page(context, request) |
| | | |
| | | def test_it_notsubmitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest() |
| | | request.subpath = ['AnotherPage'] |
| | | info = self._callFUT(context, request) |
| | | self.assertEqual(info['page'].data,'') |
| | | self.assertEqual( |
| | | info['save_url'], |
| | | request.resource_url(context, 'add_page', 'AnotherPage')) |
| | | |
| | | def test_it_submitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest({'form.submitted':True, |
| | | 'body':'Hello yo!'}) |
| | | request.subpath = ['AnotherPage'] |
| | | self._callFUT(context, request) |
| | | page = context['AnotherPage'] |
| | | self.assertEqual(page.data, 'Hello yo!') |
| | | self.assertEqual(page.__name__, 'AnotherPage') |
| | | self.assertEqual(page.__parent__, context) |
| | | |
| | | class EditPageTests(unittest.TestCase): |
| | | def _callFUT(self, context, request): |
| | | from .views import edit_page |
| | | return edit_page(context, request) |
| | | |
| | | def test_it_notsubmitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest() |
| | | info = self._callFUT(context, request) |
| | | self.assertEqual(info['page'], context) |
| | | self.assertEqual(info['save_url'], |
| | | request.resource_url(context, 'edit_page')) |
| | | |
| | | def test_it_submitted(self): |
| | | context = testing.DummyResource() |
| | | request = testing.DummyRequest({'form.submitted':True, |
| | | 'body':'Hello yo!'}) |
| | | response = self._callFUT(context, request) |
| | | self.assertEqual(response.location, 'http://example.com/') |
| | | self.assertEqual(context.data, 'Hello yo!') |
| | | |
| | | |
| | | |
| | | info = my_view(request) |
| | | self.assertEqual(info['project'], 'tutorial') |
| | |
| | | .. _wiki_adding_tests: |
| | | |
| | | ============ |
| | | Adding Tests |
| | | ============ |
| | |
| | | Running the tests |
| | | ================= |
| | | |
| | | We can run these tests by using ``setup.py test`` in the same way we did in |
| | | :ref:`running_tests`. However, first we must edit our ``setup.py`` to |
| | | include a dependency on WebTest, which we've used in our ``tests.py``. |
| | | Change the ``requires`` list in ``setup.py`` to include ``WebTest``. |
| | | |
| | | .. literalinclude:: src/tests/setup.py |
| | | :linenos: |
| | | :language: python |
| | | :lines: 11-22 |
| | | :emphasize-lines: 11 |
| | | |
| | | After we've added a dependency on WebTest in ``setup.py``, we need to run |
| | | ``setup.py develop`` to get WebTest installed into our virtualenv. Assuming |
| | | our shell's current working directory is the "tutorial" distribution |
| | | directory: |
| | | We can run these tests by using ``py.test`` similarly to how we did in |
| | | :ref:`running_tests`. Our testing dependencies have already been satisfied, |
| | | courtesy of the scaffold, so we can jump right to running tests. |
| | | |
| | | On UNIX: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/py.test tutorial/tests.py -q |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: text |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop |
| | | |
| | | Once that command has completed successfully, we can run the tests |
| | | themselves: |
| | | |
| | | On UNIX: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ $VENV/bin/python setup.py test -q |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: text |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\py.test tutorial/tests.py -q |
| | | |
| | | The expected result should look like the following: |
| | | |
| | | .. code-block:: text |
| | | |
| | | ......... |
| | | ---------------------------------------------------------------------- |
| | | Ran 23 tests in 1.653s |
| | | |
| | | OK |
| | | ........................ |
| | | 24 passed in 2.46 seconds |
| | |
| | | Adding authorization |
| | | ==================== |
| | | |
| | | In the last chapter we built :term:`authentication` into our wiki2. We also |
| | | In the last chapter we built :term:`authentication` into our wiki. We also |
| | | went one step further and used the ``request.user`` object to perform some |
| | | explicit :term:`authorization` checks. This is fine for a lot of applications, |
| | | but :app:`Pyramid` provides some facilities for cleaning this up and decoupling |
| | |
| | | .. _wiki2_background: |
| | | |
| | | ========== |
| | | Background |
| | | ========== |
| | |
| | | .. _wiki2_basic_layout: |
| | | |
| | | ============ |
| | | Basic Layout |
| | | ============ |
| | |
| | | .. _wiki2_defining_the_domain_model: |
| | | |
| | | ========================= |
| | | Defining the Domain Model |
| | | ========================= |
| | |
| | | Only the highlighted line needs to be added. |
| | | |
| | | |
| | | Running ``setup.py develop`` |
| | | Running ``pip install -e .`` |
| | | ============================ |
| | | |
| | | Since a new software dependency was added, you will need to run ``python |
| | | setup.py develop`` again inside the root of the ``tutorial`` package to obtain |
| | | and register the newly added dependency distribution. |
| | | Since a new software dependency was added, you will need to run ``pip install |
| | | -e .`` again inside the root of the ``tutorial`` package to obtain and register |
| | | the newly added dependency distribution. |
| | | |
| | | Make sure your current working directory is the root of the project (the |
| | | directory in which ``setup.py`` lives) and execute the following command. |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd tutorial |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut> cd tutorial |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . |
| | | |
| | | Success executing this command will end with a line to the console something |
| | | like this:: |
| | | |
| | | Finished processing dependencies for tutorial==0.0 |
| | | Successfully installed bcrypt-2.0.0 cffi-1.5.2 pycparser-2.14 tutorial-0.0 |
| | | |
| | | |
| | | Remove ``mymodel.py`` |
| | |
| | | :language: py |
| | | :emphasize-lines: 8,9 |
| | | |
| | | Here we align our imports with the names of the models, ``User`` and ``Page``. |
| | | Here we align our imports with the names of the models, ``Page`` and ``User``. |
| | | |
| | | |
| | | Edit ``scripts/initializedb.py`` |
| | |
| | | we've made to both the models.py file and to the initializedb.py file. See |
| | | :ref:`initialize_db_wiki2` for instructions. |
| | | |
| | | Success will look something like this:: |
| | | Success will look something like this: |
| | | |
| | | 2016-02-12 01:06:35,855 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-02-12 01:06:35,855 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-02-12 01:06:35,855 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-02-12 01:06:35,855 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-02-12 01:06:35,856 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages") |
| | | 2016-02-12 01:06:35,856 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-02-12 01:06:35,856 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("users") |
| | | 2016-02-12 01:06:35,856 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-02-12 01:06:35,857 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] |
| | | CREATE TABLE users ( |
| | | id INTEGER NOT NULL, |
| | | name TEXT NOT NULL, |
| | | role TEXT NOT NULL, |
| | | password_hash TEXT, |
| | | CONSTRAINT pk_users PRIMARY KEY (id), |
| | | CONSTRAINT uq_users_name UNIQUE (name) |
| | | ) |
| | | .. code-block:: bash |
| | | |
| | | 2016-04-09 02:49:51,711 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-04-09 02:49:51,711 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-04-09 02:49:51,712 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-04-09 02:49:51,712 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-04-09 02:49:51,713 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages") |
| | | 2016-04-09 02:49:51,714 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-04-09 02:49:51,714 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("users") |
| | | 2016-04-09 02:49:51,714 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-04-09 02:49:51,715 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] |
| | | CREATE TABLE users ( |
| | | id INTEGER NOT NULL, |
| | | name TEXT NOT NULL, |
| | | role TEXT NOT NULL, |
| | | password_hash TEXT, |
| | | CONSTRAINT pk_users PRIMARY KEY (id), |
| | | CONSTRAINT uq_users_name UNIQUE (name) |
| | | ) |
| | | |
| | | |
| | | 2016-02-12 01:06:35,857 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-02-12 01:06:35,858 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-02-12 01:06:35,858 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] |
| | | CREATE TABLE pages ( |
| | | id INTEGER NOT NULL, |
| | | name TEXT NOT NULL, |
| | | data INTEGER NOT NULL, |
| | | creator_id INTEGER NOT NULL, |
| | | CONSTRAINT pk_pages PRIMARY KEY (id), |
| | | CONSTRAINT uq_pages_name UNIQUE (name), |
| | | CONSTRAINT fk_pages_creator_id_users FOREIGN KEY(creator_id) REFERENCES users (id) |
| | | ) |
| | | 2016-04-09 02:49:51,715 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-04-09 02:49:51,716 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-04-09 02:49:51,716 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] |
| | | CREATE TABLE pages ( |
| | | id INTEGER NOT NULL, |
| | | name TEXT NOT NULL, |
| | | data INTEGER NOT NULL, |
| | | creator_id INTEGER NOT NULL, |
| | | CONSTRAINT pk_pages PRIMARY KEY (id), |
| | | CONSTRAINT uq_pages_name UNIQUE (name), |
| | | CONSTRAINT fk_pages_creator_id_users FOREIGN KEY(creator_id) REFERENCES users (id) |
| | | ) |
| | | |
| | | |
| | | 2016-02-12 01:06:35,859 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-02-12 01:06:35,859 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-02-12 01:06:36,383 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) |
| | | 2016-02-12 01:06:36,384 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) |
| | | 2016-02-12 01:06:36,384 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('editor', 'editor', '$2b$12$bSr5QR3wFs1LAnld7R94e.TXPj7DVoTxu2hA1kY6rm.Q3cAhD.AQO') |
| | | 2016-02-12 01:06:36,384 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) |
| | | 2016-02-12 01:06:36,384 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('basic', 'basic', '$2b$12$.v0BQK2xWEQOnywbX2BFs.qzXo5Qf9oZohGWux/MOSj6Z.pVaY2Z6') |
| | | 2016-02-12 01:06:36,385 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?) |
| | | 2016-02-12 01:06:36,385 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page', 1) |
| | | 2016-02-12 01:06:36,385 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-04-09 02:49:51,716 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-04-09 02:49:51,717 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-04-09 02:49:52,256 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) |
| | | 2016-04-09 02:49:52,257 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) |
| | | 2016-04-09 02:49:52,257 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('editor', 'editor', b'$2b$12$APUPJvI/kKxrbQPyQehkR.ggoOM6fFYCZ07SFCkWGltl1wJsKB98y') |
| | | 2016-04-09 02:49:52,258 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) |
| | | 2016-04-09 02:49:52,258 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('basic', 'basic', b'$2b$12$GeFnypuQpZyxZLH.sN0akOrPdZMcQjqVTCim67u6f89lOFH/0ddc6') |
| | | 2016-04-09 02:49:52,259 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?) |
| | | 2016-04-09 02:49:52,259 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page', 1) |
| | | 2016-04-09 02:49:52,259 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | |
| | | |
| | | View the application in a browser |
| | | --------------------------------- |
| | |
| | | .. _wiki2_defining_views: |
| | | |
| | | ============== |
| | | Defining Views |
| | | ============== |
| | |
| | | Only the highlighted line needs to be added. |
| | | |
| | | Again, as we did in the previous chapter, the dependency now needs to be |
| | | installed, so re-run the ``python setup.py develop`` command. |
| | | installed, so re-run the ``$VENV/bin/pip install -e .`` command. |
| | | |
| | | |
| | | Static assets |
| | |
| | | |
| | | .. literalinclude:: src/views/tutorial/templates/layout.jinja2 |
| | | :linenos: |
| | | :emphasize-lines: 11,36 |
| | | :emphasize-lines: 11,35-36 |
| | | :language: html |
| | | |
| | | Since we're using a templating engine, we can factor common boilerplate out of |
| | |
| | | .. _wiki2_design: |
| | | |
| | | ====== |
| | | Design |
| | | ====== |
| | |
| | | .. _wiki2_distributing_your_application: |
| | | |
| | | ============================= |
| | | Distributing Your Application |
| | | ============================= |
| | |
| | | .. _wiki2_installation: |
| | | |
| | | ============ |
| | | Installation |
| | | ============ |
| | |
| | | ---------------- |
| | | |
| | | This tutorial assumes that you have already followed the steps in |
| | | :ref:`installing_chapter`, except **do not create a virtualenv or install |
| | | Pyramid**. Thereby you will satisfy the following requirements. |
| | | :ref:`installing_chapter`, except **do not create a virtual environment or |
| | | install Pyramid**. Thereby you will satisfy the following requirements. |
| | | |
| | | * Python interpreter is installed on your operating system |
| | | * :term:`setuptools` or :term:`distribute` is installed |
| | | * :term:`virtualenv` is installed |
| | | * A Python interpreter is installed on your operating system. |
| | | * You've satisfied the :ref:`requirements-for-installing-packages`. |
| | | |
| | | |
| | | Create directory to contain the project |
| | |
| | | Create and use a virtual Python environment |
| | | ------------------------------------------- |
| | | |
| | | Next let's create a ``virtualenv`` workspace for our project. We will use the |
| | | ``VENV`` environment variable instead of the absolute path of the virtual |
| | | Next let's create a virtual environment workspace for our project. We will use |
| | | the ``VENV`` environment variable instead of the absolute path of the virtual |
| | | environment. |
| | | |
| | | On UNIX |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ export VENV=~/pyramidtut |
| | | $ virtualenv $VENV |
| | | $ python3 -m venv $VENV |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> c:\Python35\Scripts\virtualenv %VENV% |
| | | c:\> c:\Python35\Scripts\python -m venv %VENV% |
| | | |
| | | |
| | | Upgrade ``pip`` and ``setuptools`` in the virtual environment |
| | | ------------------------------------------------------------- |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pip install --upgrade pip setuptools |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> %VENV%\Scripts\pip install --upgrade pip setuptools |
| | | |
| | | |
| | | Install Pyramid into the virtual Python environment |
| | |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/easy_install pyramid |
| | | $ $VENV/bin/pip install pyramid |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\> %VENV%\Scripts\easy_install pyramid |
| | | c:\> %VENV%\Scripts\pip install pyramid |
| | | |
| | | |
| | | Install SQLite3 and its development packages |
| | | -------------------------------------------- |
| | | |
| | | If you used a package manager to install your Python or if you compiled your |
| | | Python from source, then you must install SQLite3 and its development packages. |
| | | If you downloaded your Python as an installer from https://www.python.org, then |
| | | you already have it installed and can skip this step. |
| | | If you used a package manager to install your Python or if you compiled |
| | | your Python from source, then you must install SQLite3 and its |
| | | development packages. If you downloaded your Python as an installer |
| | | from https://www.python.org, then you already have it installed and can skip |
| | | this step. |
| | | |
| | | If you need to install the SQLite3 packages, then, for example, using the |
| | | Debian system and ``apt-get``, the command would be the following: |
| | | If you need to install the SQLite3 packages, then, for example, using |
| | | the Debian system and ``apt-get``, the command would be the following: |
| | | |
| | | .. code-block:: bash |
| | | |
| | |
| | | |
| | | .. note:: If you are using Windows, the ``alchemy`` scaffold may not deal |
| | | gracefully with installation into a location that contains spaces in the |
| | | path. If you experience startup problems, try putting both the virtualenv |
| | | and the project into directories that do not contain spaces in their paths. |
| | | path. If you experience startup problems, try putting both the virtual |
| | | environment and the project into directories that do not contain spaces in |
| | | their paths. |
| | | |
| | | |
| | | .. _installing_project_in_dev_mode: |
| | |
| | | ------------------------------------------ |
| | | |
| | | In order to do development on the project easily, you must "register" the |
| | | project as a development egg in your workspace using the ``setup.py develop`` |
| | | project as a development egg in your workspace using the ``pip install -e .`` |
| | | command. In order to do so, change directory to the ``tutorial`` directory that |
| | | you created in :ref:`sql_making_a_project`, and run the ``setup.py develop`` |
| | | command using the virtualenv Python interpreter. |
| | | you created in :ref:`sql_making_a_project`, and run the ``pip install -e .`` |
| | | command using the virtual environment Python interpreter. |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | |
| | | .. code-block:: bash |
| | | |
| | | $ cd tutorial |
| | | $ $VENV/bin/python setup.py develop |
| | | $ $VENV/bin/pip install -e . |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut> cd tutorial |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . |
| | | |
| | | The console will show ``setup.py`` checking for packages and installing missing |
| | | packages. Success executing this command will show a line like the following:: |
| | | The console will show ``pip`` checking for packages and installing missing |
| | | packages. Success executing this command will show a line like the following: |
| | | |
| | | Finished processing dependencies for tutorial==0.0 |
| | | .. code-block:: bash |
| | | |
| | | Successfully installed Chameleon-2.24 Mako-1.0.4 MarkupSafe-0.23 \ |
| | | Pygments-2.1.3 SQLAlchemy-1.0.12 pyramid-chameleon-0.3 \ |
| | | pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 pyramid-tm-0.12.1 \ |
| | | transaction-1.4.4 tutorial waitress-0.8.10 zope.sqlalchemy-0.7.6 |
| | | |
| | | |
| | | .. _install-testing-requirements: |
| | | |
| | | Install testing requirements |
| | | ---------------------------- |
| | | |
| | | In order to run tests, we need to install the testing requirements. This is |
| | | done through our project's ``setup.py`` file, in the ``tests_require`` and |
| | | ``extras_require`` stanzas, and by issuing the command below for your |
| | | operating system. |
| | | |
| | | .. literalinclude:: src/installation/setup.py |
| | | :language: python |
| | | :linenos: |
| | | :lineno-start: 22 |
| | | :lines: 22-26 |
| | | |
| | | .. literalinclude:: src/installation/setup.py |
| | | :language: python |
| | | :linenos: |
| | | :lineno-start: 45 |
| | | :lines: 45-47 |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/pip install -e ".[testing]" |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e ".[testing]" |
| | | |
| | | |
| | | .. _sql_running_tests: |
| | | |
| | | Run the tests |
| | | ------------- |
| | | |
| | | After you've installed the project in development mode, you may run the tests |
| | | for the project. |
| | | After you've installed the project in development mode as well as the testing |
| | | requirements, you may run the tests for the project. |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py test -q |
| | | $ $VENV/bin/py.test tutorial/tests.py -q |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\py.test tutorial\tests.py -q |
| | | |
| | | For a successful test run, you should see output that ends like this:: |
| | | For a successful test run, you should see output that ends like this: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | .. |
| | | ---------------------------------------------------------------------- |
| | | Ran 2 tests in 0.053s |
| | | 2 passed in 0.44 seconds |
| | | |
| | | OK |
| | | |
| | | Expose test coverage information |
| | | -------------------------------- |
| | | |
| | | You can run the ``nosetests`` command to see test coverage information. This |
| | | runs the tests in the same way that ``setup.py test`` does, but provides |
| | | additional "coverage" information, exposing which lines of your project are |
| | | covered by the tests. |
| | | You can run the ``py.test`` command to see test coverage information. This |
| | | runs the tests in the same way that ``py.test`` does, but provides additional |
| | | "coverage" information, exposing which lines of your project are covered by the |
| | | tests. |
| | | |
| | | To get this functionality working, we'll need to install the ``nose`` and |
| | | ``coverage`` packages into our ``virtualenv``: |
| | | We've already installed the ``pytest-cov`` package into our virtual |
| | | environment, so we can run the tests with coverage. |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/easy_install nose coverage |
| | | $ $VENV/bin/py.test --cov=tutorial --cov-report=term-missing tutorial/tests.py |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\easy_install nose coverage |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ |
| | | --cov-report=term-missing tutorial\tests.py |
| | | |
| | | Once ``nose`` and ``coverage`` are installed, we can run the tests with |
| | | coverage. |
| | | |
| | | On UNIX |
| | | ^^^^^^^ |
| | | If successful, you will see output something like this: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/nosetests --cover-package=tutorial --cover-erase --with-coverage |
| | | ======================== test session starts ======================== |
| | | platform Python 3.5.1, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 |
| | | rootdir: /Users/stevepiercy/projects/pyramidtut/tutorial, inifile: |
| | | plugins: cov-2.2.1 |
| | | collected 2 items |
| | | |
| | | On Windows |
| | | ^^^^^^^^^^ |
| | | tutorial/tests.py .. |
| | | ------------------ coverage: platform Python 3.5.1 ------------------ |
| | | Name Stmts Miss Cover Missing |
| | | ---------------------------------------------------------------- |
| | | tutorial/__init__.py 8 6 25% 7-12 |
| | | tutorial/models/__init__.py 22 0 100% |
| | | tutorial/models/meta.py 5 0 100% |
| | | tutorial/models/mymodel.py 8 0 100% |
| | | tutorial/routes.py 3 3 0% 1-3 |
| | | tutorial/scripts/__init__.py 0 0 100% |
| | | tutorial/scripts/initializedb.py 26 26 0% 1-45 |
| | | tutorial/tests.py 39 0 100% |
| | | tutorial/views/__init__.py 0 0 100% |
| | | tutorial/views/default.py 12 0 100% |
| | | tutorial/views/notfound.py 4 4 0% 1-7 |
| | | ---------------------------------------------------------------- |
| | | TOTAL 127 39 69% |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\nosetests --cover-package=tutorial \ |
| | | --cover-erase --with-coverage |
| | | |
| | | If successful, you will see output something like this:: |
| | | |
| | | .. |
| | | Name Stmts Miss Cover Missing |
| | | ---------------------------------------------------------- |
| | | tutorial.py 8 6 25% 7-12 |
| | | tutorial/models.py 22 0 100% |
| | | tutorial/models/meta.py 5 0 100% |
| | | tutorial/models/mymodel.py 8 0 100% |
| | | tutorial/scripts.py 0 0 100% |
| | | tutorial/views.py 0 0 100% |
| | | tutorial/views/default.py 12 0 100% |
| | | ---------------------------------------------------------- |
| | | TOTAL 55 6 89% |
| | | ---------------------------------------------------------------------- |
| | | Ran 2 tests in 0.579s |
| | | |
| | | OK |
| | | ===================== 2 passed in 0.57 seconds ====================== |
| | | |
| | | Our package doesn't quite have 100% test coverage. |
| | | |
| | |
| | | |
| | | The ``initialize_tutorial_db`` command does not perform a migration, but |
| | | rather it simply creates missing tables and adds some dummy data. If you |
| | | already have a database, you should delete it before running |
| | | ``initialize_tutorial_db`` again. |
| | | |
| | | .. note:: |
| | | |
| | | The ``initialize_tutorial_db`` command is not performing a migration but |
| | | rather simply creating missing tables and adding some dummy data. If you |
| | | already have a database, you should delete it before running |
| | | ``initialize_tutorial_db`` again. |
| | | |
| | |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\initialize_tutorial_db development.ini |
| | | |
| | | The output to your console should be something like this:: |
| | | The output to your console should be something like this: |
| | | |
| | | 2016-02-21 23:57:41,793 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-02-21 23:57:41,793 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-02-21 23:57:41,794 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-02-21 23:57:41,794 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-02-21 23:57:41,796 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models") |
| | | 2016-02-21 23:57:41,796 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-02-21 23:57:41,798 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] |
| | | .. code-block:: bash |
| | | |
| | | 2016-04-09 00:53:37,801 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-04-09 00:53:37,801 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-04-09 00:53:37,802 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 |
| | | 2016-04-09 00:53:37,802 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () |
| | | 2016-04-09 00:53:37,802 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models") |
| | | 2016-04-09 00:53:37,803 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-04-09 00:53:37,803 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] |
| | | CREATE TABLE models ( |
| | | id INTEGER NOT NULL, |
| | | name TEXT, |
| | |
| | | ) |
| | | |
| | | |
| | | 2016-02-21 23:57:41,798 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-02-21 23:57:41,798 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-02-21 23:57:41,799 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name) |
| | | 2016-02-21 23:57:41,799 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-02-21 23:57:41,799 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-02-21 23:57:41,801 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) |
| | | 2016-02-21 23:57:41,802 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?) |
| | | 2016-02-21 23:57:41,802 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1) |
| | | 2016-02-21 23:57:41,821 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-04-09 00:53:37,803 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-04-09 00:53:37,804 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-04-09 00:53:37,805 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name) |
| | | 2016-04-09 00:53:37,805 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () |
| | | 2016-04-09 00:53:37,806 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | 2016-04-09 00:53:37,807 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) |
| | | 2016-04-09 00:53:37,808 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?) |
| | | 2016-04-09 00:53:37,808 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1) |
| | | 2016-04-09 00:53:37,809 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT |
| | | |
| | | Success! You should now have a ``tutorial.sqlite`` file in your current |
| | | working directory. This is an SQLite database with a single table defined in it |
| | |
| | | |
| | | - You are willing to use :term:`URL dispatch` to map URLs to code. |
| | | |
| | | - You want to use zope.sqlalchemy_, pyramid_tm_ and the transaction_ package to |
| | | scope sessions to requests. |
| | | - You want to use zope.sqlalchemy_, pyramid_tm_, and the transaction_ packages |
| | | to scope sessions to requests. |
| | | |
| | | - You want to use pyramid_jinja2_ to render your templates. Different |
| | | templating engines can be used, but we had to choose one to make this |
| | |
| | | |
| | | .. _transaction: |
| | | http://zodb.readthedocs.org/en/latest/transactions.html |
| | | |
| | | .. _pyramid_jinja2: |
| | | http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/ |
| | | |
| | | .. _pyramid_tm: |
| | | http://docs.pylonsproject.org/projects/pyramid-tm/en/latest/ |
| | | |
| | | .. _zope.sqlalchemy: |
| | | https://pypi.python.org/pypi/zope.sqlalchemy |
| | | |
| | | .. _transaction: |
| | | http://zodb.readthedocs.org/en/latest/transactions.html |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_tutorial_db development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest', |
| | | ] |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='tutorial', |
| | | tests_require=tests_require, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | |
| | | self.session = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | def init_database(self): |
| | | from .models import Base |
| | | from .models.meta import Base |
| | | Base.metadata.create_all(self.engine) |
| | | |
| | | def tearDown(self): |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_tutorial_db development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest', |
| | | ] |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='tutorial', |
| | | tests_require=tests_require, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | |
| | | self.session = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | def init_database(self): |
| | | from .models import Base |
| | | from .models.meta import Base |
| | | Base.metadata.create_all(self.engine) |
| | | |
| | | def tearDown(self): |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_tutorial_db development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest', |
| | | ] |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='tutorial', |
| | | tests_require=tests_require, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li class="current-version">Generated by v1.7.dev0</li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | |
| | | {% block content %} |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7.dev0</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | {% endblock content %} |
| | |
| | | self.session = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | def init_database(self): |
| | | from .models import Base |
| | | from .models.meta import Base |
| | | Base.metadata.create_all(self.engine) |
| | | |
| | | def tearDown(self): |
New file |
| | |
| | | 0.0 |
| | | --- |
| | | |
| | | - Initial version |
New file |
| | |
| | | include *.txt *.ini *.cfg *.rst |
| | | recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml |
New file |
| | |
| | | tutorial README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_tutorial_db development.ini |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
New file |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | | use = egg:tutorial |
| | | |
| | | 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 |
| | | pyramid_tm |
| | | |
| | | sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite |
| | | |
| | | # 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 |
| | | host = 127.0.0.1 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | | keys = root, tutorial, sqlalchemy |
| | | |
| | | [handlers] |
| | | keys = console |
| | | |
| | | [formatters] |
| | | keys = generic |
| | | |
| | | [logger_root] |
| | | level = INFO |
| | | handlers = console |
| | | |
| | | [logger_tutorial] |
| | | level = DEBUG |
| | | handlers = |
| | | qualname = tutorial |
| | | |
| | | [logger_sqlalchemy] |
| | | level = INFO |
| | | handlers = |
| | | qualname = sqlalchemy.engine |
| | | # "level = INFO" logs SQL queries. |
| | | # "level = DEBUG" logs SQL queries and results. |
| | | # "level = WARN" logs neither. (Recommended for production systems.) |
| | | |
| | | [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 |
New file |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | | use = egg:tutorial |
| | | |
| | | pyramid.reload_templates = false |
| | | pyramid.debug_authorization = false |
| | | pyramid.debug_notfound = false |
| | | pyramid.debug_routematch = false |
| | | pyramid.default_locale_name = en |
| | | |
| | | sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite |
| | | |
| | | [server:main] |
| | | use = egg:waitress#main |
| | | host = 0.0.0.0 |
| | | port = 6543 |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | | keys = root, tutorial, sqlalchemy |
| | | |
| | | [handlers] |
| | | keys = console |
| | | |
| | | [formatters] |
| | | keys = generic |
| | | |
| | | [logger_root] |
| | | level = WARN |
| | | handlers = console |
| | | |
| | | [logger_tutorial] |
| | | level = WARN |
| | | handlers = |
| | | qualname = tutorial |
| | | |
| | | [logger_sqlalchemy] |
| | | level = WARN |
| | | handlers = |
| | | qualname = sqlalchemy.engine |
| | | # "level = INFO" logs SQL queries. |
| | | # "level = DEBUG" logs SQL queries and results. |
| | | # "level = WARN" logs neither. (Recommended for production systems.) |
| | | |
| | | [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 |
New file |
| | |
| | | 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', |
| | | 'pyramid_tm', |
| | | 'SQLAlchemy', |
| | | 'transaction', |
| | | 'zope.sqlalchemy', |
| | | 'waitress', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | 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 wsgi bfg pylons pyramid', |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = tutorial:main |
| | | [console_scripts] |
| | | initialize_tutorial_db = tutorial.scripts.initializedb:main |
| | | """, |
| | | ) |
New file |
| | |
| | | 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.include('.models') |
| | | config.include('.routes') |
| | | config.scan() |
| | | return config.make_wsgi_app() |
New file |
| | |
| | | from sqlalchemy import engine_from_config |
| | | from sqlalchemy.orm import sessionmaker |
| | | from sqlalchemy.orm import configure_mappers |
| | | import zope.sqlalchemy |
| | | |
| | | # import or define all models here to ensure they are attached to the |
| | | # Base.metadata prior to any initialization routines |
| | | from .mymodel import MyModel # flake8: noqa |
| | | |
| | | # run configure_mappers after defining all of the models to ensure |
| | | # all relationships can be setup |
| | | configure_mappers() |
| | | |
| | | |
| | | def get_engine(settings, prefix='sqlalchemy.'): |
| | | return engine_from_config(settings, prefix) |
| | | |
| | | |
| | | def get_session_factory(engine): |
| | | factory = sessionmaker() |
| | | factory.configure(bind=engine) |
| | | return factory |
| | | |
| | | |
| | | def get_tm_session(session_factory, transaction_manager): |
| | | """ |
| | | Get a ``sqlalchemy.orm.Session`` instance backed by a transaction. |
| | | |
| | | This function will hook the session to the transaction manager which |
| | | will take care of committing any changes. |
| | | |
| | | - When using pyramid_tm it will automatically be committed or aborted |
| | | depending on whether an exception is raised. |
| | | |
| | | - When using scripts you should wrap the session in a manager yourself. |
| | | For example:: |
| | | |
| | | import transaction |
| | | |
| | | engine = get_engine(settings) |
| | | session_factory = get_session_factory(engine) |
| | | with transaction.manager: |
| | | dbsession = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | """ |
| | | dbsession = session_factory() |
| | | zope.sqlalchemy.register( |
| | | dbsession, transaction_manager=transaction_manager) |
| | | return dbsession |
| | | |
| | | |
| | | def includeme(config): |
| | | """ |
| | | Initialize the model for a Pyramid app. |
| | | |
| | | Activate this setup using ``config.include('tutorial.models')``. |
| | | |
| | | """ |
| | | settings = config.get_settings() |
| | | |
| | | # use pyramid_tm to hook the transaction lifecycle to the request |
| | | config.include('pyramid_tm') |
| | | |
| | | session_factory = get_session_factory(get_engine(settings)) |
| | | config.registry['dbsession_factory'] = session_factory |
| | | |
| | | # make request.dbsession available for use in Pyramid |
| | | config.add_request_method( |
| | | # r.tm is the transaction manager used by pyramid_tm |
| | | lambda r: get_tm_session(session_factory, r.tm), |
| | | 'dbsession', |
| | | reify=True |
| | | ) |
New file |
| | |
| | | from sqlalchemy.ext.declarative import declarative_base |
| | | from sqlalchemy.schema import MetaData |
| | | |
| | | # Recommended naming convention used by Alembic, as various different database |
| | | # providers will autogenerate vastly different names making migrations more |
| | | # difficult. See: http://alembic.readthedocs.org/en/latest/naming.html |
| | | NAMING_CONVENTION = { |
| | | "ix": 'ix_%(column_0_label)s', |
| | | "uq": "uq_%(table_name)s_%(column_0_name)s", |
| | | "ck": "ck_%(table_name)s_%(constraint_name)s", |
| | | "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", |
| | | "pk": "pk_%(table_name)s" |
| | | } |
| | | |
| | | metadata = MetaData(naming_convention=NAMING_CONVENTION) |
| | | Base = declarative_base(metadata=metadata) |
New file |
| | |
| | | from sqlalchemy import ( |
| | | Column, |
| | | Index, |
| | | Integer, |
| | | Text, |
| | | ) |
| | | |
| | | from .meta import Base |
| | | |
| | | |
| | | class MyModel(Base): |
| | | __tablename__ = 'models' |
| | | id = Column(Integer, primary_key=True) |
| | | name = Column(Text) |
| | | value = Column(Integer) |
| | | |
| | | |
| | | Index('my_index', MyModel.name, unique=True, mysql_length=255) |
New file |
| | |
| | | def includeme(config): |
| | | config.add_static_view('static', 'static', cache_max_age=3600) |
| | | config.add_route('home', '/') |
New file |
| | |
| | | import os |
| | | import sys |
| | | import transaction |
| | | |
| | | from pyramid.paster import ( |
| | | get_appsettings, |
| | | setup_logging, |
| | | ) |
| | | |
| | | from pyramid.scripts.common import parse_vars |
| | | |
| | | from ..models.meta import Base |
| | | from ..models import ( |
| | | get_engine, |
| | | get_session_factory, |
| | | get_tm_session, |
| | | ) |
| | | from ..models import MyModel |
| | | |
| | | |
| | | def usage(argv): |
| | | cmd = os.path.basename(argv[0]) |
| | | print('usage: %s <config_uri> [var=value]\n' |
| | | '(example: "%s development.ini")' % (cmd, cmd)) |
| | | sys.exit(1) |
| | | |
| | | |
| | | def main(argv=sys.argv): |
| | | if len(argv) < 2: |
| | | usage(argv) |
| | | config_uri = argv[1] |
| | | options = parse_vars(argv[2:]) |
| | | setup_logging(config_uri) |
| | | settings = get_appsettings(config_uri, options=options) |
| | | |
| | | engine = get_engine(settings) |
| | | Base.metadata.create_all(engine) |
| | | |
| | | session_factory = get_session_factory(engine) |
| | | |
| | | with transaction.manager: |
| | | dbsession = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | model = MyModel(name='one', value=1) |
| | | dbsession.add(model) |
New file |
| | |
| | | @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; |
| | | } |
| | | } |
New file |
| | |
| | | {% extends "layout.jinja2" %} |
| | | |
| | | {% block content %} |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> |
| | | <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> |
| | | </div> |
| | | {% endblock content %} |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="{{request.locale_name}}"> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | | <meta name="description" content="pyramid web application"> |
| | | <meta name="author" content="Pylons Project"> |
| | | <link rel="shortcut icon" href="{{request.static_url('tutorial:static/pyramid-16x16.png')}}"> |
| | | |
| | | <title>Alchemy Scaffold for The Pyramid Web Framework</title> |
| | | |
| | | <!-- Bootstrap core CSS --> |
| | | <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> |
| | | |
| | | <!-- Custom styles for this scaffold --> |
| | | <link href="{{request.static_url('tutorial:static/theme.css')}}" rel="stylesheet"> |
| | | |
| | | <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> |
| | | <!--[if lt IE 9]> |
| | | <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> |
| | | <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> |
| | | <![endif]--> |
| | | </head> |
| | | |
| | | <body> |
| | | |
| | | <div class="starter-template"> |
| | | <div class="container"> |
| | | <div class="row"> |
| | | <div class="col-md-2"> |
| | | <img class="logo img-responsive" src="{{request.static_url('tutorial:static/pyramid.png')}}" alt="pyramid web framework"> |
| | | </div> |
| | | <div class="col-md-10"> |
| | | {% block content %} |
| | | <p>No content</p> |
| | | {% endblock content %} |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | | <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="copyright"> |
| | | Copyright © Pylons Project |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | |
| | | <!-- Bootstrap core JavaScript |
| | | ================================================== --> |
| | | <!-- Placed at the end of the document so the pages load faster --> |
| | | <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> |
| | | <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> |
| | | </body> |
| | | </html> |
New file |
| | |
| | | {% extends "layout.jinja2" %} |
| | | |
| | | {% block content %} |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | {% endblock content %} |
New file |
| | |
| | | import unittest |
| | | import transaction |
| | | |
| | | from pyramid import testing |
| | | |
| | | |
| | | def dummy_request(dbsession): |
| | | return testing.DummyRequest(dbsession=dbsession) |
| | | |
| | | |
| | | class BaseTest(unittest.TestCase): |
| | | def setUp(self): |
| | | self.config = testing.setUp(settings={ |
| | | 'sqlalchemy.url': 'sqlite:///:memory:' |
| | | }) |
| | | self.config.include('.models') |
| | | settings = self.config.get_settings() |
| | | |
| | | from .models import ( |
| | | get_engine, |
| | | get_session_factory, |
| | | get_tm_session, |
| | | ) |
| | | |
| | | self.engine = get_engine(settings) |
| | | session_factory = get_session_factory(self.engine) |
| | | |
| | | self.session = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | def init_database(self): |
| | | from .models.meta import Base |
| | | Base.metadata.create_all(self.engine) |
| | | |
| | | def tearDown(self): |
| | | from .models.meta import Base |
| | | |
| | | testing.tearDown() |
| | | transaction.abort() |
| | | Base.metadata.drop_all(self.engine) |
| | | |
| | | |
| | | class TestMyViewSuccessCondition(BaseTest): |
| | | |
| | | def setUp(self): |
| | | super(TestMyViewSuccessCondition, self).setUp() |
| | | self.init_database() |
| | | |
| | | from .models import MyModel |
| | | |
| | | model = MyModel(name='one', value=55) |
| | | self.session.add(model) |
| | | |
| | | def test_passing_view(self): |
| | | from .views.default import my_view |
| | | info = my_view(dummy_request(self.session)) |
| | | self.assertEqual(info['one'].name, 'one') |
| | | self.assertEqual(info['project'], 'tutorial') |
| | | |
| | | |
| | | class TestMyViewFailureCondition(BaseTest): |
| | | |
| | | def test_failing_view(self): |
| | | from .views.default import my_view |
| | | info = my_view(dummy_request(self.session)) |
| | | self.assertEqual(info.status_int, 500) |
New file |
| | |
| | | from pyramid.response import Response |
| | | from pyramid.view import view_config |
| | | |
| | | from sqlalchemy.exc import DBAPIError |
| | | |
| | | from ..models import MyModel |
| | | |
| | | |
| | | @view_config(route_name='home', renderer='../templates/mytemplate.jinja2') |
| | | def my_view(request): |
| | | try: |
| | | query = request.dbsession.query(MyModel) |
| | | one = query.filter(MyModel.name == 'one').first() |
| | | except DBAPIError: |
| | | return Response(db_err_msg, content_type='text/plain', status=500) |
| | | return {'one': one, 'project': 'tutorial'} |
| | | |
| | | |
| | | db_err_msg = """\ |
| | | Pyramid is having a problem using your SQL database. The problem |
| | | might be caused by one of the following things: |
| | | |
| | | 1. You may need to run the "initialize_tutorial_db" script |
| | | to initialize your database tables. Check your virtual |
| | | environment's "bin" directory for this script and try to run it. |
| | | |
| | | 2. Your database server may not be running. Check that the |
| | | database server referred to by the "sqlalchemy.url" setting in |
| | | your "development.ini" file is running. |
| | | |
| | | After you fix the problem, please restart the Pyramid application to |
| | | try it again. |
| | | """ |
New file |
| | |
| | | from pyramid.view import notfound_view_config |
| | | |
| | | |
| | | @notfound_view_config(renderer='../templates/404.jinja2') |
| | | def notfound_view(request): |
| | | request.response.status = 404 |
| | | return {} |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_tutorial_db development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest', |
| | | ] |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='tutorial', |
| | | tests_require=tests_require, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | |
| | | <div class="row"> |
| | | <div class="links"> |
| | | <ul> |
| | | <li class="current-version">Generated by v1.7.dev0</li> |
| | | <li class="current-version">Generated by v1.7</li> |
| | | <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li> |
| | | <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> |
| | | <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> |
| | |
| | | {% block content %} |
| | | <div class="content"> |
| | | <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> |
| | | <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7.dev0</span>.</p> |
| | | <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p> |
| | | </div> |
| | | {% endblock content %} |
| | |
| | | self.session = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | def init_database(self): |
| | | from .models import Base |
| | | from .models.meta import Base |
| | | Base.metadata.create_all(self.engine) |
| | | |
| | | def tearDown(self): |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_tutorial_db development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest', |
| | | ] |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='tutorial', |
| | | tests_require=tests_require, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | |
| | | import transaction |
| | | import unittest |
| | | from webtest import TestApp |
| | | import webtest |
| | | |
| | | |
| | | class FunctionalTests(unittest.TestCase): |
| | |
| | | 'auth.secret': 'seekrit', |
| | | } |
| | | app = main({}, **settings) |
| | | cls.testapp = TestApp(app) |
| | | cls.testapp = webtest.TestApp(app) |
| | | |
| | | session_factory = app.registry['dbsession_factory'] |
| | | cls.engine = session_factory.kw['bind'] |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_tutorial_db development.ini |
| | | |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ### |
| | | # app configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html |
| | | ### |
| | | |
| | | [app:main] |
| | |
| | | |
| | | ### |
| | | # logging configuration |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html |
| | | # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html |
| | | ### |
| | | |
| | | [loggers] |
| | |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest', |
| | | ] |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='tutorial', |
| | | version='0.0', |
| | | description='tutorial', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='tutorial', |
| | | tests_require=tests_require, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | |
| | | self.session = get_tm_session(session_factory, transaction.manager) |
| | | |
| | | def init_database(self): |
| | | from .models import Base |
| | | from .models.meta import Base |
| | | Base.metadata.create_all(self.engine) |
| | | |
| | | def tearDown(self): |
| | |
| | | .. _wiki2_adding_tests: |
| | | |
| | | ============ |
| | | Adding Tests |
| | | ============ |
| | |
| | | Running the tests |
| | | ================= |
| | | |
| | | We can run these tests by using ``setup.py test`` in the same way we did in |
| | | :ref:`running_tests`: |
| | | We can run these tests similarly to how we did in :ref:`running_tests`: |
| | | |
| | | On UNIX: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ $VENV/bin/python setup.py test -q |
| | | $ $VENV/bin/py.test -q |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: ps1con |
| | | |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q |
| | | c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q |
| | | |
| | | The expected result should look like the following: |
| | | |
| | | .. code-block:: text |
| | | |
| | | ..................... |
| | | ---------------------------------------------------------------------- |
| | | Ran 22 tests in 5.320s |
| | | |
| | | OK |
| | | ...................... |
| | | 22 passed, 1 pytest-warnings in 5.81 seconds |
| | | |
| | | .. note:: If you use Python 3 during this tutorial, you will see deprecation |
| | | warnings in the output, which we will choose to ignore. In making this |
| | |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/python setup.py develop |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/initialize_{{project}}_db development.ini |
| | | |
| | |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest', |
| | | ] |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='{{project}}', |
| | | version='0.0', |
| | | description='{{project}}', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='{{package}}', |
| | | tests_require=tests_require, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | |
| | | request = testing.DummyRequest() |
| | | info = my_view(request) |
| | | self.assertEqual(info['project'], '{{project}}') |
| | | |
| | | |
| | | class FunctionalTests(unittest.TestCase): |
| | | def setUp(self): |
| | | from {{package}} 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) |
| | |
| | | {{project}} README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | 'waitress', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='{{project}}', |
| | | version='0.0', |
| | | description='{{project}}', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="{{package}}", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = {{package}}:main |
| | |
| | | color: #f2b7bd; |
| | | font-weight: 400; |
| | | } |
| | | .starter-template .links ul li a { |
| | | color: #ffffff; |
| | | .starter-template .links ul li a, a { |
| | | color: #f2b7bd; |
| | | text-decoration: underline; |
| | | } |
| | | .starter-template .links ul li a:hover { |
| | | .starter-template .links ul li a:hover, a:hover { |
| | | color: #ffffff; |
| | | text-decoration: underline; |
| | | } |
| | | .starter-template .links ul li .icon-muted { |
| | |
| | | {{project}} README |
| | | ================== |
| | | |
| | | Getting Started |
| | | --------------- |
| | | |
| | | - cd <directory containing this file> |
| | | |
| | | - $VENV/bin/pip install -e . |
| | | |
| | | - $VENV/bin/pserve development.ini |
| | | |
| | |
| | | 'waitress', |
| | | ] |
| | | |
| | | tests_require = [ |
| | | 'WebTest >= 1.3.1', # py3 compat |
| | | 'pytest', # includes virtualenv |
| | | 'pytest-cov', |
| | | ] |
| | | |
| | | setup(name='{{project}}', |
| | | version='0.0', |
| | | description='{{project}}', |
| | | long_description=README + '\n\n' + CHANGES, |
| | | classifiers=[ |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | "Programming Language :: Python", |
| | | "Framework :: Pyramid", |
| | | "Topic :: Internet :: WWW/HTTP", |
| | | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", |
| | | ], |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | extras_require={ |
| | | 'testing': tests_require, |
| | | }, |
| | | install_requires=requires, |
| | | tests_require=requires, |
| | | test_suite="{{package}}", |
| | | entry_points="""\ |
| | | [paste.app_factory] |
| | | main = {{package}}:main |