Sphinx directive for RESTful HTTP API examples

sphinxcontrib-httpexample enhances sphinxcontrib-httpdomain, a Sphinx domain extension for describing RESTful HTTP APIs in detail, with a simple call example directive. The new directive provided by this extension generates RESTful HTTP API call examples for different tools from a single HTTP request example.

The audience for this extension are developers and technical writes documenting their RESTful HTTP APIs. This extension has originally been developed for documenting plone.restapi.

  • Configuration:

    The URL scheme, either http or https, used in the generated examples can be configured with the httpexample_scheme configuration variable. It defaults to http.

    # conf.py
    httpexample_scheme = 'https'
    
  • Syntax:

    .. http:example:: space separated list of tools
       :request: ../optional/rel/path/to/plaintext/request
       :response: ../optional/rel/path/to/plaintext/response
    
       Raw plaintext HTTP request example, which is
       required only when :request: is not specified.
    
  • Example:

    ..  http:example:: curl wget httpie python-requests
    
        GET /Plone/front-page HTTP/1.1
        Host: localhost:8080
        Accept: application/json
        Authorization: Basic YWRtaW46YWRtaW4=
    
  • Rendering:

    http

    GET /Plone/front-page HTTP/1.1
    Host: localhost:8080
    Accept: application/json
    Authorization: Basic YWRtaW46YWRtaW4=
    

    curl

    curl -i -X GET http://localhost:8080/Plone/front-page -H "Accept: application/json" --user admin:admin
    

    wget

    wget -S -O- http://localhost:8080/Plone/front-page --header="Accept: application/json" --auth-no-challenge --user=admin --password=admin
    

    httpie

    http http://localhost:8080/Plone/front-page Accept:application/json -a admin:admin
    

    python-requests

    requests.get('http://localhost:8080/Plone/front-page', headers={'Accept': 'application/json'}, auth=('admin', 'admin'))
    
  • Supported tools:

Examples of use:

Examples with inline sources

Example 1

Code
..  http:example:: curl wget httpie python-requests

    GET /Plone/front-page HTTP/1.1
    Host: localhost:8080
    Accept: application/json
    Authorization: Basic YWRtaW46YWRtaW4=


    HTTP/1.1 200 OK
    Content-Type: application/json

    {
      "@id": "http://localhost:8080/Plone/front-page",
      "@type": "Document",
      "UID": "1f699ffa110e45afb1ba502f75f7ec33",
      "allow_discussion": null,
      "changeNote": "",
      "contributors": [],
      "created": "2016-01-21T01:14:48+00:00",
      "creators": [
        "test_user_1_",
        "admin"
      ],
      "description": "Congratulations! You have successfully installed Plone.",
      "effective": null,
      "exclude_from_nav": false,
      "expires": null,
      "id": "front-page",
      "language": "",
      "modified": "2016-01-21T01:24:11+00:00",
      "parent": {
        "@id": "http://localhost:8080/Plone",
        "@type": "Plone Site",
        "description": "",
        "title": "Plone site"
      },
      "relatedItems": [],
      "review_state": "private",
      "rights": "",
      "subjects": [],
      "table_of_contents": null,
      "text": {
        "content-type": "text/plain",
        "data": "If you're seeing this instead of the web site you were expecting, the owner of this web site has just installed Plone. Do not contact the Plone Team or the Plone mailing lists about this.",
        "encoding": "utf-8"
      },
      "title": "Welcome to Plone"
    }

Note

Request and response must be separated with two or more blank lines and the first response line must start with string “HTTP/” or “HTTP “.

Result

http

GET /Plone/front-page HTTP/1.1
Host: localhost:8080
Accept: application/json
Authorization: Basic YWRtaW46YWRtaW4=

curl

curl -i -X GET http://localhost:8080/Plone/front-page -H "Accept: application/json" --user admin:admin

wget

wget -S -O- http://localhost:8080/Plone/front-page --header="Accept: application/json" --auth-no-challenge --user=admin --password=admin

