BGP-Ranking/bgpranking/querying.py

72 lines
2.9 KiB
Python
Raw Normal View History

2018-04-10 21:27:35 +02:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import TypeVar
2018-04-10 23:22:32 +02:00
import datetime
2018-04-10 21:27:35 +02:00
from dateutil.parser import parse
import logging
from redis import StrictRedis
from .libs.helpers import get_socket_path
from .libs.exceptions import InvalidDateFormat
2018-04-10 21:27:35 +02:00
2018-04-10 23:22:32 +02:00
Dates = TypeVar('Dates', datetime.datetime, datetime.date, str)
2018-04-10 21:27:35 +02:00
class Querying():
2018-04-10 21:27:35 +02:00
def __init__(self, loglevel: int=logging.DEBUG):
self.__init_logger(loglevel)
self.storage = StrictRedis(unix_socket_path=get_socket_path('storage'), decode_responses=True)
self.ranking = StrictRedis(unix_socket_path=get_socket_path('storage'), db=1, decode_responses=True)
self.asn_meta = StrictRedis(unix_socket_path=get_socket_path('storage'), db=2, decode_responses=True)
def __init_logger(self, loglevel: int):
self.logger = logging.getLogger(f'{self.__class__.__name__}')
self.logger.setLevel(loglevel)
def __normalize_date(self, date: Dates):
2018-04-10 23:22:32 +02:00
if isinstance(date, datetime.datetime):
2018-04-10 21:27:35 +02:00
return date.date().isoformat()
2018-04-10 23:22:32 +02:00
elif isinstance(date, datetime.date):
2018-04-10 21:27:35 +02:00
return date.isoformat()
elif isinstance(date, str):
try:
return parse(date).date().isoformat()
except ValueError:
raise InvalidDateFormat('Unable to parse the date. Should be YYYY-MM-DD.')
2018-04-12 18:09:04 +02:00
def asns_global_ranking(self, date: Dates=datetime.date.today(), source: str='', ipversion: str='v4', limit: int=100):
2018-04-10 21:27:35 +02:00
'''Aggregated ranking of all the ASNs known in the system, weighted by source.'''
d = self.__normalize_date(date)
2018-04-12 18:09:04 +02:00
if source:
key = f'{d}|{source}|asns|{ipversion}'
else:
key = f'{d}|asns|{ipversion}'
2018-04-10 21:27:35 +02:00
return self.ranking.zrevrange(key, start=0, end=limit, withscores=True)
2018-04-12 18:09:04 +02:00
def asn_details(self, asn: int, date: Dates= datetime.date.today(), source: str='', ipversion: str='v4'):
2018-04-10 21:27:35 +02:00
'''Aggregated ranking of all the prefixes anounced by the given ASN, weighted by source.'''
d = self.__normalize_date(date)
2018-04-12 18:09:04 +02:00
if source:
2018-04-12 18:29:44 +02:00
key = f'{d}|{source}|{asn}|{ipversion}|prefixes'
2018-04-12 18:09:04 +02:00
else:
key = f'{d}|{asn}|{ipversion}'
2018-04-10 21:27:35 +02:00
return self.ranking.zrevrange(key, start=0, end=-1, withscores=True)
2018-04-12 18:09:04 +02:00
def asn_rank(self, asn: int, date: Dates= datetime.date.today(), source: str='', ipversion: str='v4'):
2018-04-10 21:27:35 +02:00
'''Get the rank of a single ASN, weighted by source.'''
d = self.__normalize_date(date)
2018-04-12 18:09:04 +02:00
if source:
2018-04-12 18:29:44 +02:00
key = f'{d}|{source}|{asn}|{ipversion}'
2018-04-12 18:09:04 +02:00
else:
key = f'{d}|asns|{ipversion}'
return self.ranking.zscore(key, asn)
2018-04-10 21:27:35 +02:00
2018-04-12 18:09:04 +02:00
def get_sources(self, date: Dates= datetime.date.today()):
'''Get the sources availables for a specific day (default: today).'''
2018-04-10 21:27:35 +02:00
d = self.__normalize_date(date)
2018-04-12 18:09:04 +02:00
key = f'{d}|sources'
return self.storage.smembers(key)