how to post a curl command using python - python-3.x

I need help with this.. Basically i need to use this command. This is the example given using CURL. All i need to do is simply paste this in cmd and it does its job.
curl \
-H "Content-Type: application/json" -X POST \
-u "{username}":"{password}" \
-d "{\"dialog_node\":\"greeting\",\"conditions\":\"#hello\",\"output\":{\"text\":\"Hi! How can I help you?\"},\"title\":\"greeting\"}" "https://gateway-s.watsonplatform.net/conversation/api/v1/workspaces/bec28d8f-18c1-4e97-8d08-9c842c658b51/dialog_nodes?version=2017-05-26"
The URL documentation can be found here:
https://www.ibm.com/watson/developercloud/conversation/api/v1/?curl#create_dialognode
The problem now is that i want to run this in a python script instead of in CMD.. i have searched google and stackOverflow for a few hours now.. but i cant seem to find the right answer..
So far i seen ppl using
1.requests
2.urllib
3.urllib2
4.pycurl
5.subprocess
I want to do it the right way. What is the best way to run the above command in a python script and how do i do it?
Also i am using python 3

Likes Simon O'Doherty said, you can use the Python SDK for using Conversation service. It is really the best practice to use the service, using the SDK or http requests.
"If something's worth doing, it's worth doing right, right?". So what
you're asking is "how do I run this other program, from within my
program, just to make a measly little web request?".
You can use cURL command, yes, you can. But it hardly looks very
Pythonic. That's a lot of work just for one little request. Python's
is more than it.
Author from the phrases here.
But, your question looks like you really want to use the cURL command inside your Python code, so, here is one example. In this case, you can use subprocess.
Call the Converstation:
import subprocess
subprocess.call(['curl', '-x', 'POST', '-H', '"Accept: application/json"', '-u', '{"userNameFromServiceCredentials:PasswordFromServiceCredentials" }', '"https://gateway-s.watsonplatform.net/conversation/api/v1/workspaces/bec28d8f-18c1-4e97-8d08-9c842c658b51/dialog_nodes?version=2017-05-26"'])
Important: For send the message and getting the output, you need to use the function subprocess.check_output(); like this example. And send the message for the right router, your cURL command needs to looks like this example from #German Atannasio and #Pridkkett.
Note: This answer is just to tell what is the better way to you follow, and if you really wants to use, one "Stone path" for you follow.
API Reference for using Watson Conversation Service with Python.
Requests documentation here.

If you are using Watson Conversation, then you can just use the Python WDC SDK.
https://github.com/watson-developer-cloud/python-sdk
For your example above it would be:
from watson_developer_cloud import ConversationV1
username = 'USERNAME',
password = 'PASSWORD',
version = '2017-05-26',
workspace_id = 'bec28d8f-18c1-4e97-8d08-9c842c658b51'
url = 'https://gateway-s.watsonplatform.net/conversation/api'
conversation = ConversationV1(
username=username
password=password,
version=version,
url=url
}
dialog_nodes = []
welcome_node = {
'output': {
'text': { 'values': [ 'Welcome!' ],
'selection_policy': 'sequential'
}
},
'parent': None,
'context': None,
'metadata': None,
'next_step': None,
'conditions': 'welcome',
'dialog_node': 'Welcome',
'previous_sibling': None
}
dialog_nodes.append(welcome_node)
# this appends to the previous node above, set by previous_sibling
node = {
'dialog_node': 'greeting',
'conditions': '#hello',
'context': None,
'metadata': None,
'next_step': None,
'output':{
'text': { 'values': [ 'Hi! How can I help you?' ]},
'selection_policy': 'sequential'
}
},
'title': 'greeting ',
'previous_sibling': 'Welcome',
'parent': None
}
dialog_nodes.append(node)
## Update the workspace.
response = conversation.update_workspace(
workspace_id=workspace_id,
dialog_nodes=dialog_nodes
)
print(response)
This call is an all or nothing, so if you have existing nodes it will delete them. The reason being is the SDK doesn't have the individual node editing. But this is a faster way to do it, rather then editing a single node (if you have more then one node).
If you want to make the individual call, then you will need to use something like requests, until the SDK is updated.
Example (using same variables from above):
import requests
from requests.auth import HTTPBasicAuth
endpoint = '{}/v1/workspaces/{}/dialog_nodes?version={}'.format(url,workspace_id,version)
basic_auth = HTTPBasicAuth(username, password)
# Change the condition to always execute.
node['conditions'] = 'true'
response = requests.post(url=endpoint, auth=basic_auth, json=node)

