Python HTTP Get Request (Occasional 401 - Unauthorized) - python

I'm using the following python script to connect with adsl modem and retrive wifi information
host = 192.168.1.1
pwd = **********
conn = httplib.HTTPConnection(host)
auth = b64encode("admin:"+pwd).decode("ascii")
head = { 'Authorization' : 'Basic %s' % auth }
conn.request("GET", "/basic/home_wlan.htm", headers = head)
resp = conn.getresponse()
#Do something ....
conn.close()
Most of the times evereything is OK, but sometimes happemes to receive 401 - Unauthorized http error.
When I retry executing immidiatly after this error, everything works ok. Now, to overcome this I added the following code immidiatly before #Do something...:
if resp.status == 401:
conn = httplib.HTTPConnection(host)
auth = b64encode("admin:"+pwd).decode("ascii")
head = { 'Authorization' : 'Basic %s' % auth }
conn.request("GET", "/basic/home_wlan.htm", headers = head)
resp = conn.getresponse()
In other terms I'm repeating the connection negotiation if 401 occurs. In my opinion this is not so elegant to do this. Can someone give me a more acceptable solution?

Related

Solution for the Invalid URL non-numeric port error?

I am trying to use a cryptcurrency API to get some information from a remote server in python. The example from the API how to do it is here: https://developers.cryptoapis.io/technical-documentation/blockchain-data/unified-endpoints/get-transaction-details-by-transaction-id
But when I try to run it I get an exception
Exception has occurred: InvalidURL
nonnumeric port: '//rest.cryptoapis.io/v2'
I am not sure what is wrong here (new to Python). Can someone please point out? I thought at least the formal example from the API provider must work?
My code is:
import http.client
conn = http.client.HTTPConnection("https://rest.cryptoapis.io/v2")
headers = {
'Content-Type': "application/json",
'X-API-Key': "API key provided by the software provider"
}
conn.request("GET", "blockchain-data,bitcoin,testnet,transactions,4b66461bf88b61e1e4326356534c135129defb504c7acb2fd6c92697d79eb250", headers=headers )
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Looks like you misunderstood the documentation. You may find this helpful:-
import requests
import json
APIKEY = 'YourAPIKeyGoesHere' # <-----
BASE = 'https://rest.cryptoapis.io/v2'
BLOCKCHAIN = 'bitcoin'
NETWORK = 'testnet'
TID = '4b66461bf88b61e1e4326356534c135129defb504c7acb2fd6c92697d79eb250'
with requests.Session() as session:
h = {'Content-Type': 'application/json',
'X-API-KEY': APIKEY}
r = session.get(
f'{BASE}/blockchain-data/{BLOCKCHAIN}/{NETWORK}/transactions/{TID}', headers=h)
r.raise_for_status()
print(json.dumps(r.json(), indent=4, sort_keys=True))

How to solve "[Winerror]:10054 An existing connection was forcibly closed by the remote host"?

