I am trying to post a record into Netsuite and it works well with the Postman, but throwing invalid login Error with Python.
Below is the Code.
import requests
url = "https://5559796-sb1.suitetalk.api.netsuite.com/services/rest/record/v1/qbc_pqr_1234"
payload="{\"aaa\":\"AN\",\"bbb\":\"OA\",\"ccc\":1,\"ddd\":false,\"eee\":114.01,\"fff\":\"OAOTWH\",\"ggg\":\"hhh\",\"hhh\":18,\"iii\":2,\"jjj\":\"2021-07-31\",\"kkk\":3257.29,\"lll\":\"Intra-Brand Stay - 3.5%\"}"
headers = {
'Content-Type': 'application/json',
'Authorization': 'OAuth realm="5559796_SB1",oauth_consumer_key="xxxxx",oauth_token="abcdefgh",oauth_signature_method="HMAC-SHA256",oauth_timestamp="1630905651",oauth_nonce="xxxxx",oauth_version="1.0",oauth_signature="xxxxx"'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
And the error is :
{"type":"https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2","title":"Unauthorized","status":401,"o:errorDetails":[{"detail":"Invalid login attempt. For more details, see the Login Audit Trail in the NetSuite UI at Setup > Users/Roles > User Management > View Login Audit Trail.","o:errorCode":"INVALID_LOGIN"}]}
Also, how can I read the payload from a json file with multiple records.
While hitting NetSuite API you need to create a signature which is responsible to establish your connection below is the code which will help you.
import hashlib
import hmac
import json
import requests
import base64
import time
import random
import urllib.parse
def _generateTimestamp():
return str(int(time.time()))
def _generateNonce(length=11):
"""Generate pseudorandom number"""
return ''.join([str(random.randint(0, 9)) for i in range(length)])
def _generateSignature(method, url, consumerKey, Nonce, currentTime, token, consumerSecret,
tokenSecret, offset):
signature_method = 'HMAC-SHA256'
version = '1.0'
base_url = url
encoded_url = urllib.parse.quote_plus(base_url)
collected_string = None
if type(offset) == int:
collected_string = '&'.join(['oauth_consumer_key=' + consumerKey, 'oauth_nonce=' + Nonce,
'oauth_signature_method=' + signature_method, 'oauth_timestamp=' + currentTime,
'oauth_token=' + token, 'oauth_version=' + version, 'offset=' + str(offset)])
else:
collected_string = '&'.join(['oauth_consumer_key=' + consumerKey, 'oauth_nonce=' + Nonce,
'oauth_signature_method=' + signature_method, 'oauth_timestamp=' + currentTime,
'oauth_token=' + token, 'oauth_version=' + version])
encoded_string = urllib.parse.quote_plus(collected_string)
base = '&'.join([method, encoded_url, encoded_string])
key = '&'.join([consumerSecret, tokenSecret])
digest = hmac.new(key=str.encode(key), msg=str.encode(base), digestmod=hashlib.sha256).digest()
signature = base64.b64encode(digest).decode()
return urllib.parse.quote_plus(signature)
def import_customer():
nsAccountID = "YOUR_ACCOUNT_ID"
consumerKey = "YOUR_CONSUMER_KEY"
consumerSecret = "YOUR_CONSUMER_SECRET"
token = "YOUR_TOKEN"
tokenSecret = "YOUR_TOKEN_SECRET"
base_url = "https://nsAccountID.suitetalk.api.netsuite.com/services/rest/record/v1/customer"
Nonce = self._generateNonce(length=11)
currentTime = self._generateTimestamp()
signature = self._generateSignature('GET', base_url, consumerKey, Nonce, currentTime, token, consumerSecret, tokenSecret, offset)
payload = ""
oauth = "OAuth realm=\"" + nsAccountID + "\"," \
"oauth_consumer_key=\"" + consumerKey + "\"," \
"oauth_token=\"" + token + "\"," \
"oauth_signature_method=\"HMAC-SHA256\"," \
"oauth_timestamp=\"" + currentTime + "\"," \
"oauth_nonce=\"" + Nonce + "\"," \
"oauth_version=\"1.0\"," \
"oauth_signature=\"" + signature + "\""
headers = {
'Content-Type': "application/json",
'Authorization': oauth,
'cache-control': "no-cache",
}
response = requests.request("GET", base_url + '?offset=' + str(offset), data=payload, headers=headers)
return json.loads(response.text)
print(import_customer())
And here you can see the example of import customer. In every API hit you need to generate signature with every required information
Related
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
is there a way to use idealista Api in python or a simpler way ?
I didn't try this before.
I have the APIkey and the secret, and have a list of cadastral codes, so want to get rent price for each code!
Hi this works for me using Python 3.8
First you need to get the token from Idealista:
import json
import requests
import base64
def get_token():
API_KEY= "YOUR_API_KEY"
SECRET= "YOUR_SECRET"
message = API_KEY + ":" + SECRET
auth = "Basic " + base64.b64encode(message.encode("ascii")).decode("ascii")
headers_dic = {"Authorization" : auth,
"Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8"}
params_dic = {"grant_type" : "client_credentials",
"scope" : "read"}
r = requests.post("https://api.idealista.com/oauth/token",
headers = headers_dic,
params = params_dic)
bearer_token = json.loads(r.text)['access_token']
return bearer_token
With that token now you can access the search api:
def get_search():
headers_dic = {"Authorization" : "Bearer " + TOKEN,
"Content-Type" : "application/x-www-form-urlencoded"}
params_dic = {"operation" : "rent",
"locationId" : "0-EU-ES-01",
"propertyType" : "homes"}
r = requests.post("https://api.idealista.com/3.5/es/search",
headers = headers_dic,
params = params_dic)
result_json = json.loads(r.text)
return result_json
I found that the locationId goes from 0-EU-ES-01 to 0-EU-ES-56 for Spain. I didn't try the other countries.
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
I can download public files without problem.
As I admin, i will make a list who can download private file. (Google Drive's feature)
This is my code: https://stackoverflow.com/posts/39225272/revisions
I have oauth2client and google-drive-credentials.json file on .credentials folder.
In this file (google-drive-credentials) "access_token" and "refresh_token" available.
When I try to download PRIVATE files, google returns Login screen html file with request. I need to pass this with automatic. This should never come.
Here is my code:
SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'abc'
authInst = auth.auth(SCOPES, CLIENT_SECRET_FILE, APPLICATION_NAME)
credentials = authInst.getCredentials()
URL = "https://docs.google.com/uc?export=download"
session = requests.Session()
session2 = requests.Session()
toplamyari = int(int(toplamboyut) / 2)
if os.path.exists(yazp1):
sizefile = os.path.getsize(yazp1)
yazmaModu = 'ab'
bytearalik = 'bytes=' + str(sizefile) + '-' + str(toplamyari)
else:
bytearalik = 'bytes=0' + '-' + str(toplamyari)
if os.path.exists(yazp1[0:len(yazp1)-1]+"2"):
dosyaboy=os.path.getsize(str(yazp1[0:len(yazp1)-1])+'2')
self.temp2boyut=dosyaboy
bytearalik2 = 'bytes=' + str(toplamyari + 1 + dosyaboy) + '-' + str(toplamboyut)
else:
bytearalik2 = 'bytes=' + str(toplamyari+1) + '-' + str(toplamboyut)
arlik2=int(int(toplamboyut)-int(toplamyari))
accessToken = credentials.access_token
session.headers.update({'Range': bytearalik, 'Authorization':'Bearer " + accessToken})
#session2.headers.update({'Range': bytearalik2}) #don't worry about that, that's for download faster(download 2 part at same time)
response = session.get(URL, params={'id':link}, headers={'Authorization':'Bearer '+accessToken}, stream=True)
with that code as i said, i can download PUBLIC files but can not download access given private files. I think request not access, idk. And sorry for English. Thanks for all.
FIXED
Changed URL.
accessToken = credentials.access_token
#refreshTok=credentials.refresh_token
tokenTotal = 'Bearer ' + str(accessToken)
session.headers.update({'Range': bytearalik, 'Authorization':tokenTotal, 'token_type':'Bearer'})
session2.headers.update(
{'Range': bytearalik2, 'Authorization':tokenTotal ,'token_type': 'Bearer', 'accept': '*/*',
'accept-encoding': 'gzip, deflate', 'user-agent': '(gzip)',
'x-goog-api-client': 'gdcl/1.7.11 gl-python/3.7.3'})
URL='https://www.googleapis.com/drive/v3/files/'+link+'?alt=media'
download = self.DownladInfo()
download.create(self.getOyunfromID(listedekiIndex), boyut, 0, listedekiIndex, sifre, hizlimiti)
download.driveadi = dosyadi[0:dosyadi.rfind('.')]
self.indirilecek_indexler.append(download)
response = session.get(URL, stream=True)
response2 = session2.get(URL, stream=True)
if response.status_code != 206 or response2.status_code != 206:
self.indirmeyebaslarkenhatalar.append(response.status_code)
return
I'm a beginner with Python and trying to build a service that takes information from api.ai, passes it to an API, then returns a confirmation message from the JSON it returns.
app.py:
#!/usr/bin/env python
from __future__ import print_function
from future.standard_library import install_aliases
install_aliases()
from urllib.parse import urlparse, urlencode
from urllib.request import urlopen, Request
from urllib.error import HTTPError
import json
import os
import sys
import logging
from flask import Flask, render_template
from flask import request
from flask import make_response
# Flask app should start in global layout
app = Flask(__name__)
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.ERROR)
#app.route('/webhook', methods=['POST'])
def webhook():
req = request.get_json(silent=True, force=True)
print("Request:")
print(json.dumps(req, indent=4))
res = processRequest(req)
res = json.dumps(res, indent=4)
# print(res)
r = make_response(res)
r.headers['Content-Type'] = 'application/json'
return r
def processRequest(req):
if req.get("result").get("action") != "bookMyConference":
return {}
#oauth
orequest = req.get("originalRequest") # work down the tree
odata = orequest.get("data") # work down the tree
user = odata.get("user") # work down the tree
access_token = user.get("access_token")
#data
result = req.get("result") # work down the tree
parameters = result.get("parameters") # work down the tree
startdate = parameters.get("start-date")
meetingname = parameters.get("meeting-name")
payload = {
"start-date": startdate,
"end-date": startdate,
"meeting-name": meetingname
}
# POST info to join.me
baseurl = "https://api.join.me/v1/meetings"
p = Request(baseurl)
p.add_header('Content-Type', 'application/json; charset=utf-8')
p.add_header('Authorization', 'Bearer ' + access_token) #from oauth
jsondata = json.dumps(payload)
jsondataasbytes = jsondata.encode('utf-8') # needs to be bytes
jresult = urlopen(p, jsondataasbytes).read()
data = json.loads(jresult)
res = makeWebhookResult(data)
return res
def makeWebhookResult(data):
speech = "Appointment scheduled!"
print("Response:")
print(speech)
return {
"speech": speech,
"displayText": speech,
# "data": data,
"source": "heroku-bookmyconference"
}
if __name__ == '__main__':
port = int(os.getenv('PORT', 5000))
print("Starting app on port %d" % port)
app.run(debug=False, port=port, host='0.0.0.0')
Edit 4: Here's the error I'm getting in my Heroku logs:
2017-03-21T19:06:09.383612+00:00 app[web.1]: HTTPError: HTTP Error
400: Bad Request
Borrowing from here, using urlib modules inside processRequest() you could add your payload to urlopen like this:
req = Request(yql_url)
req.add_header('Content-Type', 'application/json; charset=utf-8')
jsondata = json.dumps(payload)
jsondataasbytes = jsondata.encode('utf-8') # needs to be bytes
result = urlopen(req, jsondataasbytes).read()
data = json.loads(result)
Things get more succinct if using the requests module:
headers = {'content-type': 'application/json'}
result = requests.post(yql_url, data=json.dumps(payload), headers=headers)
data = result.json()
EDIT: Adding some details specific to the join.me api
Looking at the join.me docs you'll need to obtain an access token to add to your header. But you also need an app auth code before you can get an access token. You can get the app auth code manually, or by chaining some redirects.
To get started, try this url in your browser and get the code from the callback params. Using your join.me creds:
auth_url = 'https://secure.join.me/api/public/v1/auth/oauth2' \
+ '?client_id=' + client_id \
+ '&scope=scheduler%20start_meeting' \
+ '&redirect_uri=' + callback_url \
+ '&state=ABCD' \
+ '&response_type=code'
print(auth_url) # try in browser
To get an access token:
token_url = 'https://secure.join.me/api/public/v1/auth/token'
headers = {'content-type': 'application/json'}
token_params = {
'client_id': client_id,
'client_secret': client_secret,
'code': auth_code,
'redirect_uri': callback_url,
'grant_type': 'authorization_code'
}
result = requests.post(token_url, data=json.dumps(token_params), headers=headers)
access_token = result.json().get('access_token')
Then your header for the post to /meetings would need to look like:
headers = {
'content-type': 'application/json',
'Authorization': 'Bearer ' + access_token
}