How to define FOR loop in python - python-3.x

Please I need help here. In the code below, I want the FOR loop to loop through all the accounts with the associated API KEYs and SECRETs listed and send bitcoins from them to the recipient email address one after the other as long as their balance is greater than zero:
#!/data/data/com.termux/files/usr/bin/python3.8
from coinbase.wallet.client import Client
import json
api_key1 = '<key>'
api_secret1 = '<secret>'
api_key2 = '<key>'
api_secret2 = '<secret>'
api_key3 = '<key>'
api_secret3 = '<secret>'
api_key4 = '<key>'
api_secret4 = '<secret>'
api_key5 = '<key>'
api_secret5 = '<secret>'
client = Client(api_key, api_secret)
accounts = client.get_accounts()['data']
for account in accounts:
sending_currency = account['currency']
if float(account['balance']['amount']) > 0:
#Send to other account
sending_account = client.get_account(account['id'])
sending_amount = account['balance']['amount']
print('sending %s %s from SENDER_EMAIL_ADDRESS' %(sending_amount, sending_currency))
sending_account.send_money(to = 'RECEPIENT_EMAIL_ADDRESS', amount = sending_amount, currency = sending_currency)

In order to attain what you have described, I would use a list of dictionaries, this will also be iterable and hence usable in the for loop. in order to do this I'd rewrite your code as such :
#!/data/data/com.termux/files/usr/bin/python3.8
from coinbase.wallet.client import Client
import json
credentials = [
{'api_key':'<key1>', 'api_secret':'<secret1>'},
{'api_key':'<key2>', 'api_secret':'<secret2>'},
{'api_key':'<key3>', 'api_secret':'<secret3>'}
........
]
while True:
for credential in credentials:
client = Client(credential['api_key'], credential['api_secret'])
accounts = client.get_accounts()['data']
for account in accounts:
sending_currency = account['currency']
if float(account['balance']['amount']) > 0:
#Send to other account
sending_account = client.get_account(account['id'])
sending_amount = account['balance']['amount']
print('sending %s %s from SENDER_EMAIL_ADDRESS' %(sending_amount, sending_currency))
sending_account.send_money(to = 'RECEPIENT_EMAIL_ADDRESS', amount = sending_amount, currency = sending_currency)
else:
........

Related

Create sublist from list

