How can I get attribute valus of a JSON using JMESPath - python

I need to get the value of _ISSUE_CURRENCY.
I have a JSON which is as below:
{
'#value': 'VR-GROUP PLC',
'_ISSUE_CURRENCY': 'EUR',
'_PRICING_MULTIPLIER': 1,
'_TYPE': 'Debt',
'_SETTLEMENT_CALENDAR_ID': 'Tgt',
'_SUBTYPE': 'Bond',
'_IS_UNIT_TRADED': 'N',
'_ISSUE_STATUS': 'Active',
'_OWNERSHIP_TYPE': 'Unknown',
'_ISSUE_METHOD': 'Unknown',
'_DENOMINATION_CURRENCY': 'EUR'
}
My code so far:
f_asset = open(f"{tempdir}\\cdwassets_all.csv").read().replace("\n", "")
json_obj_asset = json.loads(f_asset, strict=False)
try:
issue_cur = jmespath.search("validatedAsset.assetName", doc)
except:
issue_cur = ''
# currency.append(issue_cur)
print(issue_cur)
# output:
{'#value': 'VR-GROUP PLC', '_ISSUE_CURRENCY': 'EUR', '_PRICING_MULTIPLIER': 1, '_TYPE': 'Debt', '_SETTLEMENT_CALENDAR_ID': 'Tgt', '_SUBTYPE': 'Bond', '_IS_UNIT_TRADED': 'N', '_ISSUE_STATUS': 'Active', '_OWNERSHIP_TYPE': 'Unknown', '_ISSUE_METHOD': 'Unknown', '_DENOMINATION_CURRENCY': 'EUR'}
I tried to do it this way, but without success.
issue_cur = jmespath.search("validatedAsset.assetName", doc)["_ISSUE_CURRENCY"]
print(issue_cur)
# output
{'#value': 'VR-GROUP PLC', '_ISSUE_CURRENCY': 'EUR', '_PRICING_MULTIPLIER': 1, '_TYPE': 'Debt', '_SETTLEMENT_CALENDAR_ID': 'Tgt', '_SUBTYPE': 'Bond', '_IS_UNIT_TRADED': 'N', '_ISSUE_STATUS': 'Active', '_OWNERSHIP_TYPE': 'Unknown', '_ISSUE_METHOD': 'Unknown', '_DENOMINATION_CURRENCY': 'EUR'}
I need to verify that _ISSUE_CURRENCY attribute exists.

You are stating:
I have a JSON which is as below
This is not a JSON, as described in the RFC 7159, describing what is a valid JavaScript Object Notation (JSON), the quotation mark that delimits strings is the character %x22, so a double quote ".reference
This should actually be raised by the json.loads function call of your code already, the script:
import json
json_data = """
{
'validatedAsset': {
'assetName': {
'#value': 'VR-GROUP PLC',
'_ISSUE_CURRENCY': 'EUR',
'_PRICING_MULTIPLIER': 1,
'_TYPE': 'Debt',
'_SETTLEMENT_CALENDAR_ID': 'Tgt',
'_SUBTYPE': 'Bond',
'_IS_UNIT_TRADED': 'N',
'_ISSUE_STATUS': 'Active',
'_OWNERSHIP_TYPE': 'Unknown',
'_ISSUE_METHOD': 'Unknown',
'_DENOMINATION_CURRENCY': 'EUR'
}
}
}
"""
json.loads(json_data, strict=False)
Would raise:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 3 (char 5)
So, I am going to assume that what you are calling a valid JSON is the actual print of the json.loads function, which is then a valid Python dictionary.
So, you just have to modify your JMESPath query to get the _ISSUE_CURRENCY, and make it this query:
validatedAsset.assetName._ISSUE_CURRENCY
Which would give you EUR as a result.
Given the code
import json
import jmespath
json_data = """
{
"validatedAsset": {
"assetName": {
"#value": "VR-GROUP PLC",
"_ISSUE_CURRENCY": "EUR",
"_PRICING_MULTIPLIER": 1,
"_TYPE": "Debt",
"_SETTLEMENT_CALENDAR_ID": "Tgt",
"_SUBTYPE": "Bond",
"_IS_UNIT_TRADED": "N",
"_ISSUE_STATUS": "Active",
"_OWNERSHIP_TYPE": "Unknown",
"_ISSUE_METHOD": "Unknown",
"_DENOMINATION_CURRENCY": "EUR"
}
}
}
"""
print(jmespath.search(
"validatedAsset.assetName._ISSUE_CURRENCY",
json.loads(json_data, strict=False)
))
This yields:
EUR

Related

