Archive for the ‘Framework’ Category

ImportError: No module named datetime

Monday, December 15th, 2014

Of course, a new upgrade to Python on my devbox and the virtualenv breaks. And, merely reinstalling the virtualenv over top doesn’t work.

This is where you need to make sure your python project has an adequate setup.py to install the dependencies or you’re going to end up reinstalling by hand.

First, deactivate and make sure you’re not in the virtualenv. Get into the virtualenv’s top level directory and:


cd /virtualenvroot
rm -rf bin/ include/ lib/ local/
virtualenv /virtualenvroot
source bin/activate

Then, rerun setup.py with either install or develop and you should be set.

uwsgi version 1.2.3, Debian, and Pyramid

Saturday, February 23rd, 2013

First, we need to install uwsgi:

apt-get update
apt-get install uwsgi uwsgi-plugin-python

Then we need to create a .ini file that goes into /etc/uwsgi/apps-available:

[uwsgi]
uid = username
gid = username
workers = 4
buffer-size = 25000
chmod-socket = 666
single-interpreter = true
master = true
socket = /tmp/project.sock
plugin = python
pythonpath = /var/www/virtualenv/bin
paste = config:/var/www/virtualenv/project/production.ini
home = /var/www/virtualenv

Then create the symlink:

ln -s /etc/uwsgi/apps-available/project.ini /etc/uwsgi/apps-enabled/project.ini

Then restart uwsgi:

/etc/init.d/uwsgi restart

If it doesn’t work, a few things might need to be checked. First, you need to make sure your virtualenv is using Python 2.7.

If you still need to debug, you can do

uwsgi --ini /etc/uwsgi/apps-enabled/project.ini

which will give you some output at which point you should be able to determine the issue.

For Nginx, the config on your site should contain something like the following:

    location / {
        uwsgi_pass  unix:/tmp/project.sock;
        include     uwsgi_params;
    }

and /etc/nginx/uwsgi_params should contain

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO		$document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

uwsgi_param  SCRIPT_NAME	'';

AngularJS – a first step

Wednesday, September 19th, 2012

If you’ve not heard of AngularJS, I’m not surprised. It moves MVC or MV* to the browser and provides a unique, lightweight, powerful way to write apps that execute on the client side. Forms, validation, controllers, routes are all handled fairly easily.

The one thing I look for in every framework I use is a decent form library. No form library, and my interest wanes quickly. I don’t know how frameworks can claim to speed up development if you have to hand code forms, do your own validation and handle the form submission. It isn’t like you don’t expect people to input data.

The first thing with AngularJS that I ran into is the markup. While most frameworks have a template language that is executed before presentation, AngularJS’s markup is written directly in the HTML. The one thing that seems missing is the ability to do conditionals in templates. That was a design choice and a decent one to stand firm on, but, working around that to make a dynamic menu was a little complicated.

Passing things to your $scope allow you to communicate from your controller to the page. When using a controller, your urls look like http://site.com/#/page, but, if you view source, the page looks rather barren. I know Google’s searchbots can crawl the site as it did about eight minutes after I created the site.

There are a number of demos and videos and watching them gives you a fairly complete overview of AngularJS.

Development was quick. I spent a total of three days writing a quick app to familiarize myself with it and overall, the documentation is excellent, the examples are pretty good and cover a wide variety of use cases. There is a learning curve, but, the documentation is written very well, explaining the why in addition to having functional documentation.

To handle synchronous events with JavaScript’s async behavior, $q, a promise handler which works with a service was written. In your controller, you ask for a promise, hand it off to your service which resolves the promise, and your controller continues at that point, modifying the DOM on your page allowing for a very dynamic site.

Form handling is superb. Validation of fields can be handled quickly and you can even specify regexes in the HTML for extremely tight validation. Once you’ve received the data, your controller can act on that data.

Controllers and routes initially caught me off guard. When I first looked at them, I missed the ng-app specification and had to remove my controller declaration on my div from a prior iteration. Once I did that, and understood how partials worked, my app became a multipage app.

I didn’t do much DOM manipulation, but, AngularJS has quite a few powerful methods that make it quite easy. Selecting and modifying DOM elements is quick, and, with a service/controller setup, you can simply send changes through to the scope and they’ll be reflected.

Overall, my first experience with AngularJS is a positive one.

The first app I wrote was StravaPerf which utilizes the Strava API and d3.js to display graphs showing rider improvement. While Strava’s API is quite robust, I’ve run into API limits in the past, so, I use Varnish to work around the fact that JSONP isn’t supported, and, to cache the JSON responses coming back from Strava. This eliminates the need to have any backend or persistent storage. As a result, the app runs almost entirely from Varnish and only hits the backend on a cold start.

AngularJS is quite powerful and easy to use. I can see a number of potential projects that could easily be handled with it that would be extremely dynamic and interactive. This would push the edge of the web and allow app-like behavior in the browser.

Redesign of one of the forms in the Control Panel

Thursday, February 2nd, 2012

One of the biggest problems I had with the old control panel was that certain functions really weren’t well thought out, so, using the control panel was quite cumbersome. Some of the earlier redesigns of the Task Status Report made a large impact. Making the report easy to read and to convey the critical information very quickly was one of the goals.

The primary goal was to make sure that it was as easy to use the Control Panel to do things as it was to start an ssh session and do things manually. But, we needed to make the form easy enough for people to use that didn’t know what they needed.

Easy enough for everyone, still quick enough for someone that knows precisely what they want.

The following two screenshots are from the old Control Panel. Arguably one could say that the Simple interface was harder to use than the Advanced interface.

Simple Cronjob Entry Form

Advanced Cronjob Entry Form

The replacement Cron Job entry page:

With a few buttons to allow very commonly entered options to be selected, adding a cron job becomes quite easy. I have debated whether to add a single line entry that just takes the raw crontab entry so that people don’t need to parse it and fill in the form.

Sometimes, forms can be usable.

Ajax Push Engine, Pyramid and a quick demo application

Wednesday, January 11th, 2012

Earlier today I was debating Ajax Push and Pyramid for a project I had in mind. I ended up spending about 45 minutes writing a quick proof of concept, then, decided that perhaps something a bit more detailed with some documentation would be helpful for others.

I used Pyramid and APE and wrote a quick demo app. All of the code for the demo app can be downloaded from http://code.google.com/p/pyramid-ape-demo/.

In the html/ directory, the files, graphics and javascript files required to run the client side of the app are included. In the ape_server/ directory, the javascript that needs to be installed in the Ape Server scripts/ directory is present. You’ll want to modify the password. Also included in the html/ directory is a python script called push.py which allows you to use urllib2.urlopen to communicate with the server directly. And finally, in the ape/ directory is a very minimal Pyramid application. pyramidape.wsgi is also included as a starting point to get the site set up.

In the demo, the left hand Coke can is controlled completely by the Ape Javascript Client code. Communications between the browser and Ape server are not processed by anything but Ape. On the right hand side, the Coke can is controlled by a json post to Pyramid and then Pyramid uses urllib2.urlopen to communicate with Ape which then updates the page.

Changes made on the page are reflected among all of the other people that are currently viewing the page in realtime. Since we’re using Ajax push, the page doesn’t need to be reloaded to show those changes. In this example, an img src and the alt text is changed along with a button. You can write your script to modify any html on the page – changing the colors of the page, elements, etc.

Using Ajax push and long polling with Pyramid isn’t difficult and this simple demo and example code should be a good starting point.

Entries (RSS) and Comments (RSS).
Cluster host: li