I was browsing around for 1 day already, but I was not able to find how to fetch CloudFlare API responses in Python.
Usually the communication between the host and the CloudFlare's servers is established using cURL:
curl -k -s "https://api.cloudflare.com/host-gw.html" -d 'act=user_lookup' -d 'host_key=8ayf9yaoh2h8faosh2o8dhas' -d 'cloudflare_email=admin#tech-world.info' | python -mjson.tool
So this is the cURL request, which returns the following dictionary:
{
"msg": null,
"request": {
"act": "user_lookup",
"cloudflare_email": "admin#tech-world.info"
},
"response": {
"cloudflare_email": "admin#tech-world.info",
"hosted_zones": [
"tech-world.info"
],
"unique_id": "78yastaig238w9ayfhao8h28hdas",
"user_api_key": "ga7srgfr2i7dfagsd2r89hasd",
"user_authed": true,
"user_exists": true,
"user_key": "d8ha92hiuhda7892houkljhadskju"
},
"result": "success"
}
So I am trying to execute the cURL command from python in order to get the dictionary output (this is just placeholder cURL execution exapmle):
import subprocess
my_var = subprocess.call(["curl", "-X", "GET", "-I", "http://www.tech-world.com"])
But the call() method prints the data it receives, but I want to assign the dict to variable for later use.
I have checked the urllib2, but I did not find a way to use it to accomplish my goals.
Why do you use cURL instead of normal Python HTTP library (such as Requests)?
r = requests.post('https://api.cloudflare.com/host-gw.html', data={'host_key': '8ayf9yaoh2h8faosh2o8dhas', 'cloudflare_email': 'admin#tech-world.info', 'act': 'user_lookup'})
Also there is a library named pyflare for working with CloudFlare using Python.
(it's the first text that I post for urgent warning)
I can't comment (too low reputation), but I can't to not alert that's you have opened your credentials from production server.
Related
My goal is to automatically pull from a private github repository every time a change is pushed to the master branch, but I'm not sure how I should go about this.
check this docs about github api pulls
example command
curl \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/octocat/hello-world/pulls
if the status is 200 then you will get a json response with metadata:
[
{
"url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
"id": 1,
"node_id": "MDExOlB1bGxSZXF1ZXN0MQ==",
"html_url": "https://github.com/octocat/Hello-World/pull/1347",
"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch",
"issue_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
"commits_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347/commits",
"review_comments_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347/comments",
"review_comment_url": "https://api.github.com/repos/octocat/Hello-World/pulls/comments{/number}",
"comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments",
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/6dcb09b5b57875f334f61aebed695e2e4193db5e",
"number": 1347,
....
i guess from here you need to apply the diffs and the patches manually (using git ofcouse)
"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch",
to apply the patch using git, check this stack-post
to do that in python, you need to use requests library and call git as subprocess command
In the scrapyd docs I couldn't find anyway to override the behavior of how scrapyd sends responses.
So when sending a request to scrapyd:
curl http://localhost:6800/schedule.json -d project=project -d spider=spider
Instead of receiving this:
{"node_name": "local", "status": "ok", "jobid": "7fa5d068969c11e8abbfbc5436cd1f60"}
I want to return when the job finished, and whether or not it was successful, like this:
{"node_name": "local", "status": "(error or finished)", "jobid": "7fa5d068969c11e8abbfbc5436cd1f60"}
Is this possible through a pipeline or something?
I am getting this error only when using the simulator/google assistant. When I use the Slack integration or test within DialogFlow then it works perfectly.
I checked this question about settings in DialogFlow, but that wasn't my issue. I checked this question but because I use python in my webhook, I can't be sure whether that would solve it for me or not.
I am doing the following:
First, the user invokes any one of my intents which are connected through a webhook to my python code. Call this intent1.
Second, I check to see what the response (response1) would be for intent1 in my code.
Third, I send response1 to another intent intent2 via a followup-event event2.
The reason why I'm doing this just for interest is that I'm allowing multiple types of conversation flows. The first being FAQs and the second being a directed conversation.
The JSON I'm sending back is:
"followupEventInput":{
"name":"EventName",
"parameters":{
"speech": str(speech)
}
}
EventName is event2.
speech is response1
I also tried adding this to the JSON, but it didn't change anything:
,"payload": {"google":{"expectUserResponse": False}}
The Debug from the simulator shows:
{
"response": "",
"expectUserResponse": false,
"conversationToken": "GidzaW11bG...",
"audioResponse": "//NExAASWK...",
"debugInfo": {
"assistantToAgentDebug": {
"curlCommand": "curl -v 'https://api.api.ai/api/integrations/google?token=2b0fcc112a9b40c48f7a7182a29f6b2f' -H 'Content-Type: application/json;charset=UTF-8' -H 'Google-Actions-API-Version: 2' -H 'Authorization: eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMjlkYjJlYTE4NjBkMmU4NzFlZTQ4NTA2Mjg3ZmIwNWIwNGNhM2YifQ.eyJhdWQiOiJkbmFmaXQtZmFxIiwiZXhwIjoxNTMwODU5MzIzLCJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJqdGkiOiJiNDcwZjdhODYyYWJiMzI0NjRjNGY5MmU4MTQ1ZWU5NTFlYTA1MWY5IiwiaWF0IjoxNTMwODU5MjAzLCJuYmYiOjE1MzA4NTg5MDN9.XMAmItiH9SEo1I24T5xEPvSfP7dPX21AYHvVqZZReayNoR396ZQ1JdHZiY9rwGfp49qSwn2ea9EDkNVCQ-PK8NIKdTdxG-L0HuhY7r8nEMfzO4PjJKU6bI-Ry1OwL3A90WGK0l8rwJpByHSfA1gTsS7PU983yyR51PCJFkVnd2KQfX1ZKPIqpcEzKkCvexh9mwOx8cH6iVYuBzmHctH1FRLqhzzRb9zcx3Qq2mDFB8cVbl8SluXLyV4hBeKSeFe-HnkWEzqE3zvgIbAZha2rAOMb2xx1ta_M86hmwET4woAB-hBlR77cyNZV49Y5GmFrF5DozvQWEw1GNoRxcZCLhA' -A 'Mozilla/5.0 (compatible; Google-Cloud-Functions/2.1; +http://www.google.com/bot.html)' -X POST -d '{\"user\":{\"userId\":\"ABwppHEpW9IVOkzk8egeV0A0NHO5Ug4wqLj3ney3hdwx_iPW4cMeayYws8m-fzoFiYksk7JsnDmi-g\",\"locale\":\"en-US\",\"lastSeen\":\"2018-07-05T15:54:50Z\"},\"conversation\":{\"conversationId\":\"1530859188209\",\"type\":\"ACTIVE\",\"conversationToken\":\"[]\"},\"inputs\":[{\"intent\":\"actions.intent.TEXT\",\"rawInputs\":[{\"inputType\":\"KEYBOARD\",\"query\":\"what are the best recipes for oranges\"}],\"arguments\":[{\"name\":\"text\",\"rawText\":\"what are the best recipes for oranges\",\"textValue\":\"what are the best recipes for oranges\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.MEDIA_RESPONSE_AUDIO\"},{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]}],\"requestType\":\"SIMULATOR\"}'",
"assistantToAgentJson": "{\"user\":{\"userId\":\"ABwppHEpW9IVOkzk8egeV0A0NHO5Ug4wqLj3ney3hdwx_iPW4cMeayYws8m-fzoFiYksk7JsnDmi-g\",\"locale\":\"en-US\",\"lastSeen\":\"2018-07-05T15:54:50Z\"},\"conversation\":{\"conversationId\":\"1530859188209\",\"type\":\"ACTIVE\",\"conversationToken\":\"[]\"},\"inputs\":[{\"intent\":\"actions.intent.TEXT\",\"rawInputs\":[{\"inputType\":\"KEYBOARD\",\"query\":\"what are the best recipes for oranges\"}],\"arguments\":[{\"name\":\"text\",\"rawText\":\"what are the best recipes for oranges\",\"textValue\":\"what are the best recipes for oranges\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.MEDIA_RESPONSE_AUDIO\"},{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]}],\"requestType\":\"SIMULATOR\"}"
},
"agentToAssistantDebug": {
"agentToAssistantJson": "{\n \"responseMetadata\": {\n \"status\": {\n \"code\": 10,\n \"message\": \"Failed to parse Dialogflow response into AppResponse because of empty speech response\",\n \"details\": [{\n \"#type\": \"type.googleapis.com/google.protobuf.Value\",\n \"value\": \"{\\\"id\\\":\\\"63a2647e-43fc-4c36-9067-5c48b51626bb\\\",\\\"timestamp\\\":\\\"2018-07-06T06:40:04.014Z\\\",\\\"lang\\\":\\\"en-us\\\",\\\"result\\\":{},\\\"status\\\":{\\\"code\\\":200,\\\"errorType\\\":\\\"success\\\"},\\\"sessionId\\\":\\\"1530859188209\\\"}\"\n }]\n }\n }\n}"
},
"sharedDebugInfoList": [
{
"name": "ResponseValidation",
"debugInfo": "",
"subDebugEntryList": [
{
"name": "MalformedResponse",
"debugInfo": "'final_response' must be set.",
"subDebugEntryList": []
}
]
}
]
},
"visualResponse": {
"visualElementsList": [],
"suggestionsList": [],
"agentLogoUrl": ""
},
"clientError": 0,
"is3pResponse": 1
}
The value of the agentToAssistantJson field includes the message "Failed to parse Dialogflow response into AppResponse because of empty speech response". As it suggests, whatever you're sending in your response is missing speech information.
You don't specify what Event2 is doing, what it is sending back, or what it is doing with the parameter (if anything), but the likely issue is that it isn't sending back anything. Just including the speech as a parameter doesn't do anything - parameters are just information, not replies.
While there are some uses for followup events, most of the time they aren't what you really want. If you want to reply with a message from the fulfillment - just reply with the message.
I'm trying to use Google's API for geolocation giving wifi data to determine location. This is their intro. And this is my code
#author: Keith
"""
import requests
payload = {
"considerIp": "false",
"wifiAccessPoints": [
{
"macAddress": "00:25:9c:cf:1c:ac",
"signalStrength": -43,
"signalToNoiseRatio": 0
},
{
"macAddress": "00:25:9c:cf:1c:ad",
"signalStrength": -55,
"signalToNoiseRatio": 0
}
],
'key':'<MyAPIKey>'
}
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate',
params=payload)
print(r.text)
This is the output
{
"location": {
"lat": 32.3643098,
"lng": -88.703656
},
"accuracy": 6061.0
}
The request ignored all of the payload except the key portion and just found the geolocation using my IP address. So I'm sending the json payload incorrectly. I know this is probably really simple, but I'm stuck and couldn't find an example of python being used with requests to do this type of API query. Thanks
Edit:
Picked up the cURL library and executed this command with success:
curl -d #your_filename.json -H "Content-Type: application/json" -i "https://www.googleapis.com/geolocation/v1/geolocate?key=<myapikey>"
and got the output I expected. I just want to be able to do the same thing in requests, but the data I'm trying to send is in "your_filename.json".
Please try the following:
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate?key='+ '<MyAPIKey>', json=payload)
Note the key was moved to query params (URL) and json argument was used in place of params.
Okay I figured out the error of my ways. Taking a better look at requests.post function, I see that I'm not using the parameters argument correctly. After this, it worked perfectly,
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate', params=parameters, json=mydata, headers=headers)
I'm following this to restart Ambari components that are in INSTALLED state, for this i have written a python code parse the Ambari services using Pycurl that works.
But once the JSON is parsed i will be generating a JSON file like:
{
"RequestInfo": {
"command": "START",
"context": "Restart all components on HOST"
},
"Requests/resource_filters": [
{
"component_name": "NAMENODE",
"hosts": "hadoopm",
"service_name": "HDFS"
},
{
"component_name": "RESOURCEMANAGER",
"hosts": "hadoopm",
"service_name": "YARN"
}]}
this works with:
curl -u username:password -H 'X-Requested-By-ambari' http://ambariserver:8080/api/v1/clusters/CLUSTERNAME/requests -d#service-restart.json
but the same is not working and failing with 400 Bad request error with the below code:
import pycurl
c = pycurl.Curl()
c.setopt(pycurl.URL, url_post)
c.setopt(pycurl.HTTPHEADER, ["X-Requested-By:ambari"])
data = json.dumps(json.loads(open(output_temp_file,'rb').read()), indent=1, sort_keys=True)
tabs = re.sub('\n +', lambda match: '\n' + '\t' * (len(match.group().strip('\n')) / 2), data)
tabJSON=json.dumps(json.loads(open(output_temp_file,'rb').read()), indent=1, sort_keys=True)
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.USERPWD,'admin:'+admin_pass)
c.setopt(pycurl.POSTFIELDS, 'tabJSON')
c.setopt(pycurl.WRITEFUNCTION, service_buffer.write)
c.setopt(pycurl.VERBOSE, 1)
c.perform()
c.close()
and failing with HTTP/1.1 400 Bad Request
is there something wrong that i'm doing with this can someone please help me with this.
Probably API call format is outdated in documentation. I'd suggest going by example:
open dev console in Chrome
use Ambari UI to perform an action (e.g. restart all services)
go to Network, find relevant POST/PUT request (sort by non-200 Status column)
copy request (right click on request -> Copy -> copy as cURL )
Now you have up-to-date CURL command example, and can go further playing around request body