The Pyramid version of the todo app for the Python Web Shootout

indypy, updated 🕥 2022-09-16 17:44:57

ToDo Pyramid App

This is the Pyramid app for the Python Web Shootout.

Try it out here: http://demo.todo.sixfeetup.com

Install

You can follow the instructions in the Pyramid docs on installation.

Once you have Python and virtualenv installed, you can do the following:

$ mkdir ~/.virtualenvs $ cd ~/.virtualenvs $ virtualenv -p python2.7 todopyramid $ cd todopyramid $ source bin/activate

This creates the new virtual environment, now you can install the app.

(todopyramid)$ cd ~/Desktop (todopyramid)$ git clone https://github.com/indypy/todopyramid.git (todopyramid)$ cd todopyramid (todopyramid)$ pip install -r requirements.txt -e .

This gives us the end result of the finished app. If it is the first time you are running the app, you will need to initialize the database.

(todopyramid)$ initialize_todopyramid_db development.ini

It can now be started up by doing the following.

(todopyramid)$ pserve development.ini

Now go to http://localhost:6543 and enjoy!

How the sausage was made

The above install directions tell you how to get the finished application started. Here we will document how the app was created from scratch.

First steps

Started by creating a virtualenv and installing Pyramid into it.

(todopyramid)$ pip install pyramid

This gives us a starting point and the pcreate command to create a new app. In this case, we used the alchemy scaffold.

(todopyramid)$ cd ~/Desktop (todopyramid)$ pcreate -s alchemy todopyramid

Since we are responsible developers, the first thing we should do is put this code into version control.

(todopyramid)$ cd todopyramid (todopyramid)$ git init (todopyramid)$ git add . (todopyramid)$ git commit -m 'initial package from pcreate alchemy scaffold'

Before we start up the app for the first time, we need to install the new package that we've created, and all of its dependencies.

(todopyramid)$ python2.7 setup.py develop

Now that we've installed some more packages, we need to freeze the list of packages.

(todopyramid)$ pip freeze > requirements.txt (todopyramid)$ git add requirements.txt (todopyramid)$ git commit -m 'committing first version of requirements file'

Now let's initialize the database. In our example, we will be using SQLite.

(todopyramid)$ initialize_todopyramid_db development.ini

We don't want to check in the database, add it to the .gitignore file.

(todopyramid)$ echo "todopyramid.sqlite" > .gitignore (todopyramid)$ git add .gitignore (todopyramid)$ git commit -m 'ignore the SQLite database'

Now we can start up the app and see what it looks like.

(todopyramid)$ pserve development.ini

This will include all the boilerplate code from the alchemy template.

Remove boilerplate

For our purposes, we won't need some of the boilerplate code that has been added. We'll just get rid of it.

