Python Fabric load config from separate file - python

I am use python fabric with all configuration in one .fab file.
How can I put sensitive data as password to separate file and then import/load to fab main file?

Define a simple function within your fabfile.py to read your passwords out of a separate file. Something along the lines of:
def new_getpass(username):
with open("/etc/passwd", "r") as f:
for entry in [l.split(":") for l in f.readlines()]:
if entry[0] == username:
return entry
return None
This will return None in the event that the username cannot be found and the entire user's record as a list in the event the user is found.
Obviously my example is getting its data from /etc/passwd but you can easily adapt this basic functionality to your own file:
credentials.dat
database1|abcd1234
database2|zyxw0987
And then the above code modified to use this file like this, with the slight variation to return only the password (since we know the database name):
def getpass(database):
with open("credentials.dat", "r") as f:
for entry in [l.split("|") for l in f.readlines()]:
if entry[0] == username:
return entry[1]
return None
While not as simple as an import, it provides you flexibility to be able to use plaintext files to store your credentials in.

Related

Storing data in .txt file and retrieving it

I was trying to make some sort of login system,
I have it so that if a username and password are in test.txt (there is multiple ones) it should let you login, I haven't even passed the step of verifying if the username and password are in the txt file and its destroying me, I don't know how to do it and I tried for hours, I made it so "if you find this username in the text file, give me the line number and check if the password this password is in the same line of the username ,(I used split (',')) , if both email and password entered are existent in the txt file and in the same line then..(didn't do that yet).
so it is confusing me, lots of errors, if no errors then it isn't working like I intended, here is my spaghetti code
def test():
with open('test.txt', 'r') as f:
for num, line in enumerate(f,1):
username = line.split(',')
if username in num:
if username == q1:
print("found user in line: " + num)
Line = num
password = line.split(',')
if password in Line:
if password == q2:
print("found pass in line: " + num)
can someone help me fix this and explain to me how storing data in .txt files work and how to retrieve them? YouTube and google didn't help much really, if you can suggest a video that will be cool too, because I'm confused at this point, all I have left is to try MongoDB because it has functions to retrieve data and store it already built in
but as its local on my pc not on the internet, I don't think I will need MongoDB, so that will be an overkill for a local test
With json, you can get it done this way:
JSON File
{
"user1":{"password":"123456"},
"user2":{"password": "abcde"}
}
Python
import json
def test(username, password):
with open("answer.json", "r") as read_it:
data = json.load(read_it)
if data[username][password] == '123456':
print('User found!')
else:
print('User or password doesn\'t exist')
test('user1', 'password')
If you want to use a text file, then as a simple example:
cat test.txt
aklaver, dog
adrian, cat
alklaver, fish
user_name = 'aklaver'
with open('test.txt', 'r') as pwd_file:
lines = pwd_file.readlines()
for line in lines:
user, pwd = line.split(',')
if user == user_name:
print(pwd)
dog

How do I add to a list in a file while also being able to be written to?

