get key basis on value by reading property file in python? - python

I have a property file "holder.txt" like this which is in key=value format. Here key is clientId and value is hostname.
p10=machineA.abc.host.com
p11=machineB.pqr.host.com
p12=machineC.abc.host.com
p13=machineD.abc.host.com
Now I want to read this file in python and get corresponding clientId where this python script is running. For example: if python script is running on machineA.abc.host.com then it should give me p10 as clientId. Similarly for others.
import socket, ConfigParser
hostname=socket.getfqdn()
print(hostname)
# now basis on "hostname" figure out whats the clientId
# by reading "holder.txt" file
Now I have worked with ConfigParser but my confusion is how can I get value of key which is clientId basis on what hostname it is? Can we do this in python?

You Need to read and store the holder file in memory as a dictionary:
mappings = {}
with open('holder.txt', 'r') as f:
for line in f:
mapping = line.split('=')
mappings[mapping[1].rstrip()] = mapping[0]
Then perform a mapping every time you want to get clientId from hostname:
import socket, ConfigParser
hostname=socket.getfqdn()
clientId = mappings[hostname]
Hope that helps.

Related

Python - Get empty key from yml file

I have a lot yaml file names that have similar structure but with different data. I need to parse out selective data, and put into a single csv (excel) file as three columns.
But i facing an issue with empty key, that always gives me an "KeyError: 'port'"
my yaml file example:
base:
server: 10.100.80.47
port: 3306
namePrefix: well
user: user1
password: kjj&%$
base:
server: 10.100.80.48
port:
namePrefix: done
user: user2
password: fhfh#$%
In the second block i have an empty "port", and my script is stuck on that point.
I need that always that an empty key is found it doesn't write anything.
from asyncio.windows_events import NULL
from queue import Empty
import yaml
import csv
import glob
yaml_file_names = glob.glob('./*.yaml')
rows_to_write = []
for i, each_yaml_file in enumerate(yaml_file_names):
print("Processing file {} of {} file name: {}".format(
i+1, len(yaml_file_names),each_yaml_file))
with open(each_yaml_file) as file:
data = yaml.safe_load(file)
for v in data:
if "port" in v == "":
data['base']['port'] = ""
rows_to_write.append([data['base']['server'],data['base']['port'],data['server']['host'],data['server']['contex']])
with open('output_csv_file.csv', 'w', newline='') as out:
csv_writer = csv.writer(out)
csv_writer.writerow(["server","port","hostname", "contextPath"])
csv_writer.writerows(rows_to_write)
print("Output file output_csv_file.csv created")
You are trying to access the key by index e.g.
data['base']['port']
But what you want is to access it with the get method like so:
data['base'].get('port')
This way if the key does not exists it return None as default, and you could even change the default value to whatever you want by passing it as the second parameter.
In PyYAML, an empty element is returned as None, not an empty string.
if data['base']['port'] is None:
data['base']['port'] = ""
Your yaml file is invalid. In yaml file, whenever you have a key (like port: in your example) you must provide a value, you cannot leave it empty and go to the next line. Unless the value is the next bunch of keys of course, but in that case you need to ident the following lines one step more, which is obviously not what you intend to do here.
This is likely why you cannot parse the file as expected with the python yaml module. If you are the creator of those yaml file, you really need to put a key in the file like port: None if you don't want to provide a value for the port, or even better you just not provide any port key at all.
If they are provided to you by someone else, ask them to provide valid yaml files.
Then the other solutions posted should work.

Using nslookup to find domain name and only the domain name

Currently I have a text file with mutiple IP's I am currently attempting to pull only the domain name from the set of information given using nslookup (code below)
with open('test.txt','r') as f:
for line in f:
print os.system('nslookup' + " " + line)
This works in so far that it pulls all the information from the first IP's. I can't get it passed the first IP but I'm currently attempting to clean up the information recived to only the Domain name of the IP. Is there any way to do that or do I need to use a diffrent module
Like IgorN, I wouldn't make a system call to use nslookup; I would also use socket. However, the answer shared by IgorN provides the hostname. The requestor asked for the domain name. See below:
import socket
with open('test.txt', 'r') as f:
for ip in f:
fqdn = socket.gethostbyaddr(ip) # Generates a tuple in the form of: ('server.example.com', [], ['127.0.0.1'])
domain = '.'.join(fqdn[0].split('.')[1:])
print(domain)
Assuming that test.txt contains the following line, which resolves to a FQDN of server.example.com:
127.0.0.1
this will generate the following output:
example.com
which is what (I believe) the OP desires.
import socket
name = socket.gethostbyaddr(‘127.0.0.1’)
print(name) #to get the triple
print(name[0]) #to just get the hostname

Reading YAML file with Python results in AttributeError

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

python key unknown in yaml

I have the following yaml file
name: somehost
values:
network_lo: "127.0.0.1"
network_eth0: "10.10.10.10"
hardwaremodel: x64
network_eth1: "192.168.10.10"
I would like to fetch all network* keys / values and print there values in an single value.
Though the interfaces could have different names. So i don't know what the interface name is called.
Normally I would do something like this:
with open(file, 'r') as stream:
facts = yaml.load(stream)
multiple = facts['values']['network*']
# single interface
print facts['values']['network_db_backend']
expected
# all interfaces
print multiple
expected: 127.0.0.1, 10.10.10.10, 192.168.10.10
How can I go over an yaml file fetch all network interfaces and print there values into a single string ?
something like this should work
import yaml
with open('file.yaml''', 'r') as stream:
facts = yaml.load(stream)
multiple = ', '.join([val for (key,val) in facts['values'].iteritems() if "network" in key])
# single interface
print facts['values']['network_lo']
# 127.0.0.1
# all interfaces
print multiple
and you can replace
"network" in key
with a regexp if you wish

How to use pyfig module in python?

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.

Categories