Getting a Facebook page access token for a simple app (Python) - python

I'm trying to create a very simple Facebook app (using the Python SDK) that does nothing more than post to its own page. The eventual app will make one post per day, and that's all it will do. (Please note that I am a novice programmer, and this is in part a learning exercise for me.)
My initial test code looks like this, and it successfully posts to the page:
import facebook
token = 'XXXXX'
graph = facebook.GraphAPI(access_token = token,
version = "2.1")
graph.put_object(parent_object='me',
connection_name='feed',
message='Test post to page')
The catch is that it only works if I plug in a value for token that is a valid page access token. For testing, I can get one from the Graph API Explorer, but obviously I'd like my app to be able to get one each time it runs, using its own credentials (e.g. app ID and app secret).
I have been searching for a way to do this with the Python SDK, but I have had no luck finding out how, in part because most apps are much more complicated (involving user logins and so forth). I don't see Is there a simple way to do this, or is the problem more complicated than I think it is?

There is no way to auto-generate a Page Token, but you can use an Extended Page Token - it is valid forever.
More information:
https://developers.facebook.com/docs/facebook-login/access-tokens/expiration-and-extension
http://www.devils-heaven.com/facebook-access-tokens/
Token debugger: https://developers.facebook.com/tools/debug/accesstoken/

Related

Flask-Dance for OAuth

I am relatively new to programming, and have been learning about OAuth2 with Python. Specifically, I have been learning how to use Flask-Dance, beginning with its implementation for Google authentication. I am wondering:
1) Which Google API does Flask-Dance make use of? I see that the default scope in F-D is 'profile', but I can't seem to figure out what other scopes are available
2) What is the difference between the Google API Explorer and the Google OAuth2 Playground? When/why would I use one over the other?
Any help would be appreciated.
Thanks!
1.) Flask dance makes use of OAuth. Oauth is used specifically for allowing users to give authorization to your app or for authenticating users with the OpenID standard. What this means is, say, you want to get data from a user's google account, e.g. you want a list of their google contacts, you'll use OAuth to get authorization from that user. Another use case is if you want to let users login to your application using google. You'd use Oauth for that. In this case you'll be dealing mostly with access tokens and authorization codes, this is what Flask Dance is for.
For more information on OAuth, here's a video that explains it and its various use cases in plain English: https://www.youtube.com/watch?v=0VWkQMr7r_c
2.) The Google API is for a completely different use case. You're not trying to get data from a user's google account and you're not trying to let users login to your application with google. You want to simply use a Google service on your application. For instance you want to use Google Maps in your app so that you can let users of your app get directions to a place. In this case, you'll be working with API keys that identify your application.

Spotipy -- accessing tracks from a public playlist without authentication

