As I have been building IndieWeb services, I have found some of the code I have written to be useful across multiple applications. For instance, I wrote logic that initialises and verifies an authentication request using IndieAuth. I copied this same code across my Webmention endpoint, Micropub server, and other tools with minor modifications. The downside to this was that every time I wanted to make a change to that logic, I had to make a change in several places.
I started to think about what I could do to bring important pieces of code into one place. I then asked myself: should I make a library that packages some of the key IndieWeb functions that I need to build applications? With a library, logic such as verifying an IndieAuth request or canonicalizing a URL (formatting a URL in a standard way) could be kept in one place. Any update I made to the main version of the code would be reflected across my applications. After some thought, I decided to build indieweb-utils, a Python library with building blocks that will assist developers in building IndieWeb applications.
The decision to make a library started back when I wanted to bring all of my authentication code into one place. I decided to make a library that would just contain my authentication code that I use across various services. Then, I thought: what about all of the other IndieWeb functions and modules I had written? Should they be packaged in this library too? Should they be separate?
I decided to create one big library that included code for functions that are useful in building IndieWeb applications. Building separate libraries would add a lot of overhead in terms of documentation and configuration. Also, some libraries would turn out to be very small so all of that overhead would not necessarily be justified.
A few conversations in the IndieWeb chat led me to the conclusion that a single library with core IndieWeb utilities would be most useful for both me and other developers. The broad scope of the library, implied by its name and definition, means that the library is not confined to implementing a particular standard. This broad scope means I do need to be careful about what I include, something I take seriously. To identify what functions should be in the library, I ask myself: what building blocks are useful for building IndieWeb applications?
The term "building blocks" is crucial because I do not want the library to fully implement every specification or feature that the IndieWeb community develops and matures. indieweb-utils provides features to help you implement IndieAuth but will not fully implement the specification out of the box. This means you can consider your own implementation and code how you need to, with reference to utilities that can help you build your application as you want. There is no single perfect implementation of any IndieWeb ideas or standards/ indieweb-utils reflects that idea.
I looked at my code across multiple IndieWeb projects I made and asked myself: what features would be broadly useful in a library? I thought about the code that I had to repeat at least once over or may have to repeat again in future projects. I came to the conclusion that there were a few key functions the indieweb-utils library should have from the start, including:
All of these features could be used for multiple applications. You could use webmention endpoint discovery for a webmention endpoint or a sending tool configured with your site. You could use the IndieAuth callback handlers to speed up your implementation of any application that uses IndieAuth for authentication. You could use the reply context logic in a Micropub client to make it easier to get information about a resource to which you intend to reply on your site.
The indieweb-utils library uses Read the Docs and Sphinx for documentation. This is an ideal stack because Read the Docs and Sphinx provide many out-of-the-box documentation features that you cannot get from a simple markdown file in GitHub. For instance, I can use Sphinx and its autodoc feature to read docstrings and include them in my documentation. I can easily write tables of contents that outline what is on a page in the library.
Setting up the documentation for indieweb-utils took some time. I wrote docstrings for all functions in the script. Sphinx takes these docstrings and uses them to create rich documentation. I created a markdown file that documents all features in the library, how they work, and what response you can expect from them.
This is my first project using Read the Docs. I am still working my way through ensuring the documentation is what it needs to be. I had to spend some time checking the documentation to ensure my Restructured Text (RST) markdown was correct. I couldn't get the autofunction feature in Sphinx to work. This feature writes documentation based on a docstring. I had to spend time experimenting to get it to work. Note: make sure you include your project's library in your Sphinx requirements.txt file if you want to use the autodoc features.
The indieweb-utils Python library is now available to install. You can install it using the following command:
pip install indieweb-utils
I have published documentation for the library on Read the Docs. The documentation is available at indieweb-utils.readthedocs.io. But, this is only the beginning. Now that the documentation and library are publicly available, I suspect more work will need to be done to ensure the documentation and project meets expectations. If you decide to use the library, I would love to hear any feedback you have, from what you like to what you struggled to understand. This feedback will help me improve the library.
I am actively facilitating help in developing the library. If you have participated in the IndieWeb community and would like to help, feel free to take a look at the project GitHub page and see if there are any ways you can help. The main needs right now are to test the existing features. I am slowly working through my existing IndieWeb projects to use indieweb-utils and will submit patches if I encounter any issues. If you have a feature you would like to add, please create an Issue in the project GitHub page so we can discuss it.
This project is currently under active development. As a result, please do not expect the code to be fully polished. This is only the beginning of the library.
The indieweb-utils library is already helping me cut down on duplicate code across my projects. I hope that the library can help you implement IndieWeb features in your Python projects. If you have any questions, please refer to the project documentation and email me at firstname.lastname@example.org if you would like to chat.