Dronzil Dronzil - 3 months ago 14
Python Question

Python looping through file data and outputting

I have some code that I need to use to ingest a file containing emails, and interact with the 'haveibeenpwned' API to return dates of when they have been seen in public dumps.

So far this is what I have below and I am currently struggling with implementing the following:

1.) Each request must be delayed by 1 second, per the API usage guidelines.

2.) The script must take in a file which will contain the emails to be submitted (I tried invoking it with a for-loop on command line but that did not work).

3.) The email addresses submitted must be echoed to the output file for correlating with the breach data.

Essentially I am looking to run the script, supply an input file (probably with argparse) and then have the script output the following example contents to a file, being appended as it runs through the supplied list of emails...


email1@email.com

DATA - Breached on xxxx-xx-xx

email2@email.com

DATA - Breached on xxxx-xx-xx


Any help or suggestions with the required changes would be much appreciated. You can see its current functionality by running it with '-a' and supplying an email address.

import argparse
import json
import requests


def accCheck(acc):
r = requests.get(
'https://haveibeenpwned.com/api/v2/breachedaccount/%s?truncateResponse=false' % acc
)
data = json.loads(r.text)
for i in data:
print(
i['Name'] +
' - Breached on ' +
i['BreachDate']
)

def list():
r = requests.get(
'https://haveibeenpwned.com/api/v2/breaches'
)
data = json.loads(r.text)
for i in data:
print(
i['Name'] +
' - Breached on - ' +
i['BreachDate']
)

if __name__ == '__main__':
ap = argparse.ArgumentParser()
ap.add_argument(
'-a',
'--account'
)
ap.add_argument(
'--list',
action='store_true'
)
args = ap.parse_args()
acc = args.account
list = args.list
if not list:
if not acc:
print(
'Specify an account (-a <email>) to check or --list for site info'
)
exit(0)
try:
accCheck(acc)
except ValueError:
print(
'No breach data found'
)
else:
list()

Answer Source

You could accept the input file and output file as command line arguments like this:

ap.add_argument(
    '-if',
    '--input_file'
    )

ap.add_argument(
    '-of',
    '--ouput_file'
    )
args = ap.parse_args()

input_file = args.input_file

ouput_file = args.ouput_file

Assuming that the file you specified as your input file contains an email account on each line , you could do the following :

with open(input_file,'r') as fl,RedirectStdoutTo(ouput_file):
        for acc in fl:
            try:
                accCheck(acc.rstrip())
            except ValueError:
                print(
                    'No breach data found'
                )

RedirectStdoutTo is a class you would write to allow you to redirect your print output to a file

class RedirectStdoutTo:
    def __init__(self, filename):
        self.out_new = open(filename,'w')

    def __enter__(self):
        self.out_old = sys.stdout
        sys.stdout = self.out_new

    def __exit__(self, *args):
        sys.stdout = self.out_old
        self.out_new.close()