Running wdb alongside your development server

We've been using the wonderful wdb WSGI middleware tool at work to aid in debugging our Flask app. The features it brings to the table have helped immensely with development, and it has quickly established itself as a integral part of my toolbox.

One minor issue I had with it, though, was the fact that one needs to manually start the wdb.server.py script before launching a development server. If only I could start and stop wdb whenever Flask did. Some Google-fu introduced me to bash's signal trapping features. After some experimentation, I devised the following wrapper script.

This has been working quite reliably for us. Here's hoping it helps you!

Quick and dirty parameter passing in Angular 2; The Angling.

This is a followup to an earlier post.

After pushing that hack out to the rest of my team, I felt some modicum of pride - I had, through understanding little-used parts (at least, publicly) of a poorly-documented framework, managed to reason out a nice solution.

Days passed and the codebase expanded. One day a teammate approached me and said, "Hey, you know that trick you used to pass the ID into the controller?" "Yes," I replied cautiously. "You didn't need it."

Insert "Duck typing" joke here.

Wat.

As a refresher, here's what I had ended up implementing:

<div data-ng-controller="ParentController">
    <div data-ng-repeat="childGuid in childrenGuids" data-ng-controller="ChildController" data-id="{{childGuid}}"/>
</div>

... which had some companion JavaScript in the repeated controller that read the value of data-id when the view was updated. There was no other way to pass data in to the ChildController, right? Wrong. Let's step back for a second.

Scope in Angular is special. While the framework goes out of its way to make it seem like things are tightly bound to the encompassing controller and that the DOM merely exists for presentation purposes, nothing (especially in web development) is ever that cut and dry.

Quoth the Angular documentation:

Scopes are arranged in hierarchical structure which mimic the DOM structure of the application.

and...

The Model is scope properties; scopes are attached to DOM where scope properties are accessed through bindings.

As my coworker reminded me, the scope referenced within the ChildController isn't bound to the controller, it's bound to the DOM. And, in the case of the repeater, the scope on the repeater node includes the childGuid property.

What the code looks like now...

<div data-ng-controller="ParentController">
    <div data-ng-repeat="childGuid in childrenGuids" data-ng-controller="ChildController"/>
</div>
var ChildController = function() {
    $scope.id = $scope.childGuid;

    var init = function() {
        // do initialization
    };

    init();
};

As you can see, on the second line of the controller, I'm directly referencing the repeated element. You don't need to re-assign it like I'm doing in this example, by the way, calling it directly won't/shouldn't present any issues.

An important caveat: if you think the controller might get used elsewhere, it would be beneficial to guard against instantiation without the required arguments...

var ChildController = function($exceptionHandler) {
    $scope.id = '';

    var init = function() {
        if (typeof $scope.childGuid === "undefined") {
            $exceptionHandler("The ChildController must be initialized with a childGuid in scope");
        }
        $scope.id = $scope.childGuid;
        // continue iniitialization
    };

    init();
};

And with that my hack was dead. This was a good thing as hacks are, by nature, smells that should be minimized.

The moral of the story? Write self-congratulatory blog posts about slightly-hacky solutions. Someone will submit a patch.

Capabale Chromecast Configuration (or, how I got Chromecast to work with Ubuntu)

