I have a YAML file: ./YAML/simpleData.yml
- name: 'Somu'
age: 26
content:
- name: 'Neo'
age: 27
content: []
- name: 'Ari'
age: 26
content: []
And I'm trying to parse it using PyYAML via:
import yaml
# Creating objects directly with the YAML module:
print("Attempting Direct Object Load: ")
class Person:
def __init__(self, name, age, con):
self.name = name
self.age = hp
self.content = con
def __repr__(self):
return "%s(name=%r, hp=%r, sp=%r)" % (
self.__class__.__name__, self.name, self.age, self.content)
def printData(self):
print(self.name)
print(self.age)
if self.content:
for per in self.content:
print("-->", end="")
per.printData()
# Data load:
person_obj = None
data = ""
try:
with open('YAML/simpleData.yml') as source:
for line in source:
data += line
except Exception as err:
print("An exception occurred: " + str(err))
person_obj = yaml.load("""!!python/object:__main__.Person\n""" + data)
if not person_obj:
print("Data Loading Failed..! EXITING!!")
exit(1)
person_obj.printData()
I'm new to Python, and thus can't determine what I'm doing wrong, due to which this exception is being raised:
yaml.constructor.ConstructorError: expected a mapping node, but found sequence
in "<unicode string>", line 1, column 1:
!!python/object:__main__.Person
^
How do I fix this?
Full Output Dump:
Attempting Direct Object Load:
Traceback (most recent call last):
File "/home/somu/Programming/python/HeadFirstPython/yamlIntro.py", line 106, in <module>
person_obj = yaml.load("""!!python/object:__main__.Person\n""" + data)
File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/__init__.py", line 72, in load
return loader.get_single_data()
File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 37, in get_single_data
return self.construct_document(node)
File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 46, in construct_document
for dummy in generator:
File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 578, in construct_python_object
state = self.construct_mapping(node, deep=deep)
File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 204, in construct_mapping
return super().construct_mapping(node, deep=deep)
File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 122, in construct_mapping
node.start_mark)
yaml.constructor.ConstructorError: expected a mapping node, but found sequence
in "<unicode string>", line 1, column 1:
!!python/object:__main__.Person
^
Process finished with exit code 1
At the root, c.q. top level, of your file you have a sequence. The first element of which is a mapping with among others the key-value pair name: Somu.
If you want to load this using PyYAML in the way you described, you should strip of the first two characters of each line:
data += line[2:]
or insert the !!python/object:__main__.Person after the first dash:
data = data.replace('- ', '- !!python/object:__main__.Person\n', 1)
Related
I was trying to create a workbook and change its title to time for now:
class Roll_call_list():
__file_name = ''
def __init__(self):
self.__file_name = input("Input your file name:")+'.xlsx'
if os.path.isfile(self.__file_name):
self.load()
else:
self.new_workbook()
self.save_file()
def new_workbook(self):
self.workbook = Workbook()
self.worksheet = self.workbook.active
self.paint_sheet()
def load(self):
self.workbook = load_workbook(self.__file_name)
self.worksheet = self.workbook.create_sheet()
self.paint_sheet()
def paint_sheet(self):
local_time = time.localtime(time.time())
self.worksheet.title = f'{local_time.tm_hour}:{local_time.tm_min}'
But it raise a value error like below:
Traceback (most recent call last):
File "d:\code\python\selenium\MeetRollCaller\main.py", line 176, in <module>
roll_call_list = Roll_call_list()
File "d:\code\python\selenium\MeetRollCaller\main.py", line 63, in __init__
self.new_workbook()
File "d:\code\python\selenium\MeetRollCaller\main.py", line 68, in new_workbook
self.paint_sheet()
File "d:\code\python\selenium\MeetRollCaller\main.py", line 75, in paint_sheet
self.worksheet.title = f'{local_time.tm_hour}:{local_time.tm_min}'
File "C:\Users\ZIV\AppData\Local\Programs\Python\Python310\lib\site-packages\openpyxl\workbook\child.py", line 93, in title
raise ValueError(msg)
ValueError: Invalid character : found in sheet title
It seems like I have a same title as a sheet in the workbook, but this is a brand new work book without any sheet. I have no idea why it occurs.
Can someone help me fix the error and tell me why?
I have a project that searches PDFs for URLs and in the process extracts the PDF Metadata. It works perfectly around 99.6% of the time without any errors. But every once in a while, a file throws the old "invalid token error. Traceback Below:
Traceback (most recent call last):
File "c:\python38\lib\runpy.py", line 193, in _run_module_as_main
return run_code(code, main_globals, None,
File "c:\python38\lib\runpy.py", line 86, in run_code
exec(code, run_globals)
File "C:\Python38\Scripts\linkrot.exe_main.py", line 7, in
File "c:\python38\lib\site-packages\linkrot\cli.py", line 182, in main
pdf = linkrot.linkrot(args.pdf)
File "c:\python38\lib\site-packages\linkrot_init.py", line 131, in init
self.reader = PDFMinerBackend(self.stream)
File "c:\python38\lib\site-packages\linkrot\backends.py", line 213, in init
self.metadata.update(xmp_to_dict(metadata))
File "c:\python38\lib\site-packages\linkrot\libs\xmp.py", line 92, in xmp_to_dict
return XmpParser(xmp).meta
File "c:\python38\lib\site-packages\linkrot\libs\xmp.py", line 41, in init
self.tree = ET.XML(xmp)
File "c:\python38\lib\xml\etree\ElementTree.py", line 1320, in XML
parser.feed(text)
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 55, column 10
My assumption is that there is some sort of issue with the XML extracted from the PDF, but I can't be sure. Is there a workaround? Some way the rest of the program could run when this error throws? The metadata is valuable to the process so I'd like to keep it if possible. I don't know etree that well, so I'd appreciate some help. The Code itself is below:
class XmpParser(object):
"""
Parses an XMP string into a dictionary.
Usage:
parser = XmpParser(xmpstring)
meta = parser.meta
"""
def __init__(self, xmp):
self.tree = ET.XML(xmp)
self.rdftree = self.tree.find(RDF_NS + "RDF")
#property
def meta(self):
""" A dictionary of all the parsed metadata. """
meta = defaultdict(dict)
if self.rdftree:
for desc in self.rdftree.findall(RDF_NS + "Description"):
for (
el
) in (
desc.iter()
):
ns, tag = self._parse_tag(el)
value = self._parse_value(el)
meta[ns][tag] = value
return dict(meta)
def _parse_tag(self, el):
""" Extract the namespace and tag from an element. """
ns = None
tag = el.tag
if tag[0] == "{":
ns, tag = tag[1:].split("}", 1)
if ns in NS_MAP:
ns = NS_MAP[ns]
return ns, tag
def _parse_value(self, el): # noqa: C901
""" Extract the metadata value from an element. """
if el.find(RDF_NS + "Bag") is not None:
value = []
for li in el.findall(RDF_NS + "Bag/" + RDF_NS + "li"):
value.append(li.text)
elif el.find(RDF_NS + "Seq") is not None:
value = []
for li in el.findall(RDF_NS + "Seq/" + RDF_NS + "li"):
value.append(li.text)
elif el.find(RDF_NS + "Alt") is not None:
value = {}
for li in el.findall(RDF_NS + "Alt/" + RDF_NS + "li"):
value[li.get(XML_NS + "lang")] = li.text
else:
value = el.text
return value
Any help or advice would be appreciated.
I am new to programming and I created a son program that stores your name, than the items in your list.
import json
list_ = []
filename = 'acco.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input("What is your name? ")
while True:
list_items = input("What is the item you want to add? q to quit")
if list_items == 'q':
break
list_.append(list_items)
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("These is your list of items:")
print(list_)
print("We'll remember you when you come back, " + username + "!")
json.dump(list_items, f_obj)
else:
print("Welcome back, " + username + "!")
print("Here are the items of your list:")
print(_list)
However, an error keeps showing up when I run the program. The error says that there is an error in line 8, the line of code where it says
username = json.load(f_obj)
This is the exact error
Traceback (most recent call last):
File "/Users/dgranulo/Documents/rememberme.py", line 8, in <module>
username = json.load(f_obj)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 296, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 340, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 8 (char 7)
If anyone can help that would be greatly appreciated,
Thanks,
You're serializing objects one by one. A str and a list. Do it once in a collection like a list or dict.
This one works;
>>> print(json.loads('"a"'))
a
But this one a str and a list is an error;
>>> json.loads('"a"[1]')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.6/json/decoder.py", line 342, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 4 (char 3)
Write to the file with a dict;
with open(filename, 'w') as f_obj:
# json.dump(username, f_obj)
print("These is your list of items:")
print(list_)
print("We'll remember you when you come back, " + username + "!")
# json.dump(list_items, f_obj)
# dump a dict
json.dump({'username': username, 'items': list_}, f_obj)
Now json.load will return a dict with keys username and items.
I have the following code which returns the public IP's
def gather_public_ip():
ACCESS_KEY = config.get('aws','access_key')
SECRET_KEY = config.get('aws','secret_key')
regions = regions = ['us-west-2','eu-central-1','ap-southeast-1']
# regions = config.get('aws','region').split(',')
all_EIP = []
for region in regions:
client = boto3.client('ec2',aws_access_key_id=ACCESS_KEY,aws_secret_access_key=SECRET_KEY,region_name=region,)
addresses_dict = client.describe_addresses()
for eip_dict in addresses_dict['Addresses']:
if 'PrivateIpAddress' in eip_dict:
print eip_dict['PublicIp']
# return str(eip_dict['PublicIp'])
all_EIP.append(eip_dict['PublicIp'])
print all_EIP
# print str(all_EIP)
return str(all_EIP)
This is called and returned as :
net_range = gather_public_ip()
for ip in net_range:
r = s.run(ip)
run looks like :
def run(self, targets="" ,options="-Pn"):
#start a new nmap scan on localhost with some specific options
syslog.syslog("Scan started")
parsed = None
nmproc = NmapProcess(targets,options)
rc = nmproc.run()
if rc != 0:
syslog.syslog("nmap scan failed: {0}".format(nmproc.stderr))
try:
parsed = NmapParser.parse(nmproc.stdout)
self.report = parsed
except NmapParserException as e:
syslog.syslog("Exception raised while parsing scan: {0}".format(e.msg))
syslog.syslog("Scan complete")
syslog.syslog("Scan duration: "+ str(parsed.elapsed))
self.report = parsed
return parsed
after printing the list , this throws me :
Traceback (most recent call last):
File "portwatch.py", line 300, in <module>
r = s.run(ip)
File "portwatch.py", line 239, in run
rc = nmproc.run()
File "/usr/local/lib/python2.7/dist-packages/libnmap/process.py", line 257, in run
else shlex.split(self.__nmap_command_line)
File "/usr/lib/python2.7/shlex.py", line 279, in split
return list(lex)
File "/usr/lib/python2.7/shlex.py", line 269, in next
token = self.get_token()
File "/usr/lib/python2.7/shlex.py", line 96, in get_token
raw = self.read_token()
File "/usr/lib/python2.7/shlex.py", line 172, in read_token
raise ValueError, "No closing quotation"
ValueError: No closing quotation
Make sure your ip is not "" or shlex will fail, cf Which exception to raise if a given string does not match some format?
This error occurs on pynsq 0.4.2
STACKTRACE
2013-07-30 15:03:43,205 ERROR [ip-10-114-195-89:4150:nsq_msg_handler] failed to handle_message()
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/nsq/Reader.py", line 367, in _data_callback
self._handle_message(conn, message)
File "/usr/local/lib/python2.7/dist-packages/nsq/Reader.py", line 291, in _handle_message
return message.requeue()
File "/usr/local/lib/python2.7/dist-packages/nsq/nsq.py", line 47, in requeue
self.respond(REQ, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/nsq/Reader.py", line 211, in _message_responder
self._requeue(conn, message, time_ms=kwargs.get('time_ms', -1))
File "/usr/local/lib/python2.7/dist-packages/nsq/Reader.py", line 222, in _requeue
return self.finish(conn, message)
AttributeError: 'Reader' object has no attribute 'finish'
CODE
def connect_nsq(self):
r = nsq.Reader(message_handler=self.nsq_msg_handler, lookupd_http_addresses=["127.0.0.1:4161"], topic="test_topic", channel="test_channel", max_in_flight=500)
nsq.run()
# callback
def nsq_msg_handler(self, message):
try:
before_ts = get_utc_now_ts()
json_data = json.loads(message.body)
my_data = json_data["key1"]
my_data = json_data["key2"]
my_data = json_data["key3"]
after_ts = get_utc_now_ts()
delta = after_ts - before_ts
logger.debug("took %f seconds for json_data _id: %s" % (delta, json_data["_id"]))
except Exception as reason:
print reason, traceback.format_exc()
return False
return true
This issue was fixed in the latest release of pynsq which is 0.5.0
Here's the bug report: https://github.com/bitly/pynsq/issues/44