Skip to content

Example usage of pyramid_angularstarter

Tom Willis edited this page Jul 12, 2014 · 2 revisions

A week or so ago I "released" pyramid_angularstarter. And as you can read from the description, it is a pyramid project scaffold for an angularjs application with some other niceties I've come to use such as ...

In other words, most of the toys that I would reasonably want for those new fangled websites I want to build. What I didn't do was "document" how one might use it. Documentation is always difficult, you run the risk of potentially documenting everything or nothing at all. Guess which side I chose? :) I feel that anyone with experience in pyramid should be able to figure it out. However, this may be unreasonable, so this gist is my attempt at rectifying that and hopefully getting some feedback on how it might be improved.

Installation

Installing it should hopefully not be a surprise to any one familiar with python. We'll create a virtualenv here to give us enough isolation to play around some.

 $ virtualenv -p /usr/bin/python2.7 testenv
Running virtualenv with interpreter /usr/bin/python2.7
New python executable in testenv/bin/python
Installing setuptools, pip...done.
 ~/projects
 $ cd testenv
 ~/projects/testenv
 $ ./bin/pip install pyramid_angularstarter
 ....<snip>

As I mentioned before, pyramid_angularstarter is a project scaffold. It generates a project skeleton for you. By virtue of it being installed, pyramid has been installed as well as the "pcreate" command. Running "pcreate -l" will list all the templates that pyramid knows about in this environment which is all the ones that pyramid installs as well as the additional ones provided by pyramid_angularstarter.

 $ ./bin/pcreate -l
Available scaffolds:
  alchemy:           Pyramid SQLAlchemy project using url dispatch
  angularjs:         Pyramid + Angularjs
  angularjs_w_user:  Pyramid + Angularjs + User model, registration, forgot password
  starter:           Pyramid starter project
  zodb:              Pyramid ZODB project using traversal

The templates that start with "angularjs_" are the ones provided by pyramid_angularstarter. This means that the program "pcreate" now understands how to generate a project skeleton for an angularjs app backed by pyramid.

Generating the project

It should be no surprise to someone familiar with pyramid what to do next, but here's how you generate a project from a template with pcreate

~/projects/testenv
 $ ./bin/pcreate -t angularjs_w_user imgurclone
 ...<snip>

Now there's a directory called "imgurclone", this contains the project.

Running the generated web application.

All pyramid applications are structured as python eggs with a setup.py in the project root. And as any python developer probably knows, in order to hack on a python egg you need to make the environment aware of it and install all it's dependencies. This is done like this....

~/projects/testenv
 $ cd imgurclone/
 ~/projects/testenv/imgurclone
 $ ../bin/python setup.py develop
running develop
<snip>

This does a couple of things for us. First, it makes the environment whose interpreter is at ~/projects/testenv/bin/python aware of the project "imgurclone", Secondly it installs all of the projects python dependencies. Usually, this is all you would need to do to get the web application running.

 ~/projects/testenv/imgurclone
 $ ../bin/pserve development.ini --reload

