When you’re building a Web API, you’re likely going to need to figure out how to provide documentation to your end-users. If you didn’t think of that when you started your project, it can be a real deflating moment when it finally comes to mind. Documentation is boring and tedious. It’s nowhere near as fun as code.
Because documentation is boring, most software developers will quickly turn towards documentation tools. It’ll be so much faster to write documentation if we can just build or apply some software to do it, and building a software tool is much more fun than just sitting down and writing.
Documentation tools have advantages over hand-written documentation: they’re easier to keep up-to-date, they can produce output much faster, and they can provide much better coverage with less effort. But, before you go looking at API documentation tools, take a step back and figure out some high-level details about what your documentation looks like.
Cross-site request forgery (CSRF) is a type of security exploit where a user’s web browser is tricked by a third-party site into performing actions on websites that the user is logged into. It is often a difficult attack to pull off, as it requires a number of factors to line up at once. Protecting against it requires good discipline and good design practices, especially when it comes to protecting Web APIs.
Here’s a brief example of a fictitious CSRF attack against a bank:
My customers will be angry if I break my API.
When you release your Web API, it’s carved into stone. It’s a scary commitment to never make an incompatible change. If you fail, you’ll have irate customers yelling in your inbox, followed by your boss, and then your boss’s boss. You have to support this API. Forever. Unless you version it, right?
After publishing The Web API Checklist, I received comments (#1, #2) regarding API versioning. Before you struggle with how to version your API, I want you to know how to design your API to avoid future incompatibilities.
If my API is well designed, it won’t be fragile.
It is possible to design your API in a manner that reduces its fragility and increases its resilience to change. The key is to design your API around its intent. In the SOA world, this is also referred to as business-orientation. It’s a difficult design concept to understand, best explained with a fictitious example:
pyPdf and pg8000 have been ported to run under Python 3.0a1, in new Mercurial repository branches.
pg8000 is a Pure-Python database driver for PostgreSQL, compatible with the standard DB API (although under Python 3.0, the Binary object expects a bytes argument). pg8000 does not yet support every standard PostgreSQL data type, but it supports some of the most common data types.
pyPdf is a Pure-Python PDF toolkit. It is capable of reading and writing PDF files, and can be easily used for operations like splitting and merging PDF files.
I am pretty happy with the upgrade to Python 3.0a1. The 2to3 conversion utility provides a good start for some of the most mechanical of changes. pyPdf and pg8000 used strings as byte buffers pretty extensively, especially pyPdf, and so the changes were pretty extensive.
Having a good test suite is essential to the upgrade process. That was why I chose these two projects to start with, as I have a pretty good pg8000 test suite, and a very comprehensive pyPdf suite. After running 2to3 on the source code, it was just a matter of beating the code into order until all the tests run. It took about 4 hours per project, but many projects wouldn’t have as many changes as these projects have.
There are a couple of unexpected behaviours (in my opinion) regarding the new bytes type:
- b"xref" != b"x". Getting a single item out of a bytes type returns an integer, which fails to compare with a bytes instance of a length 1.
- b"x" == "x" throws an exception, rather than returning False. This exception is useful for finding places where byte/string comparisons are being done by mistake, but I ran into one instance where I wanted to compare these objects and have it be false. It was easy to code around.
- You can’t derive a class from bytes. I hope that this will be fixed in future releases, since pyPdf’s StringObject class derived from str previously. (It can’t derive from str now, since the PDF files have no encoding information for strings [that I know of…])
Good work on Python 3.0a1, developers! I love the separation of strings and byte arrays, even though it took me a lot of work to fix up these couple of projects. It’s the right way to do things.
A new version of pg8000, a Pure-Python interface for the PostgreSQL database, has been released today. This version supports DB-API 2.0 as documented in PEP-249. The request to add DB-API support to pg8000 was the biggest thing I heard about over the last pg8000 release.
Also new in version 1.02 is SSL support, datetime parameter input, comprehensive unit tests, and bytea object support.