Skip to content

Commit

Permalink
Feature/ch996/black formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
nitz14 authored and dabeeeenster committed Nov 23, 2020
1 parent 72b94c5 commit fed1c58
Show file tree
Hide file tree
Showing 169 changed files with 5,249 additions and 3,126 deletions.
1 change: 1 addition & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test:
POSTGRES_PASSWORD: testpass
script:
- pip install -r requirements-dev.txt
- black --check .
- pytest src -p no:warnings

deploydevelop:
Expand Down
7 changes: 7 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[settings]
use_parentheses=true
multi_line_output=3
include_trailing_comma=true
line_length=79
known_first_party=analytics,app,custom_auth,environments,integrations,organisations,projects,segments,users,webhooks,api,audit,e2etests,features,permissions,util
known_third_party=apiclient,axes,chargebee,coreapi,corsheaders,dj_database_url,django,djoser,drf_yasg2,environ,google,influxdb_client,ordered_model,pyotp,pytest,pytz,requests,rest_framework,rest_framework_nested,rest_framework_recursive,shortuuid,simple_history,six,trench,whitenoise
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
repos:
- repo: https://github.com/asottile/seed-isort-config
rev: v1.9.3
hooks:
- id: seed-isort-config
- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.21
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: stable
hooks:
- id: black
language_version: python3
46 changes: 23 additions & 23 deletions src/analytics/influxdb_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def __init__(self, name):
self.name = name
self.records = []
self.write_api = influxdb_client.write_api(write_options=SYNCHRONOUS)

def add_data_point(self, field_name, field_value, tags=None):
point = Point(self.name)
point.field(field_name, field_value)

if tags is not None:
for tag_key, tag_value in tags.items():
point = point.tag(tag_key, tag_value)
Expand All @@ -29,22 +29,23 @@ def add_data_point(self, field_name, field_value, tags=None):
def write(self):
self.write_api.write(bucket=settings.INFLUXDB_BUCKET, record=self.records)


@staticmethod
def influx_query_manager(
date_range: str = "30d",
date_stop: str = "now()",
drop_columns: str = "'organisation', 'organisation_id', 'type', 'project', 'project_id'",
filters: str = "|> filter(fn:(r) => r._measurement == 'api_call')",
extra: str = ""
date_range: str = "30d",
date_stop: str = "now()",
drop_columns: str = "'organisation', 'organisation_id', 'type', 'project', 'project_id'",
filters: str = "|> filter(fn:(r) => r._measurement == 'api_call')",
extra: str = "",
):
query_api = influxdb_client.query_api()

query = f'from(bucket:"{read_bucket}")' \
f' |> range(start: -{date_range}, stop: {date_stop})' \
f' {filters}' \
f' |> drop(columns: [{drop_columns}])' \
f'{extra}'
query = (
f'from(bucket:"{read_bucket}")'
f" |> range(start: -{date_range}, stop: {date_stop})"
f" {filters}"
f" |> drop(columns: [{drop_columns}])"
f"{extra}"
)

result = query_api.query(org=influx_org, query=query)
return result
Expand All @@ -62,7 +63,7 @@ def get_events_for_organisation(organisation_id):
|> filter(fn: (r) => r["_field"] == "request_count") \
|> filter(fn: (r) => r["organisation_id"] == "{organisation_id}")',
drop_columns='"organisation", "project", "project_id"',
extra="|> sum()"
extra="|> sum()",
)

total = 0
Expand All @@ -85,17 +86,16 @@ def get_event_list_for_organisation(organisation_id: int):
filters=f'|> filter(fn:(r) => r._measurement == "api_call") \
|> filter(fn: (r) => r["organisation_id"] == "{organisation_id}")',
drop_columns='"organisation", "organisation_id", "type", "project", "project_id"',
extra="|> aggregateWindow(every: 24h, fn: sum)"
extra="|> aggregateWindow(every: 24h, fn: sum)",
)
dataset = []
labels = []
for result in results:
for record in result.records:
dataset.append({
't': record.values['_time'].isoformat(),
'y': record.values['_value']
})
labels.append(record.values['_time'].strftime('%Y-%m-%d'))
dataset.append(
{"t": record.values["_time"].isoformat(), "y": record.values["_value"]}
)
labels.append(record.values["_time"].strftime("%Y-%m-%d"))
return dataset, labels


Expand All @@ -111,7 +111,7 @@ def get_multiple_event_list_for_organisation(organisation_id: int):
filters=f'|> filter(fn:(r) => r._measurement == "api_call") \
|> filter(fn: (r) => r["organisation_id"] == "{organisation_id}")',
drop_columns='"organisation", "organisation_id", "type", "project", "project_id"',
extra="|> aggregateWindow(every: 24h, fn: sum)"
extra="|> aggregateWindow(every: 24h, fn: sum)",
)
if not results:
return results
Expand All @@ -120,6 +120,6 @@ def get_multiple_event_list_for_organisation(organisation_id: int):

