How can I split the path by (".") using python? - python

-----------------------mapper-------------------
"contact_information":{
"person_name":{
"FormattedName":"some name"
}
}
--------------------current data---------------
client_profile_data = {
"contact_information":{
"person_name":{
"FormattedName":"Abu DND Md"
}
}
}
---------------------changed data------------
profile_data = {
"contact_information":{
"person_name":{
"FormattedName":"Abu DND"
}
}
}
I need to get the changes of "FormattedName(Field)" between client_profile_data & profile_data. So I wrote some function in "helper.py"
------------------------helper.py------------------
PROFILE_FEEDBACK_MAPPINGS = {
'FormattedName': {
'type': 'nested',
'parent_name': "person_name",
'path': "contact_information.person_name.FormattedName"
}
}
def find_diff(client_profile_data, profile_data):
result = []
for key, value in PROFILE_FEEDBACK_MAPPINGS.items():
if value['type'] == 'nested':
try:
if client_profile_data[value['path'][0][1]][key] != profile_data[value['path'][0][1]][key]:
result.append({
'current': profile_data[value['parent_name']][key],
'changed': client_profile_data[value['parent_name']][key],
})
except Exception:
continue
return result
----------------Expected output-------------------
changed: "Abu DND"
current: "Abu DND Md"
-----------------Actual output---------
getting none
Can anyone help me? I need a changes from client_profile_data and profile_data so that I define a function initially which will check the type and after that I want to split the path bcz(contact_information.person_name.FormattedName) will give second if condition will get the differences so that differences will be appending to result. I tried in this way but not working, please help me.

Not sure about what you are looking for but with minimal changes of your code, a solution coud be :
def find_diff(client_profile_data, profile_data):
result = []
for key, value in PROFILE_FEEDBACK_MAPPINGS.items():
if value['type'] == 'nested':
try:
split_path = value['path'].split(".")
client_name = client_profile_data[split_path[0]][split_path[1]][key]
profile_name = profile_data[split_path[0]][split_path[1]][key]
if client_name != profile_name:
result.append({
'current': profile_data[split_path[0]][value['parent_name']][key],
'changed': client_profile_data[split_path[0]][value['parent_name']][key],
})
except Exception:
continue
return result
You forgot to "split" the path to use it as "keys" for your dictionnaries.

Related

Can I get the name of a JSON schema from one of its values using Python?

I am trying to get a JSON sub-schema's "name" from based off of its contents. This is kind of hard to explain, so an example would be better:
{
"dummy_name_1": {
"dummy_key_1": "unique_dummy_value_1",
"dummy_key_2": "dummy_value_2"
},
"dummy_name_2": {
"dummy_key_1": "unique_dummy_value_2",
"dummy_key_2": "dummy_value_2"
}
}
I want to get the name of dummy_name_1 (which would be "dummy_name_1") given the value of the key "dummy_key_1" (which would be "unique_dummy_value_1"). Basically, if I give the Python function I want "dummy_key_1" and "unique_dummy_value_1" as parameters, I want it to return the string "dummy_name_1".
Something like this? structure being your dict.
def get_dummy_name(dummy_key, dummy_value):
for dummy_name, content in structure.items():
if dummy_key in content.keys() and content[dummy_key] == dummy_value:
return dummy_name
try with this:
def get_category_name(key_name, key_value):
dictionary = {
"dummy_name_1": {
"dummy_key_1": "unique_dummy_value_1",
"dummy_key_2": "dummy_value_2"
},
"dummy_name_2": {
"dummy_key_1": "unique_dummy_value_2",
"dummy_key_2": "dummy_value_2"
}
}
for elem in dictionary.items():
if key_name in elem[1] and elem[1][key_name] == key_value:
return elem[0]
return False
response = get_category_name('dummy_key_1', 'unique_dummy_value_1')

How to get an element value in Python dictionary

