Code Samples

Sometimes it’s best to just see it done. For that, we have some code samples for you to peruse. Though we are working diligently on full libraries for interfacing with our API, they aren’t quite ready yet. Until then, these examples should get you started (and never be afraid to ask if not), the interface is simple enough that whatever language you are using should run closely to what’s happening here in python and cURL.

Bash + cURL (HTTP authentication)

This is a simple example of making a request from the command line. You probably won’t be using cURL, but if you run into issues we’ve found it’s best to try to recreate them with cURL with the -vv flag.
You get a lot of of insight into what your request and response look like this way. Another good thing about cURL is that it’s easy to see what it’s doing even if you’re not familiar with the tool.

#!/bin/bash
export USER='USERNAME'
export PASSWORD='PASSWORD'
export CLIENT_KEY='KEY'
export BASE='https://api.appfigures.com/v2/'

# get products
curl -H"X-Client-Key: $CLIENT_KEY" -u"$USER:$PASSWORD" "${BASE}products/mine?pretty=true"

#get total sales by product
curl -H"X-Client-Key: $CLIENT_KEY" -u"$USER:$PASSWORD" "${BASE}reports/sales/products?pretty=true"

Bash + cURL (OAuth)

Here, we’ll manually go through getting an OAuth Access Token.
It’s a mess, so hopefully you wouldn’t have to do this yourself but it illustrates the protocol effectively.
Note the oauth_callback set to oob and the X-OAuth-Scope is set to products:read.

oob means out of band. Which is to say you don’t want the user to be redirected during the authorization process, but instead you want them to be given a code to paste into the program. products:read means the only thing the resulting Access Token will be able to do is access product data. You can look here for more about this. If you want to skip scopes entirely you can, the issued access tokens will simply inherit the scope that you specified when creating the client key.

#!/bin/bash
#change these
CLIENT_KEY='clientkey'
CLIENT_SECRET='clientsecret'

BASE='https://api.appfigures.com/v2/'

# get and parse Request Token
OUTPUT="$(curl -v -XPOST $BASE'oauth/request_token' \
       -H'Authorization: OAuth oauth_signature_method=PLAINTEXT,
                                oauth_consumer_key='$CLIENT_KEY',
                                oauth_callback=oob,
                                oauth_signature='$CLIENT_SECRET'&' \
       -H'X-OAuth-Scope: products:read' \
       -H'Content-Length: 0')"

REQUEST_TOKEN=`echo $OUTPUT |  sed 's/.*oauth_token=\([^&]*\).*/\1/'`
REQUEST_SECRET=`echo $OUTPUT |  sed 's/.*oauth_token_secret=\([^&]*\).*/\1/'`

# Forward to be authorized and get verifier
echo "Go to ${BASE}oauth/authorize?oauth_token=$REQUEST_TOKEN to get your code."
read -p'verifier:' VERIFIER

#Exchange Request Token for Access Token
OUTPUT="$(curl -v -XGET $BASE'oauth/access_token' \
       -H'Authorization: OAuth oauth_signature_method=PLAINTEXT,
                                oauth_verifier='$VERIFIER',
                                oauth_consumer_key='$CLIENT_KEY',
                                oauth_token='$REQUEST_TOKEN',
                                oauth_signature='$CLIENT_SECRET'&'$REQUEST_SECRET)"

ACCESS_TOKEN=`echo $OUTPUT |  sed 's/.*oauth_token=\([^&]*\).*/\1/'`
ACCESS_SECRET=`echo $OUTPUT |  sed 's/.*oauth_token_secret=\([^&]*\).*/\1/'`


# Make a request to get products
curl -XGET -v $BASE'products/mine' \
        -H'Authorization: OAuth oauth_signature_method=PLAINTEXT,
                                oauth_consumer_key='$CLIENT_KEY',
                                oauth_token='$ACCESS_TOKEN',
                                oauth_signature='$CLIENT_SECRET'&'$ACCESS_SECRET

Python (HTTP Authentication)

The below example uses the requests package, available from pip or easy_install. make_request is where the magic happens, the rest is just exercising the API
by getting and manipulating resources.

""" Script that demonstrates how to access the Appfigures API
    from python. It relies on requests, because urllib is no fun
    Released into the Public Domain (for what it's worth)
"""

import requests

# Fill these constants in
USERNAME = 'USERNAME'
PASSWORD = 'PASSWORD'
APP_KEY = 'APP_KEY'
BASE_URI = "https://api.appfigures.com/v2/"

# Helper function for auth and app_key
# first / in uri is optional
def make_request(uri, **querystring_params):
  headers = {"X-Client-Key": APP_KEY}
  auth =(USERNAME, PASSWORD)
  return requests.get(BASE_URI + uri.lstrip("/"),
                        auth=auth,
                        params=querystring_params,
                        headers=headers)

# Get the root resource to show we are in business
root_response = make_request("/")
assert 200 == root_response.status_code
assert USERNAME == root_response.json()["user"]["email"]

# Get a list of products
product_response = make_request("/products/mine")
assert 200 == product_response.status_code
assert 0 < len(product_response.json())
for (id, product) in product_response.json().items():
  print(product["name"], product["id"])

