RIPE-NCC / ripe-atlas-sagan

A parsing library for RIPE Atlas measurement results
GNU General Public License v3.0
48 stars 25 forks source link

Could not decode DNS results #78

Closed pavel-odintsov closed 7 years ago

pavel-odintsov commented 8 years ago

Hello!

I'm trying to decode this file: RIPE-Atlas-measurement-6929346.json.zip

This way:

from ripe.atlas.sagan import DnsResult

f = open('/Users/pavel/Downloads/RIPE-Atlas-measurement-6929346.json', 'r+')
contents = f.read()
my_result = DnsResult.get(contents)

But it's not working as expected:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/pavel/anaconda/lib/python2.7/site-packages/ripe/atlas/sagan/base.py", line 235, in get
    kind = raw_data["type"].lower()
TypeError: list indices must be integers, not str

Could you help me?

pavel-odintsov commented 8 years ago

I got this data from my measurement here: https://atlas.ripe.net/api/v2/measurements/6929346/results?start=1478563200&stop=1478649599&format=json

astrikos commented 8 years ago

Hi @pavel-odintsov, you need to pass a single result in the get function. What you pass is a list like string. Try something like this:

import json
contents=json.load(contents)
result = DnsResult.get(contents[0])

The get function can understand str as well, as long as it is in the right json format. For more details you can see docs

pavel-odintsov commented 8 years ago

Oh, great! It's working ;) Thank a lot!

danielquinn commented 8 years ago

I see this sort of question a lot. Maybe it's worth considering implementing something like Result.get_list()?

pavel-odintsov commented 8 years ago

Yep, it will be pretty useful!

astrikos commented 8 years ago

@danielquinn I would put that somewhere in helpers and not on Result class. It will be misleading having method for multiple results in a class called Result. We also have the fragmented version of results. So something like the following would work nicely as well:

with open("RIPE-Atlas-measurement-6929346.json", "r") as f:
    for line in f:
        my_result = DnsResult.get(line)

where file comes from https://atlas.ripe.net/api/v2/measurements/6929346/results?start=1478563200&stop=1478649599&format=txt (Notice the format change to txt)

danielquinn commented 8 years ago

I dunno, a class method that returns multiple instances of said class isn't all that strange, and it might help with how people tend to make use of the library. I mean, this is probably the most common problem I hear from people using it: they try to pass in a JSON blob containing multiple results and don't understand what they did wrong.

Something like Result.get_multiple(<raw json>) might go a long way to fixing that. either that, or a more expressive error message that tells you what you did wrong when you pass multiple instances to .get(). Maybe the latter option is better considering the former would allow people to make some terrible mistakes in their own code.

I didn't mean to hijack the issue though, so feel free to close this. I just thought it worth mentioning as this is easily the 20th time I've heard someone make this mistake.