Posts Tagged ‘api’

Facebook REST-API — (Part2/2 — Erlang)

Monday, March 15th, 2010

This is the second part of two minimal examples, on how to interact with the Facebook REST API. Last weeks part was in python, this time we do the exact same thing in erlang. (Note that there are python and erlang libs in various stages of completion, but my focus is on minimal examples and understanding here.)

The code below calls the function users.getinfo in the “call” method. The request send to the Facebook REST server has to be signed according to Facebook’s signing algorithm this is done in “get_rest_url”.

The result will be requested to be transmitted as JSON encoded text. I am using mochijson2 to decode the result.

-module(fb).
-export([call/1, test/0]).

-define(SECRET, "a1b1c1e1d1f1......"
-define(API_KEY, "a2b2c2e2d2f2......"
-define(REST_SERVER, "api.facebook.com").
-define(URL_START, "/restserver.php?").

get_rest_url(Args) ->
  % this implements the the facebook signing recipe
  % the link is in the text above
  SortedArgs = lists:sort(Args),
  Fun = fun({Key, Value}) -> Key ++ "=" ++ Value end,
  StringArgs = lists:map(Fun, SortedArgs),
  String = lists:flatten(StringArgs, ?SECRET),
  <<M:128>> = erlang:md5(String),
  Sig = lists:flatten(io_lib:format("~32.16.0b",[M])),  % string rep of hexdigest
  StringArgs2 = lists:map(fun(X) -> X ++ "&" end, StringArgs),
  lists:flatten(["http://", ?REST_SERVER, ?URL_START, StringArgs2, "sig=", Sig]).

call(Args) ->
  {Megaseconds,Seconds,Microseconds} = erlang:now(),
  CallId = integer_to_list(Megaseconds)
        ++ integer_to_list(Seconds)
        ++ integer_to_list(Microseconds),
  Args2 = lists:append(Args, [{"api_key", ?API_KEY},   % my application key
                             {"call_id", CallId},      % just any value that increases
                             {"format",  "JSON"}]),    % request JSON formatted reply
  Url = fb:get_rest_url(Args2),
  {ok, {{HttpVer, Code, Msg}, Headers, Body}} =
                    http:request(get, {Url, [{"User-Agent", "test "}]}, [], []),
  mochijson2:decode(Body).

test() ->
  call([{"method","users.getinfo"},
        {"v","1.0"},
        {"uids","1234567..."},
        {"fields","first_name"}]).

you would run the above like this:

erl -pa /some/path/to/mochiweb/ebin/
Erlang R13B04 (erts-5.7.5) [source] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]

Eshell V5.7.5  (abort with ^G)
1> inets:start().
ok
2> c(fb).
./fb.erl:28: Warning: variable 'Code' is unused
./fb.erl:28: Warning: variable 'Headers' is unused
./fb.erl:28: Warning: variable 'HttpVer' is unused
./fb.erl:28: Warning: variable 'Msg' is unused
{ok,fb}
3> fb:test().
[{struct,[{<<"first_name">>,<<"Joe">>},
          {<<"uid">>,123456...}]}]
4>

Facebook REST-API — (Part1/2 — Python)

Thursday, March 11th, 2010

This is the first part of 2 minimal examples, on how to interact with the Facebook REST API. This part will be an example in python, the next part will do the exact same thing in erlang. (Note that there are python and erlang libs in various stages of completion, but my focus is on minimal examples and understanding here.)

The code below calls the function users.getinfo in the “call” method. The request send to the Facebook REST server has to be signed according to Facebook’s signing algorithm this is done in “get_rest_url”.

The result will be requested to be transmitted as JSON encoded text. I am using cjson to decode the result, but you could use any of the python JSON libs (Note that from python 2.6 onward there is a json lib in the standard lib).

__secret__     = 'a1b1c1e1d1f1......'
__api_key__    = 'a2b2c2e2d2f2......'
__restserver__ = 'api.facebook.com'
__url_start__  = '/restserver.php?'

import time
import hashlib
import httplib
import cjson

def get_rest_url(d):
  # this implements the recipe you can find on this page:
  # http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application
  l = d.items()
  l.sort()
  l = [str(x[0])+'='+str(x[1]) for x in l]
  sig = hashlib.md5(''.join(l) + __secret__).hexdigest()
  url_list = [ __url_start__ ]
  url_list.extend([x+'&' for x in l])
  url_list.append('sig='+sig)
  return ''.join(url_list)

def call(d):
  # make sure certain keys are set
  d.update({'api_key': __api_key__,   # my application key
            'call_id': time.time(),   # just any value that increases
            'format' : 'JSON'})       # request JSON formatted reply
  url = get_rest_url(d)
  connection = httplib.HTTPConnection(__restserver__)
  connection.request('GET',url)
  response = connection.getresponse()
  return cjson.decode(response.read())

def main():
  d = {'method':'users.getinfo',
       'v':'1.0',
       'uids':'1234567...',    #use ur own userid for testing
       'fields':'contact_email,first_name',
      }
  print call(d)
if __name__ == '__main__':
  main()

Yum Python API

Friday, June 20th, 2008

Running larger sites demands for scripting node installation.

I like to use python for the task (surprise surprise). As it happens the mayor package managment tool for Red Hat, CentOS and Scientific Linux “yum” is itself written in python.

Since yum lacks documentation on how to use inside your own python code I have googled the web and found this nice page: Deciphering the Yum API.

For some reasons the code didn’t work for me on Scientific Linux 4 (Red Hat 3.4.6-9) which still uses python2.3. So I fiddled around a bit and got it working. Here are the updated examples.

Listing packages:

import yum

yb = yum.YumBase()
yb.doConfigSetup()
yb.doTsSetup()
yb.doRpmDBSetup()
for pkg in yb.rpmdb.getPkgList():
  print pkg

Searching packages:

In newer versions of yum there seems to be YumBase.searchGenerator, wich should be prefered for performance and memory footprint. However in the enterprise class distros i have to deal with, I could not use it. So I present a solution with YumBase.searchPackages.

import yum

yb = yum.YumBase()
yb.doConfigSetup()
yb.doRepoSetup()
yb.doSackSetup()
yb.doTsSetup()
yb.doRpmDBSetup()
fields = ['name']        # fields to look at
criteria = ["k3b"]       # strings to find in fields
matches = yb.searchPackages(fields, criteria)
for match in matches:
  print match

Ask if a certain package is installed:

import yum

yb = yum.YumBase()
yb.doConfigSetup()
yb.doTsSetup()
yb.doRpmDBSetup()
# prints 1 if installed else 0
print yb.rpmdb.installed('vim-enhanced')

Installing packages:

Install the editor joe. Note that we do not use the “standard” YumBase but the “command line” YumBaseCli. This class provides the installPkgs() function which magically sorts out which package we want by just saying “joe”. Note also that by using YumBaseCli in this way, we are bypassing some argument checks the command line yum would have done. To make sure yum doesn’t ask any questions we do “ybc.conf.setConfigOption(‘assumeyes’,True)”.
Beware of the consequences.

import sys

sys.path.append('/usr/share/yum-cli')

import cli

ybc = cli.YumBaseCli()
ybc.doConfigSetup()
ybc.doTsSetup()
ybc.doRpmDBSetup()
ybc.installPkgs(['joe'])
ybc.buildTransaction()
ybc.conf.setConfigOption('assumeyes',True)
ybc.doTransaction()