0

trying to do a PUT using curl and python subprocess, however, I am unable to set the content type for my request.


import subprocess

item = '{"title": "Copy", "id": "1mglMSA_wU", "type": "document", "parentId": "1WtlhD7a", "modifiedTime": "2019-01-16T21:33:36.631Z", "createdTime": "2019-01-16T21:29:26.327Z", "shared": "True"}'
cmd = f'curl -H "Content-Type: application/json" -X  PUT localhost:9200/ax/_doc/1?pretty  -d\'{item}\''

res = subprocess.Popen(f'ssh {user}@{host} {cmd}', shell=True,
                       stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
print(res)

I keep getting the following error:

{
  "error" : "Content-Type header [] is not supported",
  "status" : 406
}
tripleee
  • 175,061
  • 34
  • 275
  • 318
glls
  • 2,325
  • 1
  • 22
  • 39

1 Answers1

1

The remote ssh command invokes another shell, so you need to escape strings twice, or - much better - get rid of one shell if you can.

Also, you are reinventing subprocess.run(), with several bugs.

import subprocess

item = '{"title": "Copy", "id": "1mglMSA_wU", "type": "document", "parentId": "1WtlhD7a", "modifiedTime": "2019-01-16T21:33:36.631Z", "createdTime": "2019-01-16T21:29:26.327Z", "shared": "True"}'

res = subprocess.run(
    ['ssh', f'{user}@{host}',
     'curl', '-H', 'Content-Type: application/json',
             '-X', 'PUT', 'localhost:9200/ax/_doc/1?pretty', '-d', item],
    capture_output=True, text=True, check=True)  # no shell=True
print(res.stdout)

I can see no particular reason to put the command in a separate variable, though if you like, you can of course put it in a list and then interpolate the things you need into the list before you pass it to subprocess.run().

Perhaps see also Actual meaning of 'shell=True' in subprocess

The immediate problem is that you were passing simply -H Content-Type: because one layer of quotes was getting peeled off.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • `subprocess.run()` was introduced in Python 3.5. `capture_output` and the alias `text` for what was previously only called `universal_newlines` was introduced in 3.7. Perhaps see https://stackoverflow.com/questions/4256107/running-bash-commands-in-python/51950538#51950538 if you need compatibility with earlier versions. – tripleee Nov 10 '20 at 06:16