Dialogflow query HTTP Request - python

I am trying to create a very simple chatbot using dialogflow that I can ask a question and get a fulfillment message back. I was able to use python's dialogflow library to get this working, but when I tried to change it to a regular request it did not work. Here is the working code:
import os
import dialogflow
from google.api_core.exceptions import InvalidArgument
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = PATH_TO_JSON
DIALOGFLOW_PROJECT_ID = PROJECT_ID
DIALOGFLOW_LANGUAGE_CODE = 'en'
SESSION_ID = 'me'
text_to_be_analyzed = "How are my stocks"
session_client = dialogflow.SessionsClient()
session = session_client.session_path(DIALOGFLOW_PROJECT_ID, SESSION_ID)
text_input = dialogflow.types.TextInput(text=text_to_be_analyzed, language_code=DIALOGFLOW_LANGUAGE_CODE)
query_input = dialogflow.types.QueryInput(text=text_input)
try:
response = session_client.detect_intent(session=session, query_input=query_input)
except InvalidArgument:
raise
#print(response)
print("Response:", response.query_result.fulfillment_text)
and it prints
your stocks are good
Using the request library I tried a similar setup and wrote this:
my_key = CLIENT_ACCESS_TOKEN
url = "https://api.dialogflow.com/v1/query?v=20170712"
headers = {
'Authorization': 'Bearer ' + my_key ,
'Content-Type' : 'application/json'
}
body = {
"lang": "en",
"query": "how are my stocks",
"sessionId": "me",
}
r.post(url,headers=headers,data=body).text
and I get an error:
{
"status": {
"code": 400,
"errorType": "bad_request",
"errorDetails": "Cannot parse json. Please validate your json. Code: 400"
}
}
I am getting my example from this url for the query post request. The reason I want this to work as an http request is because I would like to be able to use it in other applications and want to have a consistent way of accessing my intents. Thanks for the help!

Upon more research I found the error at this link. So the question was less about integration with dialogflow and more about making a request in python.

Related

Google Cloud Platform: Uptime Check / Response Validation "403(Forbidden)"

Trying to get Google to validate the output of my "Cloud-Function" in the "Response-Validation" for "Uptime-Checks".
I've used "regex" to try to validate my "Json" output but it doesn't work, when I test it I get: "Responded with "403 (Forbidden)" in 219 ms."
below is an example of what my "Source" is in the "Cloud-Function":
def example(request):
from flask import request, jsonify
import requests
postdata = {
"zzz": ["zzz"],
"zzz": ["zzz"],
"zzz": "zzz",
"zzz": {"distinct": True}
}
posturl = 'zzz'
requestheaders = {'Content-Type': 'application/json', 'X-Api-Key': 'zzz'}
r = requests.post(url=posturl, json=postdata, headers=requestheaders)
result = r.json()
return(result)
Resolved:
It was a permissions issue in the "IAM", due to the "Cloud Functions" and the "Monitoring/UptimeCheck" being in different projects.
How I tested it:
When I changed the functions "Authentication" to "Allow unauthenticated" which is open to the public, my regex in the "Response Content" worked
Sidenote:
make sure your "Path" under the "Target" tab in the "Uptime Check" is correct, look at the "URL ?" which is under "Path" to make sure you got the correct url.

How do I format my GET request to the Spotify Web API in Python?

I'm new to working with APIs. I'm trying to create a script that will output the tracks of a public playlist from Spotify. I have hit a roadblock at an early stage: I'm unsure how exactly to format my GET request to retrieve the tracks of the playlist in question and where I put the OAuth access token. My current attempt returns a 401 status code.
What I've done so far:
I have created an App on the Spotify Developers website dashboard.
I have saved client_id and client_secret from the dashboard into a script ("spotifysecrets.py").
I have run the following code in my main script:
import requests
from spotifysecrets import client_id as cid, client_secret as cs
AUTH_URL = "https://accounts.spotify.com/api/token"
token_req = requests.post(AUTH_URL, {
"grant_type": "client_credentials",
"client_id": cid,
"client_secret": cs
})
access_token = token_req.json()["access_token"]
Everything appears to have worked fine so far. The problem occurs in the next step.
Having obtained the token, I am getting a 401 error when trying to make my tracks request. The code I have written is as follows:
pl_id = "…" # I have elided the actual playlist ID for the purposes of this question
tracks = "https://api.spotify.com/v1/playlists/{}/tracks".format(pl_id)
songs_req = requests.get(tracks, {
"Authorization": "Basic {}".format(access_token)
})
Edit
I have tried using
songs_req = requests.get(tracks, headers={
"Authorization": "Basic {}".format(access_token)
})
instead but this gives a 400 error.
I looked into the api and I believe you have a syntax error:
songs_req = requests.get(tracks, {
"Authorization": "Basic {}".format(access_token)
})
should be:
songs_req = requests.get(tracks, {
"Authorization": "Bearer {}".format(access_token)
})