I have following list named svc_tk_input
['4505/tcp', '4506/tcp', '80/tcp', '4505/udp', '4506/udp', '80/udp']
and i have following service so defined:
svc_a = [port_x/udp]
svc_b = [port_y/tcp]
svc_c = [port_x/udp, port_x/tcp]
svc_d = [port_x/tcp, port_x/udp]
svc_e = [port_y/udp, port_y/tcp]
svc_f = [port_y/tcp, port_y/udp]
svc_g = [port_x/tcp, port_y/tcp]
svc_h = [port_x/udp, port_y/udp]
svc_i = [port_y/tcp, port_x/tcp]
svc_l = [port_y/udp, port_x/udp]
svc_m = [port_x/tcp, port_y/udp]
svc_n = [port_x/udp, port_y/tcp]
svc_o = [port_y/tcp, port_x/udp]
svc_p = [port_y/udp, port_x/tcp]
Final target is to see if any service is defined given the port/protocol in svc_tk_input.
Idea:
create a second list svc_tk_input_mod
svc_tk_input_mod list has all combination of input port/protocol
svc_tk_input_mod = [('4505/tcp'), ('4505/udp'), ('4506/tcp'), ('4506/udp'),...,('4505/tcp' ,'4505/udp'), ('4505/tcp' ,'80/udp'),... ]
check at the end if any service is defined (out of scope here and this part is already covered)
I try to create the list svc_tk_input_mod by using itertools permutations but list that i get contains such combination
[('4505/tcp', '4506/tcp', '4505/udp', '4506/udp'), ('4505/tcp', '4506/tcp', '4506/udp', '4505/udp'), ('4505/tcp', '4505/udp', '4506/tcp', '4506/udp'), (...)]
As you can see each single element never can match the definition of service (service is a list of max 2 element)
Any suggestion on how can i improve the above?
Update here my code
list_protocols = str(policy_dict[term_name]["protocol"]).split(",") # (udp tcp)
list_ports = str(policy_dict[term_name][port_item]).split(",") # (53, 22, 1024-65535)
svc_tk_val_input = [ ]
svc_tk_val_input = build_svc_tk_val_input.build_svc_tk_val(list_protocols, list_ports,svc_tk_val_input)
svc_tk_val_input_permutation = [ ]
svc_tk_val_input_permutation = build_svc_tk_val_input.build_svc_tk_val_permutation(svc_tk_val_input, svc_tk_val_input_permutation)
svc_tk_val_input_permutation_2 = [ ]
if len(list_ports)>2:
svc_tk_val_input_permutation_2 =
build_svc_tk_val_input.build_svc_tk_val_permutation_with_len(svc_tk_val_input, svc_tk_val_input_permutation,2)
def build_svc_tk_val(list_protocols, list_ports,svc_tk_val_input):
for protocol in list_protocols:
for port in list_ports:
ppp_item = port+"/"+protocol
print(ppp_item)
# Token that we want
svc_tk_val_input.append(ppp_item)
return svc_tk_val_input
def build_svc_tk_val_permutation(svc_tk_val_input,svc_tk_val_input_permutation):
svc_tk_val_permutation = permutations(svc_tk_val_input)
for svc_tk_id_item_permutation in list(svc_tk_val_permutation):
#print(f"Combination {svc_tk_id_item_permutation}")
svc_tk_val_input_permutation.append(svc_tk_id_item_permutation)
return svc_tk_val_input_permutation
def build_svc_tk_val_permutation_with_len(svc_tk_val_input,svc_tk_val_input_permutation,permutation_len):
svc_tk_val_permutation = permutations(svc_tk_val_input,permutation_len)
for svc_tk_id_item_permutation in list(svc_tk_val_permutation):
#print(f"Combination {svc_tk_id_item_permutation}")
svc_tk_val_input_permutation.append(svc_tk_id_item_permutation)
return svc_tk_val_input_permutation

Send message from random date

I am trying to make my discord bot send a message from a random date in the server's history but the around argument doesn't seem to work properly
def random_date():
d1 = date(year=2020, month=3,day=16)
d2= date.today()
delta = d2 - d1
int_delta = delta.days
random_number_of_days = random.randrange(int_delta)
ran = random_number_of_days
global day
day = d1 + timedelta(ran)
# en = d1 + timedelta(ran + 1)
return day
#commands.command(name='quote')
async def quote(self,message):
day = random_date()
messages = await message.channel.history(around=day).flatten()
msg = random.choice(messages)
embed = discord.Embed(description=f'{msg.content}' , color=message.author.color, timestamp=msg.created_at)
embed.set_author(name=f"{msg.author.name}#{msg.author.discriminator}", icon_url=msg.author.avatar_url)
embed.add_field(name = 'Source' , value = f"[Jump]({msg.jump_url})")
embed.set_footer(text=f"Found in : #{message.channel.name}")
await message.channel.send(embed=embed)
See https://discordpy.readthedocs.io/en/latest/api.html?highlight=channel%20history#discord.TextChannel.history
You need to use datetime.datetime()
Also see: https://docs.python.org/3/library/datetime.html#datetime.datetime if you need help with that

Linkedin web scraping snippet