# Get data for all inapps for a year by month
products = product_response.json().values()
inapps = [p for p in products if p["type"] == u"app"]
inapp_ids = [str(product["id"]) for product in inapps]
inapp_names = [inapp["name"] for inapp in inapps]
route = "/reports/sales?start_date=-30&group_by=dates,products"
inapp_sales_response = make_request(route,
                                    granularity="monthly",
                                    products=";".join(inapp_ids))
print(inapp_sales_response.json())
assert 200 == inapp_sales_response.status_code

# Make a little table of revenue
data = inapp_sales_response.json()
months = sorted(data.keys())
print(",".join(["date\\product_name"] + inapp_names))
for month in months:
  values = data[month]
  downloads = []
  for inapp_id in inapp_ids:
    if inapp_id in values:
      downloads.append(values[inapp_id]["downloads"])
    else:
      downloads.append("0")
  print(",".join([month] + map(str, downloads)))

Python (OAuth)

There's a decent python package for OAuth called rauth.
This example shows how to use it to get an Access Token and start making requests.

Warning: when you do get a rauth session, make sure that querystring parameters are given in the params= keyword arg-- if they are given as part of the url rauth won't sign the request correctly.

""" Demonstrates using the rauth library to interact with
    the Appfigures API
"""

from rauth import OAuth1Session, OAuth1Service


base_url = "https://api.appfigures.com/v2"
client_key = "client_key"
client_secret = "client_secret"


request_token_url = base_url + "/oauth/request_token"
authorize_url = base_url + "/oauth/authorize"
access_token_url = base_url + "/oauth/access_token"

def get_service():
  """ Returns an OAuthService configured for us """
  return OAuth1Service(name="appfigures",
                        consumer_key=client_key,
                        consumer_secret=client_secret,
                        request_token_url=request_token_url,
                        access_token_url=access_token_url,
                        authorize_url=authorize_url,
                        base_url=base_url)


def get_session(access_token=None, access_token_secret=None):
  """If access_token and secret are given, create and return a session.

      If they are not given, go through the authorization process
      interactively and return the new session
  """
  oauth = get_service()

  if access_token:
    session = OAuth1Session(client_key, client_secret,
                            access_token, access_token_secret,
                            service=oauth)
    return session

  params = {"oauth_callback": "oob"}
  headers = {'X-OAuth-Scope': 'public:read,products:read'}
  request_token, request_token_secret = oauth.get_request_token(
                                          params=params,
                                          headers=headers
                                        )

  authorization_url = oauth.get_authorize_url(request_token)
  print("Go here: %s to get your verification token."
          % authorization_url)
  verifier = raw_input("Paste verifier here: ")
  session =  oauth.get_auth_session(request_token, 
                                    request_token_secret,
                                    "POST",
                                    data={"oauth_verifier":verifier})
  return session


if __name__ == "__main__":
  s = get_session()
  print("Access Token: %s\tAccess Secret:%s"
          % (s.access_token, s.access_token_secret))
  resp = s.get(base_url + "/products/mine")
  print([ product['name'] for (id, product) in resp.json().items()])

  # it is VERY important that querystring parameters go in params
  # rather than directly put in the URL. rauth will not sign the request
  # correctly if you did s.get(base_url+"products/mine?store=apple")
  resp = s.get(base_url + "/products/mine", params=dict(store="apple"))
  print([ product['name'] for (id, product) in resp.json().items()])

  resp = s.get(base_url + "/reports/sales/products")
  print("Status code(%s) should be 403 because of scope" %
          resp.status_code)

C# (HTTP Authentication)

Here's snippet of C# code that talks to the API.

using System;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ApiClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(" --- Products --- ");
            AppfiguresApi client = new AppfiguresApi("USERNAME", "PASSWORD", "CLIENT_KEY");

            var products = client.MakeRequest("products/mine");
            foreach(var product in products){
                Console.WriteLine(product.Value["name"]);
            }

            Console.WriteLine("\n--- Sales Over Past 7 Days ---");
            var sevenDaySales = client.MakeRequest("/reports/sales?group_by=dates&start_date=-7");
            foreach (var date in sevenDaySales) {
                var sales = date.Value;
                Console.WriteLine(String.Format("{0}: {1,-4}(${2:C})", date.Key, sales["downloads"], sales["revenue"]));
            }
            Console.ReadKey();
        }
    }

    class AppfiguresApi
    {
        private static readonly Uri BaseUrl = new Uri("https://api.appfigures.com/v2/");
        public readonly String Username;
        public readonly String Password;
        public readonly String ClientKey;

        public AppfiguresApi(String username, String password, String clientKey)
        {
            this.Username = username;
            this.Password = password;
            this.ClientKey = clientKey;
        }

        public JObject MakeRequest(String path)
        {
            Uri fullUri = new Uri(BaseUrl, path);
            WebRequest request = WebRequest.Create(fullUri);
            request.PreAuthenticate = true;
            request.Credentials = new NetworkCredential(this.Username, this.Password);
            request.Headers.Add("X-Client-Key: " + ClientKey);
            WebResponse response = request.GetResponse();
            using (StreamReader responseReader = new StreamReader(response.GetResponseStream())) {
                return JObject.ReadFrom(new JsonTextReader(responseReader)) as JObject;
            }
        }
    }
}