Easy Facebook Scripting in Python
UPDATED: fbconsole Pypi Package and Github Repository
Sometimes you just want to write a little script using Facebook’s api that updates your status, or downloads all your photos, or deletes all those empty albums you accidentally created. In order to streamline my writing of one-off facebook scripts, I created a micro api client that implements the client-side authentication flow and has a few utility functions for accessing the graph api and fql.
To use this mini api client, all you have to do is put 4 lines of code at the top of your python script:
from urllib import urlretrieve
import imp
urlretrieve('https://raw.github.com/gist/1194123/fbconsole.py', '.fbconsole.py')
fb = imp.load_source('fb', '.fbconsole.py')
Now you can specify the permissions you’ll need for your script (from the list of available api permissions) and authenticate yourself:
fb.AUTH_SCOPE = ['publish_stream'] fb.authenticate()
By default, the api client makes requests as the “fbconsole” app. You can use your own app by setting fb.APP_ID. When you authenticate, a browser window will open asking for whatever permissions were requested by your script. After you go through the permission dialog, the script will continue running. The access token used is stored in a local file when you authenticate so the next time around you won’t be presented with a dialog in your browser.
Once authenticated, you can make whatever calls to the graph api or fql that you want. For example:
Post a status update
status = fb.graph_post("/me/feed", {"message":"Hello from my awesome script"})
Fetch likes on a status update
likes = fb.graph("/"+status["id"]+"/likes")
Delete a status update
fb.graph_delete("/"+status["id"])
Upload a photo (why does python make this so hard?)
fb.graph_post("/me/photos", {"message":"My photo", "source":open("my-photo.jpg")})
Query FQL tables
friends = fb.fql("SELECT name FROM user WHERE uid IN "
"(SELECT uid2 FROM friend WHERE uid1 = me())")
If you download
https://raw.github.com/gist/1194123/fbconsole.py
and run it, you’ll be dropped into a python shell so you can just play around with api calls in an interactive environment. An IPython shell will be used if you have IPython installed.
The code is just in a gist on github at
. Feel free to comment on this post or on the gist if you have questions.
Love it & so intresting
Interesting! Thanks :)
Looks great, will have to give it a try :)
While the urlretrieve() approach is a neat hack (with some rather interesting security implications), perhaps you would be willing to consider publishing this on the Python Package Index (http://pypi.python.org)?
There’s a decent guide on how to do that here:
http://guide.python-distribute.org/quickstart.html
(just replace the “towelstuff” package directory in the example with your “fbconsole.py” file and update the metadata appropriately)
Great work!
I am working on a similar concept as yours, but it would use huge javascript and would be on a client! Looking forward to having your inputs and thoughts!!
great work! t.y.!
Agreed. Given how much attention this is now getting, making a proper pypi package is definitely on my list. I’ll see if I can get to it tomorrow. My primary reason for not making a package in the first place was to lower the barrier to entry to people who don’t have much programming experience or knowledge of python. Explaining how to use a package management system always seems to be more complicated than just giving a few lines to copy/paste.
can we have this kind of program in PHP, i would like to work in PHP command line code
This is incredible, thanks sir.
Hey, Paul. Good post, and congratulations on cracking the top 10 over on Hacker News.
This is a nice little client and I will be using it, but you are crazy if you think I’m putting those four lines of code that download a python script and do an eval on it, executing potentially malicious code. Big security issue. Do the right thing for yourself and your readers and create a proper github repository and set it up with setuptools. See this link: http://packages.python.org/an_example_pypi_project/setuptools.html. It basically means put your file in a subdirectory along with a blank __init__.py file and then creating a simple setup.py file that declares the dependencies in the directory above.
Once you have that done, all you can have your readers install it with `pip install https://github.com/YOURGITHUBUSERNAME/YOURFBPROJECT/tarball/master` and then they can import it in their code.
If you are not used to using github, they have the new Mac client that makes it drop dead simple.
Good luck!
Nice work. Ive been doing some facebook hacks on free time using scrapy. I think i have a good idea using this and scrapy and gui to build suttin for me ;)
What are your facebook app settings? I keep getting the following error when trying to use my own application:
API Error Code: 191
API Error Description: The specified URL is not owned by the application
Error Message: Invalid redirect_uri: Given URL is not allowed by the Application configuration.
Thanks,
@Dave, you have to set the redirect uri in your application settings to http://127.0.0.1:8080/
Pretty sweet. Just tried it out now with a couple of posts.
good job, I’ll be using this!
+1 on a github repo
The github repo has arrived. See https://github.com/facebook/fbconsole
wat d hel python z,sm one tell me
Nice! Thanks for the repo and setuptools!
Thanx for this post, I tried the script and it is very easy to use it indeed. I just have one comment: once you’re signed in, you do not really need to authenticate and grant access to any application. You can simply go to the graph api page, https://developers.facebook.com/docs/reference/api/ and bam, there’s your access_token in the example links, like this one:
News feed: https://graph.facebook.com/me/home?access_token=…
Hi pcardune, thank you for te fbconsole, good work, how i can get emails of my friends? i do the:
friends = fb.fql(“SELECT name FROM user WHERE uid IN ”
“(SELECT uid2 FROM friend WHERE uid1 = me())”)
And it gets their names, what SELECT gets their emails and what other information i could get?
Thank you again.
@r3c4ll here you’ll find the docs for the tables http://developers.facebook.com/docs/reference/fql/
@r3c4ll friends = fb.fql(“SELECT uid, name, email, contact_email, proxied_email FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me())”)
@bgpergo, You can set the ACCESS_TOKEN variable in fbconsole and skip the authentication altogether if you want. I’m updating the README on github to mention that.
@pcardune this is a follow-up of my first comment about the authentication. I just got an error:
“Error validating access token: Session has expired”
It seems that the access_token I acquired from the graph api page example expires quickly, but obviously, you store the access_token in a local file to save unnecessary oauth request, so my questions are:
Does the access_token acquired from oauth request expires too?
If it does, you need to delete the local file manually to be able to authenticate again, don’t you?
@bgpergo, That’s correct. I’m fixing that in an upcoming diff. Just haven’t gotten to it yet.
@pcardune, I’m trying to use my app_id and getting this error while authenticating:
An error occurred with $appname. Please try again later.
API Error Code: 191
API Error Description: The specified URL is not owned by the application
Error Message: Invalid redirect_uri: Given URL is not allowed by the Application configuration.
I’m new to facebook apps, could you please help me, what should I configure on my app page? I suspect I have to set redirect uri (http://127.0.0.1:8080) into a certain field, but which field?
Thanks for your help!
hm… very strange, I’m getting this same error
An error occurred with foo. Please try again later.
API Error Code: 191
API Error Description: The specified URL is not owned by the application
Error Message: Invalid redirect_uri: Given URL is not allowed by the Application configuration.
When trying to generate a new access_token on the Graph API Explorer page
https://developers.facebook.com/tools/explorer/40345380047/?method=GET&path=1059426812
Is this some kind of bug or am I missing something?
Is it possible to get all the url of images of all my friends using FQL?
Pingback: fbconsole Pypi Package and Github Repository « Heterogenous Mixture
Pingback: Veckans länktips – 2011-09-11 | lillbra.se
How do you add/delete a friend?
When I try fb.graph(‘A_PROFILE/picture’) it doesn’t work:
Traceback (most recent call last):
File “”, line 1, in
File “.fbconsole.py”, line 174, in graph
return json.load(urllib2.urlopen(_get_url(path, args=params)))
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py”, line 278, in load
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py”, line 326, in loads
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py”, line 360, in decode
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py”, line 378, in raw_decode
ValueError: No JSON object could be decoded
is it expected?
Thanks!
That’s because //picture returns a jpeg file, not a json response. What are you trying to do exactly? If you are looking for some other handling for images from graph api, you might want to open an issue on the github project: https://github.com/facebook/fbconsole
I’d like to grab the picture of a profile and show on my application… how could I do that using fb.graph?
Thanks!
Hi. I have a stupid question. Can we fetch the links of all updates of a page, a wall, or a group?
Hi, I just found your script to update my status on facebook. When I tryout the >>> print “Hello”,graph(‘/me’)['name'] the console drops a Traceback
File “C:\Python27\lib\urllib2.py”, line 521, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 400: Bad Request
Is there a change in the FB API ?
Pingback: It All Starts Here « Jason James Hoyle
Hi,
how can i @tag someone using the status update? i tried something i saw on some other page in which they said to use this format: @[{UID}:1:{UserName}] but it just writes that to the status instead of tagging my friend, any hints?
thanks
Wow! awesome !. A question for you , do you have a Interface implemented to post to Facebook groups , or help me with pointers to get started on this ? I have a simple task to upload a Trance group I own with my latest track findings , so I am looking to cook up something like a Batch script which could read from a Txt File , Youtube links and post them in my group daily.
I know there are concerns with this about spamming a group , but this is an interesting use-case as well.
I have tried this before i saw this post, and i must say, its Awesomeeeee!! :)
Thank you so much for taking the pain to code it and release it and giving out a nice simple doc which is to the point.!!
Thanks a lot..!!!!!!!!!!!!!!!!11
What’s the minimum Python version this will run on? It’s not running on 2.5. (json isn’t included…I tried importing simplejson as json but then also got the error “from urlparse import urlparse, parse_qs
ImportError: cannot import name parse_qs”
Will this run with Python 2.6?
This has only been tested with python 2.6 and 2.7. I’ll see how easy it is to add support for python2.5 to the fbconsole python package, the code for which can be found here: https://github.com/facebook/fbconsole
I got it to run on Python 2.5 by making just two simple changes. import json is now import simplejson as json, as I said. And I import parse_qs from the cgi module. And it runs.
But I am unable to upload a photo. When I use this code:
graph_post(“/me/photos”, {“message”:”My photo”, “source”:open(“python.png”)})
I get this back in the console: “HTTPError: HTTP Error 400: Bad Request”. It *does*, however, allow me to post an update message (“Hello from my awesome script”) just fine.
Any ideas?
Hi, thank you for ur script, but I have some problem, it seems to only work sporadically and I get socket urlopen Error 104: Connection reset by peer.
Output is as following:
(any help would be much appreciated, cheers ;)
(fbconsole has been imported and session authenticated)
>>> status = fbconsole.post(‘/me/feed’, {‘test’:’1100′})
Traceback (most recent call last):
File “/usr/lib/python3.2/urllib/request.py”, line 1136, in do_open
h.request(req.get_method(), req.selector, req.data, headers)
File “/usr/lib/python3.2/http/client.py”, line 964, in request
self._send_request(method, url, body, headers)
File “/usr/lib/python3.2/http/client.py”, line 1002, in _send_request
self.endheaders(body)
File “/usr/lib/python3.2/http/client.py”, line 960, in endheaders
self._send_output(message_body)
File “/usr/lib/python3.2/http/client.py”, line 805, in _send_output
self.send(msg)
File “/usr/lib/python3.2/http/client.py”, line 743, in send
self.connect()
File “/usr/lib/python3.2/http/client.py”, line 1105, in connect
server_hostname=server_hostname)
File “/usr/lib/python3.2/ssl.py”, line 181, in wrap_socket
_context=self)
File “/usr/lib/python3.2/ssl.py”, line 268, in __init__
raise x
File “/usr/lib/python3.2/ssl.py”, line 264, in __init__
self.do_handshake()
File “/usr/lib/python3.2/ssl.py”, line 443, in do_handshake
self._sslobj.do_handshake()
socket.error: [Errno 104] Connection reset by peer
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “”, line 1, in
File “/usr/lib/python3.2/site-packages/fbconsole.py”, line 628, in post
return _get_client().post(path, params=params)
File “/usr/lib/python3.2/site-packages/fbconsole.py”, line 541, in post
return json.loads(opener.open(self.__get_url(path), params).read().decode(‘utf-8′))
File “/usr/lib/python3.2/urllib/request.py”, line 369, in open
response = self._open(req, data)
File “/usr/lib/python3.2/urllib/request.py”, line 387, in _open
‘_open’, req)
File “/usr/lib/python3.2/urllib/request.py”, line 347, in _call_chain
result = func(*args)
File “/usr/lib/python3.2/urllib/request.py”, line 1172, in https_open
context=self._context, check_hostname=self._check_hostname)
File “/usr/lib/python3.2/urllib/request.py”, line 1139, in do_open
raise URLError(err)
urllib.error.URLError:
>>>
Great work, thanks for the contribution!
I was wondering if I could use fbconsole to automate writing some settings information for application development purposes. The information is available via a url at my application, but I’m not certain if fbconsole will allow me to access and return that information in html. It’s not exactly graph data, but I was trying to do this:
settings = fbconsole.get(‘/my-app/admin/controller/settings’)
or
settings = fbconsole.get(‘http://apps.facebook.com/my-app/admin/controller/settings’)
…both return errors, the first, bad url, the second, invalid port (I suppose fbconsole is wrapping HTTPConnection, so passing the url is an argument error, etc)…
Anyway to do something like this via fbconsole?
Thanks, adq
Are you including this migration option? I can’t retrieve Recent Activity Posts :(
https://developers.facebook.com/docs/reference/api/post/
story
Text of stories not intentionally generated by users, such as those generated when two users become friends; you must have the “Include recent activity stories” migration enabled in your app to retrieve these stories
read_stream
string
https://developers.facebook.com/blog/post/592/
Pingback: Affiliate Marketing: What affiliate networks have the best API, allowing developers to access maximum data? - Quora
Pingback: Python Facebook graph api - Upload photo to fan page - feed99
Traceback (most recent call last):
File “./main.py”, line 4, in
fbconsole.authenticate()
File “/home/louback/FacebookPublisher/fbconsole.py”, line 294, in authenticate
data = json.loads(open(ACCESS_TOKEN_FILE).read())
File “/usr/lib/python2.7/site-packages/anyjson/__init__.py”, line 130, in
deserialize = lambda value: implementation.deserialize(value)
File “/usr/lib/python2.7/site-packages/anyjson/__init__.py”, line 99, in deserialize
raise ValueError(*exc.args)
ValueError: No JSON object could be decoded: line 1 column 0 (char 0)
Why is that?
forget about it, I found the problem, thanks man
Traceback (most recent call last):
File “./main.py”, line 6, in
status = fbconsole.post(‘me/feed’, {‘message’:'Testing Wall’})
File “/usr/lib/python2.7/site-packages/fbconsole.py”, line 286, in post
return json.load(urllib2.urlopen(request))
File “/usr/lib64/python2.7/urllib2.py”, line 126, in urlopen
return _opener.open(url, data, timeout)
File “/usr/lib64/python2.7/urllib2.py”, line 400, in open
response = self._open(req, data)
File “/usr/lib64/python2.7/urllib2.py”, line 418, in _open
‘_open’, req)
File “/usr/lib64/python2.7/urllib2.py”, line 378, in _call_chain
result = func(*args)
File “/usr/lib/python2.7/site-packages/poster/streaminghttp.py”, line 170, in https_open
return self.do_open(StreamingHTTPSConnection, req)
File “/usr/lib64/python2.7/urllib2.py”, line 1177, in do_open
raise URLError(err)
urllib2.URLError:
and that? is a bug?
How can I publish a picture on group feed? Im trying like that
fbconsole.post(‘/257042030978195/feed’, {‘message’:'picture info’, ‘picture’:open(‘pic.jpg’)})
this number is the group id.
I am trying to use GRAPH API to search for ‘Programming’ groups using ‘Request’ method as follows:
LIMIT = 100
i=0
while True:
results = gapi.request(“search”,{“q”: “programming”,”type”: “group”,”limit”: LIMIT,”offset”: LIMIT *i})
if not results['data']:
break
ids = [group['id'] for group in results['data'] if group['name'
].lower().find(‘programming’) > -1]
# once groups stop containing the term we are looking for in their name, bail out
if len(ids) == 0:
break
group_ids += ids
i += 1
BUT I get the following error, do you know how I could resolve this. I appreciate your help.
File “C:\Python27\Lib\SITE-P~1\PYTHON~2\pywin\framework\scriptutils.py”, line 325, in RunScript
exec codeObject in __main__.__dict__
File “C:\FacebookApps\facebook__graph_query.py”, line 39, in
results = gapi.request(“search”,{“q”: “programming”,”type”: “group”,”limit”: LIMIT,”offset”: LIMIT *i})
TypeError: __call__() takes exactly 1 argument (3 given)
Many thanks! I think will be very useful for me… http://sourceforge.net/projects/miniaturizador
Pingback: Easy Facebook Scripting in Python | koma 小站
Please help, when I import fbconsole, I got this error
Internal Server Error
import_string() failed for ‘myapp.views.index’. Possible reasons are: – missing __init__.py in a package; – package or module path not included in sys.path; – duplicated package or module name taking precedence in sys.path; – missing module, class, function or variable; Debugged import: – ‘myapp’ found in ‘D:\\PythonProj\\LLL\\myapp\\__init__.pyc’. – ‘myapp.views’ not found. Original exception: ImportError: No module named fbconsole
I installed fbconsole using pip install fbconsole
Thanks this is amazing sir!
how do i reset the access token?
{u’error_subcode’: 463, u’error_code’: 190, u’error_msg’: u’Error validating access token: Session has expired at unix time 1361746800. The current unix time is 1361837574.’, u’request_args’: [{u'value': u'fql.query', u'key': u'method'}, {u'value': u'AAACjeiZB6FgIBACqHZCUunAzdQIuWN15nB01ypZBrp4Qr4QQM0mayDdw5ZBkq895m4LZC65ZBZC797m9KxrQOZAeFwX0v9AuHd9SFU4R6luy2kiLfZAOFU1jl', u'key': u'access_token'}, {u'value': u'SELECT name FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me())', u'key': u'query'}, {u'value': u'json', u'key': u'format'}]}
wait i think i found the answer https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/
rm .fb_access_token
This is just wonderful. Is it possible to get my wall data in JSON ?