Opposite single/double quotes using pymongo command - python

I am trying to take user input, create a URI, and add it with a collection in Pymongo, but whenever I try to do this, the format gets messed up and I cant figure out how to fix it.
When running the line:
print(db.command("create", "storage", someStorage={ "URI": {FS_URI}}))
where "Storage" is the collection,
I want the object to be {"fs" : "something://a:b"} or {'fs' : 'something://a:b'}
FS_URI = ('\"fs\" : \"'+URI+'\"')
gives the error: Cannot encode object: {'"fs" : "something://a:b"'}
FS_URI = ("fs\" : \"%s" % URI)
gives the error" Cannot encode object: {'fs" : "something://a:b'}
FS_URI = ("fs\' : \'%s" % URI)
gives the error" Cannot encode object: {"fs' : 'something://a:b"}
The quotes are always unmatching, or have extra quotes around them.
I have tried the command with the actual URI in the quote format I want, and it runs perfectly.

I found that using a dict solved this problem, by changing
FS_URI = ("fs\" : \"%s" % URI)
to a JSON object rather than a string:
FS_URI = {"fs": "{}".format(URI)}
solved this problem

Related

Unable to update contact's profile picture using Google's People API

So, i wrote this code:
json_data = "{\"photoBytes\":" + str(bytearray(open("image.png", "rb").read())) + "}"
service.people().updateContactPhoto('people/c4942919248052589775', json_data)
but it gives me this error:
TypeError: method() takes 1 positional argument but 3 were given
I cannot understand why. As the docs say, I should use it like this...
You are passing a string value as a request body which should be in json format.
Try using json.dumps() first on your json_date before passing it as a parameter in updateContactPhoto().
Your code should look like this:
json_data = "{\"photoBytes\":" + str(bytearray(open("image.png", "rb").read())) + "}"
service.people().updateContactPhoto('people/c4942919248052589775', json.dumps(json_data))
I was able to figure this out with a lot of trial and error and I found that the photo needs to be base64 encoded and the best method to get that into JSON below (thanks to this answer for this tip).
Here's the working code for me below
import base64
JSON = """{
"photoBytes": "%s"
}
""" % (base64.b64encode(open("test.png", "rb").read()).decode('utf-8'))
update_body = json.loads(JSON)
service.people().updateContactPhoto(resourceName="people/123456789", body=update_body).execute()

errors parsing json objects using python3.7, unable to access key values