httpie

http http://localhost:8080/Plone/front-page Accept:application/json -a admin:admin

python-requests

requests.get('http://localhost:8080/Plone/front-page', headers={'Accept': 'application/json'}, auth=('admin', 'admin'))

response

HTTP/1.1 200 OK
Content-Type: application/json

{
  "@id": "http://localhost:8080/Plone/front-page",
  "@type": "Document",
  "UID": "1f699ffa110e45afb1ba502f75f7ec33",
  "allow_discussion": null,
  "changeNote": "",
  "contributors": [],
  "created": "2016-01-21T01:14:48+00:00",
  "creators": [
    "test_user_1_",
    "admin"
  ],
  "description": "Congratulations! You have successfully installed Plone.",
  "effective": null,
  "exclude_from_nav": false,
  "expires": null,
  "id": "front-page",
  "language": "",
  "modified": "2016-01-21T01:24:11+00:00",
  "parent": {
    "@id": "http://localhost:8080/Plone",
    "@type": "Plone Site",
    "description": "",
    "title": "Plone site"
  },
  "relatedItems": [],
  "review_state": "private",
  "rights": "",
  "subjects": [],
  "table_of_contents": null,
  "text": {
    "content-type": "text/plain",
    "data": "If you're seeing this instead of the web site you were expecting, the owner of this web site has just installed Plone. Do not contact the Plone Team or the Plone mailing lists about this.",
    "encoding": "utf-8"
  },
  "title": "Welcome to Plone"
}

or with inline response starting with just “HTTP ” without the HTTP version:

http

GET /Plone/front-page HTTP/1.1
Host: localhost:8080
Accept: application/json
Authorization: Basic YWRtaW46YWRtaW4=

curl

curl -i -X GET http://localhost:8080/Plone/front-page -H "Accept: application/json" --user admin:admin

wget

wget -S -O- http://localhost:8080/Plone/front-page --header="Accept: application/json" --auth-no-challenge --user=admin --password=admin

httpie

http http://localhost:8080/Plone/front-page Accept:application/json -a admin:admin

python-requests

requests.get('http://localhost:8080/Plone/front-page', headers={'Accept': 'application/json'}, auth=('admin', 'admin'))

response

HTTP 200 OK
Content-Type: application/json

{
  "@id": "http://localhost:8080/Plone/front-page",
  "@type": "Document",
  "UID": "1f699ffa110e45afb1ba502f75f7ec33",
  "allow_discussion": null,
  "changeNote": "",
  "contributors": [],
  "created": "2016-01-21T01:14:48+00:00",
  "creators": [
    "test_user_1_",
    "admin"
  ],
  "description": "Congratulations! You have successfully installed Plone.",
  "effective": null,
  "exclude_from_nav": false,
  "expires": null,
  "id": "front-page",
  "language": "",
  "modified": "2016-01-21T01:24:11+00:00",
  "parent": {
    "@id": "http://localhost:8080/Plone",
    "@type": "Plone Site",
    "description": "",
    "title": "Plone site"
  },
  "relatedItems": [],
  "review_state": "private",
  "rights": "",
  "subjects": [],
  "table_of_contents": null,
  "text": {
    "content-type": "text/plain",
    "data": "If you're seeing this instead of the web site you were expecting, the owner of this web site has just installed Plone. Do not contact the Plone Team or the Plone mailing lists about this.",
    "encoding": "utf-8"
  },
  "title": "Welcome to Plone"
}

Example 2

Code
..  http:example:: curl wget httpie python-requests

    POST /Plone/folder HTTP/1.1
    Host: localhost:8080
    Accept: application/json
    Content-Type: application/json
    Authorization: Basic YWRtaW46YWRtaW4=

    {
        "@type": "Document",
        "title": "My Document"
    }
Result

http

POST /Plone/folder HTTP/1.1
Host: localhost:8080
Accept: application/json
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=

