peeringdb / peeringdb-py

PeeringDB python client
BSD 2-Clause "Simplified" License
89 stars 22 forks source link

Inconsistencies between Client and API #71

Open ericat opened 1 year ago

ericat commented 1 year ago

Hello, querying the Network ('net') resource with .get and ASN id does not seem to yield the same result when compared to the api. e.g. curl https://www.peeringdb.com/api/net/14854 vs:pdb.get(resource.Network, 14854).

The latter is missing several nested fields such as netfac_set and netixlan_set. Other fields, such as org, seems to only contain an id.

Another example - the NetworkIXLan resource cannot be queried with ix_id (i.e. does not have that field) as filter (unlike the API):

peeringdb-client-flask-1  | django.core.exceptions.FieldError: Cannot resolve keyword 'ix_id' into field. Choices are: asn, created, id, ipaddr4, ipaddr6, is_rs_peer, ixlan, ixlan_id, net, net_id, notes, operational, speed, status, updated, version

Some resources are just missing fields (when compared to the API), e.g. InternetExchange is missing the name / name long etc, they're just not added in the models in your django-peeringdb repo.

grizz commented 1 year ago

@ericat are you using the provided django concrete models? As far as I know, all the data is loaded from the API.

ericat commented 1 year ago

Hello Matt, sorry it has been a while, I put together a simple Flask app as an example:

from flask import Flask, request
from django.forms.models import model_to_dict
from django.core import serializers
from peeringdb import resource
from peeringdb.client import Client

import json

pdb = Client()

app = Flask(__name__)

#  Get by pk (private key) routes
@app.route('/net/<pk>', methods=['GET'])
def get_net_by(pk):
    obj = pdb.get(resource.Network, pk)
    return json.loads(serializers.serialize('json', [obj]))

if __name__ == "__main__":
    app.run()

if I run then curl this with curl http://127.0.0.1:5000/net/14854 | jq . then I get

[
  {
    "fields": {
      "aka": "",
      "asn": 6752,
      "created": "2017-10-05T10:33:05",
      "info_ipv6": true,
      "info_multicast": false,
      "info_never_via_route_servers": false,
      "info_prefixes4": 40,
      "info_prefixes6": 1,
      "info_ratio": "Mostly Inbound",
      "info_scope": "Regional",
      "info_traffic": "20-50Gbps",
      "info_type": "NSP",
      "info_unicast": true,
      "irr_as_set": "AS6752",
      "looking_glass": "",
      "name": "ANDORRA TELECOM",
      "name_long": "",
      "notes": "",
      "notes_private": "",
      "org": 18174,
      "policy_contracts": "Not Required",
      "policy_general": "Open",
      "policy_locations": "Not Required",
      "policy_ratio": false,
      "policy_url": "",
      "rir_status": "ok",
      "rir_status_updated": "2022-07-27T05:29:57.260",
      "route_server": "",
      "social_media": {},
      "status": "ok",
      "status_dashboard": null,
      "updated": "2022-07-27T05:33:25",
      "version": 0,
      "website": "https://www.andorratelecom.ad"
    },
    "model": "django_peeringdb.network",
    "pk": 14854
  }
]

Is django_peeringdb.network the correct model?

If you compare the output with curl https://www.peeringdb.com/api/net/14854 | jq . you will see I'm missing some fields (including the nested ones). What am I doing wrong? Thank you.

grizz commented 1 year ago

@ericat

The PDB curl is a depth=1 or 2 query, you should be comparing it against:

curl https://www.peeringdb.com/api/net/14854?depth=0 | jq .
ericat commented 1 year ago

hi Matt, yes that's fair enough. I can see from the code you do have a fetch that we can use a depth with. However that goes via the API, while the purpose of setting this up is to go through our local copy (see here https://docs.peeringdb.com/howto/work_within_peeringdbs_query_limits/ 'local cache'). There doesn't seem to be a depth argument for get, I suppose I was asking for confirmation on that.