0

I'm trying to make a request, in python, from a VM running Ryu controller to a VM running a openvswitch. I've tested said request, and it works when I execute it in a terminal (a string is supposed to be returned):

curl -X POST -d '{"priority": 500, "match": {"in_port": 3}}' http://localhost:8080/stats/flow/8796748823560

This was my first try in python:

import subprocess

proc = subprocess.run(['curl', '-X', 'POST', '-d', '\'{"priority": 500, "match": { "in_port": 3} }\'','http://localhost:8080/stats/flow/8796748823560'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

response = proc.stdout.decode('utf-8')

A simple POST, as you can see. However, the response is always " ", showing the error:

curl: (3) URL using bad/illegal format or missing URL

Then, I decided to use the requests python library and wrote the POST the following way:

import requests

data = '{ "priority": 500, "match": {"in_port": 3}}'

response = requests.post('http://localhost:8080/stats/flow/234', data=data)

However, I don't know where to put the option -X. In the library documentation, I cannot find the right place to put it, if there is any.

I need help to understand where I should place that -X option in the code and, if it is not possible, how could I execute that curl on python (I was trying to avoid the shell=True flag on subprocess, as I don't think it is safe).

imll
  • 321
  • 3
  • 13
  • 1
    `-X POST` instructs curl to make a POST request. You're already doing that in your last approach by using `requests.post()`. – snwflk Jan 02 '20 at 00:21
  • 1
    Does this answer your question? [Post JSON using Python Requests](https://stackoverflow.com/questions/9733638/post-json-using-python-requests) – snwflk Jan 02 '20 at 00:21
  • 1
    You don't need the single quotes in your first attempt to use `subprocess`: subprocess.run(['curl', '-X', 'POST', '-d', '{"priority": 500, "match": { "in_port": 3} }', 'http://localhost:8080/stats/flow/8796748823560'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)`. They were part of the shell syntax for specifying the JSON as a single argument, not part of the JSON itself. – chepner Jan 02 '20 at 00:24
  • Well, I though the -X option was the problem here... Because I keep getting **** as the result of the above curl (using requests library)... Now I understand how that option is not needed in the code. However, how could it be that a curl executed in the terminal returns the string I want but not in the python3 code? @snwflk although it helps me understand more about the library, I tested the answer and it still returns response 400... – imll Jan 02 '20 at 00:32
  • 1
    you can uses url https://httpbin.org/post with curl and python code and it will send back all data which it get. And then you can compare both to see differences. One of differences can be `User-Agent` header because Python sends `Python/something` and some servers automatically block it. – furas Jan 02 '20 at 00:36
  • 1
    why do you use `"in_port": in_port` instead of `"in_port": 3` ? It can makes problem. – furas Jan 02 '20 at 00:37
  • @furas Sorry, it was a small typo. I changed it now to '3'. I didn't know the https://httpbin.org/post website and I found out that I could get the user-agent with https://httpbin.davecheney.com/user-agent , and so I added the right user-agent to the code. It works now, I appreciate the help! – imll Jan 02 '20 at 00:50
  • 1
    it seems https://httpbin.davecheney.com is old version of https://httpbin.org - it even uses url `http://httpbin.org` in examples. There is also https://httpbin.org/user-agent Many pages works even if you uses incomplet User-Agent like `Mozilla/5.0` – furas Jan 02 '20 at 01:03

1 Answers1

1

The -X/--request in curl is an option that is followed by the HTTP verb to be used in the request. Since this is followed by POST it means that a POST request should be used. In fact -X POST is not needed since the mere presence of -d should cause curl to make a HTTP POST request.

Thus, use of request.post with data containing the body should be sufficient.