{
    "@type": "Document",
    "title": "My Document"
}

curl

curl -i -X POST http://localhost:8080/Plone/folder -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"@type": "Document", "title": "My Document"}' --user admin:admin

wget

wget -S -O- http://localhost:8080/Plone/folder --header="Accept: application/json" --header="Content-Type: application/json" --post-data='{"@type": "Document", "title": "My Document"}' --auth-no-challenge --user=admin --password=admin

httpie

echo '{
  "@type": "Document",
  "title": "My Document"
}' | http POST http://localhost:8080/Plone/folder Accept:application/json Content-Type:application/json -a admin:admin

python-requests

requests.post('http://localhost:8080/Plone/folder', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'@type': 'Document', 'title': 'My Document'}, auth=('admin', 'admin'))

Example 3

Code
..  http:example:: curl wget httpie python-requests

    PATCH /Plone/folder/my-document HTTP/1.1
    Host: localhost:8080
    Content-Type: application/json
    Accept: application/json
    Authorization: Basic YWRtaW46YWRtaW4=

    {
        "title": "My New Document Title"
    }
Result

http

PATCH /Plone/folder/my-document HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Accept: application/json
Authorization: Basic YWRtaW46YWRtaW4=

{
    "title": "My New Document Title"
}

curl

curl -i -X PATCH http://localhost:8080/Plone/folder/my-document -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"title": "My New Document Title"}' --user admin:admin

wget

wget -S -O- --method=PATCH http://localhost:8080/Plone/folder/my-document --header="Accept: application/json" --header="Content-Type: application/json" --body-data='{"title": "My New Document Title"}' --auth-no-challenge --user=admin --password=admin

httpie

echo '{
  "title": "My New Document Title"
}' | http PATCH http://localhost:8080/Plone/folder/my-document Accept:application/json Content-Type:application/json -a admin:admin

python-requests

requests.patch('http://localhost:8080/Plone/folder/my-document', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'title': 'My New Document Title'}, auth=('admin', 'admin'))

Example 4

Code
..  http:example:: curl wget httpie python-requests

    GET /items?user_id=12&user_id=13 HTTP/1.1
    Host: localhost
    Accept: application/json
    Authorization: Basic YWRtaW46YWRtaW4=

    :query from: 20170101
    :query to: 20171231
    :query user_id: 15
    :query limit: 20
    :query sort: date-asc
Result

http

GET /items?user_id=12&user_id=13&from=20170101&to=20171231&user_id=15&limit=20&sort=date-asc HTTP/1.1
Host: localhost
Accept: application/json
Authorization: Basic YWRtaW46YWRtaW4=

curl

curl -i -X GET 'http://localhost/items?user_id=12&user_id=13&from=20170101&to=20171231&user_id=15&limit=20&sort=date-asc' -H "Accept: application/json" --user admin:admin

wget

wget -S -O- 'http://localhost/items?user_id=12&user_id=13&from=20170101&to=20171231&user_id=15&limit=20&sort=date-asc' --header="Accept: application/json" --auth-no-challenge --user=admin --password=admin

httpie

http 'http://localhost/items?user_id=12&user_id=13&from=20170101&to=20171231&user_id=15&limit=20&sort=date-asc' Accept:application/json -a admin:admin

python-requests

requests.get('http://localhost/items?user_id=12&user_id=13&from=20170101&to=20171231&user_id=15&limit=20&sort=date-asc', headers={'Accept': 'application/json'}, auth=('admin', 'admin'))

Examples with external sources

Example 1

Code
..  http:example:: curl wget httpie python-requests
    :request: ../tests/fixtures/001.request.txt
    :response: ../tests/fixtures/001.response.txt
Result

http

GET /Plone/front-page HTTP/1.1
Host: localhost:8080
Accept: application/json
Authorization: Basic YWRtaW46YWRtaW4=

curl

curl -i -X GET http://localhost:8080/Plone/front-page -H "Accept: application/json" --user admin:admin

