"Access to this API has been disallowed" while querying Financial Times' - python

How to get FT articles via their API ?
After asking for a key I first used a python API wrapper around their content API, v2. So I ran the following:
from pyft import FT
ft = FT()
# the id can be pulled from the slug url of an FT.com story
content = ft.get_content("6f2ca3d6-86f5-11e4-982e-00144feabdc0")
print(content)
And got:
{'error': 'Access to this API has been disallowed'}
So I followed the official instructions but got the same error :

This should be a Bug from FT. Since, the get_content_notifications without any issues.
notification = ft.get_content_notifications("2018-10-10T00:00:00.000Z")
print(notification)
{
"requestUrl": "https://api.ft.com/content/notifications?since=2018-10-10T00%3A00%3A00.000Z",
"notifications": [
{
"type": "http://www.ft.com/thing/ThingChangeType/UPDATE",
"id": "http://www.ft.com/thing/e75d5a6c-b725-11e8-bbc3-ccd7de085ffe",
"apiUrl": "https://api.ft.com/content/e75d5a6c-b725-11e8-bbc3-ccd7de085ffe"
}
}

This is because your API key is under Headline License, which only allows access to limited enpoints. Therefore, you should consider purchasing a Datamining License in order to get access to more enpoints including the "get content" in your code. See more here: https://developer.ft.com/portal/docs-start-obtain-an-api-key

Instructions from FT.com
Download FT_API_Postman_Collection.json
Open Postman
Click Import, click Choose Files and specify FT_API_Postman_Collection.json. An import success message appears for each collection imported
Click the Eye icon to setup an Environment
Click Add
Enter an Environment name. for example, FTAPI
Copy your API Key from the email sent to you in the previous step
Enter a Key and a Value
Click Add
Click Add
When you setup an FTAPI environment, make sure the variable is named 'KEY' as this is what it is called in the Postman collection.json

Related

Read google spreadsheet in pandas dataframe

Not very experience with API authentication but I cannot figure out how to read a Google Sheet share with me from Python.
I've tried:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('/Users/alexiseggermont/Downloads/Accountable-7b29dac08324.json', scope)
gc = gspread.authorize(credentials)
wks = gc.open("mysheet").sheet1
This gives me ImportError: cannot import name 'opentype' on line 2.
I then tried:
import oauth2client.client, oauth2client.file, oauth2client.tools
import gspread
flow = oauth2client.client.OAuth2WebServerFlow(client_id, client_secret, 'https://spreadsheets.google.com/feeds')
storage = oauth2client.file.Storage('credentials.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
import argparse
flags = argparse.ArgumentParser(parents=[oauth2client.tools.argparser]).parse_args([])
credentials = oauth2client.tools.run_flow(flow, storage, flags)
gc = gspread.authorize(credentials)
# when this cell is run, your browser will take you to a Google authorization page.
# this authorization is complete, the credentials will be cached in a file named credentials.dat
This opens a window asking if I want to give my app access to my sheets, and I click yes. But then sheet = gc.open("mysheet").sheet1 gives me a permission error:
APIError: {
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission"
}
],
"code": 403,
"message": "Insufficient Permission"
}
}
The only suggestion I find to solve this error is to change the 'scope' variable, but there is no scope variable used in that code, so I am confused.
You can add several scopes using spaces. So can you try the following modification?
From :
flow = oauth2client.client.OAuth2WebServerFlow(client_id, client_secret, 'https://spreadsheets.google.com/feeds')
To :
flow = oauth2client.client.OAuth2WebServerFlow(client_id, client_secret, 'https://spreadsheets.google.com/feeds https://www.googleapis.com/auth/drive')
Note :
Before you run the modified script, please remove credentials.dat. By this, credentials.dat is created using new scopes.
In my environment, I confirmed that when the scopes is only https://spreadsheets.google.com/feeds, the same error occurs. When the scopes are https://spreadsheets.google.com/feeds https://www.googleapis.com/auth/drive, no error occurs.
there is also Gspread-Pandas library itself, where the docs have a simple intro to the Oauth part, and in a simpler way:
https://github.com/aiguofer/gspread-pandas
Before using, you will need to download Google client credentials for your app.
Client Credentials To allow a script to use Google Drive API we need
to authenticate our self towards Google. To do so, we need to create a
project, describing the tool and generate credentials. Please use your
web browser and go to Google console and :
Choose Create Project in popup menu on the top. A dialog box appears,
so give your project a name and click on Create button. On the
left-side menu click on API Manager. A table of available APIs is
shown. Switch Drive API and click on Enable API button. Do the same
for Sheets API. Other APIs might be switched off, for our purpose. On
the left-side menu click on Credentials. In section OAuth consent
screen select your email address and give your product a name. Then
click on Save button. In section Credentials click on Add credentials
and switch OAuth 2.0 client ID. A dialog box Create Cliend ID appears.
Select Application type item as Other. Click on Create button. Click
on Download JSON icon on the right side of created OAuth 2.0 client
IDs and store the downloaded file on your file system. Please be
aware, the file contains your private credentials, so take care of the
file in the same way you care of your private SSH key; i.e. move
downloaded JSON to ~/.config/gspread_pandas/google_secret.json (or you
can configure the directory and file name by directly calling
gspread_pandas.conf.get_config Thanks to similar project df2gspread
for this great description of how to get the client credentials.
User Credentials Once you have your client credentials, you can have
multiple user credentials stored in the same machine. This can be
useful when you have a shared server (for example with a Jupyter
notebook server) with multiple people that may want to use the
library. The first parameter to Spread must be the key identifying a
user's credentials. The first time this is called for a specific key,
you will have to authenticate through a text based OAuth prompt; this
makes it possible to run on a headless server through ssh or through a
Jupyter notebook. After this, the credentials for that user will be
stored (by default in ~/.config/gspread_pandas/creds or you can
manually set it in GSPREAD_PANDAS_CONFIG_DIR env var) and the tokens
will berefreshed automatically any time the tool is used.
Users will only be able to interact with Spreadsheets that they have
access to.
Handling Authentication In the backend, the library is leveraging
Google's oauth2client
<http://oauth2client.readthedocs.io/en/latest/__ to handle
authentication. It conveniently stores everything as described above
so that you don't have to worry about boiler plate code to handle
auth. However, if you need to customize how you handle authentication
you can do so in a few different ways. You can change the directory
where everything is stored using the GSPREAD_PANDAS_CONFIG_DIR env
var. You can also generate your own
oauth2client.client.OAuth2Credentials and pass them in when
instanciating a Client or Spread object. For other ways to customize
authentication, see gspread_pandas.conf.get_config and
gspread_pandas.conf.get_creds

Data transfer between two users don't work from Admin SDK and Admin Web Panel

I'm writing code in Python that has the task to suspend user and transfer his data to other user.
Unfortunatelly I discovered that that functionality doesn't work.
Acording to documentation of API
https://developers.google.com/admin-sdk/data-transfer/v1/reference/transfers/insert
I created in code object which looks like this in python:
{
'oldOwnerUserId': 'XXXXXXXXXXXXXXXXXXXXX',
'newOwnerUserId': 'YYYYYYYYYYYYYYYYYYYYY',
'applicationDataTransfers':
[
{'applicationId': 'UUUUUUU'}
]
}
Where:
"XXXXXXXXXXXXXXXXXXXXX" is old user ID
"YYYYYYYYYYYYYYYYYYYYY" is new user ID
"UUUUUUU" is my Google drive Application ID
then I'm running code:
transfer_service.transfers().insert(body=transfer_data).execute()
While running the script there are no errors. After few seconds I recive email that "Data transfer successful" but when I look into new created directory on Drive I see that it is empty. I tested this several times with the same result.
I'm sure that it isn't problem with:
Credidentials - I'm able to get ID's of users and ID of google drive
Users and drive ID's - I have checked them via web panel in above link
I tried to do the same thing via https://admin.google.com and result is the same.
What cause that problem?
After contacting Google they told me to add transfer parameters described on website:
https://developers.google.com/admin-sdk/data-transfer/v1/parameters
working object now looks like this:
{
'oldOwnerUserId': 'XXXXXXXXXXXXXXXXXXXXX',
'newOwnerUserId': 'YYYYYYYYYYYYYYYYYYYYY',
'applicationDataTransfers':
[
{
'applicationId': 'UUUUUUU'
'applicationTransferParams':
[
{
'key': 'PRIVACY_LEVEL',
'value': ['PRIVATE', 'SHARED']
}
]
}
]
}
Acording to my conversation w Google without applicationTransferParams script works but It doesn't know what type of data needs to transfer.

inserting a moment into g+ from python

My question is very similar to moment.insert from python code but Fausto has already managed to get further than me so I'm unable to apply that answer at this time.
My code looks like this, and my question is "how do I post to my g+ profile"
user = 'awarner#######.com'
key = open(keyFile, 'r').read()
credentials = SignedJwtAssertionCredentials(
'##########developer.gserviceaccount.com',
key,
scope='https://www.googleapis.com/auth/plus.login',
sub=user)
http = httplib2.Http()
http = credentials.authorize(http)
service = build(serviceName='plus', version='v1', http=http)
# Not really required here but these calls demonstrate that we are authenticated
searchResults = service.people().search(query='AlistairWarner').execute()
listMoments = service.moments().list(userId='me', collection='vault').execute()
moment = { "type" : "http://schemas.google.com/AddActivity",
"target" : {
"id" : "target-id-1",
"type" : "http://schemas.google.com/AddActivity",
"name" : "The Google+ Platform",
"description" : "A page that describes just how awesome Google+ is!",
"image" : "https://developers.google.com/+/plugins/snippet/examples/thing.png"
}
}
# This call fails with a "401 Unauthorized" error
insertResults = service.moments().insert(userId='me', collection='vault', body=moment).execute()
Just for the record I have confirmed that I have correctly delegated domain-wide authority to my service account for the necessary scopes - although I don't believe that this is really an authorization issue per se because the list call is working. I have also confirmed that my "App" appears on my g+ profile under Apps as mentioned by Prisoner in response to Fausto's question (referenced above).
Looking at the API reference page it does warn that you will get the 401 error that I am seeing. It, and other posts here on StackOverflow (I'd give the ref but not allowed to), say that you need to add the data-requestvisibleactions (again, can't give ref) attribute but I am struggling to see the relevance of the Sign-In Button that they describe attaching it to in my code - which has no UI, I just run it from the command line. So, requestvisibleactions does seem to be the best candidate, I just don't know how to translate that into something that I can use here.
Does anyone have a clue how to get this working?
You need to add this as part of your OAuth request credentials. So it might look something like
credentials = SignedJwtAssertionCredentials(
'##########developer.gserviceaccount.com',
key,
scope='https://www.googleapis.com/auth/plus.login',
requestvisibleactions='http://schemas.google.com/AddActivity',
sub=user)

Facebook Graph API key error

I am working on a python AppEngine application with Facebook login. I want to be able to access a logged-in user's friends' bios (their "about me" information).
Having requested/saved changes for all of the permissions I need on the Facebook developer's dashboard, I can successfully make calls like this:
friends = graph.get_connections("me", "friends", fields="name")
for friend in friends["data"]:
print friend["name"]
But trying to access the about me, as specified by the "bio" field in the docs, results in a key error:
friends = graph.get_connections("me", "friends", fields="name,bio")
for friend in friends["data"]:
print friend["bio"]
AppEngine log when running on local host:
File "/Users/nicole/aggie-harmony/main.py", line 154, in get
user = self.current_user
File "/Users/nicole/aggie-harmony/main.py", line 108, in current_user
bio = friend["bio"]
KeyError: 'bio'
INFO 2013-11-16 02:59:27,243 module.py:608] default: "GET / HTTP/1.1" 500 -
I have experimented with other fields, and it seems like anything that requires an access token will generate a key error (although the docs actually seem to have been updated mere HOURS before this question was posted...and they now suggest that "Other fields that have been explicitly set to public visibility can also be retrieved without an access token"...in my test user, the bio is indeed public!)
Unless I am just missing something syntax-wise, is this indeed a token issue? My app is based on the example here and basically obtains/uses the access token like this (auth stuff was generated previously and stored in its own file):
...
cookie = facebook.get_user_from_cookie(self.request.cookies, auth.FACEBOOK_APP_ID,
auth.FACEBOOK_APP_SECRET)
...
graph = facebook.GraphAPI(cookie["access_token"])
...
Interestingly enough, the app doesn't pop up a permission box for the user after the log-in area, which might support my hunch...
SOLVED: It was indeed an issue of permissions. In my adapted example html file, I just needed to change this:
function doLogin() {
FB.login(function(response) {} , {perms:''});
}
...to this:
function doLogin() {
FB.login(function(response) {} , {perms:'user_about_me,friends_about_me,user_likes,friends_likes,user_relationship_details,friends _relationship_details,user_relationships,friends_relationships, user_education_history, friends_education_history'});
}
Facebook takes care of the rest with the proper oauth dialog, etc.

