Rookeries v0.17.0 – Auto-Building + Multi-Template Support

Recovering from PyCon Canada 2019, and the holidays took longer than I expected. However I am pleased to announce the release of version 0.17.0 of Rookeries to start off this new year!

Version 0.17.0 includes a number of improvements to the serve command:

  • Auto-building of the site when a file in a project changes.
  • Opening of the resulting build site in a browser using the --open flag.
  • Auto-refreshing of the opened site when in development mode.

In addition, I added:

  • Multi-template support which will allow for building out complex templates in the future.
  • Improvements to the UX experience.

If you are running version 0.16.0, you can run a re-install using the rookeries-online-installer.sh to update to the latest version. Otherwise you can install v0.17.0 by following the instruction on the Download page.

Next Steps

As for what I plan to work on next, I want to improve the infrastructure around downloading, installing and working with both plugins and templates. I will be using my new site for my Juggling JSON with jq Cookbook ebook as a test bed for improving working with Rookeries. That way I have some real use cases outside of Rookeries’ project page. I am looking forward to working on both projects and see how they both develop in parallel.

Do you know that my mailing list is the first to know about releases and developments around Rookeries? Consider subscribing to the mailing list to be among the first to know!

PyCon Canada 2019 Retrospective

This Tuesday marked the last day of the coding sprints, and with that PyCon Canada 2019 ended. Now that I have wrapped up my own commitments for the conference, I feel that I should post a brief retrospective on how the conference went.

Overall the conference this year turned out very well! The organizers received a lot of praise for our hard work. And I am humbled that I can be counted as one of the core organizers. I am seriously considering helping out again next year with the sprints.

Preparation

Any larger conference takes time and energy to prepare for. PyCon Canada 2019 proved no different. Thankfully experience from last year proved valuable in getting everything to come together. As the event drew closer, we were able to stay on track with the work, through meetings, emails and messages.

If you never worked on a conference organization team, you do not realize how much work goes into a conference:

  • Picking out a venue.
  • Choosing an appropriate mix of talks.
  • Organizing schedules and volunteers.
  • Ensuring equipment runs smoothly.
  • Designing promotional material, merchandise, websites, etc.
  • Figuring out the catering to feed 500+ attendees.
  • Promoting everything.

Thankfully we had a great team, and were able to make everything come together. Thank you Elaine Wong, and Chris Fournier for chairing this conference, and getting us all through it! Thanks to the team I focused on the sprints, and getting my employer to sponsor the conference, while others could focus on other aspects of the conference.

Venue

The Carlu proved an excellent venue for the conference. Not only a stylish, comfortable, compact (but not crowded) space but also staffed by a very professional crew. We only ran into a few minor technical difficulties, but otherwise the operation went smoothly. The catering and food was amazing, even impressing our French Canadian attendees (who are accustomed to good cuisine)! Hopefully we will be able to use the space again in the future.

Sponsors

Corporate sponsors help keep PyCon Canada reasonably priced, and in turn as an organizer, I hope the sponsors find it benefitial. A conference lets sponsors get the word out.

During the conference I ended up chatting with quite a few of the sponsors. The visual effects and animation studio DNEG was an unexpected sponsors. I ended up chatting with their reps a lot about their asset setup (in-house Python), and their work. (I am a huge nerd when it comes to computer graphics and animation.)

Also it was nice to see the other sponsors:

It was great talking to all of you, and I learned a new thing.

I also appreciate all the effort that went into getting all the sponsors onboard. Getting my own employer to sponsor proved a bit more involved than I expected. Even though everyone at Points wanted to go, details of who could go, what benefits to expect from the sponsorship, which budget would be involved, etc., took a bit to figure out. I am hoping that planning for next year’s conference starts early, and because of that the sponsorship experience goes more smoothly.

Talks

I enjoyed our selection of talks this year! And I heard similar sentiments from other attendees. Unforunately as a speaker and organizer, I did not get to see many talks, these are the ones really stood out for me:

I also presented my talk Rust Accelerated Python at PyCon Canada this year. It went very well, thank you to both Elaine and the session chair for making the session go well. I found the setup for the slides vs. speaker notes a bit fiddly, but not terribly. Otherwise my edits to make the talk more concise went well, and I had time for a QA! Overall I got a lot of interest in both Rust and creating bindings in Python. Ended up fielding quite a few questions about the state of the Rust ecosystem, how useful would it be to learn Rust for data science, etc. I am super happy that was able to both educate and entertain, and enjoy doing so!

