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

Kasiah/community dot com connector #1112

Merged
merged 34 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7f4241f
build out community.com connector
KasiaHinkson Aug 5, 2024
277b159
fix url
KasiaHinkson Aug 5, 2024
439d053
add to init
KasiaHinkson Aug 5, 2024
bc49be2
get not post
KasiaHinkson Aug 5, 2024
efbf3d4
small edits to fix connector
KasiaHinkson Aug 5, 2024
657b86e
Update community.py
KasiaHinkson Aug 6, 2024
528e2df
change some names and add test
KasiaHinkson Aug 8, 2024
27dbb09
fix param name
KasiaHinkson Aug 8, 2024
d0a31bd
fix url
KasiaHinkson Aug 8, 2024
bd593ce
wrong url again
KasiaHinkson Aug 8, 2024
c8438e9
maybe this will magically work
KasiaHinkson Aug 8, 2024
bbc1518
add a log for test
KasiaHinkson Aug 8, 2024
71489d9
another log
KasiaHinkson Aug 8, 2024
48fb07a
another log
KasiaHinkson Aug 8, 2024
98fec87
trying again
KasiaHinkson Aug 8, 2024
5b9e0d6
will this pass
KasiaHinkson Aug 8, 2024
ed8e712
more stuff
KasiaHinkson Aug 8, 2024
b62a481
change test response
KasiaHinkson Aug 8, 2024
fc2551e
content not json
KasiaHinkson Aug 8, 2024
4f27edc
another log
KasiaHinkson Aug 8, 2024
36b0651
more logs
KasiaHinkson Aug 8, 2024
d052f40
different test values
KasiaHinkson Aug 8, 2024
83f8674
shorten the test string
KasiaHinkson Aug 8, 2024
126453a
values don't matter
KasiaHinkson Aug 8, 2024
8877778
cleanup
KasiaHinkson Aug 8, 2024
2ae666f
docs
KasiaHinkson Aug 8, 2024
d868766
fix link
KasiaHinkson Aug 8, 2024
ab5b88f
remove commented code
KasiaHinkson Aug 8, 2024
d07daab
don't need these
KasiaHinkson Aug 8, 2024
96af8fa
remove another thing
KasiaHinkson Aug 8, 2024
82576c6
linting
KasiaHinkson Aug 8, 2024
0e6667d
incorporate sharine's fix with an extra try except
KasiaHinkson Aug 9, 2024
22f8841
update links
KasiaHinkson Aug 12, 2024
5d6c17c
links
KasiaHinkson Aug 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions parsons/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
("parsons.catalist.catalist", "CatalistMatch"),
("parsons.census.census", "Census"),
("parsons.civis.civisclient", "CivisClient"),
("parsons.community.community", "Community"),
("parsons.controlshift.controlshift", "Controlshift"),
("parsons.copper.copper", "Copper"),
("parsons.crowdtangle.crowdtangle", "CrowdTangle"),
Expand Down
3 changes: 3 additions & 0 deletions parsons/community/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from parsons.community.community import Community

__all__ = ["Community"]
103 changes: 103 additions & 0 deletions parsons/community/community.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import logging
from parsons.utilities.api_connector import APIConnector
from parsons.utilities import check_env
from parsons.etl import Table

logger = logging.getLogger(__name__)

POLLING_DELAY = 1
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 CSV API. Not required, default is
https://secure.actblue.com/api/v1. You can set an ``ACTBLUE_URI`` env variable or
use this URI parameter if a different endpoint is necessary - for example, when
running this code in a test environment where you don't want to hit the actual API.
"""

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}",
# "accept": "*/*",
# "accept-encoding": "gzip",
}
self.client = APIConnector(
self.uri,
headers=self.headers,
)

def get_request(self, resource):
"""
GET request to Community.com API to get the CSV data.

`Args:`
resource: str
Data resource 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 {resource}")
url = (
f"{resource}.csv.gz"
if resource != "outbound_message_type_usage"
else f"{resource}.csv.gz/segment-based-subscription"
)
response = self.client.get_request(url=url)
return response

def get_resource(self, resource):
"""
Get specified data from Community.com API as Parsons table.

`Args:`
resource: str
Data resource 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(resource=resource)
response_string = get_request_response.decode("utf-8")
table = Table.from_csv_string(response_string)
return table
7 changes: 5 additions & 2 deletions parsons/utilities/api_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@ def get_request(self, url, params=None):

r = self.request(url, "GET", params=params)
self.validate_response(r)
logger.debug(r.json())

return r.json()
try:
logger.debug(r.json())
return r.json()
except JSONDecodeError:
return r.content

def post_request(
self, url, params=None, data=None, json=None, success_codes=[200, 201, 202, 204]
Expand Down
35 changes: 35 additions & 0 deletions test/test_community/test_community.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import unittest
import requests_mock
from parsons import Table, Community
from unittest.mock import MagicMock


TEST_CLIENT_ID = "someuuid"
TEST_CLIENT_TOKEN = "somesecret"

TEST_ID = "12345"
TEST_URI = "https://faketestingurl.com/example"

TEST_CSV_TYPE = "campaigns"

TEST_GET_RESPONSE = {
"body": '"LEADER_ID","DATE_DAY","OUTBOUND_MESSAGE_TYPE","MESSAGE_COUNT","SEGMENT_COUNT"\n"6e83b266-899f-4a01-b39c-e614a4929df7","2022-10-03","FAN_ONBOARDING",1,3',
}


class TestCommunity(unittest.TestCase):
@requests_mock.Mocker()
def setUp(self, m):
self.com = Community(TEST_CLIENT_ID, TEST_CLIENT_TOKEN, TEST_URI)
self.from_csv = Table.from_csv
test_csv_data = Table.from_csv_string(open("test/test_actblue/test_csv_data.csv").read())
Table.from_csv = MagicMock(name="mocked from_csv", return_value=test_csv_data)

def tearDown(self):
Table.from_csv = self.from_csv

@requests_mock.Mocker()
def test_successful_get_request(self, m):
m.get(f"{TEST_URI}/{TEST_CLIENT_ID}/{TEST_CSV_TYPE}.csv.gz", json=TEST_GET_RESPONSE)

assert self.com.get_request(resource=TEST_CSV_TYPE) == TEST_GET_RESPONSE
3 changes: 3 additions & 0 deletions test/test_community/test_community_data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
LEADER_ID,DATE_DAY,OUTBOUND_MESSAGE_TYPE,MESSAGE_COUNT,SEGMENT_COUNT
6e83b266-899f-4a01-b39c-e614a4929df7,2022-10-03,FAN_ONBOARDING,1,,
6e83b266-899f-4a01-b39c-e614a4929df7,2022-09-21,AUTOMATED,2,2
Loading