Since I got several requests for BitSyncHub to support BitBucket Git repository synching to GitHub, I went ahead and added the functionality. The service will dedtect the appropriate repository type, and push specified branches - although the source branch will be ignored for now, so a branch speficiation of ‘foo:bar’ will simply push ‘bar’.
To make this happen, I finally had to bring gitapi a bit closer to completion, so I released the first version to PyPi for general consumption as well.
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.
(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.
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.
My name is Fredrik, and sometimes I write code I’m not that proud of.
A friend of mine started on a Python project recently, and when I asked him to put it up on Bitbucket his response was an immediate and not-quite-mock “But then people will see my code!”. I believe this fear of showing one’s code is common, and I believe that it is a problem. Not so much for open source, or anything like that, but for the individual - it suggests a belief that your code isn’t good enough, that other people’s code is better, and/or that offering my code up for others to see will lead to rejection and ridicule.
Edit: got complaints that code was hard to read, trying out Pygments.
In part 1, we looked at sending functions as arguments to other functions, at nesting functinons, and finally we wrapped a function in another function. We’ll begin this part by giving an example implementation on the exercise I gave in part 1:
>>> def print_call(fn): … def fn_wrap(*args, **kwargs): … print("Calling %s with arguments: \n\targs: %s\n\tkwargs:%s" % ( .
Since I, in retrospect, made the wrong choice when cutting down a Python course to four hours and messed up the decorator exercise, I promised the attendees that I’d make a post about closures and decorators and explain it better - this is my attempt to do so.
Functions are objects, too. In fact, in Python they are First Class Objects - that is, they can be handled like any other object with no special restrictions.