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; } } } }