Python: “List.append = ‘list’ object attribute ‘append’ is read-only” - python

I’m trying to write a response from a Solr server to a CSV file. I’m pretty new to python and have been given code to modify. Originally the code looked like this ...
for doc in response.results:
status = json.loads(doc['status'])
The script runs and prints the correct information. But it only every prints one result (last one). I think this is because the loop constantly writes over the varible 'status' until its worked through the response.
After some reading I decided to store the information in a list. That way i could print the information to seprate lines in a list. I created an empty list and changed the code below -
for doc in response.results:
list.append = json.loads(doc['status'])
I got this response back after trying to run the code -
`AttributeError: 'list' object attribute 'append' is read-only`.
Where am I going wrong? Is a list not the best approach?

>>> list.append
<method 'append' of 'list' objects>
You're trying to modify the append method of the built-in list class!
Just do
docstats = []
for doc in response.results:
docstats.append(json.loads(doc['status']))
or equivalently:
docstats = [json.loads(doc['status']) for doc in response.results]

I'm not sure what you are trying to do.
I guess you haven't created a list variable. list is a python's builtin class for lists, so if there's no variable to mask it, you'll access that. And you tried to modify one of it's propterties, which is not allowed (it's not like ruby where you can monkey-patch anything).
Is this what you want? :
l=[]
for doc in response.results:
l.append(json.loads(doc[‘status’]))

Try
list.append(json.loads(doc['status']))

Related

Cant replace spaces in a python variable

i tried to replace spaces in a variable in python but it returns me this error
AttributeError: 'HTTPHeaders' object has no attribute 'replace'
this is my code
for req in driver.requests:
print(req.headers)
d = req.headers
x = d.replace("""
""", "")
So, if you check out the class HTTPHeaders you'll see it has a __repr__ function and that it's an HTTPMessage object.
Depending on what you exactly want to achieve (which is still not clear to me!, i.e, for which header do you want to replace spaces?) you can go about this two ways. Use the methods on the HTTPMessage object (documented here) or use the string version of it by calling repr on the response. I recommend you use the first approach as it is much cleaner.
I'll give an example in which I remove spaces for all canary values in all of the requests:
for req in driver.requests:
canary = req.headers.get("canary")
canary = canary.replace(" ", "")
P.S., your question is nowhere near clear enough as it stands. Only after asking multiple times and linking your other question it becomes clear that you are using seleniumwire, for example. Ideally, the code you provide can be run by anyone with the installed packages and reproduces the issue you have. BUT, allright, the comments made it more clear.

Python http request and loop over contents of JSON