However, there are a couple extra steps because we need to set up the javascript side. The following assumes you have nodejs installed which installs the "npm" command in your path. You also need to install gulp and (bower)[http://bower.io/#install-bower]. After you do all this, you can set up the javascript/css side of the project this way...

 ~/projects/testenv/imgurclone
$ cd imgurclone/client-src
 ~/projects/testenv/imgurclone/imgurclone/client-src
 $ npm install && bower install && gulp
 ...<snip>

And after a lot of output, the required gulp plugins are installed at ~/projects/testenv/imgurclone/imgurclone/client-src/node_modules , and all the javascript libraries the app currently depends on are installed at ~/projects/testenv/imgurclone/imgurclone/client-src/bower_components and finally we run gulp once to generate the javascript from coffeescript and the css from sass and put it in ~/projects/testenv/imgurclone/imgurclone/static . We can now run the application and see the page.

~/projects/testenv/imgurclone/imgurclone/client-src
 $ cd ../../
 ~/projects/testenv/imgurclone
 $ ../bin/pserve development.ini --reload

Now point your browser at http://localhost:6543/#/ and you should be greeted with a very basic web page.

Database setup

I'm using alembic to keep track of changes to the database schema. There's a bit of frustration here due to the user model using a custom column type for the users password. I believe the frustration is worth it since handling passwords incorrectly has the potential to frustrate and inconvenience more people.

Generating the initial migration.

Alembic has already been initialized and configured for this project. You can look at imgurclone/alembic.ini and imgurclone/migrations/env.py for more details as to how it is configured. Now we need generate the database schema for the models declared in imgurclone/imgurclone/models.py, which currently is the User model and the Command model. It should be obvious what the User model is for, the Command model on the other hand is used in the registration process and forgot password process.

Here's how to generate the initial migration and all future migrations.

~/projects/testenv/imgurclone
 $ ../bin/alembic revision --autogenerate -m "initial"

And this to apply a migration. However you will likely get an error that needs to be fixed

~/projects/testenv/imgurclone
 $ ../bin/alembic upgrade head
 ...<snip>
   File "migration/versions/513b7793f3db_initial.py", line 38, in upgrade
    sa.Column('password', sa.PasswordType(length=1137), nullable=True),
AttributeError: 'module' object has no attribute 'PasswordType'

This is the frustration part. The User model has a column with type of password type. alembic assumes this column type is provided by sqlalchemy but it is actually provided by sqlaclhemy_utils.types.password so, we need to manually edit the script and run it again. Also, the database that was generated has to be erased b/c it's schema is in an unknown state and not usable.

 ~/projects/testenv/imgurclone
 $ rm db.sqlite 

Now we need to edit the generated migration file located at ~/projects/testenv/imgurclone/migrations/versions/...

--- a/513b7793f3db_initial.py
+++ b/513b7793f3db_initial.py
@@ -12,7 +12,7 @@ down_revision = None
 
 from alembic import op
 import sqlalchemy as sa
-
+from sqlalchemy_utils.types.password import PasswordType
 
 def upgrade():
     ### commands auto generated by Alembic - please adjust! ###
@@ -35,7 +35,7 @@ def upgrade():
     sa.Column('email', sa.Unicode(length=1024), nullable=True),
     sa.Column('first_name', sa.Unicode(length=1024), nullable=True),
     sa.Column('last_name', sa.Unicode(length=1024), nullable=True),
-    sa.Column('password', sa.PasswordType(length=1137), nullable=True),
+    sa.Column('password', PasswordType(), nullable=True),
     sa.PrimaryKeyConstraint('id'),
     sa.UniqueConstraint('email')
     )

Now we should be able to generate the database correctly.

~/projects/testenv/imgurclone
 $ ../bin/alembic upgrade head

email setup

In order for "registration" and "forgot password" to work, we need to get a working email configuration which includes an smtp server that you have permission to use.

The file at ~/projects/testenv/imgurclone/development.ini has most of the configuration already. Generally we just need a user and password to an smtp server. Sorry you can't have mine, here's how to put your settings in.

Create a file called at ~/projects/testenv/imgurclone/secret_settings.ini. the application is setup to use this file if it exists, allowing you to keep settings that should not be under version control separated.

[secrets]                                             
mail.transport.username = youremailaddress@gmail.com                                                 
mail.transport.password = yourgmailpassword

If your username and password are correct, you should be able to register and activate a new user.

what's next?

Hopefully, you can read the code and change to suit your needs on the client or server side of the application. Typically you can run "gulp watch" from the ~/projects/testenv/imgurclone/imgurclone/client-src/ and then "../bin/pserve development.ini --reload" from the ~/projects/testenv/imgurclone and most of the time gulp will compile your coffeescript and sass, and then pyramid will serve the latest along with latest views that you write.

Happy coding.