Skip to content

Commit 5462713

Browse files
committed
23rd Commit - Solved the issue with pandas datetime parsing on the Mailing List list_lists method.
1 parent 37ee233 commit 5462713

14 files changed

+107
-84
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
.DS_Store
2-
index.rst
2+
build/
33
__pycache__/
44
Contacts/__pycache__/
55
Survey/__pycache__/
66
Setup/__pycache__/
7-
build/
87
dist/
98
QualtricsAPI.egg-info
109
setup.py
1110
pipfile.lock
11+
/documentation
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes.

QualtricsAPI/Contacts/mailinglists.py renamed to QualtricsAPI/XM/mailinglists.py

Lines changed: 92 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
import pandas as pd
66
from QualtricsAPI.Setup import Credentials
77
from QualtricsAPI.JSON import Parser
8+
from QualtricsAPI.Exceptions import MailingListIDError
89

910
class MailingList(Credentials):
11+
''' This class contains methods that give users the ability to work with their users Mailing list's and
12+
their users Mailing Lists contact data within the XMDirectory.'''
1013

1114
def __init__(self, token=None, directory_id=None, data_center=None):
1215
self.token = token
@@ -15,7 +18,7 @@ def __init__(self, token=None, directory_id=None, data_center=None):
1518
return
1619

1720
def create_list(self, name=None):
18-
'''This function creates a mailing list in the XM Directory for the specified user token.
21+
'''This method will create a mailing list in the XM Directory for the your specified user's account.
1922
2023
:param list_name: the name of the list to be created.
2124
:return: set containing the list_name and the list's new id
@@ -34,32 +37,37 @@ def create_list(self, name=None):
3437
return list_params
3538

3639
def list_lists(self, page_size=100, offset=0, to_df=True):
37-
'''This function lists all the mailing lists in the directory for the specified user token.
38-
39-
:param page_size: the number of contacts per call.
40-
:param offset: the offset from the order of contacts.
40+
'''This method lists all the mailing lists in the directory for the specified user token. Use the page_size and offset
41+
parameters to dictate the size and position of the list that is returned. Page_size is defaulted at 100, and offset is
42+
defaulted to start at the beginning (i.e. offset=0).
43+
44+
:param page_size: The number of mailing lists to return per call.
45+
:type page_size: int
46+
:param offset: The index offset that you would like to apply in you call.
47+
:type offset: int
4148
:param to_df: if True, returns the mailing lists and their member objects in a pandas DataFrame.
42-
:return: either a pandas DataFrame or a list of tuples, containing lists and their respective member objects.
49+
:return: Either a pandas DataFrame or a list of tuples, containing lists and their respective member objects.
4350
'''
4451

4552
headers, base_url = self.header_setup()
4653
url = base_url + f"/mailinglists?pageSize={page_size}&offset={offset}"
4754
request = r.get(url, headers=headers)
4855
response = request.json()
49-
keys = Parser().extract_keys(response)[2:-4]
56+
keys = ['mailingListId', 'name', 'ownerId', 'lastModifiedDate', 'creationDate','contactCount']
5057
mailing_lists = Parser().json_parser(response=response, keys=keys, arr=False)
5158
if to_df is True:
5259
mailing_list = pd.DataFrame(mailing_lists).transpose()
5360
mailing_list.columns = keys
54-
#mailing_list['creationDate'] = pd.to_datetime(mailing_list['creationDate'],unit='ms')
55-
#mailing_list['lastModified'] = pd.to_datetime(mailing_list['lastModified'],unit='ms')
61+
mailing_list['creationDate'] = pd.to_datetime(mailing_list['creationDate'], unit='ms')
62+
mailing_list['lastModifiedDate'] = pd.to_datetime(mailing_list['lastModifiedDate'], unit='ms')
5663
return mailing_list
5764
return mailing_lists
5865

5966
def get_list(self, mailing_list=None):
6067
'''This function gets the list specfied by the mailing list param and returns the list members.
6168
62-
:param mailing_list: the mailing list id.
69+
:param mailing_list: Your mailing list id that you are interested in getting information on.
70+
:type mailing_list: str
6371
:return: a dictionary containing the mailing list member objects.
6472
'''
6573

@@ -72,24 +80,28 @@ def get_list(self, mailing_list=None):
7280
request = r.get(url, headers=headers)
7381
response = request.json()
7482
list_info = {
75-
"list_id": response['result']['mailingListId'],
76-
"list_name": response['result']['name'],
77-
"owner_id": response['result']['ownerId'],
78-
"contact_count": response['result']['contactCount'],
79-
"last_modified": t.ctime(response['result']['lastModifiedDate']*0.001),
80-
"creation_date": t.ctime(response['result']['creationDate']*0.001)
83+
"mailingListId": response['result']['mailingListId'],
84+
"name": response['result']['name'],
85+
"ownerId": response['result']['ownerId'],
86+
"lastModifiedDate": response['result']['lastModifiedDate'],
87+
"creationDate": response['result']['creationDate'],
88+
"contactCount": response['result']['contactCount']
8189
}
82-
#Return a DataFrame?
90+
df = pd.DataFrame.from_dict(list_info, orient='index').transpose()
91+
df['creationDate'] = pd.to_datetime(df['creationDate'], unit='ms')
92+
df['lastModifiedDate'] = pd.to_datetime(df['lastModifiedDate'], unit='ms')
8393
except MailingListIDError:
8494
print('Hey there! It looks like your Mailing List ID is incorrect. You can find the Mailing List ID on the Qualtrics site under your account settings. It will begin with "CG_". Please try again.')
85-
return list_info
95+
return df
8696

8797
def rename_list(self, mailing_list=None, name=None):
88-
'''This function takes an existing mailing list name and updates it to reflect the name defined in this function.
98+
'''This method takes an existing mailing list name and updates it to reflect the name defined in the name method.
8999
90-
:param mailing_list: the mailing list id.
91-
:param name: the new name for the mailing list.
92-
:return: nothing, but prints a if successful.
100+
:param mailing_list: Your mailing list id that you are interested in renaming.
101+
:type mailing_list: str
102+
:param name: The new name for the mailing list.
103+
:type name: str
104+
:return: A string confirming that you successfully renamed the list.
93105
'''
94106

