I have two jsons as follows: json1:This is the payload I am submitting to an API
{
"id": 0,
"object_type": "SCHEMA",
"object_meta": {
"source_id": 1002,
"database": "raw_exadata",
"schema": "clv"
},
"business_name": "",
"business_logic": "",
"verified_use_cases": ["p"],
"classifications": ["bb464f04-f879-361c-95e5-42bcca6a9535"]
}
,
{
"id": 1,
"object_type": "TABLE",
"object_meta": {
"source_id": 1002,
"database": "raw",
"schema": "clv",
"table": "clv_cust"
},
"business_name": "",
"business_logic": "",
"verified_use_cases": [],
"classifications": ["p"],
}
]
json2: this is the response of an API call which tells me the error in the data that was posted
{
"errors": {
"0": {
"verified_use_cases": {
"0": [
"Not a valid UUID."
]
}
},
"1": {
"classifications": {
"0": [
"Not a valid UUID."
]
}
}
}
}
I want to produce a very user friendly response to the posted payload stating such and such an object has an invalid entry hence it has failed.
For the above, I need to map (or lookup) on the "id" from json2 to json1 and fetch the object_type and also that the entry in the verified_use_cases, classifications is wrong with corresponding id.
What I have tried so far:
from collections import defaultdict
p=json.loads(response.text)
result=defaultdict(list)
for i in p['errors']:
result['obj_id'].append(int(i))
result['error'].append(p['errors'][i])
Now this gives me the object_id, but I am not sure how I can map it further with json1.
Kindly help.
PS: the fields, verified use cases, classifications are all multi valued with comma separated actually, hence you can see the "0" int the error json
Thanks in advance
CodePudding user response:
You should consider a couple of things in mind:
- When you are working with APIs, make sure that you use some kind of validation or preprocesses, I suggest you to use
Pydantic
with it's validators and easiest ways of converting any json to necessary class. - Example of using
pydantic
with your code, example will be below. - Taking look at docs, here it is: https://pydantic-docs.helpmanual.io/
And as a result when you'd like to create any of these defined classes you can do:
parse_obj_as(ApiObject, response.json)
Example:
class ApiObject(BaseModel):
id: int = Field(alias="id")
object_type: str = Field(alias="object_type")
object_meta: ObjectMeta = Field(alias="object_meta") # Same class with it's defined fields
business_name: str = Field(alias="business_name")
business_logic: str = Field(alias="business_logic")
verified_use_cases: List[str] = Field(alias="verified_use_cases")
classifications: List[str] = Field(alias="classification")
CodePudding user response:
json1 = [{
"id": 0,
"object_type": "SCHEMA",
"object_meta": {
"source_id": 1002,
"database": "raw_exadata",
"schema": "clv"
},
"business_name": "",
"business_logic": "",
"verified_use_cases": ["p"],
"classifications": ["bb464f04-f879-361c-95e5-42bcca6a9535"]
}
,
{
"id": 1,
"object_type": "TABLE",
"object_meta": {
"source_id": 1002,
"database": "raw",
"schema": "clv",
"table": "clv_cust"
},
"business_name": "",
"business_logic": "",
"verified_use_cases": [],
"classifications": ["p"],
}
]
json2 = {
"errors": {
"0": {
"verified_use_cases": {
"0": [
"Not a valid UUID."
]
}
},
"1": {
"classifications": {
"0": [
"Not a valid UUID."
]
}
}
}
}
resp = {}
for record in json1:
key = str(record["id"])
if key in json2["errors"]:
record['errors'] = json2["errors"][key]#adding json2
resp[key] = record
Response
print(json.dumps(resp))
{
"0": {
"id": 0,
"object_type": "SCHEMA",
"object_meta": {
"source_id": 1002,
"database": "raw_exadata",
"schema": "clv"
},
"business_name": "",
"business_logic": "",
"verified_use_cases ": ["p "],
"classifications ": ["bb464f04 - f879 - 361 c - 95e5 - 42 bcca6a9535 "],
"errors ": {
"verified_use_cases ": {
"0 ": ["Not a valid UUID."]
}
}
},
"1 ": {
"id ": 1,
"object_type ": "TABLE ",
"object_meta ": {
"source_id ": 1002,
"database ": "raw ",
"schema ": "clv ",
"table ": "clv_cust "
},
"business_name ": "",
"business_logic ": "",
"verified_use_cases ": [],
"classifications": ["p"],
"errors": {
"classifications": {
"0": ["Not a valid UUID."]
}
}
}
}