summaryrefslogtreecommitdiff
path: root/docs/tutorials/wiki2
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/wiki2')
-rw-r--r--docs/tutorials/wiki2/authentication.rst2
-rw-r--r--docs/tutorials/wiki2/basiclayout.rst14
-rw-r--r--docs/tutorials/wiki2/definingmodels.rst143
-rw-r--r--docs/tutorials/wiki2/definingviews.rst14
-rw-r--r--docs/tutorials/wiki2/design.rst33
-rw-r--r--docs/tutorials/wiki2/distributing.rst12
-rw-r--r--docs/tutorials/wiki2/index.rst7
-rw-r--r--docs/tutorials/wiki2/installation.rst340
-rw-r--r--docs/tutorials/wiki2/src/authentication/.coveragerc3
-rw-r--r--docs/tutorials/wiki2/src/authentication/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki2/src/authentication/MANIFEST.in2
-rw-r--r--docs/tutorials/wiki2/src/authentication/README.txt31
-rw-r--r--docs/tutorials/wiki2/src/authentication/development.ini8
-rw-r--r--docs/tutorials/wiki2/src/authentication/production.ini11
-rw-r--r--docs/tutorials/wiki2/src/authentication/pytest.ini3
-rw-r--r--docs/tutorials/wiki2/src/authentication/setup.py65
-rw-r--r--docs/tutorials/wiki2/src/authentication/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki2/src/authentication/tutorial/views/default.py6
-rw-r--r--docs/tutorials/wiki2/src/authorization/.coveragerc3
-rw-r--r--docs/tutorials/wiki2/src/authorization/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki2/src/authorization/MANIFEST.in2
-rw-r--r--docs/tutorials/wiki2/src/authorization/README.txt31
-rw-r--r--docs/tutorials/wiki2/src/authorization/development.ini8
-rw-r--r--docs/tutorials/wiki2/src/authorization/production.ini11
-rw-r--r--docs/tutorials/wiki2/src/authorization/pytest.ini3
-rw-r--r--docs/tutorials/wiki2/src/authorization/setup.py65
-rw-r--r--docs/tutorials/wiki2/src/authorization/tutorial/views/default.py6
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/.coveragerc3
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/MANIFEST.in2
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/README.txt31
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/development.ini8
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/production.ini11
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/pytest.ini3
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/setup.py65
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py2
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja28
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja24
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py2
-rw-r--r--docs/tutorials/wiki2/src/installation/.coveragerc3
-rw-r--r--docs/tutorials/wiki2/src/installation/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki2/src/installation/MANIFEST.in2
-rw-r--r--docs/tutorials/wiki2/src/installation/README.txt31
-rw-r--r--docs/tutorials/wiki2/src/installation/development.ini8
-rw-r--r--docs/tutorials/wiki2/src/installation/production.ini11
-rw-r--r--docs/tutorials/wiki2/src/installation/pytest.ini3
-rw-r--r--docs/tutorials/wiki2/src/installation/setup.py65
-rw-r--r--docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py2
-rw-r--r--docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja28
-rw-r--r--docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja24
-rw-r--r--docs/tutorials/wiki2/src/installation/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki2/src/installation/tutorial/views/default.py2
-rw-r--r--docs/tutorials/wiki2/src/models/.coveragerc3
-rw-r--r--docs/tutorials/wiki2/src/models/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki2/src/models/MANIFEST.in2
-rw-r--r--docs/tutorials/wiki2/src/models/README.txt31
-rw-r--r--docs/tutorials/wiki2/src/models/development.ini8
-rw-r--r--docs/tutorials/wiki2/src/models/production.ini11
-rw-r--r--docs/tutorials/wiki2/src/models/pytest.ini3
-rw-r--r--docs/tutorials/wiki2/src/models/setup.py65
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja28
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja24
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/views/default.py2
-rw-r--r--docs/tutorials/wiki2/src/tests/.coveragerc3
-rw-r--r--docs/tutorials/wiki2/src/tests/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki2/src/tests/MANIFEST.in2
-rw-r--r--docs/tutorials/wiki2/src/tests/README.txt31
-rw-r--r--docs/tutorials/wiki2/src/tests/development.ini8
-rw-r--r--docs/tutorials/wiki2/src/tests/production.ini11
-rw-r--r--docs/tutorials/wiki2/src/tests/pytest.ini3
-rw-r--r--docs/tutorials/wiki2/src/tests/setup.py65
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py1
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py12
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py16
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py23
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py67
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/views/default.py6
-rw-r--r--docs/tutorials/wiki2/src/views/.coveragerc3
-rw-r--r--docs/tutorials/wiki2/src/views/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki2/src/views/MANIFEST.in2
-rw-r--r--docs/tutorials/wiki2/src/views/README.txt31
-rw-r--r--docs/tutorials/wiki2/src/views/development.ini8
-rw-r--r--docs/tutorials/wiki2/src/views/production.ini11
-rw-r--r--docs/tutorials/wiki2/src/views/pytest.ini3
-rw-r--r--docs/tutorials/wiki2/src/views/setup.py65
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja22
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/views/default.py6
-rw-r--r--docs/tutorials/wiki2/tests.rst43
91 files changed, 963 insertions, 721 deletions
diff --git a/docs/tutorials/wiki2/authentication.rst b/docs/tutorials/wiki2/authentication.rst
index 5447db861..ff59ce70b 100644
--- a/docs/tutorials/wiki2/authentication.rst
+++ b/docs/tutorials/wiki2/authentication.rst
@@ -92,7 +92,7 @@ Our authentication policy is expecting a new setting, ``auth.secret``. Open
the file ``development.ini`` and add the highlighted line below:
.. literalinclude:: src/authentication/development.ini
- :lines: 18-20
+ :lines: 17-19
:emphasize-lines: 3
:lineno-match:
:language: ini
diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst
index 98a14c644..233231f8d 100644
--- a/docs/tutorials/wiki2/basiclayout.rst
+++ b/docs/tutorials/wiki2/basiclayout.rst
@@ -4,7 +4,7 @@
Basic Layout
============
-The starter files generated by the ``alchemy`` scaffold are very basic, but
+The starter files generated by the ``alchemy`` cookiecutter are very basic, but
they provide a good orientation for the high-level patterns common to most
:term:`URL dispatch`-based :app:`Pyramid` projects.
@@ -29,7 +29,6 @@ code:
.. literalinclude:: src/basiclayout/tutorial/__init__.py
:end-before: main
- :linenos:
:lineno-match:
:language: py
@@ -38,7 +37,6 @@ the ``main`` function we've defined in our ``__init__.py``:
.. literalinclude:: src/basiclayout/tutorial/__init__.py
:pyobject: main
- :linenos:
:lineno-match:
:language: py
@@ -179,7 +177,7 @@ decorator in order to create a view configuration within our application.
Without being processed by ``scan``, the decorator effectively does nothing.
``@view_config`` is inert without being detected via a :term:`scan`.
-The sample ``my_view()`` created by the scaffold uses a ``try:`` and
+The sample ``my_view()`` created by the cookiecutter uses a ``try:`` and
``except:`` clause to detect if there is a problem accessing the project
database and provide an alternate error response. That response will include
the text shown at the end of the file, which will be displayed in the browser
@@ -191,7 +189,7 @@ Content models with the ``models`` package
In an SQLAlchemy-based application, a *model* object is an object composed by
querying the SQL database. The ``models`` package is where the ``alchemy``
-scaffold put the classes that implement our models.
+cookiecutter put the classes that implement our models.
First, open ``tutorial/models/meta.py``, which should already contain the
following:
@@ -222,7 +220,6 @@ application's database schema.
.. literalinclude:: src/basiclayout/tutorial/models/meta.py
:lines: 15-16
:lineno-match:
- :linenos:
:language: py
Next open ``tutorial/models/mymodel.py``, which should already contain the
@@ -239,7 +236,6 @@ we have defined one named ``MyModel`` in ``mymodel.py``:
.. literalinclude:: src/basiclayout/tutorial/models/mymodel.py
:pyobject: MyModel
:lineno-match:
- :linenos:
:language: py
Our example model does not require an ``__init__`` method because SQLAlchemy
@@ -292,7 +288,6 @@ database engine using :func:`sqlalchemy.engine_from_config` from the
.. literalinclude:: src/basiclayout/tutorial/models/__init__.py
:pyobject: get_engine
:lineno-match:
- :linenos:
:language: py
The function ``get_session_factory`` accepts an :term:`SQLAlchemy` database
@@ -303,7 +298,6 @@ used for creating sessions bound to the database engine.
.. literalinclude:: src/basiclayout/tutorial/models/__init__.py
:pyobject: get_session_factory
:lineno-match:
- :linenos:
:language: py
The function ``get_tm_session`` registers a database session with a transaction
@@ -314,7 +308,6 @@ unless an exception is raised, in which case the transaction will be aborted.
.. literalinclude:: src/basiclayout/tutorial/models/__init__.py
:pyobject: get_tm_session
:lineno-match:
- :linenos:
:language: py
Finally, we define an ``includeme`` function, which is a hook for use with
@@ -328,7 +321,6 @@ of an incoming request to our application.
.. literalinclude:: src/basiclayout/tutorial/models/__init__.py
:pyobject: includeme
:lineno-match:
- :linenos:
:language: py
That's about all there is to it regarding models, views, and initialization
diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst
index 9f7b82d1d..5cebb943c 100644
--- a/docs/tutorials/wiki2/definingmodels.rst
+++ b/docs/tutorials/wiki2/definingmodels.rst
@@ -4,7 +4,7 @@
Defining the Domain Model
=========================
-The first change we'll make to our stock ``pcreate``-generated application will
+The first change we'll make to our stock cookiecutter-generated application will
be to define a wiki page :term:`domain model`.
.. note::
@@ -22,10 +22,10 @@ Declaring dependencies in our ``setup.py`` file
The models code in our application will depend on a package which is not a
dependency of the original "tutorial" application. The original "tutorial"
-application was generated by the ``pcreate`` command; it doesn't know about our
+application was generated by the cookiecutter; it doesn't know about our
custom application requirements.
-We need to add a dependency, the ``bcrypt`` package, to our ``tutorial``
+We need to add a dependency, the `bcrypt <https://pypi.python.org/pypi/bcrypt>`_ package, to our ``tutorial``
package's ``setup.py`` file by assigning this dependency to the ``requires``
parameter in the ``setup()`` function.
@@ -38,6 +38,10 @@ Open ``tutorial/setup.py`` and edit it to look like the following:
Only the highlighted line needs to be added.
+.. note::
+
+ We are using the ``bcrypt`` package from PyPI to hash our passwords securely. There are other one-way hash algorithms for passwords if ``bcrypt`` is an issue on your system. Just make sure that it's an algorithm approved for storing passwords versus a generic one-way hash.
+
Running ``pip install -e .``
============================
@@ -53,31 +57,31 @@ On UNIX:
.. code-block:: bash
- $ cd tutorial
- $ $VENV/bin/pip install -e .
+ $ $VENV/bin/pip install -e .
On Windows:
.. code-block:: doscon
- c:\pyramidtut> cd tutorial
- c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e .
+ c:\tutorial> %VENV%\Scripts\pip install -e .
Success executing this command will end with a line to the console something
-like this::
+like the following.
- Successfully installed bcrypt-2.0.0 cffi-1.5.2 pycparser-2.14 tutorial-0.0
+.. code-block:: text
+
+ Successfully installed bcrypt-3.1.2 cffi-1.9.1 pycparser-2.17 tutorial
Remove ``mymodel.py``
----------------------
+=====================
Let's delete the file ``tutorial/models/mymodel.py``. The ``MyModel`` class is
only a sample and we're not going to use it.
Add ``user.py``
----------------
+===============
Create a new file ``tutorial/models/user.py`` with the following contents:
@@ -98,12 +102,12 @@ and ``role`` (all instances of :class:`sqlalchemy.schema.Column`). These will
map to columns in the ``users`` table. The ``id`` attribute will be the primary
key in the table. The ``name`` attribute will be a text column, each value of
which needs to be unique within the column. The ``password_hash`` is a nullable
-text attribute that will contain a securely hashed password [1]_. Finally, the
+text attribute that will contain a securely hashed password. Finally, the
``role`` text attribute will hold the role of the user.
There are two helper methods that will help us later when using the user
objects. The first is ``set_password`` which will take a raw password and
-transform it using bcrypt_ into an irreversible representation, a process known
+transform it using ``bcrypt`` into an irreversible representation, a process known
as "hashing". The second method, ``check_password``, will allow us to compare
the hashed value of the submitted password against the hashed value of the
password stored in the user's record in the database. If the two hashed values
@@ -116,7 +120,7 @@ authenticate as any user.
Add ``page.py``
----------------
+===============
Create a new file ``tutorial/models/page.py`` with the following contents:
@@ -138,7 +142,7 @@ guaranteed that an instance of ``page`` will have a corresponding
Edit ``models/__init__.py``
----------------------------
+===========================
Since we are using a package for our models, we also need to update our
``__init__.py`` file to ensure that the models are attached to the metadata.
@@ -155,12 +159,16 @@ Here we align our imports with the names of the models, ``Page`` and ``User``.
Edit ``scripts/initializedb.py``
---------------------------------
+================================
We haven't looked at the details of this file yet, but within the ``scripts``
directory of your ``tutorial`` package is a file named ``initializedb.py``.
Code in this file is executed whenever we run the ``initialize_tutorial_db``
-command, as we did in the installation step of this tutorial [2]_.
+command, as we did in the installation step of this tutorial.
+
+.. note::
+
+ The command is named ``initialize_tutorial_db`` because of the mapping defined in the ``[console_scripts]`` entry point of our project's ``setup.py`` file.
Since we've changed our model, we need to make changes to our
``initializedb.py`` script. In particular, we'll replace our import of
@@ -180,7 +188,7 @@ Only the highlighted lines need to be changed.
Installing the project and re-initializing the database
--------------------------------------------------------
+=======================================================
Because our model has changed, and in order to reinitialize the database, we
need to rerun the ``initialize_tutorial_db`` command to pick up the changes
@@ -191,53 +199,53 @@ Success will look something like this:
.. code-block:: bash
- 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
- 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] ()
- 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
- 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] ()
- 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("users")
- 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ()
- 2016-05-22 04:12:09,228 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages")
- 2016-05-22 04:12:09,228 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ()
- 2016-05-22 04:12:09,229 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-05-22 04:12:09,229 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ()
- 2016-05-22 04:12:09,230 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT
- 2016-05-22 04:12:09,230 INFO [sqlalchemy.engine.base.Engine:1097][MainThread]
- CREATE TABLE pages (
- id INTEGER NOT NULL,
- name TEXT NOT NULL,
- data TEXT 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-05-22 04:12:09,231 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ()
- 2016-05-22 04:12:09,231 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT
- 2016-05-22 04:12:09,782 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit)
- 2016-05-22 04:12:09,783 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?)
- 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('editor', 'editor', b'$2b$12$K/WLVKRl5fMAb6UM58ueTetXlE3rlc5cRK5zFPimK598scXBR/xWC')
- 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?)
- 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('basic', 'basic', b'$2b$12$JfwLyCJGv3t.RTSmIrh3B.FKXRT9FevkAqafWdK5oq7Hl4mgAQORe')
- 2016-05-22 04:12:09,785 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?)
- 2016-05-22 04:12:09,785 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page', 1)
- 2016-05-22 04:12:09,786 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT
+ 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
+ 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] ()
+ 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
+ 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] ()
+ 2016-12-20 02:51:11,196 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] PRAGMA table_info("pages")
+ 2016-12-20 02:51:11,196 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ()
+ 2016-12-20 02:51:11,196 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] PRAGMA table_info("users")
+ 2016-12-20 02:51:11,197 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ()
+ 2016-12-20 02:51:11,197 INFO [sqlalchemy.engine.base.Engine:1140][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-12-20 02:51:11,197 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ()
+ 2016-12-20 02:51:11,198 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT
+ 2016-12-20 02:51:11,199 INFO [sqlalchemy.engine.base.Engine:1140][MainThread]
+ CREATE TABLE pages (
+ id INTEGER NOT NULL,
+ name TEXT NOT NULL,
+ data TEXT 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-12-20 02:51:11,199 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ()
+ 2016-12-20 02:51:11,200 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT
+ 2016-12-20 02:51:11,755 INFO [sqlalchemy.engine.base.Engine:679][MainThread] BEGIN (implicit)
+ 2016-12-20 02:51:11,755 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?)
+ 2016-12-20 02:51:11,755 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('editor', 'editor', '$2b$12$ds7h2Zb7.l6TEFup5h8f4ekA9GRfEpE1yQGDRvT9PConw73kKuupG')
+ 2016-12-20 02:51:11,756 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?)
+ 2016-12-20 02:51:11,756 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('basic', 'basic', '$2b$12$KgruXP5Vv7rikr6dGB3TF.flGXYpiE0Li9K583EVomjY.SYmQOsyi')
+ 2016-12-20 02:51:11,757 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?)
+ 2016-12-20 02:51:11,757 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('FrontPage', 'This is the front page', 1)
+ 2016-12-20 02:51:11,757 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT
View the application in a browser
----------------------------------
+=================================
We can't. At this point, our system is in a "non-runnable" state; we'll need
to change view-related files in the next chapter to be able to start the
@@ -250,14 +258,3 @@ your console that ends with this exception:
ImportError: cannot import name MyModel
This will also happen if you attempt to run the tests.
-
-.. _bcrypt: https://pypi.python.org/pypi/bcrypt
-
-.. [1] We are using the bcrypt_ package from PyPI to hash our passwords
- securely. There are other one-way hash algorithms for passwords if
- bcrypt is an issue on your system. Just make sure that it's an
- algorithm approved for storing passwords versus a generic one-way hash.
-
-.. [2] The command is named ``initialize_tutorial_db`` because of the mapping
- defined in the ``[console_scripts]`` entry point of our project's
- ``setup.py`` file.
diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst
index 996bff88c..3c343e155 100644
--- a/docs/tutorials/wiki2/definingviews.rst
+++ b/docs/tutorials/wiki2/definingviews.rst
@@ -42,7 +42,7 @@ installed, so re-run the ``$VENV/bin/pip install -e .`` command.
Static assets
--------------
+=============
Our templates name static assets, including CSS and images. We don't need
to create these files within our package's ``static`` directory because they
@@ -133,7 +133,7 @@ The highlighted lines need to be added or edited.
We added some imports, and created a regular expression to find "WikiWords".
We got rid of the ``my_view`` view function and its decorator that was added
-when we originally rendered the ``alchemy`` scaffold. It was only an example
+when we originally rendered the ``alchemy`` cookiecutter. It was only an example
and isn't relevant to our application. We also deleted the ``db_err_msg``
string.
@@ -340,7 +340,7 @@ indicated by the emphasized lines:
.. literalinclude:: src/views/tutorial/templates/layout.jinja2
:linenos:
- :emphasize-lines: 11,35-36
+ :emphasize-lines: 11,35-37
:language: html
Since we're using a templating engine, we can factor common boilerplate out of
@@ -350,7 +350,7 @@ template inheritance via blocks.
- We have defined two placeholders in the layout template where a child
template can override the content. These blocks are named ``subtitle`` (line
11) and ``content`` (line 36).
-- Please refer to the Jinja2_ documentation for more information about template
+- Please refer to the `Jinja2 documentation <http://jinja.pocoo.org/>`_ for more information about template
inheritance.
@@ -375,7 +375,7 @@ This template is used by ``view_page()`` for displaying a single wiki page.
view (line 6). ``content`` contains HTML, so the ``|safe`` filter is used to
prevent escaping it (e.g., changing ">" to "&gt;").
- We create a link that points at the "edit" URL, which when clicked invokes
- the ``edit_page`` view for the requested page (line 9).
+ the ``edit_page`` view for the requested page (lines 8-10).
The ``edit.jinja2`` template
@@ -436,7 +436,7 @@ There are several important things to note about this configuration:
the view.
Finally, we may delete the ``tutorial/templates/mytemplate.jinja2`` template
-that was provided by the ``alchemy`` scaffold, as we have created our own
+that was provided by the ``alchemy`` cookiecutter, as we have created our own
templates for the wiki.
.. note::
@@ -475,5 +475,3 @@ each of the following URLs, checking that the result is as expected:
will generate a ``NoResultFound: No row was found for one()`` error. You'll
see an interactive traceback facility provided by
:term:`pyramid_debugtoolbar`.
-
-.. _jinja2: http://jinja.pocoo.org/
diff --git a/docs/tutorials/wiki2/design.rst b/docs/tutorials/wiki2/design.rst
index 523a6e6d8..515aff276 100644
--- a/docs/tutorials/wiki2/design.rst
+++ b/docs/tutorials/wiki2/design.rst
@@ -23,22 +23,22 @@ We'll be using an SQLite database to hold our wiki data, and we'll be using
Within the database, we will define two tables:
-- The `users` table which will store the `id`, `name`, `password_hash` and
- `role` of each wiki user.
-- The `pages` table, whose elements will store the wiki pages.
- There are four columns: `id`, `name`, `data` and `creator_id`.
+- The ``users`` table which will store the ``id``, ``name``, ``password_hash`` and
+ ``role`` of each wiki user.
+- The ``pages`` table, whose elements will store the wiki pages.
+ There are four columns: ``id``, ``name``, ``data`` and ``creator_id``.
-There is a one-to-many relationship between `users` and `pages` tracking
-the user who created each wiki page defined by the `creator_id` column on the
-`pages` table.
+There is a one-to-many relationship between ``users`` and ``pages`` tracking
+the user who created each wiki page defined by the ``creator_id`` column on the
+``pages`` table.
-URLs like ``/PageName`` will try to find an element in the `pages` table that
+URLs like ``/PageName`` will try to find an element in the ``pages`` table that
has a corresponding name.
To add a page to the wiki, a new row is created and the text is stored in
-`data`.
+``data``.
-A page named ``FrontPage`` containing the text *This is the front page*, will
+A page named ``FrontPage`` containing the text "This is the front page" will
be created when the storage is initialized, and will be used as the wiki home
page.
@@ -61,12 +61,12 @@ We'll eventually be adding security to our application. To do this, we'll
be using a very simple role-based security model. We'll assign a single
role category to each user in our system.
-`basic`
- An authenticated user who can view content and create new pages. A `basic`
+``basic``
+ An authenticated user who can view content and create new pages. A ``basic``
user may also edit the pages they have created but not pages created by
other users.
-`editor`
+``editor``
An authenticated user who can create and edit any content in the system.
In order to accomplish this we'll need to define an authentication policy
@@ -101,16 +101,12 @@ in the following table:
+----------------------+-----------------------+-------------+----------------+------------+
| URL | Action | View | Template | Permission |
-| | | | | |
+======================+=======================+=============+================+============+
| / | Redirect to | view_wiki | | |
| | /FrontPage | | | |
+----------------------+-----------------------+-------------+----------------+------------+
| /PageName | Display existing | view_page | view.jinja2 | view |
| | page [2]_ | [1]_ | | |
-| | | | | |
-| | | | | |
-| | | | | |
+----------------------+-----------------------+-------------+----------------+------------+
| /PageName/edit_page | Display edit form | edit_page | edit.jinja2 | edit |
| | with existing | | | |
@@ -149,14 +145,13 @@ in the following table:
| | login form with | | | |
| | "login failed" | | | |
| | message. | | | |
-| | | | | |
+----------------------+-----------------------+-------------+----------------+------------+
| /logout | Redirect to | logout | | |
| | /FrontPage | | | |
+----------------------+-----------------------+-------------+----------------+------------+
.. [1] This is the default view for a Page context when there is no view name.
-.. [2] Pyramid will return a default 404 Not Found page if the page *PageName*
+.. [2] Pyramid will return a default 404 Not Found page if the page ``PageName``
does not exist yet.
.. [3] ``pyramid.exceptions.Forbidden`` is reached when a user tries to invoke
a view that is not authorized by the authorization policy.
diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst
index f38a733f4..dd6b1b750 100644
--- a/docs/tutorials/wiki2/distributing.rst
+++ b/docs/tutorials/wiki2/distributing.rst
@@ -19,22 +19,22 @@ On Windows:
.. code-block:: doscon
- c:\pyramidtut> %VENV%\Scripts\python setup.py sdist
+ c:\tutorial> %VENV%\Scripts\python setup.py sdist
The output of such a command will be something like:
.. code-block:: text
running sdist
- # .. more output ..
+ # more output
creating dist
Creating tar archive
removing 'tutorial-0.0' (and everything under it)
-Note that this command creates a tarball in the "dist" subdirectory named
+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
<https://pypi.python.org/pypi>`_ and share it with the rest of the world, where
-it can be downloaded via ``easy_install`` remotely like any other package
-people download from PyPI.
+it can be downloaded via ``pip install`` remotely like any other package people
+download from PyPI.
diff --git a/docs/tutorials/wiki2/index.rst b/docs/tutorials/wiki2/index.rst
index 18e9f552e..740a7f014 100644
--- a/docs/tutorials/wiki2/index.rst
+++ b/docs/tutorials/wiki2/index.rst
@@ -4,13 +4,11 @@ SQLAlchemy + URL dispatch wiki tutorial
=======================================
This tutorial introduces an :term:`SQLAlchemy` and :term:`URL dispatch`-based
-:app:`Pyramid` application to a developer familiar with Python. When the
-tutorial is finished, the developer will have created a basic wiki
+:app:`Pyramid` application to a developer familiar with Python. When finished, the developer will have created a basic wiki
application with authentication and authorization.
For cut and paste purposes, the source code for all stages of this tutorial can
-be browsed on GitHub at `docs/tutorials/wiki2/src
-<https://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src>`_,
+be browsed on `GitHub <https://github.com/Pylons/pyramid/>`_,
which corresponds to the same location if you have Pyramid sources.
.. toctree::
@@ -26,4 +24,3 @@ which corresponds to the same location if you have Pyramid sources.
authorization
tests
distributing
-
diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst
index 0440c2d1d..c61d4360d 100644
--- a/docs/tutorials/wiki2/installation.rst
+++ b/docs/tutorials/wiki2/installation.rst
@@ -15,178 +15,137 @@ install Pyramid**. Thereby you will satisfy the following requirements.
* You've satisfied the :ref:`requirements-for-installing-packages`.
-Create directory to contain the project
----------------------------------------
+Install SQLite3 and its development packages
+--------------------------------------------
-We need a workspace for our project files.
+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.
-On UNIX
-^^^^^^^
+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
- $ mkdir ~/pyramidtut
-
-On Windows
-^^^^^^^^^^
+ $ sudo apt-get install libsqlite3-dev
-.. code-block:: doscon
- c:\> mkdir pyramidtut
+Install cookiecutter
+--------------------
+We will use a :term:`cookiecutter` to create a Python package project from a Python package project template. See `Cookiecutter Installation <https://cookiecutter.readthedocs.io/en/latest/installation.html>`_ for instructions.
-Create and use a virtual Python environment
--------------------------------------------
+Generate a Pyramid project from a cookiecutter
+----------------------------------------------
-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.
+We will create a Pyramid project in your home directory for UNIX or at the root for Windows. It is assumed you know the path to where you installed ``cookiecutter``. Issue the following commands and override the defaults in the prompts as follows.
On UNIX
^^^^^^^
.. code-block:: bash
- $ export VENV=~/pyramidtut
- $ python3 -m venv $VENV
+ $ cd ~
+ $ cookiecutter https://github.com/Pylons/pyramid-cookiecutter-alchemy
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\> set VENV=c:\pyramidtut
-
-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:: doscon
-
- c:\> c:\Python27\Scripts\virtualenv %VENV%
+ c:\> cd \
+ c:\> cookiecutter https://github.com/Pylons/pyramid-cookiecutter-alchemy
-Python 3.5:
+On all operating systems
+^^^^^^^^^^^^^^^^^^^^^^^^
+If prompted for the first item, accept the default ``yes`` by hitting return.
-.. code-block:: doscon
-
- c:\> c:\Python35\Scripts\python -m venv %VENV%
+.. code-block:: text
+ You've cloned ~/.cookiecutters/pyramid-cookiecutter-alchemy before.
+ Is it okay to delete and re-clone it? [yes]: yes
+ project_name [Pyramid Scaffold]: myproj
+ repo_name [myproj]: tutorial
-Upgrade ``pip`` and ``setuptools`` in the virtual environment
--------------------------------------------------------------
+Change directory into your newly created project
+------------------------------------------------
On UNIX
^^^^^^^
.. code-block:: bash
- $ $VENV/bin/pip install --upgrade pip setuptools
+ $ cd tutorial
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\> %VENV%\Scripts\pip install --upgrade pip setuptools
+ c:\> cd tutorial
-Install Pyramid into the virtual Python environment
----------------------------------------------------
+Set and use a ``VENV`` environment variable
+-------------------------------------------
+
+We will set the ``VENV`` environment variable to the absolute path of the virtual environment, and use it going forward.
On UNIX
^^^^^^^
-.. parsed-literal::
+.. code-block:: bash
- $ $VENV/bin/pip install "pyramid==\ |release|\ "
+ $ export VENV=~/tutorial
On Windows
^^^^^^^^^^
-.. parsed-literal::
-
- c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ "
-
-
-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 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
-
- $ sudo apt-get install libsqlite3-dev
+.. code-block:: doscon
+ c:\tutorial> set VENV=c:\tutorial
-Change directory to your virtual Python environment
----------------------------------------------------
-Change directory to the ``pyramidtut`` directory, which is both your workspace
-and your virtual environment.
+Create a virtual environment
+----------------------------
On UNIX
^^^^^^^
.. code-block:: bash
- $ cd pyramidtut
+ $ python3 -m venv $VENV
On Windows
^^^^^^^^^^
-.. code-block:: doscon
+Each version of Python uses different paths, so you will need to adjust the path to the command for your Python version. Recent versions of the Python 3 installer for Windows now install a Python launcher.
- c:\> cd pyramidtut
+Python 2.7:
+.. code-block:: doscon
-.. _sql_making_a_project:
+ c:\tutorial> c:\Python27\Scripts\virtualenv %VENV%
-Making a project
-----------------
+Python 3.6:
-Your next step is to create a project. For this tutorial we will use
-the :term:`scaffold` named ``alchemy`` which generates an application
-that uses :term:`SQLAlchemy` and :term:`URL dispatch`.
+.. code-block:: doscon
-: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.
+ c:\tutorial> python -m venv %VENV%
-By passing ``alchemy`` into the ``pcreate`` command, the script creates the
-files needed to use SQLAlchemy. By passing in our application name
-``tutorial``, the script inserts that application name into all the required
-files. For example, ``pcreate`` creates the ``initialize_tutorial_db`` in the
-``pyramidtut/bin`` directory.
-The below instructions assume your current working directory is "pyramidtut".
+Upgrade packaging tools in the virtual environment
+--------------------------------------------------
On UNIX
^^^^^^^
.. code-block:: bash
- $ $VENV/bin/pcreate -s alchemy tutorial
+ $ $VENV/bin/pip install --upgrade pip setuptools
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\pyramidtut> %VENV%\Scripts\pcreate -s alchemy tutorial
-
-.. 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 virtual
- environment and the project into directories that do not contain spaces in
- their paths.
+ c:\tutorial> %VENV%\Scripts\pip install --upgrade pip setuptools
.. _installing_project_in_dev_mode:
@@ -194,74 +153,49 @@ On Windows
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 ``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 ``pip install -e .``
-command using the virtual environment Python interpreter.
+In order to do development on the project easily, you must "register" the project as a development egg in your workspace. We will install testing requirements at the same time. We do so with the following command.
On UNIX
^^^^^^^
.. code-block:: bash
- $ cd tutorial
- $ $VENV/bin/pip install -e .
+ $ $VENV/bin/pip install -e ".[testing]"
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\pyramidtut> cd tutorial
- c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e .
+ c:\tutorial> %VENV%\Scripts\pip install -e ".[testing]"
-The console will show ``pip`` checking for packages and installing missing
-packages. Success executing this command will show a line like the following:
+On all operating systems
+^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block:: bash
+The console will show ``pip`` checking for packages and installing missing packages. Success executing this command will show a line like the following:
- 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:
+.. code-block:: bash
-Install testing requirements
-----------------------------
+ Successfully installed Jinja2-2.8 Mako-1.0.6 MarkupSafe-0.23 \
+ PasteDeploy-1.5.2 Pygments-2.1.3 SQLAlchemy-1.1.4 WebOb-1.6.3 \
+ WebTest-2.0.24 beautifulsoup4-4.5.1 coverage-4.2 py-1.4.32 pyramid-1.7.3 \
+ pyramid-debugtoolbar-3.0.5 pyramid-jinja2-2.7 pyramid-mako-1.0.2 \
+ pyramid-tm-1.1.1 pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 \
+ transaction-2.0.3 translationstring-1.3 tutorial venusian-1.0 \
+ waitress-1.0.1 zope.deprecation-4.2.0 zope.interface-4.3.3 \
+ zope.sqlalchemy-0.7.7
-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.
+Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas.
.. literalinclude:: src/installation/setup.py
:language: python
- :linenos:
- :lineno-start: 22
+ :lineno-match:
: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:: doscon
-
- c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e ".[testing]"
+ :lineno-match:
+ :lines: 46-48
.. _sql_running_tests:
@@ -286,7 +220,7 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q
+ c:\tutorial> %VENV%\Scripts\py.test -q
For a successful test run, you should see output that ends like this:
@@ -301,7 +235,7 @@ Expose test coverage information
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
+:term:`coverage` information, exposing which lines of your project are covered by the
tests.
We've already installed the ``pytest-cov`` package into our virtual
@@ -319,46 +253,45 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov \
- --cov-report=term-missing
+ c:\tutorial> %VENV%\Scripts\py.test --cov --cov-report=term-missing
If successful, you will see output something like this:
.. code-block:: bash
- ======================== 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
-
- 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 2 33% 2-3
- tutorial/scripts/__init__.py 0 0 100%
- tutorial/scripts/initializedb.py 26 16 38% 22-25, 29-45
- tutorial/views/__init__.py 0 0 100%
- tutorial/views/default.py 12 0 100%
- tutorial/views/notfound.py 4 2 50% 6-7
- ----------------------------------------------------------------
- TOTAL 88 26 70%
- ===================== 2 passed in 0.57 seconds ======================
+ ======================== test session starts ========================
+ platform Python 3.6.0, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
+ rootdir: /Users/stevepiercy/tutorial, inifile:
+ plugins: cov-2.4.0
+ collected 2 items
+
+ tutorial/tests.py ..
+ ------------------ coverage: platform Python 3.6.0 ------------------
+ 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 2 33% 2-3
+ tutorial/scripts/__init__.py 0 0 100%
+ tutorial/scripts/initializedb.py 26 16 38% 22-25, 29-45
+ tutorial/views/__init__.py 0 0 100%
+ tutorial/views/default.py 12 0 100%
+ tutorial/views/notfound.py 4 2 50% 6-7
+ ----------------------------------------------------------------
+ TOTAL 88 26 70%
+ ===================== 2 passed in 0.57 seconds ======================
Our package doesn't quite have 100% test coverage.
-.. _test_and_coverage_scaffold_defaults_sql:
+.. _test_and_coverage_cookiecutter_defaults_sql:
-Test and coverage scaffold defaults
------------------------------------
+Test and coverage cookiecutter defaults
+---------------------------------------
-Scaffolds include configuration defaults for ``py.test`` and test coverage.
+Cookiecutters include configuration defaults for ``py.test`` and test coverage.
These configuration files are ``pytest.ini`` and ``.coveragerc``, located at
the root of your package. Without these defaults, we would need to specify the
path to the module on which we want to run tests and coverage.
@@ -375,11 +308,10 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \
- --cov-report=term-missing tutorial\tests.py -q
+ c:\tutorial> %VENV%\Scripts\py.test --cov=tutorial tutorial\tests.py -q
py.test follows :ref:`conventions for Python test discovery
-<pytest:test discovery>`, and the configuration defaults from the scaffold
+<pytest:test discovery>`, and the configuration defaults from the cookiecutter
tell ``py.test`` where to find the module on which we want to run tests and
coverage.
@@ -417,36 +349,36 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\initialize_tutorial_db development.ini
+ c:\tutorial> %VENV%\Scripts\initialize_tutorial_db development.ini
The output to your console should be something like this:
.. code-block:: bash
- 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
- 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] ()
- 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
- 2016-05-22 04:03:28,889 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] ()
- 2016-05-22 04:03:28,890 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models")
- 2016-05-22 04:03:28,890 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ()
- 2016-05-22 04:03:28,892 INFO [sqlalchemy.engine.base.Engine:1097][MainThread]
- CREATE TABLE models (
- id INTEGER NOT NULL,
- name TEXT,
- value INTEGER,
- CONSTRAINT pk_models PRIMARY KEY (id)
- )
-
-
- 2016-05-22 04:03:28,892 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ()
- 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT
- 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name)
- 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ()
- 2016-05-22 04:03:28,894 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT
- 2016-05-22 04:03:28,896 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit)
- 2016-05-22 04:03:28,897 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?)
- 2016-05-22 04:03:28,897 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1)
- 2016-05-22 04:03:28,898 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT
+ 2016-12-18 21:30:08,675 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
+ 2016-12-18 21:30:08,675 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] ()
+ 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
+ 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] ()
+ 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] PRAGMA table_info("models")
+ 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ()
+ 2016-12-18 21:30:08,677 INFO [sqlalchemy.engine.base.Engine:1140][MainThread]
+ CREATE TABLE models (
+ id INTEGER NOT NULL,
+ name TEXT,
+ value INTEGER,
+ CONSTRAINT pk_models PRIMARY KEY (id)
+ )
+
+
+ 2016-12-18 21:30:08,677 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ()
+ 2016-12-18 21:30:08,678 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT
+ 2016-12-18 21:30:08,679 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] CREATE UNIQUE INDEX my_index ON models (name)
+ 2016-12-18 21:30:08,679 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ()
+ 2016-12-18 21:30:08,679 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT
+ 2016-12-18 21:30:08,681 INFO [sqlalchemy.engine.base.Engine:679][MainThread] BEGIN (implicit)
+ 2016-12-18 21:30:08,682 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO models (name, value) VALUES (?, ?)
+ 2016-12-18 21:30:08,682 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('one', 1)
+ 2016-12-18 21:30:08,682 INFO [sqlalchemy.engine.base.Engine:719][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
@@ -457,7 +389,8 @@ working directory. This is an SQLite database with a single table defined in it
Start the application
---------------------
-Start the application.
+Start the application. See :ref:`what_is_this_pserve_thing` for more
+information on ``pserve``.
On UNIX
^^^^^^^
@@ -471,7 +404,7 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload
+ c:\tutorial> %VENV%\Scripts\pserve development.ini --reload
.. note::
@@ -482,9 +415,10 @@ If successful, you will see something like this on your console:
.. code-block:: text
- Starting subprocess with file monitor
- Starting server in PID 82349.
- serving on http://127.0.0.1:6543
+ Starting subprocess with file monitor
+ Starting server in PID 44078.
+ Serving on http://localhost:6543
+ Serving on http://localhost:6543
This means the server is ready to accept requests.
@@ -501,13 +435,15 @@ page. You can read more about the purpose of the icon at
application while you develop.
-Decisions the ``alchemy`` scaffold has made for you
----------------------------------------------------
+Decisions the ``alchemy`` cookiecutter has made for you
+-------------------------------------------------------
-Creating a project using the ``alchemy`` scaffold makes the following
+Creating a project using the ``alchemy`` cookiecutter makes the following
assumptions:
-- You are willing to use :term:`SQLAlchemy` as a database access tool.
+- You are willing to use SQLite for persistent storage, although almost any SQL database could be used with SQLAlchemy.
+
+- You are willing to use :term:`SQLAlchemy` for a database access tool.
- You are willing to use :term:`URL dispatch` to map URLs to code.
diff --git a/docs/tutorials/wiki2/src/authentication/.coveragerc b/docs/tutorials/wiki2/src/authentication/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/authentication/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki2/src/authentication/CHANGES.txt b/docs/tutorials/wiki2/src/authentication/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki2/src/authentication/CHANGES.txt
+++ b/docs/tutorials/wiki2/src/authentication/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki2/src/authentication/MANIFEST.in b/docs/tutorials/wiki2/src/authentication/MANIFEST.in
index 42cd299b5..05cc195d9 100644
--- a/docs/tutorials/wiki2/src/authentication/MANIFEST.in
+++ b/docs/tutorials/wiki2/src/authentication/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/tutorials/wiki2/src/authentication/README.txt b/docs/tutorials/wiki2/src/authentication/README.txt
index 5b0101e5f..81102a869 100644
--- a/docs/tutorials/wiki2/src/authentication/README.txt
+++ b/docs/tutorials/wiki2/src/authentication/README.txt
@@ -1,14 +1,33 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/initialize_tutorial_db development.ini
+- Create a Python virtual environment.
-- $VENV/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Configure the database.
+
+ env/bin/initialize_tutorial_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini
index 4a6c9325c..0786c1f66 100644
--- a/docs/tutorials/wiki2/src/authentication/development.ini
+++ b/docs/tutorials/wiki2/src/authentication/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
@@ -29,12 +28,11 @@ auth.secret = seekrit
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini
index a13a0ca19..05d60feec 100644
--- a/docs/tutorials/wiki2/src/authentication/production.ini
+++ b/docs/tutorials/wiki2/src/authentication/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -16,14 +16,17 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
auth.secret = real-seekrit
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/authentication/pytest.ini b/docs/tutorials/wiki2/src/authentication/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki2/src/authentication/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki2/src/authentication/setup.py b/docs/tutorials/wiki2/src/authentication/setup.py
index def3ce1f6..cc1aa421c 100644
--- a/docs/tutorials/wiki2/src/authentication/setup.py
+++ b/docs/tutorials/wiki2/src/authentication/setup.py
@@ -19,39 +19,42 @@ requires = [
'transaction',
'zope.sqlalchemy',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'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
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ 'console_scripts': [
+ 'initialize_tutorial_db = tutorial.scripts.initializedb:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/tests.py b/docs/tutorials/wiki2/src/authentication/tutorial/tests.py
index 99e95efd3..ce650ca7c 100644
--- a/docs/tutorials/wiki2/src/authentication/tutorial/tests.py
+++ b/docs/tutorials/wiki2/src/authentication/tutorial/tests.py
@@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest):
from .views.default import my_view
info = my_view(dummy_request(self.session))
self.assertEqual(info['one'].name, 'one')
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
class TestMyViewFailureCondition(BaseTest):
diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py
index 1b071434c..2d058d874 100644
--- a/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -32,10 +32,10 @@ def view_page(request):
exists = request.dbsession.query(Page).filter_by(name=word).all()
if exists:
view_url = request.route_url('view_page', pagename=word)
- return '<a href="%s">%s</a>' % (view_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/tutorials/wiki2/src/authorization/.coveragerc b/docs/tutorials/wiki2/src/authorization/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/authorization/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki2/src/authorization/CHANGES.txt b/docs/tutorials/wiki2/src/authorization/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki2/src/authorization/CHANGES.txt
+++ b/docs/tutorials/wiki2/src/authorization/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki2/src/authorization/MANIFEST.in b/docs/tutorials/wiki2/src/authorization/MANIFEST.in
index 42cd299b5..05cc195d9 100644
--- a/docs/tutorials/wiki2/src/authorization/MANIFEST.in
+++ b/docs/tutorials/wiki2/src/authorization/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt
index 5b0101e5f..81102a869 100644
--- a/docs/tutorials/wiki2/src/authorization/README.txt
+++ b/docs/tutorials/wiki2/src/authorization/README.txt
@@ -1,14 +1,33 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/initialize_tutorial_db development.ini
+- Create a Python virtual environment.
-- $VENV/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Configure the database.
+
+ env/bin/initialize_tutorial_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini
index 4a6c9325c..0786c1f66 100644
--- a/docs/tutorials/wiki2/src/authorization/development.ini
+++ b/docs/tutorials/wiki2/src/authorization/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
@@ -29,12 +28,11 @@ auth.secret = seekrit
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini
index a13a0ca19..05d60feec 100644
--- a/docs/tutorials/wiki2/src/authorization/production.ini
+++ b/docs/tutorials/wiki2/src/authorization/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -16,14 +16,17 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
auth.secret = real-seekrit
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/authorization/pytest.ini b/docs/tutorials/wiki2/src/authorization/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki2/src/authorization/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py
index def3ce1f6..cc1aa421c 100644
--- a/docs/tutorials/wiki2/src/authorization/setup.py
+++ b/docs/tutorials/wiki2/src/authorization/setup.py
@@ -19,39 +19,42 @@ requires = [
'transaction',
'zope.sqlalchemy',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'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
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ 'console_scripts': [
+ 'initialize_tutorial_db = tutorial.scripts.initializedb:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py
index 9358993ea..65c12ed3b 100644
--- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -25,10 +25,10 @@ def view_page(request):
exists = request.dbsession.query(Page).filter_by(name=word).all()
if exists:
view_url = request.route_url('view_page', pagename=word)
- return '<a href="%s">%s</a>' % (view_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/tutorials/wiki2/src/basiclayout/.coveragerc b/docs/tutorials/wiki2/src/basiclayout/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/basiclayout/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt b/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt
+++ b/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in
index 42cd299b5..05cc195d9 100644
--- a/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in
+++ b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/tutorials/wiki2/src/basiclayout/README.txt b/docs/tutorials/wiki2/src/basiclayout/README.txt
index 5b0101e5f..81102a869 100644
--- a/docs/tutorials/wiki2/src/basiclayout/README.txt
+++ b/docs/tutorials/wiki2/src/basiclayout/README.txt
@@ -1,14 +1,33 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/initialize_tutorial_db development.ini
+- Create a Python virtual environment.
-- $VENV/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Configure the database.
+
+ env/bin/initialize_tutorial_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini
index 22b733e10..be80882a5 100644
--- a/docs/tutorials/wiki2/src/basiclayout/development.ini
+++ b/docs/tutorials/wiki2/src/basiclayout/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
@@ -27,12 +26,11 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini
index d2ecfe22a..c01ad9a7e 100644
--- a/docs/tutorials/wiki2/src/basiclayout/production.ini
+++ b/docs/tutorials/wiki2/src/basiclayout/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -14,14 +14,17 @@ pyramid.default_locale_name = en
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/basiclayout/pytest.ini b/docs/tutorials/wiki2/src/basiclayout/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki2/src/basiclayout/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py
index ede0a82ef..d3992a8f2 100644
--- a/docs/tutorials/wiki2/src/basiclayout/setup.py
+++ b/docs/tutorials/wiki2/src/basiclayout/setup.py
@@ -17,39 +17,42 @@ requires = [
'transaction',
'zope.sqlalchemy',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'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
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ 'console_scripts': [
+ 'initialize_tutorial_db = tutorial.scripts.initializedb:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py
index 3fc82cfba..5ca037787 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py
@@ -5,7 +5,7 @@ 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 # noqa
+from .mymodel import MyModel # flake8: noqa
# run configure_mappers after defining all of the models to ensure
# all relationships can be setup
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2
index ab8c5ea3d..1f658c834 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2
@@ -8,7 +8,7 @@
<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>
+ <title>Cookiecutter Alchemy project 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">
@@ -29,7 +29,7 @@
<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">
+ <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 %}
@@ -40,10 +40,8 @@
<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-globe icon-muted"></i><a href="https://webchat.freenode.net/?channels=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>
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2
index 6b49869c4..359f55ffa 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2
@@ -2,7 +2,7 @@
{% 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&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">myproj</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
</div>
{% endblock content %}
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py
index 99e95efd3..ce650ca7c 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py
@@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest):
from .views.default import my_view
info = my_view(dummy_request(self.session))
self.assertEqual(info['one'].name, 'one')
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
class TestMyViewFailureCondition(BaseTest):
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py
index ad0c728d7..a404d4154 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py
@@ -13,7 +13,7 @@ def my_view(request):
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'}
+ return {'one': one, 'project': 'myproj'}
db_err_msg = """\
diff --git a/docs/tutorials/wiki2/src/installation/.coveragerc b/docs/tutorials/wiki2/src/installation/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/installation/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki2/src/installation/CHANGES.txt b/docs/tutorials/wiki2/src/installation/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki2/src/installation/CHANGES.txt
+++ b/docs/tutorials/wiki2/src/installation/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki2/src/installation/MANIFEST.in b/docs/tutorials/wiki2/src/installation/MANIFEST.in
index 42cd299b5..05cc195d9 100644
--- a/docs/tutorials/wiki2/src/installation/MANIFEST.in
+++ b/docs/tutorials/wiki2/src/installation/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/tutorials/wiki2/src/installation/README.txt b/docs/tutorials/wiki2/src/installation/README.txt
index 5b0101e5f..81102a869 100644
--- a/docs/tutorials/wiki2/src/installation/README.txt
+++ b/docs/tutorials/wiki2/src/installation/README.txt
@@ -1,14 +1,33 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/initialize_tutorial_db development.ini
+- Create a Python virtual environment.
-- $VENV/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Configure the database.
+
+ env/bin/initialize_tutorial_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini
index 22b733e10..be80882a5 100644
--- a/docs/tutorials/wiki2/src/installation/development.ini
+++ b/docs/tutorials/wiki2/src/installation/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
@@ -27,12 +26,11 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini
index d2ecfe22a..c01ad9a7e 100644
--- a/docs/tutorials/wiki2/src/installation/production.ini
+++ b/docs/tutorials/wiki2/src/installation/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -14,14 +14,17 @@ pyramid.default_locale_name = en
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/installation/pytest.ini b/docs/tutorials/wiki2/src/installation/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki2/src/installation/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki2/src/installation/setup.py b/docs/tutorials/wiki2/src/installation/setup.py
index ede0a82ef..d3992a8f2 100644
--- a/docs/tutorials/wiki2/src/installation/setup.py
+++ b/docs/tutorials/wiki2/src/installation/setup.py
@@ -17,39 +17,42 @@ requires = [
'transaction',
'zope.sqlalchemy',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'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
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ 'console_scripts': [
+ 'initialize_tutorial_db = tutorial.scripts.initializedb:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py
index 3fc82cfba..5ca037787 100644
--- a/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py
+++ b/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py
@@ -5,7 +5,7 @@ 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 # noqa
+from .mymodel import MyModel # flake8: noqa
# run configure_mappers after defining all of the models to ensure
# all relationships can be setup
diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2
index ab8c5ea3d..1f658c834 100644
--- a/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2
+++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2
@@ -8,7 +8,7 @@
<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>
+ <title>Cookiecutter Alchemy project 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">
@@ -29,7 +29,7 @@
<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">
+ <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 %}
@@ -40,10 +40,8 @@
<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-globe icon-muted"></i><a href="https://webchat.freenode.net/?channels=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>
diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2
index 6b49869c4..359f55ffa 100644
--- a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2
+++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2
@@ -2,7 +2,7 @@
{% 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&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">myproj</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
</div>
{% endblock content %}
diff --git a/docs/tutorials/wiki2/src/installation/tutorial/tests.py b/docs/tutorials/wiki2/src/installation/tutorial/tests.py
index 99e95efd3..ce650ca7c 100644
--- a/docs/tutorials/wiki2/src/installation/tutorial/tests.py
+++ b/docs/tutorials/wiki2/src/installation/tutorial/tests.py
@@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest):
from .views.default import my_view
info = my_view(dummy_request(self.session))
self.assertEqual(info['one'].name, 'one')
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
class TestMyViewFailureCondition(BaseTest):
diff --git a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py
index ad0c728d7..a404d4154 100644
--- a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py
@@ -13,7 +13,7 @@ def my_view(request):
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'}
+ return {'one': one, 'project': 'myproj'}
db_err_msg = """\
diff --git a/docs/tutorials/wiki2/src/models/.coveragerc b/docs/tutorials/wiki2/src/models/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/models/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki2/src/models/CHANGES.txt b/docs/tutorials/wiki2/src/models/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki2/src/models/CHANGES.txt
+++ b/docs/tutorials/wiki2/src/models/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki2/src/models/MANIFEST.in b/docs/tutorials/wiki2/src/models/MANIFEST.in
index 42cd299b5..05cc195d9 100644
--- a/docs/tutorials/wiki2/src/models/MANIFEST.in
+++ b/docs/tutorials/wiki2/src/models/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/tutorials/wiki2/src/models/README.txt b/docs/tutorials/wiki2/src/models/README.txt
index 5b0101e5f..81102a869 100644
--- a/docs/tutorials/wiki2/src/models/README.txt
+++ b/docs/tutorials/wiki2/src/models/README.txt
@@ -1,14 +1,33 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/initialize_tutorial_db development.ini
+- Create a Python virtual environment.
-- $VENV/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Configure the database.
+
+ env/bin/initialize_tutorial_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini
index 22b733e10..be80882a5 100644
--- a/docs/tutorials/wiki2/src/models/development.ini
+++ b/docs/tutorials/wiki2/src/models/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
@@ -27,12 +26,11 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini
index d2ecfe22a..c01ad9a7e 100644
--- a/docs/tutorials/wiki2/src/models/production.ini
+++ b/docs/tutorials/wiki2/src/models/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -14,14 +14,17 @@ pyramid.default_locale_name = en
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/models/pytest.ini b/docs/tutorials/wiki2/src/models/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki2/src/models/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py
index 742a7c59c..faf76aa27 100644
--- a/docs/tutorials/wiki2/src/models/setup.py
+++ b/docs/tutorials/wiki2/src/models/setup.py
@@ -18,39 +18,42 @@ requires = [
'transaction',
'zope.sqlalchemy',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'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
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ 'console_scripts': [
+ 'initialize_tutorial_db = tutorial.scripts.initializedb:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2
index ab8c5ea3d..1f658c834 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2
+++ b/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2
@@ -8,7 +8,7 @@
<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>
+ <title>Cookiecutter Alchemy project 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">
@@ -29,7 +29,7 @@
<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">
+ <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 %}
@@ -40,10 +40,8 @@
<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-globe icon-muted"></i><a href="https://webchat.freenode.net/?channels=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>
diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2
index 6b49869c4..359f55ffa 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2
+++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2
@@ -2,7 +2,7 @@
{% 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&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">myproj</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
</div>
{% endblock content %}
diff --git a/docs/tutorials/wiki2/src/models/tutorial/tests.py b/docs/tutorials/wiki2/src/models/tutorial/tests.py
index 99e95efd3..ce650ca7c 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/tests.py
+++ b/docs/tutorials/wiki2/src/models/tutorial/tests.py
@@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest):
from .views.default import my_view
info = my_view(dummy_request(self.session))
self.assertEqual(info['one'].name, 'one')
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
class TestMyViewFailureCondition(BaseTest):
diff --git a/docs/tutorials/wiki2/src/models/tutorial/views/default.py b/docs/tutorials/wiki2/src/models/tutorial/views/default.py
index ad0c728d7..a404d4154 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/models/tutorial/views/default.py
@@ -13,7 +13,7 @@ def my_view(request):
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'}
+ return {'one': one, 'project': 'myproj'}
db_err_msg = """\
diff --git a/docs/tutorials/wiki2/src/tests/.coveragerc b/docs/tutorials/wiki2/src/tests/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/tests/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki2/src/tests/CHANGES.txt b/docs/tutorials/wiki2/src/tests/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki2/src/tests/CHANGES.txt
+++ b/docs/tutorials/wiki2/src/tests/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki2/src/tests/MANIFEST.in b/docs/tutorials/wiki2/src/tests/MANIFEST.in
index 42cd299b5..05cc195d9 100644
--- a/docs/tutorials/wiki2/src/tests/MANIFEST.in
+++ b/docs/tutorials/wiki2/src/tests/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/tutorials/wiki2/src/tests/README.txt b/docs/tutorials/wiki2/src/tests/README.txt
index 5b0101e5f..81102a869 100644
--- a/docs/tutorials/wiki2/src/tests/README.txt
+++ b/docs/tutorials/wiki2/src/tests/README.txt
@@ -1,14 +1,33 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/initialize_tutorial_db development.ini
+- Create a Python virtual environment.
-- $VENV/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Configure the database.
+
+ env/bin/initialize_tutorial_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini
index 4a6c9325c..0786c1f66 100644
--- a/docs/tutorials/wiki2/src/tests/development.ini
+++ b/docs/tutorials/wiki2/src/tests/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
@@ -29,12 +28,11 @@ auth.secret = seekrit
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini
index a13a0ca19..05d60feec 100644
--- a/docs/tutorials/wiki2/src/tests/production.ini
+++ b/docs/tutorials/wiki2/src/tests/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -16,14 +16,17 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
auth.secret = real-seekrit
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/tests/pytest.ini b/docs/tutorials/wiki2/src/tests/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki2/src/tests/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki2/src/tests/setup.py b/docs/tutorials/wiki2/src/tests/setup.py
index def3ce1f6..cc1aa421c 100644
--- a/docs/tutorials/wiki2/src/tests/setup.py
+++ b/docs/tutorials/wiki2/src/tests/setup.py
@@ -19,39 +19,42 @@ requires = [
'transaction',
'zope.sqlalchemy',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'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
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ 'console_scripts': [
+ 'initialize_tutorial_db = tutorial.scripts.initializedb:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py
index f3c0a6fef..c860ef8cf 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py
@@ -28,6 +28,7 @@ def usage(argv):
def main(argv=sys.argv):
if len(argv) < 2:
usage(argv)
+ return
config_uri = argv[1]
options = parse_vars(argv[2:])
setup_logging(config_uri)
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py
index 715768b2e..0250e71c9 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py
@@ -11,6 +11,9 @@ class FunctionalTests(unittest.TestCase):
basic_wrong_login = (
'/login?login=basic&password=incorrect'
'&next=FrontPage&form.submitted=Login')
+ basic_login_no_next = (
+ '/login?login=basic&password=basic'
+ '&form.submitted=Login')
editor_login = (
'/login?login=editor&password=editor'
'&next=FrontPage&form.submitted=Login')
@@ -68,6 +71,10 @@ class FunctionalTests(unittest.TestCase):
res = self.testapp.get(self.basic_login, status=302)
self.assertEqual(res.location, 'http://localhost/FrontPage')
+ def test_successful_log_in_no_next(self):
+ res = self.testapp.get(self.basic_login_no_next, status=302)
+ self.assertEqual(res.location, 'http://localhost/')
+
def test_failed_log_in(self):
res = self.testapp.get(self.basic_wrong_login, status=200)
self.assertTrue(b'login' in res.body)
@@ -120,3 +127,8 @@ class FunctionalTests(unittest.TestCase):
self.testapp.get(self.editor_login, status=302)
res = self.testapp.get('/FrontPage', status=200)
self.assertTrue(b'FrontPage' in res.body)
+
+ def test_redirect_to_edit_for_existing_page(self):
+ self.testapp.get(self.editor_login, status=302)
+ res = self.testapp.get('/add_page/FrontPage', status=302)
+ self.assertTrue(b'FrontPage' in res.body)
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py
new file mode 100644
index 000000000..f5273456e
--- /dev/null
+++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py
@@ -0,0 +1,16 @@
+import os
+import unittest
+
+
+class TestInitializeDB(unittest.TestCase):
+
+ def test_usage(self):
+ from ..scripts.initializedb import main
+ with self.assertRaises(SystemExit):
+ main(argv=['foo'])
+
+ def test_run(self):
+ from ..scripts.initializedb import main
+ main(argv=['foo', 'development.ini'])
+ self.assertTrue(os.path.exists('tutorial.sqlite'))
+ os.remove('tutorial.sqlite')
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py
new file mode 100644
index 000000000..cbec6420d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py
@@ -0,0 +1,23 @@
+import unittest
+from pyramid.testing import DummyRequest
+
+
+class TestMyAuthenticationPolicy(unittest.TestCase):
+
+ def test_no_user(self):
+ request = DummyRequest()
+ request.user = None
+
+ from ..security import MyAuthenticationPolicy
+ policy = MyAuthenticationPolicy(None)
+ self.assertEqual(policy.authenticated_userid(request), None)
+
+ def test_authenticated_user(self):
+ from ..models import User
+ request = DummyRequest()
+ request.user = User()
+ request.user.id = 'foo'
+
+ from ..security import MyAuthenticationPolicy
+ policy = MyAuthenticationPolicy(None)
+ self.assertEqual(policy.authenticated_userid(request), 'foo')
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py
new file mode 100644
index 000000000..9490ac990
--- /dev/null
+++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py
@@ -0,0 +1,67 @@
+import unittest
+import transaction
+
+from pyramid import testing
+
+
+class BaseTest(unittest.TestCase):
+
+ def setUp(self):
+ from ..models import get_tm_session
+ self.config = testing.setUp(settings={
+ 'sqlalchemy.url': 'sqlite:///:memory:'
+ })
+ self.config.include('..models')
+ self.config.include('..routes')
+
+ session_factory = self.config.registry['dbsession_factory']
+ self.session = get_tm_session(session_factory, transaction.manager)
+
+ self.init_database()
+
+ def init_database(self):
+ from ..models.meta import Base
+ session_factory = self.config.registry['dbsession_factory']
+ engine = session_factory.kw['bind']
+ Base.metadata.create_all(engine)
+
+ def tearDown(self):
+ testing.tearDown()
+ transaction.abort()
+
+ def makeUser(self, name, role):
+ from ..models import User
+ return User(name=name, role=role)
+
+
+class TestSetPassword(BaseTest):
+
+ def test_password_hash_saved(self):
+ user = self.makeUser(name='foo', role='bar')
+ self.assertFalse(user.password_hash)
+
+ user.set_password('secret')
+ self.assertTrue(user.password_hash)
+
+
+class TestCheckPassword(BaseTest):
+
+ def test_password_hash_not_set(self):
+ user = self.makeUser(name='foo', role='bar')
+ self.assertFalse(user.password_hash)
+
+ self.assertFalse(user.check_password('secret'))
+
+ def test_correct_password(self):
+ user = self.makeUser(name='foo', role='bar')
+ user.set_password('secret')
+ self.assertTrue(user.password_hash)
+
+ self.assertTrue(user.check_password('secret'))
+
+ def test_incorrect_password(self):
+ user = self.makeUser(name='foo', role='bar')
+ user.set_password('secret')
+ self.assertTrue(user.password_hash)
+
+ self.assertFalse(user.check_password('incorrect'))
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views/default.py b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py
index 9358993ea..65c12ed3b 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -25,10 +25,10 @@ def view_page(request):
exists = request.dbsession.query(Page).filter_by(name=word).all()
if exists:
view_url = request.route_url('view_page', pagename=word)
- return '<a href="%s">%s</a>' % (view_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/tutorials/wiki2/src/views/.coveragerc b/docs/tutorials/wiki2/src/views/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki2/src/views/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki2/src/views/CHANGES.txt b/docs/tutorials/wiki2/src/views/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki2/src/views/CHANGES.txt
+++ b/docs/tutorials/wiki2/src/views/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki2/src/views/MANIFEST.in b/docs/tutorials/wiki2/src/views/MANIFEST.in
index 42cd299b5..05cc195d9 100644
--- a/docs/tutorials/wiki2/src/views/MANIFEST.in
+++ b/docs/tutorials/wiki2/src/views/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/tutorials/wiki2/src/views/README.txt b/docs/tutorials/wiki2/src/views/README.txt
index 5b0101e5f..81102a869 100644
--- a/docs/tutorials/wiki2/src/views/README.txt
+++ b/docs/tutorials/wiki2/src/views/README.txt
@@ -1,14 +1,33 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/initialize_tutorial_db development.ini
+- Create a Python virtual environment.
-- $VENV/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Configure the database.
+
+ env/bin/initialize_tutorial_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini
index 22b733e10..be80882a5 100644
--- a/docs/tutorials/wiki2/src/views/development.ini
+++ b/docs/tutorials/wiki2/src/views/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
@@ -27,12 +26,11 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini
index d2ecfe22a..c01ad9a7e 100644
--- a/docs/tutorials/wiki2/src/views/production.ini
+++ b/docs/tutorials/wiki2/src/views/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -14,14 +14,17 @@ pyramid.default_locale_name = en
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki2/src/views/pytest.ini b/docs/tutorials/wiki2/src/views/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki2/src/views/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki2/src/views/setup.py b/docs/tutorials/wiki2/src/views/setup.py
index def3ce1f6..cc1aa421c 100644
--- a/docs/tutorials/wiki2/src/views/setup.py
+++ b/docs/tutorials/wiki2/src/views/setup.py
@@ -19,39 +19,42 @@ requires = [
'transaction',
'zope.sqlalchemy',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'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
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ 'console_scripts': [
+ 'initialize_tutorial_db = tutorial.scripts.initializedb:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2
index 71785157f..7575de8a7 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2
+++ b/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2
@@ -29,7 +29,7 @@
<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">
+ <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">
diff --git a/docs/tutorials/wiki2/src/views/tutorial/tests.py b/docs/tutorials/wiki2/src/views/tutorial/tests.py
index 99e95efd3..ce650ca7c 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/tests.py
+++ b/docs/tutorials/wiki2/src/views/tutorial/tests.py
@@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest):
from .views.default import my_view
info = my_view(dummy_request(self.session))
self.assertEqual(info['one'].name, 'one')
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
class TestMyViewFailureCondition(BaseTest):
diff --git a/docs/tutorials/wiki2/src/views/tutorial/views/default.py b/docs/tutorials/wiki2/src/views/tutorial/views/default.py
index bb6300b75..3b95e0f59 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/views/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -31,10 +31,10 @@ def view_page(request):
exists = request.dbsession.query(Page).filter_by(name=word).all()
if exists:
view_url = request.route_url('view_page', pagename=word)
- return '<a href="%s">%s</a>' % (view_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst
index e923ff9cb..e1f83a755 100644
--- a/docs/tutorials/wiki2/tests.rst
+++ b/docs/tutorials/wiki2/tests.rst
@@ -8,7 +8,7 @@ We will now add tests for the models and views as well as a few functional
tests in a new ``tests`` subpackage. Tests ensure that an application works,
and that it continues to work when changes are made in the future.
-The file ``tests.py`` was generated as part of the ``alchemy`` scaffold, but it
+The file ``tests.py`` was generated as part of the ``alchemy`` cookiecutter, but it
is a common practice to put tests into a ``tests`` subpackage, especially as
projects grow in size and complexity. Each module in the test subpackage
should contain tests for its corresponding module in our application. Each
@@ -50,20 +50,36 @@ so on.
View the results of all our edits to ``tests`` subpackage
=========================================================
-Open ``tutorial/tests/test_views.py``, and edit it such that it appears as
-follows:
+Create ``tutorial/tests/test_views.py`` such that it appears as follows:
.. literalinclude:: src/tests/tutorial/tests/test_views.py
:linenos:
:language: python
-Open ``tutorial/tests/test_functional.py``, and edit it such that it appears as
-follows:
+Create ``tutorial/tests/test_functional.py`` such that it appears as follows:
.. literalinclude:: src/tests/tutorial/tests/test_functional.py
:linenos:
:language: python
+Create ``tutorial/tests/test_initdb.py`` such that it appears as follows:
+
+.. literalinclude:: src/tests/tutorial/tests/test_initdb.py
+ :linenos:
+ :language: python
+
+Create ``tutorial/tests/test_security.py`` such that it appears as follows:
+
+.. literalinclude:: src/tests/tutorial/tests/test_security.py
+ :linenos:
+ :language: python
+
+Create ``tutorial/tests/test_user_model.py`` such that it appears as follows:
+
+.. literalinclude:: src/tests/tutorial/tests/test_user_model.py
+ :linenos:
+ :language: python
+
.. note::
@@ -77,32 +93,27 @@ follows:
Running the tests
=================
-We can run these tests similarly to how we did in :ref:`running_tests`:
+We can run these tests similarly to how we did in :ref:`running_tests`, but first delete the SQLite database ``tutorial.sqlite``. If you do not delete the database, then you will see an integrity error when running the tests.
On UNIX:
.. code-block:: bash
+ $ rm tutorial.sqlite
$ $VENV/bin/py.test -q
On Windows:
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q
+ c:\tutorial> del tutorial.sqlite
+ c:\tutorial> %VENV%\Scripts\py.test -q
The expected result should look like the following:
.. code-block:: text
- ......................
- 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
- tutorial run on both Python 2 and 3, the authors prioritized simplicity and
- focus for the learner over accommodating warnings. In your own app or as
- extra credit, you may choose to either drop Python 2 support or hack your
- code to work without warnings on both Python 2 and 3.
+ ................................
+ 32 passed in 9.90 seconds
.. _webtest: http://docs.pylonsproject.org/projects/webtest/en/latest/