Python: writing to a text file - python

I want my code to write certain errors to text file. It's copying files over, and I want to write the "un-copied" files to a text file for a record. I have my script appending an array with file paths every time it hits an error (like so):
errors.append(srcfile)
After my loop, I have the following code, which I thought would write the paths to my text file:
text_file = open("%s_copy_log.txt" % username, "a")
for line in errors:
text_file.write(line)
text_file.close()
Am I missing something?

This is an example of an XY problem: You want to do something, think of a solution, find a problem with that solution, and ask for help with that. I'm assuming that although you could do logging yourself (as you are trying), but using Python's built in logger will make more sense. They've already done most of what you need, all you need to do is import it, configure it, and use it.
import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
example.log:
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too
This also supports things like command line logging level setting, and a bunch of other stuff.
Docs Tutorial

Try changing a to a+, which tells python to create a file if it doesn't exist.
text_file = open("%s_copy_log.txt" % username, "a+")
Further Reading on Python File IO Types

I'm not sure what your application structure looks like, but if you have a number of users and want each username to have its own log (why?) when perhaps the best way would be something like:
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
admin_handler = logging.FileHandler("app.log")
admin_handler.setLevel(logging.DEBUG)
logger.addHandler(admin_handler)
# this will write ALL events to one location
user_logger = logger.getChild("userlog")
def login(username, password):
if verify(username, password): # however you're doing this
user_logger.addHandler(logging.FileHandler("%s.log" % username))
user_logger.setLevel(logging.WARNING) # or maybe logging.INFO?
user_logger.info("%s logged in" % username)
# authenticate the user as you currently do
else:
logger.warning("%s attempted login with bad password!" % username)
# prompt the user as you currently do
def logout():
user_logger.handlers = [] # remove previous user logger
# de-authenticate as normal
def user_log_something(the_thing):
if the_thing.is(something_critical):
user_logger.critical(the_thing)

Related

Rename log file in Python while file keeps writing any other logs

I am using the Python logger mechanism for keeping a record of my logs. I have two types of logs,
one is the Rotating log (log1, log2, log3...) and a non-rotating log called json.log (which has json logs in it as the name suggests).
The log files are created when the server is started and close when the app is closed.
What I am trying to do in general is: When I press the import button on my page, to have all json logs saved on the sqlite db.
The problem I am facing is:
When I try to rename the json.log file like this:
source_file = "./logs/json.log"
snapshot_file = "./logs/json.snapshot.log"
try:
os.rename(source_file, snapshot_file)
I get the windowsError: [Error 32] The process cannot access the file because it is being used by another process
and this is because the file is being used by the logger continuously. Therefore, I need to "close" the file somehow so I can do my I/O operation successfully.
The thing is that this is not desirable because logs might be lost until the file is closed, then renamed and then "re-created".
I was wondering if anyone came across such scenario again and if any practical solution was found.
I have tried something which works but does not seem convenient and not sure if it is safe so that any logs are not lost.
My code is this:
source_file = "./logs/json.log"
snapshot_file = "./logs/json.snapshot.log"
try:
logger = get_logger()
# some hackish way to remove the handler for json.log
if len(logger.handlers) > 2:
logger.removeHandler(logger.handlers[2])
if not os.path.exists(snapshot_file):
os.rename(source_file, snapshot_file)
try:
if type(logger.handlers[2]) == RequestLoggerHandler:
del logger.handlers[2]
except IndexError:
pass
# re-adding the logs file handler so it continues writing the logs
json_file_name = configuration["brew.log_file_dir"] + os.sep + "json.log"
json_log_level = logging.DEBUG
json_file_handler = logging.FileHandler(json_file_name)
json_file_handler.setLevel(json_log_level)
json_file_handler.addFilter(JSONLoggerFiltering())
json_file_handler.setFormatter(JSONFormatter())
logger.addHandler(json_file_handler)
... code continues to write the logs to the db and then delete the json.snapshot.file
until the next time the import button is pressed; then the snapshot is created again
only for writing the logs to the db.
Also for reference my log file has this format:
{'status': 200, 'actual_user': 1, 'resource_name': '/core/logs/process', 'log_level': 'INFO', 'request_body': None, ... }
Thanks in advance :)

Username and Password login

I'd like to create a Login in which will open a text/csv file read the "Valid" usernames and passwords from the file and then if whatever the user has added has matched what was in the file then it will allow access to the rest of the program
How would i integrate the code below into one of which opens a file reads valid usernames and passwords and checks it against the users input
Currently i have something which works but there is only one password which i have set in the code.
Password = StringVar()
Username = StringVar()
def EnterPassword():
file = open('Logins.txt', 'w') #Text file i am using
with open('Logins.txt') as file:
data = file.read() #data=current text in text file
UsernameAttempt = Username.get()#how to get value from entry box
PasswordAttempt = Password.get()#how to get value from entry box
if PasswordAttempt == '' and UsernameAttempt == '':
self.delete()
Landlord = LandlordMenu()
else:
PasswordError = messagebox.showerror('Password/Username Entry','Incorrect Username or Password entered.\n Please try again.')
PasswordButton = Button(self.GenericGui,text = 'Landlord Section',height = 3, width = 15, command = EnterPassword, font = ('TkDefaultFont',14),relief=RAISED).place(x=60,y=175)
Some assistance would be appreciated
Please have a look at some documentation. Your question in "Coding Comments" -> #how to get value from entry box is easy to be solved using official documentation.
For reading files there is also official documentation on strings and file operations (reading file line by line into string, using string.split(';') to get arrays instead of row-strings).
Please do read documentation before writing applications. You do not need to know the complete API of all python modules but where to look. It is very exhausting to be dependent on other users / developers when there is no actual need for it (as there is very detailed documentation and tons of howtows for that kind of stuff).
This is not meant to be offensive but to show you how easy you can get documentation. Both results where first-results from a search engine. (ddg)
Please keep in mind that SO is neither a code writing service nor a let-me-google-that-for-you forum.

