Skip to content

How to use API

Pierre Bellon edited this page Oct 31, 2013 · 52 revisions

Supported format

Spending Stories API supports HTML & JSON format as output.

Checkout http://<your server host>/api/ on your server to browse and use the API.

Authentication

Some of the operation (flagged with *) require to be authenticated. The first thing you need to do for authentication is to have a superuser on your application. To do that check the [add a superuser][add-a-superuser] wiki page.

When your superuser is set up you should be able to create new users on your database. Create at least one user for your API or use the superuser of your app (strongly discouraged).

Simple Auth

Simple Authentication works by passing an encoded version of the user credentials. To get access to reserved method of endpoints you need to add the proper Authorization in every HTTP's request header.

Example

Here is an example of how you should use the Authorization header variable using base64 as tool for encoding the user:pass string into Base64.

curl -X DELETE localhost:8000/api/stories/80/ -H "Authorization: Basic $(echo -n 'user:pass'|base64)"
DELETE /api/stories/80/ HTTP/1.1
User-Agent: curl/7.29.0
Host: localhost:8000
Accept: */*
Authorization: Basic dXNlcjpwYXNz

Token Auth

This is our recommended authentication method. To use it you have to create/get a session token on the /api/api-token-auth/ API endpoint.

Example

  1. First create/get your session token:

    curl -X POST localhost:8000/api/api-token-auth/ -d '{ "username":"user", "password":"pass" }' -H "Content-Type: application/json"   

    HTTP Request:

    POST /api/api-token-auth/ HTTP/1.1
    User-Agent: curl/7.29.0
    Host: localhost:8000
    Accept: */*
    Content-Type: application/json
    Content-Length: 41

    HTTP Response:

    HTTP/1.0 200 OK
    Date: Thu, 31 Oct 2013 13:18:27 GMT
    Server: WSGIServer/0.1 Python/2.7.4
    Vary: Accept, Cookie
    Content-Type: application/json
    Allow: POST, OPTIONS
    
    {"token": "10ng70k3n1s10ng"}%   

    TIP: this is not a real token.

  2. Use this token in HTTP's header:

    curl -X DELETE localhost:8000/api/stories/265/ -H 'Authorization: Token 10ng70k3n1s10ng'

    HTTP Request:

    DELETE /api/stories/265/ HTTP/1.1
    User-Agent: curl/7.29.0
    Host: localhost:8000
    Accept: */*
    Authorization: Token 10ng70k3n1s10ng

    HTTP Response:

    HTTP/1.0 204 NO CONTENT
    Date: Thu, 31 Oct 2013 13:27:04 GMT
    Server: WSGIServer/0.1 Python/2.7.4
    Vary: Accept, Cookie
    Content-Length: 0
    Content-Type: application/json
    Allow: GET, PUT, DELETE, HEAD, OPTIONS, PATCH

Ajax & CSRF

To avoid CSRF attacks Ajax request must be authenticated with a X-CSRFToken. Therefor every Ajax request made must be in the front-end served by the django app. This is the only way to have a valid local cookie containing a CSRF token.

Here is a little snippet to show you how to get this token and use it in your Ajax requests:

var getCookiesObject = function(){
    var cookies = {};
    if(document.cookie && document.cookie.length){
        var cookies_splitted = document.cookie.split(';');
        for(var i in cookies_splitted){
            var cookie_splitted = cookies_splitted[i].trim().split('='); 
            cookies[cookie_splitted[0]] = cookie_splitted[1];
        }
    }
    return cookies;
}

$.ajax({
    url: '/api/stories/90/',
    method: 'DELETE', 
    success: function(d){
        console.log('successfuly deleted story 90');
    },
    headers: {
        'X-CSRFToken': getCookiesObject()['XSRF-TOKEN']
    }
});

Note that this request will fail because we are not using any auth system. So this auth is not a replacement of the other two system but a complement for Ajax request.

Entities

Stories

Stories are the central entities of our application. For further informations about stories.

  • Stories attributes
  • Endpoints
    • [/api/stories/][apistories]
    • [/api/stories/:id/][apistoriesid]
    • [/api/stories-nested/][apistories-nested]
    • [/api/stories-nested/:id/][apistories-nestedid]
  • [How to filter results][how-to-filter-results]
  • [Get stories sorted by relevance][get-results-filtered-by-relevance]

Stories attributes

Every story is composed of the following attributes:

Name Type Description Writable ?
id Integer Story identifier
value Float Spending amount
tite String Story's title
description String Story description
country String ISO code of story's country
currency String ISO code of story's currency
year Integer Story year
themes Array Related themes of this story.
type String Story description
sticky Boolean Story sticky status Staff Only
status String Story publication status Staff Only
created_at String Story creation date encoded with RFC3339 format
current_value Float Compensated value of the story (in its own currency)
current_value_usd Float Converted compensated value of story in USD.
inflation_last_year Integer Last avalaible year of inflation for this story

Endpoints

/api/stories/

GET, POST, HEAD, OPTIONS

List all stories in our application.

/api/stories/:id/

GET, PUT, DELETE, HEAD, OPTIONS, PATCH

Return a single story.

/api/stories-nested/

GET, POST, HEAD, OPTIONS

Similar as [/api/stories/][apistories] except that it's in a nested mode. That means every related object (like themes, country or currency) will be returned as well.

/api/stories-nested/:id/

GET, PUT, DELETE, HEAD, OPTIONS, PATCH

Return a single story and its nested objects.

How to filter results?

Results can be filtered using the following fields:

Name Type Description Possible values
sticky Boolean Will filter stories based on their sticky attribute. True,False,''
country String Will filter stories based on the given country The iso code of the wanted country, see /api/countries/ for more details.
currency String Will filter stories based on the given currency The iso code of the wanted currency, see /api/currencies/ for more details.
type String Will filter stories based on their type. over_one_year, discrete, see stories for more details about story types.
title String Will filter stories based on their title Title of an existing story
themes String Will filter stories based on their theme(s). Slug(s) of one or more themes

Get results filtered by relevance

An extra method exists for stories. /api/stories/ and /api/stories-nested/ endpoints can be requested with an extra parameter called relevance_for. It takes an integer or a float as parameter and correspond to an amount in USD.

It will return a list of stories that are relevant compared to this amount. Check what is a relevant story wiki page to learn more about our relevance model.

Themes

A theme can be compared as a category for every story.

Themes attributes

Name Type Description Writable ?
title String Theme's title
slug String Theme's slug, can be used to get a single theme (check /api/themes/:slug/)
description String Theme's title
image String Theme's image URL

Endpoints

/api/themes/

GET, HEAD, OPTIONS

List all themes.

/api/themes/:slug/

GET, HEAD, OPTIONS

Get one single theme using its slug.

Currencies

This entity is not representative of every currency in the world. Nonetheless we chosed to store in our API a list of the most used currencies.

Checkout the inflation wiki page to learn more about currencies & how they are important in our application.

Currencies attributes

Name Type Description Example Writable ?
iso_code String Currency's ISO code 'USD'
name String Currency's name 'US Dollar'
rate Float The currency conversion rate to USD 1
symbol String The unicode symbol(s) for this currency (if exists) '$'
priority Integer Arbitrary priority for this currency over other ones 3

/api/currencies/

GET, HEAD, OPTIONS

List all currencies.

/api/currencies/:id/

GET, HEAD, OPTIONS

Countries

Countries are useful to compute the inflation. Checkout inflation to learn more about how we compute inflation.

Countries attributes

Name Type Description Writable ?
iso_code String Country's ISO code
name String Country's name

/api/countries/

GET, HEAD, OPTIONS

[howtofilterresults]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#how-to-filter-results) [how-to-filter-results]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#how-to-filter-results [get-results-filtered-by-relevance]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#get-results-filtered-by-relevance [countries-attributes]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#countries-attributes [currencies-attributes]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#currencies-attributes [themes-attributes]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#themes-attributes [apistories]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#apistories [apistories]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#apistories [apistoriesid]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#apistoriesid [apistories-nested]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#apistories-nested [apistories-nestedid]: /jplusplus/okf-spending-stories/wiki/How-to-use-API#apistories-nestedid apithemesslug: /jplusplus/okf-spending-stories/wiki/How-to-use-API#apithemesslug

Clone this wiki locally