0

Self admitted PHP coder turning to the Python side and my head hurts. I'm trying to do what I think would be simple. Read in a file (have that working) and then store each lines input into a variable then evaluate the string variable into an existing string of text.

Here's what I have:

with open('./users.txt') as users:
    for user in users:
        conn.request("GET", "/vmrest/users?query=(alias%2520is%2520{})".format(user), headers)
        res = conn.getresponse()
        data = res.read()

All I want is the value in my user variable to be placed right at the end of the string right after "/vmrest/users?query=(alias%2520is%2520user variable here", headers)

Thanks

EDIT Realized I didn't include what was happening sorry. Below is the feedback I get when executing.

Traceback (most recent call last):
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/http/client.py", line 885, in send
 self.sock.sendall(data)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/ssl.py", line 886, in sendall
v = self.send(data[count:])
TypeError: unhashable type: 'slice'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "amer-unity.py", line 12, in <module>
conn.request("GET", "/vmrest/users?query=(alias%2520is%2520{})".format(user), headers)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/http/client.py", line 1083, in request
self._send_request(method, url, body, headers)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/http/client.py", line 1128, in _send_request
self.endheaders(body)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/http/client.py", line 1079, in endheaders
self._send_output(message_body)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/http/client.py", line 913, in _send_output
self.send(message_body)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/http/client.py", line 889, in send
self.sock.sendall(d)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/ssl.py", line 886, in sendall
v = self.send(data[count:])
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/ssl.py", line 856, in send
return self._sslobj.write(data)
File "/opt/rh/rh-python35/root/usr/lib64/python3.5/ssl.py", line 581, in write
return self._sslobj.write(data)
TypeError: a bytes-like object is required, not 'str'
8
  • 3
    And your problem is ? Commented Jun 22, 2016 at 15:39
  • 1
    Your desired behavior is pretty clear, but I don't see any reason why your code shouldn't be working. What's the current behavior? (Side note: consider requests for sending web requests. It's much better than the Python standard lib.) Commented Jun 22, 2016 at 15:40
  • 1
    try printing out the formatted string and see what you get. it should be working. you'll also probably want to strip any surrounding whitespace from user (user.strip()) Commented Jun 22, 2016 at 15:49
  • So trying your request to just print the line: >>> with open('./users.txt') as users: ... for user in users: ... print("GET", "/vmrest/users?query=(alias%2520is%2520{})".format(user), headers) ... Traceback (most recent call last): File "<stdin>", line 3, in <module> NameError: name 'headers' is not defined >>> Commented Jun 22, 2016 at 15:59
  • It looks like the basic problem is that the request method is expecting a bytes instead of str, but that's a big guess on my part. A str is a text value, and unlike in Python 2.x, it can't be used as a byte sequence. I really recommend switching to requests and seeing if it just works; my suspicion is that it will sort of magically eliminate these kinds of problems. Commented Jun 22, 2016 at 15:59

1 Answer 1

1

First, as @acushner suggests, you should strip your line:

"/vmrest/users?query=(alias%2520is%2520{})".format(user.strip())

This will remove any leading or trailing whitespace from the user string. Keep in mind that in Python, when you read a file's lines, it includes the line terminator (probably '\n' since you're on *nix). This will make sure it gets removed.

You might also want to skip empty lines:

user = user.strip()
if user:
    conn.request("GET", "/vmrest/users?query=(alias%2520is%2520{})".format(user), headers)
    # ...

If that doesn't fix it, I highly recommend switching to requests. It's a simpler library for sending web requests and receiving responses. It generally "just works" without much fuss. It's third party, so you need to install it first:

pip install requests

Then you would use it like this:

import requests

# ... some other code ...

with open('./users.txt') as users:
    for user in users:
        user = user.strip()
        if user:
            res = requests.get("/vmrest/users?query=(alias%2520is%2520{})".format(user.strip()), headers=headers)
            data = res.text

Note that there is zero set up code for establishing a connection; you just call the module method. It has some additional niceties as well, like parsing JSON:

data = res.json()
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you this is now working and I can move on to my next challenges. You're definitely right requests is far superior to the basic http module. Not sure why Cisco uses that as their reference.
@rsaturns requests has gotten a lot of traction in the Python community, but there's probably still a lot of people who don't know about it. Cisco could also have written their docs before it existed, or they might be uncomfortable with telling people to install a third party library in their official docs. Lots of possible reasons. Glad I could help, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.