JSON viewers don't accept my pattern even after dict going through json.dumps() + json.loads()

The result when printing after a = json.dumps(dicter) and print(json.loads(a)) is this:
{
'10432981': {
'tournament': {
'name': 'Club Friendly Games',
'slug': 'club-friendly-games',
'category': {
'name': 'World',
'slug': 'world',
'sport': {
'name': 'Football',
'slug': 'football',
'id': 1
},
'id': 1468,
'flag': 'international'
},
'uniqueTournament': {
'name': 'Club Friendly Games',
'slug': 'club-friendly-games',
'category': {
'name': 'World',
'slug': 'world',
'sport': {
'name': 'Football',
'slug': 'football',
'id': 1
},
'id': 1468,
'flag': 'international'
},
'userCount': 0,
'hasPositionGraph': False,
'id': 853,
'hasEventPlayerStatistics': False,
'displayInverseHomeAwayTeams': False
},
'priority': 0,
'id': 86
}
}
}
But when trying to read in any json viewer, they warn that the format is incorrect but don't specify where the problem is.
If it doesn't generate any error when converting the dict to JSON and not even when reading it, why do views warn of failure?
You must enclose the strings using double quotes ("). The json.loads returns a python dictionary, so it is not a valid JSON object. If you want to get valid JSON you can get the string that json.dumps returns.

How to convert a DynamoDB Json in a regular JSON in Python?

I get a json from DynamoDB and that is the format:
payload_stack = {'Records': [{'eventID': '123456', 'eventName': 'INSERT', 'eventVersion': '1.1',
'eventSource': 'aws:dynamodb', 'awsRegion': 'sa-east-1',
'dynamodb': {'ApproximateCreationDateTime': 1644956685.0,
'Keys': {'body_field': {'N': '1931'}},
'NewImage': {'body_field': {'N': '1931'}, 'txt_vlr_parm_requ': {'M': {
'headers': {'M': {'Authorization': {
'S': 'token'},
'correlationID': {'S': '987654321'}}},
'requestContext': {
'M': {'requestId': {'S': '123'}}},
'body': {'M': {'avro_schema': {
'S': '{"type":"record","namespace":"Tutorialspoint","name":"Employee","fields":[{"name":"Name","type":"string"},{"name":"Age","type":"int"}, {"name":"Address","type":"string"}, {"name":"Role","type":"string"} ]}'},
'cluster': {'S': 'events'}, 'sigla': {'S': 'ft7'},
'subject': {'S': 'teste-dynamo'},
'branch': {'S': 'development'},
'id_requisicao': {'N': '1818'}}}}},
'nom_tabe': {'S': 'tabela_teste'},
'cod_situ_psst_ingo': {'S': 'NOVO'}, 'historic': {
'S': '{"historico": [{"data/hora": "09-02-22 18:18:41", "status": "NOVO"}]}'},
'nom_arqu_bckt': {'S': 'arquivo.avro'}},
'SequenceNumber': '87226300000000005691898607', 'SizeBytes': 1672,
'StreamViewType': 'NEW_IMAGE'},
'eventSourceARN': 'arn:aws'}]}
However I need to convert into a regular json and take only the 'body' field, for example:
'body': {
"cluster": "events",
"subject": "teste-dynamo",
"id_requisition": 1818,
"branch": "development",
}
To catch the body field I can imagine how to do, like getting indexes on Python.
But any idea how can I convert this DYNAMODB JSON in a regular JSON?
Thanks.
I authored a library called cerealbox that makes it easier to perform this common conversion as follows.
from cerealbox.dynamo import from_dynamodb_json
# convert the DynamoDB image to a regular python dictionary
result = from_dynamodb_json(payload_stack['Records'][0]['dynamodb']['NewImage'])
# access the body as a regular dictionary
body = result['txt_vlr_parm_requ']['body']
The documentation covers how to perfom the inverse using as_dynamodb_json.
This can also be done using boto3's TypeDeserializer/TypeSerializer - a good example of this can be found here
I was able to develop a little code to convert this DynamoDB json into a regular json.
I used the dynamodb_json import.
##that one in the question
payload_stack = {...}
convert_regular_json = json.loads(payload_stack)
print(convert_regular_json)
The output:
{
'Records': [{
'eventID': '123456',
'eventName': 'INSERT',
'eventVersion': '1.1',
'eventSource': 'aws:dynamodb',
'awsRegion': 'sa-east-1',
'dynamodb': {
'ApproximateCreationDateTime': 1644956685.0,
'Keys': {
'body_field': 1931
},
'NewImage': {
'body_field': 1931,
'txt_vlr_parm_requ': {
'headers': {
'Authorization': 'token',
'correlationID': '987654321'
},
'requestContext': {
'requestId': '123'
},
'body': {
'avro_schema': '{"type":"record","namespace":"Tutorialspoint","name":"Employee","fields":[{"name":"Name","type":"string"},{"name":"Age","type":"int"}, {"name":"Address","type":"string"}, {"name":"Role","type":"string"} ]}',
'cluster': 'events',
'sigla': 'ft7',
'subject': 'teste-dynamo',
'branch': 'development',
'id_requisicao': 1818
}
},
'nom_tabe': 'tabela_teste',
'cod_situ_psst_ingo': 'NOVO',
'historic': '{"historico": [{"data/hora": "09-02-22 18:18:41", "status": "NOVO"}]}',
'nom_arqu_bckt': 'arquivo.avro'
},
'SequenceNumber': '87226300000000005691898607',
'SizeBytes': 1672,
'StreamViewType': 'NEW_IMAGE'
},
'eventSourceARN': 'arn:aws'
}]
}
And to catch the 'body' field:
catch_body_payload = var['Records'][0].get('dynamodb').get('NewImage').get('txt_vlr_parm_requ').get('body')

API connection and getting the returned result

I'm sorry for my bad english
Hello, I am using a brokerage firm for payment instrument. The API connection is successful and I get the result. But I can't use the returned result information.
payment_card = {
'cardHolderName': kartisim,
'cardNumber': kartno,
'expireMonth': kartskt_ay,
'expireYear': '2030',
'cvc': karcvc,
'registerCard': '0'
}
buyer = {
'id': adres.id,
'name': adres.adres_uye.username,
'surname': 'Doe',
'gsmNumber': '+905350000000',
'email': adres.adres_uye.email,
'identityNumber': '74300864791',
'lastLoginDate': '2015-10-05 12:43:35',
'registrationDate': '2013-04-21 15:12:09',
'registrationAddress': adres.adres_detay,
'ip': '85.34.78.112',
'city': 'Istanbul',
'country': 'Turkey',
'zipCode': '34732'
}
address = {
'contactName': 'Jane Doe',
'city': 'Istanbul',
'country': 'Turkey',
'address': 'Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1',
'zipCode': '34732'
}
basket_items = []
for bas in uye:
basa = {
'id': str(bas.id),
'name': str(bas.sepet_urun.urun_baslik),
'category1': str(bas.sepet_urun.urun_anakategori.anakategori_baslik),
'category2': str(bas.sepet_urun.urun_altkategori.altkategori_baslik),
'itemType': 'VIRTUAL',
'price': str(bas.sepet_fiyat)
}
basket_items.append(basa)
print(basket_items)
request_payload = {
'locale': 'tr',
'conversationId': '123456789',
'price': str(sepetf),
'paidPrice': str(sepetf),
'currency': 'TRY',
'installment': '1',
'basketId': str(sepetid),
'paymentChannel': 'WEB',
'paymentGroup': 'PRODUCT',
'paymentCard': payment_card,
'buyer': buyer,
'shippingAddress': address,
'billingAddress': address,
'basketItems': basket_items
}
payment = iyzipay.Payment().create(request_payload, options)
print(payment.read().decode('utf-8'))
return HttpResponse(payment["status"])
I cannot use the returned result information. The returned result is as follows
The error I get is as follows:
'HTTPResponse' object is not subscriptable
Looks like the issue is here.
return HttpResponse(payment["status"])
payment returns an HTTPResponse response object and you cannot directly index the status. Instead you should use .status attribute.
If your intention is to return JSON back as response you could use JsonResponse class from django.http module.
return JsonResponse(json.loads(payment.read().decode('utf-8')))

How to iterate over a JSON array and get values for a key which itself is a JSON object

I have been trying to do something simple yet something hard for me to solve it!
I have a json object that looks like:
jsonObject = {
'attributes': {
'192': { <--- This can be changed times to times meaning different number
'id': '192',
'code': 'hello',
'label': 'world',
'options': [
{
'id': '211',
'label': '5'
},
{
'id': '1202',
'label': '8.5'
},
{
'id': '54',
'label': '9'
},
{
'id': '1203',
'label': '9.5'
},
{
'id': '58',
'label': '10'
}
]
}
},
'template': '12345',
'basePrice': '51233',
'oldPrice': '51212',
'productId': 'hello',
}
and what I want to do is to get the values from options (To have both id and label saved into a list)
For now I only managed to do:
for att, value in jsonObject.items():
print(f"{att} - {value}"
How can I get the label and id?
You can try the following code:
attr = jsonObject['attributes']
temp = list(attr.values())[0] # It is same as "temp = attr['192']", but you said '192' can be changed.
options = temp['options']
for option in options:
print(f"id: {option['id']}, label: {option['label']}")

Converting to list of dictionary

I have a text file filled with place data provided by twitter api. Here is the sample data of 2 lines
{'country': 'United Kingdom', 'full_name': 'Dorridge, England', 'id': '31fe56e2e7d5792a', 'country_code': 'GB', 'name': 'Dorridge', 'attributes': {}, 'contained_within': [], 'place_type': 'city', 'bounding_box': {'coordinates': [[[-1.7718518, 52.3635912], [-1.7266702, 52.3635912], [-1.7266702, 52.4091167], [-1.7718518, 52.4091167]]], 'type': 'Polygon'}, 'url': 'https://api.twitter.com/1.1/geo/id/31fe56e2e7d5792a.json'}
{'country': 'India', 'full_name': 'New Delhi, India', 'id': '317fcc4b21a604d5', 'country_code': 'IN', 'name': 'New Delhi', 'attributes': {}, 'contained_within': [], 'place_type': 'city', 'bounding_box': {'coordinates': [[[76.84252, 28.397657], [77.347652, 28.397657], [77.347652, 28.879322], [76.84252, 28.879322]]], 'type': 'Polygon'}, 'url': 'https://api.twitter.com/1.1/geo/id/317fcc4b21a604d5.json'}
I want 'country', 'name' and 'cordinates' filed of each line.In order to do this we need to iterate line by line the entire file.so i append each line to a list
data = []
with open('place.txt','r') as f:
for line in f:
data.append(line)
when i checked the data type it shows as 'str' instead of 'dict'.
type(data[0])
str
data[0].keys()
AttributeError: 'str' object has no attribute 'keys'
how to fix this so that it can be saved as list of dictionaries.
Originally tweets were encoded and decoded by following code:
f.write(jsonpickle.encode(tweet._json, unpicklable=False) + '\n') #encoded and saved to a .txt file
tweets.append(jsonpickle.decode(line)) # decoding
And place data file is saved by following code:
fName = "place.txt"
newLine = "\n"
with open(fName, 'a', encoding='utf-8') as f:
for i in range(len(tweets)):
f.write('{}'.format(tweets[i]['place']) +'\n')
In your case you should use json to do the data parsing. But if you have a problem with json (which is almost impossible since we are talking about an API ), then in general to convert from string to dictionary you can do:
>>> import ast
>>> x = "{'country': 'United Kingdom', 'full_name': 'Dorridge, England', 'id': '31fe56e2e7d5792a', 'country_code': 'GB', 'name': 'Dorridge', 'attributes': {}, 'contained_within': [], 'place_type': 'city', 'bounding_box': {'coordinates': [[[-1.7718518, 52.3635912], [-1.7266702, 52.3635912], [-1.7266702, 52.4091167], [-1.7718518, 52.4091167]]], 'type': 'Polygon'}, 'url': 'https://api.twitter.com/1.1/geo/id/31fe56e2e7d5792a.json'}
"
>>> d = ast.literal_eval(x)
>>> d
d now is a dictionary instead of a string.
But again if your data are in json format python has a built-in lib to handle json format, and is better and safer to use json than ast.
For example if you get a response let's say resp you could simply do:
response = json.loads(resp)
and now you could parse response as a dictionary.
Note: Single quotes are not valid JSON.
I have never tried Twitter API. Looks like your data are not valid JSON. Here is a simple preprocess method to replace '(single quote) into "(double quote)
data = "{'country': 'United Kingdom', ... }"
json_data = data.replace('\'', '\"')
dict_data = json.loads(json_data)
dict_data.keys()
# [u'full_name', u'url', u'country', ... ]
You should use python json library for parsing and getting the value.
In python it's quite easy.
import json
x = '{"country": "United Kingdom", "full_name": "Dorridge, England", "id": "31fe56e2e7d5792a", "country_code": "GB", "name": "Dorridg", "attributes": {}, "contained_within": [], "place_type": "city", "bounding_box": {"coordinates": [[[-1.7718518, 52.3635912], [-1.7266702, 52.3635912], [-1.7266702, 52.4091167], [-1.7718518, 52.4091167]]], "type": "Polygon"}, "url": "https://api.twitter.com/1.1/geo/id/31fe56e2e7d5792a.json"}'
y = json.loads(x)
print(y["country"],y["name"],y["bounding_box"]["coordinates"])
You can use list like this
mlist= list()
for i in ndata.keys():
mlist.append(i)

Categories

Resources