KeyError: 'name' abi error on web3 Python - python

I'm trying to buy tokens using the swapExactTokensForTokens() Pancakeswap Router function), web3 imported in Python.
Problem 1: I keep getting an abi KeyError: 'name'. Here's my code and error below. I'm not sure how to handle this error.
problem 2: Is it possible to call the abi of a token without hardcoding it like I did below?
Code:
from web3 import Web3
import json
import key
import time
bsc = "https://bsc-dataseed.binance.org/"
web3 = Web3(Web3.HTTPProvider(bsc))
print(web3.isConnected())
print("Block Number: ", web3.eth.blockNumber)
#My wallet address
sender_address = '0x111111111111111111111111111111111111'
#Pancakeswap router address instantiate and ABI code
panRouterContractAddress = '0x10ED43C718714eb63d5aA57B78B54704E256024E'
panAbi = '[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"amountOut"}]'
contract = web3.eth.contract(address=panRouterContractAddress, abi=panAbi)
#Spend token instantiate and ABI
tokenToSpend = web3.toChecksumAddress("0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56") #Contract address for purchase currency (BUSD)
spendAbi = '[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"_decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]'
spendTokenContract = web3.eth.contract(tokenToSpend, abi=spendAbi) #Spend token instance
#Contract address of token and amount to purchase
tokenToBuy = web3.toChecksumAddress(input("Enter Token Address to buy: "))
#Input contract address for the token to purchase
amountIn = web3.toWei(input("How much to spend? "), 'ether')
#Amount of purchase currency to spend
#Trade execution (To accomodate fees, use the function: swapExactTokensForTokensSupportingFeeOnTransferTokens)
pancakeswap2_txn = contract.functions.swapExactTokensForTokens(amountIn, 0, [tokenToSpend,tokenToBuy], sender_address, (int(time.time()) + 1000000)).buildTransaction({
'from': sender_address,
'value': amountIn,
'gas': 250000,
'gasPrice': web3.toWei('5','gwei'),
'nonce': web3.eth.get_transaction_count(sender_address),
})
signed_txn = web3.eth.account.sign_transaction(pancakeswap2_txn, private_key=key.private)
tx_token = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
print("Success!: " + web3.toHex(tx_token))
Error:
True
Block Number: 9762322
Enter Token Address to buy: 0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82
How much BUSD to spend? 1
Traceback (most recent call last):
File "c:/Users/Owner/Documents/BlockchainPy/MyCodes/test.py", line 30, in <module>
pancakeswap2_txn = contract.functions.swapExactTokensForTokens(amountIn, 0, [tokenToSpend,tokenToBuy], sender_address, (int(time.time()) + 1000000)).buildTransaction({
File "C:\Users\Owner\Documents\BlockchainPy\lib\sitepackages\web3\contract.py", line 876, in __call__clone._set_function_info()
File "C:\Users\Owner\Documents\BlockchainPy\lib\sitepackages\web3\contract.py", line 881, in _set_function_info
self.abi = find_matching_fn_abi(
File "C:\Users\Owner\Documents\BlockchainPy\lib\site-packages\web3\_utils\contracts.py", line 127, in find_matching_fn_abi
function_candidates = pipe(abi, name_filter, arg_count_filter, encoding_filter)
File "cytoolz/functoolz.pyx", line 667, in cytoolz.functoolz.pipe
return c_pipe(data, funcs)
File "cytoolz/functoolz.pyx", line 642, in cytoolz.functoolz.c_pipe
data = func(data)
File "C:\Users\Owner\Documents\BlockchainPy\lib\site-packages\web3\_utils\abi.py", line 93, in filter_by_name
return [
File "C:\Users\Owner\Documents\BlockchainPy\lib\sitepackages\web3\_utils\abi.py", line 99, in <listcomp> and abi['name'] == name
KeyError: 'name'

Error shows problem in line 99 in file abi.py with key abi["name"] so I found this file (you have full path in error) and add print() before line 99 to see all abi used in this place
def filter_by_name(name: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
for abi in contract_abi:
print(abi)
print('---')
# ... rest ...
and it shows me
{'stateMutability': 'payable', 'type': 'amountOut'}
which doesn't have "name": ... and this makes problem.
If you check panAbi = ... then you see this {'stateMutability': ...} at the end.
If I add ie."name": "" in this {'stateMutability': ...} in panAbi then it resolves problem but I don't know what real name it should have.

Problem 2: in general, you don't need to know any ABI, you can ask bscscan to return it for you.
This is the code (use the switch DEBUG to select between testnet and mainnet).
Set your BSC API key in place of bscAPIkey
import requests
import json
def GetABI (Address):
if DEBUG:
url_eth = "https://api-testnet.bscscan.com/api"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36'} # This is chrome, you can set whatever browser you like
API_ENDPOINT = url_eth+"?module=contract&action=getabi&address="+str(Address)+"&apikey="+bscAPIkey
resp = requests.get(url = API_ENDPOINT, headers=headers)
else:
url_eth = "https://api.bscscan.com/api"
API_ENDPOINT = url_eth+"?module=contract&action=getabi&address="+str(Address)+"&apikey="+bscAPIkey
resp = requests.get(url = API_ENDPOINT)
res = json.loads(resp.text)
status = int(res['status'])
if status:
response = resp.json()
abi=json.loads(response["result"])
return abi
else:
return False

Here's how i fix it:
contract_abi = json.loads('[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_WETH","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"WETH","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"amountB","internalType":"uint256"},{"type":"uint256","name":"liquidity","internalType":"uint256"}],"name":"addLiquidity","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"},{"type":"uint256","name":"amountADesired","internalType":"uint256"},{"type":"uint256","name":"amountBDesired","internalType":"uint256"},{"type":"uint256","name":"amountAMin","internalType":"uint256"},{"type":"uint256","name":"amountBMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"amountToken","internalType":"uint256"},{"type":"uint256","name":"amountETH","internalType":"uint256"},{"type":"uint256","name":"liquidity","internalType":"uint256"}],"name":"addLiquidityETH","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amountTokenDesired","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"factory","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"}],"name":"getAmountIn","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint256","name":"reserveIn","internalType":"uint256"},{"type":"uint256","name":"reserveOut","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"}],"name":"getAmountOut","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"reserveIn","internalType":"uint256"},{"type":"uint256","name":"reserveOut","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"getAmountsIn","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"getAmountsOut","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"amountB","internalType":"uint256"}],"name":"quote","inputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"reserveA","internalType":"uint256"},{"type":"uint256","name":"reserveB","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"amountB","internalType":"uint256"}],"name":"removeLiquidity","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountAMin","internalType":"uint256"},{"type":"uint256","name":"amountBMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountToken","internalType":"uint256"},{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETH","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountToken","internalType":"uint256"},{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETHWithPermit","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"bool","name":"approveMax","internalType":"bool"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"bool","name":"approveMax","internalType":"bool"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"amountB","internalType":"uint256"}],"name":"removeLiquidityWithPermit","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountAMin","internalType":"uint256"},{"type":"uint256","name":"amountBMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"bool","name":"approveMax","internalType":"bool"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapETHForExactTokens","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapExactETHForTokens","inputs":[{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","inputs":[{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapExactTokensForETH","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapExactTokensForTokens","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapTokensForExactETH","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint256","name":"amountInMax","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapTokensForExactTokens","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint256","name":"amountInMax","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"receive","stateMutability":"payable"}]')
# Every entry in ABI must have "name" attribute! Otherwise web3.py will fail when you call contract.functions.swapExactETHForTokens(1, [my_wallet_address], my_wallet_address, deadline)
i : int = 0
for entry in contract_abi:
if 'name' not in entry:
entry['name'] = f"dummy_name_{i}"
i = i+1

Related

f-string in Python with the atlassian-python package. Gives bad request

I'm trying to fetch all issues in JIRA for all projects. When doing the call one at a time, it works perfect. When trying to run it in a for loop I'm prompted with a 400 Client error.
The way that works:
results = jira_instance.jql("project = FJA", limit = 100, fields=["issuetype", "status", "summary"])
The way that does not work:
projects = ["ADV", "WS", "FJA", "FOIJ", "QW", "UOI"]
for key in projects:
results = jira_instance.jql(f"project = {key})", limit = 100, fields=["issuetype", "status", "summary"])
The error:
Traceback (most recent call last):
File "C:\jira-api-python\jira.py", line 24, in <module>
results = jira_instance.jql("project = {key}", limit = 100, fields=["issuetype", "status", "summary"])
File "C:\.virtualenvs\jira-api-python-rouJrYa4\lib\site-packages\atlassian\jira.py", line 2271, in jql
return self.get("rest/api/2/search", params=params)
File "C:\.virtualenvs\jira-api-python-rouJrYa4\lib\site-packages\atlassian\rest_client.py", line 264, in get
response = self.request(
File "C:\.virtualenvs\jira-api-python-rouJrYa4\lib\site-packages\atlassian\rest_client.py", line 236, in request
response.raise_for_status()
File "C:\.virtualenvs\jira-api-python-rouJrYa4\lib\site-packages\requests\models.py", line 943, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://stuff.atlassian.net/rest/api/2/search?startAt=0&maxResults=100&fields=issuetype%2Cstatus%2Csummary&jql=project+%3D+%7Bkey%7D
My guess is that I'm not using the f-string correct. But when I print the value of {key} it is correct.
Any pointers would be greatly appreciated.
Thank you for your time.
Edit:
Added the full traceback, only removed the path to my machine and changed the URL to the endpoint. Below is the full file with credentials and endpoint redacted. The ideas is to create a csv for each project.
The full code:
from atlassian import Jira
import pandas as pd
import time
jira_instance = Jira(
url = "https://stuff.atlassian.net/",
username = "user",
password = "pass",
)
projects = ["ADV", "WS", "FJA", "FOIJ", "QW", "UOI"]
FIELDS_OF_INTEREST = ["key", "fields.summary", "fields.status.name"]
timestamp = time.strftime("%Y%m%d-%H%M%S")
file_ending = ".csv"
for key in projects:
print(f"stuff = {key}")
results = jira_instance.jql(f"project = {key})", limit = 1000, fields=["issuetype", "status", "summary"])
I found the very simple solution.
In this snippet: results = jira_instance.jql(f"project = {key})", limit = 1000, fields=["issuetype", "status", "summary"])
The ) after {key} was not supposed to be there.
Thank you for the help

I don't know what happens in my ThreadPoolExecutor

I am trying to create an automation to register hosts in Zabbix through its API asynchronously using concurrent.futures.ThreadPoolExecutor as you can see in this piece of code:
def zabbix_create_host(name, ip):
session = get_session()
token = get_token()
print(" "+name+" "+ip)
headers = {'Content-type': 'application/json'}
data = '{"jsonrpc": "2.0","method": "host.create","params": {"host": "'+name+'","interfaces": [{"type": 2,"main": 1,"useip": 1,"ip": "'+ip+'","dns": "","port": "10050"}],"groups": [{"groupid": "5"}],"templates": [],"macros": [{"macro": "{$USER_ID}","value": "123321"}],"inventory_mode": 0,"inventory": {"macaddress_a": "01234","macaddress_b": "56768"}},"auth": "'+token+'","id": 1}'
response = requests.post('http://127.0.0.1/api_jsonrpc.php', headers=headers, data=data)
response = response.json()
def zabbix_create_host_multiple(names, ips):
with concurrent.futures.ThreadPoolExecutor(max_workers=12) as executor:
df = pd.concat(executor,map(zabbix_create_host, names, ips))
return df
NAMES = ['PC1', 'PC2', 'PC3']
IPS = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
zabbix_create_host_multiple(NAMES, IPS)
But when executing the code I get the following error:
File "main.py", line 159, in zabbix_create_hosts
zabbix_create_host_multiple(names, ips)
File "main.py", line 173, in zabbix_create_host_multiple
df = pd.concat(executor,map(zabbix_create_host, names, ips))
File "/home/sacarino/anaconda3/envs/aZabbix/lib/python3.8/site-packages/pandas/core/reshape/concat.py", line 274, in concat
op = _Concatenator(
File "/home/sacarino/anaconda3/envs/aZabbix/lib/python3.8/site-packages/pandas/core/reshape/concat.py", line 328, in __init__
objs = list(objs)
TypeError: 'ThreadPoolExecutor' object is not iterable
Let's see if you can help me, it's the first time I've worked with this
def zabbix_create_host(name, ip):
session = get_session()
token = get_token()
print(" "+name+" "+ip)
headers = {'Content-type': 'application/json'}
data = '{"jsonrpc": "2.0","method": "host.create","params": {"host": "'+name+'","interfaces": [{"type": 2,"main": 1,"useip": 1,"ip": "'+ip+'","dns": "","port": "10050"}],"groups": [{"groupid": "5"}],"templates": [],"macros": [{"macro": "{$USER_ID}","value": "123321"}],"inventory_mode": 0,"inventory": {"macaddress_a": "01234","macaddress_b": "56768"}},"auth": "'+token+'","id": 1}'
response = requests.post('http://127.0.0.1/api_jsonrpc.php', headers=headers, data=data)
response = response.json()
return pd.Series(response)
def zabbix_create_host_multiple(names, ips):
df = pd.DataFrame()
with concurrent.futures.ThreadPoolExecutor(max_workers=12) as executor:
df = df.append(list(map(zabbix_create_host, names, ips)))
return df
NAMES = ['PC1', 'PC2', 'PC3']
IPS = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
zabbix_create_host_multiple(NAMES, IPS)
returning the response in terms of series and appending it to the dataframe

Error when requesting to transfer/send on coinbase api

I am trying to post a transfer to the coinbase api from one crypto account to another, but just cannot seem to make it happen. The error occurs at the bottom of my code when I attempt a transfer 2 times. The first time, it comes back with "{}", and the second it comes back with the traceback error.
Here is my code:
import hmac, hashlib, time, requests, os
from requests.auth import AuthBase
from coinbase.wallet.client import Client
API_KEY = os.environ.get('API_KEY')
API_SECRET = os.environ.get('API_SECRET')
xrp_acct_id = os.environ.get('XRP_ID')
usdc_acct_id = os.environ.get('USDC_ID')
xrp_destination_tag = os.environ.get('xrp_destination_tag')
xtz_acct_id = os.environ.get('XTZ_ID')
user_id = os.environ.get('Coinbase_User_Id')
# Create custom authentication for Coinbase API
class CoinbaseWalletAuth(AuthBase):
def __init__(self, api_key, secret_key):
self.api_key = api_key
self.secret_key = secret_key
def __call__(self, request):
timestamp = str(int(time.time()))
message = timestamp + request.method + request.path_url + (request.body or b'').decode()
signature = hmac.new(bytes(self.secret_key, 'utf-8'), message.encode('utf-8'), hashlib.sha256).hexdigest()
request.headers.update({
'CB-ACCESS-SIGN': signature,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': self.api_key,
'CB-VERSION': '2020-01-18'
})
return request
api_url = 'https://api.coinbase.com/v2/'
auth = CoinbaseWalletAuth(API_KEY, API_SECRET)
client = Client(API_KEY, API_SECRET)
# Get current user:
# r_user = requests.get(api_url + 'user', auth=auth)
# print(r_user.json())
# Get transactions:
# xrp_txs = client.get_transactions(xrp_acct_id)
# Get accounts:
r = requests.get(api_url + 'accounts', auth=auth)
# Get price (XRP-USD):
price = client.get_spot_price(currency_pair='XRP-USD')
# To parse the JSON
accounts_json = r.json()
#
# # Variable to figure out wallet balances
XRP_balance = 0.0
# Dictionary used to store balances and wallet name's
accounts = {}
# Loop to get balances
for i in range(0, len(accounts_json["data"])):
wallet = accounts_json["data"][i]["name"]
amount = accounts_json["data"][i]["balance"]["amount"]
# Switch statement to figure out which index which wallet is
if wallet == "XRP Wallet":
XRP_balance = float(amount) * float(price["amount"])
accounts["XRP_USD"] = XRP_balance
elif wallet == "USDC Wallet":
USDC_amount = amount
accounts["USDC"] = USDC_amount
else:
print()
print(accounts)
txs = {
'type': 'transfer',
'account_id': usdc_acct_id,
'to': xrp_acct_id,
'amount': '10',
'currency': 'USDC'
}
r = requests.post(api_url + 'accounts/' + usdc_acct_id + '/transactions', json=txs, auth=auth)
print(r.json())
###### OUTPUT FROM THIS IS "{}" ##############
tx = client.transfer_money(account_id=usdc_acct_id,
to=xtz_acct_id,
amount='10',
fee='0.99',
currency='USDC')
###### OUTPUT FROM THIS IS "Traceback error" See Below ##############
txs = {
'type': 'send',
'to': xrp_address["address"],
'destination_tag': xrp_destination_tag,
'amount': '10',
'currency': 'XRP'
}
r = requests.post(api_url + 'accounts/' + xtz_acct_id + '/transactions', json=txs, auth=auth)
print(r)
print(r.json())
########## THIS OUTPUT IS FROM AFTER TRACEBACK ERROR ################
Here is the entire output:
{'USDC': '100.000000', 'XRP_USD': 571.5256683544001}
{}
Traceback (most recent call last):
File "/Users/mattaertker/Documents/CryptoExchangeProgram/exchangeMyCurrency.py", line 97, in <module>
tx = client.transfer_money(account_id=usdc_acct_id,
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coinbase/wallet/client.py", line 339, in transfer_money
response = self._post('accounts', account_id, 'transactions', data=params)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coinbase/wallet/client.py", line 132, in _post
return self._request('post', *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coinbase/wallet/client.py", line 116, in _request
return self._handle_response(response)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coinbase/wallet/client.py", line 125, in _handle_response
raise build_api_error(response)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coinbase/wallet/error.py", line 49, in build_api_error
blob = blob or response.json()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/requests/models.py", line 898, in json
return complexjson.loads(self.text, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
<Response [400]>
{'errors': [{'id': 'validation_error', 'message': 'Please enter a valid email or Tezos address', 'field': 'base'}]}
But hey, at least I can send money from my tezos account to my tezos account:
txs = {
'type': 'send',
'to': xtz_address["address"],
'destination_tag': xrp_destination_tag,
'amount': '10',
'currency': 'XRP'
}
r = requests.post(api_url + 'accounts/' + xtz_acct_id + '/transactions', json=txs, auth=auth)
print(r)
OUTPUT:
<Response [201]>
I check my tezos account, and of course because response is 201, it did send it to itself. I recently found out it doesn't do this when you don't have destination_tag specified, but still BUG!!
If you want to convert your crypto from one currency to another, you don't have to use transfer_money. Watching Coinbase API from webapp that are the endpoints you need to call:
Have to know base_id of crypto that you want to sell and base_id of crypto want to buy. You can know it by calling GET "https://api.coinbase.com/v2/ /assets/prices?base=USD&filter=holdable&resolution=latest" and get from response the "base_id" of your currencies.
Make an order by calling POST "https://api.coinbase.com/v2/trade" with a request body in json like this: { 'amount': [amount that you want to convert], 'amount_asset': [currency of amount that you want to convert], 'amount_from': 'input', 'source_asset': ["base_id" of crypto that you want to sell], 'target_asset': ["base_id" of crypto that you want to buy] }
If previous POST "/trade" response code is 201, you have to get the
"id" value of response's json and do a commit of your order by
calling POST "https://api.coinbase.com/v2/trades/[id of json response of previous https://api.coinbase.com/v2/trade POST"]/commit. If
the response code of this POST commit is 201, your exchange is
started and if there are not error in coinbase, your conversion is
done!

TypeError: Unicode-objects must be encoded before hashing in python for azure iot hub

I'm trying to upload some data from rasberry pi to azure iot hub, I'm facing this problem,Where do I need to set the encoding/charsets?
I've tried data.encode('utf-8') something like that but not working.
Might be someone asked, please help me with this specific code.
I'm following this link.
def generate_sas_token():
expiry=3600
ttl = time.time() + expiry
sign_key = "%s\n%d" % ((quote_plus(URI)), int(ttl))
signature = b64encode(HMAC(b64decode(KEY), sign_key, sha256).digest())
rawtoken = {
'sr' : URI,
'sig': signature,
'se' : str(int(ttl))
}
rawtoken['skn'] = POLICY
return 'SharedAccessSignature ' + urlencode(rawtoken)
def send_message(token, message):
url = 'https://{0}/devices/{1}/messages/events?api-version=2016-11-14'.format(URI, IOT_DEVICE_ID)
headers = {
"Content-Type": "application/json",
"Authorization": token
}
data = json.dumps(message)
print(data)
#data.encode('utf-8')
response = requests.post(url, data=data, headers=headers)
if __name__ == '__main__':
# 2. Generate SAS Token
token = generate_sas_token()
# 3. Send Temperature to IoT Hub
while True:
#temp = read_temp()
message = { "temp": str("12") }
send_message(token, message)
time.sleep(1)
And the error is
Traceback (most recent call last):
File "/home/pi/python/test.py", line 45, in <module>
token = generate_sas_token()
File "/home/pi/python/test.py", line 20, in generate_sas_token
signature = b64encode(HMAC(b64decode(KEY), sign_key, sha256).digest())
File "/usr/lib/python3.5/hmac.py", line 84, in __init__
self.update(msg)
File "/usr/lib/python3.5/hmac.py", line 93, in update
self.inner.update(msg)
TypeError: Unicode-objects must be encoded before hashing
The error tells you must encode before creating your HMAC object. It seems you are decoding it first :
HMAC(b64decode(KEY), sign_key, sha256)
A possible solution could be:
HMAC(b64decode(KEY), sign_key.encode('utf-8'), sha256)

Global variables in python causing UnboundLocalError

I keep getting the following error message whenever I run my code:
Attempting to parse Socialblade: https://socialblade.com/youtube/user/aantonop
Got no_of_videos: 325
Internal Server Error: /api/connect_youtube/
Traceback (most recent call last):
File "/Users/test/projects/my-api/api/views.py", line 160, in post
response.update(scraper.collect_creator_data(request.data['youtubeChannelUsername']))
File "/Users/test/projects/my-api/api/scraper.py", line 23, in collect_creator_data
process_socialblade(username)
File "/Users/test/projects/my-api/api/scraper.py", line 68, in process_socialblade
if no_of_subscribers:
UnboundLocalError: local variable 'no_of_subscribers' referenced before assignment
I suspect its due to the use of global variables in my script but not sure how to rectify it. I have set up the global variables to be processed by multiple methods.
How do I fix it? Code below:
from bs4 import BeautifulSoup
from test.settings.base import YOUTUBE_URL, YOUTUBE_API_KEY
from urllib.request import Request, urlopen
import ssl
no_of_videos = 0
no_of_subscribers = 0
no_of_views = 0
avg_views = 0
like_count = 0
dislike_count = 0
channel_id = None
photo = None
description = None
start_date = None
title = None
keywords = None
sb_grade = None
def collect_creator_data(username):
process_socialblade(username)
process_youtube(username)
return {"id": channel_id,
"photo": photo,
"title": title,
"like_count": like_count,
"dislike_count": dislike_count,
"keywords": keywords,
"description": description,
"start_date": start_date,
"no_of_videos": no_of_videos,
"no_of_subscribers": no_of_subscribers,
"no_of_views": no_of_views,
"avg_views": avg_views,
"sb_grade": sb_grade
}
def process_socialblade(username):
socialblade_user_url = 'https://socialblade.com/youtube/user/' + username
context = ssl._create_unverified_context()
print('Attempting to parse Socialblade:', socialblade_user_url)
q = Request(socialblade_user_url)
q.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) '
'Chrome/23.0.1271.64 Safari/537.11')
q.add_header('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
q.add_header('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.3')
q.add_header('Accept-Encoding', 'none')
q.add_header('Accept-Language', 'en-US,en;q=0.8')
q.add_header('Connection', 'keep-alive')
socialblade_user_html = urlopen(q, context=context).read()
if socialblade_user_html:
soup = BeautifulSoup(socialblade_user_html, "html.parser")
youtube_user_top_info_list = soup.findAll('div', attrs={'class': 'YouTubeUserTopInfo'})
for i in youtube_user_top_info_list:
try:
no_of_videos = i.find('span', id='youtube-stats-header-uploads').get_text()
except AttributeError:
pass
if no_of_videos:
print('Got no_of_videos:', no_of_videos)
try:
no_of_subscribers = i.find('span', id='youtube-stats-header-subs').get_text()
except AttributeError:
pass
if no_of_subscribers:
print('Got no_of_subscribers:', no_of_subscribers)
try:
no_of_views = i.find('span', id='youtube-stats-header-views').get_text()
except AttributeError:
pass
if no_of_views:
print('Got no_of_views:', no_of_views)
else:
print('Could not parse Socialblade:', socialblade_user_html)
Should I create global variables in process_socialblade?

Categories