Skip to content

Commit

Permalink
Merge pull request #1023 from Flowminder/flowmachine-event-count
Browse files Browse the repository at this point in the history
Flowmachine event count
  • Loading branch information
mergify[bot] authored Jul 3, 2019
2 parents 05ba372 + ad2453a commit 57a71dd
Show file tree
Hide file tree
Showing 11 changed files with 345 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ All notable changes to FlowKit will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]

- FlowAPI's 'joined_spatial_aggregate' endpoint now exposes event counts.[#992](https://github.com/Flowminder/FlowKit/issues/992)
### Added


Expand Down
3 changes: 3 additions & 0 deletions docs/source/developer/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ At present, the following query types are accessible through FlowAPI:

Count of mobile phone cells per area active based on CDR traffic within a time period, broken down into time buckets.

-`event_count`

Count of events (optionally of specific types) for individual subscribers in a time period.

### FlowAPI Access tokens

Expand Down
2 changes: 2 additions & 0 deletions flowclient/flowclient/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
radius_of_gyration,
unique_location_counts,
subscriber_degree,
event_count,
)

__all__ = [
Expand Down Expand Up @@ -66,4 +67,5 @@
"radius_of_gyration",
"unique_location_counts",
"subscriber_degree",
"event_count",
]
43 changes: 42 additions & 1 deletion flowclient/flowclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import requests
import time
from requests import ConnectionError
from typing import Tuple, Union, Dict, List
from typing import Tuple, Union, Dict, List, Optional

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -1321,3 +1321,44 @@ def subscriber_degree(
"direction": direction,
"subscriber_subset": subscriber_subset,
}


def event_count(
*,
start: str,
stop: str,
direction: str = "both",
event_types: Optional[List[str]] = None,
subscriber_subset: Union[dict, None] = None,
) -> dict:
"""
Return query spec for event count
Parameters
----------
start : str
ISO format date of the first day of the count, e.g. "2016-01-01"
stop : str
ISO format date of the day _after_ the final date of the count, e.g. "2016-01-08"
direction : {"in", "out", "both"}, default "both"
Optionally, include only ingoing or outbound calls/texts. Can be one of "in", "out" or "both".
event_types : list of str, optional
The event types to include in the count (for example: ["calls", "sms"]).
If None, include all event types in the count.
subscriber_subset : dict or None, default None
Subset of subscribers to include in event counts. Must be None
(= all subscribers) or a dictionary with the specification of a
subset query.
Returns
-------
dict
Dict which functions as the query specification
"""
return {
"query_kind": "event_count",
"start": start,
"stop": stop,
"direction": direction,
"event_types": event_types,
"subscriber_subset": subscriber_subset,
}
55 changes: 55 additions & 0 deletions flowmachine/flowmachine/core/server/query_schemas/event_count.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from marshmallow import Schema, fields, post_load
from marshmallow.validate import OneOf, Length

from flowmachine.features import EventCount
from .base_exposed_query import BaseExposedQuery
from .custom_fields import EventTypes, SubscriberSubset

__all__ = ["EventCountSchema", "EventCountExposed"]


class EventCountSchema(Schema):
query_kind = fields.String(validate=OneOf(["event_count"]))
start = fields.Date(required=True)
stop = fields.Date(required=True)
direction = fields.String(
required=False, validate=OneOf(["in", "out", "both"]), default="both"
) # TODO: use a globally defined enum for this
event_types = EventTypes()
subscriber_subset = SubscriberSubset()

@post_load
def make_query_object(self, params, **kwargs):
return EventCountExposed(**params)


class EventCountExposed(BaseExposedQuery):
def __init__(self, *, start, stop, direction, event_types, subscriber_subset=None):
# Note: all input parameters need to be defined as attributes on `self`
# so that marshmallow can serialise the object correctly.
self.start = start
self.stop = stop
self.direction = direction
self.event_types = event_types
self.subscriber_subset = subscriber_subset

