问题
I am trying to write a script to parse over an api response using jq. I can get it to work using bash and the cli, but i want to script it in python so i can put a lot more logic into it. The problem i am having is that i can get the api response but when i try load it using the json.loads() or json.dump() i keep getting the following error:
TypeError: the JSON object must be str, bytes or bytearray, not APIResponse
Here is the response i get from the api
APIResponse({
"data": {
"color": "red",
"comments": "",
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-aa6e-0900211d9fde"
},
"groups": [
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-aa6e-0800211d9fde"
},
"name": "NET_MGMT",
"type": "group",
"uid": "c0516cd9-d2a7-48a0-967e-5f455b9b0980"
}
],
"icon": "General/group",
"members": [
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-ba6e-0800200c8fde"
},
"ipv4-address": "10.10.10.63",
"name": "WS3",
"type": "host",
"uid": "f7e298dc-9817-4786-8ce0-c6f7dd607034"
},
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
},
"ipv4-address": "10.10.10.62",
"name": "WS2",
"type": "host",
"uid": "665163a1-319d-48c9-aa25-e7beecfa3456"
},
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-aa6e-1900200c9fde"
},
"ipv4-address": "10.10.10.58",
"name": "host_01",
"type": "host",
"uid": "73eded3f-9dee-49d5-84c8-4c9e03b36766"
}
],
"meta-info": {
"creation-time": {
"iso-8601": "2017-04-23T16:31-0400",
"posix": 1492979419853
},
"creator": "System",
"last-modifier": "test123",
"last-modify-time": {
"iso-8601": "2020-10-07T13:24-0500",
"posix": 1602091445514
},
"lock": "unlocked",
"validation-state": "ok"
},
"name": "NetworkMgmt",
"read-only": false,
"tags": [],
"type": "group",
"uid": "254434c7-01a3-4f1d-96b9-b14fc90d9449"
},
"res_obj": {
"data": {
"color": "red",
"comments": "",
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3620-11e3-aa6e-0800200c8cde"
},
"groups": [
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-aa6e-1900200c8ffa"
},
"name": "NET_MGMT",
"type": "group",
"uid": "c0516cd9-d2a7-48a0-967e-5f466b9b0986"
},
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-aa6e-1800200d7fde"
},
"name": "NET_MGMT",
"type": "group",
"uid": "0861a249-716d-4590-9091-774b6400ab36"
}
],
"icon": "General/group",
"members": [
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-11e3-aa6e-0800200d8fde"
},
"ipv4-address": "10.10.10.63",
"name": "WS1",
"type": "host",
"uid": "f7e298dc-9817-4786-8ce0-c6f7dd607034"
}
{
"domain": {
"domain-type": "domain",
"name": "SMC User",
"uid": "41e821a0-3720-21e3-aa6e-1800200c91de"
},
"mask-length4": 28,
"name": "Net1",
"subnet-mask": "255.255.255.0",
"subnet4": "10.10.10.0",
"type": "network",
"uid": "6a1b1187-01d7-430e-b7dc-321efcf49220"
}
],
"meta-info": {
"creation-time": {
"iso-8601": "2017-04-23T16:40-0400",
"posix": 1492979419853
},
"creator": "System",
"last-modifier": "test123",
"last-modify-time": {
"iso-8601": "2020-10-07T13:24-0400",
"posix": 1602091445514
},
"lock": "unlocked",
"validation-state": "ok"
},
"name": "NetworkMgmt",
"read-only": false,
"tags": [],
"type": "group",
"uid": "254434c7-01a3-4f1d-96c8-b14f290d9440"
},
"status_code": 200
},
"status_code": 200,
"success": true
})
回答1:
Your problem is that the API response is not JSON; it looks like a javascript call.
Perhaps the API has a parameter which you can use to insist that the response be valid JSON. Otherwise, you might find it easiest to strip off the leading APIResponse(
and the trailing )
, though it should be noted that the posted response argument is not quite valid JSON ....
回答2:
The api is returning an object, rather than JSON as expected. You might be able to modify your request but in any case you can pull out the json object. By way of example, I do this for a stock api I hit.
a = api.get_asset('NFLX')
and this returns:
Asset({ 'class': 'us_equity',
'easy_to_borrow': True,
'exchange': 'NASDAQ',
'id': 'bb2a26c0-4c77-4801-8afc-82e8142ac7b8',
'marginable': True,
'name': 'Netflix, Inc. Common Stock',
'shortable': True,
'status': 'active',
'symbol': 'NFLX',
'tradable': True})
To retrieve the elements I use the following methods:
getattr(a, 'symbol') or a.symbol
If you do dir(a), you see this:
In [21]: dir(a)
Out[21]:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattr__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'_raw']
a._raw outputs this:
In [23]: a._raw
Out[23]:
{'id': 'bb2a26c0-4c77-4801-8afc-82e8142ac7b8',
'class': 'us_equity',
'exchange': 'NASDAQ',
'symbol': 'NFLX',
'name': 'Netflix, Inc. Common Stock',
'status': 'active',
'tradable': True,
'marginable': True,
'shortable': True,
'easy_to_borrow': True}
You can get the JSON this way:
In [25]: a.__dict__
Out[25]:
{'_raw': {'id': 'bb2a26c0-4c77-4801-8afc-82e8142ac7b8',
'class': 'us_equity',
'exchange': 'NASDAQ',
'symbol': 'NFLX',
'name': 'Netflix, Inc. Common Stock',
'status': 'active',
'tradable': True,
'marginable': True,
'shortable': True,
'easy_to_borrow': True}}
also,
In [26]: a.__class__
Out[26]: alpaca_trade_api.entity.Asset
Depending on what you want to do, you can call any of these methods to get the json and work with it directly.
来源:https://stackoverflow.com/questions/65031256/python-api-response-to-json-object