Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flowmachine subscriber degree #991

Merged
merged 11 commits into from
Jul 1, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

- The dev provisioning Ansible playbook now automatically generates an SSH key pair for the `flowkit` user. [#892](https://github.com/Flowminder/FlowKit/issues/892)
- FlowAPI's 'joined_spatial_aggregate' endpoint now exposes unique location counts.[#949](https://github.com/Flowminder/FlowKit/issues/949)
- FlowAPI's 'joined_spatial_aggregate' endpoint now exposes subscriber degree.[#969](https://github.com/Flowminder/FlowKit/issues/969)
- Flowdb now contains an auxiliary table to record outcomes of queries that can be run as part of the regular ETL process [#988](https://github.com/Flowminder/FlowKit/issues/988)

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

__all__ = [
Expand Down Expand Up @@ -64,4 +65,5 @@
"joined_spatial_aggregate",
"radius_of_gyration",
"unique_location_counts",
"subscriber_degree",
]
36 changes: 36 additions & 0 deletions flowclient/flowclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1285,3 +1285,39 @@ def unique_location_counts(
"aggregation_unit": aggregation_unit,
"subscriber_subset": subscriber_subset,
}


def subscriber_degree(
*,
start: str,
stop: str,
direction: str,
subscriber_subset: Union[dict, None] = None,
) -> dict:
"""
Return query spec for subscriber degree

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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't a default defined in the function here?

Optionally, include only ingoing or outbound calls/texts. Can be one of "in", "out" or "both".
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": "subscriber_degree",
"start": start,
"stop": stop,
"direction": direction,
"subscriber_subset": subscriber_subset,
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from flowmachine.core.server.query_schemas.radius_of_gyration import (
RadiusOfGyrationSchema,
)
from flowmachine.core.server.query_schemas.subscriber_degree import (
SubscriberDegreeSchema,
)
from flowmachine.core.server.query_schemas.unique_location_counts import (
UniqueLocationCountsSchema,
)
Expand All @@ -27,6 +30,7 @@ class JoinableMetrics(OneOfSchema):
type_schemas = {
"radius_of_gyration": RadiusOfGyrationSchema,
"unique_location_counts": UniqueLocationCountsSchema,
"subscriber_degree": SubscriberDegreeSchema,
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 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 SubscriberDegree
from .base_exposed_query import BaseExposedQuery
from .custom_fields import SubscriberSubset

__all__ = ["SubscriberDegreeSchema", "SubscriberDegreeExposed"]


class SubscriberDegreeSchema(Schema):
query_kind = fields.String(validate=OneOf(["subscriber_degree"]))
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
subscriber_subset = SubscriberSubset()

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


class SubscriberDegreeExposed(BaseExposedQuery):
def __init__(self, *, start, stop, direction, 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.subscriber_subset = subscriber_subset

@property
def _flowmachine_query_obj(self):
"""
Return the underlying flowmachine subscriber_degree object.

Returns
-------
Query
"""
return SubscriberDegree(
start=self.start,
stop=self.stop,
direction=self.direction,
subscriber_subset=self.subscriber_subset,
)
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@
"discriminator": {
"mapping": {
"radius_of_gyration": "#/components/schemas/RadiusOfGyration",
"subscriber_degree": "#/components/schemas/SubscriberDegree",
"unique_location_counts": "#/components/schemas/UniqueLocationCounts"
},
"propertyName": "query_kind"
Expand All @@ -343,6 +344,9 @@
{
"$ref": "#/components/schemas/RadiusOfGyration"
},
{
"$ref": "#/components/schemas/SubscriberDegree"
},
{
"$ref": "#/components/schemas/UniqueLocationCounts"
}
Expand Down Expand Up @@ -842,6 +846,45 @@
],
"type": "object"
},
"SubscriberDegree": {
"properties": {
"direction": {
"enum": [
"both",
"in",
"out"
],
"type": "string"
},
"query_kind": {
"enum": [
"subscriber_degree"
],
"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"
},
"TotalNetworkObjects": {
"properties": {
"aggregation_unit": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@
{
"$ref": "#/components/schemas/RadiusOfGyration"
},
{
"$ref": "#/components/schemas/SubscriberDegree"
},
{
"$ref": "#/components/schemas/UniqueLocationCounts"
}
Expand Down Expand Up @@ -790,6 +793,45 @@
],
"type": "object"
},
"SubscriberDegree": {
"properties": {
"direction": {
"enum": [
"both",
"in",
"out"
],
"type": "string"
},
"query_kind": {
"enum": [
"subscriber_degree"
],
"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"
},
"TotalNetworkObjects": {
"properties": {
"aggregation_unit": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@
"discriminator": {
"mapping": {
"radius_of_gyration": "#/components/schemas/RadiusOfGyration",
"subscriber_degree": "#/components/schemas/SubscriberDegree",
"unique_location_counts": "#/components/schemas/UniqueLocationCounts"
},
"propertyName": "query_kind"
Expand All @@ -343,6 +344,9 @@
{
"$ref": "#/components/schemas/RadiusOfGyration"
},
{
"$ref": "#/components/schemas/SubscriberDegree"
},
{
"$ref": "#/components/schemas/UniqueLocationCounts"
}
Expand Down Expand Up @@ -842,6 +846,45 @@
],
"type": "object"
},
"SubscriberDegree": {
"properties": {
"direction": {
"enum": [
"both",
"in",
"out"
],
"type": "string"
},
"query_kind": {
"enum": [
"subscriber_degree"
],
"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"
},
"TotalNetworkObjects": {
"properties": {
"aggregation_unit": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@
"discriminator": {
"mapping": {
"radius_of_gyration": "#/components/schemas/RadiusOfGyration",
"subscriber_degree": "#/components/schemas/SubscriberDegree",
"unique_location_counts": "#/components/schemas/UniqueLocationCounts"
},
"propertyName": "query_kind"
Expand All @@ -335,6 +336,9 @@
{
"$ref": "#/components/schemas/RadiusOfGyration"
},
{
"$ref": "#/components/schemas/SubscriberDegree"
},
{
"$ref": "#/components/schemas/UniqueLocationCounts"
}
Expand Down Expand Up @@ -825,6 +829,44 @@
],
"type": "object"
},
"SubscriberDegree": {
"properties": {
"direction": {
"enum": [
"both",
"in",
"out"
],
"type": "string"
},
"query_kind": {
"enum": [
"subscriber_degree"
],
"type": "string"
},
"start": {
"format": "date",
"type": "string"
},
"stop": {
"format": "date",
"type": "string"
},
"subscriber_subset": {
"enum": [
null
],
"nullable": true,
"type": "string"
}
},
"required": [
"start",
"stop"
],
"type": "object"
},
"TotalNetworkObjects": {
"properties": {
"aggregation_unit": {
Expand Down
11 changes: 11 additions & 0 deletions integration_tests/tests/query_tests/test_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@
),
},
),
(
"joined_spatial_aggregate",
{
"locations": flowclient.daily_location(
date="2016-01-01", aggregation_unit="admin3", method="last"
),
"metric": flowclient.subscriber_degree(
start="2016-01-01", stop="2016-01-02", direction="both"
),
},
),
(
"joined_spatial_aggregate",
{
Expand Down