So, I now own a Chromecast. Having acquired it while the Netflix promotion was in effect, I only ended up spending $11 on it. Not bad for a YouTube machine (the only reason I bought it since Roku still doesn't have YouTube support). I've been pretty happy with it thusfar as it turned out to be a great party tool, and the HDMI CEC support makes it really easy to throw YouTube videos on in the background, even if the TV is off.

However, one feature I was having trouble getting to work under Linux was tab casting. Using the Chromecast Chrome extension, one should be able to transmit the contents of a tab to a Chromecast on the local network. For some, reason, though, I was unable to do so. After some poking around, I determined that my firewall (ufw, the greatest misnomer of them all) was causing this. Since it was using a randomly assigned local port to establish the connection, simply opening a port wasn't the answer. Not to be deterred, I set about conquering this problem. Here's what I did.

  1. Find the Chromecast's MAC address. In my case this was a two-step operation...

    1. Launch the Chromecast app to determine the device's IP address.

      A screenshot of the IP address of a Chromecast desplayed within the Chromecast app.

      The IP address is circled in red.

    2. Ping the device and then check the address resolution stats.

      [aru@Ananke:~]$ ping -c 1 192.168.1.42
      PING 192.168.1.42 (192.168.1.42) 56(84) bytes of data.
      64 bytes from 192.168.1.42: icmp_req=1 ttl=64 time=1.66 ms
      
      --- 192.168.1.42 ping statistics ---
      1 packets transmitted, 1 received, 0% packet loss, time 0ms
      rtt min/avg/max/mdev = 1.669/1.669/1.669/0.000 ms
      
      [aru@Ananke:~]$ arp -a 192.168.1.42
      ? (192.168.1.42) at d0:e7:82:7c:15:76 [ether] on wlan0
      
  2. Assign a static IP to the device. Configure your router to assign a static IP to the MAC address you found in the previous step. If you don't know how to do this, Port-Forward.com has some decent tutorials. You may have to restart your router after setting up this rule.

  3. Determine your local port range. In my case, since I'm using IPv4, I did the following:

    [aru@Ananke:~]$ cat /proc/sys/net/ipv4/ip_local_port_range
    32768   61000
    

    The two numbers are the lower and upper bounds of the local ports available for casting.

  4. Whitelist your Chromecast. Using the now-static IP address and your local port ranges, tell ufw to step off!

    [aru@Ananke:~]$ sudo ufw allow proto udp from 192.168.1.42 to any port 32768:61000
    Rule added
    

Once you've done this, open up Chrome, click on the Chromecast button, and start tabcasting!

Chromecast extension screenshot.

As you can see, I don't use Chrome for very much.

Quick and dirty parameter passing in Angular

Don't use this code, instead, read this post and then read the follow-up.

Since my last post I've switched teams at work after completing a massive redesign of all of my old team's webapps. The overhaul saw the unification of the look and feel of the product's core webapps, with a significant amount of instrumentation and modularity to enable the less aesthetically-inclined people within the team to contribute without reducing the overall coherence of the application.

It just so happens that I joined my new team just as they were planning a massive redesign of their frontend! After assessing our users' needs and desires, we set out to redesign our stack. I'm not going to go into the full details of the transition in this post, but we settled on a Python stack running AngularJS, Flask, uWSGI and nginx (a huge improvement, development-wise, from our current JQueryUI, TurboGears, mod_wsgi and Apache system).

Prior to this redesign effort, my only experiences with client side MVC frameworks were with KnockoutJS, a great JavaScript library for manging databinding. However, when you scaled it up to include things like validation, complex objects, RESTful behavior against remote resources, and DOM manipulation, it really started to show its seams. Part of what attracted me to Angular was its similar approach to data binding, but with a stricter separation of concerns between the controller and view layers.

I could continue to wax poetic about our decision, but I'll save that for another post. I just wanted to provide some backstory for this post.

Just the other day I found myself writing a controller that instantiates new child controllers via a repeater...

<div data-ng-controller="ParentController">
    <div data-ng-repeat="childGuid in childrenGuids" data-ng-controller="ChildController" />
</div>

This worked fine. Pushing a new item to ParentController's $scope.children array would generate a new ChildController. However, I soon discovered that what I was attempting to engineer would require each ChildController to have a unique ID, generated by the ParentController prior to the child's instantiation. I attempted to use templating to my advantage in various ways, for example:

<div data-ng-controller="ParentController">
    <div data-ng-repeat="childGuid in childrenGuids" data-ng-controller="ChildController">
        <input type="hidden" value="{{childGuid}}" />
    </div>
</div>

No dice. Why not try broadcasting from the parent scope after I push something to the stack? I feared race conditions. Why not a directive? It felt like too much code for something that should be simple. After reading the relevant portions of the Angular docs several times over, I threw together a nice little hack that got the job done.

<div data-ng-controller="ParentController">
    <div data-ng-repeat="childGuid in childrenGuids" data-ng-controller="ChildController" data-id="{{childGuid}}"/>
</div>
var ParentController = function() {
    $scope.childrenGuids = [];

    $scope.addChild = function() {
        var guid = newGuid();
        $scope.childrenGuids.push(guid);
    };
};

var ChildController = function() {
    $scope.id = '';

    var init = function() {
        //finish initialization
    };

    $attrs.$observe('id', function(value) {
        if (!$scope.id) { //defensive sanity check
            $scope.id = value;
            init();
        }
    });
};

Essentially, what I'm doing is passing the ID in via the controller declaration. However, because of the order in which Angular digests the markup, interpolation of templated attributes happens after the construction of the controller. Because of that, I had to instruct the framework to do some extra processing when the interpolation event fired and the data-id attribute was updated. After that the controller is free to finish its initialization phase.

Happy with the outcome, I pushed my changes out to my team and made a note to revisit this block when I get around to refactoring this section (it'll happen, don't worry).

EDIT: It happened.