-
Notifications
You must be signed in to change notification settings - Fork 12
How to use API
Spending Stories API supports HTML & JSON format as output.
Checkout http://<your server host>/api/
on your server to browse and use the API.
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 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 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.
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 where user
is your user login and pass
your password.
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
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.
-
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 { "username":"user", "password":"pass" }
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.
-
Use this token in the HTTP 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
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.
Stories are the central entities of our application. For further information 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]
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 | ✗ |
GET, POST, HEAD, OPTIONS
List all stories in our application.
GET, PUT * , DELETE * , HEAD, OPTIONS, PATCH *
* : require authentication and reserved to staff
Operations on a single story.
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.
GET, PUT * , DELETE * , HEAD, OPTIONS, PATCH *
* : require authentication and reserved to staff
Return a single story and its nested objects.
Results can be filtered using the following fields:
Name | Type | Description | Possible values |
---|---|---|---|
sticky | Boolean |
Filters stories based on their sticky attribute. |
True ,False ,''
|
country | String |
Filters stories based on the given country | The iso code of the wanted country, see /api/countries/ for more details. |
currency | String |
Filters stories based on the given currency | The iso code of the wanted currency, see /api/currencies/ for more details. |
type | String |
Filters stories based on their type. |
over_one_year , discrete , see stories for more details about story types. |
title | String |
Filters stories based on their title | Title of an existing story |
themes | String |
Filters stories based on their theme(s). | Slug(s) of one or more themes |
HTTP Request:
GET /api/stories/?sticky=True&themes=aid&themes=health HTTP/1.1
User-Agent: curl/7.29.0
Host: localhost:8000
Accept: */*
Note the multiple themes in URL, this is because one story can have multiple themes. This request can be understood as: list every top stories related to the aid or health themes.
HTTP Response:
HTTP/1.0 200 OK
Date: Thu, 31 Oct 2013 16:54:02 GMT
Server: WSGIServer/0.1 Python/2.7.4
Vary: Accept, Cookie
Content-Type: application/json
Allow: GET, POST, HEAD, OPTIONS
[
{
"source" : "http://www.birminghammail.co.uk/lifestyle/health/birmingham-highest-diabetes-rate-uk-5729342",
"status" : "published",
"extras" : "{}",
"currency" : "GBP",
"created_at" : "2013-08-20T12:22:23.485Z",
"sticky" : true,
"id" : 239,
"country" : "GBR",
"themes" : [
"health"
],
"value" : 350,
"current_value_usd" : 531.838108479779,
"description" : "The Cabinet Member for Health and Wellbeing at Birmingham City Council spent £350 on prescriptions for every diabetes patient annually.",
"current_value" : 350,
"type" : "discrete",
"title" : "Diabetes prescriptions pro capita costs in Birmingham",
"inflation_last_year" : 2012,
"year" : 2013
},
...
]
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 to learn more about our relevance model.
A theme can be compared as a category for every story.
- [Themes attributes][themes-attributes]
- Endpoints
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 | ✗ |
GET, HEAD, OPTIONS
List all themes.
GET /api/themes/ HTTP/1.1
User-Agent: curl/7.29.0
Host: localhost:8000
Accept: */*
HTTP/1.0 200 OK
Date: Thu, 31 Oct 2013 17:04:46 GMT
Server: WSGIServer/0.1 Python/2.7.4
Vary: Accept, Cookie
Content-Type: application/json
Allow: GET, HEAD, OPTIONS
[
{
"image": "/media/themes/aid.svg",
"slug": "aid",
"title": "aid",
"description": null,
"active": true
},
...
]
GET, HEAD, OPTIONS
Get one single theme using its slug
.
GET /api/themes/aid/ HTTP/1.1
User-Agent: curl/7.29.0
Host: localhost:8000
Accept: */*
HTTP/1.0 200 OK
Date: Thu, 31 Oct 2013 17:04:46 GMT
Server: WSGIServer/0.1 Python/2.7.4
Vary: Accept, Cookie
Content-Type: application/json
Allow: GET, HEAD, OPTIONS
{
"image": "/media/themes/aid.svg",
"slug": "aid",
"title": "aid",
"description": null,
"active": true
}
This entity is not representative of every currency in the world. Nonetheless we chose to store in our API a list of the most used currencies.
Check out the inflation wiki page to learn more about currencies & how they are important in our application.
- [Currencies attributes][currencies-attributes]
- Endpoints
Name | Type | Description | Writable ? |
---|---|---|---|
iso_code | String |
Currency's ISO code | ✗ |
name | String |
Currency's name | ✗ |
rate | Float |
The currency conversion rate to USD | ✗ |
symbol | String |
The Unicode symbol(s) for this currency (if exists) | ✗ |
priority | Integer |
Arbitrary priority for this currency over other ones | ✗ |
GET, HEAD, OPTIONS
List all currencies.
GET /api/currencies/ HTTP/1.1
User-Agent: curl/7.29.0
Host: localhost:8000
Accept: */*
HTTP/1.0 200 OK
Date: Thu, 31 Oct 2013 17:01:05 GMT
Server: WSGIServer/0.1 Python/2.7.4
Vary: Accept, Cookie
Content-Type: application/json
Allow: GET, HEAD, OPTIONS
[
{
"priority" : 3,
"rate" : 81.528316,
"symbol" : "دج",
"iso_code" : "DZD",
"name" : "Algerian dinar"
},
...
]
GET, HEAD, OPTIONS
Return a single currency based on its iso_code
:
GET /api/currencies/DZD/ HTTP/1.1
User-Agent: curl/7.29.0
Host: localhost:8000
Accept: */*
HTTP/1.0 200 OK
Date: Thu, 31 Oct 2013 17:01:05 GMT
Server: WSGIServer/0.1 Python/2.7.4
Vary: Accept, Cookie
Content-Type: application/json
Allow: GET, HEAD, OPTIONS
{
"priority" : 3,
"rate" : 81.528316,
"symbol" : "دج",
"iso_code" : "DZD",
"name" : "Algerian dinar"
}
Countries are useful to compute the inflation. Checkout inflation to learn more about how we compute inflation.
- [Countries attributes][countries-attributes]
- Endpoints
Name | Type | Description | Writable ? |
---|---|---|---|
iso_code | String |
Country's ISO code | ✗ |
name | String |
Country's name | ✗ |
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