95107
assert len(mailing_list) == 18, 'Hey there! The parameter for "mailing_list" that was passed is the wrong length. It should have 18 characters.'
@@ -102,16 +114,17 @@ def rename_list(self, mailing_list=None, name=None):
102114
request = r.put(url, json=data, headers=headers)
103115
response = request.json()
104116
if response['meta']['httpStatus'] == '200 - OK':
105-
print(f'Your mailing list "{mailing_list}" has been renamed in the XM Directory')
117+
print(f'Your mailing list "{mailing_list}" has been renamed to {name} in the XM Directory.')
106118
except MailingListIDError:
107119
print('Hey there! It looks like your Mailing List ID is incorrect. You can find the Mailing List ID on the Qualtrics site under your account settings. It will begin with "CG_". Please try again.')
108120
return
109121

110122
def delete_list(self,mailing_list=None):
111-
'''This function deletes a mailing list from the XM Directory.
123+
'''This method will delete the specified mailing list from the given users XM Directory.
112124
113-
:param mailing_list: the mailing list id
114-
:return: nothing, but prints a if successful and errors if unsuccessful.
125+
:param mailing_list: Your mailing list id that you are interested in deleting.
126+
:type mailing_list: str
127+
:return: A string confirming that you successfully deleted the list.
115128
'''
116129
assert len(mailing_list) == 18, 'Hey there! The parameter for "mailing_list" that was passed is the wrong length. It should have 18 characters.'
117130
assert mailing_list[:3] == 'CG_', 'Hey there! It looks like your Mailing List ID is incorrect. You can find the Mailing List ID on the Qualtrics site under your account settings. Please try again.'
@@ -123,53 +136,76 @@ def delete_list(self,mailing_list=None):
123136
request = r.delete(url, json=data, headers=headers)
124137
response = request.json()
125138
if content['meta']['httpStatus'] == '200 - OK':
126-
print(f'Your mailing list "{mailing_list}" has been deleted from the XM Directory')
139+
print(f'Your mailing list "{mailing_list}" has been deleted from the XM Directory.')
127140
except MailingListIDError:
128141
print('Hey there! It looks like your Mailing List ID is incorrect. You can find the Mailing List ID on the Qualtrics site under your account settings. It will begin with "CG_". Please try again.')
129142
return
130143

131-
def list_contacts(self, mailing_list=None):
132-
'''This function lists the contacts within the defined mailing list.
144+
def list_contacts(self, mailing_list=None, page_size=100, offset=0, to_df=True):
145+
'''This method creates a pandas DataFrame of all the contacts information within the defined mailing list.
133146
134147
:param mailing_list: the mailing list id
135-
:return: a pandas DataFrame containing the contact information.
148+
:type mailing_list: str
149+
:param page_size: The number of contacts in the mailing list to return per call.
150+
:type page_size: int
151+
:param offset: The index offset that you would like to apply in you call.
152+
:type offset: int
153+
:param to_df: if True, returns the contacts in the mailing list and their member objects in a pandas DataFrame.
154+
:return: a pandas DataFrame, or a dictionary containing the contacts information.
136155
'''
137156
assert len(mailing_list) == 18, 'Hey, the parameter for "mailing_list" that was passed is the wrong length. It should have 18 characters.'
138157
assert mailing_list[:3] == 'CG_', 'Hey there! It looks like your Mailing List ID is incorrect. You can find the Mailing List ID on the Qualtrics site under your account settings. Please try again.'
139158