wget

wget -S -O- http://localhost:8080/Plone/front-page --header="Accept: application/json" --auth-no-challenge --user=admin --password=admin

httpie

http http://localhost:8080/Plone/front-page Accept:application/json -a admin:admin

python-requests

requests.get('http://localhost:8080/Plone/front-page', headers={'Accept': 'application/json'}, auth=('admin', 'admin'))

response

HTTP/1.1 200 OK
Content-Type: application/json

{
  "@id": "http://localhost:8080/Plone/front-page",
  "@type": "Document",
  "UID": "1f699ffa110e45afb1ba502f75f7ec33",
  "allow_discussion": null,
  "changeNote": "",
  "contributors": [],
  "created": "2016-01-21T01:14:48+00:00",
  "creators": [
    "test_user_1_",
    "admin"
  ],
  "description": "Congratulations! You have successfully installed Plone.",
  "effective": null,
  "exclude_from_nav": false,
  "expires": null,
  "id": "front-page",
  "language": "",
  "modified": "2016-01-21T01:24:11+00:00",
  "parent": {
    "@id": "http://localhost:8080/Plone",
    "@type": "Plone Site",
    "description": "",
    "title": "Plone site"
  },
  "relatedItems": [],
  "review_state": "private",
  "rights": "",
  "subjects": [],
  "table_of_contents": null,
  "text": {
    "content-type": "text/plain",
    "data": "If you're seeing this instead of the web site you were expecting, the owner of this web site has just installed Plone. Do not contact the Plone Team or the Plone mailing lists about this.",
    "encoding": "utf-8"
  },
  "title": "Welcome to Plone"
}

Example 2

Code
..  http:example:: curl wget httpie python-requests
    :request: ../tests/fixtures/002.request.txt
    :response: ../tests/fixtures/002.response.txt
Result

http

POST /Plone/folder HTTP/1.1
Host: localhost:8080
Accept: application/json
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=

{
    "@type": "Document",
    "title": "My Document"
}

curl

curl -i -X POST http://localhost:8080/Plone/folder -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"@type": "Document", "title": "My Document"}' --user admin:admin

wget

wget -S -O- http://localhost:8080/Plone/folder --header="Accept: application/json" --header="Content-Type: application/json" --post-data='{"@type": "Document", "title": "My Document"}' --auth-no-challenge --user=admin --password=admin

httpie

echo '{
  "@type": "Document",
  "title": "My Document"
}' | http POST http://localhost:8080/Plone/folder Accept:application/json Content-Type:application/json -a admin:admin

python-requests

requests.post('http://localhost:8080/Plone/folder', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'@type': 'Document', 'title': 'My Document'}, auth=('admin', 'admin'))

response

HTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:8080/Plone/folder/my-document

{
    "@type": "Document",
    "id": "my-document",
    "title": "My Document"
}

Example 3

Code
..  http:example:: curl wget httpie python-requests
    :request: ../tests/fixtures/003.request.txt
    :response: ../tests/fixtures/003.response.txt
Result

http

PATCH /Plone/folder/my-document HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Accept: application/json
Authorization: Basic YWRtaW46YWRtaW4=

{
    "title": "My New Document Title"
}

curl

curl -i -X PATCH http://localhost:8080/Plone/folder/my-document -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"title": "My New Document Title"}' --user admin:admin

wget

wget -S -O- --method=PATCH http://localhost:8080/Plone/folder/my-document --header="Accept: application/json" --header="Content-Type: application/json" --body-data='{"title": "My New Document Title"}' --auth-no-challenge --user=admin --password=admin

httpie

echo '{
  "title": "My New Document Title"
}' | http PATCH http://localhost:8080/Plone/folder/my-document Accept:application/json Content-Type:application/json -a admin:admin

python-requests

requests.patch('http://localhost:8080/Plone/folder/my-document', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'title': 'My New Document Title'}, auth=('admin', 'admin'))

response

HTTP/1.1 204 No Content