Here is my updated code with the revisions. I only added the user_num = 1 to try to avoid the unsupported operand error I was getting , but that didn't work either.
.py
class MetropolisApp(App):
user_num = 1
database_url = 'https://metropolis-58211.firebaseio.com/'
def build(self):
self.my_firebase = MyFirebase()
return ControlScreens()
def on_start(self):
user_num_req = requests.get("https://metropolis-58211.firebaseio.com/user_num.json")
self.user_num = user_num_req.json()
db = requests.get('https://metropolis-58211.firebaseio.com/' + str(self.user_num) + '.json')
#print(db.ok)
data = json.loads(db.content.decode())
#print(data)
def post(self, firstname, lastname, email, username, password):
self.user_num += 1
# Make a python dictionary
fname_data = {"fname": firstname}
lname_data = {"lname": lastname}
email_data = {"email": email}
user_id = {"userid": username}
user_pw = {"userpw": password}
# Send the python dictionary
requests.post(url=self.database_url + str(self.user_num) + '.json', json=fname_data)
requests.post(url=self.database_url + str(self.user_num) + '.json', json=lname_data)
requests.post(url=self.database_url + str(self.user_num) + '.json', json=email_data)
requests.post(url=self.database_url + str(self.user_num) + '.json', json=user_id)
requests.post(url=self.database_url + str(self.user_num) + '.json', json=user_pw)
def in_database(self, firstname, lastname, email, username, password):
fname_data = {"fname": firstname}
lname_data = {"lname": lastname}
email_data = {"email": email}
user_id = {"userid": username}
user_pw = {"userpw": password}
requests.patch(url=self.database_url + str(self.user_num) + '.json', json=fname_data)
requests.patch(url=self.database_url + str(self.user_num) + '.json', json=lname_data)
requests.patch(url=self.database_url + str(self.user_num) + '.json', json=email_data)
requests.patch(url=self.database_url + str(self.user_num) + '.json', json=user_id)
requests.patch(url=self.database_url + str(self.user_num) + '.json', json=user_pw)
check_request = requests.get(
'https://metropolis-58211.firebaseio.com/.json?orderBy="userid"&equalTo="%s"' % self.root.ids[
'user_login'].text)
print(check_request.json())
# print(self.root.ids)
Not sure if the .kv file is needed, but here is the main code in which I am having errors.
Edited Database
There are a couple concepts to understand here. The first is the rule system of Firebase's real-time database. The rule system dictates what kind of reads/writes to the database are allowed. An important part of the rule system is using indexes to tell Firebase that you want to be able to query your data by a certain parameter. For example, you need to query your database by the userid parameter. In your rules tab of your real-time database, you need to tell Firebase to let you 'indexOn' the 'userid' parameter, like so:
{
"rules": {
".read": true, // Note - this allows all reads from anyone anywhere. only use for testing
".write": true, // same comment
".indexOn": ["userid"] // You can allow multiple indexOns by doing ["userid","foo","bar"]
}
}
The ".indexOn" portion above is part of your top level rules (/ in your database), and you want to index on data that is inside some special identifier (/special_identifier/userid). The special identifier for your test user is 2 in this case.
Now that you are allowing your database to be queried by the userid parameter, you need to actually send a request using python to query it. The next concept here is sending some special arguments in the URL of your get request (read Firebase's documentation here). In this case, you need to try to get data from your top level (/) location, and orderBy userid and only return values equalTo self.root.ids['user_login'].text
Your URL in this case would be:
'https://metropolis-58211.firebaseio.com/.json?orderBy="userid"&equalTo="%s"'%self.root.ids['user_login'].text
Notice how you use the ? character to specify you're going to send some special parameters, and the & means another special parameter is coming. Also make sure your values that you are ordering-by or equaling-to are surrounded in " (assuming their strings in your database, which they are at the moment).
When you do a get request to that URL, either it will return the data for that user, or an empty dictionary.
check_request = requests.get('https://metropolis-58211.firebaseio.com/.json?orderBy="userid"&equalTo="%s"'%self.root.ids['user_login'].text)
print(check_request.json()) # If this has data, the user exists, if it's an empty dictionary, {}, the user doesn't exist
Related
So I made a chatbot using Dialogflow. It's supposed to retrieve the number of daily covid-19 cases through webhook call. In my python program, I programmed so that it would save the fulfillment message to MongoDB and then send the message to Dialogflow. Only problem right now is that if I connect to my database, the program won't return anything. But when I don't connect, then it works just fine.
Here's the part of the code that I'm having trouble with:
log = Conversations.Log()
sessionID = req.get('responseId')
result = req.get("queryResult")
intent = result.get("intent").get('displayName')
query_text = result.get("queryText")
parameters = result.get("parameters")
cust_name = parameters.get("cust_name")
cust_contact = parameters.get("cust_contact")
cust_email = parameters.get("cust_email")
db = configureDataBase()
if intent == 'covid_searchcountry':
cust_country = parameters.get("geo-country")
if(cust_country=="United States"):
cust_country = "USA"
fulfillmentText, deaths_data, testsdone_data = makeAPIRequest(cust_country)
webhookresponse = "***Covid Report*** \n\n" + " New cases :" + str(fulfillmentText.get('new')) + \
"\n" + " Active cases : " + str(
fulfillmentText.get('active')) + "\n" + " Critical cases : " + str(fulfillmentText.get('critical')) + \
"\n" + " Recovered cases : " + str(
fulfillmentText.get('recovered')) + "\n" + " Total cases : " + str(fulfillmentText.get('total')) + \
"\n" + " Total Deaths : " + str(deaths_data.get('total')) + "\n" + " New Deaths : " + str(
deaths_data.get('new')) + \
"\n" + " Total Test Done : " + str(deaths_data.get('total')) + "\n\n*******END********* \n "
print(webhookresponse)
log.saveConversations(sessionID, cust_country, webhookresponse, intent, db)
log.saveCases( "country", fulfillmentText, db)
return {
"fulfillmentMessages": [
{
"text": {
"text": [
webhookresponse
]
}
},
{
"text": {
"text": [
"Do you want me to send the detailed report to your e-mail address? Type.. \n 1. Sure \n 2. Not now "
# "We have sent the detailed report of {} Covid-19 to your given mail address.Do you have any other Query?".format(cust_country)
]
}
}
]
}
Whenever I comment out db=configureDataBase(), everything works fine, but when I establish the connection again, the program will stop returning.
Here's the code for configureDataBase():
def configureDataBase():
client = MongoClient("connection URL")
return client.get_database('Covid_19_DB')
If anyone can help me figure out why connecting to my database is causing it to break, I'd really appreciate it.
Getting this error how to fix ? i m trying to create a function to plance an order kucoin api v2 python but give error how to fix
i tried to make this function with full code but still cant find a solution whats wrong
Kucoin Api v2 Python Place a New Order Code - {'code': '400005', 'msg': 'Invalid KC-API-SIGN'}
base_uri = 'https://api.kucoin.com'
def float_to_dic(price):
formatted_float = "{:.9f}".format(price)
return formatted_float
def get_headers(method, endpoint):
now = int(time.time() * 1000)
str_to_sign = str(now) + method + endpoint
signature = base64.b64encode(hmac.new(api_secret.encode(), str_to_sign.encode(), hashlib.sha256).digest()).decode()
passphrase = base64.b64encode(hmac.new(api_secret.encode(), api_passphrase.encode(), hashlib.sha256).digest()).decode()
return {'KC-API-KEY': api_key,
'KC-API-KEY-VERSION': '2',
'KC-API-PASSPHRASE': passphrase,
'KC-API-SIGN': signature,
'KC-API-TIMESTAMP': str(now)
}
#List Accounts
method = 'POST'
endpoint = '/api/v1/orders'
price_buy = float(1900)
quantity = 0.3
price = "{:.9f}".format(price_buy)
symbol = 'ETH-USDT'
body = '{"text":"t-123456","symbol":"' + symbol + '","type":"market","tradeType":"TRADE","side":"buy","time_in_force":"gtc","auto_borrow":false}'
response = requests.request(method, base_uri+endpoint, headers=get_headers(method, endpoint), data=body)
print(response.status_code)
print(response.json())
Here is a snippet of code i have created based on kucoin-python wrapper.
You can test it :
from kucoin.client import Trade, Market
class my_kukoin_handler:
def __init__(self,key,sec,pas):
self.api_key = key
self.api_secret = sec
self.api_passphrase = pas
self.client = Trade(key=self.api_key, secret=self.api_secret, passphrase=self.api_passphrase, is_sandbox=False, url='')
def update_client(self):
self.client = Trade(key=self.api_key, secret=self.api_secret, passphrase=self.api_passphrase, is_sandbox=False,url='')
def buy(self,coin_no_usdt,qty):
try:
order_id = self.client.create_market_order(str(coin_no_usdt).upper().replace('USDT','').strip()+'-USDT', 'buy', size=str(int(qty)))
except Exception as e :
print('Kukoin error while buyin has occured',str(e))
you need to pass your timestamp for your signature encode process
the other thing i did was this:
encode(Config.SECRET_KEY, timestamp + "POST" + "/api/v1/orders" + kucoinOrderRequest.toString()) + "",
KucoinOrderRequest model class toString function is basically a json format of the request, like this:
"{" +
"\n\"clientOid\":\"" + clientOid + '\"' +
",\n\"side\":\"" + side + '\"' +
",\n\"symbol\":\"" + symbol + '\"' +
",\n\"type\":\"" + type + '\"' +
",\n\"size\":\"" + size + '\"' +
"\n}";
The body needs to be converted to json before making the request since this is V2.
I am trying to send an authentificated message over an API at iconomi.com.
I am used to sign message when dealing with other exchange API, but can't be authentificated with this specific one.
I read the official documentation for authentification:
You generate the ICN-SIGN header by creating a sha512 HMAC using the
base64-decoded secret key on the prehash string timestamp + method +
requestPath + body (where + represents string concatenation) and
base64-encode the output, where:
the timestamp value is the same as the ICN-TIMESTAMP header. the body
is the request body string or omitted if there is no request body
(typically for GET requests). method must always be in upper case
Example: base64_encode(HMAC_SHA512(secret_key, timestamp + upper_case(method) + requestPath + body))
I found also a java client example on the official github, please see bellow signature generation in java :
private String generateServerDigest(String method, String uri, long timestamp, String body) {
//return timestamp + request.getMethodValue() + uri + body;
String checkDigestString = timestamp + method + uri + body;// "GET+/v1/daa-list+123123123"; //timestamp in epoch milliseconds
// hash server composited digest with algorithm and apikeys secret
SecretKeySpec signingKey = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA512");
Mac mac;
try {
mac = Mac.getInstance(signingKey.getAlgorithm());
mac.init(signingKey);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
log.warn("Could not ={}", signingKey.getAlgorithm());
return null;
}
return Base64.getEncoder().encodeToString(mac.doFinal(checkDigestString.getBytes()));
}
Please note that checkDigestString code timestamp + method + uri + body and comment GET+/v1/daa-list+123123123 are already different on the official doc.
And this is my python implementation attempt :
def sign(timestamp,method,requestPath,body):
global api_secret
base64_decoded_secret_key = base64.b64decode(api_secret)
content_to_hash = (str(timestamp) + method.upper() + requestPath + body).encode('utf-8')
sign_digest = hmac.new(base64_decoded_secret_key, content_to_hash , hashlib.sha512).digest()
return base64.b64encode(sign_digest).decode('utf-8')
When I try this signature method with requestPath = "/v1/user/balance" (which required to be authentificated), it fail without error...
Does any one used with both java and python may help me to convert this signature method to python ?
This code will work for GET:
import time,requests
import hashlib,hmac,base64
api_key = "my api key"
api_secret = "my api secret"
defaut_encoding = "utf8"
uri = "https://api.iconomi.com"
requestPath = "/v1/user/balance"
api_url_target = uri+requestPath # https://api.iconomi.com/v1/user/balance
method="GET"
body=""
icn_timestamp = int(1000.*time.time())
message = (str(icn_timestamp) + method.upper() + requestPath + body).encode(defaut_encoding)
signature_digest = hmac.new(api_secret.encode(defaut_encoding), message, hashlib.sha512).digest() #here digest is byte
b64_signature_digest= base64.b64encode(signature_digest).decode(defaut_encoding)
headers_sign= {
"ICN-API-KEY":api_key,
"ICN-SIGN":b64_signature_digest,
"ICN-TIMESTAMP":str(icn_timestamp)
}
s=requests.session()
res = s.get(api_url_target,headers=headers_sign,timeout=3, verify=True).content
print (res)
Update for #Karl comment, this code will work for POST:
import time,requests
import hashlib,hmac,base64,json
api_key = "my api key"
api_secret = "my api secret"
ticker = "my ticker strategy"
defaut_encoding = "utf8"
uri = "https://api.iconomi.com"
requestPath = "/v1/strategies/"+ticker+"/structure"
api_url_target = uri+requestPath # https://api.iconomi.com/v1/strategies/{my ticker strategy}/structure
method="POST"
body="{'ticker': ticker, 'values': [{'rebalancedWeight': 1., 'targetWeight':1., 'assetTicker': 'XMR', 'assetName': 'Monero', 'assetCategory': 'Privacy'}]}"
icn_timestamp = int(1000.*time.time())
message = (str(icn_timestamp) + method.upper() + requestPath + body).encode(defaut_encoding)
signature_digest = hmac.new(api_secret.encode(defaut_encoding), message, hashlib.sha512).digest() #here digest is byte
b64_signature_digest= base64.b64encode(signature_digest).decode(defaut_encoding)
headers_sign= {
"ICN-API-KEY":api_key,
"ICN-SIGN":b64_signature_digest,
"ICN-TIMESTAMP":str(icn_timestamp)
}
s=requests.session()
res = s.post(api_url_target,headers=headers_sign,json = json.loads(body), timeout=3, verify=True).content
print (res)
Is there a way to automate checking Google Page Speed scores?
So I figured out how to do this using the Google Page Speed API buried in the documentation.
The TL:DR explanation is you can use the following URL setup, replacing the bracketed values after enabling Google Pagespeed API in Cloud Console (and if in a browser you must also have Authenticated Google Cloud User Signed In).
https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url={YOUR_SITE_URL}/&filter_third_party_resources=true&locale=en_US&screenshot=false&strategy=desktop&key={YOUR_API_KEY}
As you can see from the link above you will need a Google Pagespeed API Key. These are from scratch setup instructions. If your project is already on Cloud Console you can skip the first few steps.
Go to Cloud https://console.developers.google.com
Sign up for an account if necessary.
Create a Project
Go to Menu > API Manager > Credentials
Create credentials button > API Key
Copy Key then hit close
Menu > Dashboard > Enable API
Use Search to find PageSpeed insights API and click on it
Use the “|> ENABLE” button near the title
Once you have an API Key you can replace the values in the URL, it should look something like this:
https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=https://www.example.com/&filter_third_party_resources=true&locale=en_US&screenshot=false&strategy=desktop&key=FaKeApIKey29nS8U22mM
The parameter strategy=desktop in the url can be changed to strategy=mobile. For mobile you get a speed and a usability score. Here's what the start of the JSON looks like:
{
"kind": "pagespeedonline#result",
"id": "https://www.example.com/fake/page”,
"responseCode": 200,
"title": "Example Domain",
"ruleGroups": {
"SPEED": {
"score": 100
},
"USABILITY": {
"score": 100
}
},
....continued...
So I automated this using a Python & Python Unit Test.
import requests
import json
import unittest
from globes import *
api_key = '' # Add API key. Found here: https://console.developers.google.com/apis/credentials/key/
base = 'http://example.com'
locale_code = 'en_US'
def get_insights_json(self, page_url, local, device_type, api_key, speed_or_useability, expected_score):
url = 'https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=' + page_url + '&filter_third_party_resources=true&locale=' + local + '&screenshot=false&strategy=' + device_type + '&key=' + api_key
# print "Getting :: " + url
r = requests.get(url)
return_code = r.status_code
try: self.assertEqual(return_code, 200)
except AssertionError, e: self.verificationErrors.append(str(page_url) + " did not return 200")
return_text = r.text
return_json = json.loads(return_text)
score = return_json['ruleGroups'][speed_or_useability]['score']
print 'Getting ' + speed_or_useability + ' for ' + page_url + ' and got a score of ' + str(score)
try: self.assertTrue(int(score) >= expected_score)
except AssertionError, e: self.verificationErrors.append(str(page_url) + ' expected ' + device_type + ' speed score to be greater than ' + str(expected_score) + ', instead got ' + str(score) )
class TestAllAPIs(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.maxDiff = None
def tearDown(self):
self.assertEqual([], self.verificationErrors)
def test_desktop_speed(self):
current_page = base + '' # You could add to the url to test other pages, I tend to do this is a loop using a list I set up by base url.
device_type = 'desktop'
target = 'SPEED'
get_insights_json(self, current_page, locale_code, device_type, api_key, target, 80)
def test_mobile_speed(self):
current_page = base + ''
device_type = 'mobile'
target = 'SPEED'
get_insights_json(self, current_page, locale_code, device_type, api_key, target, 80)
def test_mobile_useability(self):
current_page = base + ''
device_type = 'mobile'
target = 'USABILITY'
get_insights_json(self, current_page, locale_code, device_type, api_key, target, 80)
if __name__ == "__main__":
unittest.main()
There is one thing that's a little of a mystery to me is why browsers need to be authenticated with Google to get JSON from URL but Python requests does not.
Anybody using this guide (as of April 2022) will need to update to the following:
https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url={YOUR_SITE_URL}/&filter_third_party_resources=true&locale=en_US&screenshot=false&strategy=desktop&key={YOUR_API_KEY}
The difference is the "/v2/" needs to be replaced with "/v5/"
I am trying to use the TransactionSearch API to bring up merchant transaction history. I have been stuck with a "security header is not valid error" and wasn't able to find a solution in the other posts. My code works fine on the sandbox server and I generated live credentials+signature from PayPal. I assume that if they gave me credentials that I have permission to access the API.
My python code is as follows:
import requests
def getTransactionHistory(start_datetime, end_datetime):
headers = {'X-PAYPAL-SECURITY-USERID' : api_username, 'X-PAYPAL-SECURITY-PASSWORD' : api_password,
'X-PAYPAL-SECURITY-SIGNATURE' : api_sig}
data = 'USER=' + api_username + '&PWD=' + api_password + '&SIGNATURE=' + api_sig + '&METHOD=' + \
'TransactionSearch' + '&STARTDATE=' + start_datetime + '&ENDDATE=' + end_datetime + \
'&VERSION=94'
print data
req = requests.post(base+nvp_point, data=data)
return req.text
r = getTransactionHistory('2012-01-01T05:38:48Z', '2012-01-02T05:38:48Z')
The above code is correct. There was a '-' in my signature or password, which was not copy-pasted correctly. Solved.