I have a python lambda function which receives posted data. The function looks a bit like this:
import json
import ....
def handle(event, context):
if event["body"]:
posted_data = json.loads(event["body"])
print(posted_data)
print(posted_data["email"])
print(posted_data.get("email"))
The line print(posted_data) prints my json object like this:
{
"tel": "078723646",
"message": "jsd fljxdisfbv lskdjnildufv nlksjfg",
"email": "my#selg.om"
}
The line print(posted_data["email"]) gives me this error:
[ERROR] TypeError: string indices must be integers
The line print(posted_data.get("email") give this error:
[ERROR] AttributeError: 'str' object has no attribute 'get'
Yet, when I open a console, run python, and do this:
>>> obj = {"tel": "078276353", "message": "uisdjy df jdslfj lsdjf fb", "email": "tetet#gdgdg.lo"}
>>> type(obj)
The response I get is:
<class 'dict'>
So, I'm a little confused as to whether it's a dictionary or a string.
What I need to do is to access each of the values in the object.
I tried this, but that had the effect of reversing the json.loads
I also looked here, but that did not assist. I checked this but it doesn't seem to be relevant to my case.
After a suggestion from #brunns I inserted print(type(posted_data)) after posted_data = json.loads(event["body"]) and discovered that posted_data is in fact a string.
I was expecting json.loads(event["body"]) to convert the json object to a python object. How do I go about retrieving the values in the object?

Format String of Dictionary

I've a string of dictionary as following:
CREDENTIALS = "{\"aaaUser\": {\"attributes\": {\"pwd\": \"cisco123\", \"name\": \"admin\"}}}"
Now I want to format this string to replace the pwd and name dynamically. What I've tried is:
CREDENTIALS = "{\"aaaUser\": {\"attributes\": {\"pwd\": \"{0}\", \"name\": \"{1}\"}}}".format('password', 'username')
But this gives following error:
traceback (most recent call last):
File ".\ll.py", line 4, in <module>
CREDENTIALS = "{\"aaaUser\": {\"attributes\": {\"pwd\": \"{0}\", \"name\": \"{1}\"}}}".format('password', 'username')
KeyError: '"aaaUser"
It is possible by just loading the string as dict using json.loads()and then setting the attributes as required, but this is not what I want. I want to format the string, so that I can use this string in other files/modules.
'
What I'm missing here? Any help would be appreciated.
Don't try to work with the JSON string directly; decode it, update the data structure, and re-encode it:
# Use single quotes instead of escaping all the double quotes
CREDENTIALS = '{"aaaUser": {"attributes": {"pwd": "cisco123", "name": "admin"}}}'
d = json.loads(CREDENTIALS)
attributes = d["aaaUser"]["attributes"]
attributes["name"] = username
attributes["pwd"] = password
CREDENTIALS = json.dumps(d)
With string formatting, you would need to change your string to look like
CREDENTIALS = '{{"aaaUser": {{"attributes": {{"pwd": "{0}", "name": "{1}"}}}}}}'
doubling all the literal braces so that the format method doesn't mistake them for placeholders.
However, formatting also means that the password needs to be pre-escaped if it contains anything that could be mistaken for JSON syntax, such as a double quote.
# This produces invalid JSON
NEW_CREDENTIALS = CREDENTIALS.format('new"password', 'bob')
# This produces valid JSON
NEW_CREDENTIALS = CREDENTIALS.format('new\\"password', 'bob')
It's far easier and safer to just decode and re-encode.
str.format deals with the text enclosed with braces {}. Here variable CREDENTIALS has the starting letter as braces { which follows the str.format rule to replace it's text and find the immediately closing braces since it don't find it and instead gets another opening braces '{' that's why it throws the error.
The string on which this method is called can contain literal text or replacement fields delimited by braces {}
Now to escape braces and replace only which indented can be done if enclosed twice like
'{{ Hey Escape }} {0}'.format(12) # O/P '{ Hey Escape } 12'
If you escape the parent and grandparent {} then it will work.
Example:
'{{Escape Me {n} }}'.format(n='Yes') # {Escape Me Yes}
So following the rule of the str.format, I'm escaping the parents text enclosed with braces by adding one extra brace to escape it.
"{{\"aaaUser\": {{\"attributes\": {{\"pwd\": \"{0}\", \"name\": \"{1}\"}}}}}}".format('password', 'username')
#O/P '{"aaaUser": {"attributes": {"pwd": "password", "name": "username"}}}'
Now Coming to the string formatting to make it work. There is other way of doing it. However this is not recommended in your case as you need to make sure the problem always has the format as you mentioned and never mess with other otherwise the result could change drastically.
So here the solution that I follow is using string replace to convert the format from {0} to %(0)s so that string formatting works without any issue and never cares about braces .
'Hello %(0)s' % {'0': 'World'} # Hello World
SO here I'm using re.sub to replace all occurrence
def myReplace(obj):
found = obj.group(0)
if found:
found = found.replace('{', '%(')
found = found.replace('}', ')s')
return found
CREDENTIALS = re.sub('\{\d{1}\}', myReplace, "{\"aaaUser\": {\"attributes\": {\"pwd\": \"{0}\", \"name\": \"{1}\"}}}"% {'0': 'password', '1': 'username'}
print CREDENTIALS # It should print desirable result

Can't convert a string to JSON using python 3? [duplicate]

This question already has answers here:
How can I parse (read) and use JSON?
(5 answers)
Closed 25 days ago.
In Python I'm getting an error:
Exception: (<type 'exceptions.AttributeError'>,
AttributeError("'str' object has no attribute 'read'",), <traceback object at 0x1543ab8>)
Given python code:
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.load(jsonStr)['data']['children']
What does this error mean and what did I do to cause it?
The problem is that for json.load you should pass a file like object with a read function defined. So either you use json.load(response) or json.loads(response.read()).
Ok, this is an old thread but.
I had a same issue, my problem was I used json.load instead of json.loads
This way, json has no problem with loading any kind of dictionary.
Official documentation
json.load - Deserialize fp (a .read()-supporting text file or binary file containing a JSON document) to a Python object using this conversion table.
json.loads - Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.
You need to open the file first. This doesn't work:
json_file = json.load('test.json')
But this works:
f = open('test.json')
json_file = json.load(f)
If you get a python error like this:
AttributeError: 'str' object has no attribute 'some_method'
You probably poisoned your object accidentally by overwriting your object with a string.
How to reproduce this error in python with a few lines of code:
#!/usr/bin/env python
import json
def foobar(json):
msg = json.loads(json)
foobar('{"batman": "yes"}')
Run it, which prints:
AttributeError: 'str' object has no attribute 'loads'
But change the name of the variablename, and it works fine:
#!/usr/bin/env python
import json
def foobar(jsonstring):
msg = json.loads(jsonstring)
foobar('{"batman": "yes"}')
This error is caused when you tried to run a method within a string. String has a few methods, but not the one you are invoking. So stop trying to invoke a method which String does not define and start looking for where you poisoned your object.
AttributeError("'str' object has no attribute 'read'",)
This means exactly what it says: something tried to find a .read attribute on the object that you gave it, and you gave it an object of type str (i.e., you gave it a string).
The error occurred here:
json.load(jsonStr)['data']['children']
Well, you aren't looking for read anywhere, so it must happen in the json.load function that you called (as indicated by the full traceback). That is because json.load is trying to .read the thing that you gave it, but you gave it jsonStr, which currently names a string (which you created by calling .read on the response).
Solution: don't call .read yourself; the function will do this, and is expecting you to give it the response directly so that it can do so.
You could also have figured this out by reading the built-in Python documentation for the function (try help(json.load), or for the entire module (try help(json)), or by checking the documentation for those functions on http://docs.python.org .
Instead of json.load() use json.loads() and it would work:
ex:
import json
from json import dumps
strinjJson = '{"event_type": "affected_element_added"}'
data = json.loads(strinjJson)
print(data)
So, don't use json.load(data.read()) use json.loads(data.read()):
def findMailOfDev(fileName):
file=open(fileName,'r')
data=file.read();
data=json.loads(data)
return data['mail']
use json.loads() function , put the s after that ... just a mistake btw i just realized after i searched error
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.loads(jsonStr)['data']['children']
try this
Open the file as a text file first
json_data = open("data.json", "r")
Now load it to dict
dict_data = json.load(json_data)
If you need to convert string to json. Then use loads() method instead of load(). load() function uses to load data from a file so used loads() to convert string to json object.
j_obj = json.loads('["label" : "data"]')

Using JSON module to encode an object in Python

I have this String that I need to pass into a REST request
{"notification":{"tag":"MyTag"}}
I'm trying to turn into an object using the JSON module in python.
This is my attempt so far
import json
obj = json.dumps([{'notification': ('{tag : MyTag}')}])
But it isn't parsed correctly so the REST request won't work. Anyone have any ideas?
Just dump your dictionary as is, replace:
obj = json.dumps([{'notification': ('{tag : MyTag}')}])
with:
obj = json.dumps({"notification": {"tag": "MyTag"}})

Categories

Resources