diff options
| author | Steve Piercy <web@stevepiercy.com> | 2018-06-30 05:18:05 -0700 |
|---|---|---|
| committer | Steve Piercy <web@stevepiercy.com> | 2018-06-30 05:18:05 -0700 |
| commit | f63c10ee0eed7cbcb59c68535cbccf2fa88d41e0 (patch) | |
| tree | 5954f7288611584f7c4b3f85c86fffcbeee4f103 /docs/tutorials | |
| parent | 0d08c32d4ae73d57f1695e97b3c8605ccfa06ebc (diff) | |
| download | pyramid-f63c10ee0eed7cbcb59c68535cbccf2fa88d41e0.tar.gz pyramid-f63c10ee0eed7cbcb59c68535cbccf2fa88d41e0.tar.bz2 pyramid-f63c10ee0eed7cbcb59c68535cbccf2fa88d41e0.zip | |
Synch up source files for authentication step
Diffstat (limited to 'docs/tutorials')
14 files changed, 197 insertions, 71 deletions
diff --git a/docs/tutorials/wiki2/src/authentication/.gitignore b/docs/tutorials/wiki2/src/authentication/.gitignore new file mode 100644 index 000000000..1853d983c --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/.gitignore @@ -0,0 +1,21 @@ +*.egg +*.egg-info +*.pyc +*$py.class +*~ +.coverage +coverage.xml +build/ +dist/ +.tox/ +nosetests.xml +env*/ +tmp/ +Data.fs* +*.sublime-project +*.sublime-workspace +.*.sw? +.sw? +.DS_Store +coverage +test diff --git a/docs/tutorials/wiki2/src/authentication/README.txt b/docs/tutorials/wiki2/src/authentication/README.txt index 7b33da610..5d5133e34 100644 --- a/docs/tutorials/wiki2/src/authentication/README.txt +++ b/docs/tutorials/wiki2/src/authentication/README.txt @@ -20,7 +20,17 @@ Getting Started env/bin/pip install -e ".[testing]" -- Configure the database. +- Initialize and upgrade the database using Alembic. + + - Generate your first revision. + + env/bin/alembic -c development.ini revision --autogenerate -m "init" + + - Upgrade to that revision. + + env/bin/alembic -c development.ini upgrade head + +- Load default data into the database using a script. env/bin/initialize_tutorial_db development.ini diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index cc2a5586e..d76a6cd72 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -28,6 +28,12 @@ auth.secret = seekrit # wsgi server configuration ### +[alembic] +# path to migration scripts +script_location = tutorial/alembic +file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s +# file_template = %%(rev)s_%%(slug)s + [server:main] use = egg:waitress#main listen = localhost:6543 diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index 759807abf..c46adb7b5 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -22,6 +22,12 @@ auth.secret = real-seekrit # wsgi server configuration ### +[alembic] +# path to migration scripts +script_location = tutorial/alembic +file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s +# file_template = %%(rev)s_%%(slug)s + [server:main] use = egg:waitress#main listen = *:6543 diff --git a/docs/tutorials/wiki2/src/authentication/pytest.ini b/docs/tutorials/wiki2/src/authentication/pytest.ini index 8b76bc410..a3489cdf8 100644 --- a/docs/tutorials/wiki2/src/authentication/pytest.ini +++ b/docs/tutorials/wiki2/src/authentication/pytest.ini @@ -1,3 +1,3 @@ [pytest] testpaths = tutorial -python_files = *.py +python_files = test*.py diff --git a/docs/tutorials/wiki2/src/authentication/setup.py b/docs/tutorials/wiki2/src/authentication/setup.py index abc24876d..28b766cbe 100644 --- a/docs/tutorials/wiki2/src/authentication/setup.py +++ b/docs/tutorials/wiki2/src/authentication/setup.py @@ -9,10 +9,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ + 'alembic', 'bcrypt', 'docutils', 'plaster_pastedeploy', - 'pyramid >= 1.9a', + 'pyramid >= 1.9', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', @@ -56,7 +57,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/alembic/env.py b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/env.py new file mode 100644 index 000000000..ba116d0f3 --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/env.py @@ -0,0 +1,58 @@ +"""Pyramid bootstrap environment. """ +from alembic import context +from pyramid.paster import get_appsettings, setup_logging +from sqlalchemy import engine_from_config + +from tutorial.models.meta import Base + +config = context.config + +setup_logging(config.config_file_name) + +settings = get_appsettings(config.config_file_name) +target_metadata = Base.metadata + + +def run_migrations_offline(): + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + context.configure(url=settings['sqlalchemy.url']) + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online(): + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + engine = engine_from_config(settings, prefix='sqlalchemy.') + + connection = engine.connect() + context.configure( + connection=connection, + target_metadata=target_metadata + ) + + try: + with context.begin_transaction(): + context.run_migrations() + finally: + connection.close() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/script.py.mako new file mode 100644 index 000000000..2c0156303 --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/script.py.mako @@ -0,0 +1,24 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} +branch_labels = ${repr(branch_labels)} +depends_on = ${repr(depends_on)} + + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/versions/README.txt new file mode 100644 index 000000000..09ed32c8d --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/versions/README.txt @@ -0,0 +1 @@ +Placeholder for alembic versions
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py index 3c9ba8e54..a4209a6e9 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # noqa -from .user import User # noqa +from .page import Page # flake8: noqa +from .user import User # 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/authentication/tutorial/scripts/initialize_db.py b/docs/tutorials/wiki2/src/authentication/tutorial/scripts/initialize_db.py new file mode 100644 index 000000000..231d5d44b --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/tutorial/scripts/initialize_db.py @@ -0,0 +1,56 @@ +import os +import sys + +from pyramid.paster import bootstrap, setup_logging +from sqlalchemy.exc import OperationalError + +from .. import models + + +def setup_models(dbsession): + editor = models.User(name='editor', role='editor') + editor.set_password('editor') + dbsession.add(editor) + + basic = models.User(name='basic', role='basic') + basic.set_password('basic') + dbsession.add(basic) + + page = models.Page( + name='FrontPage', + creator=editor, + data='This is the front page', + ) + dbsession.add(page) + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s <config_uri>\n' + '(example: "%s development.ini")' % (cmd, cmd)) + sys.exit(1) + + +def main(argv=sys.argv): + if len(argv) != 2: + usage(argv) + config_uri = argv[1] + setup_logging(config_uri) + env = bootstrap(config_uri) + + try: + with env['request'].tm: + dbsession = env['request'].dbsession + setup_models(dbsession) + except OperationalError: + print(''' +Pyramid is having a problem using your SQL database. The problem +might be caused by one of the following things: + +1. You may need to initialize your database tables with `alembic`. + Check your README.txt for description and try to run it. + +2. Your database server may not be running. Check that the + database server referred to by the "sqlalchemy.url" setting in + your "development.ini" file is running. + ''') diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/authentication/tutorial/scripts/initializedb.py deleted file mode 100644 index f3c0a6fef..000000000 --- a/docs/tutorials/wiki2/src/authentication/tutorial/scripts/initializedb.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys -import transaction - -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) - -from pyramid.scripts.common import parse_vars - -from ..models.meta import Base -from ..models import ( - get_engine, - get_session_factory, - get_tm_session, - ) -from ..models import Page, User - - -def usage(argv): - cmd = os.path.basename(argv[0]) - print('usage: %s <config_uri> [var=value]\n' - '(example: "%s development.ini")' % (cmd, cmd)) - sys.exit(1) - - -def main(argv=sys.argv): - if len(argv) < 2: - usage(argv) - config_uri = argv[1] - options = parse_vars(argv[2:]) - setup_logging(config_uri) - settings = get_appsettings(config_uri, options=options) - - engine = get_engine(settings) - Base.metadata.create_all(engine) - - session_factory = get_session_factory(engine) - - with transaction.manager: - dbsession = get_tm_session(session_factory, transaction.manager) - - editor = User(name='editor', role='editor') - editor.set_password('editor') - dbsession.add(editor) - - basic = User(name='basic', role='basic') - basic.set_password('basic') - dbsession.add(basic) - - page = Page( - name='FrontPage', - creator=editor, - data='This is the front page', - ) - dbsession.add(page) diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/authentication/tutorial/templates/layout.jinja2 index 9b2dc82fc..4016b26c9 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/authentication/tutorial/templates/layout.jinja2 @@ -16,7 +16,7 @@ <!-- Custom styles for this scaffold --> <link href="{{request.static_url('tutorial:static/theme.css')}}" rel="stylesheet"> - <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!-- HTML5 shiv and Respond.js IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js" integrity="sha384-0s5Pv64cNZJieYFkXYOTId2HMA2Lfb6q2nAcx2n0RTLUnCAoTTsS0nKEO27XyKcY" crossorigin="anonymous"></script> <script src="//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js" integrity="sha384-ZoaMbDF+4LeFxg6WdScQ9nnR1QC2MIRxA1O9KWEXQwns1G8UNyIEZIQidzb0T1fo" crossorigin="anonymous"></script> @@ -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/authentication/tutorial/views/default.py b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py index 2d058d874..8ed90d5b2 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py @@ -10,7 +10,7 @@ from pyramid.httpexceptions import ( from pyramid.view import view_config -from ..models import Page +from .. import models # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") @@ -23,13 +23,13 @@ def view_wiki(request): @view_config(route_name='view_page', renderer='../templates/view.jinja2') def view_page(request): pagename = request.matchdict['pagename'] - page = request.dbsession.query(Page).filter_by(name=pagename).first() + page = request.dbsession.query(models.Page).filter_by(name=pagename).first() if page is None: raise HTTPNotFound('No such page') def add_link(match): word = match.group(1) - exists = request.dbsession.query(Page).filter_by(name=word).all() + exists = request.dbsession.query(models.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, escape(word)) @@ -45,7 +45,7 @@ def view_page(request): @view_config(route_name='edit_page', renderer='../templates/edit.jinja2') def edit_page(request): pagename = request.matchdict['pagename'] - page = request.dbsession.query(Page).filter_by(name=pagename).one() + page = request.dbsession.query(models.Page).filter_by(name=pagename).one() user = request.user if user is None or (user.role != 'editor' and page.creator != user): raise HTTPForbidden @@ -65,12 +65,12 @@ def add_page(request): if user is None or user.role not in ('editor', 'basic'): raise HTTPForbidden pagename = request.matchdict['pagename'] - if request.dbsession.query(Page).filter_by(name=pagename).count() > 0: + if request.dbsession.query(models.Page).filter_by(name=pagename).count() > 0: next_url = request.route_url('edit_page', pagename=pagename) return HTTPFound(location=next_url) if 'form.submitted' in request.params: body = request.params['body'] - page = Page(name=pagename, data=body) + page = models.Page(name=pagename, data=body) page.creator = request.user request.dbsession.add(page) next_url = request.route_url('view_page', pagename=pagename) |