140159
try:
141160
headers, base_url = self.header_setup()
142-
url = base_url + f"/mailinglists/{mailing_list}/contacts"
143-
response = r.get(url, headers=headers)
144-
lists = response.json()
145-
contact_lists = []
146-
i=0
147-
while lists['result']['nextPage'] is not None:
148-
contact_list = Parser().json_parser(lists,'results','contactId','firstName', 'lastName', 'email', 'phone', 'extRef', 'language', 'unsubscribed')
149-
contact_list_ = pd.DataFrame(contact_list, columns=['contact_id','first_name','last_name','email','phone','unsbscribed','language','external_ref'])
150-
contact_list_['mailing_list'] = mailing_list
151-
contact_lists.append(contact_list_)
152-
url = lists['result']['nextPage']
153-
response = r.get(url, headers=headers)
154-
lists = response.json()
155-
i+=1
156-
contact_list = pd.concat(contact_lists).reset_index(drop=True)
161+
url = base_url + f"/mailinglists/{mailing_list}/contacts?pageSize={page_size}&offset={offset}"
162+
request = r.get(url, headers=headers)
163+
response = request.json()
164+
keys = ['contactId','firstName', 'lastName', 'email', 'phone', 'extRef', 'language', 'unsubscribed']
165+
contact_list = Parser().json_parser(response=response, keys=keys, arr=False)
166+
if to_df is True:
167+
contact_list = pd.DataFrame(contact_list).transpose()
168+
contact_list.columns = keys
169+
contact_list['mailing_list'] = mailing_list
170+
171+
#contact_list = []
172+
#while lists['result']['nextPage'] is not None:
173+
#contact_list = Parser().json_parser(lists, keys=keys arr=False)
174+
#contact_df = pd.DataFrame(contact_list).transpose()
175+
#contact_df.columns = keys
176+
#contact_df['mailing_list'] = mailing_list
177+
#contact_lists.append(contact_df)
178+
#url = lists['result']['nextPage']
179+
#response = r.get(url, headers=headers)
180+
#lists = response.json()
181+
#contact_df = pd.concat(contact_lists).reset_index(drop=True)
182+
157183
except MailingListIDError:
158184
print('Hey there! It looks like your Mailing List ID is incorrect. You can find the Mailing List ID on the Qualtrics site under your account settings. It will begin with "CG_". Please try again.')
159185
return contact_list
160186

161187
def create_contact_in_list(self, mailing_list=None, first_name=None, last_name=None, email=None, phone=None, external_ref=None, unsubscribed=False,language="en",metadata={}):
162-
'''This function creates contacts in a specified mailing list.
163-
164-
:param mailing_list: the mailing list id.
165-
:param first_name: the contacts first name.
166-
:param last_name: the contacts last name.
167-
:param email: the contacts email.
168-
:param phone: the contacts phone number.
169-
:param external_ref: the contacts external reference.
170-
:param unsubscribed: denotes whether the contact is unsubscribed.
171-
:param language: the native language of the contact (Default: English)
172-
:param metadata: any relevant contact metadata.
188+
'''This method creates contacts in the specified mailing list. It is important to remember here that whenever you create a contact in
189+
a mailing list, you are also creating that contact in the XMDirectory. Once created 2 seperate IDs are created for the contact. The ContactID
190+
is the reference for the contact in the XMDirectory, and the Contact Lookup ID is the reference of the contact in the Mailing List.
191+
192+
:param mailing_list: The mailing list id for the list that you want to add the contact too.
193+
:type mailing_list: str
194+
:param first_name: The new contact's first name.
195+
:type first_name: str
196+
:param last_name: The new contact's last name.
197+
:type last_name: str
198+
:param email: The new contact's email.
199+
:type email: str
200+
:param phone: The new contact's phone number.
201+
:tyoe phone: str
202+
:param external_ref: The new contact's external reference.
203+
:type external_ref: str
204+
:param unsubscribed: This parameter denotes whether the new contact is unsubscribed from surveys (Default: False).
205+
:type unsbscribed: str
206+
:param language: The language prefered by the new contact (Default: English)
207+
:type language: str
208+
:param metadata: Any relevant contact metadata.
173209
:type metadata: dict
174210
:return: the contact id (contact_id) in XMDirectory, and the contact id (contact_list_id) in the mailing list.
175211
'''

QualtricsAPI/Contacts/xmdirectory.py renamed to QualtricsAPI/XM/xmdirectory.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def create_contact_in_XM(self, first_name=None, last_name=None, email=None, phon
3232
:type language: str
3333
:param metadata: any relevant contact metadata.
3434
:type metadata: dict
35-
:return: The newly created contact id (contact_id) in XMDirectory.
35+
:return: The newly created contact id (CID) in XMDirectory.
3636
:type return: str
3737
'''
3838