In python3 when sending files with pycurl, I want to understand why do I have to send the binary file directly
instead of providing its path
IBM Watson
#coding:utf-8
import certifi
import pycurl
import io
response = io.BytesIO()
c = pycurl.Curl()
#"apikey" is a key word
user = "apikey"
pwd = "YouRaPiKey"
#the file you want to submit
with open("path_to_file/audio-file.flac","rb") as f:
audiofile = f.read()
c.setopt(c.URL, "https://api. .... /.... /.. /v1/recognize")
c.setopt(pycurl.USERPWD, "{}:{}".format(user, pwd))
c.setopt(c.WRITEFUNCTION, response.write)
c.setopt(c.HTTPHEADER, ['Content-Type: audio/flac','Transfer-Encoding: chunked'])
c.setopt(c.POSTFIELDS, audiofile)
c.setopt(c.CAINFO,certifi.where())
c.perform()
c.close()
body = response.getvalue()
body = body.decode('iso-8859-1')
print(body)

Related

How to send a whatsapp message from python

I am trying to create a program which on certain conditions will send whatsapp message as notification. I want to perform this task without any third-party registration. Is there a way I can perform this using any python module or framework ?
Create a new file called "wasend.py" and write the following code on it:
import webbrowser
import pyautogui
from time import sleep
def send(text, phone):
webbrowser.open("whatsapp://send?text=" + text.replace('\n', '%0A') + "&phone=" + phone.replace('+', ''))
sleep(10)
pyautogui.click(x=1787, y=978)
sleep(0.2)
pyautogui.hotkey('enter')
sleep(1)
pyautogui.hotkey('alt', "f4")
Then, execute the following commands:
$ pip install pyautogui
$ pip install webbrowser
Create another file called "send.py". On it, write the following code:
import wasend
wasend.send("message", "phone")
I built this program. These are the params of the wasend.send() function:
wasend.send(message, number)
> message
The message in plain text. (Use * for bold, _ for italic, and plain Whatsapp formatting)
Write "\n" to make a line break.
> number
The phone number in the format: IIINNNNNNNNN (i = indicative, n = number, without the plus sign)
The program takes 11.5 seconds to execute (you can change the sleep to make it fast, but give some time to WhatsApp to load. If you already have WhatsApp loaded, change line 7 in wasend.py to sleep(1), so the program takes only 2.5 seconds to load.
You could do it in the following way, I hope it helps.
import requests
import json
PHONE_ID = "<whatsapp-phone-id>"
TOKEN = "<whatsapp-token>"
NUMBER = "<number>"
MESSAGE = "<message>"
URL = "https://graph.facebook.com/v13.0/"+PHONE_ID+"/messages"
headers = {
"Authorization": "Bearer "+TOKEN,
"Content-Type": "application/json"
}
data = {
"messaging_product": "whatsapp",
"to": NUMBER,
"type": "text",
"text": json.dumps({ "preview_url": False, "body": MESSAGE})
}
response = requests.post(URL, headers=headers, data=data)
response_json = response.json()
print(response_json)
You can find more details in the following source https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#text-object

Using Django to create Strava Webhook subscription

I am trying to create a Strava webhook subscription to recieve events from users who have authorised my Strava application. I was able to successfully create a subscription using the code in this Strava tutorial. However, I don't understand Javascript, so can't adapt the code to my needs. I am therefore trying to replicate it's functionality within Python using Django.
My basic approach has been to follow the setup outlined in the Django section of this webpage, then replace the code in the file views.py with the code below. I have tried to make the code function as similarly as possible to the Javascript function within the tutorial I linked above. However, I'm very new to web applications, so have taken shortcuts / 'gone with what works without understang why' in several places.
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.clickjacking import xframe_options_exempt
import json
#csrf_exempt
#xframe_options_exempt
def example(request):
if request.method == "GET":
verify_token = "STRAVA"
str_request = str(request)
try:
mode = str_request[str_request.find("hub.mode=") + 9 : len(str_request) - 2]
token = str_request[str_request.find("hub.verify_token=") + 17 : str_request.find("&hub.challenge")]
challenge = str_request[str_request.find("hub.challenge=") + 14 : str_request.find("&hub.mode")]
except:
return HttpResponse('Could not verify. Mode, token or challenge not valid.')
if (mode == 'subscribe' and token == verify_token):
resp = json.dumps({"hub.challenge":challenge},separators=(',', ':'))
return HttpResponse(resp, content_type='application/json; charset=utf-8')
else:
return HttpResponse('Could not verify mode or token.')
The Strava documentation says that the callback url must respond to a GET request within 2 seconds with a status of 200 and an echo of the hub.challenge json string. This function seems to do that. Yet when I try to create a POST request equivalent to the one below:
$ curl -X POST https://www.strava.com/api/v3/push_subscriptions \
-F client_id=[MY-CLIENT-ID] \
-F client_secret=[MY-CLIENT-SECRET] \
-F 'callback_url=http://[MY-IP-ADDRESS]:8000/webhooks/example/' \
-F 'verify_token=STRAVA'
I get the following response:
{
"message": "Bad Request",
"errors": [
{
"resource": "PushSubscription",
"field": "callback url",
"code": "not verifiable"
}
]
}
Does anyone have any idea what might be going wrong?
P.S. Please let me know if there's anything I can do to make this example more reproducible. I don't really understand this area well enough to know whether I'm leaving out some crucial info!

Converting a CURL into python script

I am trying to convert a Curl POST request into a python script, and i am not getting the desired output, please let me know what i am doing wrong here.
CURL request
curl -s -w '%{time_starttransfer}\n' --request POST \
--url http://localhost:81/kris/execute \
--header 'content-type: application/json' \
--data '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
This runs the uptime command in the node for which the ip is provided and returns a JSON output:
{"command":"uptime","output":["{\"body\":\" 17:30:06 up 60 days, 11:23, 1 user, load average: 0.00, 0.01, 0.05\\n\",\"host\":\"10.0.0.1\"}"]}0.668894
When i try to run the same with python, it fails and never gets the output
Code :
import urllib3
import json
http = urllib3.PoolManager()
payload = '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
encoded_data = json.dumps(payload)
resp = http.request(
'POST',
'http://localhost:81/kris/execute ',
body=encoded_data,
headers={'Content-Type': 'application/json'})
print(resp)
I would recommend you use the requests library. It's higher level than urllib and simpler to use. (For a list of reasons why it's awesome, see this answer.)
Plus it requires only minor changes to your code to work:
import requests
payload = '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
resp = requests.post(
'http://localhost:81/kris/execute',
data=payload,
headers={'Content-Type': 'application/json'})
print(resp.text)
Note that the method POST is the function instead of a parameter and that is uses the named param data instead of body. It also returns a Response object, so you have to access its text property to get the actual response content.
Also, you don't need to json.dumps your string. That function is used to convert Python objects to JSON strings. The string you're using is already valid JSON, so you should just send that directly.
Here is an online utility you can check out to convert curl requests to python code.
Curl to python converter
Another alternative is Postman application. There you will have the option to convert curls to code for various languages, in the code section.
It a very good practice to check if the api requests are working by running the curl in postman.
And for your case, here is the code using python requests library.
import requests
headers = {
'content-type': 'application/json',
}
data = '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
response = requests.post('http://localhost:81/kris/execute', headers=headers, data=data)
Hope that helps! Happy Coding!

