I am getting this error: configparser.ParsingError: Source contains parsing errors: 'my.ini'
although I am getting uncommented-values printed on the terminal.
my.ini:
[my]
# user
root
# passwd
password
I read here that # or ; could be used for commenting. This is how I am doing it:
import configparser
c = configparser.ConfigParser()
c.read('my.ini')
getval = c.items('my')
The problem is root and password don't have a value assigned to them. Since it appears that you want to allow that, just say so when you create the ConfigParser instance:
c = configparser.ConfigParser(allow_no_value=True)
Or in Python 2:
c = ConfigParser.ConfigParser(allow_no_value=True)
I am facing the same issue, but the below line resolves the error the as same above one.
from configparser import ConfigParser
config = ConfigParser(allow_no_value=True)
Thanks.
Related
I'm trying to use ConfigParser to edit a string that stores a .ini file content.
To import the string I use ConfigParser.read_string(my_string).
what I'm looking for is the exact opposite function so I can later set my string's value as content of my confing object.
I could use f-string in some loop but this wouldn't be ideal in my opinion.
import configparser
config = configparser.ConfigParser()
sample_config = """
[settings]
user = jeff
help = pls
"""
config.read_string(sample_config)
config["settings"]["user"] = "Orili"
sample_config = config.write_string()
the function write_string() does not exist
what I want:
print(sample_config)
output:
[settings]
user = Orili
help = pls
import configparser
config= configparser.ConfigParser()
config.read(r'C:\Users\PycharmProjects\Integration\local.ini')
print(config.sections())
Don't know what to do after this. I had tried this code
server = config.get('db','server')
It throws an output from print statement and an error.
['"db"', '"Auth"']
configparser.NoSectionError: No section: 'db'
local.ini file contains
["db"]
server=raj
log=ere2
["Auth"]
login=hi
Make ini file like this:
[db]
server=raj
log=ere2
[Auth]
login=hi
and import like:
import configparser
config= configparser.ConfigParser()
config.read(r'C:\Users\PycharmProjects\Integration\local.ini')
server = config['db']['server')]
Or if you want the returned data to always be str, use:
server = str(config['db']['server')])
['"db"', '"Auth"']
Answer:
["db","Auth"]
For anyone who may encounter this and the accepted solution doesn't work for them, Rohit-Pandley's answer is probably correct except for 2 small syntax errors where "config['db']['server')]" is used.
The ")" in the 'server' key call (inside the []) is not supposed to be there. It should read like this instead.
server = config['db']['server']
and
server = eval(config['db']['server'])
So altogether it should look like this. (This is Rohit-Pandley's solution copied and fixed)
Make ini file like this:
[db]
server=raj
log=ere2
[Auth]
login=hi
and import like:
import configparser
config= configparser.ConfigParser()
config.read(r'C:\Users\PycharmProjects\Integration\local.ini')
server = config['db']['server']
Or it return always str so if data type is other then string then use:
server = eval(config['db']['server'])
I'm trying to make a script to back up a MySQL database. I have a config.yml file:
DB_HOST :'localhost'
DB_USER : 'root'
DB_USER_PASSWORD:'P#$$w0rd'
DB_NAME : 'moodle_data'
BACKUP_PATH : '/var/lib/mysql/moodle_data'
Now I need to read this file. My Python code so far:
import yaml
config = yaml.load(open('config.yml'))
print(config.DB_NAME)
And this is an error that comes up:
file "conf.py", line 4, in <module>
print(config.DB_NAME)
AttributeError: 'str' object has no attribute 'DB_NAME'
Does anyone have an idea where I made a mistake?
There are 2 issues:
As others have said, yaml.load() loads associative arrays as mappings, so you need to use config['DB_NAME'].
The syntax in your config file is not correct: in YAML, keys are separated from values by a colon+space.
Should work if the file is formatted like this:
DB_HOST: 'localhost'
DB_USER: 'root'
DB_USER_PASSWORD: 'P#$$w0rd'
DB_NAME: 'moodle_data'
BACKUP_PATH: '/var/lib/mysql/moodle_data'
To backup your data base, you should be able to export it as a .sql file. If you're using a specific interface, look for Export.
Then, for Python's yaml parser.
DB_HOST :'localhost'
DB_USER : 'root'
DB_USER_PASSWORD:'P#$$w0rd'
DB_NAME : 'moodle_data'
BACKUP_PATH : '/var/lib/mysql/moodle_data'
is a key-value thing (sorry, didn't find a better word for that one). In certain langage (such as PHP I think), they are converted to objects. In python though, they are converted to dicts (yaml parser does it, JSON parser too).
# access an object's attribute
my_obj.attribute = 'something cool'
my_obj.attribute # something cool
del my_obj.attribute
my_obj.attribute # error
# access a dict's key's value
my_dict = {}
my_dict['hello'] = 'world!'
my_dict['hello'] # world!
del my_dict['hello']
my_dict['hello'] # error
So, that's a really quick presentation of dicts, but that should you get you going (run help(dict), and/or have a look here you won't regret it)
In your case:
config['DB_NAME'] # moodle_data
Try this:
import yaml
with open('config.yaml', 'r') as f:
doc = yaml.load(f)
To access "DB_NAME" you can use:
txt = doc["DB_NAME"]
print txt
This is the part of the mailer.py script:
config = pyfig.Pyfig(config_file)
svnlook = config.general.svnlook #svnlook path
sendmail = config.general.sendmail #sendmail path
From = config.general.from_email #from email address
To = config.general.to_email #to email address
what does this config variable contain? Is there a way to get the value for config variable without pyfig?
In this case config = a pyfig.Pyfig object initialised with the contents of the file named by the content of the string config_file.
To find out what that object does and contains you can either look at the documentation and/or the source code, both here, or you can print out, after the initialisation, e.g.:
config = pyfig.Pyfig(config_file)
print "Config Contains:\n\t", '\n\t'.join(dir(config))
if hasattr(config, "keys"):
print "Config Keys:\n\t", '\n\t'.join(config.keys())
or if you are using Python 3,
config = pyfig.Pyfig(config_file)
print("Config Contains:\n\t", '\n\t'.join(dir(config)))
if hasattr(config, "keys"):
print("Config Keys:\n\t", '\n\t'.join(config.keys()))
To get the same data without pyfig you would need to read and parse at the content of the file referenced by config_file within your own code.
N.B.: Note that pyfig seems to be more or less abandoned - no updates in over 5 years, web site no longer exists, etc., so I would strongly recommend converting the code to use a json configuration file instead.
How can one write comments to a given file within sections?
If I have:
import ConfigParser
with open('./config.ini', 'w') as f:
conf = ConfigParser.ConfigParser()
conf.set('DEFAULT', 'test', 1)
conf.write(f)
I will get the file:
[DEFAULT]
test = 1
But how can I get a file with comments inside [DEFAULT] section, like:
[DEFAULT]
; test comment
test = 1
I know I can write codes to files by doing:
import ConfigParser
with open('./config.ini', 'w') as f:
conf = ConfigParser.ConfigParser()
conf.set('DEFAULT', 'test', 1)
conf.write(f)
f.write('; test comment') # but this gets printed after the section key-value pairs
Is this a possibility with ConfigParser? And I don't want to try another module because I need to keep my program as "stock" as possible.
You can use the allow_no_value option if you have Version >= 2.7
This snippet:
import ConfigParser
config = ConfigParser.ConfigParser(allow_no_value=True)
config.add_section('default_settings')
config.set('default_settings', '; comment here')
config.set('default_settings', 'test', 1)
with open('config.ini', 'w') as fp:
config.write(fp)
config = ConfigParser.ConfigParser(allow_no_value=True)
config.read('config.ini')
print config.items('default_settings')
will create an ini file like this:
[default_settings]
; comment here
test = 1
Update for 3.7
I've been dealing with configparser lately and came across this post. Figured I'd update it with information relevant to 3.7.
Example 1:
config = configparser.ConfigParser(allow_no_value=True)
config.set('SECTION', '; This is a comment.', None)
Example 2:
config = configparser.ConfigParser(allow_no_value=True)
config['SECTION'] = {'; This is a comment':None, 'Option':'Value')
Example 3: If you want to keep your letter case unchanged (default is to convert all option:value pairs to lowercase)
config = configparser.ConfigParser(allow_no_value=True)
config.optionxform = str
config.set('SECTION', '; This Comment Will Keep Its Original Case', None)
Where "SECTION" is the case-sensitive section name you want the comment added to. Using "None" (no quotes) instead of an empty string ('') will allow you to set the comment without leaving a trailing "=".
You can create variable that starts by # or ; character:
conf.set('default_settings', '; comment here', '')
conf.set('default_settings', 'test', 1)
created conf file is
[default_settings]
; comment here =
test = 1
ConfigParser.read function won't parse first value
config = ConfigParser.ConfigParser()
config.read('config.ini')
print config.items('default_settings')
gives
[('test','1')]
You could also use ConfigUpdater. It has many more convenience options to update configuration files in a minimal invasive way.
You would basically do:
from configupdater import ConfigUpdater
updater = ConfigUpdater()
updater.add_section('DEFAULT')
updater.set('DEFAULT', 'test', 1)
updater['DEFAULT']['test'].add_before.comment('test comment', comment_prefix=';')
with open('./config.ini', 'w') as f:
updater.write(f)
Freaky solution for the above :)
Note there is a side-effect, see if that suites you
config = configparser.ConfigParser(comment_prefixes='///')
config.set('section', '# cmt', 'comment goes here')
configparse will treat comments as variables, but real software would not.
This would even preserve the comments on writes done after read of the same ini file, which is a real game changer (disappearing comments are just horrible) :) and you don't need to do allow_no_value=True to allow empty value, just minor visual candy :)
so the ini file would look like:
[section]
# cmt = comment goes here
which pretty much gets the job done :)
please make sure to initialize comment_prefixes with a string that would never appear in your ini file just in case
This worked for me in 3.9.
Side effect on writing the already existing comments. They would not disappear which was normal default, but will be converted to a similar form # first = <remaining>, where first - first word of comment, remaining - remaining of the comment, which would change how file looks, so be carefull...