I want to search through public playlists and get the tracks. So far I have code which can get the names of the playlists but not the tracks:
import spotipy
import sys
sp = spotipy.Spotify()
if len(sys.argv) > 1:
artist_name = ' '.join(sys.argv[1:])
results = sp.search(q=artist_name, limit=20, type='playlist')
for i, t in enumerate(results['playlists']['items']):
print(i,' ', t['name'])
This will print a list of the first 20 public playlists names given the search condition. What I want is to also print the tracks in each playlist! I thought this would be simple, but after searching it seems like the only way is to via authentication, which I do not want. These tracks are public, so why would I need to authenticate to list the tracks?! There are two reasons I think this. 1) if I add (in the loop):
print t['tracks']
the request response says "This request requires authentication". Additionally, I found this example on the spotipy documentation which is exactly what I want, but only for authenticated users. https://github.com/plamere/spotipy/blob/dd021c4087981b583ef0f2b276cd43bbc6fd429f/examples/user_playlists_contents.py
So, is there any way to view the tracks without authenticating as the owner of that playlist? Opening the desktop Spotify app can quickly show anyone that public playlist tracks are completely searchable and viewable so it must be possible.
I apologize if this is an extremely specific question -- but I'm not sure where else to ask seeing as this is my first time with this API or with an API like this at all. I have done quite a bit of research on this topic and now have resigned to asking for help.
This is a typical OAuth confusion. There are potentially three parties involved here.
Your application (that tiny little python snippet above)
Spotify Web API
A Spotify user
If your app wanted to find and delete a Spotify user's playlists that begin with X, the Spotify Web API would demand that your app first nicely ask the user for permission to do that. Feels natural...
In this scenario, your app Playlist X Deleter first has to authenticate to prove that it actually is Playlist X Deleter. The user then needs to authenticate with Spotify to prove that it actually is the user the Playlist X Deleter wanted to delete playlists for. Then, the user who we now know who it is needs to authorize Playlist X Deleter that we now know who it is to delete playlists.
So, you have an app that authenticates and a user who authenticates.
For information that is public, there is no obvious reason why a user needs to authenticate. There is also no obvious reason why an app needs to authenticate. However, Spotify has decided that the app must authenticate to get public playlist information. Maybe so it can disable bad users who spiders too much playlist data or otherwise abuse the api.
In this case, since there are no private playlists involved, and only read rights, no user needs to authorize anything. In the OAuth world, this is called client credentials flow https://www.rfc-editor.org/rfc/rfc6749#section-4.4
Go to the developer console and create an application to get a client_id and client_secret:
https://developer.spotify.com/my-applications/#!/applications/create
Then follow:
https://developer.spotify.com/web-api/authorization-guide/#client_credentials_flow
or in your case, supply the client_id and client_secret to spotipy through the SpotifyClientCredentials
doc: http://spotipy.readthedocs.io/en/latest/#spotipy.oauth2.SpotifyClientCredentials
example snippet (that doesn't fill in anything though): https://github.com/plamere/spotipy/blob/master/examples/client_credentials_flow.py

Error 414 when logging in with multiple accounts

We're using GAE Python and allow users to login using their existing Google accounts. The login code is straightforward:
def _require_login(self, target_url="/"):
if not self.user_bundle.user:
return self.redirect(
self.user_bundle.create_login_url(target_url),
abort=True
)
This creates a redirect to Google for the user to login, then upon successful login gets sent back to wherever they were originally trying to navigate.
The problem seems to be that if a user has more than a certain number of Google / GApps accounts logged in simultaneously (we're guessing 3 or more I can successfully reproduce it once I hit 5 accounts), they get an "Error 414" from Google:
My brief search on the error states that the URL is too long, since it's a GET request. Just about all of the advice states to use POST instead. The problem is, we're using Google's built-in create_login_url method, which, as far as I can tell, doesn't provide a way to specify POST instead of GET.
How can we fix this?
According to the Google Cloud Platform's Twitter account:
Unfortunately, only current fix is to logout of some accounts. >4 accounts logged in makes the URL too long (> 2048 bytes).
So now we're going to either make a pre-login page where it tells the user to log out of enough user accounts to meet the maximum number, or find an external library that allows us to let users log in without having to work around the limit.

Having trouble installing SimpleAuth for GAE

I have been working for a while, trying to install SimpleAuth on Google App Engine and I am running in to trouble. First off in the bottom of the sample code they have this:
def _get_consumer_info_for(self, provider):
"""Should return a tuple (key, secret) for auth init requests.
For OAuth 2.0 you should also return a scope, e.g.
('my app id', 'my app secret', 'email,user_about_me')
The scope depends solely on the provider.
See example/secrets.py.template
"""
return secrets.AUTH_CONFIG[provider]
and I don't see the secrets file anywhere nor what it is supposed to do.
Then in addition to that small problem I am curious how I am supposed to render the providers and their login URLs to the user. This page: https://github.com/crhym3/simpleauth/blob/master/example/handlers.py has a great description of the general setup but it doesn't have any description of what we actually need to pass to the user to let them login.
Thanks!
First off, please take into account that it's just an example, so some code parts were simplified for the demo purposes.
secrets is a separate module. The README file says to copy secrets.py.template into secrets.py and set proper client/consumer ids and secrets. Again, see README for info on where to get client/secrets for different providers.
The rendering is up to you. What I did as an example is this:
<p>Try logging in with one of these:</p>
Google
Facebook
Yahoo! (OpenID)
Twitter
LinkedIn
Windows Live
Those /auth/... links should get routed to your handler (normally webapp2.RequestHandler or some subclass) that's mixed in with SimpleAuthHandler.
You can see the example app live at https://simpleauth.appspot.com, hopefully it'll clarify things.

Grant GAE-app access to a Google API with google-api-python-client

I'm developing a Google App Engine-app where one can fill out an online-form and based on how you fill it out a calendar post in a specific Google Calendar is created. What I'm wondering about is authorization in this type of situation where I want this form to be 100% publicly available and require no login whatsover to create the calendar post.
Using OAuth2 I have gotten the actual form and post-creation to work as I want but only when I'm signed in.
This is what I'm doing now, I have:
One registered app, let's call it form-app(.appspot.com)
One Google account, let's call it form-app-admin(#gmail.com) This account owns the Google Calendar that the posts are going in.
One API Project owned by form-app-admin
I have used these and the google-api-python-client library (with its oauth2decorator) as in the Google App Engine-example so when I'm logged in as form-app-admin and surf onto form-app.appspot.com everything works exactly as I want it to but if I am not logged in as form-app-admin, naturally, it doesn't.
So what I would like to do is to kind of grant this permission to write to form-app-admin's primary calendar to the actual app rather than the user currently using the app. Or is there a better way?
The only premises is that anyone (logged into gmail or not) should be able to fill out the form and thus creating a post in some google calendar.
Naturally I would be very thankful if anyone happened to have the appropriate python code to achieve this but primarily I want help figuring out how to go about this since I have very little experience with auth-related stuff.
Thank you for your time!
/Tottish
What you want is the App Identity API. That page shows examples of how to use the API to assert identity to Google APIs.

Categories