How to implement the Microsoft Speaker Recognition / Verification API in Python?

I would like to implement the Speaker Recognition API from Microsoft's Cognitive Services for a Speaker Verification project. I already have a Speaker Recognition API key. I got the sample Python code directly from the documentation (on the bottom of the documentation):
https://westus.dev.cognitive.microsoft.com/docs/services/563309b6778daf02acc0a508/operations/563309b7778daf06340c9652
########### Python 3.2 #############
import http.client, urllib.request, urllib.parse, urllib.error, base64
headers = {
# Request headers
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': '{subscription key}',
}
params = urllib.parse.urlencode({
})
try:
conn = http.client.HTTPSConnection('westus.api.cognitive.microsoft.com')
conn.request("POST", "/spid/v1.0/verificationProfiles?%s" % params, "{body}", headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
####################################
This is the code sample for the first step, create and save a voice profile.
To conduct Speaker Verification, we need to do 3 steps:
1) Create Profile
2) Create Enrollment
3) Verification
I'm stuck already at the first step now. This is my first time working with APIs in general, so I'm not really sure what parts of the Python code I have to change. I know that I need do insert my API key in 'Ocp-Apim-Subscription-Key' but other than that, what else? For example, if I add my API key in that specific field and let the code run, I received this error message.
b'{"error":{"code":"BadRequest","message":"locale is not specified"}}'
Where do I need to insert the locale ("en-us") for example? It is not really clear to me from the documentation what I need to edit. If you can guide me what I need to insert/add in my API calls I would be very thankful.
Thanks so much in advance!
When you create a Speaker Recognition profile, it has to be linked with a locale, and you specify this locale in the request body. The body should be a JSON object like the following one:
{
"locale":"en-us",
}
For the sample to work, you need to replace "{body}" with the actual body value like this:
conn.request("POST", "/spid/v1.0/verificationProfiles?%s" % params, "{\"locale\":\"en-US\"}", headers)