@@ -98,11 +98,10 @@ def list_contacts_in_directory(self, page_size=100, offset=0, to_df=True):
9898
url = base_url + f"/contacts?pageSize={page_size}&offset={offset}"
9999
request = r.get(url, headers=headers)
100100
response = request.json()
101-
#extract_keys
102-
contact_list = Parser().json_parser(response=response,keys=['contactId','firstName', 'lastName', 'email', 'phone', 'unsubscribed', 'language', 'extRef'])
103-
col_names = ['contact_id','first_name','last_name','email','phone','unsubscribed','language','external_ref']
101+
keys = ['contactId','firstName', 'lastName', 'email', 'phone','unsubscribed', 'language', 'extRef']
102+
contact_list = Parser().json_parser(response=response,keys=keys)
104103
if to_df is True:
105-
contact_list = pd.DataFrame(contact_list, columns=col_names)
104+
contact_list = pd.DataFrame(contact_list, columns=keys)
106105
return contact_list
107106
except ServerError:
108107
print(f"ServerError:\nError Code: {response['meta']['error']['errorCode']}\nError Message: {response['meta']['error']['errorMessage']}", s.msg)

QualtricsAPI/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from QualtricsAPI.Setup import Credentials
33
from QualtricsAPI.Survey import Responses
44
from QualtricsAPI.JSON import Parser
5-
from QualtricsAPI.Contacts import MailingList
6-
from QualtricsAPI.Contacts import XMDirectory
5+
from QualtricsAPI.XM import MailingList
6+
from QualtricsAPI.XM import XMDirectory
77

88
__all__ = ["Setup", "JSON", "Contacts", "Survey"]

QualtricsAPI/tests/test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from QualtricsAPI.Setup import Credentials
55
from QualtricsAPI.Survey import Responses
66
from QualtricsAPI.JSON import Parser
7-
from QualtricsAPI.Contacts import MailingList
8-
from QualtricsAPI.Contacts import XMDirectory
7+
from QualtricsAPI.XM import MailingList
8+
from QualtricsAPI.XM import XMDirectory
99

1010
# Setup Tests Class
1111
class setup_tests(object):

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ This will generate environment variables that will be used to populate the HTTP
3737
Now the generation of the necessary HTTP headers will be handled automatically, so we don't have to worry about it. We have 2 modules available to work with Contact Data. The first is `XMDirectory()`, and `MailingList()`. We import each as follows below.
3838

3939
```python
40-
from QualtricsAPI.Contacts import XMDirectory
41-
from QualtricsAPI.Contacts import MailingList
40+
from QualtricsAPI.XM import XMDirectory
41+
from QualtricsAPI.XM import MailingList
4242

4343
#Create instances of each
4444
x = XMDirectory()

documentation/source/mailinglist.rst

Lines changed: 0 additions & 5 deletions
This file was deleted.

documentation/source/quickstart.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ find one of these IDs check out `Qualtrics - Finding Your Qualtrics IDs Guide <h
2020
:members: qualtrics_api_credentials
2121

2222
Example Implementation
23-
###########################
23+
----------------------
2424

2525
Here is an example on how to implement the qualtrics_api_credentials() method.
2626
::

documentation/source/responses.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
Survey Responses
22
==================
33

4-
5-
.. autoclass:: QualtricsAPI.Survey.responses.Responses
6-
:members: get_responses, get_questions
4+
.. automethod:: QualtricsAPI.Survey.responses.Responses.get_responses
5+
.. automethod:: QualtricsAPI.Survey.responses.Responses.get_questions

documentation/source/xmdirectory.rst

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)