get end user tokens for eBay restful in Python

currently I am using eBay Trading API with Python. Thanks to: https://github.com/timotheus/ebaysdk-python
I used https://github.com/luke-dixon/django-ebay-accounts to get tokens for user.
Now, I would like to use Restful API (https://developer.ebay.com/docs#Acc). I don't think I can use tokens I have already. So, I managed thanks to Getting an Ebay OAuth Token get one. But I think I missing something, because during the process I cannot include info for user (name/password), so, for example https://api.ebay.com/sell/fulfillment/v1/order?limit=10 returns:
{
"errors": [{
"errorId": 1100,
"domain": "ACCESS",
"category": "REQUEST",
"message": "Access denied",
"longMessage": "Insufficient permissions to fulfill the request."
}]
}
Any idea how can I get a token for the user?
Just snippet of code to make things more clear:
AppSettings = {
'app_id': EBAY_PRODUCTION_APPID,
'app_secret': EBAY_PRODUCTION_CERTID,
'dev_id': EBAY_PRODUCTION_DEVID,
'ruName': EBAY_PRODUCTION_RU_NAME
}
authHeaderData = AppSettings['app_id'] + ':' + AppSettings['app_secret']
encodedAuthHeader = base64.b64encode(authHeaderData.encode())
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic ".encode() + encodedAuthHeader
}
body = {
"grant_type": "client_credentials",
"redirect_uri": settings.EBAY_PRODUCTION_RU_NAME,
"scope": "https://api.ebay.com/oauth/api_scope"
}
data = urllib.parse.urlencode(body)
tokenURL = "https://api.ebay.com/identity/v1/oauth2/token"
response = requests.post(tokenURL, headers=headers, data=body)
authDict = response.json()
So the request to run I need is:
r = requests.get("https://api.ebay.com/sell/fulfillment/v1/order?limit=10",
headers={"Authorization": "{}".format(authDict['access_token']),
"Content-Type": "application/json",
"X-EBAY-C-MARKETPLACE-ID": "EBAY_UK",
"Accept": "application/json"
})
According to this, I believe you are supposed to use the following authorization header:
headers['Authorization'] = "Bearer " + USER_ACCESS_TOKEN
Where the USER_ACCESS_TOKEN is the massive token generated on this page.
It looks something like this:
'v^1.1#i^1#p^3#f^0#I^3#r^0#t^ ...
...
...
...
... bfxr8BJtphi2M/oo2xpYo2hiMWxmZt4fVzS7qe2tMXUSAAA='
The Authorization you are using is for requests that aren't linked to a specific user account (search results, meta data for items, etc.). To make requests that are for specific users (eg. orders or inventory updates), you have to get their permission via their USER_ACCESS_TOKEN.
If you need help getting the USER_ACCESS_TOKEN let me know and I'll update.
Note that I have been trying to do the same thing that you are doing for about 6 hours now, and still haven't figured it out, so I am not confident in this answer.
Hope this helps. If you do figure it out, you should post an answer so others can too (ie myself xD).
eBay definitely wins the gold metal for worst api docs in the history of api docs...
The API Explore # developer.ebay.com has description of HTTP Headers for each RestFul API. E.G. Fulfillment API - getOrdres:
HTTP Headers
Authorization:Bearer <OAUTH_token>
Accept:application/json
Content-Type:application/json
Sample code:
import requests,json
headers = {
"Authorization": "Bearer Type_Your_Token_here_or_Paste_IF_too_long",
'Accept':'application/json',
'Content-Type':'application/json'
}
EndPoint = "https://api.ebay.com/sell/fulfillment/v1/order?filter=orderfulfillmentstatus:%7BNOT_STARTED|IN_PROGRESS%7D"
response = requests.get(EndPoint,headers = headers)
https://newbedev.com/ebay-oauth-token-and-refresh-tokens has introduced eBay OAuth token much better than eBay.
By the way, "grant_type": "client_credentials" is only valid for clients who can on have one scope. https://api.ebay.com/oauth/api_scope.
A shortcut to get your code run: the refresh token is actually the token you have for standard API, which is valid for 18 months. With a refresh token, you can get token without getting the annoying "authorization code" via user consent.
In short, please use refresh token to get user access token for the restful API.
Hope the above helps.