for result in results:
for i, record in enumerate(result.records):
dataset[i][record.values['resource']] = record.values['_value']
dataset[i]['name'] = record.values['_time'].isoformat()
dataset[i][record.values["resource"]] = record.values["_value"]
dataset[i]["name"] = record.values["_time"].isoformat()
return dataset
34 changes: 21 additions & 13 deletions src/analytics/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
from django.conf import settings
from google.oauth2 import service_account

GA_SCOPES = ['https://www.googleapis.com/auth/analytics.readonly']
GA_API_NAME = 'analytics'
GA_API_VERSION = 'v3'
GA_SCOPES = ["https://www.googleapis.com/auth/analytics.readonly"]
GA_API_NAME = "analytics"
GA_API_VERSION = "v3"


def get_service():
"""
Get the google service object to use to query the API
"""
credentials = service_account.Credentials.from_service_account_info(
json.loads(settings.GOOGLE_SERVICE_ACCOUNT), scopes=GA_SCOPES)
json.loads(settings.GOOGLE_SERVICE_ACCOUNT), scopes=GA_SCOPES
)

# Build the service object.
return build(GA_API_NAME, GA_API_VERSION, credentials=credentials)
Expand All @@ -26,12 +27,19 @@ def get_events_for_organisation(organisation):
:return: number of events as integer
"""
ga_response = get_service().data().ga().get(
ids=settings.GA_TABLE_ID,
start_date='30daysAgo',
end_date='today',
metrics='ga:totalEvents',
dimensions='ga:date',
filters=f'ga:eventCategory=={organisation.get_unique_slug()}').execute()

return int(ga_response['totalsForAllResults']['ga:totalEvents'])
ga_response = (
get_service()
.data()
.ga()
.get(
ids=settings.GA_TABLE_ID,
start_date="30daysAgo",
end_date="today",
metrics="ga:totalEvents",
dimensions="ga:date",
filters=f"ga:eventCategory=={organisation.get_unique_slug()}",
)
.execute()
)

return int(ga_response["totalsForAllResults"]["ga:totalEvents"])
69 changes: 44 additions & 25 deletions src/analytics/tests/test_influxdb_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

import analytics
from analytics.influxdb_wrapper import InfluxDBWrapper
from analytics.influxdb_wrapper import get_events_for_organisation, get_event_list_for_organisation, get_multiple_event_list_for_organisation
from analytics.influxdb_wrapper import (
get_events_for_organisation,
get_event_list_for_organisation,
get_multiple_event_list_for_organisation,
)

# Given
org_id = 123
Expand All @@ -15,7 +19,9 @@
def test_write(monkeypatch):
# Given
mock_influxdb_client = mock.MagicMock()
monkeypatch.setattr(analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client)
monkeypatch.setattr(
analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client
)

mock_write_api = mock.MagicMock()
mock_influxdb_client.write_api.return_value = mock_write_api
Expand All @@ -31,14 +37,18 @@ def test_write(monkeypatch):


def test_influx_db_query_when_get_events_then_query_api_called(monkeypatch):
query = f'from(bucket:"{read_bucket}") |> range(start: -30d, stop: now()) ' \
f'|> filter(fn:(r) => r._measurement == "api_call") ' \
f'|> filter(fn: (r) => r["_field"] == "request_count") ' \
f'|> filter(fn: (r) => r["organisation_id"] == "{org_id}") ' \
f'|> drop(columns: ["organisation", "project", "project_id"])' \
f'|> sum()'
query = (
f'from(bucket:"{read_bucket}") |> range(start: -30d, stop: now()) '
f'|> filter(fn:(r) => r._measurement == "api_call") '
f'|> filter(fn: (r) => r["_field"] == "request_count") '
f'|> filter(fn: (r) => r["organisation_id"] == "{org_id}") '
f'|> drop(columns: ["organisation", "project", "project_id"])'
f"|> sum()"
)
mock_influxdb_client = mock.MagicMock()
monkeypatch.setattr(analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client)
monkeypatch.setattr(
analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client
)

mock_query_api = mock.MagicMock()
mock_influxdb_client.query_api.return_value = mock_query_api
Expand All @@ -51,14 +61,18 @@ def test_influx_db_query_when_get_events_then_query_api_called(monkeypatch):


def test_influx_db_query_when_get_events_list_then_query_api_called(monkeypatch):
query = f'from(bucket:"{read_bucket}") ' \
f'|> range(start: -30d, stop: now()) ' \
f'|> filter(fn:(r) => r._measurement == "api_call") ' \
f'|> filter(fn: (r) => r["organisation_id"] == "{org_id}") ' \
f'|> drop(columns: ["organisation", "organisation_id", "type", "project", "project_id"])' \
f'|> aggregateWindow(every: 24h, fn: sum)'
query = (
f'from(bucket:"{read_bucket}") '
f"|> range(start: -30d, stop: now()) "
f'|> filter(fn:(r) => r._measurement == "api_call") '
f'|> filter(fn: (r) => r["organisation_id"] == "{org_id}") '
f'|> drop(columns: ["organisation", "organisation_id", "type", "project", "project_id"])'
f"|> aggregateWindow(every: 24h, fn: sum)"
)
mock_influxdb_client = mock.MagicMock()
monkeypatch.setattr(analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client)
monkeypatch.setattr(
analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client
)

mock_query_api = mock.MagicMock()
mock_influxdb_client.query_api.return_value = mock_query_api
Expand All @@ -70,15 +84,21 @@ def test_influx_db_query_when_get_events_list_then_query_api_called(monkeypatch)
mock_query_api.query.assert_called_once_with(org=influx_org, query=query)


def test_influx_db_query_when_get_multiple_events_for_organistation_then_query_api_called(monkeypatch):
query = f'from(bucket:"{read_bucket}") ' \
'|> range(start: -30d, stop: now()) ' \
'|> filter(fn:(r) => r._measurement == "api_call") ' \
f'|> filter(fn: (r) => r["organisation_id"] == "{org_id}") ' \
'|> drop(columns: ["organisation", "organisation_id", "type", "project", "project_id"])' \
'|> aggregateWindow(every: 24h, fn: sum)'
def test_influx_db_query_when_get_multiple_events_for_organistation_then_query_api_called(
monkeypatch,
):
query = (
f'from(bucket:"{read_bucket}") '
"|> range(start: -30d, stop: now()) "
'|> filter(fn:(r) => r._measurement == "api_call") '
f'|> filter(fn: (r) => r["organisation_id"] == "{org_id}") '
'|> drop(columns: ["organisation", "organisation_id", "type", "project", "project_id"])'
"|> aggregateWindow(every: 24h, fn: sum)"
)
mock_influxdb_client = mock.MagicMock()
monkeypatch.setattr(analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client)
monkeypatch.setattr(
analytics.influxdb_wrapper, "influxdb_client", mock_influxdb_client
)

mock_query_api = mock.MagicMock()
mock_influxdb_client.query_api.return_value = mock_query_api
Expand All @@ -88,4 +108,3 @@ def test_influx_db_query_when_get_multiple_events_for_organistation_then_query_a

# Then
mock_query_api.query.assert_called_once_with(org=influx_org, query=query)

31 changes: 22 additions & 9 deletions src/analytics/tests/test_unit_track.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,27 @@
from django.conf import settings

import analytics
from analytics.track import track_request_googleanalytics, track_request_influxdb
from analytics.track import (
track_request_googleanalytics,
track_request_influxdb,
)


@pytest.mark.parametrize("request_uri, expected_ga_requests", (
@pytest.mark.parametrize(
"request_uri, expected_ga_requests",
(
("/api/v1/flags/", 2),
("/api/v1/identities/", 2),
("/api/v1/traits/", 2),
("/api/v1/features/", 1),
("/health", 1)
))
("/health", 1),
),
)
@mock.patch("analytics.track.requests")
@mock.patch("analytics.track.Environment")
def test_track_request_googleanalytics(MockEnvironment, mock_requests, request_uri, expected_ga_requests):
def test_track_request_googleanalytics(
MockEnvironment, mock_requests, request_uri, expected_ga_requests
):
"""
Verify that the correct number of calls are made to GA for the various uris.
Expand All @@ -37,11 +45,14 @@ def test_track_request_googleanalytics(MockEnvironment, mock_requests, request_u
assert mock_requests.post.call_count == expected_ga_requests


@pytest.mark.parametrize("request_uri, expected_resource", (
@pytest.mark.parametrize(
"request_uri, expected_resource",
(
("/api/v1/flags/", "flags"),
("/api/v1/identities/", "identities"),
("/api/v1/traits/", "traits"),
))
),
)
@mock.patch("analytics.track.InfluxDBWrapper")
@mock.patch("analytics.track.Environment")
def test_track_request_sends_data_to_influxdb_for_tracked_uris(
Expand All @@ -65,7 +76,10 @@ def test_track_request_sends_data_to_influxdb_for_tracked_uris(
# Then
call_list = MockInfluxDBWrapper.call_args_list
assert len(call_list) == 1
assert mock_influxdb.add_data_point.call_args_list[0][1]["tags"]["resource"] == expected_resource
assert (
mock_influxdb.add_data_point.call_args_list[0][1]["tags"]["resource"]
== expected_resource
)


@mock.patch("analytics.track.InfluxDBWrapper")
Expand All @@ -90,4 +104,3 @@ def test_track_request_does_not_send_data_to_influxdb_for_not_tracked_uris(

# Then
MockInfluxDBWrapper.assert_not_called()

Loading

0 comments on commit fed1c58

Please sign in to comment.