I'm developing a Python package to communicate with an API. In order not to hard code the username and password I would like to read the credentials from a JSON file loacated in a 'conf' directory. So if no username and pasword are given it tries to load the credentials from the file:
def __init__(self, user=None, pswd=None):
""" Illustrate method-level docstring."""
if pswd is None:
try:
with open('conf/credentials.json') as data_file:
data = json.load(data_file)
user = data['user']
pswd = data['password']
print('You will log in with user', user)
except IOError:
print("Could not read file: credentials.json. Please Instantiate object with your username and password")
This solution works fine when executing the code in the same directory, but once the package is installed the system doesn't find the file:
Could not read file: credentials.json. Please Instantiate object with
your username and password
How can I overcome this problem? Is it possible to refer to the installation path? I don't want to encrypt the password, I just want to have the credentials in a separate file and add the file in the .gitignore file to prevent sharing this information.
You may try using 'file' which stores filename (with absolute or relative path) and build your path based on this.
You may also store your secret data in other directory (outside of your codebase) like ~/. It may be even better to pass this filename as environmental variable (see os.environ) so users may point to the right file.
Related
I have made a config file named "config.cfg" that's on the same folder of my .py file.
My config file is like this:
[NetAccess]
host=localhost
port=3306
[Credentials]
username=myuser
password=mypass
[Database]
name=mydb
in my .py file I have this code:
import configparser
config = configparser.ConfigParser()
config.read('config.cfg')
__DBMSuser = config.get('Credentials', 'username')
__DBMSpsw = config.get('Credentials', 'password')
When I launch my program, I receive this error:
configparser.NoSectionError: No section: 'Credentials'
Can someone help me?
I've solved it. My code was correct, and the .cfg file was correctly saved in the folder of my program, but because of other parts of my code, my current directory changed to "C:/Windows/Service32". Not reading the file, I had not error until I was trying to read the sections, so I got NoSectionError.
To solve it, I've choice a standard folder (in AppData) where to save my file and read it and then I've used the absolute path.
Your code is working for me. Most likely the issue is reading the config file itself. Config Parser's read method is configured to fail silently if it fails to find or read the file, but the read function returns a read_ok boolean flag. Use it to check if the read was successful:
import configparser
config = configparser.ConfigParser()
filename = 'config.cfg'
read_ok = config.read(filename)
if read_ok:
__DBMSuser = config['Credentials']['username']
__DBMSpsw = config['Credentials']['password']
else:
print(f'Could not read file {filename}')
There is no mistake in your code, cuz it works for me.
I think there is some small error with file:
Make sure your file is in same directory as python file
Have you saved your file? maybe you forgot to press ctrl+s
If even that's not working for you, try another version of Python
I am a python developer and somewhat new to using Google's gMail API to import .eml files into a gMail account.
I've gotten all of the groundwork done getting my oAuth credentials working, etc.
However, I am stuck where I load in the data-file. I need help loading the message data in to place in a variable..
How do I create the message_data variable reference - in the appropriate format - from my sample email file (which is stored in rfc822 format) that is on disk?
Assuming I have a file on disk at /path/to/file/sample.eml ... how do I load that to message_data in the proper format for the gMail API import call?
...
# how do I properly load message_data from the rfc822 disk file?
media = MediaIoBaseUpload(message_data, mimetype='message/rfc822')
message_response = service.users().messages().import_(
userId='me',
fields='id',
neverMarkSpam=True,
processForCalendar=False,
internalDateSource='dateHeader',
media_body=media).execute(num_retries=2)
...
You want to import an eml file using Gmail API.
You have already been able to get and put values for Gmail API.
You want to achieve this using google-api-python-client.
service in your script can be used for uploading the eml file.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification point:
In this case, the method of "Users.messages: insert" is used.
Modified script:
Before you run the script, please set the filename with the path of the eml file.
eml_file = "###" # Please set the filename with the path of the eml file.
user_id = "me"
f = open(eml_file, "r", encoding="utf-8")
eml = f.read()
f.close()
message_data = io.BytesIO(eml.encode('utf-8'))
media = MediaIoBaseUpload(message_data, mimetype='message/rfc822', resumable=True)
metadata = {'labelIds': ['INBOX']}
res = service.users().messages().insert(userId=user_id, body=metadata, media_body=media).execute()
print(res)
In above script, the following modules are also required.
import io
from googleapiclient.http import MediaIoBaseUpload
Note:
In above modified script, {'labelIds': ['INBOX']} is used as the metadata. In this case, the imported eml file can be seen at INBOX of Gmail. If you want to change this, please modify this.
Reference:
Users.messages: insert
If I misunderstood your question and this was not the result you want, I apologize.
I have a password protected zip-file called important.zip, it contains 1 folder, the password for the zip-file is 123, however when I use run this code with a wrong password the folder is still getting extracted, how can I make it that I can not extract the folder without the correct password?
import zipfile
zFile=zipfile.ZipFile("important.zip")
try:
zFile.extractall(pwd="oranges")
except Exception as e:
print e
The zipfile module checks for this as well as it can it returns a 'Bad password for file' when the password doesn't match.
But it does this on a per file basis. As each file in a ZIP file can have its own different password which was the password that was given when the file was added to the archive.
I think that your zip file was not password protected as zipfile accepts a password when extracting for files that aren't password protected. It does not report an error when the password is not used because the file was not password protected.
To avoid extracting a zip file that is not password protected when a password is provided one has check if the files are password protected:
import zipfile
def all_files_are_password_protected(zf):
return all(zinfo.flag_bits & 0x1 for zinfo in zf.infolist())
zFile=zipfile.ZipFile("important.zip")
try:
if all_files_are_password_protected(zFile):
zFile.extractall(pwd="oranges")
except Exception as e:
import traceback
traceback.print_exc()
Based on:
zf = zipfile.ZipFile(archive_name)
for zinfo in zf.infolist():
is_encrypted = zinfo.flag_bits & 0x1
if is_encrypted:
print '%s is encrypted!' % zinfo.filename
From How to check if a zip file is encrypted using python's standard library zipfile?
Note that every file has their own password so some files might fail to be extracted if encrypted with a different password.
Have a peculiar issue that I can't seem to fix on my own..
I'm attempting to FTP a list of files in a directory over to an iSeries IFS using Python's ftplib library.
Note, the files are in a single subdirectory down from the python script.
Below is an excerpt of the code that is giving me trouble:
from ftplib import FTP
import os
localpath = os.getcwd() + '/Files/'
def putFiles():
hostname = 'host.name.com'
username = 'myuser'
password = 'mypassword'
myftp = FTP(hostname)
myftp.login(username, password)
myftp.cwd('/STUFF/HERE/')
for file in os.listdir(localpath):
if file.endswith('.csv'):
try:
file = localpath + file
print 'Attempting to move ' + file
myftp.storbinary("STOR " + file, open(file, 'rb'))
except Exception as e:
print(e)
The specific error that I am getting throw is:
Attempting to move /home/doug/Files/FILE.csv
426-Unable to open or create file /home/doug/Files to receive data.
426 Data transfer ended.
What I've done so far to troubleshoot:
Initially I thought this was a permissions issue on the directory containing my files. I used chmod 777 /home/doug/Files and re-ran my script, but the same exception occured.
Next I assumed there was an issue between my machine and the iSeries. I validated that I could indeed put files by using ftp. I was successfully able to put the file on the iSeries IFS using the shell FTP.
Thanks!
Solution
from ftplib import FTP
import os
localpath = os.getcwd() + '/Files/'
def putFiles():
hostname = 'host.name.com'
username = 'myuser'
password = 'mypassword'
myftp = FTP(hostname)
myftp.login(username, password)
myftp.cwd('/STUFF/HERE/')
for csv in os.listdir(localpath):
if csv.endswith('.csv'):
try:
myftp.storbinary("STOR " + csv, open(localpath + csv, 'rb'))
except Exception as e:
print(e)
As written, your code is trying to execute the following FTP command:
STOR /home/doug/Files/FILE.csv
Meaning it is trying to create /home/doug/Files/FILE.csv on the IFS. Is this what you want? I suspect that it isn't, given that you bothered to change the remote directory to /STUFF/HERE/.
If you are trying to issue the command
STOR FILE.csv
then you have to be careful how you deal with the Python variable that you've named file. In general, it's not recommended that you reassign a variable that is the target of a for loop, precisely because this type of confusion can occur. Choose a different variable name for localpath + file, and use that in your open(..., 'rb').
Incidentally, it looks like you're using Python 2, since there is a bare print statement with no parentheses. I'm sure you're aware that Python 3 is recommended by now, but if you do stick to Python 2, it's recommended that you avoid using file as a variable name, because it actually means something in Python 2 (it's the name of a type; specifically, the return type of the open function).
I have my NAS server located and i am able to get/upload files on it. Now i have suituation where i need to read .png files location from server and pass it on UI thread to show the image. Right now i am only aware of method get which needs local location to save. I don't want file to be save on my local machine but just i shall be able to show that image on my application.
I have gone through this http://docs.paramiko.org/en/2.1/api/sftp.html but didn't found relevant method to use
Code is :-
import paramiko
paramiko.util.log_to_file(r'D:\TechnoThrone\Builds\paramiko.log')
# Open a transport
host = "stedgela01.TechnoThrone.com"
port = 2222
transport = paramiko.Transport((host, port))
# Auth
password = "xxx"
username = "xxxx"
transport.connect(username = username, password = password)
# Go!
sftp = paramiko.SFTPClient.from_transport(transport)
# Download
filepath = '/A/B/C/pic_ex.png'
localpath = r'D:\picfolder\pic_ex.png'
sftp.get(filepath, localpath)
I don't quite get the problem, so I will try to guess a bit.
You should be able to look at content in paths in the remote server without need to download locally the file.
get is not the right method if you don't want to download because as per documentation:
get(remotepath, localpath, callback=None) Copy a remote file
(remotepath) from the SFTP server to the local host as localpath. Any
exception raised by operations will be passed through. This method is
primarily provided as a convenience.
Parameters: remotepath (str) – the remote file to copy localpath
(str) – the destination path on the local host callback (callable) –
optional callback function (form: func(int, int)) that accepts the
bytes transferred so far and the total bytes to be transferred
There are other methods which can get filenames in a remote directory and attributes of those without the need to download.
These are listdir, listdir_attr and listdir_iter for example.
For example, listdir_attr will
Return a list containing SFTPAttributes objects corresponding to files
in the given path. The list is in arbitrary order. It does not include
the special entries '.' and '..' even if they are present in the
folder.
The returned SFTPAttributes objects will each have an additional
field: longname, which may contain a formatted string of the file’s
attributes, in unix format. The content of this string will probably
depend on the SFTP server implementation.
Parameters: path (str) – path to list (defaults to '.')
Returns: list
of SFTPAttributes objects
You could use something along these lines:
list_png_files = []
for file_attributes in sftp.listdir_attr("remote_path"):
if file_attributes.filename.endswith('.png'):
list_png_files.append(file_attributes.filename)
Check if it will give you relative or absolute path of course.
Similar you could try with listdir, etc.
def _list_remote_dir(self, dir="."):
sftp_session = self.ssh_session.open_sftp() # ssh_session is paramiko.SSHClient()
sftp_session.chdir(".")
cwd = sftp_session.getcwd()
print(cwd)
remote_file_attrs = sftp_session.listdir_attr()
for i in remote_file_attrs:
logging.info(i.filename)
this snipet may help, you got the current working directory, and you got the file name, you can get the abs-path of files on server.