I am trying to fetch the json response using the VirusTotal API. To fetch the results as a response I have created a python script which is as shown below : Then error show like this : [Winerror]:10054 An existing connection was forcibly closed by the remote host
import requests
url = "https://www.virustotal.com/vtapi/v2/file/scan"
api_key = "MyApiKey"
params = {"apikey": api_key}
files = {"file": ("app.exe", open("C:/Users/Administrator/Desktop/malware detection/app.exe", "rb")}
try:
response = requests.post(url, files=files, params=params)
print(response.json())
except Exception as e:
print(e)
To provide more information, please try the following:
import requests
url = "https://www.virustotal.com/vtapi/v2/file/scan"
api_key = "MyApiKey"
params = {"apikey": api_key}
files = {"file": ("app.exe", open("C:/Users/Administrator/Desktop/malware detection/app.exe", "rb"))}
try:
response = requests.post(url, files=files, params=params)
print(response.json())
except Exception as e:
print(e)
And post the error response you receive from the updated code.
This issue is resolved, The issue was encountered only for the skype.exe file. while scanning using malware machine learning.

Python - Requests module - Receving streaming updates - Connection reset by peer

I have been building my own python (version 3.2.1) trading application in a practice account of a Forex provider (OANDA) but I am having some issues in receiving the streaming prices with a Linux debian-based OS.
In particular, I have followed their "Python streaming rates" guide available here: http://developer.oanda.com/rest-live/sample-code/.
I have a thread calling the function 'connect_to_stream' which prints out all the ticks received from the server:
streaming_thread = threading.Thread(target=streaming.connect_to_stream, args=[])
streaming_thread.start()
The streaming.connect_to_stream function is defined as following:
def connect_to_stream():
[..]#provider-related info are passed here
try:
s = requests.Session()
url = "https://" + domain + "/v1/prices"
headers = {'Authorization' : 'Bearer ' + access_token,
'Connection' : 'keep-alive'
}
params = {'instruments' : instruments, 'accountId' : account_id}
req = requests.Request('GET', url, headers = headers, params = params)
pre = req.prepare()
resp = s.send(pre, stream = True, verify = False)
return resp
except Exception as e:
s.close()
print ("Caught exception when connecting to stream\n%s" % str(e))
if response.status_code != 200:
print (response.text)
return
for line in response.iter_lines(1):
if line:
try:
msg = json.loads(line)
print(msg)
except Exception as e:
print ("Caught exception when connecting to stream\n%s" % str(e))
return
The msg variable contains the tick received for the streaming.
The problem is that I receive ticks for three hours on average after which the connection gets dropped and the script either hangs without receiving any ticks or throws an exception with reason "Connection Reset by Peer".
Could you please share any thoughts on where I am going wrong here? Is it anything related to the requests library (iter_lines maybe)?
I would like to receive ticks indefinitely unless a Keyboard exception is raised.
Thanks
That doesn't seem too weird to me that a service would close connections living for more than 3 hours.
That's probably a safety on their side to make sure to free their server sockets from ghost clients.
So you should probably just reconnect when you are disconnected.
try:
s = requests.Session()
url = "https://" + domain + "/v1/prices"
headers = {'Authorization' : 'Bearer ' + access_token,
'Connection' : 'keep-alive'
}
params = {'instruments' : instruments, 'accountId' : account_id}
req = requests.Request('GET', url, headers = headers, params = params)
pre = req.prepare()
resp = s.send(pre, stream = True, verify = False)
return resp
except SocketError as e:
if e.errno == errno.ECONNRESET:
pass # connection has been reset, reconnect.
except Exception as e:
pass # other exceptions but you'll probably need to reconnect too.

Python and pushbullet api: send a file

I'm trying to send a file using Pushbullet following their API docs.
This is my function:
def push_file(AccessToken, file_name):
f = open(file_name, 'rb')
file_type = mimetypes.guess_type(file_name)[0]
print("Uploading {0}...".format(file_name))
try:
data = {
'file_name': file_name,
'file_type' : file_type
}
resp = requests.post(UPLOAD_REQUEST_URL, data=data, auth=(AccessToken, '')).json()
if resp.get('error') != None:
print("Error: {0}".format(resp.get('error')['message']))
return
file_url = resp.get('file_url')
print(file_url)
resp = requests.post(resp.get('upload_url'), data=resp.get('data'), auth=(AccessToken, ''), files={'file': f})
data = {
'type' : 'file',
'file_name' : file_name,
'file_type' : file_type,
'file_url' : file_url,
'body' : ''
}
resp = requests.post(PUSH_URL, data=data, auth=(AccessToken, '')).json()
except requests.exceptions.ConnectionError:
traceback.print_exc()
f.close()
But I keep getting:
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='s3.amazonaws.com', port=443): Max retries exceeded with url: /pushbullet-uploads (Caused by <class 'ConnectionResetError'>: [Errno 104] Connection reset by peer)
If I use another AccessToken I still get this error, even if it's the first time I post to that url.
The upload process is unfortunately not very good and will hopefully be improved soon. It is the one request that does not obey the JSON rule. There is a curl example that shows this (https://docs.pushbullet.com/#upload-request), but understanding curl syntax is basically impossible.
Here's an example that I just typed up and seems to work:
import requests
import json
ACCESS_TOKEN = '<your access token here>'
resp = requests.post('https://api.pushbullet.com/v2/upload-request', data=json.dumps({'file_name': 'image.jpg'}), headers={'Authorization': 'Bearer ' + ACCESS_TOKEN, 'Content-Type': 'application/json'})
if resp.status_code != 200:
raise Exception('failed to request upload')
r = resp.json()
resp = requests.post(r['upload_url'], data=r['data'], files={'file': open('image.jpg', 'rb')})
if resp.status_code != 204:
raise Exception('failed to upload file')
print r['file_name'], r['file_type'], r['file_url']
According to the Pusbullet API
All POST requests should be over HTTPS and use a JSON body with the
Content-Type header set to "application/json".
Try changing your requests.post calls like so:
resp = requests.post(UPLOAD_REQUEST_URL, json=data, auth=(AccessToken, '')).json()
Use json=data instead of data=data. Requests will automatically set Content-Type to application/json.

Using Python to POST XML over HTTPS

Let me start with I have successfully connected to my service end point. When I run my program, I get a 200 OK and a text response of XML request null. These are both good things! It's exactly what I get if I paste the URL of the service end point into a browser.
My question is, in my program I thought I was properly attaching my XML request payload to my POST. However with the response of XML request null. indeed I am not.
xml = '''xml request here '''
host = "www.xmlendpoint.com"
url = "/service/endpoint"
def doRequest():
conn = httplib.HTTPSConnection(host)
headers = {"Content-type": "text/xml","Content-Length": "%d" % len(xml)}
conn.request("POST", url, "", headers)
conn.send(xml)
res = conn.getresponse()
print res.status, res.reason
print res.read()
conn.close()
if __name__ == "__main__":
doRequest()
Anything glaring wrong here?

Categories