I'm trying to do something along the lines of this: I need a way to set up a file and be able to add to a value to it each time the command is used.
All the file format will be this:
{} | {}.format(user.id, list_items)
I don't want list_items to be overwritten. I want them as a list and be able to added to.
Full Code:
with open('test2.txt', 'a+') as f:
newf = new_list_file.png
user.id = message.id
list_files = file.name
f.readlines()
if user.id in f:
f.write(newf)
else:
f.write('{} | [{}]'.format(user.id, newf)
When each new person that uses this command, it will add them in my registry and what file they uploaded. I need the list updated without rewriting the list. Hence why the if statement is there.

Deleting usernames and not via password in a text file

Guest = {}
with open('LogIn.txt') as f:
credentials = [x.strip().split(':') for x in f.readlines()]
for username,password in credentials:
Guest[username] = password
def DelUser():
DB = open('LogIn.txt',"r+")
username = DB.read()
delete = raw_input("Input username to delete: ")
if delete in username:
<insert code to remove line containing username:password combination>
So, I have a LogIn.txt file with the following username:password combinations:
chris:test
char:coal
yeah:men
test:test
harhar:lololol
I want to delete the username:password combination that I want to in the object "delete"
But the problem is, if I use the
if delete in username:
argument, it'll have to consider the password as well. and example, what if I have two accounts with the same password? Or like the one above. What path can I take for this one? Or am I missing something here?
According to your current DelUser function, you can read the file, remove the line that start with the user to delete, and write a new one:
def DelUser():
# read the current files, and get one line per user/password
with open('LogIn.txt',"r+") as fd:
lines = fd.readlines()
# ask the user which one he want to delete
delete = raw_input("Input username to delete: ")
# filter the lines without the line starting by the "user:"
lines = [x for x in lines if not x.startswith('%s:' % delete)]
# write the final file
with open('LogIn.txt', 'w') as fd:
fd.writelines(lines)
Use
if delete in Guest:
to test if delete is a key in Guest. Since the keys of Guest represent usernames, if delete in Guest tests if delete is a username.
You could use the fileinput module to rewrite the file "inplace":
import fileinput
import sys
def DelUser(Guest):
delete = raw_input("Input username to delete: ")
for line in fileinput.input(['LogIn.txt'], inplace = True, backup = '.bak'):
if delete not in Guest:
sys.stdout.write(line)

process large text file in python

I have a very large file (3.8G) that is an extract of users from a system at my school. I need to reprocess that file so that it just contains their ID and email address, comma separated.
I have very little experience with this and would like to use it as a learning exercise for Python.
The file has entries that look like this:
dn: uid=123456789012345,ou=Students,o=system.edu,o=system
LoginId: 0099886
mail: fflintstone#system.edu
dn: uid=543210987654321,ou=Students,o=system.edu,o=system
LoginId: 0083156
mail: brubble#system.edu
I am trying to get a file that looks like:
0099886,fflintstone#system.edu
0083156,brubble#system.edu
Any tips or code?
That actually looks like an LDIF file to me. The python-ldap library has a pure-Python LDIF handling library that could help if your file possesses some of the nasty gotchas possible in LDIF, e.g. Base64-encoded values, entry folding, etc.
You could use it like so:
import csv
import ldif
class ParseRecords(ldif.LDIFParser):
def __init__(self, csv_writer):
self.csv_writer = csv_writer
def handle(self, dn, entry):
self.csv_writer.writerow([entry['LoginId'], entry['mail']])
with open('/path/to/large_file') as input, with open('output_file', 'wb') as output:
csv_writer = csv.writer(output)
csv_writer.writerow(['LoginId', 'Mail'])
ParseRecords(input, csv_writer).parse()
Edit
So to extract from a live LDAP directory, using the python-ldap library you would want to do something like this:
import csv
import ldap
con = ldap.initialize('ldap://server.fqdn.system.edu')
# if you're LDAP directory requires authentication
# con.bind_s(username, password)
try:
with open('output_file', 'wb') as output:
csv_writer = csv.writer(output)
csv_writer.writerow(['LoginId', 'Mail'])
for dn, attrs in con.search_s('ou=Students,o=system.edu,o=system', ldap.SCOPE_SUBTREE, attrlist = ['LoginId','mail']:
csv_writer.writerow([attrs['LoginId'], attrs['mail']])
finally:
# even if you don't have credentials, it's usually good to unbind
con.unbind_s()
It's probably worthwhile reading through the documentation for the ldap module, especially the example.
Note that in the example above, I completely skipped supplying a filter, which you would probably want to do in production. A filter in LDAP is similar to the WHERE clause in a SQL statement; it restricts what objects are returned. Microsoft actually has a good guide on LDAP filters. The canonical reference for LDAP filters is RFC 4515.
Similarly, if there are potentially several thousand entries even after applying an appropriate filter, you may need to look into the LDAP paging control, though using that would, again, make the example more complex. Hopefully that's enough to get you started, but if anything comes up, feel free to ask or open a new question.
Good luck.
Assuming that the structure of each entry will always be the same, just do something like this:
import csv
# Open the file
f = open("/path/to/large.file", "r")
# Create an output file
output_file = open("/desired/path/to/final/file", "w")
# Use the CSV module to make use of existing functionality.
final_file = csv.writer(output_file)
# Write the header row - can be skipped if headers not needed.
final_file.writerow(["LoginID","EmailAddress"])
# Set up our temporary cache for a user
current_user = []
# Iterate over the large file
# Note that we are avoiding loading the entire file into memory
for line in f:
if line.startswith("LoginID"):
current_user.append(line[9:].strip())
# If more information is desired, simply add it to the conditions here
# (additional elif's should do)
# and add it to the current user.
elif line.startswith("mail"):
current_user.append(line[6:].strip())
# Once you know you have reached the end of a user entry
# write the row to the final file
# and clear your temporary list.
final_file.writerow(current_user)
current_user = []
# Skip lines that aren't interesting.
else:
continue
Again assuming your file is well-formed:
with open(inputfilename) as inputfile, with open(outputfilename) as outputfile:
mail = loginid = ''
for line in inputfile:
line = inputfile.split(':')
if line[0] not in ('LoginId', 'mail'):
continue
if line[0] == 'LoginId':
loginid = line[1].strip()
if line[0] == 'mail':
mail = line[1].strip()
if mail and loginid:
output.write(loginid + ',' + mail + '\n')
mail = loginid = ''
Essentially equivalent to the other methods.
To open the file you'll want to use something like the with keyword to ensure it closes properly even if something goes wrong:
with open(<your_file>, "r") as f:
# Do stuff
As for actually parsing out that information, I'd recommend building a dictionary of ID email pairs. You'll also need a variable for the uid and the email.
data = {}
uid = 0
email = ""
To actually parse through the file (the stuff run while your file is open) you can do something like this:
for line in f:
if "uid=" in line:
# Parse the user id out by grabbing the substring between the first = and ,
uid = line[line.find("=")+1:line.find(",")]
elif "mail:" in line:
# Parse the email out by grabbing everything from the : to the end (removing the newline character)
email = line[line.find(": ")+2:-1]
# Given the formatting you've provided, this comes second so we can make an entry into the dict here
data[uid] = email
Using the CSV writer (remember to import csv at the beginning of the file) we can output like this:
writer = csv.writer(<filename>)
writer.writerow("User, Email")
for id, mail in data.iteritems:
writer.writerow(id + "," + mail)
Another option is to open the writer before the file, write the header, then read the lines from the file at the same time as writing to the CSV. This avoids dumping the information into memory, which might be highly desirable. So putting it all together we get
writer = csv.writer(<filename>)
writer.writerow("User, Email")
with open(<your_file>, "r") as f:
for line in f:
if "uid=" in line:
# Parse the user id out by grabbing the substring between the first = and ,
uid = line[line.find("=")+1:line.find(",")]
elif "mail:" in line:
# Parse the email out by grabbing everything from the : to the end (removing the newline character)
email = line[line.find(": ")+2:-1]
# Given the formatting you've provided, this comes second so we can make an entry into the dict here
writer.writerow(iid + "," + email)

File management

I am working on python and biopython right now. I have a file upload form and whatever file is uploaded suppose(abc.fasta) then i want to pass same name in execute (abc.fasta) function parameter and display function parameter (abc.aln). Right now i am changing file name manually, but i want to have it automatically.
Workflow goes like this.
----If submit is not true then display only header and form part
--- if submit is true then call execute() and get file name from form input
--- Then displaying result file name is same as executed file name but only change in extension
My raw code is here -- http://pastebin.com/FPUgZSSe
Any suggestions, changes and algorithm is appreciated
Thanks
You need to read the uploaded file out of the cgi.FieldStorage() and save it onto the server. Ususally a temp directory (/tmp on Linux) is used for this. You should remove these files after processing or on some schedule to clean up the drive.
def main():
import cgi
import cgitb; cgitb.enable()
f1 = cgi.FieldStorage()
if "dfile" in f1:
fileitem = f1["dfile"]
pathtoTmpFile = os.path.join("path/to/temp/directory", fileitem.filename)
fout = file(pathtoTmpFile, 'wb')
while 1:
chunk = fileitem.file.read(100000)
if not chunk: break
fout.write (chunk)
fout.close()
execute(pathtoTmpFile)
os.remove(pathtoTmpFile)
else:
header()
form()
This modified the execute to take the path to the newly saved file.
cline = ClustalwCommandline("clustalw", infile=pathToFile)
For the result file, you could also stream it back so the user gets a "Save as..." dialog. That might be a little more usable than displaying it in HTML.

Categories

Resources