using urllib3 module instead of requests in python - python

This code works correctly in python 2.X version. I am trying to use the similar code in python version 3.
The problem is that I do not want to use requests module. I need to make it work using "urllib3".
import requests
import urllib
event = {'url':'http://google.com', 'email':'abc#gmail.com', 'title':'test'}
url = event['url']
if event['email']:
email=event['email']
if event['title']:
title=event['title']
url1 = urllib.parse.unquote(url)
myfile=urllib.request.urlopen(url1)
requests.post("https://api.mailgun.net/v3/xxx.mailgun.org/messages",
auth=("api", "key-xxx"),
files=[("attachment", myfile)
],
data={"from": "Excited User <excited-user#example.com>",
"to": email,
"subject": title,
"text": "Testing some awesomness with attachments!",
"html": myfile})
I am getting TypeError while trying to run this code:
import urllib3
event = {'url':'http://oksoft.blogspot.com', 'email':'abc#gmail.com', 'title':'test'}
url = event['url']
if event['email']:
email=event['email']
if event['title']:
title=event['title']
url1 = urllib.parse.unquote(url)
myfile=urllib.request.urlopen(url1)
http = urllib3.PoolManager()
url = "https://api.mailgun.net/v3/xxx.mailgun.org/messages"
params={"from": "Excited User <excited-user#example.com>",
"to": email,
"subject": title,
"text": "Testing some awesomness with attachments!",
"html": myfile}
http.request(
"POST", url, headers={"Content-Type": "application/json", "api":"key-xxx"}, body= params
)

This code uses the urllib.reqeust module. To actually create a file attachment as opposed to inline html content is a bit more involved than setting an html parameter with file contents.
import urllib.request
import urllib.error
import urllib.parse
import io
import mimetypes
import uuid
class MultiPartForm:
"""Accumulate the data to be used when posting a form."""
def __init__(self):
self.form_fields = []
self.files = []
# Use a large random byte string to separate
# parts of the MIME data.
self.boundary = uuid.uuid4().hex.encode('utf-8')
return
def get_content_type(self):
return 'multipart/form-data; boundary={}'.format(
self.boundary.decode('utf-8'))
def add_field(self, name, value):
"""Add a simple field to the form data."""
self.form_fields.append((name, value))
def add_file(self, fieldname, filename, fileHandle,
mimetype=None):
"""Add a file to be uploaded."""
body = fileHandle.read()
if mimetype is None:
mimetype = (
mimetypes.guess_type(filename)[0] or
'application/octet-stream'
)
self.files.append((fieldname, filename, mimetype, body))
return
#staticmethod
def _form_data(name):
return ('Content-Disposition: form-data; '
'name="{}"\r\n').format(name).encode('utf-8')
#staticmethod
def _attached_file(name, filename):
return ('Content-Disposition: file; '
'name="{}"; filename="{}"\r\n').format(
name, filename).encode('utf-8')
#staticmethod
def _content_type(ct):
return 'Content-Type: {}\r\n'.format(ct).encode('utf-8')
def __bytes__(self):
"""Return a byte-string representing the form data,
including attached files.
"""
buffer = io.BytesIO()
boundary = b'--' + self.boundary + b'\r\n'
# Add the form fields
for name, value in self.form_fields:
buffer.write(boundary)
buffer.write(self._form_data(name))
buffer.write(b'\r\n')
buffer.write(value.encode('utf-8'))
buffer.write(b'\r\n')
# Add the files to upload
for f_name, filename, f_content_type, body in self.files:
buffer.write(boundary)
buffer.write(self._attached_file(f_name, filename))
buffer.write(self._content_type(f_content_type))
buffer.write(b'\r\n')
buffer.write(body)
buffer.write(b'\r\n')
buffer.write(b'--' + self.boundary + b'--\r\n')
return buffer.getvalue()
event = {'url':'http://oksoft.blogspot.com', 'email':'abc#gmail.com', 'title':'test'}
url = event['url']
if event['email']:
email=event['email']
if event['title']:
title=event['title']
form = MultiPartForm()
form.add_field("from", "Excited User <excited-user#example.com>")
form.add_field("to", email)
form.add_field("subject", title)
form.add_field("text", "Testing some awesomness with attachments!")
with urllib.request.urlopen(url) as f:
form.add_file("attachment", "test.html", f, "text/html")
url = "https://api.mailgun.net/v3/xxx.mailgun.org/messages"
# create basic authorization opener
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='MG API',
uri=url,
user='api',
passwd='xxx-key')
opener = urllib.request.build_opener(auth_handler)
data = bytes(form)
req = urllib.request.Request(url, data=data)
req.add_header('Content-type', form.get_content_type())
req.add_header('Content-length', len(data))
with opener.open(req) as f:
print(f.read().decode('utf-8'))