You can view the talk slides here and the associated BitBucket repo here.

Sprints

Finally the coding sprints went very well. Apart from some minor organizational snafus that almost noone noticed, and that I plan on improving for next year, the sprints went very well. We got a good mix of both experienced and novice developers come out. People sprint on around 8-10 projects including: pyodide, graphene, pylint, commitzen, flask and statsmodels. Overall people enjoyed the sprints, and many of the first time sprinters expressed wanting to sprint again!

I personally I got to work on the pyodide project, once everyone was settled in:

Thanks to Mozilla Toronto for providing the space and hosting us! And thanks again to Elaine with making sure we had coffee, sweets and pizza to fuel the sprinters!

Speaking At PyCon Canada 2019 – Rust Accelerated Pythons

I am happy to announce that I will be giving a talk on Rust and Python at PyCon Canada 2019: Rust Accelerated Pythons!


I will be talking about how to write Python bindings for Rust. With Rust you can create and call fast native code without worrying about having to use C/C++. And creating Python bindings is pretty easy in Rust. This talk will give an introduction to the Rust language, the challenges of writing cross-language bindings, and an example of working with the excellent PyO3 library. Hope to see you there if you are in the Toronto area for PyCon Canada!

If you can’t make it out to PyCon Canada this year, I also plan on giving this talk at an upcoming Rust Toronto meetup. More details will on that in a future post.

Rookeries v0.16.0 – Cross-Platform Support

On Wednesday night, I released version 0.16.0 of Rookeries, my developer/designer friendly static site generator! What makes this release exciting is that I added cross-platform support for macOS and FreeBSD! Also I setup an cross-platform installer, that works on all 64-bit x86 Linux distros including Windows Subsystem for Linux (WSL) 2.0. And I plan on supporting Linux, macOS (OS X) and FreeBSD as first-class systems going forward.

Also a multitude of stability and UX improvements landed in this release.
You can download Rookeries and install it using the new cross-platform installer here.

Rookeries v0.16.0 screenshot

Now this took quite some time and effort, especially around figuring out cross-compiling and what each OS could reasonably support. Over the course of the next few weeks, I will be writing about the challenges and how I overcame them when adding cross-platform support. (Including a quick aside why I dropped native non-WSL Windows support, and took up FreeBSD instead.)

Do you know that my mailing list is the first to know about releases and developments around Rookeries? Consider subscribing to the mailing list to be among the first to know!

Rookeries v0.15.0 Released – Technical Preview of the Static Site Generator

It turns out that rewriting a CMS into a static site generator takes a bit of time. 😉 After 3 months of silence, I can finally announce the long awaited release of version 0.15.0 of Rookeries. This release is the first fully functional technical preview of the static site generator!

You can now create, build and develop a full site with Rookeries! In fact I rebuilt the Rookeries site, using Rookeries to prove out the concept. You start by using the generator to setup a new project. Then you can add Markdown files to build new pages to an existing site, change the HTML and CSS templates, and run a build which creates a modern site. A site that in essence is a server-side rendered single-page application. So if you are running Debian or Ubuntu Linux you can try it out Rookeries by installing the deb package.

Now, this release is a technical preview release to demonstrate the concept. I plan on making the template and plugin systems more flexible. Also I want to improve the usability by adding an automatic rebuild when a page is edited. And I need to write proper documentation as well. Support for other operating systems and distributions is also in the works. However already Rookeries is significantly faster than its nearest competitor: GatsbyJS and smaller in size. And you get a nicer, more maintainable site than from many other tools.

So please take Rookeries for a spin, and let me know how you like it!

Rookeries v0.13.1 – Release + Web Assembly Experiments

This past month I’ve been trying to determine the future direction I want to take my projects: especially Rookeries. Ultimately I want to build something that lasts and is able to sustain itself financially. As someone who is still a novice in the arts of marketing, and business development, this is hard, and doing this in an open, transparent environment like with libre software, just adds to it. While I have many musings on what is needed to run a sustainable open source project, they are just that: musings. Without getting into the weeds, I think the Ghost blogging platform team is doing the right thing. I recommend the Indie Hacker podcast that interviews John O’Nolan of Ghost.

