I have a python script that I cobbled together that checks my gmail via the rss feed and outputs the text to the screen. It worked on python 2.6.6 but I've been unsuccessful to get it working under python 3.2.3.
I've used 2to3 to convert it. The code is here:https://www.dropbox.com/s/b1277mi7vc7hv3f/gmailcheckparseconky.py3
The problem occurs in the ObtainEmailFeed function.
I get the dreaded "TypeError("expected bytes, not %s" % s.__class__.__name__)" error when I use
b64auth = base64.encodestring("%s:%s" % (user, password))
however when I use
string = bytes("%s:%s" % (user,password), 'utf-8')
string2=str(string,'utf-8')
b64auth = base64.encodestring( string)
I get
auth = "Basic " + b64auth
TypeError: Can't convert 'bytes' object to str implicitly
which seems to bring the whole problem back full circle.
I've tried hard coding in my password as text and that doesn't work. I get an
urllib.error.HTTPError: HTTP Error 401: Unauthorized when I set `auth = "Basic user:password"
As I said I cobbled the code together. I don't fully understand what gmail needs for me to authorize. Continuing along with that vein, I'd prefer help in fixing this code so I can learn and get a better understanding of python instead of pointing me to another script on the web that does the same/similar thing as to what I'm doing.
Thanks in advance,
Nick
Since python3 there is a distinction between bytes and strings. The error comes from the fact that base64.encodestring is now a deprecated alias for encodebytes (see also: http://docs.python.org/py3k/library/base64.html#module-base64), and so it wants you to give bytes, and it will give you bytes back.
You might want to do:
string = bytes("%s:%s" % (user,password), 'utf-8')
b64bytes = base64.encodebytes(string)
b64auth = b64bytes.decode('ascii')
Then b64auth will be a string and you will be able to use it as string in rest of the code.
Related
i am working on a generating questions from a given text, while encoding and unicoding the text format i facing an issue. please can any help me out.
ww2 = u'''
World War II (often abbreviated to WWII or WW2), also known as the Second World War, was a global war that lasted from 1939 to 1945, although related
'''
ww2 = unicode(ww2, 'utf-8')
ww2b = TextBlob(ww2)
Whenever you are encoding a string it will be of type which you cant put into TextBlob() directly. If you are using the encoded value in between before TextBlob() call then you need to decode it first. Also the whole point of BLOB is that they store raw binary strings. So just go ahead and store your stuff directly into your BLOB without encoding them.
I'm getting in Python 3 the data from an HTML form. To simplify to the maximum, my Python code looks like this:
#!/usr/bin/python3
import cgi
form = cgi.FieldStorage()
print('Content-type: text/html; charset=utf-8\n')
data = form.getvalue('nom')
print(data)
Now it prints (like it's supposed to) the name filled in the HTML form, however when that name has an accent (for example Valérie), then the accented character is printed as a ? (in this case Python prints Val?rie).
I know it's a problem of encoding (Python being notorious for this), and I've searched quite a bit (encode, decode, locale, etc...) but didn't get it to work unfortunately. If anyone knows how to fix this and have it print Valérie, I'd really appreciate it ;-)
EDIT: got it to work using print(data.encode('utf-8').decode('latin-1'))
Take care.
I know that my authentication is working and I can make tweets just fine. I have no reason to believe that the tweepy library is causing this problem, though I suppose I have no reason to rule it out. My code looks something like this, attempting to tweet an emoji flag. No other emoji is working either.
auth = tweepy.OAuthHandler(keys.twitter['consumer_key'], keys.twitter['consumer_secret'])
auth.set_access_token(keys.twitter['access_token'], keys.twitter['access_token_secret'])
api = tweepy.API(auth)
print('Connected to the Twitter API...')
api.update_status(r'testing \U0001F1EB\U0001F1F7')
I get an error code 400 with seemingly no additional info about what the reason is. Trying to determine if the problem is the encoding in the string is somehow wrong, or if it is simply some sort of problem with sending it to Twitter's API.
You have unicode in your string. Because you are using Python 2 use:
api.update_status(u"testing \U0001F1EB\U0001F1F7")
Notice that I changed r"x" to u"x".
If you are using Python 3, you can just use:
api.update_status("testing \U0001F1EB\U0001F1F7")
Update: This is the tweet that I sent using this code:
https://twitter.com/twistedhardware/status/686527722634383360
I'm using a free web host but choosing not to work with any Python framework, and am stuck trying to print Chinese characters saved in the source file (using emacs to save file encoded in utf-8) to the resulting HTML page. I thought Unicode "just works" in Python 3.1 so I am baffled. I found three solutions that aren't working. I might just be missing a detail or two.
The host is Alwaysdata, and it has been straightforward to use, so I have little clue about details of how they put together the parts. All I do is upload or edit (with ssh) Python files to a www folder, change permissions, point a browser to the right URL, and it works.
My first attempt, which works on local IDLE (and also the server's Python command line interactive shell, which makes me even more confused why it won't work when it's passed to a browser)
#!/usr/bin/python3.1
mystr = "世界好"
print("Content-Type: text/html\n\n")
print("""<!DOCTYPE html>
<html><head><meta charset="utf-8"></head>
<body>""")
print(mystr)
The error is:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3:
ordinal not in range(128)
Then I tried
print(mystr.encode("utf-8"))
resulting in no error, but the following undesired output to the browser:
b'\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'
Third, the following lines were added but got an error:
import sys
sys.setdefaultencoding("utf-8")
AttributeError: 'module' object has no attribute 'setdefaultencoding'
Finally, replacing print with f.write:
import codecs
f = codecs.open(sys.stdout, "w", "utf-8")
mystr = "你好世界"
...
f.write(mystr)
error:
TypeError: invalid file: <_io.TextIOWrapper name='<stdout>'
encoding='ANSI_X3.4-1968'>
How do I get the output to work? Do I need to use a framework for a quick fix?
It sounds like you are using CGI, which is a stupid API as it's using stdout, made for output to humans, to output to your browser. This is the basic source of your problems.
You need to encode it in UTF-8, and then write to sys.stdout.buffer instead of sys.stdout.
And after that, get yourself a webframework. Really, you'll be a lot happier.
I just updated from python 3.1 to python 3.2 (formatted HD) and one of my scripts stopped working. It gives me the error in the title.
I would fix it myself but I don't even know what an iterable of bytes is lol. I tried typecasting bytes(data) but that didn't work either. TypeError: string argument without an encoding
url = "http://example.com/index.php?app=core&module=global§ion=login&do=process"
values = {"username" : USERNAME,
"password" : PASSWORD}
data = urllib.parse.urlencode(values)
req = urllib.request.Request(url, data)
urllib.request.urlopen(req)
It crashes at the last line.
Works in 3.1, but not 3.2
You did basically correct in trying to convert the string into bytes, but you did it the wrong way. Python doesn't have typecasting (so what you did was not typecasting).
The way to do it is to encode the text data into bytes data, which you do with the encode function:
binary_data = data.encode('encoding')
What 'encoding' should be depends. You should probably use 'ascii' here. If you have characters that aren't ASCII, then you need to use another encoding, typically 'utf8', but then you also need to tell the receiving webserver that it is UTF-8. It might also not want UTF8, but then you have to ask it, and it's getting complicated. :-)
#Enders, I know this is an old question, but I'd like to explain a few more things for somebody fighting with this issue.
It is specifically with this line of code here:
data = urllib.parse.urlencode(values)
That you are having issues, as you are trying to encode the data: values (urlencode).
If you refer to the urllib.parse documentation scroll to the bottom to find what urlencode does: https://docs.python.org/3/library/urllib.parse.html <~ you will see that you are trying to encode your user/pass into a data string:
Convert a mapping object or a sequence of two-element tuples, which may contain str or bytes objects, to a percent-encoded ASCII text string. If the resultant string is to be used as a data for POST operation with the urlopen() function, then it should be encoded to bytes, otherwise it would result in a TypeError.
Perhaps what you are trying to do here is do some kind of encryption of your user/password, but I don't really think this is the right way. If it is, then you probably need to make sure that the receiving end (the destination of your url) know that you're encoding your user/pass with this.
A more up-to-date approach is to use the powerful Requests library. They have compatibility with very common authentication protocols: http://docs.python-requests.org/en/master/user/authentication/
In this case, I'd do something like this:
requests.get(url, auth=('user', 'pass'))