Using additional Google APIs in my Glassware (Sharing to g+ accounts)

I'm trying to share a card ( the html inside it ) from my Glassware using python and the Python Mirror API Quickstart code.
creds = StorageByKeyName(Credentials, '#####', 'credentials').get()
plus_service = util.create_service('plus', 'v1', creds)
moment = {"type":"http://schemas.google.com/AddActivity",
"target": {
"id": "target-id-1",
"type":"http://schemas.google.com/AddActivity",
"name": "The Google+ Platform",
"description": "A page that describes just how awesome Google+ is!",
"image": "https://developers.google.com/+/plugins/snippet/examples/thing.png"
}
}
google_request = plus_service.moments().insert(userId='me', collection='vault', body=moment)
result = google_request.execute()
I got this response back:
HttpError: <HttpError 403 when requesting https://www.googleapis.com/plus/v1/people/me/moments/vault?alt=json returned "Insufficient Permission">
I can understand that is a permission problem but my question is, what is the suggested UI to ask to a glass user for G+ permissions?
Furthermore, by adding "https://www.googleapis.com/auth/plus.login" in the requested permissions I got this:
https://www.googleapis.com/plus/v1/people/me/moments/vault?alt=json returned "Unauthorized">
Thanks in advance
To get G+ access, you can piggyback on the authorization process that Mirror API uses. Make the following modifications to the Mirror API Python Quickstart project:
First, enable the Google+ API in the Google API Console for your project.
Second, in oauth/hander.py, add your G+ scope to the SCOPES list:
SCOPES = ('https://www.googleapis.com/auth/glass.timeline '
'https://www.googleapis.com/auth/glass.location '
'https://www.googleapis.com/auth/userinfo.profile '
'https://www.googleapis.com/auth/plus.login')
Third, revoke your old auth tokens and get fresh ones. Do this by signing out of and signing back into your Quickstart instance's web front end. When you sign in, the sign in page should be updated to list the new Google+ permission:
With these steps, the code you posted should work. Comment if it doesn't and I can help you continue debugging.

Categories

Resources