(todopyramid)$ git rm static/* (todopyramid)$ touch static/.gitignore (todopyramid)$ git add static/.gitignore (todopyramid)$ git rm templates/* (todopyramid)$ git commit -m 'removing boilerplate templates'

We've put a .gitignore in the static dir so that the directory stays in place. We'll add templates to the templates dir soon, so it isn't necessary for that dir.

Let's get fancy

Now we are ready to start adding our customizations. First thing we want to do is add in Bootstrap to ease creation of layouts. Since we will be using Deform to create forms later on, we will use the deform_bootstrap package.

Add it to the setup.py

requires = [ # ... 'deform_bootstrap', ]

Then we need to pull in its dependencies (which includes Deform itself). Then update the requirements.txt file.

(todopyramid)$ python2.7 setup.py develop (todopyramid)$ pip freeze > requirements.txt

Then add the static resources to the __init__.py

```

Adding the static resources from Deform

config.add_static_view('deform_static', 'deform:static', cache_max_age=3600) config.add_static_view('deform_bootstrap_static', 'deform_bootstrap:static', cache_max_age=3600) ```

Now we need to get our template structure in place. We'll add a todopyramid/layouts.py with the following (see the Creating a Custom UX for Pyramid tutorial for more details):

``` ifrom pyramid.renderers import get_renderer from pyramid.decorator import reify

class Layouts(object):

@reify
def global_template(self):
    renderer = get_renderer("templates/global_layout.pt")
    return renderer.implementation().macros['layout']

```

Add the global_layout.pt with at least the following (look at the source code for the complete template):

```

<!-- Styles from Deform Bootstrap -->
<link rel="stylesheet" href="${request.static_url('deform_bootstrap:static/deform_bootstrap.css')}" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="${request.static_url('deform_bootstrap:static/chosen_bootstrap.css')}" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="${request.static_url('deform:static/css/ui-lightness/jquery-ui-1.8.11.custom.css')}" type="text/css" media="screen" charset="utf-8" />

Site content goes here

```

Now we have to modify our boilerplate view to use the layout in todopyramid/views.py, notice that we've also changed the view name and template name to reflect what this view does, showing the home page.

``` from .layouts import Layouts

class ToDoViews(Layouts):

def __init__(self, context, request):
    self.context = context
    self.request = request

@view_config(route_name='home', renderer='templates/home.pt')
def home_view(request):
    # view code here
    return {}

```

Now we can add a todopyramid/templates/home.pt to our app with the following

```

Home

Welcome to the Pyramid version of the ToDo app.

```

Now subsequent templates can be set up in the same manner.

Authentication

Our app will need to authorize users in order to be able to add a ToDo list. Pyramid, having no opinions on the matter, leaves us with a myriad of options. One quick way is to utilize the Mozilla Persona login system. There just so happens to be a plugin for this called pyramid_persona

Following the documentation for the personas plugin, we add it to the dependencies of our app, build the latest version and include the plugin in our config.

We also override the default forbidden view in order to integrate a login form into our global template layout.

Not Found

In order to keep up appearances, we add a custom Not Found view that integrates into our global layout. This is quite simple using the pyramid.view.notfound_view_config

Models

Now that we have created the shell for our app, it is time to create some models. We will be utilizing SQLAlchemy in this case since it fits the needs of our application.

We will create a TodoItem and Tag model to start out with. This will give us the basis for our todo list.

Issues

Bump mako from 0.7.3 to 1.2.2

opened on 2022-09-16 17:44:56 by dependabot[bot]

Bumps mako from 0.7.3 to 1.2.2.

Release notes

Sourced from mako's releases.

1.2.2

Released: Mon Aug 29 2022

bug

  • [bug] [lexer] Fixed issue in lexer where the regexp used to match tags would not correctly interpret quoted sections individually. While this parsing issue still produced the same expected tag structure later on, the mis-handling of quoted sections was also subject to a regexp crash if a tag had a large number of quotes within its quoted sections.

    References: #366

1.2.1

Released: Thu Jun 30 2022

bug

  • [bug] [tests] Various fixes to the test suite in the area of exception message rendering to accommodate for variability in Python versions as well as Pygments.

    References: #360

misc

  • [performance] Optimized some codepaths within the lexer/Python code generation process, improving performance for generation of templates prior to their being cached. Pull request courtesy Takuto Ikuta.

    References: #361

1.2.0

Released: Thu Mar 10 2022

changed

  • [changed] [py3k] Corrected "universal wheel" directive in setup.cfg so that building a wheel does not target Python 2.

    References: #351

  • [changed] [py3k] The bytestring_passthrough template argument is removed, as this flag only applied to Python 2.

... (truncated)

Commits


Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/indypy/todopyramid/network/alerts).

Bump waitress from 1.4.3 to 2.1.1

opened on 2022-03-21 22:16:09 by dependabot[bot]

Bumps waitress from 1.4.3 to 2.1.1.

Changelog

Sourced from waitress's changelog.

2.1.1

Security Bugfix


- Waitress now validates that chunked encoding extensions are valid, and don't
  contain invalid characters that are not allowed. They are still skipped/not
  processed, but if they contain invalid data we no longer continue in and
  return a 400 Bad Request. This stops potential HTTP desync/HTTP request
  smuggling. Thanks to Zhang Zeyu for reporting this issue. See
  https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36
  • Waitress now validates that the chunk length is only valid hex digits when parsing chunked encoding, and values such as 0x01 and +01 are no longer supported. This stops potential HTTP desync/HTTP request smuggling. Thanks to Zhang Zeyu for reporting this issue. See https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36

  • Waitress now validates that the Content-Length sent by a remote contains only digits in accordance with RFC7230 and will return a 400 Bad Request when the Content-Length header contains invalid data, such as +10 which would previously get parsed as 10 and accepted. This stops potential HTTP desync/HTTP request smuggling Thanks to Zhang Zeyu for reporting this issue. See https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36

2.1.0

Python Version Support

  • Python 3.6 is no longer supported by Waitress

  • Python 3.10 is fully supported by Waitress

Bugfix


- ``wsgi.file_wrapper`` now sets the ``seekable``, ``seek``, and ``tell``
  attributes from the underlying file if the underlying file is seekable. This
  allows WSGI middleware to implement things like range requests for example

See Pylons/waitress#359 and Pylons/waitress#363

  • In Python 3 OSError is no longer subscriptable, this caused failures on Windows attempting to loop to find an socket that would work for use in the trigger.

</tr></table>

... (truncated)

Commits
  • 9e0b8c8 Merge pull request from GHSA-4f7p-27jc-3c36
  • b28c9e8 Prep for 2.1.1
  • bd22869 Remove extraneous calls to .strip() in Chunked Encoding
  • d9bdfa0 Validate chunk size in Chunked Encoding are HEXDIG
  • d032a66 Error when receiving back Chunk Extension
  • 884bed1 Update tests to remove invalid chunked encoding chunk-size
  • 1f6059f Be more strict in parsing Content-Length
  • e75b0d9 Add new regular expressions for Chunked Encoding
  • 22c0394 Merge pull request #367 from Pylons/fixup/collect-wasyncore-tests
  • dc15d9f Make sure to collect all wasyncore tests
  • Additional commits viewable in compare view


Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/indypy/todopyramid/network/alerts).

Bump ipython from 0.13.1 to 7.16.3

opened on 2022-01-21 19:19:20 by dependabot[bot]

Bumps ipython from 0.13.1 to 7.16.3.

Release notes

Sourced from ipython's releases.

7.9.0

No release notes provided.

7.8.0

No release notes provided.

7.7.0

No release notes provided.

7.6.1

No release notes provided.

7.6.0

No release notes provided.

7.5.0

No release notes provided.

7.4.0

No release notes provided.

7.3.0

No release notes provided.

7.2.0

No release notes provided.

7.1.1

No release notes provided.

7.1.0

No release notes provided.

7.0.1

No release notes provided.

7.0.0

No release notes provided.

7.0.0-doc

No release notes provided.

7.0.0rc1

No release notes provided.

7.0.0b1

No release notes provided.

6.2.1

No release notes provided.

... (truncated)

Commits


Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/indypy/todopyramid/network/alerts).

Bump sqlalchemy from 0.8.0b2 to 1.3.0

opened on 2021-03-30 01:16:06 by dependabot[bot]

Bumps sqlalchemy from 0.8.0b2 to 1.3.0.

Release notes

Sourced from sqlalchemy's releases.

1.3.0

Released: March 4, 2019

  • [feature] [schema] Added new parameters Table.resolve_fks and MetaData.reflect.resolve_fks which when set to False will disable the automatic reflection of related tables encountered in ForeignKey objects, which can both reduce SQL overhead for omitted tables as well as avoid tables that can't be reflected for database-specific reasons. Two Table objects present in the same MetaData collection can still refer to each other even if the reflection of the two tables occurred separately.

    References: #4517

  • [feature] [orm] The Query.get() method can now accept a dictionary of attribute keys and values as a means of indicating the primary key value to load; is particularly useful for composite primary keys. Pull request courtesy Sanjana S.

    References: #4316

  • [feature] [orm] A SQL expression can now be assigned to a primary key attribute for an ORM flush in the same manner as ordinary attributes as described in flush_embedded_sql_expressions where the expression will be evaulated and then returned to the ORM using RETURNING, or in the case of pysqlite, works using the cursor.lastrowid attribute.Requires either a database that supports RETURNING (e.g. Postgresql, Oracle, SQL Server) or pysqlite.

    References: #3133

  • [bug] [sql] The Alias class and related subclasses CTE, Lateral and TableSample have been reworked so that it is not possible for a user to construct the objects directly. These constructs require that the standalone construction function or selectable-bound method be used to instantiate new objects.

    References: #4509

  • [engine] [feature] Revised the formatting for StatementError when stringified. Each error detail is broken up over multiple newlines instead of spaced out on a single line. Additionally, the SQL representation now stringifies the SQL statement rather than using repr(), so that newlines are rendered as is. Pull request courtesy Nate Clark.

    References: #4500

Commits


Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/indypy/todopyramid/network/alerts).

Python 3 support

opened on 2015-05-08 22:24:20 by christianmlong

I ported this project to run on Python 3.4. The site runs, but I can't log in. I suspect it has something to do with the newer versions of the dependencies I had to specify to get it to run on Python 3.4.

The version I converted to 3.4 is at https://github.com/christianmlong/todopyramid, on branch python3

The site runs, and when I click Sign In, it goes to the Persona sign-in page. However, after the Persona page is done, and I am back at the Todo app, I get two errors. See attached screenshots.


Firefox

failure 1 failure 2

Chrome

failure 1 chrome failure 2 chrome

These screenshots are in the order that the errors occur - note the order is different on FF and Chrome.


The "Syntax error: Unexpected token <" error message looks like it's getting some html where it shouldn't be.


Steps to reproduce:

git clone [email protected]:christianmlong/todopyramid.git todopyramid34 cd todopyramid34 mkvirtualenv indypy34 --python=python3.4 git co python3 pip install -r requirements.txt python setup.py develop initialize_todopyramid_db development.ini pserve development.ini - Visit http://192.168.56.20:6543/ - Click on Sign In - Complete the Persona sign in process - When the Persona window closes, the error occurs.


This problem has been verified when running the server on Windows 8.1 and on Ubuntu 14.04.

tiny changes in Readme

opened on 2015-04-29 13:47:56 by areski None
IndyPy

Repositories of code and presentations from our meetings

GitHub Repository