Flask not writing to file

I've been meaning to log all the users that visit the site to a file.
Using Flask for the backend.
I have not been able to get python to write to the file. Tried keeping exception handling to catch any errors that might be generated while writing. No exceptions are being raised.
Here is the part of the blueprint that should write to file.
from .UserDataCache import UserDataCache
udc = UserDataCache()
#main.route('/')
def index():
s = Suggestion.query.all()
udc.writeUsertoFile()
return render_template('suggestions.html', suggestions = s)
Here is the UserDataCache class:
from flask import request
from datetime import datetime
class UserDataCache():
def __init__(self):
pass
def writeUsertoFile(self):
try:
with open("userData.txt","a") as f:
f.write(str(datetime.now()) + " " + request.remote_addr + " " + request.url + " " + request.headers.get('User-Agent') + "\n")
except IOError,e:
print e
return
I recommend using an absolute path and verifying the permissions on that file. Something like /tmp/UserData.txt or another absolute path should work. The web server's user is what needs the permission to write to the file (www-data if you're using apache2 with Ubuntu, or check your web server's conf file to verify).
As far as why you're not seeing the exception you're catching, I see you're using print. If you're calling the app using a web browser, you'll need to send the error to something else, like a log file or flash it to the browser, or raise an error so it gets logged in the web server error log.
Is your python file name begins with uppercase? If so, try to modify it into lowercase.
I just came into the same problem and copied the exactly same code into two .py file. The only difference is their file name, one being 'Flask_test.py' and another being 'flask_for_test.py'. It's weird that 'Flask_test.py' works just fine except it cannot write into any file and 'flask_for_test.py' works perfectly.
I don't know whether the format of the file name has an effect on the function of python but using lowercase file name works for me.
By the way, all other solutions I found didn't work.

I need a super-duper simple CGI Python photo upload

I've looked through tons of answers but the truth is, I only know super basic python and I really need help. I don't know the os module or anything like that and I can't use PHP (not that I know it anyway, but it's not permitted) and I need something so easy that I can understand it.
Basically, I need a CGI upload (I don't need the HTML form, I've got that much down) that will take the photo and save it. That's it. I don't need any fancy place for it to save, I just need the file to be properly uploaded from the form.
I've got various versions of this function and I can't get them working because I don't understand them so PLEASE HELP!!!
import cgi
def savefile (filename, photodoc):
form=cgi.FieldStorage()
name=form[filename]
period=name.split(.)
if period[1]=="jpeg" or period[1]=="jpg" or period[1]=="png":
idk what to do
else:
make an error message
This cgi program will "take the photo and save it. That's it."
#!/usr/bin/python2.7
import cgi
field=cgi.FieldStorage()['fieldname']
open(field.filename, 'wb').write(field.value)
Among the things it doesn't do are error checking and security checking, and specifying in what directory the files should be saved.
Duplicate question but here's what you need:
Depending if windows or linux, first set to binary mode:
try:
import msvcrt
msvcrt.setmode (0, os.O_BINARY)
msvcrt.setmode (1, os.O_BINARY)
except ImportError:
pass
Then:
form = cgi.FieldStorage()
name = form[filename]
period = name.split('.') #You need the quotes around the period
if period[1]=='jpeg' or period[1] == 'jpg' or period[1] =='png':
if upload.filename:
name = os.path.basename(upload.filename)
out = open(YOUR_FILEPATH_HERE + name, 'wb', 1000)
message = "The file '" + name + "' was uploaded successfully"
while True:
packet = upload.file.read(1000)
if not packet:
break
out.write(packet)
out.close()
else:
print 'Error'
Some sources:
How to use Python/CGI for file uploading
http://code.activestate.com/recipes/273844-minimal-http-upload-cgi/

GData: How to avoid hardcoding login info

I am working on a reporting system which automatically updates results overnight and puts them in files on a google drive.
The way it is working right now is by hardcoding the login and password information which is by no means ideal even if it works. A search in StackOverflow does not point this question specifically, which surprises me.
A very simplified example with the relevant sections of code looks like:
import gdata.docs.service
class GDrive(object):
def __init__(self, email, password)
self.gd_client = gdata.docs.service.DocService()
self.gd_client.ClientLogin(email, password)
def upload(self):
# Code to Upload file somewhere in GDrive.
gd = GDrive("the#email.address", "ThePassword")
gd.upload()
Can something be done to avoid writing explicitly the username and password?
I would make use of the OAuth2 protocol. It is a secure way to store credentials for a long time (but not forever).
A bit of a short answer from my cell, but check:
https://developers.google.com/drive/about-auth
And this bit makes working with Oauth2 a lot easier:
https://developers.google.com/api-client-library/python/platforms/google_app_engine#Decorators
import gdata.docs.service
import sys
class GDrive(object):
def __init__(self, email, password)
self.gd_client = gdata.docs.service.DocService()
self.gd_client.ClientLogin(email, password)
def upload(self):
# Code to Upload file somewhere in GDrive.
if __name__ == "__main__":
username = sys.argv[1]
password = sys.argv[2]
gd = GDrive(username, password)
gd.upload()
now run from your commandline like script.py the#email.address ThePassword where script.py is the name of your python scripts...

Categories