Fail to retrieve response message in Eclipse Ditto

I am trying to create an example in which a client issues a message to a thing and the thing replies back to the client. The thing is connected to Eclipse Ditto via a MQTT connection and the client is simulated via a curl command. In order to do so, I took some parts from the following two tutorials: https://www.eclipse.org/ditto/2018-12-05-example-command-and-control.html and https://github.com/eclipse/ditto-examples/tree/master/mqtt-bidirectional.
Besides the fact that Ditto does not route the messages from the client to the thing in a very reliable way (I would say that one out of three messages is not delivered to the client), the client is not able to receive the response message from the thing, even with a very high timeout value.
This is my Python code that acts as the thing:
import logging
import time
import random
import json
import paho.mqtt.client as mqtt
def on_message(client, userdata, message):
response = json.dumps({
"topic": "org.eclipse.ditto/teapot/things/live/messages/brew",
"headers": {
"content-type": "application/json",
"correlation-id": "command-and-control"
},
"path": "/inbox/messages/brew",
"value": {
"eta": 58
},
"status": 200
})
client.publish(outTopic, response)
inTopic = "ditto-tutorial/org.eclipse.ditto:teapot/#";
outTopic = "ditto-tutorial/";
thingId = "teapot";
interval = 10
broker_address = "test.mosquitto.org"
client = mqtt.Client(thingId) #create new instance
client.on_message = on_message #attach function to callback
client.connect(broker_address) #connect to broker
client.loop_start() #start the loop
client.subscribe(inTopic)
while True:
time.sleep(interval)
This is my curl command that simulates the client:
curl -i -X POST 'http://localhost:8080/api/2/things/org.eclipse.ditto:teapot/inbox/messages/brew?timeout=60' \
-u ditto:ditto \
-H 'x-correlation-id: command-and-control' \
-d '{"targetTemperature":85}'
At the beginning I thought that I was doing something wrong with the Ditto protocol, but I believe this is not the case, since the correlation-id is the same in both request and responde and the other fields seem to be OK.
I think the problem might be that you are using a fixed correlation-id for your commands and responses. Try to use a random, e.g. a UUID.

Resources