Using Python for Facebook to search - python

I'm trying to use Python to search the Facebook Graph for Pages. When I use the Graph API Explorer on the Facebook webpage and I enter:
search?q=aquafresh&type=page
I get the results I'm looking for. When I do the same in Python (after installing the PythonForFacebook module):
post = graph.get_object("search?q=aquafresh&type=post")
I get:
facebook.GraphAPIError: Unsupported get request. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api
I believe I'm properly identifying with the token, I'm using the same one as the webpage and it works on the webpage. I'm also able to do basic queries in Python (e.g., querying for "me" works fine)

I figured out a way to do this that doesn't involve the Facebook Graph API. Instead, use the Requests library:
import requests
token = "your_token"
query = "your_query"
requests.get("https://graph.facebook.com/search?access_token=" + token + "&q=" + query + "&type=page")

You can directly use search method of `GraphAPI
import facebook
TOKEN = "" # Your GraphAPI token here.
graph = facebook.GraphAPI(access_token=TOKEN, version="2.7")
posts = graph.search(q="aquafresh", type="post")
print posts['data']
Instead of:-
$ pip install facebook-sdk
Use this:-
pip install -e git+https://github.com/mobolic/facebook-sdk.git#egg=facebook-sdk

What works for me is:
graph.request('search', {'q': 'aquafresh', 'type': 'page'})
That’s not exactly what you need, but when I try to search for posts (rather than pages) containing “aquafresh,” I get:
In [13]: graph.request('search', {'q': 'aquafresh', 'type': 'post'})
---------------------------------------------------------------------------
GraphAPIError Traceback (most recent call last)
<ipython-input-13-9aa008df54ba> in <module>()
----> 1 graph.request('search', {'q': 'aquafresh', 'type': 'post'})
/home/telofy/.buildout/eggs/facebook_sdk-0.4.0-py2.7.egg/facebook.pyc in request(self, path, args, post_args)
296 except urllib2.HTTPError, e:
297 response = _parse_json(e.read())
--> 298 raise GraphAPIError(response)
299 except TypeError:
300 # Timeout support for Python <2.6
GraphAPIError: (#11) Post search has been deprecated
(I wonder why deprecation doesn’t result in a mere warning.)
The request method seems to be missing from the documentation, but it’s documented in the code.

This should work:
import facebook
aToken = "your access tocken"
graph = facebook.GraphAPI(access_token=aToken, version="2.10")
data = graph.search(
q='aquafresh',
type='post'
)

Related

Get tokens in DocuSign in Python

I am working in a project and I am trying to get the access token to use the DocuSign API, but the call to get the oauth userinfo does not work.
Authentication type: JWT Grant
Python SDK: docusign-python-client
The code:
class BaseDocusign:
api_client = None
_token_received = False
expiresTimestamp = 0
account = None
def __init__(self):
BaseDocusign.api_client = ApiClient()
def token_is_expired(self):
current_time = int(round(time.time()))
return (current_time + DOCUSIGN_EXPIRE_TIME - 10) > BaseDocusign.expiresTimestamp
def check_token(self):
if not BaseDocusign._token_received or self.token_is_expired():
self.update_token()
def update_token(self):
client = BaseDocusign.api_client
client.request_jwt_user_token(
DOCUSIGN_CLIENT_ID,
DOCUSIGN_ACCOUNT_ID,
DOCUSIGN_AUTH_SERVER,
DOCUSIGN_PRIVATE_KEY,
DOCUSIGN_EXPIRE_TIME
)
if BaseDocusign.account is None:
account = self.get_account_info(client)
print account
BaseDocusign._token_received = True
BaseDocusign.expiresTimestamp = (int(round(time.time())) + DOCUSIGN_EXPIRE_TIME)
def get_account_info(self, client):
client.host = DOCUSIGN_AUTH_SERVER
response = client.call_api("/oauth/userinfo", "GET", response_type="object")
if len(response) > 1 and 200 > response[1] > 300:
raise Exception("can not get user info: %d".format(response[1]))
accounts = response[0]['accounts']
target = target_account_id
if target is None or target == "FALSE":
# Look for default
for acct in accounts:
if acct['is_default']:
return acct
# Look for specific account
for acct in accounts:
if acct['account_id'] == target:
return acct
raise Exception("User does not have access to account {target}\n")
When I run it:
a = BaseDocusign()
a.update_token()
The access token is generated:
{"access_token":"eyJ0eXAiOiJNVCIsImFsZyI6IlJTMjU2Iiwia2lkIjoiNjgxODVmZjEtNGU1MS00Y2U5LWFmMWMtNjg5ODEyMjAzMzE3In0.AQkAAAABAAsADQAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwIgAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwBwAAq89LFJXXSAgAAOvyWVeV10gLAB8AAABodHRwczovL2FjY291bnQtZC5kb2N1c2lnbi5jb20vDAAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwGAABAAAABQAAABIAAQAAAAYAAABqd3RfYnI.f_XW63iL5ABts-gq48ciWKQnaYyNiIEG9rC_CpnyWo0Hzf-B_G3hIRUWJzD1Yiyyy4pKm_8-zoalsoqANcMeXsjwBTCMlXIhc216ZWa6nHR6CheRbfTHM6bJ1LKwRdmnpwLywu_qiqrEwEOlZkwH_GzSSP9piUtpCmhgdZY1GFnG2u9JU_3jd8nKN87PE_cn2sjD3fNMRHQXjnPeHPyBZpC171TyuEvQFKCbV5QOwiVXmZbE9Aa_unC-xXvvJ2cA3daVaUBHoasXUxo5CZDNb9aDxtQkn5GCgQL7JChL7XAfrgXAQMOb-rEzocBpPJKHl6chBNiFcl-gfFWw2naomA","token_type":"Application","expires_in":28800}
But when try to get the account info, the call fails:
{"error":"internal_server_error","reference_id":"f20e360c-185d-463e-9f0b-ce95f38fe711"}
To do this, I call to the get_account_info function and it calls to the endpoint oauth/userinfo, but the call fails.
response = client.call_api("/oauth/userinfo", "GET", response_type="object")
# Response: {"error":"internal_server_error","reference_id":"f20e360c-185d-463e-9f0b-ce95f38fe711"}
To do this example, I need the variable account_id and according to this example, the get_account_info function gets it.
I have also tried to do what the web says (step4) to get user information and the answer is:
curl --request GET https://account-d.docusign.com/oauth/userinfo--header "Authorization: Bearer eyJ0eXAiOiJNVCIsImFsZyI6IlJTMjU2Iiwia2lkIjoiNjgxODVmZjEtNGU1MS00Y2U5LWFmMWMtNjg5ODEyMjAzMzE3In0.AQoAAAABAAUABwAAYWSFlJrXSAgAAMko55ya10gCAP-ftnA70YROvfpqFSh7j7kVAAEAAAAYAAEAAAAFAAAADQAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwIgAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwEgABAAAABgAAAGp3dF9iciMAJAAAAGY3M2I2MTJjLThiNzctNGI0Yy1hZGU0LWUyNGVhMmI2ODExMA.YHFoD2mQbwh8rdiPi8swg9kO9srlDyJcpqUo8XI5tdZki2I_Nla-qb9VaD4gAy8tSXVSY7unRjfClFDAqC8Ur73caHuZo7tN5tIKmXi6C3VzPWPGFJtsceKNEGMqwznw6OBVuPQG0IGlRjXK37Ur1nILLUWKb7w6O5Uz6y0e5uR8sxzZWh1adm2zHqd6khiQuAFB9vG2sS3jaudtck1qV6HRB_kARvUie1zglvHydc42Nc_o5GtIm3sGrqW7rio3YpHVX39nTKM-28kjOvPSNwzXp3IlZtaxuB6EdexrECH19nIaNbCe29LrdpzreRMyjEwwM309bOaKJ1KV82NbTQ"
# Response
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
curl: (3) URL using bad/illegal format or missing URL
Thanks for all :)
Just looking into the code, the return is "acct", a dictionary. So you need to use account['account_id']
I found this full example: https://github.com/docusign/eg-01-python-jwt
And in here: https://github.com/docusign/eg-01-python-jwt/blob/master/example_base.py#L44
you see how they are passing the account_id
Hopefully this helps. good luck
You must use request_jwt_user_token not request_jwt_application_token
See the code example: https://github.com/docusign/eg-01-python-jwt/blob/master/example_base.py#L34
request_jwt_application_token is only for some of the DocuSign organization APIs.
Added
From the comment:
I have changed the call to request_jwt_user_token and I get another token, but it still fails. The response is {"error":"internal_server_error","reference_id":"846114d0-1bcd-47a6-ba23-317049b54d00"}
Answer:
You're calling the /oauth/userinfo API method. But the Authorization header was not included.
One way is to set the Authorization explicitly:
client.set_default_header("Authorization", "Bearer " + ds_access_token)
In your case, the SDK is supposed to set it for you. It could be that you're using a new client object, an older SDK version, or some other issue.
I just downloaded the eg-01-python-jwt code example repo and it worked fine. I suggest that you download the example app and get it running first, then update the app to your needs.
Also, check the version of the Python SDK you're using:
pip3 show docusign_esign
Name: docusign-esign
Version: 3.0.0
Summary: DocuSign REST API
...
Location: /usr/local/lib/python3.7/site-packages
...
This error can be also caused by using an expired token (use the refresh end point to get a new one)

Azure loganalytics python SDK always throws MissingApiVersionParameter exception

I try to follow MS official doc to get the log from my resource in Azure Log Monitor but never success.
My code is like below.
from azure.loganalytics import LogAnalyticsDataClient
from azure.common.client_factory import get_client_from_cli_profile
from azure.loganalytics.models import QueryBody
log_client = get_client_from_cli_profile(LogAnalyticsDataClient)
myWorkSpaceId = '1234567890...'
result = log_client.query(myWorkSpaceId, QueryBody(**{'query': 'Heartbeat| limit 50'}))
And I always get exception like below:
result = log_client.query(myWorkSpaceId, QueryBody(**{'query': 'Heartbeat| limit 50'}))
File ".../lib/python2.7/site-packages/azure/loganalytics/log_analytics_data_client.py", line 121, in query
raise models.ErrorResponseException(self._deserialize, response)
azure.loganalytics.models.error_response.ErrorResponseException: (MissingApiVersionParameter) The api-version query parameter (?api-version=) is required for all requests
I trace code into library in /azure/loganalytics/log_analytics_data_client.py, and dump the url string used for query like below.
print(url, query_parameters, header_parameters, body_content)
request = self._client.post(url, query_parameters)
response = self._client.send(request, header_parameters, body_content, stream=False, **operation_config)
The output of the url and query information is like below and it look like no version information in between and I doubt this is why I get the exception:
('https://management.azure.com/workspaces/1234567890.../query', {}, {'Content-Type': 'application/json; charset=utf-8'}, {'query': 'Heartbeat| limit 50'})
My azure SDK version is 4.0.0, and my azure-loganalytics library version is v0.1.0, running on Ubuntu.
Does anyone run into same issue or know how to fix this?
Thanks.

IBM Phoneme Detection in Python

I'm trying to use the watson developer cloud python library to interface with the IBM Speech to Text API in an effort to detect which phonemes or syllables exist in some text. But I'm running into some issues relating to a required parameter called customization_id, and I'm hoping someone might be able to provide more context on what value to pass in. I wasn't able to understand after reading the docs. Here is a code snippet:
from watson_developer_cloud import TextToSpeechV1, WatsonApiException
API_KEY = "<redacted>"
URL = "https://gateway-wdc.watsonplatform.net/text-to-speech/api"
client = TextToSpeechV1(iam_apikey=API_KEY, url=URL)
try:
#response = client.get_word(customization_id="1", word="HELLO WORLD")
#> Malformed GUID: '1'
#response = client.get_word(word="HELLO WORLD")
#> get_word() missing 1 required positional argument: 'customization_id'
#response = client.get_word(customization_id=None, word="HELLO WORLD")
#> ValueError: customization_id must be provided
#response = client.get_word(customization_id="GA", word="HELLO WORLD")
#> ERROR 400: Malformed GUID: 'GA'
# WHAT VALUE TO USE FOR CUSTOMIZATION_ID ??? ...
response = client.get_word(customization_id="_______", word="HELLO WORLD") #>
print("RESPONSE")
print(type(response))
except WatsonApiException as ex:
print(f"ERROR {str(ex.code)}: {ex.message}")
EDIT: It is possible the expected value is the identifier of a new custom voice model. I've started investigating that strategy here, but unfortunately I'm also running into issues on that one as well. The approach might be something like:
# ...
voice_model_response = client.create_voice_model(
name="My Custom Model",
language=LANG,
description="to get a valid 'customization_id' value..."
).get_result()
customization_id = voice_model_response["customization_id"]
response = client.get_word(customization_id=customization_id, word="HELLO WORLD")
# ...
I think you have misread the documentation for the Speech to Text service.
You can create a customisation to modify how a corpus uses pronunciation to detect words
https://cloud.ibm.com/apidocs/speech-to-text?code=python#add-custom-words
But to do that you need to create a customisation, which you can’t do with a lite account.
https://cloud.ibm.com/apidocs/speech-to-text?code=python#create-a-custom-language-model
You can use the API to list which customisations you have already created.
https://cloud.ibm.com/apidocs/speech-to-text?code=python#list-custom-language-models
It turns out I was using the wrong URL and wrong API Key. After fixing the URL to really be "https://gateway-wdc.watsonplatform.net/text-to-speech/api" and creating and upgrading a new standard-level text to speech service and using that service's API Key, I was able to implement the two-step process I mentioned in the updated part of my question.

Google API batch request returns HttpError 404 for every call through Python client

I have a little application based on google-api-python-client, but the batch request has not been working anymore for a couple of days (error 404).
For example, the following code worked fine until a few days ago.
from apiclient.http import BatchHttpRequest
from apiclient.discovery import build
import json
DEVELOPER_KEY = "foobar"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
channelIds = ['UC2C_jShtL725hvbm1arSV9w','UC2C_jShtL725hvbm1arSV9w']
parts_list = [
"id",
"brandingSettings",
]
fields_list = [
"items/id",
"items/brandingSettings/channel",
]
parts = ",".join(parts_list)
fields = ",".join(fields_list)
request_map = {}
def this_is_the_callback_function(request_id, response, exception):
if exception is not None:
# Do something with the exception
print exception
pass
else:
print request_id
print request_map[int(request_id)]
print json.dumps(response,sort_keys=True, indent=4)
service = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
batch = service.new_batch_http_request(callback=this_is_the_callback_function)
channels = service.channels()
i = 0
for c in channelIds:
i += 1
request_map[i] = c
request = channels.list(id=c,part=parts, fields=fields)
batch.add(request)
print request_map
batch.execute()
Now, If i run it, I get:
{1: 'UC2C_jShtL725hvbm1arSV9w', 2: 'UC2C_jShtL725hvbm1arSV9w'}
<HttpError 404 when requesting https://www.googleapis.com/youtube/v3/channels?fields=items%2Fid%2Citems%2FbrandingSettings%2Fchannel&alt=json&part=id%2CbrandingSettings&id=UC2C_jShtL725hvbm1arSV9w&key=foobar returned "Not Found">
<HttpError 404 when requesting https://www.googleapis.com/youtube/v3/channels?fields=items%2Fid%2Citems%2FbrandingSettings%2Fchannel&alt=json&part=id%2CbrandingSettings&id=UC2C_jShtL725hvbm1arSV9w&key=foobar returned "Not Found">
Strange. What it seems odd to me is that If I try to make a simple request to those links (simply by cutting and pasting an URL in the browser), the server returns data as usual.
It seems this problem is fixed with the newest version of the python library.
However, if someone still has to solve it, or is using a different environment (like iOS or android), that's the solution.
it seems google have used before a single batch url, which was:
https://www.googleapis.com/batch
this worked well in my apps, until it suddenly stopped. it seems the solution is to change the url for the batch calls to :
https://www.googleapis.com/batch/youtube/v3
(for youtube apis)
usually the google api objects will expose a property allowing to change this value, but if not it can be changed in source.

How to connect to weather API using requests?

I am trying to learn Requests and practicing by connecting to the weather API. But for some reason I can't get it to work? It is clear the weather API is wanting the param in a certain way that I cannot seem to figure out how it translates to Requests.
Here is my code:
r = requests.get('http://api.openweathermap.org/data/2.5/weather', q={'Anderson'})
Here is the link to the API page:
https://openweathermap.org/current
I see the weather pages wants the param in terms of q = city, but the error I get is:
TypeError: request() got an unexpected keyword argument 'q'
Also here the the Requests page that I am referring to: http://docs.python-requests.org/en/master/
Thanks for the help!
Please review the requests user manual, at least the quickstart guide.
The RESTful API you are about to use expects GET request with q="City Name" parameter. Moreover you must have the appid and add it for every request.
Register you application and choose a pricing plan https://openweathermap.org/price
Pass both q="City Name" and APPID=xxx parameters
Here is corresponding request:
api_url = 'http://api.openweathermap.org/data/2.5/weather'
appid = ...
r = requests.get(url=api_url, params=dict(q='Anderson', APPID=appid))
You need an appid for openweather, which for individual use is free (https://openweathermap.org/appid#get)
>>> import requests
>>> r = requests.get('http://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b1b15e88fa797225412429c1c50c122a1')
>>> loc_weather = r.content.strip()
>>> loc_weather
'{"coord":{"lon":-0.13,"lat":51.51},"weather":[{"id":300,"main":"Drizzle","description":"light intensity drizzle","icon":"09d"}],"base":"stations","main":{"temp":280.32,"pressure":1012,"humidity":81,"temp_min":279.15,"temp_max":281.15},"visibility":10000,"wind":{"speed":4.1,"deg":80},"clouds":{"all":90},"dt":1485789600,"sys":{"type":1,"id":5091,"message":0.0103,"country":"GB","sunrise":1485762037,"sunset":1485794875},"id":2643743,"name":"London","cod":200}'
Try changing your call to the one that follows (by adding the api key to the params):
r = requests.get('http://api.openweathermap.org/data/2.5/weather', params={'q': 'Anderson', 'APPID': YOUR_API_KEY})
This worked for weatherbit.
The url:
url = "https://api.weatherbit.io/v2.0/history/daily"
Create a payload:
payload = {'key':'12345fcfa0hjde13a7896fbdae1ghjkjh',
'city_id': '1261481', # This is New Delhi
'start_date': '2021-03-13',
'end_date': '2021-03-14'}
Call it using GET (the website specifies that GET call is supported):
data = requests.get(url, params=payload)
assert data.status_code == 200
assert 'error' not in data.json().keys()
Your data:
data.json() # Or text or content
My sys specs: Python 3.8, Request 2.25.1

Categories

Resources