summaryrefslogtreecommitdiff
path: root/pyramid/scaffolds
diff options
context:
space:
mode:
Diffstat (limited to 'pyramid/scaffolds')
-rw-r--r--pyramid/scaffolds/__init__.py16
-rw-r--r--pyramid/scaffolds/alchemy/+dot+coveragerc_tmpl3
-rw-r--r--pyramid/scaffolds/alchemy/+package+/__init__.py15
-rw-r--r--pyramid/scaffolds/alchemy/+package+/models.py27
-rw-r--r--pyramid/scaffolds/alchemy/+package+/models/__init__.py_tmpl73
-rw-r--r--pyramid/scaffolds/alchemy/+package+/models/meta.py16
-rw-r--r--pyramid/scaffolds/alchemy/+package+/models/mymodel.py18
-rw-r--r--pyramid/scaffolds/alchemy/+package+/routes.py3
-rw-r--r--pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py21
-rw-r--r--pyramid/scaffolds/alchemy/+package+/static/theme.min.css1
-rw-r--r--pyramid/scaffolds/alchemy/+package+/templates/404.jinja2_tmpl8
-rw-r--r--pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl (renamed from pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl)15
-rw-r--r--pyramid/scaffolds/alchemy/+package+/templates/mytemplate.jinja2_tmpl8
-rw-r--r--pyramid/scaffolds/alchemy/+package+/tests.py_tmpl78
-rw-r--r--pyramid/scaffolds/alchemy/+package+/views/__init__.py0
-rw-r--r--pyramid/scaffolds/alchemy/+package+/views/default.py_tmpl (renamed from pyramid/scaffolds/alchemy/+package+/views.py_tmpl)15
-rw-r--r--pyramid/scaffolds/alchemy/+package+/views/notfound.py_tmpl7
-rw-r--r--pyramid/scaffolds/alchemy/MANIFEST.in_tmpl2
-rw-r--r--pyramid/scaffolds/alchemy/README.txt_tmpl2
-rw-r--r--pyramid/scaffolds/alchemy/development.ini_tmpl1
-rw-r--r--pyramid/scaffolds/alchemy/production.ini_tmpl2
-rw-r--r--pyramid/scaffolds/alchemy/pytest.ini_tmpl3
-rw-r--r--pyramid/scaffolds/alchemy/setup.py_tmpl22
-rw-r--r--pyramid/scaffolds/starter/+dot+coveragerc_tmpl3
-rw-r--r--pyramid/scaffolds/starter/+package+/static/theme.min.css1
-rw-r--r--pyramid/scaffolds/starter/+package+/tests.py_tmpl12
-rw-r--r--pyramid/scaffolds/starter/README.txt_tmpl11
-rw-r--r--pyramid/scaffolds/starter/pytest.ini_tmpl3
-rw-r--r--pyramid/scaffolds/starter/setup.py_tmpl21
-rw-r--r--pyramid/scaffolds/tests.py11
-rw-r--r--pyramid/scaffolds/zodb/+dot+coveragerc_tmpl3
-rw-r--r--pyramid/scaffolds/zodb/+package+/static/theme.css8
-rw-r--r--pyramid/scaffolds/zodb/+package+/static/theme.min.css1
-rw-r--r--pyramid/scaffolds/zodb/README.txt_tmpl11
-rw-r--r--pyramid/scaffolds/zodb/pytest.ini_tmpl3
-rw-r--r--pyramid/scaffolds/zodb/setup.py_tmpl21
36 files changed, 321 insertions, 144 deletions
diff --git a/pyramid/scaffolds/__init__.py b/pyramid/scaffolds/__init__.py
index 4e811a42b..62c3eeecc 100644
--- a/pyramid/scaffolds/__init__.py
+++ b/pyramid/scaffolds/__init__.py
@@ -35,11 +35,10 @@ class PyramidTemplate(Template):
msg = dedent(
"""
%(separator)s
- Tutorials: http://docs.pylonsproject.org/projects/pyramid_tutorials
- Documentation: http://docs.pylonsproject.org/projects/pyramid
-
- Twitter (tips & updates): http://twitter.com/pylons
- Mailing List: http://groups.google.com/group/pylons-discuss
+ Tutorials: http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/
+ Documentation: http://docs.pylonsproject.org/projects/pyramid/en/latest/
+ Twitter: https://twitter.com/trypyramid
+ Mailing List: https://groups.google.com/forum/#!forum/pylons-discuss
Welcome to Pyramid. Sorry for the convenience.
%(separator)s
@@ -53,12 +52,13 @@ class PyramidTemplate(Template):
class StarterProjectTemplate(PyramidTemplate):
_template_dir = 'starter'
- summary = 'Pyramid starter project'
+ summary = 'Pyramid starter project using URL dispatch and Chameleon'
class ZODBProjectTemplate(PyramidTemplate):
_template_dir = 'zodb'
- summary = 'Pyramid ZODB project using traversal'
+ summary = 'Pyramid project using ZODB, traversal, and Chameleon'
class AlchemyProjectTemplate(PyramidTemplate):
_template_dir = 'alchemy'
- summary = 'Pyramid SQLAlchemy project using url dispatch'
+ summary = 'Pyramid project using SQLAlchemy, SQLite, URL dispatch, and'
+ ' Chameleon'
diff --git a/pyramid/scaffolds/alchemy/+dot+coveragerc_tmpl b/pyramid/scaffolds/alchemy/+dot+coveragerc_tmpl
new file mode 100644
index 000000000..273a4a580
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+dot+coveragerc_tmpl
@@ -0,0 +1,3 @@
+[run]
+source = {{package}}
+omit = {{package}}/test*
diff --git a/pyramid/scaffolds/alchemy/+package+/__init__.py b/pyramid/scaffolds/alchemy/+package+/__init__.py
index 867049e4f..4dab44823 100644
--- a/pyramid/scaffolds/alchemy/+package+/__init__.py
+++ b/pyramid/scaffolds/alchemy/+package+/__init__.py
@@ -1,21 +1,12 @@
from pyramid.config import Configurator
-from sqlalchemy import engine_from_config
-
-from .models import (
- DBSession,
- Base,
- )
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
- engine = engine_from_config(settings, 'sqlalchemy.')
- DBSession.configure(bind=engine)
- Base.metadata.bind = engine
config = Configurator(settings=settings)
- config.include('pyramid_chameleon')
- config.add_static_view('static', 'static', cache_max_age=3600)
- config.add_route('home', '/')
+ config.include('pyramid_jinja2')
+ config.include('.models')
+ config.include('.routes')
config.scan()
return config.make_wsgi_app()
diff --git a/pyramid/scaffolds/alchemy/+package+/models.py b/pyramid/scaffolds/alchemy/+package+/models.py
deleted file mode 100644
index a0d3e7b71..000000000
--- a/pyramid/scaffolds/alchemy/+package+/models.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from sqlalchemy import (
- Column,
- Index,
- Integer,
- Text,
- )
-
-from sqlalchemy.ext.declarative import declarative_base
-
-from sqlalchemy.orm import (
- scoped_session,
- sessionmaker,
- )
-
-from zope.sqlalchemy import ZopeTransactionExtension
-
-DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
-Base = declarative_base()
-
-
-class MyModel(Base):
- __tablename__ = 'models'
- id = Column(Integer, primary_key=True)
- name = Column(Text)
- value = Column(Integer)
-
-Index('my_index', MyModel.name, unique=True, mysql_length=255)
diff --git a/pyramid/scaffolds/alchemy/+package+/models/__init__.py_tmpl b/pyramid/scaffolds/alchemy/+package+/models/__init__.py_tmpl
new file mode 100644
index 000000000..f626d1ef0
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/models/__init__.py_tmpl
@@ -0,0 +1,73 @@
+from sqlalchemy import engine_from_config
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy.orm import configure_mappers
+import zope.sqlalchemy
+
+# import or define all models here to ensure they are attached to the
+# Base.metadata prior to any initialization routines
+from .mymodel import MyModel # noqa
+
+# run configure_mappers after defining all of the models to ensure
+# all relationships can be setup
+configure_mappers()
+
+
+def get_engine(settings, prefix='sqlalchemy.'):
+ return engine_from_config(settings, prefix)
+
+
+def get_session_factory(engine):
+ factory = sessionmaker()
+ factory.configure(bind=engine)
+ return factory
+
+
+def get_tm_session(session_factory, transaction_manager):
+ """
+ Get a ``sqlalchemy.orm.Session`` instance backed by a transaction.
+
+ This function will hook the session to the transaction manager which
+ will take care of committing any changes.
+
+ - When using pyramid_tm it will automatically be committed or aborted
+ depending on whether an exception is raised.
+
+ - When using scripts you should wrap the session in a manager yourself.
+ For example::
+
+ import transaction
+
+ engine = get_engine(settings)
+ session_factory = get_session_factory(engine)
+ with transaction.manager:
+ dbsession = get_tm_session(session_factory, transaction.manager)
+
+ """
+ dbsession = session_factory()
+ zope.sqlalchemy.register(
+ dbsession, transaction_manager=transaction_manager)
+ return dbsession
+
+
+def includeme(config):
+ """
+ Initialize the model for a Pyramid app.
+
+ Activate this setup using ``config.include('{{project}}.models')``.
+
+ """
+ settings = config.get_settings()
+
+ # use pyramid_tm to hook the transaction lifecycle to the request
+ config.include('pyramid_tm')
+
+ session_factory = get_session_factory(get_engine(settings))
+ config.registry['dbsession_factory'] = session_factory
+
+ # make request.dbsession available for use in Pyramid
+ config.add_request_method(
+ # r.tm is the transaction manager used by pyramid_tm
+ lambda r: get_tm_session(session_factory, r.tm),
+ 'dbsession',
+ reify=True
+ )
diff --git a/pyramid/scaffolds/alchemy/+package+/models/meta.py b/pyramid/scaffolds/alchemy/+package+/models/meta.py
new file mode 100644
index 000000000..0682247b5
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/models/meta.py
@@ -0,0 +1,16 @@
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.schema import MetaData
+
+# Recommended naming convention used by Alembic, as various different database
+# providers will autogenerate vastly different names making migrations more
+# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html
+NAMING_CONVENTION = {
+ "ix": 'ix_%(column_0_label)s',
+ "uq": "uq_%(table_name)s_%(column_0_name)s",
+ "ck": "ck_%(table_name)s_%(constraint_name)s",
+ "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
+ "pk": "pk_%(table_name)s"
+}
+
+metadata = MetaData(naming_convention=NAMING_CONVENTION)
+Base = declarative_base(metadata=metadata)
diff --git a/pyramid/scaffolds/alchemy/+package+/models/mymodel.py b/pyramid/scaffolds/alchemy/+package+/models/mymodel.py
new file mode 100644
index 000000000..d65a01a42
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/models/mymodel.py
@@ -0,0 +1,18 @@
+from sqlalchemy import (
+ Column,
+ Index,
+ Integer,
+ Text,
+)
+
+from .meta import Base
+
+
+class MyModel(Base):
+ __tablename__ = 'models'
+ id = Column(Integer, primary_key=True)
+ name = Column(Text)
+ value = Column(Integer)
+
+
+Index('my_index', MyModel.name, unique=True, mysql_length=255)
diff --git a/pyramid/scaffolds/alchemy/+package+/routes.py b/pyramid/scaffolds/alchemy/+package+/routes.py
new file mode 100644
index 000000000..25504ad4d
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/routes.py
@@ -0,0 +1,3 @@
+def includeme(config):
+ config.add_static_view('static', 'static', cache_max_age=3600)
+ config.add_route('home', '/')
diff --git a/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py b/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
index 7dfdece15..7307ecc5c 100644
--- a/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
+++ b/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
@@ -2,8 +2,6 @@ import os
import sys
import transaction
-from sqlalchemy import engine_from_config
-
from pyramid.paster import (
get_appsettings,
setup_logging,
@@ -11,11 +9,13 @@ from pyramid.paster import (
from pyramid.scripts.common import parse_vars
+from ..models.meta import Base
from ..models import (
- DBSession,
- MyModel,
- Base,
+ get_engine,
+ get_session_factory,
+ get_tm_session,
)
+from ..models import MyModel
def usage(argv):
@@ -32,9 +32,14 @@ def main(argv=sys.argv):
options = parse_vars(argv[2:])
setup_logging(config_uri)
settings = get_appsettings(config_uri, options=options)
- engine = engine_from_config(settings, 'sqlalchemy.')
- DBSession.configure(bind=engine)
+
+ engine = get_engine(settings)
Base.metadata.create_all(engine)
+
+ session_factory = get_session_factory(engine)
+
with transaction.manager:
+ dbsession = get_tm_session(session_factory, transaction.manager)
+
model = MyModel(name='one', value=1)
- DBSession.add(model)
+ dbsession.add(model)
diff --git a/pyramid/scaffolds/alchemy/+package+/static/theme.min.css b/pyramid/scaffolds/alchemy/+package+/static/theme.min.css
deleted file mode 100644
index 0d25de5b6..000000000
--- a/pyramid/scaffolds/alchemy/+package+/static/theme.min.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a,a{color:#f2b7bd;text-decoration:underline}.starter-template .links ul li a:hover,a:hover{color:#fff;text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
diff --git a/pyramid/scaffolds/alchemy/+package+/templates/404.jinja2_tmpl b/pyramid/scaffolds/alchemy/+package+/templates/404.jinja2_tmpl
new file mode 100644
index 000000000..1917f83c7
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/templates/404.jinja2_tmpl
@@ -0,0 +1,8 @@
+{% extends "layout.jinja2" %}
+
+{% block content %}
+<div class="content">
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1>
+ <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p>
+</div>
+{% endblock content %}
diff --git a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl
index 3f1d23d47..51e382654 100644
--- a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl
+++ b/pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl
@@ -1,12 +1,12 @@
<!DOCTYPE html>
-<html lang="${request.locale_name}">
+<html lang="\{\{request.locale_name\}\}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="pyramid web application">
<meta name="author" content="Pylons Project">
- <link rel="shortcut icon" href="${request.static_url('{{package}}:static/pyramid-16x16.png')}">
+ <link rel="shortcut icon" href="\{\{request.static_url('{{package}}:static/pyramid-16x16.png')\}\}">
<title>Alchemy Scaffold for The Pyramid Web Framework</title>
@@ -14,7 +14,7 @@
<link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this scaffold -->
- <link href="${request.static_url('{{package}}:static/theme.css')}" rel="stylesheet">
+ <link href="\{\{request.static_url('{{package}}:static/theme.css')\}\}" rel="stylesheet">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
@@ -29,13 +29,12 @@
<div class="container">
<div class="row">
<div class="col-md-2">
- <img class="logo img-responsive" src="${request.static_url('{{package}}:static/pyramid.png')}" alt="pyramid web framework">
+ <img class="logo img-responsive" src="\{\{request.static_url('{{package}}:static/pyramid.png')\}\}" alt="pyramid web framework">
</div>
<div class="col-md-10">
- <div class="content">
- <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">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 {{pyramid_version}}</span>.</p>
- </div>
+ {% block content %}
+ <p>No content</p>
+ {% endblock content %}
</div>
</div>
<div class="row">
diff --git a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.jinja2_tmpl b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.jinja2_tmpl
new file mode 100644
index 000000000..01fe5b8e3
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.jinja2_tmpl
@@ -0,0 +1,8 @@
+{% extends "layout.jinja2" %}
+
+{% block content %}
+<div class="content">
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">\{\{project\}\}</span>, an&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework {{pyramid_version}}</span>.</p>
+</div>
+{% endblock content %}
diff --git a/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl b/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl
index e6425eb91..072eab5b2 100644
--- a/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl
+++ b/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl
@@ -3,53 +3,63 @@ import transaction
from pyramid import testing
-from .models import DBSession
+def dummy_request(dbsession):
+ return testing.DummyRequest(dbsession=dbsession)
-class TestMyViewSuccessCondition(unittest.TestCase):
+
+class BaseTest(unittest.TestCase):
def setUp(self):
- self.config = testing.setUp()
- from sqlalchemy import create_engine
- engine = create_engine('sqlite://')
+ self.config = testing.setUp(settings={
+ 'sqlalchemy.url': 'sqlite:///:memory:'
+ })
+ self.config.include('.models')
+ settings = self.config.get_settings()
+
from .models import (
- Base,
- MyModel,
+ get_engine,
+ get_session_factory,
+ get_tm_session,
)
- DBSession.configure(bind=engine)
- Base.metadata.create_all(engine)
- with transaction.manager:
- model = MyModel(name='one', value=55)
- DBSession.add(model)
+
+ self.engine = get_engine(settings)
+ session_factory = get_session_factory(self.engine)
+
+ self.session = get_tm_session(session_factory, transaction.manager)
+
+ def init_database(self):
+ from .models.meta import Base
+ Base.metadata.create_all(self.engine)
def tearDown(self):
- DBSession.remove()
+ from .models.meta import Base
+
testing.tearDown()
+ transaction.abort()
+ Base.metadata.drop_all(self.engine)
+
+
+class TestMyViewSuccessCondition(BaseTest):
+
+ def setUp(self):
+ super(TestMyViewSuccessCondition, self).setUp()
+ self.init_database()
+
+ from .models import MyModel
+
+ model = MyModel(name='one', value=55)
+ self.session.add(model)
def test_passing_view(self):
- from .views import my_view
- request = testing.DummyRequest()
- info = my_view(request)
+ from .views.default import my_view
+ info = my_view(dummy_request(self.session))
self.assertEqual(info['one'].name, 'one')
self.assertEqual(info['project'], '{{project}}')
-class TestMyViewFailureCondition(unittest.TestCase):
- def setUp(self):
- self.config = testing.setUp()
- from sqlalchemy import create_engine
- engine = create_engine('sqlite://')
- from .models import (
- Base,
- MyModel,
- )
- DBSession.configure(bind=engine)
-
- def tearDown(self):
- DBSession.remove()
- testing.tearDown()
+class TestMyViewFailureCondition(BaseTest):
def test_failing_view(self):
- from .views import my_view
- request = testing.DummyRequest()
- info = my_view(request)
- self.assertEqual(info.status_int, 500) \ No newline at end of file
+ from .views.default import my_view
+ info = my_view(dummy_request(self.session))
+ self.assertEqual(info.status_int, 500)
diff --git a/pyramid/scaffolds/alchemy/+package+/views/__init__.py b/pyramid/scaffolds/alchemy/+package+/views/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/views/__init__.py
diff --git a/pyramid/scaffolds/alchemy/+package+/views.py_tmpl b/pyramid/scaffolds/alchemy/+package+/views/default.py_tmpl
index 292bce579..7bf0026e5 100644
--- a/pyramid/scaffolds/alchemy/+package+/views.py_tmpl
+++ b/pyramid/scaffolds/alchemy/+package+/views/default.py_tmpl
@@ -3,22 +3,20 @@ from pyramid.view import view_config
from sqlalchemy.exc import DBAPIError
-from .models import (
- DBSession,
- MyModel,
- )
+from ..models import MyModel
-@view_config(route_name='home', renderer='templates/mytemplate.pt')
+@view_config(route_name='home', renderer='../templates/mytemplate.jinja2')
def my_view(request):
try:
- one = DBSession.query(MyModel).filter(MyModel.name == 'one').first()
+ query = request.dbsession.query(MyModel)
+ one = query.filter(MyModel.name == 'one').first()
except DBAPIError:
- return Response(conn_err_msg, content_type='text/plain', status_int=500)
+ return Response(db_err_msg, content_type='text/plain', status=500)
return {'one': one, 'project': '{{project}}'}
-conn_err_msg = """\
+db_err_msg = """\
Pyramid is having a problem using your SQL database. The problem
might be caused by one of the following things:
@@ -33,4 +31,3 @@ might be caused by one of the following things:
After you fix the problem, please restart the Pyramid application to
try it again.
"""
-
diff --git a/pyramid/scaffolds/alchemy/+package+/views/notfound.py_tmpl b/pyramid/scaffolds/alchemy/+package+/views/notfound.py_tmpl
new file mode 100644
index 000000000..69d6e2804
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/+package+/views/notfound.py_tmpl
@@ -0,0 +1,7 @@
+from pyramid.view import notfound_view_config
+
+
+@notfound_view_config(renderer='../templates/404.jinja2')
+def notfound_view(request):
+ request.response.status = 404
+ return {}
diff --git a/pyramid/scaffolds/alchemy/MANIFEST.in_tmpl b/pyramid/scaffolds/alchemy/MANIFEST.in_tmpl
index 0ff6eb7a0..f93f45544 100644
--- a/pyramid/scaffolds/alchemy/MANIFEST.in_tmpl
+++ b/pyramid/scaffolds/alchemy/MANIFEST.in_tmpl
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml
diff --git a/pyramid/scaffolds/alchemy/README.txt_tmpl b/pyramid/scaffolds/alchemy/README.txt_tmpl
index a05c0e174..83c37edea 100644
--- a/pyramid/scaffolds/alchemy/README.txt_tmpl
+++ b/pyramid/scaffolds/alchemy/README.txt_tmpl
@@ -6,7 +6,7 @@ Getting Started
- cd <directory containing this file>
-- $VENV/bin/python setup.py develop
+- $VENV/bin/pip install -e .
- $VENV/bin/initialize_{{project}}_db development.ini
diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl
index 07811f7c3..f8ee290be 100644
--- a/pyramid/scaffolds/alchemy/development.ini_tmpl
+++ b/pyramid/scaffolds/alchemy/development.ini_tmpl
@@ -13,7 +13,6 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite
diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl
index 022bc0b7b..4d9f835d4 100644
--- a/pyramid/scaffolds/alchemy/production.ini_tmpl
+++ b/pyramid/scaffolds/alchemy/production.ini_tmpl
@@ -11,8 +11,6 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite
diff --git a/pyramid/scaffolds/alchemy/pytest.ini_tmpl b/pyramid/scaffolds/alchemy/pytest.ini_tmpl
new file mode 100644
index 000000000..a30c8bcad
--- /dev/null
+++ b/pyramid/scaffolds/alchemy/pytest.ini_tmpl
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = {{package}}
+python_files = *.py
diff --git a/pyramid/scaffolds/alchemy/setup.py_tmpl b/pyramid/scaffolds/alchemy/setup.py_tmpl
index 9496b9948..9318817dc 100644
--- a/pyramid/scaffolds/alchemy/setup.py_tmpl
+++ b/pyramid/scaffolds/alchemy/setup.py_tmpl
@@ -10,7 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
- 'pyramid_chameleon',
+ 'pyramid_jinja2',
'pyramid_debugtoolbar',
'pyramid_tm',
'SQLAlchemy',
@@ -19,16 +19,22 @@ requires = [
'waitress',
]
+tests_require = [
+ 'WebTest >= 1.3.1', # py3 compat
+ 'pytest', # includes virtualenv
+ 'pytest-cov',
+ ]
+
setup(name='{{project}}',
version='0.0',
description='{{project}}',
long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
+ "Programming Language :: Python",
+ "Framework :: Pyramid",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ ],
author='',
author_email='',
url='',
@@ -36,7 +42,9 @@ setup(name='{{project}}',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
- test_suite='{{package}}',
+ extras_require={
+ 'testing': tests_require,
+ },
install_requires=requires,
entry_points="""\
[paste.app_factory]
diff --git a/pyramid/scaffolds/starter/+dot+coveragerc_tmpl b/pyramid/scaffolds/starter/+dot+coveragerc_tmpl
new file mode 100644
index 000000000..273a4a580
--- /dev/null
+++ b/pyramid/scaffolds/starter/+dot+coveragerc_tmpl
@@ -0,0 +1,3 @@
+[run]
+source = {{package}}
+omit = {{package}}/test*
diff --git a/pyramid/scaffolds/starter/+package+/static/theme.min.css b/pyramid/scaffolds/starter/+package+/static/theme.min.css
deleted file mode 100644
index 2f924bcc5..000000000
--- a/pyramid/scaffolds/starter/+package+/static/theme.min.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} \ No newline at end of file
diff --git a/pyramid/scaffolds/starter/+package+/tests.py_tmpl b/pyramid/scaffolds/starter/+package+/tests.py_tmpl
index 94912a850..30f3f0430 100644
--- a/pyramid/scaffolds/starter/+package+/tests.py_tmpl
+++ b/pyramid/scaffolds/starter/+package+/tests.py_tmpl
@@ -15,3 +15,15 @@ class ViewTests(unittest.TestCase):
request = testing.DummyRequest()
info = my_view(request)
self.assertEqual(info['project'], '{{project}}')
+
+
+class FunctionalTests(unittest.TestCase):
+ def setUp(self):
+ from {{package}} import main
+ app = main({})
+ from webtest import TestApp
+ self.testapp = TestApp(app)
+
+ def test_root(self):
+ res = self.testapp.get('/', status=200)
+ self.assertTrue(b'Pyramid' in res.body)
diff --git a/pyramid/scaffolds/starter/README.txt_tmpl b/pyramid/scaffolds/starter/README.txt_tmpl
index 40f98d14a..127ad7595 100644
--- a/pyramid/scaffolds/starter/README.txt_tmpl
+++ b/pyramid/scaffolds/starter/README.txt_tmpl
@@ -1 +1,12 @@
{{project}} README
+==================
+
+Getting Started
+---------------
+
+- cd <directory containing this file>
+
+- $VENV/bin/pip install -e .
+
+- $VENV/bin/pserve development.ini
+
diff --git a/pyramid/scaffolds/starter/pytest.ini_tmpl b/pyramid/scaffolds/starter/pytest.ini_tmpl
new file mode 100644
index 000000000..a30c8bcad
--- /dev/null
+++ b/pyramid/scaffolds/starter/pytest.ini_tmpl
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = {{package}}
+python_files = *.py
diff --git a/pyramid/scaffolds/starter/setup.py_tmpl b/pyramid/scaffolds/starter/setup.py_tmpl
index 3802c3e23..2e5ce92c7 100644
--- a/pyramid/scaffolds/starter/setup.py_tmpl
+++ b/pyramid/scaffolds/starter/setup.py_tmpl
@@ -15,16 +15,22 @@ requires = [
'waitress',
]
+tests_require = [
+ 'WebTest >= 1.3.1', # py3 compat
+ 'pytest', # includes virtualenv
+ 'pytest-cov',
+ ]
+
setup(name='{{project}}',
version='0.0',
description='{{project}}',
long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
+ "Programming Language :: Python",
+ "Framework :: Pyramid",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ ],
author='',
author_email='',
url='',
@@ -32,9 +38,10 @@ setup(name='{{project}}',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
install_requires=requires,
- tests_require=requires,
- test_suite="{{package}}",
entry_points="""\
[paste.app_factory]
main = {{package}}:main
diff --git a/pyramid/scaffolds/tests.py b/pyramid/scaffolds/tests.py
index 49358c1cf..44680a464 100644
--- a/pyramid/scaffolds/tests.py
+++ b/pyramid/scaffolds/tests.py
@@ -29,19 +29,18 @@ class TemplateTest(object):
self.make_venv(self.directory)
here = os.path.abspath(os.path.dirname(__file__))
os.chdir(os.path.dirname(os.path.dirname(here)))
- subprocess.check_call(
- [os.path.join(self.directory, 'bin', 'python'),
- 'setup.py', 'develop'])
+ pip = os.path.join(self.directory, 'bin', 'pip')
+ subprocess.check_call([pip, 'install', '-e', '.'])
os.chdir(self.directory)
subprocess.check_call(['bin/pcreate', '-s', tmpl_name, 'Dingle'])
os.chdir('Dingle')
- py = os.path.join(self.directory, 'bin', 'python')
- subprocess.check_call([py, 'setup.py', 'install'])
+ subprocess.check_call([pip, 'install', '.[testing]'])
if tmpl_name == 'alchemy':
populate = os.path.join(self.directory, 'bin',
'initialize_Dingle_db')
subprocess.check_call([populate, 'development.ini'])
- subprocess.check_call([py, 'setup.py', 'test'])
+ subprocess.check_call([
+ os.path.join(self.directory, 'bin', 'py.test')])
pserve = os.path.join(self.directory, 'bin', 'pserve')
for ininame, hastoolbar in (('development.ini', True),
('production.ini', False)):
diff --git a/pyramid/scaffolds/zodb/+dot+coveragerc_tmpl b/pyramid/scaffolds/zodb/+dot+coveragerc_tmpl
new file mode 100644
index 000000000..273a4a580
--- /dev/null
+++ b/pyramid/scaffolds/zodb/+dot+coveragerc_tmpl
@@ -0,0 +1,3 @@
+[run]
+source = {{package}}
+omit = {{package}}/test*
diff --git a/pyramid/scaffolds/zodb/+package+/static/theme.css b/pyramid/scaffolds/zodb/+package+/static/theme.css
index be50ad420..0f4b1a4d4 100644
--- a/pyramid/scaffolds/zodb/+package+/static/theme.css
+++ b/pyramid/scaffolds/zodb/+package+/static/theme.css
@@ -72,10 +72,12 @@ p {
color: #f2b7bd;
font-weight: 400;
}
-.starter-template .links ul li a {
- color: #ffffff;
+.starter-template .links ul li a, a {
+ color: #f2b7bd;
+ text-decoration: underline;
}
-.starter-template .links ul li a:hover {
+.starter-template .links ul li a:hover, a:hover {
+ color: #ffffff;
text-decoration: underline;
}
.starter-template .links ul li .icon-muted {
diff --git a/pyramid/scaffolds/zodb/+package+/static/theme.min.css b/pyramid/scaffolds/zodb/+package+/static/theme.min.css
deleted file mode 100644
index 2f924bcc5..000000000
--- a/pyramid/scaffolds/zodb/+package+/static/theme.min.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} \ No newline at end of file
diff --git a/pyramid/scaffolds/zodb/README.txt_tmpl b/pyramid/scaffolds/zodb/README.txt_tmpl
index 40f98d14a..127ad7595 100644
--- a/pyramid/scaffolds/zodb/README.txt_tmpl
+++ b/pyramid/scaffolds/zodb/README.txt_tmpl
@@ -1 +1,12 @@
{{project}} README
+==================
+
+Getting Started
+---------------
+
+- cd <directory containing this file>
+
+- $VENV/bin/pip install -e .
+
+- $VENV/bin/pserve development.ini
+
diff --git a/pyramid/scaffolds/zodb/pytest.ini_tmpl b/pyramid/scaffolds/zodb/pytest.ini_tmpl
new file mode 100644
index 000000000..a30c8bcad
--- /dev/null
+++ b/pyramid/scaffolds/zodb/pytest.ini_tmpl
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = {{package}}
+python_files = *.py
diff --git a/pyramid/scaffolds/zodb/setup.py_tmpl b/pyramid/scaffolds/zodb/setup.py_tmpl
index 3a6032429..19771d756 100644
--- a/pyramid/scaffolds/zodb/setup.py_tmpl
+++ b/pyramid/scaffolds/zodb/setup.py_tmpl
@@ -19,16 +19,22 @@ requires = [
'waitress',
]
+tests_require = [
+ 'WebTest >= 1.3.1', # py3 compat
+ 'pytest', # includes virtualenv
+ 'pytest-cov',
+ ]
+
setup(name='{{project}}',
version='0.0',
description='{{project}}',
long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
+ "Programming Language :: Python",
+ "Framework :: Pyramid",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ ],
author='',
author_email='',
url='',
@@ -36,9 +42,10 @@ setup(name='{{project}}',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
install_requires=requires,
- tests_require=requires,
- test_suite="{{package}}",
entry_points="""\
[paste.app_factory]
main = {{package}}:main