I'm doing a web scraping data university research project. I started working on a ready GitHub project, but this project does not retrieve all the data.
The project works like this:
Search Google using keywords: example: (accountant 'email me at' Google)
Extract a snippet.
Retrieve data from this snippet.
The issue is:
The snippets extracted are like this: " ... marketing division in 2009. For more information on career opportunities with our company, email me: vicki#productivedentist.com. Neighborhood Smiles, LLCĀ ..."
The snippet does not show all, the "..." hides information like role, location... How can I retrieve all the information with the script?
from googleapiclient.discovery import build #For using Google Custom Search Engine API
import datetime as dt #Importing system date for the naming of the output file.
import sys
from xlwt import Workbook #For working on xls file.
import re #For email search using regex.
if __name__ == '__main__':
# Create an output file name in the format "srch_res_yyyyMMdd_hhmmss.xls in output folder"
now_sfx = dt.datetime.now().strftime('%Y%m%d_%H%M%S')
output_dir = './output/'
output_fname = output_dir + 'srch_res_' + now_sfx + '.xls'
search_term = sys.argv[1]
num_requests = int(sys.argv[2])
my_api_key = "replace_with_you_api_key" #Read readme.md to know how to get you api key.
my_cse_id = "011658049436509675749:gkuaxghjf5u" #Google CSE which searches possible LinkedIn profile according to query.
service = build("customsearch", "v1", developerKey=my_api_key)
wb=Workbook()
sheet1 = wb.add_sheet(search_term[0:15])
wb.save(output_fname)
sheet1.write(0,0,'Name')
sheet1.write(0,1,'Profile Link')
sheet1.write(0,2,'Snippet')
sheet1.write(0,3,'Present Organisation')
sheet1.write(0,4,'Location')
sheet1.write(0,5,'Role')
sheet1.write(0,6,'Email')
sheet1.col(0).width = 256 * 20
sheet1.col(1).width = 256 * 50
sheet1.col(2).width = 256 * 100
sheet1.col(3).width = 256 * 20
sheet1.col(4).width = 256 * 20
sheet1.col(5).width = 256 * 50
sheet1.col(6).width = 256 * 50
wb.save(output_fname)
row = 1 #To insert the data in the next row.
#Function to perform google search.
def google_search(search_term, cse_id, start_val, **kwargs):
res = service.cse().list(q=search_term, cx=cse_id, start=start_val, **kwargs).execute()
return res
for i in range(0, num_requests):
# This is the offset from the beginning to start getting the results from
start_val = 1 + (i * 10)
# Make an HTTP request object
results = google_search(search_term,
my_cse_id,
start_val,
num=10 #num value can be 1 to 10. It will give the no. of results.
)
for profile in range (0, 10):
snippet = results['items'][profile]['snippet']
myList = [item for item in snippet.split('\n')]
newSnippet = ' '.join(myList)
contain = re.search(r'[\w\.-]+#[\w\.-]+', newSnippet)
if contain is not None:
title = results['items'][profile]['title']
link = results['items'][profile]['link']
org = "-NA-"
location = "-NA-"
role = "-NA-"
if 'person' in results['items'][profile]['pagemap']:
if 'org' in results['items'][profile]['pagemap']['person'][0]:
org = results['items'][profile]['pagemap']['person'][0]['org']
if 'location' in results['items'][profile]['pagemap']['person'][0]:
location = results['items'][profile]['pagemap']['person'][0]['location']
if 'role' in results['items'][profile]['pagemap']['person'][0]:
role = results['items'][profile]['pagemap']['person'][0]['role']
print(title[:-23])
sheet1.write(row,0,title[:-23])
sheet1.write(row,1,link)
sheet1.write(row,2,newSnippet)
sheet1.write(row,3,org)
sheet1.write(row,4,location)
sheet1.write(row,5,role)
sheet1.write(row,6,contain[0])
print('Wrote {} search result(s)...'.format(row))
wb.save(output_fname)
row = row + 1
print('Output file "{}" written.'.format(output_fname))

AWS Cognito 90 day automated Password rotation