It returns a TypeError: can't concat str to bytes because your myfile is of type http.client.HTTPResponse, not of type str -- which needs to be passed to the request body.
So gotta first transform the response to a string and then json-serialize the body params.
Full code:
import urllib3
import urllib.request
import urllib.parse
import json
event = {'url': 'http://oksoft.blogspot.com',
'email': 'abc#gmail.com', 'title': 'test'}
url = event['url']
if event['email']:
email = event['email']
if event['title']:
title = event['title']
url1 = urllib.parse.unquote(url)
myfile = urllib.request.urlopen(url1)
myfile_content = myfile.read()\
.decode(myfile.headers
.get_content_charset(failobj='utf-8'))
http = urllib3.PoolManager()
url = "https://api.mailgun.net/v3/xxx.mailgun.org/messages"
params = {"from": "Excited User <excited-user#example.com>",
"to": email,
"subject": title,
"text": "Testing some awesomness with attachments!",
"html": myfile_content}
### EDIT
auth_headers = urllib3.util.make_headers(
basic_auth='api:xxx')
r = http.request(
"POST",
url,
headers=auth_headers,
fields=params
)
print(r.status, r.data)

Related

How to create paste on rentry.co with python?

How do I create a request to rentry.co in order to create pastes?
I've tried to solve this in Python but I get the following response:
403 reason: Forbidden ...
I tried changing the URL and adding my cookie.
My code looks currently as follows.
import requests
text = "Hello World!"
data = {"text":text}
r = requests.post("https://rentry.co/api", data=data)
print(f"status code: {r.status_code}")
print(f"reason: {r.reason}") ```
try this
#!/usr/bin/env python3
import http.cookiejar
import sys
import urllib.parse
import urllib.request
from http.cookies import SimpleCookie
from json import loads as json_loads
_headers = {"Referer": 'https://rentry.co'}
class UrllibClient:
"""Simple HTTP Session Client, keeps cookies."""
def __init__(self):
self.cookie_jar = http.cookiejar.CookieJar()
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cookie_jar))
urllib.request.install_opener(self.opener)
def get(self, url, headers={}):
request = urllib.request.Request(url, headers=headers)
return self._request(request)
def post(self, url, data=None, headers={}):
postdata = urllib.parse.urlencode(data).encode()
request = urllib.request.Request(url, postdata, headers)
return self._request(request)
def _request(self, request):
response = self.opener.open(request)
response.status_code = response.getcode()
response.data = response.read().decode('utf-8')
return response
def new(url, edit_code, text):
client, cookie = UrllibClient(), SimpleCookie()
cookie.load(vars(client.get('https://rentry.co'))['headers']['Set-Cookie'])
csrftoken = cookie['csrftoken'].value
payload = {
'csrfmiddlewaretoken': csrftoken,
'url': url,
'edit_code': edit_code,
'text': text
}
return json_loads(client.post('https://rentry.co/api/new', payload, headers=_headers).data)
def get_rentry_link(text):
url, edit_code = '', ''
response = new(url, edit_code, text)
if response['status'] != '200':
print('error: {}'.format(response['content']))
try:
for i in response['errors'].split('.'):
i and print(i)
sys.exit(1)
except:
sys.exit(1)
else:
pastebin_link = response['url']
print('Url: {}\nEdit code: {}'.format(response['url'], response['edit_code']))
return pastebin_link
if __name__ == '__main__':
link_list = ['https://stackoverflow.com/', 'https://www.youtube.com/', 'https://www.google.com/']
pastebin_link = get_rentry_link('\n'.join(map(str, link_list)))

hie i have been trying to develop my own trading robot using python, Can someone illustrate to me how to get live prices from deriv

I need to use a socket stream API or any tools you know to get historical and live prices from my broker(Deriv) to my system server were the program will be hosted. Thank you in advance
I use huobi api to build my bot.. below are some working codes:
import requests
import json
import hmac
import hashlib
import base64
from urllib.parse import urlencode
import time
base_uri = 'api.huobi.pro'
AccessKeyId = 'xxxxxx'
SecretKey = 'xxxxxx'
account_id = '11111111'
def get_url(method, endpoint):
timestamp = str(datetime.utcnow().isoformat())[0:19]
params = urlencode({'AccessKeyId': AccessKeyId, 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'Timestamp': timestamp})
pre_signed_text = method + '\n' + base_uri + '\n' + endpoint + '\n' + params
hash_code = hmac.new(SecretKey.encode(), pre_signed_text.encode(), hashlib.sha256).digest()
signature = urlencode({'Signature': base64.b64encode(hash_code).decode()})
return 'https://' + base_uri + endpoint + '?' + params + '&' + signature
def get_all_open_orders():
url = get_url('GET', '/v1/order/openOrders')
response = requests.request('GET', url, headers={}, data={})
return json.loads(response.text)['data']
def place_new_order(data): #for both buy/sell
url = get_url('POST', '/v1/order/orders/place')
response = requests.request('POST', url, headers={'Content-Type': 'application/json'}, data=data)
return json.loads(response.text)
def cancel_order(order_id):
url = get_url('POST', '/v1/order/orders/{}/submitcancel'.format(order_id))
response = requests.request('POST', url, headers={}, data={})
return json.loads(response.text)
To get current price
SYMBOL = 'xrphusd'
url = 'https://api.huobi.pro/market/history/kline?period=1min&size=1&symbol=' + SYMBOL
response = requests.request('GET', url, headers={}, data={})
print(json.loads(response.text)['data'][0])
To place an order (can be 'buy-limit' or 'sell-limit')
price = "1.25"
quantity = "100"
payload = {"account-id": str(account_id), "amount": quantity, "price": price, "source": "api", "symbol": SYMBOL, "type": "buy-limit"}
status = place_new_order(json.dumps(payload))
print(status)
Documentation available here https://huobiapi.github.io/docs/spot/v1/en

Bitmex Signature Not Valid

I am trying to make authenticated post request to place an order on the testnet. I have been trying to get it going for couple of days, but unable to figure out why I get "Signature not Valid"
import json
import requests
import aiohttp
import asyncio
import urllib
import time
import hashlib, hmac
import urllib.parse
import json
api_key = "YOUR_API_KEY"
api_secret = "YOUR_SECRET_KEY"
base_url = 'https://testnet.bitmex.com'
method = 'POST'
data = '{"symbol":"XBTUSD","quantity":1,"price":395.01}'
path = '/api/v1/order'
url = base_url + path
print(url)
nonce = int(time.time() * 1000)
print(nonce)
message = bytes(method + path + str(nonce) + data, 'utf-8')
print(message)
def generate_signature(secret, verb, url, nonce, data):
"""Generate a request signature compatible with BitMEX."""
# Parse the url so we can remove the base and extract just the path.
parsedURL = urllib.parse.urlparse(url)
path = parsedURL.path
if parsedURL.query:
path = path + '?' + parsedURL.query
message = bytes(verb + path + str(nonce) + data, 'utf-8')
# print("Computing HMAC: %s" % message)
signature = hmac.new(bytes(secret, 'utf-8'), message, digestmod=hashlib.sha256).hexdigest()
return signature
# signature = hmac.new(bytes(api_secret, 'utf-8'), message, digestmod=hashlib.sha256).hexdigest()
signature = generate_signature(api_secret, method, path, nonce, data)
print(signature)
headers = {'api-expires':str(nonce),'api-key':api_key,'api-signature':signature, 'Content-Type': 'aplication/json','Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest'}
print(headers)
r = requests.post(url, data=data, headers=headers)
print(r.status_code)
print(r.text)
What is wrong in this code? Please assume that correct api key and secret provided.
I am getting the following response.
401
{"error":{"message":"Signature not valid.","name":"HTTPError"}}
https://www.bitmex.com/app/apiKeysUsage

Looking for example Python code for Netsuite API using OAuth?

Netsuite's documentation is not forthcoming. Does anyone have code they've written that will help me generate a valid signature.
There is some sample code in the NetSuite Suite answers site, but you'll have to log in to access it.
https://netsuite.custhelp.com/app/answers/detail/a_id/42165/kw/42165
Here is the code from the answer that I was able to make work. The only difference is that their code broke by trying to encode the timestamp as an int. I typecasted it to a str and the encoding worked fine. The keys/tokens/realm are from their demo code. Insert your own and you should be good to go.
import oauth2 as oauth
import requests
import time
url = "https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5", secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38", secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "GET"
realm="ACCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
req = oauth.Request(method=http_method, url=url, parameters=params)
signature_method = oauth.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
headery = header['Authorization'].encode('ascii', 'ignore')
headerx = {"Authorization": headery, "Content-Type":"application/json"}
print(headerx)
conn = requests.get("https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1",headers=headerx)
print(conn.text)
Just for reference, I recently did this in Python3 using requests_oauthlib and it worked with standard use of the library:
from requests_oauthlib import OAuth1Session
import json
url = 'https://xxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=xxx&deploy=xxx'
oauth = OAuth1Session(
client_key='xxx',
client_secret='xxx',
resource_owner_key='xxx',
resource_owner_secret='xxx',
realm='xxx')
payload = dict(...)
resp = oauth.post(
url,
headers={'Content-Type': 'application/json'},
data=json.dumps(payload),
)
print(resp)
Building off NetSuite's original sample code I was able to get the below working with SHA256, I think you could do a similar thing for SHA512.
import binascii
import hmac
import time
from hashlib import sha256
import oauth2 as oauth
import requests
url = "https://<account>.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=<scriptId>&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5",
secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38",
secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "POST"
realm = "CCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
class SignatureMethod_HMAC_SHA256(oauth.SignatureMethod):
name = 'HMAC-SHA256'
def signing_base(self, request, consumer, token):
if (not hasattr(request, 'normalized_url') or request.normalized_url is None):
raise ValueError("Base URL for request is not set.")
sig = (
oauth.escape(request.method),
oauth.escape(request.normalized_url),
oauth.escape(request.get_normalized_parameters()),
)
key = '%s&' % oauth.escape(consumer.secret)
if token:
key += oauth.escape(token.secret)
raw = '&'.join(sig)
return key.encode('ascii'), raw.encode('ascii')
def sign(self, request, consumer, token):
"""Builds the base signature string."""
key, raw = self.signing_base(request, consumer, token)
hashed = hmac.new(key, raw, sha256)
# Calculate the digest base 64.
return binascii.b2a_base64(hashed.digest())[:-1]
req = oauth.Request(method=http_method, url=url, parameters=params)
oauth.SignatureMethod_HMAC_SHA256 = SignatureMethod_HMAC_SHA256
signature_method = oauth.SignatureMethod_HMAC_SHA256()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
header_y = header['Authorization'].encode('ascii', 'ignore')
header_x = {"Authorization": header_y, "Content-Type": "application/json"}
print(header_x)
response = requests.request("POST", url, data={}, headers=header_x)
# conn = requests.post(url, headers=headerx)
print(response.text)

Creating a python wrapper for an API using classes

I am trying to make a Python Wrapper for an API. I have been able to create scripts that work fine but don't use classes. I want to make a real wrapper of that API using classes. I am new to OOP in Python.
Following was my attempt but I am stuck at how to convert it to an OO type.
import urllib2
from urllib import urlencode
import json
class apiclient:
def __init__(self,
request_url,
hmh_api_key,
client_id,
grant_type="password",
username="username",
password="password"):
values = {
"client_id": client_id,
"grant_type": grant_type,
"username": username,
"password": password
}
data = urlencode(values)
req = urllib2.Request(request_url, data)
req.add_header("Api-Key", api_key)
response = urllib2.urlopen(req)
response_header = response.info().dict
response_body = response.read()
json_acceptable_string = response_body.replace("'", "\"")
response_body_dict = json.loads(json_acceptable_string)
return response_body_dict ## this is the response
if __name__ == "__main__":
API_KEY = "75b5cc58a5cdc0a583f91301cefedf0c"
CLIENT_ID = "ef5f7a03-58e8-48d7-a38a-abbd2696bdb6.hmhco.com"
REQUEST_URL = "http://some.url"
client = apiclient(request_url=REQUEST_URL,
api_key=API_KEY,
client_id=CLIENT_ID)
print client
Without classes, I get the response JSON as response_body_dict but with classes I get TypeError: __init__() should return None. How should I start designing my program.
I have shown only a part of the whole program, there are a lot many similar scripts that send requests to URLs and get JSON responses.
Thanks!
You should not return something from __init__ function.
EDIT:
If you need that value you should use the response_body_dict as a class member and get him from other method:
import urllib2
from urllib import urlencode
import json
class apiclient:
def __init__(self,
request_url,
api_key,
client_id,
grant_type="password",
username="username",
password="password"):
values = {
"client_id": client_id,
"grant_type": grant_type,
"username": username,
"password": password
}
data = urlencode(values)
req = urllib2.Request(request_url, data)
req.add_header("Api-Key", api_key)
response = urllib2.urlopen(req)
response_header = response.info().dict
response_body = response.read()
json_acceptable_string = response_body.replace("'", "\"")
self.response_body_dict = json.loads(json_acceptable_string)
def get_response_body(self):
return self.response_body_dict
if __name__ == "__main__":
API_KEY = "75b5cc58a5cdc0a583f91301cefedf0c"
CLIENT_ID = "ef5f7a03-58e8-48d7-a38a-abbd2696bdb6.hmhco.com"
REQUEST_URL = "http://some.url"
client = apiclient(request_url=REQUEST_URL,
api_key=API_KEY,
client_id=CLIENT_ID)
response = client.get_response_body()
print client

Categories

Resources