I'm trying to learn Python and have following problem:
I get an error while running this as it cannot see the 'name' attribute in data.
It works when I grab one by one items from JSON. However when I want to do it in a loop it fails.
I assume my error is wrong request. That it cannot read JSON correctly and see attributes.
import requests
import json
def main():
req = requests.get('http://pokeapi.co/api/v2/pokemon/')
print("HTTP Status Code: " + str(req.status_code))
print(req.headers)
json_obj = json.loads(req.content)
for i in json_obj['name']:
print(i)
if __name__ == '__main__':
main()
You want to access the name attribute of the results attribute in your json_object like this:
for pokemon in json_obj['results']:
print (pokemon['name'])
I was able to guess that you want to access the results keys because I have looked at the result of
json_obj.keys()
that is
dict_keys(['count', 'previous', 'results', 'next'])
Because all pokemons are saved in a list which is under keyword results, so you firstly need to get that list and then iterate over it.
for result in json_obj['results']:
print(result['name'])
A couple things: as soon mentioned, iterating through json_obj['name'] doesn't really make sense - use json_obj['results'] instead.
Also, you can use req.json() which is a method that comes with the requests library by default. That will turn the response into a dictionary which you can then iterate through as usual (.iteritems() or .items(), depending if you're using Python 2 or 3).

Robotframework - updating value in json dictionary gives error AttributeError: 'list' object has no attribute 'update'

I have this JSON object and i like to update a value within the object. I found a way how i should do this on stackoverflow (Json handling in ROBOT) and its failing and i don't understand why.
This is de object:
{"elementKey":"P690-C0-C3-B1","fields":[{"key":"P690-C1-C2-C1-C1-C1-F0","values":[]},{"key":"P690-C0-C2-F8","values":["1200"]},{"key":"P690-C0-C2-F9","values":["22000"]},{"key":"P690-C0-C2-F11","values":["I"]},{"key":"P690-C0-C2-F10","values":["2200"]},{"key":"P690-C0-C2-C0-C0-F0","values":["98-zsg-2"]},{"key":"P690-C1-C0-C0-F1","values":["Personenauto"]},{"key":"P690-C1-C0-C0-F2","values":["Personenauto KVP"]},{"key":"P690-C0-C2-F6","values":["B"]},{"key":"P690-C0-C2-F7","values":["75"]},{"key":"P690-C0-C2-F4","values":["2"]},{"key":"P690-C0-C2-F5","values":["5"]},{"key":"P690-C0-C2-F2","values":["model"]},{"key":"P690-C0-C2-F3","values":["2017"]},{"key":"P690-C1-C2-C2-C2-C1-F0","values":[]},{"key":"P690-C0-C2-F1","values":["merk"]}]}
In Robot frame I made this test, inspired on the given link.
${json_string}= Set Variable "see text above"
${json}= Evaluate json.loads('''${json_string}''') json
Set To Dictionary ${json["fields"]} ${new_value}
${json_string}= evaluate json.dumps(${json}) json
With ${new_value} i tried value=shizzleliz, value[0]=shizzleliz, value[1]=shizzleliz, P690-C1-C2-C1-C1-C1-F0=shizzleliz
All give the error: AttributeError: 'list' object has no attribute 'update'
When i change ${json["fields"]} to ${json} then the give value is set to the library but not in de fields section/collection.
Does anyone have a clue of what i'm doing wrong? And if you have a suggestion how i can update the value, i'd like that very much :)
target is to change: {"key":"P690-C1-C2-C1-C1-C1-F0","values":[]}
to: {"key":"P690-C1-C2-C1-C1-C1-F0","values":["shizzleliz"]}
For the first part in your question - the error AttributeError: 'list' object has no attribute 'update', you've already seen the comment - you're calling Set To Dictionary on a list object, which cannot pass.
For the second part, in order to set that value when the key is equal to something, you have to iterate over all the list members, and set it based on a condition over the key:
${json_string}= Set Variable see text above
${json1}= Evaluate json.loads('''${json_string}''') json
${target value}= Create List shizzleiz
:FOR ${element} IN #{json1["fields"]}
\ Run Keyword If "${element['key']}" == "P690-C1-C2-C1-C1-C1-F0"
... Set To Dictionary ${element} values=${target value}
${json_string}= evaluate json.dumps(${json1}) json
It looks a little cumbersome in RF (compared to python); one remark - it's never a good idea to name a local variable the same as a module - thus I've renamed it to ${json1}
I found an easier solution using Catenate where I needed to randomize two values in the json body.
${shizzleiz}= shizzleiz # or whatever you want to appear there
${json_string}= Catenate {"elementKey":"P690-C0-C3-B1","fields":[{"key":"P690-C1-C2-C1-C1-C1-F0","values":[]},{"key":"P690-C0-C2-F8","values":["1200"]},{"key":"P690-C0-C2-F9","values":["22000"]},{"key":"P690-C0-C2-F11","values":["I"]},{"key":"P690-C0-C2-F10","values":["2200"]},{"key":"P690-C0-C2-C0-C0-F0","values":["98-zsg-2"]},{"key":"P690-C1-C0-C0-F1","values":["Personenauto"]},{"key":"P690-C1-C0-C0-F2","values":["Personenauto KVP"]},{"key":"P690-C0-C2-F6","values":["B"]},{"key":"P690-C0-C2-F7","values":["75"]},{"key":"P690-C0-C2-F4","values":["2"]},{"key":"P690-C0-C2-F5","values":["5"]},{"key":"P690-C0-C2-F2","values":["model"]},{"key":"P690-C0-C2-F3","values":["2017"]},{"key":"P690-C1-C2-C2-C2-C1-F0","values": ${shizzleiz} ${the-rest-of-the-long-json-as-a-string}
then continue on with:
${json}= Evaluate json.loads('''${json_string}''') json
${json_string}= evaluate json.dumps(${json}) json
(basically do the work before reacting to the json function - obviously this requires knowing the values beforehand and could also work with more variables.)

TypeError: documents must be a non-empty list

I'm doing a program using Twitter API and MongoDB in 2.7 Python language.
I get a timeline and put it in a dictionary, which I want to store in a MongoDB database. To do this I have next code:
def saveOnBD(self, dic):
client = MongoClient("xxxx", "port")
db = client.DB_Tweets_User_Date
collection = db.tweets
collection.insert_many(dic)
I'm debbuging and dic it's not empty but I get next error:
TypeError: documents must be a non-empty list
How can I fix it?
I trying many options, but i solved that question changing the post method.
Instead of:
collection.insert_many(dic)
I used this:
collection.insert_one(dic)
I supose that, as I try to post only a variable(dic) and "insert_many()" is for many variables that retun me the error. That change solved me the question
you can either put in an entry before running the bulk entry function or use insert()
A list of documents must be passed to insert_many method
E.g.:
collection.insert_many([dic])

Accessing dictionary elements in python

I working with some twitter data, I get the data by monitoring the twitter stream, then I save the results in a *.txt file
I´m trying to manipulate this txt file with python, for that I use the json.loads() instruction, with every line in the file where the twitter stream result was saved, in that way I got every file line as an json object.
for line in twitter_file
data = json.loads(line)
The json object (one json object for one file line) is loaded in a variable called "data"
Everyting is working there, when I try to access an element in the "data" json object I can do it, for example, if I can see the place element, I can do it with data["place"], so I got this:
"place":{
"id":"00a961d91f76dde8",
"url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/00a961d91f76dde8.json",
"place_type":"city",
"name":"Capital - Corrientes",
"full_name":"Capital - Corrientes",
"country_code":"AR",
"country":"Argentina",
"contained_within":[]
}
I can access the "place" element, if I execute print data["place"] , I can see the text displayed above.
The problem comes when I'm trying to access an specific key in place dictionary,
I tried to do it in this way
data["place"]["place_type"]
I'm waiting to get the "city" value as result, but I can not do it, I get the following error: TypeError: "NoneType" object has no attribute '__getitem__'
I also tried other ways to display the key-value pairs with the following:
for key,value in data["data"].items()
print key
But I don't get the result
I also tried with
print data["place"].keys()[0]
To get printed the first element, but It doesn't work either. I got the following error message: AttributeError: 'NoneType' object has no attribute 'keys'
It seems that my data["place"] is not being considered as a dictionary by Python, that's what I guess, but I'm not sure, I'm pretty new at Python, so any comment will be very helpful for me.
You are looping over a file and loading each line as JSON. Some of those JSON objects have place set to a dictionary, others have it set to None.
Whenever you just loaded a line with the value associated with the place key set to None, you'll get the AttributeError exception.
You need to test for this first:
place = data['place']
if place is not None:
print place['place_type']

Categories

Resources