@property
def _flowmachine_query_obj(self):
"""
Return the underlying flowmachine event_count object.
Returns
-------
Query
"""
return EventCount(
start=self.start,
stop=self.stop,
direction=self.direction,
tables=self.event_types,
subscriber_subset=self.subscriber_subset,
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from flowmachine.core.server.query_schemas.subscriber_degree import (
SubscriberDegreeSchema,
)
from flowmachine.core.server.query_schemas.event_count import EventCountSchema
from flowmachine.core.server.query_schemas.unique_location_counts import (
UniqueLocationCountsSchema,
)
Expand All @@ -31,6 +32,7 @@ class JoinableMetrics(OneOfSchema):
"radius_of_gyration": RadiusOfGyrationSchema,
"unique_location_counts": UniqueLocationCountsSchema,
"subscriber_degree": SubscriberDegreeSchema,
"event_count": EventCountSchema,
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,59 @@
],
"type": "object"
},
"EventCount": {
"properties": {
"direction": {
"enum": [
"both",
"in",
"out"
],
"type": "string"
},
"event_types": {
"items": {
"enum": [
"calls",
"mds",
"sms",
"topups"
],
"type": "string"
},
"minItems": 1,
"nullable": true,
"type": "array"
},
"query_kind": {
"enum": [
"event_count"
],
"type": "string"
},
"start": {
"format": "date",
"type": "string"
},
"stop": {
"format": "date",
"type": "string"
},
"subscriber_subset": {
"enum": [
null
],
"nullable": true,
"type": "string"
}
},
"required": [
"query_kind",
"start",
"stop"
],
"type": "object"
},
"FlowmachineQuerySchema": {
"discriminator": {
"mapping": {
Expand Down Expand Up @@ -334,13 +387,17 @@
"JoinableMetrics": {
"discriminator": {
"mapping": {
"event_count": "#/components/schemas/EventCount",
"radius_of_gyration": "#/components/schemas/RadiusOfGyration",
"subscriber_degree": "#/components/schemas/SubscriberDegree",
"unique_location_counts": "#/components/schemas/UniqueLocationCounts"
},
"propertyName": "query_kind"
},
"oneOf": [
{
"$ref": "#/components/schemas/EventCount"
},
{
"$ref": "#/components/schemas/RadiusOfGyration"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,59 @@
],
"type": "object"
},
"EventCount": {
"properties": {
"direction": {
"enum": [
"both",
"in",
"out"
],
"type": "string"
},
"event_types": {
"items": {
"enum": [
"calls",
"mds",
"sms",
"topups"
],
"type": "string"
},
"minItems": 1,
"nullable": true,
"type": "array"
},
"query_kind": {
"enum": [
"event_count"
],
"type": "string"
},
"start": {
"format": "date",
"type": "string"
},
"stop": {
"format": "date",
"type": "string"
},
"subscriber_subset": {
"enum": [
null
],
"nullable": true,
"type": "string"
}
},
"required": [
"query_kind",
"start",
"stop"
],
"type": "object"
},
"FlowmachineQuerySchema": {
"oneOf": [
{
Expand Down Expand Up @@ -288,6 +341,9 @@
},
"JoinableMetrics": {
"oneOf": [
{
"$ref": "#/components/schemas/EventCount"
},
{
"$ref": "#/components/schemas/RadiusOfGyration"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,59 @@
],
"type": "object"
},
"EventCount": {
"properties": {
"direction": {
"enum": [
"both",
"in",
"out"
],
"type": "string"
},
"event_types": {
"items": {
"enum": [
"calls",
"mds",
"sms",
"topups"
],
"type": "string"
},
"minItems": 1,
"nullable": true,
"type": "array"
},
"query_kind": {
"enum": [
"event_count"
],
"type": "string"
},
"start": {
"format": "date",
"type": "string"
},
"stop": {
"format": "date",
"type": "string"
},
"subscriber_subset": {
"enum": [
null
],
"nullable": true,
"type": "string"
}
},
"required": [
"query_kind",
"start",
"stop"
],
"type": "object"
},
"FlowmachineQuerySchema": {
"discriminator": {
"mapping": {
Expand Down Expand Up @@ -334,13 +387,17 @@
"JoinableMetrics": {
"discriminator": {
"mapping": {
"event_count": "#/components/schemas/EventCount",
"radius_of_gyration": "#/components/schemas/RadiusOfGyration",
"subscriber_degree": "#/components/schemas/SubscriberDegree",
"unique_location_counts": "#/components/schemas/UniqueLocationCounts"
},
"propertyName": "query_kind"
},
"oneOf": [
{
"$ref": "#/components/schemas/EventCount"
},
{
"$ref": "#/components/schemas/RadiusOfGyration"
},
Expand Down
Loading

0 comments on commit 57a71dd

Please sign in to comment.