I have a requirement to create an automated password reset script. I created a custom field in order to try and track this and also hope I can access some of the standard fields. This script should find users with the following criteria:
The latest of any of the following 3 dates that are >= 90 days ago : Sign_Up, Forgot_Password, or custom:pwdCreateDate
I can't seem to find any boto3 cognito client ways of getting the information on this except for forgot password which shows up in admin_list_user_auth_events and that response doesn't include username in the response. I suppose since you provide username to get the events you can figure out a way to find the latest forgot password from the events and tie it to the username.
Has anyone else implemented any boto3 automation to set the account to force password reset based on any of these fields?
here is where i landed, take it with the understanding that coginito has some limitations which make true flawless password rotation difficult. Also know if you can make the script more efficient you should because in lambda you probably time out with more than about 350 users due to the 5RPS on the admin API.
Prerequisites : set the lambda function to 5 concurrency or you will exceed the limit of 5RPS. 1 mutable field in your cognito userpool attributes to put a date in. a custom lambda zip file that includes pandas saved to s3.
import os
import sys
# this adds the parent directory of bin so we can find the module
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))
sys.path.append(parent_dir)
#This addes venv lib/python2.7/site-packages/ to the search path
mod_path = os.path.abspath(parent_dir+"/lib/python"+str(sys.version_info[0])+"."+str(sys.version_info[1])+"/site-packages/")
sys.path.append(mod_path)
import boto3
import datetime
import pandas as pd
import time
current_path = os.path.dirname(os.path.realpath(__file__))
# Use this one for the parent directory
ENV_ROOT = os.path.abspath(os.path.join(current_path, os.path.pardir))
# Use this one for the current directory
#ENV_ROOT = os.path.abspath(os.path.join(current_path))
sys.path.append(ENV_ROOT)
#if __name__ == "__main__":
def lambda_handler(event, context):
user_pool_id = os.environ['USER_POOL_ID']
idp_client = boto3.client('cognito-idp')
users_list = []
page_token = None
dateToday = datetime.datetime.today().date()
def update_user(user) :
idp_client.admin_update_user_attributes(
UserPoolId = user_pool_id,
Username = user,
UserStatus = 'RESET_REQUIRED',
UserAttributes = [
{
'Name': 'custom:pwdCreateDate',
'Value': str(dateToday)
}
]
)
users = idp_client.list_users(
UserPoolId = user_pool_id
)
for user in users['Users']: users_list.append(user['Username'])
page_token = users['PaginationToken']
while 'PaginationToken' in users :
users = idp_client.list_users(
UserPoolId = user_pool_id,
PaginationToken = page_token
)
for user in users["Users"]: users_list.append(user["Username"])
if 'PaginationToken' in users :
page_token = users['PaginationToken']
attrPwdDates = []
for i in range(len(users_list)) :
userAttributes = idp_client.admin_get_user(
UserPoolId = user_pool_id,
Username = users_list[i]
)
for a in userAttributes['UserAttributes'] :
if a['Name'] == 'custom:pwdCreateDate' :
attrPwdDates.append(datetime.datetime.strptime(a['Value'], '%Y-%m-%d %H:%M:%S.%f').date())
time.sleep(1.0)
list_of_userattr_tuples = list(zip(users_list, attrPwdDates))
df1 = pd.DataFrame(list_of_userattr_tuples,columns = ['Username','Password_Last_Set'])
authPwdDates = []
for i in range(len(users_list)) :
authEvents = idp_client.admin_list_user_auth_events(
UserPoolId = user_pool_id,
Username = users_list[i]
)
for event in authEvents['AuthEvents'] :
if event['EventType'] == 'ForgotPassword' and event['EventResponse'] == 'Pass' :
authPwdDates.append(event['CreationDate'].date())
break
time.sleep(1.0)
list_of_userauth_tuples = list(zip(users_list, authPwdDates))
df2 = pd.DataFrame(list_of_userauth_tuples,columns = ['Username','Password_Last_Forgot'])
df3 = df1.merge(df2,how='left', on = 'Username')
df3[['Password_Last_Set','Password_Last_Forgot']] = df3[['Password_Last_Set','Password_Last_Forgot']].apply(pd.to_datetime)
cols = ['Password_Last_Set','Password_Last_Forgot']
df4 = df3.loc[df3[cols].max(axis=1)<=pd.Timestamp.now() - pd.Timedelta(90, unit='d'), 'Username']
for i,r in df4.iterrows() :
update_user(r['Username'])

CoSign API: Sending SOAP from Python client generated by suds