I am trying to get the value of DomainName from the below dictionary.
print(domain_name)
# output
{
'DomainNames': [
{
'DomainName': 'some-value'
},
]
}
I have tried:
print(domain_name['DomainNames'][0]['DomainName'])
but it doesn't give that value. I even tried:
print(domain_name['DomainNames']['DomainName'])
Here is my code:
def add_es_tags():
for region in get_regions_depending_on_account():
pass
es_client = boto3.client('es', region_name="us-east-1")
response = es_client.list_domain_names()
get_es_domain_ARN("us-east-1", response)
def get_es_domain_ARN(region, domain_names):
es_client = boto3.client('es', region_name=region)
arns = []
print(len(domain_names))
for domain_name in domain_names:
# print(type(domain_name))
print(domain_name['DomainNames'][0]['DomainName'])
Like this:
domain_name = {
'DomainNames': [
{
'DomainName': 'some-value'
},
]
}
print(domain_name)
print(domain_name['DomainNames'][0]['DomainName'])
Yes, the answer is: it works exactly as you suggested!
Edit: Never mind, I'll update this when you've formulated a full question that actually matches what you're doing.

Extracting JSON value from key

I have a JSON object like so, and I need to extract the name value of any object, using the id. I have tried many different iterations of this but I can't seem to get anything to work. Any general pointers would be much appreciated. Thank you.
{
"weeks":[
{
"1":[
{
"name":"Stackoverflow Question",
"description":"Have you ever asked a question on StackoverFlow?",
"date":"11/25/2019",
"id":"whewhewhkahfasdjkhgjks"
},
{
"name":"I Can't Believe It's Not Butter!",
"description":"Can you believe it? I sure can't.",
"date":"11/25/2019",
"id":"agfasdgasdgasdgawe"
}
]
},
{
"2":[
{
"name":"Hello World",
"description":"A hello world.",
"date":"12/02/2019",
"id":"aewgasdgewa"
},
{
"name":"Testing 123",
"description":"Sometimes people don't say it be like it is but it do.",
"date":"12/04/2019",
"id":"asdgasdgasdgasd"
}
]
}
]
}
Hope you need to find the name based on id, then try out the code below,
def get_name(data, id):
for week in data['weeks']:
for i in week:
for j in week[i]:
if j['id'] == id:
return j['name']
return None
get_name(data, 'asdgasdgasdgasd')
output
'Testing 123'
Not sure if this is what you are looking for
for week in a["weeks"]:
for k, v in week.values():
print(v['name'])
considering the variable a your dict.
Is the structure fixed, or can the depth of the JSON differ from the example?
This one would work as well if there are more or lesser hierarchies.
It basically searches in each dictionary inside a JSON-like structure for the field_name and returns the value of the argument output_name.
Maybe it helps you when your data structure changes :)
data = {
"weeks":[
{
"1":[
{
"name":"Stackoverflow Question",
"description":"Have you ever asked a question on StackoverFlow?",
"date":"11/25/2019",
"id":"whewhewhkahfasdjkhgjks"
},
{
"name":"I Can't Believe It's Not Butter!",
"description":"Can you believe it? I sure can't.",
"date":"11/25/2019",
"id":"agfasdgasdgasdgawe"
}
]
},
{
"2":[
{
"name":"Hello World",
"description":"A hello world.",
"date":"12/02/2019",
"id":"aewgasdgewa"
},
{
"name":"Testing 123",
"description":"Sometimes people don't say it be like it is but it do.",
"date":"12/04/2019",
"id":"asdgasdgasdgasd"
}
]
}
]
}
def extract_name(data, field_name: str, matching_value: str, output_name: str):
"""
:param data: json-like datastructure in which you want to search
:param field_name: the field name with which you want to match
:param matching_value: the value you want to match
:param output_name: the name of the value which you want to get
:return:
"""
if isinstance(data, list):
for item in data:
res = _inner_extract_name(item, field_name, matching_value, output_name)
if res is not None:
return res
elif isinstance(data, dict):
for item in data.values():
res = _inner_extract_name(item, field_name, matching_value, output_name)
if res is not None:
return res
def _inner_extract_name(item, field_name, matching_value, output_name):
if isinstance(item, dict):
res = extract_name(item, field_name, matching_value, output_name)
if field_name in item:
if item[field_name] == matching_value:
if output_name in item:
return item[output_name]
else:
res = extract_name(item, field_name, matching_value, output_name)
return res
if __name__ == "__main__":
name = extract_name(data, "id", "aewgasdgewa", "name")
print(name)
``

