Introducing BitSyncHub Since I’m an automation nut, when I found Travis CI, I was understandably excited - automatic running of my testcases for hgapi from the repository as opposed to a pre-push hook (as I have had it set up since the beginning of time) would avoid the oh-so embarrassing mistakes of forgetting to add a new file to the repository and having a non-working version in the repo. I just have to set up some service to synch to the GitHub mirror and all will.
I’ll be in Florence for EuroPython 2013 and do (more or less) a follow-up to the training session I held last year - a very hands-on venture into Python lanugage and standard library features that will allow you to implement your bad ideas in awesome hacks and good ideas with beautiful magic. This is how fun we had last year!
Ok, so they’re all looking at their screens, but that’s kind of the point with a training session in my opinion, hands on keyboards as much as possible.
The other day I needed to download some zip files, unpack them, parse the CSV files in them, and return the data as dicts. I did the very same thing a couple of years ago, and although the source is lost, I recall having a Python (2.4?) script of about two screens to do the download - so a hundred lines. When re-implementing the solution now that I know Python and the standard library better, I ended up with 12 lines written in just a few minutes - edited for blogging clarity it clocks in at 13 lines:
When we started with fleet management at Visual Units, one thing was really hard to get right - distance calculations. There was no end of information available, but most-to-all of it was on a level of mathematics far beyond a poor developer who feels that anything beyond discrete mathematics and basic geometry and statistics really should be somebody else’s problem. The implementations that could be found were closed-source licensed version we really could not afford at that stage.
(part 1, part 2, part 3, part 4)
I’m almost done with the parts to make this project PyPI ready - it can now work on your application as long as you implement the actual code to route calls to the right part of your API - this works:
python -m pyrest.launcher –server pyrest.integration.cherry \ –api=pyrest.examples.hg Configuration can also be done using a config file instead of or together with command-line arguments.
(part 1, part 2, part 3)
I’ve now split the code into separate parts - pyrest.py now only has generic functionality for hooking and routing, along with a bunch of helpers to create responses with HTTP response types. In fact, it’s only 35 lines of code, and that’s the entire ‘core’ of pyRest so far.
The CherryPy integration has moved to the pyrest.integration package as cherry.py - it’s still pretty clumsy to use (python -m pyrest.
In part 2, I hooked up the API to CherryPy in a very crude fashion, and this time we’ll look at how we can add handlers for resources in a less clumsy way. I decided to keep handlers on one ‘level’ only - that is, /sketch/parrot and sketch will both be handled by the /sketch handler. This is because I find that the same sub-resource often is present in several places (what about //props/parrot?
In part 1, a very unexciting base CherryPy implementation was all we had, but now it’s time to hook up something real! Instead of creating a mock API to work against as example code, I’ve decided to use hgapi to access the pyrest repo itself as example implementation - very meta!
I’ve decided to hook the API in before I refactor the code to separate the web framework from pyRest, since I firmly belive in getting things working first and cleaning up after.
After having written code to expose APIs through RESTful web services a couple of times, I’ve decided to do it once more, only this time I won’t get paid, I won’t have deadlines, I’ll write it so I’ll never have to write it again, and I’ll make it available as open source.
Problem is, I’m a lazy, lazy person, and have not been able to muster the energy to actually get writing, which leads me to this blog post - since I’ve not been updating the blog as I should either, I’ll kill two projects with one meeting and make the actual development process open as well, as a series of blog posts and a repository at BitBucket.
I got a feature request on hgapi the other day, pointing out that it was not possible to filter the Mercurial log using the API, since there is no dedicated way to do it and the fallback method - sending keyword arguments that will be passed to the command line - does not work. The signature of the method in question is
def hg_log(self, identifier=None, limit=None, template=None, branch=None, **kwargs): with kwargs accepting any keyword arguments and passing them to the command line.