-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
157 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from parsons.community.community import Community | ||
|
||
__all__ = ["Community"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import logging | ||
from parsons.utilities.api_connector import APIConnector | ||
from parsons.utilities import check_env | ||
from parsons.etl import Table | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
COMMUNITY_API_ENDPOINT = "https://dl.community.com/download/v1/files/" | ||
|
||
|
||
class Community(object): | ||
""" | ||
Instantiate class. | ||
`Args:` | ||
community_client_id: str | ||
The Community provided Client ID. Not required if ``COMMUNITY_CLIENT_ID`` env | ||
variable set. | ||
community_access_token: str | ||
The Community provided access token. Not required if ``COMMUNITY_ACCESS_TOKEN`` env | ||
variable set. | ||
community_uri: str | ||
The URI to access the API. Not required, default is | ||
`<https://dl.community.com/download/v1/files/>`_. You can set an ``COMMUNITY_URL`` env | ||
variable or use this URI parameter if a different endpoint is necessary. | ||
`API Documentation <https://developer.community.com/reference/data-export-api-downloading-data>`_ | ||
""" | ||
|
||
def __init__(self, community_client_id=None, community_access_token=None, community_url=None): | ||
self.community_client_id = check_env.check("community_client_id", community_client_id) | ||
self.community_access_token = check_env.check( | ||
"community_access_token", community_access_token | ||
) | ||
self.uri = ( | ||
check_env.check("COMMUNITY_URL", community_url, optional=True) | ||
or f"{COMMUNITY_API_ENDPOINT}/{community_client_id}/" | ||
) | ||
self.headers = { | ||
"Authorization": f"Bearer {self.community_access_token}", | ||
} | ||
self.client = APIConnector( | ||
self.uri, | ||
headers=self.headers, | ||
) | ||
|
||
def get_request(self, filename): | ||
""" | ||
GET request to Community.com API to get the CSV data. | ||
`Args:` | ||
filename: str | ||
Data filename you are requesting. | ||
Options: | ||
'campaigns': Campaign Performance data | ||
'outbound_message_type_usage`: Message Segment Usage data | ||
'campaign_links': Campaign Link Performance data | ||
'members': Member Details data | ||
'member_state_changes': Member Subscription Status data | ||
'custom_member_data': Custom Member Data | ||
'communities': Communities data | ||
'member_communities': Member Communities data | ||
`Returns:` | ||
Response of GET request; a successful response returns the CSV formatted data | ||
""" | ||
|
||
logger.info(f"Requesting {filename}") | ||
url = ( | ||
f"{filename}.csv.gz" | ||
if filename != "outbound_message_type_usage" | ||
else f"{filename}.csv.gz/segment-based-subscription" | ||
) | ||
response = self.client.get_request(url=url, return_format="content") | ||
return response | ||
|
||
def get_data_export(self, filename): | ||
""" | ||
Get specified data from Community.com API as Parsons table. | ||
`Args:` | ||
filename: str | ||
Data filename you are requesting. | ||
Options: | ||
'campaigns': Campaign Performance data | ||
'outbound_message_type_usage`: Message Segment Usage data | ||
'campaign_links': Campaign Link Performance data | ||
'members': Member Details data | ||
'member_state_changes': Member Subscription Status data | ||
'custom_member_data': Custom Member Data | ||
'communities': Communities data | ||
'member_communities': Member Communities data | ||
`Returns:` | ||
Contents of the generated contribution CSV as a Parsons table. | ||
""" | ||
|
||
get_request_response = self.get_request(filename=filename) | ||
response_string = get_request_response.decode("utf-8") | ||
table = Table.from_csv_string(response_string) | ||
return table |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import unittest | ||
import requests_mock | ||
from parsons import Community | ||
|
||
|
||
TEST_CLIENT_ID = "someuuid" | ||
TEST_CLIENT_TOKEN = "somesecret" | ||
|
||
TEST_FILENAME = "campaigns" | ||
TEST_URI = f"https://faketestingurl.com/{TEST_CLIENT_ID}" | ||
TEST_FULL_URL = f"{TEST_URI}/{TEST_FILENAME}.csv.gz" | ||
|
||
TEST_GET_RESPONSE_CSV_STRING = b'"CAMPAIGN_ID","LEADER_ID"\n"0288","6e83b"\n' | ||
|
||
TEST_EXPECTED_COLUMNS = [ | ||
"CAMPAIGN_ID", | ||
"LEADER_ID", | ||
] | ||
|
||
|
||
class TestCommunity(unittest.TestCase): | ||
@requests_mock.Mocker() | ||
def setUp(self, m): | ||
self.com = Community(TEST_CLIENT_ID, TEST_CLIENT_TOKEN, TEST_URI) | ||
|
||
@requests_mock.Mocker() | ||
def test_successful_get_request(self, m): | ||
m.get(TEST_FULL_URL, content=TEST_GET_RESPONSE_CSV_STRING) | ||
|
||
assert self.com.get_request(filename=TEST_FILENAME) == TEST_GET_RESPONSE_CSV_STRING | ||
|
||
# test get resource | ||
@requests_mock.Mocker() | ||
def test_successful_get_data_export(self, m): | ||
m.get(TEST_FULL_URL, content=TEST_GET_RESPONSE_CSV_STRING) | ||
|
||
table = self.com.get_data_export( | ||
TEST_FILENAME, | ||
) | ||
assert TEST_EXPECTED_COLUMNS == table.columns |