mediaItems.search not working with albumId

When I run the following code I get this error.
{'error': {'code': 400, 'message': 'Invalid JSON payload received. Unknown name "album_id": Proto field is not repeating, cannot start list.', 'status': 'INVALID_ARGUMENT', 'details': [{'#type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'description': 'Invalid JSON payload received. Unknown name "album_id": Proto field is not repeating, cannot start list.'}]}]}}
If I remove the "albumId": ["albumid code"] it works fine and returns
10 new items, total 10
def _actually_list_media_items(session):
ret = []
params = {
'fields': 'mediaItems(id,baseUrl,filename,mimeType,productUrl),nextPageToken',
}
search_json = {
"pageSize": 10,
"albumId": ["<albumid code>"],
"filters": {
"includeArchivedMedia": False,
"contentFilter": {
"excludedContentCategories": [
"DOCUMENTS",
"RECEIPTS",
"SCREENSHOTS",
"UTILITY",
"WHITEBOARDS",
]
},
"mediaTypeFilter": {
"mediaTypes": [
"PHOTO",
],
},
},
}
tmp = 0
while tmp < 1:
rsp = session.post(
'https://photoslibrary.googleapis.com/v1/mediaItems:search',
params=params,
json=search_json,
).json()
if 'error' in rsp:
print(rsp)
cur = [m for m in rsp.get('mediaItems', [])]
ret += cur
print(f'{len(cur)} new items, total {len(ret)}')
pageToken = rsp.get('nextPageToken')
if pageToken is None:
break
params['pageToken'] = pageToken
tmp = tmp + 1
return ret
The comment about albumId and filters being exclusive is correct, so you need to pick one or the other. However, assuming you want to use the albumId by itself, you need to remove the square brackets around your albumid code, here's a clip from my code:
searchbody = {
"albumId": album_id,
"pageSize": 10
}
print(searchbody)
mediaresults = gAPIservice.mediaItems().search(body=searchbody).execute()
mediaitems = mediaresults.get('mediaItems', [])
for item in mediaitems:
print(u'{0} ({1})'.format(item['filename'], item['id']))
Edit:
Apparently you can't use albumId and filters together: source
filters: object(Filters)
Filters to apply to the request. Can't be set in conjunction with an albumId.
Aside from that, albumId is a supposed to be a string not an array: source
"albumId": "<albumid code>",

Conditional updating: Update only if value is None or 'null' or key doesn't exist

I'm trying to figure out if there is a way to use conditionals such as $set to do more advanced updating. This is what I'm trying to do in pseudo code:
# new data to use in a possible update
newData = { 'emailAddress' : $usersEmailAddress,
'keyA' : 'valueA',
'keyB' : None,
'keyC' : '<null>' }
self.request.root.db.users.update(
{ 'emailAddress' : newData['emailAddress'] },
{ '$set': {
"Here, loop through all newData keys/values and if
notNull(newData[key]) == True and is different than the
corresponding key/value in the user
document (or if user document doesn't have that key)
than update with newData key/value"
} }, upsert = False, safe = True )
# The result should be that if the value of keyA (and ONLY key A because the
# others are null) is different in the user document
# than in newData, than the user document should be updated with the new value.
# function to catch any possible None value or equivalent string
def notNull(valueToCheck):
if thingToCheck and thingToCheck != "null" and thingToCheck != 'nil' and thingToCheck != '<null>' and thingToCheck != '' and thingToCheck != ' ':
return True
else:
return False
What's the most efficient way of doing this? Because currently I'm having to pull the entire document with find_one and, I'm told, thats rather expensive. Is there a way to do this with just $set?
No, MongoDB does not support this feature. You can either, as you say, retrieve the document, analyze it in your client-side code, and issue an update based on its contents, or you could issue a series of updates like:
db.users.update({
'emailAddress': newData['emailAddress'],
'$or': [
{ 'keyA': { '$exists': false } },
{ 'keyA': None } ] }
]
}, {
'$set': { 'keyA': newData['keyA'] }
})
The former will be more efficient, of course, since it's a single fetch and a single update. But consider whether you need to guard against multiple MongoDB clients simultaneously fetching and updating the same document.

Categories