How can I make a Post Request on Python with urllib3?

I've been trying to make a request to an API, I have to pass the following body:
{
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
}
Altough the code seems to be right and it finished with "Process finished with exit code 0", it's not working well. I have no idea of what I'm missing but this is my code:
http = urllib3.PoolManager()
http.urlopen('POST', 'http://localhost:8080/assets', headers={'Content-Type':'application/json'},
data={
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
})
By the way, this the first day working with Python so excuse me if I'm not specific enough.
Since you're trying to pass in a JSON request, you'll need to encode the body as JSON and pass it in with the body field.
For your example, you want to do something like:
import json
encoded_body = json.dumps({
"description": "Tenaris",
"ticker": "TS.BA",
"industry": "Metalúrgica",
"currency": "ARS",
})
http = urllib3.PoolManager()
r = http.request('POST', 'http://localhost:8080/assets',
headers={'Content-Type': 'application/json'},
body=encoded_body)
print r.read() # Do something with the response?
Edit: My original answer was wrong. Updated it to encode the JSON. Also, related question: How do I pass raw POST data into urllib3?
I ran into this issue when making a call to Gitlab CI. Since the above did not work for me (gave me some kind of error about not being able to concatenate bytes to a string), and because the arguments I was attempting to pass were nested, I thought I would post what ended up working for me:
API_ENDPOINT = "https://gitlab.com/api/v4/projects/{}/pipeline".format(GITLAB_PROJECT_ID)
API_TOKEN = "SomeToken"
data = {
"ref": ref,
"variables": [
{
"key": "ENVIRONMENT",
"value": some_env
},
{ "key": "S3BUCKET",
"value": some_bucket
},
]
}
req_headers = {
'Content-Type': 'application/json',
'PRIVATE-TOKEN': API_TOKEN,
}
http = urllib3.PoolManager()
encoded_data = json.dumps(data).encode('utf-8')
r = http.request('POST', API_ENDPOINT,
headers=req_headers,
body=encoded_data)
resp_body = r.data.decode('utf-8')
resp_dict = json.loads(r.data.decode('utf-8'))
logger.info('Response Code: {}'.format(r.status))
logger.info('Response Body: {}'.format(resp_body))
if 'message' in resp_body:
logfile_msg = 'Failed Gitlab Response-- {} {message}'.format(r.status, **resp_dict)
I recently became interested in using urllib3, and came across this problem. If you read the urllib3 "User Guide" page, you will see this:
For POST and PUT requests, you need to manually encode query parameters in the URL
Your code should be adjusted to look like this:
import urllib3
from urllib.parse import urlencode
data = {"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"}
http = urllib3.PoolManager()
encoded_data = urlencode(data)
http.request('POST',
'http://localhost:8080/assets?'+encoded_data,
headers={'Content-Type':'application/json'})

post request to change permissions for a file in google drive is failing

Im using python requests library to make google a drive api request to change permissions of a file, in this case the owner.
Here is what my code looks like
fileId = "123abcEfJl-mNooP45Kl6u" #fake file id
url = https://www.googleapis.com/drive/v2/files/%s/permissions' % fileId
payload = {"role":"owner", "type":"user", "value":"<some_user>#gmail.com"}
headers = {'Authorization': 'Bearer %s'%access_token, 'Content-Type':'application/json'}
permResponse = requests.post(url, data=payload, headers=headers)
print permResponse.text
When I run this, I get the following response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
I've been following the google docs api for this and have not been able to figure out what im doing incorrectly.
https://developers.google.com/drive/v2/reference/permissions/insert
Even their Try It! section is broken because there isn't an option to add the required 'value' field.
What am I doing incorrectly? Is anyone else running into these issues?
Thanks
I'm using the urllib.request module, and It works fine. This is my code:
key = "?key=" + MY_API_KEY
url_destino = ("https://www.googleapis.com/drive/v2/files/%s/permissions" % source_id)+ key
values = "{"role":"owner", "type":"user", "value":"<some_user>#gmail.com"}"
data = values.encode('utf-8')
request = urllib.request.Request(url_destino, data, method='POST')
request.add_header("Authorization", "Bearer " + token)
request.add_header("Content-Length", len(data))
request.add_header("Content-Type", "application/json")
print(request.header_items()) # for debugging purpouse
f = urllib.request.urlopen(request)
print(f.read())
I've thought to replace the urllib.request by Requests module (it's more clean to work with) in my little library but, now works.
Because I use Python 3 I can't use the google-api-python-client.

Categories