Reputation: 1339
I am working with Python for the 1st time and wondering what would be the best way to do access fields in json strings.
I have a use case of extracting fields from array inside array kind of structure. I am able to get the value out of it using multiple for
s & if
s using the dict
's general ideology, but I assume there could be better ways provided by Python or Python's JSON library itself to do the same (something similar to the jq bash library's select), hence the question.
Below is the sample of my input and output
Code & Input
import json
def get_auth_ref(auth_policy_json: str) -> str:
auth_policy_json_obj = json.loads(auth_policy_json)
auth_policy_rules = auth_policy_json_obj["spec"]["rules"]
for rule in auth_policy_rules:
if "when" in rule:
conditions = rule["when"]
for condition in conditions:
if condition["key"] == "request.headers[x-api-key]":
return condition["values"][0]
# some JSON:
auth_policy_json = '''{
"apiVersion": "security.istio.io/v1beta1",
"kind": "AuthorizationPolicy",
"metadata": {
"name": "some-policy",
"namespace": "some-namespace"
},
"spec": {
"action": "ALLOW",
"rules": [
{
"to": [
{
"operation": {
"methods": [
"GET"
],
"paths": [
"/docs",
"/openapi.json",
"/redoc"
]
}
}
]
},
{
"to": [
{
"operation": {
"methods": [
"GET"
],
"paths": [
"/healthz*",
"/metrics*"
]
}
}
],
"when": [
{
"key": "request.headers[User-Agent]",
"values": [
"Knative-Activator-Probe",
"Go-http-client/1.1"
]
}
]
},
{
"when": [
{
"key": "request.headers[x-api-key]",
"values": [
"sample-api-key"
]
}
]
}
],
"selector": {
"matchLabels": {
"serving.knative.dev/service": "some-service"
}
}
}
}'''
print(get_auth_ref(auth_policy_json))
Output
sample-api-key
Upvotes: 0
Views: 389
Reputation: 1928
jsonpath-ng
can parse even such a nested json object very easily. It can be installed by the following command:
pip install --upgrade jsonpath-ng
import json
from jsonpath_ng.ext import parse
# Load the sample as dict
data = json.loads(auth_policy_json)
# Define an expression of a json path and search the target value
expr = parse(r'$..*[?key="request.headers[x-api-key]"]')
api_key = expr.find(data)[0].value['values'][0]
print(api_key)
# Define an expression of a more specific json path and search the target value
expr = parse(r'$.spec.rules.[*].when[?key="request.headers[x-api-key]"]')
api_key = expr.find(data)[0].value['values'][0]
print(api_key)
sample-api-key
sample-api-key
Upvotes: 1