Also I’ve been playing around with some of the interesting Rust Web Assembly projects out there. I think they have potential to improve Rookeries in a radical manner. However before I get anyone’s hopes up, I want to get something working before I announce the future direction of Rookeries. (Something, something, Web Assembly, something, something, plugin extensibility.) In the meantime I am releasing version 0.13.1 of Rookeries!

This version is mostly bug fixes, and code re-organization that will help me extend the project into the future.

P.S. My mailing list knows about my releases and plans of Rookeries, before the blog. So you should totally sign up for the Rookeries mailing list.

Rust + Gtk = Wow

As I’ve been experimenting with writing Rust apps, I attempted to create a small little GUI application. At first I attempted to setup everything with Qt, but C++/Qt interoperability with Rust is painful. Very, very painful. I experimented with some more radical UI frameworks such as Azul and Conrad. These have a lot of promise going forward. However for the here and now, I recommend looking at gtk-rs, Rust binding for Gtk.

With a bit of experimentation, looking through gtk-rs examples, some other projects using gtk-rs, and lots and lots of searching, I was able to create this:

This is a code viewer that lets you open Rust code, and view it. Yes, you are looking at a portion of the code that runs that code viewer. Getting the GtkSourceView working took some coaxing. Also I had to learn how to use the Glade UI editor for Gtk. Overall it took me about 2 to 3 hours to pull this off. I am very impressed with the results, and it opens up new possibilities for me.

Packaging up a Rust Binary for Linux

Prologue

I should of written an update for quite some time. While I’ve been experimenting with marketing analytics, learning about data science, business development, doing DevOps with GitLab CI and various other things, I wanted to write up my learning when I had a chance to internalize everything. However what made me decide to write an update is this tweet from Chris Krycho. Chris runs the amazing New Rustacean podcast, which is a must listen for anyone interested in learning about programming in Rust.

How does one package a Rust app?

Chris asked about finding a good way to distribute Rust binaries across Linux distros:

Interestingly enough, I recently figured out how to package a small Rust CLI utility that I’m working on. My response was:

This post elaborates on what I meant with my reply.

Building snap packages using snapcraft

The fine folks at Canonical (the makers of Ubuntu Linux), have created something called snap packages. These packages and associated package manager help developers distribute applications (desktop, cloud, etc.) in a safe, isolated manner. I currently have slack installed this way. snaps isolate apps by having the package maintainer declare the capabilities an app requires (network access, access to system files, the GPU, home directory, etc.), and then ensuring the apps can not escape this sandbox.

Basic Setup

Getting setup with packaging a Rust crate was not too hard:

  1. Install snapcraft: sudo snap install snapcraft --classic
  2. Create a snap template inside your crate project: snap init
  3. Edit the generated snap/snapcraft.yml as per the documentation.
  4. Build the snap using snapcraft.
  5. Install the resulting snap with sudo snap install my-cool-rust-bin_x.y.z.snap --devmode --dangerous (this assuming you are experimenting with building a snap)
  6. Add you should be able to distribute your app as a snap now. (See the caveats below.)

Caveats working with snaps

Now there a bunch of caveats when working with snaps. And for my own Rust utility, I found these too taxing and I decided to go with creating a standard Debian package instead. However if I wanted to target multiple distributions and my app didn’t have a very unorthodox setup (my app relies on using the Chrome WebDriver to control a networked device managed by dd-wrt), I would probably have gone with a snap instead:

  • You need to know what capabilities your app needs: file access, network, etc. and you need to declare the appropriate interfaces in your snapcraft.yml
  • Using something other than my local system (be it a Docker based build or using a different base like base18), failed terribly at least for Rust.
  • Whether or not I’d have more success if my base system was the recommended Ubuntu 16.04 and not 18.04 is an outstanding mystery.
  • The snap confinement, even on the much more liberal devmode, works very well. No amount of coaxing on my part, let me use system paths when trying to spawn a process. This could just be me though, as not declaring network access did not block my app.
  • The docs could of been clearer about what was the latest recommended approach. (Still way clearer than the documentation for creating a DEB or RPM from scratch.)
  • Knowing which libraries (for the type of base system) your app needs takes a bit of experimentation. (e.g. I needed libssl1.0 for some builds and libssl1.1)
  • I have no idea how the classical confinement should work, and it is not recommended either way.

The end result for me was a working snap package, but an app that would not work when called from an installed snap. However I think snap packages are probably the way to go moving forward (or a similar format like flatpak). Since I only plan on targeting local Ubuntu 18.04 installs, I ended up creating a Debian package instead.

