Api "Could not authenticate you" when status kontains special characters


#1

I want to update user status with python code. I am able to tweet when status contains single word, however I get “errors”:[{“message”:“Could not authenticate you”,“code”:32}] as soon as status contains anything else than a word character.
I tried to url-encode the status, but “%” in status also causes the error.

status = urllib.parse.quote(status)

oauth_consumer_key = "[censored :)]"
consumer_secret = "[censored :)]"
oauth_token = "[censored :)]"
oauth_token_secret = “[censored :)]”

url = 'https://api.twitter.com/1.1/statuses/update.json
values = {‘status’: status, }

data = urllib.parse.urlencode(values)
binary_data = data.encode(‘ascii’)
req = urllib.request.Request(url, binary_data)
##include_entities = “true"
oauth_nonce = ‘’.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(42))
oauth_signature_method = “HMAC-SHA1"
oauth_timestamp = str(round(time.time()))
oauth_version = “1.0"
signature_base_string = “POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&oauth_consumer_key%3D” + oauth_consumer_key + “%26oauth_nonce%3D” + oauth_nonce + “%26oauth_signature_method%3D” + oauth_signature_method + “%26oauth_timestamp%3D” + oauth_timestamp + “%26oauth_token%3D” + oauth_token + “%26oauth_version%3D” + oauth_version + “%26status%3D” + status
signing_key = consumer_secret + “&” + oauth_token_secret
signature = urllib.parse.quote_plus(str(base64.b64encode(
hmac.new(signing_key.encode(‘utf-8’), signature_base_string.encode(‘utf-8’), hashlib.sha1).digest()))[2:-1])
req.add_header(‘Authorization’, 'OAuth oauth_consumer_key=”’ + oauth_consumer_key + '”, ’ +
'oauth_nonce=”’ + oauth_nonce + '", ’ +
‘oauth_signature="’ + signature + '", ’ +
'oauth_signature_method=“HMAC-SHA1”, ’ +
‘oauth_timestamp="’ + oauth_timestamp + '", ’ +
‘oauth_token="’ + oauth_token + '", ’ +
‘oauth_version=“1.0”’)
try:
response = urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
print(e.code)
print(e.read())