I need to access the signing appliance from Python. To this end, using suds, I generated a Python client from the WSDL at https://cosigndemo.arx.com:8080/sapiws/dss.asmx?wsdl .
I then used the generated client to build a simple signature request which more or less does the same as shown in the Java example provided by ARX (only, I'm asking for an invisible signature).
The problem is that when I send the request to the demo appliance, here's what I receive in return:
(DssSignResult){
Result =
(Result){
ResultMajor = "urn:oasis:names:tc:dss:1.0:resultmajor:ResponderError"
ResultMinor = "urn:oasis:names:tc:dss:1.0:resultminor:GeneralError"
ResultMessage =
(ResultMessage){
value = "Exception occured"
_lang = "en"
}
}
}
Here's the Python code I wrote:
from suds.client import Client
from suds.plugin import MessagePlugin
from suds.sax.attribute import Attribute
import logging
class MyPlugin(MessagePlugin):
def marshalled(self, context):
foo = context.envelope.getChild('ns2:Body').getChild('ns0:DssSign').getChild('ns0:SignRequest').getChild('ns1:InputDocuments').getChild('ns1:Document')
foo[0].attributes.append(Attribute('MimeType', 'application/pdf'))
print context.envelope
url = 'https://cosigndemo.arx.com:8080/sapiws/dss.asmx?wsdl'
client = Client(url, plugins=[MyPlugin()])
cid = client.factory.create("ns4:ClaimedIdentity")
cid.Name = "John Miller"
cid.SupportingInfo.LogonPassword = "12345678"
sigReq = client.factory.create("ns4:RequestBaseType")
sigReq._RequestID = "DummyRequestId"
sigReq.OptionalInputs.ClaimedIdentity = cid
sigReq.OptionalInputs.SignatureType="http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign"
sigReq.OptionalInputs.SAPISigFieldSettings._Name = "SigField"
sigReq.OptionalInputs.SAPISigFieldSettings._Invisible = "true"
sigReq.OptionalInputs.SAPISigFieldSettings._DependencyMode = "Independent"
sigReq.OptionalInputs.SAPISigFieldSettings._SignatureType = "Digital"
sigReq.OptionalInputs.SAPISigFieldSettings._EmptyFieldLabel = ""
sigReq.OptionalInputs.SAPISigFieldSettings._Page = "1"
sigReq.OptionalInputs.ReturnPDFTailOnly = "true"
sigReq.OptionalInputs.IncludeObject=None
sigReq.OptionalInputs.SignaturePlacement=None
doc = client.factory.create("ns4:DocumentType")
doc.Base64Data = open("/Users/mar/CoSignWSDL/factures-comptat217.pdf", "rb").read().encode("base64")
sigReq.InputDocuments.Document = doc
result = client.service.DssSign(sigReq)
print result
And here's the SOAP that (at least I think) it is sending to the appliance:
<SOAP-ENV:Envelope xmlns:ns3="http://arx.com/SAPIWS/DSS/1.0" xmlns:ns0="http://arx.com/SAPIWS/DSS/1.0/" xmlns:ns1="urn:oasis:names:tc:dss:1.0:core:schema" xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns2:Body>
<ns0:DssSign>
<ns0:SignRequest RequestID="DummyRequestId">
<ns1:OptionalInputs>
<ns1:ClaimedIdentity>
<ns1:Name>John Miller</ns1:Name>
<ns1:SupportingInfo>
<ns3:LogonPassword>12345678</ns3:LogonPassword>
</ns1:SupportingInfo>
</ns1:ClaimedIdentity>
<ns1:SignatureType>http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign</ns1:SignatureType>
<ns1:SAPISigFieldSettings Name="SigField" DependencyMode="Independent" SignatureType="Digital" Page="1" Invisible="true"/>
<ns1:ReturnPDFTailOnly>true</ns1:ReturnPDFTailOnly>
</ns1:OptionalInputs>
<ns1:InputDocuments>
<ns1:Document>
<ns1:Base64Data MimeType="application/pdf">...</ns1:Base64Data>
</ns1:Document>
</ns1:InputDocuments>
</ns0:SignRequest>
</ns0:DssSign>
</ns2:Body>
</SOAP-ENV:Envelope>
Note that I replaced the (very long) Base64Data content with "..." here for space reasons.
Why is it not working?
Update Problem solved thanks to the answer. Here is the working code that adds a sig to a PDF:
from suds.client import Client
from suds.plugin import MessagePlugin
from suds.sax.attribute import Attribute
from suds.bindings import binding
import logging
import xml.dom.minidom as minidom
import base64
class MyPlugin(MessagePlugin):
def marshalled(self, context):
documentNode = context.envelope.getChild('ns3:Body').getChild('ns0:DssSign').getChild('ns0:SignRequest').getChild('ns1:InputDocuments').getChild('ns1:Document')
documentNode[0].attributes.append(Attribute('MimeType', 'application/pdf'))
SAPISigFieldSettingsNode = context.envelope.getChild('ns3:Body').getChild('ns0:DssSign').getChild('ns0:SignRequest').getChild('ns1:OptionalInputs').getChild('ns1:SAPISigFieldSettings')
SAPISigFieldSettingsNode.setPrefix('ns2')
ReturnPDFTailOnlyNode = context.envelope.getChild('ns3:Body').getChild('ns0:DssSign').getChild('ns0:SignRequest').getChild('ns1:OptionalInputs').getChild('ns1:ReturnPDFTailOnly')
ReturnPDFTailOnlyNode.setPrefix('ns2')
signRequestNode = context.envelope.getChild('ns3:Body').getChild('ns0:DssSign').getChild('ns0:SignRequest')
signRequestNode.setPrefix('ns1')
binding.envns = ('SOAP-ENV', 'http://www.w3.org/2003/05/soap-envelope')
url = 'https://cosigndemo.arx.com:8080/sapiws/dss.asmx?wsdl'
client = Client(url, plugins=[MyPlugin()])
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.plugin').setLevel(logging.DEBUG)
cid = client.factory.create("ns4:ClaimedIdentity")
cid.Name = "John Miller"
cid.SupportingInfo.LogonPassword = "12345678"
sigReq = client.factory.create("ns4:RequestBaseType")
sigReq._RequestID = "DummyRequestId"
sigReq.OptionalInputs.ClaimedIdentity = cid
sigReq.OptionalInputs.SignatureType="http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign"
sigReq.OptionalInputs.SAPISigFieldSettings._Name = "SigField"
sigReq.OptionalInputs.SAPISigFieldSettings._Invisible = "true"
sigReq.OptionalInputs.SAPISigFieldSettings._DependencyMode = "Independent"
sigReq.OptionalInputs.SAPISigFieldSettings._SignatureType = "Digital"
sigReq.OptionalInputs.SAPISigFieldSettings._EmptyFieldLabel = ""
sigReq.OptionalInputs.SAPISigFieldSettings._Page = "1"
sigReq.OptionalInputs.ReturnPDFTailOnly = "true"
sigReq.OptionalInputs.IncludeObject=None
sigReq.OptionalInputs.SignaturePlacement=None
doc = client.factory.create("ns4:DocumentType")
f = open('/Users/mar/CoSignWSDL/factures-comptat217.pdf', 'r+b')
doc.Base64Data = f.read().encode("base64")
sigReq.InputDocuments.Document = doc
result = client.service.DssSign(sigReq)
signature = base64.b64decode(result.SignatureObject.Base64Signature.value)
f.seek(0, 2) #go to the end of the file
f.write(signature)
f.close()
Your SOAP request is passing ns0:SignRequest Should be: ns1:SignRequest
Also Bear in mind that there is a missing part in your code--checking the appliance's SSL certificate. It is not a must, but generally required in order to verify that the response wasn't sent by a fraudulent entity.
In .Net and Java it is done automatically when accessing web service in HTTPS (based on Microsoft certificate Store and Java certificate Store)- but as far as I see there is no equivalent in Python.

Resources