Building a Debian package with Cargo

I found a nice utility for creating a deb out of a Rust crate, called cargo-deb. After installing the crate with cargo: cargo install cargo-deb, I simply ran cargo deb and I was done. cargo-deb looked into my Cargo.toml for the metadata, ran a build and a few moments later I was the proud owner of a Debian package. Since my app relies on the chromium-browser and chromium-chromedriver packages, I added a small section in my Cargo.toml as so:

[package.metadata.deb]
depends = "$auto, chromium-browser, chromium-chromedriver"

The $auto is something that the Debian packaging mechanism needs, and that is the comma separated format that DEBs use.

Building a RPM from a DEB package

Now this the part that I didn’t do this time around. However I figured out how to create RPM packages from DEB packages a few months ago. The trick is to use the alien utility to create a RPM out of a DEB:

sudo alien --to-rpm --scripts --verbose my-cool-rust-bin.deb

For the record, I did not try to improve or debug the resulting RPM. (This entire effort was for a product that failed to launch.) However as part of my tests I was able install it and run it from on CentOS VM.

Epilogue

Anyways, I would recommend the cargo-deb and alien approach, if you are not planning to distribute a Rust app across a multitude of Linux distros. I would recommend dipping into snap if you plan on distributing something more commercial and wide-spread like a slack or kubectl. And I hope that helps you on your Rust app packaging for Linux journey!

Embedded Rust Library Experiment for Python and Web Assembly

With my ever growing list of things that I need to catch up (like wiring my home network and managing Rookeries), I needed a small fun project that I can work on. Ever since I learned enough Rust to be able to convert Rookeries, I wanted to play around with being able to speed up my code with a Rust library. I am especially interested in figuring how to call Rust code from Python or from JS with Web Assembly.

As a test bed (and a reason) for me to learn this, I created a small little library for getting the uptime of a local server (Linux only): embedded-uptime converting between different measurement units like Celsius and Fahrenheit: embedded-unit-converter. If you’d like to follow along, feel free to check it out. I will be posting updates on the blog, and on the Rookeries mailing list.

Updated on 2019 February 4: When I setup the project, I forgot that server uptimes that rely on accessing a server’s /proc/uptime can not possibly work in Web Assembly in browser environment. After some consideration I decided to go with something simple that accessible from any platform, namely conversion between different units of measure.

Onward with Postgres and Diesel – Rookeries v0.13.0

That took longer than expected… but I’ve finally migrated Rookeries to use PostgreSQL 10! I finished the majority of the raw migration work about a week before PyCon Canada. However I did not want to confuse my updates and tweets related to PyCon Canada with my work on Rookeries. Also I wanted to add a few bits of polish, create a mailing list for Rookeries and fix up any issues I found with the site. (Quite a few data and TLS certificate issues happened along with this release.)

I found that migrating Rookeries from CouchDB to PostgreSQL quite challenging. This adds yet another data point to those that argue that fixing data models and databases can be significantly harder than fixing applications. One of the challenges I stumbled in was mapping the various keys in a CouchDB document for a resource, into a table. Fortunately the JSONB columns allowed for the flexibility to let me resolve some of my earlier problematic data designs later on. I also needed to familiarize myself with diesel.rs, the amazing ORM/database engine library for Rust. I struggled with understanding how custom types worked in Rust, and why they make database mapping of columns easy for more advanced mappings (like optionally nullable, JSONB and Array). However I managed to figure out even the hard parts using a combination of the documentation and by peeking into the test cases for diesel. Having a migration tool in the companion diesel-cli utility, provides the nicest UX for building out database migrations and mapping them to code. Overall the effort paid off and I am convinced that Rust has one of the cleanest and maintainable ORM/database libraries I’ve seen.

As mentioned earlier, I created a mailing list dedicated to Rookeries updates. I will continue to blog about releases, but if you are interested in the internals and development of Rookeries, then this mailing list a good thing to follow. Consider it like a journal that you can also reply back to and enter in a conversation about the development of Rookeries. I added a panel to the side of the site, that makes subscribing to Rookeries easy.

This will hopefully will be the last of the major technological shifts for the project, at least on the backend. The next releases I plan on concentrating on getting Rookeries in a state where I can drive Gatsby powered static sites via REST APIs. Once that becomes a reality, I will work on replacing my WordPress sites with Rookeries powered sites.