The WSGI app

All ferenda projects contains a built-in web application. This app provides navigation, document display and search.

Running the web application

During development, you can just runserver. This starts up a single-threaded web server in the foreground with the web application, by default accessible as http://localhost:8000/

You can also run the web application under any WSGI server, such as mod_wsgi, uWSGI or Gunicorn. ferenda-setup creates a file called alongside which is used to serve the ferenda web app using WSGI. This is the contents of that file:

from ferenda.manager import make_wsgi_app
inifile = os.path.join(os.path.dirname(__file__), "ferenda.ini")
application = make_wsgi_app(inifile=inifile)

Apache and mod_wsgi

In your httpd.conf:

WSGIScriptAlias / /path/to/project/
WSGIPythonPath /path/to/project
<Directory /path/to/project>
    Order deny,allow
    Allow from all

The ferenda web app consists mainly of static files. Only search and API requests are dynamically handled. By default though, all static files are served by the ferenda web app. This is simple to set up, but isn’t optimal performance-wise.


Just run gunicorn wsgi:application

URLs for retrieving resources

In keeping with Linked Data principles, all URIs for your documents should be retrievable. By default, all URIs for your documents start with http://localhost:8000/res (e.g. http://localhost:8000/res/rfc/4711 – this is controlled by the url parameter in ferenda.ini). These URIs are retrievable when you run the built-in web server during development, as described above.

Document resources

For each resource, use the Accept header to retrieve different versions of it:

  • curl -H "Accept: text/html" http://localhost:8000/res/rfc/4711 returns rfc/generated/4711.html
  • curl -H "Accept: application/xhtml+xml" http://localhost:8000/res/rfc/4711 returns rfc/parsed/4711.xhtml
  • curl -H "Accept: application/rdf+xml" http://localhost:8000/res/rfc/4711 returns rfc/distilled/4711.rdf
  • curl -H "Accept: text/turtle" http://localhost:8000/res/rfc/4711 returns rfc/distilled/4711.rdf, but in Turtle format
  • curl -H "Accept: text/plain" http://localhost:8000/res/rfc/4711 returns rfc/distilled/4711.rdf, but in NTriples format

You can also get extended information about a single document in various RDF flavours. This extended information includes everything that construct_annotations() returns, i.e. information about documents that refer to this document.

  • curl -H "Accept: application/rdf+xml" http://localhost:8000/res/rfc/4711/data returns a RDF/XML combination of rfc/distilled/4711.rdf and rfc/annotation/4711.grit.xml
  • curl -H "Accept: text/turtle" http://localhost:8000/res/rfc/4711/data returns the same in Turtle format
  • curl -H "Accept: text/plain" http://localhost:8000/res/rfc/4711/data returns the same in NTriples format
  • curl -H "Accept: application/json" http://localhost:8000/res/rfc/4711/data returns the same in JSON-LD format.

Dataset resources

Each docrepo exposes information about the data it contains through it’s dataset URI. This is a single URI (controlled by dataset_uri()) which can be queried in a similar way as the document resources above:

  • curl -H "Accept: application/html" http://localhost/dataset/rfc returns a HTML view of a Table of Contents for all documents (see Customizing the table(s) of content)
  • curl -H "Accept: text/plain" http://localhost/dataset/rfc returns rfc/distilled/dump.nt which contains all RDF statements for all documents in the repository.
  • curl -H "Accept: application/rdf+xml" http://localhost/dataset/rfc returns the same, but in RDF/XML format.
  • curl -H "Accept: text/turtle" http://localhost/dataset/rfc returns the same, but in turtle format.

File extension content negotiation

In some environments, it might be difficult to set the Accept header. Therefore, it’s also possible to request different versions of a resource using a file extension suffix. Ie. requesting http://localhost:8000/res/base/123.ttl gives the same result as requesting the resource http://localhost:8000/res/base/123 using the Accept: text/turtle header. The following extensions can be used

Content-type Extension
application/xhtml+xml .xhtml
application/rdf+xml .rdf
text/turtle .ttl
text/plain .nt
application/json .json

See also The ReST API for querying.

Using develurl during development

When deploying, you won’t use http://localhost:8000/ in your public-facing URLs. Instead, come up with an external base url such as, and in ferenda.ini set:


This will make all uris in parsed and generated documents on the form, but during devel still support http://localhost:8000/res/rfc/4711.

When you set url to a new value, you must re-run ./ all generate --all --force, ./ all toc --force, ./ all news --force and ./ all frontpage --force for it to take effect.