def api_analytics(request, api_calls_display='chart', api_calls_interval='yearly', api_id=None, api_name=None): if api_id is None and api_name is None: return HttpResponseBadRequest('Must specify API id or name.') try: api = resolve_model(Api, [('id', api_id), ('name', api_name)]) except Api.DoesNotExist: return HttpResponseNotFound('The requested API was not found.') ignore_internal_keys = request.GET.get('ignore_internal_keys', True) options = { 'api': { 'id': api.id, 'name': api.name }, 'ignore_internal_keys': ignore_internal_keys, 'api_calls_display': api_calls_display, 'api_calls_interval': api_calls_interval } ctx = { 'api': api, 'options': options, 'json_options': json.dumps(options), 'LOCKSMITH_BASE_TEMPLATE': settings.LOCKSMITH_BASE_TEMPLATE } template = getattr(settings, 'LOCKSMITH_API_ANALYTICS_TEMPLATE', 'locksmith/api_analytics.html') return render(request, template, ctx)
def calls_to_api_daily(request, api_id=None, api_name=None): if api_id is None and api_name is None: return HttpResponseBadRequest("Must specify API id or name.") try: api = resolve_model(Api, [("id", api_id), ("name", api_name)]) except Api.DoesNotExist: return HttpResponseNotFound("The requested API was not found.") ignore_internal_keys = parse_bool_param(request, "ignore_internal_keys", True) end_date = parse_date_param(request, "end_date") begin_date = end_date - datetime.timedelta(days=7) qry = Report.objects.filter(api=api) if ignore_internal_keys: qry = exclude_internal_key_reports(qry) qry = qry.filter(date__gte=begin_date, date__lte=end_date) agg = qry.aggregate(calls=Sum("calls")) daily_aggs = qry.values("date").annotate(calls=Sum("calls")) result = {"api_id": api.id, "api_name": api.name, "calls": agg["calls"], "daily": []} for d in daily_aggs: result["daily"].append({"date": d["date"].strftime("%m-%d-%Y"), "calls": d["calls"]}) return HttpResponse(content=json.dumps(result), status=200, content_type="application/json")
def quarterly_leaderboard(request, year, month, api_id=None, api_name=None): try: api = resolve_model(Api, [("id", api_id), ("name", api_name)]) except Api.DoesNotExist: api = None ignore_internal_keys = parse_bool_param(request, "ignore_internal_keys", True) ignore_autoactivated_keys = parse_bool_param(request, "ignore_autoactivated_keys", True) year = int(year) month = int(month) (begin_date, end_date) = _dates_for_quarter(year, month) (prev_year, prev_month) = _start_of_previous_quarter(year, month) (prev_begin_date, prev_end_date) = _dates_for_quarter(prev_year, prev_month) callers = _callers_in_period(begin_date, end_date, api=api) prev_callers = _callers_in_period( prev_begin_date, prev_end_date, api=api, ignore_internal_keys=ignore_internal_keys, ignore_autoactivated_keys=ignore_autoactivated_keys, ) leaderboard = _leaderboard_diff(prev_callers, callers) result = { "earliest_date": begin_date.strftime("%Y-%m-%d"), "latest_date": end_date.strftime("%Y-%m-%d"), "by_key": leaderboard, } return HttpResponse(content=json.dumps(result), status=200, content_type="application/json")
def calls_to_api_monthly(request, api_id=None, api_name=None): if api_id is None and api_name is None: return HttpResponseBadRequest("Must specify API id or name.") try: api = resolve_model(Api, [("id", api_id), ("name", api_name)]) except Api.DoesNotExist: return HttpResponseNotFound("The requested API was not found.") ignore_internal_keys = parse_bool_param(request, "ignore_internal_keys", True) year = parse_int_param(request, "year") if year is None: return HttpResponseBadRequest("You must specify a year parameter.") qry = Report.objects.filter(api=api) if ignore_internal_keys: qry = exclude_internal_key_reports(qry) qry = qry.filter(date__gte=datetime.date(year, 1, 1), date__lte=datetime.date(year, 12, 31)) agg = qry.aggregate(calls=Sum("calls")) daily_aggs = qry.values("date").annotate(calls=Sum("calls")) monthly = dict(((m, {"month": m, "calls": 0}) for m in range(1, 13))) for daily in daily_aggs: month = daily["date"].month monthly[month]["calls"] += daily["calls"] result = {"api_id": api.id, "api_name": api.name, "calls": agg["calls"], "monthly": monthly.values()} return HttpResponse(content=json.dumps(result), status=200, content_type="application/json")
def calls_to_api(request, api_id=None, api_name=None): begin_date = parse_date_param(request, "begin_date") end_date = parse_date_param(request, "end_date") ignore_internal_keys = parse_bool_param(request, "ignore_internal_keys", True) if api_id is None and api_name is None: return HttpResponseBadRequest("Must specify API id or name.") try: api = resolve_model(Api, [("id", api_id), ("name", api_name)]) except Api.DoesNotExist: return HttpResponseNotFound("The requested API was not found.") qry = Report.objects.filter(api=api) if ignore_internal_keys: qry = exclude_internal_key_reports(qry) if begin_date: qry = qry.filter(date__gte=begin_date) if end_date: qry = qry.filter(date__lte=end_date) qry = qry.aggregate(calls=Sum("calls")) result = {"api_id": api.id, "api_name": api.name, "calls": qry["calls"]} if begin_date is not None: result["begin_date"] = begin_date.isoformat() if end_date is not None: result["end_date"] = end_date.isoformat() return HttpResponse(content=json.dumps(result), status=200, content_type="application/json")
def calls_by_endpoint(request, api_id=None, api_name=None): if api_id is None and api_name is None: return HttpResponseBadRequest("Must specify API id or name.") try: api = resolve_model(Api, [("id", api_id), ("name", api_name)]) except Api.DoesNotExist: return HttpResponseNotFound("The requested API was not found.") ignore_internal_keys = parse_bool_param(request, "ignore_internal_keys", True) qry = Report.objects.filter(api=api) if ignore_internal_keys: qry = exclude_internal_key_reports(qry) endpoint_aggs = qry.values("endpoint").annotate(calls=Sum("calls")) result = {"api": {"id": api.id, "name": api.name}, "by_endpoint": list(endpoint_aggs)} return HttpResponse(content=json.dumps(result), status=200, content_type="application/json")
def calls_to_api_yearly(request, api_id=None, api_name=None): if api_id is None and api_name is None: return HttpResponseBadRequest("Must specify API id or name.") try: api = resolve_model(Api, [("id", api_id), ("name", api_name)]) except Api.DoesNotExist: return HttpResponseNotFound("The requested API was not found.") ignore_internal_keys = parse_bool_param(request, "ignore_internal_keys", True) date_extents = _keys_issued_date_range() if date_extents["earliest"] and date_extents["latest"]: earliest_year = date_extents["earliest"].year latest_year = date_extents["latest"].year qry = Report.objects.filter(api=api) if ignore_internal_keys: qry = exclude_internal_key_reports(qry) agg = qry.aggregate(calls=Sum("calls")) daily_aggs = qry.values("date").annotate(calls=Sum("calls")) yearly = dict(((y, {"year": y, "calls": 0}) for y in range(earliest_year, latest_year + 1))) for daily in daily_aggs: yr = daily["date"].year yearly[yr]["calls"] += daily["calls"] else: earliest_year = None latest_year = None agg = {"calls": 0} yearly = {} result = { "api_id": api.id, "api_name": api.name, "earliest_year": earliest_year, "latest_year": latest_year, "calls": agg["calls"], "yearly": yearly.values(), } return HttpResponse(content=json.dumps(result), status=200, content_type="application/json")
def keys_leaderboard(request, year=None, month=None, api_id=None, api_name=None): try: api = resolve_model(Api, [('id', api_id), ('name', api_name)]) except Api.DoesNotExist: api = None if year is not None and month is not None: year = int(year) month = int(month) if month not in range(1, 13): return HttpResponseBadRequest("Month must be between 1 and 12, was {m}".format(m=unicode(month))) else: year = datetime.date.today().year month = datetime.date.today().month #adjust start of quarter back 3 months, so we don't include partially measured, current month if month > 3: month -= 3 else: year -= 1 if month == 3: month = 12 if month == 2: month = 11 else: month = 10 ctx = { 'latest_qtr_begin': datetime.datetime(year, month, 1).strftime('%Y-%m-%d'), 'LOCKSMITH_BASE_TEMPLATE': settings.LOCKSMITH_BASE_TEMPLATE } if api is not None: ctx['api'] = {'id': api.id, 'name': api.name} ctx['json_options'] = json.dumps(ctx) ctx['LOCKSMITH_BASE_TEMPLATE'] = settings.LOCKSMITH_BASE_TEMPLATE template = getattr(settings, 'LOCKSMITH_KEYS_LEADERBOARD_TEMPLATE', 'locksmith/leaderboard.html') return render(request, template, ctx)
def callers_of_api(request, api_id=None, api_name=None): if api_id is None and api_name is None: return HttpResponseBadRequest("Must specify API id or name.") try: api = resolve_model(Api, [("id", api_id), ("name", api_name)]) except Api.DoesNotExist: return HttpResponseNotFound("The requested API was not found.") ignore_internal_keys = parse_bool_param(request, "ignore_internal_keys", True) min_calls = parse_int_param(request, "min_calls") max_calls = parse_int_param(request, "max_calls") top = parse_int_param(request, "top") qry = api.reports if ignore_internal_keys: qry = exclude_internal_key_reports(qry) qry = qry.values("key__email", "key__key").exclude(key__status="S").annotate(calls=Sum("calls")) if min_calls is not None: qry = qry.filter(calls__gte=min_calls) if max_calls is not None: qry = qry.filter(calls__lte=max_calls) qry = qry.order_by("-calls") if top is not None: qry = qry[:top] result = { "callers": [ { "key": c["key__key"], "email": c["key__email"], "profile_url": reverse("key_analytics", args=(c["key__key"],)), "calls": c["calls"], } for c in qry ] } return HttpResponse(content=json.dumps(result), status=200, content_type="application/json")