how to post a curl command using python

5k views Asked by At

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

3

There are 3 answers

1
Sayuri Mizuguchi On BEST ANSWER

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.
5
Simon O'Doherty On

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)
0
Ous_mania On

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)