willisapi-client 1.2__tar.gz → 1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {willisapi_client-1.2 → willisapi_client-1.5}/PKG-INFO +1 -1
  2. {willisapi_client-1.2 → willisapi_client-1.5}/requirements.txt +2 -2
  3. willisapi_client-1.5/setup.py +56 -0
  4. {willisapi_client-1.2 → willisapi_client-1.5}/tests/test_auth.py +57 -67
  5. {willisapi_client-1.2 → willisapi_client-1.5}/tests/test_csv_validation.py +1 -1
  6. {willisapi_client-1.2 → willisapi_client-1.5}/tests/test_upload.py +19 -0
  7. willisapi_client-1.5/willisapi_client/__init__.py +11 -0
  8. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/__version__.py +1 -1
  9. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/api.py +1 -1
  10. willisapi_client-1.5/willisapi_client/services/auth/__init__.py +7 -0
  11. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/auth/auth_utils.py +4 -4
  12. willisapi_client-1.5/willisapi_client/services/auth/user_group_manager.py +67 -0
  13. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/download/download_utils.py +20 -30
  14. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/upload/csv_validation.py +16 -12
  15. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/upload/upload_utils.py +7 -0
  16. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/willisapi_client.py +3 -0
  17. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client.egg-info/PKG-INFO +1 -1
  18. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client.egg-info/SOURCES.txt +1 -1
  19. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client.egg-info/requires.txt +2 -2
  20. willisapi_client-1.2/setup.py +0 -37
  21. willisapi_client-1.2/willisapi_client/__init__.py +0 -6
  22. willisapi_client-1.2/willisapi_client/services/auth/__init__.py +0 -9
  23. willisapi_client-1.2/willisapi_client/services/auth/user_manager.py +0 -59
  24. {willisapi_client-1.2 → willisapi_client-1.5}/LICENSE +0 -0
  25. {willisapi_client-1.2 → willisapi_client-1.5}/MANIFEST.in +0 -0
  26. {willisapi_client-1.2 → willisapi_client-1.5}/README.md +0 -0
  27. {willisapi_client-1.2 → willisapi_client-1.5}/RELEASE.md +0 -0
  28. {willisapi_client-1.2 → willisapi_client-1.5}/setup.cfg +0 -0
  29. {willisapi_client-1.2 → willisapi_client-1.5}/tests/test_download.py +0 -0
  30. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/logging_setup.py +0 -0
  31. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/__init__.py +0 -0
  32. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/auth/login_manager.py +0 -0
  33. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/download/__init__.py +0 -0
  34. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/download/download_handler.py +0 -0
  35. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/exceptions.py +0 -0
  36. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/upload/__init__.py +0 -0
  37. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/upload/language_choices.py +0 -0
  38. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/upload/multipart_upload_handler.py +0 -0
  39. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/services/upload/utils.py +0 -0
  40. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client/timer.py +0 -0
  41. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client.egg-info/dependency_links.txt +0 -0
  42. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client.egg-info/not-zip-safe +0 -0
  43. {willisapi_client-1.2 → willisapi_client-1.5}/willisapi_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: willisapi_client
3
- Version: 1.2
3
+ Version: 1.5
4
4
  Summary: A Python client for willisapi
5
5
  Home-page: https://github.com/bklynhlth/willsiapi_client
6
6
  Author: bklynhlth
@@ -1,4 +1,4 @@
1
- aiohttp==3.8.5
1
+ aiohttp==3.9.0
2
2
  aiosignal==1.3.1
3
3
  async-timeout==4.0.2
4
4
  asyncio==3.4.3
@@ -15,7 +15,7 @@ pytz==2023.3
15
15
  requests==2.31.0
16
16
  six==1.16.0
17
17
  tzdata==2023.3
18
- urllib3==2.0.4
18
+ urllib3==2.0.7
19
19
  yarl==1.9.2
20
20
  tqdm==4.66.1
21
21
  nest-asyncio==1.5.7
@@ -0,0 +1,56 @@
1
+ # website: https://www.brooklyn.health
2
+
3
+ import setuptools
4
+ import os
5
+ import sys
6
+ import logging
7
+
8
+ # Version details
9
+ current_dir = os.path.abspath(os.path.dirname(__file__))
10
+ log_file = os.path.join(current_dir, ".willisapilogs")
11
+ details = {}
12
+ with open(os.path.join(current_dir, "willisapi_client", "__version__.py"), "r") as fv:
13
+ exec(fv.read(), details)
14
+
15
+ # Long description
16
+ with open("README.md", "r") as fh:
17
+ long_description = fh.read()
18
+
19
+ # Dependencies
20
+ with open("requirements.txt", "r") as fp:
21
+ install_requires = fp.read().split("\n")
22
+ while "" in install_requires:
23
+ install_requires.remove("")
24
+
25
+
26
+ def willisapi_package_log():
27
+ logging.basicConfig(
28
+ filename=log_file,
29
+ level=logging.CRITICAL,
30
+ format="%(asctime)s - %(levelname)s - %(message)s",
31
+ )
32
+ logging.critical("An error occurred: %s", e)
33
+
34
+
35
+ if __name__ == "__main__":
36
+ try:
37
+ setuptools.setup(
38
+ name=details["__client__"],
39
+ version=details["__latestVersion__"],
40
+ description=details["__short_description__"],
41
+ long_description=long_description,
42
+ long_description_content_type=details["__content_type__"],
43
+ url=details["__url__"],
44
+ author="bklynhlth",
45
+ python_requires=">=3.9",
46
+ install_requires=install_requires,
47
+ author_email="admin@brooklyn.health",
48
+ packages=setuptools.find_packages(exclude=["tests*"]),
49
+ include_package_data=True,
50
+ zip_safe=False,
51
+ license="Apache",
52
+ )
53
+
54
+ except Exception as e:
55
+ willisapi_package_log("An error occurred: {}".format(e))
56
+ sys.exit(1)
@@ -1,5 +1,5 @@
1
1
  from willisapi_client.services.auth.login_manager import login
2
- from willisapi_client.services.auth.user_manager import create_user
2
+ from willisapi_client.services.auth.user_group_manager import create_account
3
3
  from unittest.mock import patch
4
4
  from datetime import timedelta, datetime
5
5
 
@@ -10,6 +10,8 @@ class TestLoginFunction:
10
10
  self.username = "dummy"
11
11
  self.password = "password"
12
12
  self.id_token = "dummy_token"
13
+ self.client_email = "dummy@gmail.com"
14
+ self.client_name = "dummy_group"
13
15
  self.expires_in = 100
14
16
  self.expires_in_date = str(
15
17
  self.dt.replace(hour=0, minute=0, second=0, microsecond=0)
@@ -65,97 +67,85 @@ class TestLoginFunction:
65
67
  assert key == None
66
68
  assert expire_in == None
67
69
 
68
-
69
- class TestSignupFunction:
70
- def setup_method(self):
71
- self.username = "dummy"
72
- self.password = "password"
73
- self.admin_key = "admin_key"
74
- self.non_admin_key = "non_admin_key"
75
- self.client_email = "client@email.com"
76
- self.client_name = "client"
77
- self.first_name = "First"
78
- self.last_name = "Last"
79
-
80
- @patch("willisapi_client.services.auth.login_manager.AuthUtils.signup")
81
- def test_signup_failed(self, mocked_signup):
82
- mocked_signup.return_value = {
70
+ @patch("willisapi_client.services.auth.user_group_manager.AuthUtils.create_account")
71
+ def test_create_account_success(self, mocked_create_account):
72
+ mocked_create_account.return_value = {
83
73
  "status_code": 200,
84
- "message": "Not an admin user",
74
+ "message": "User already present in the group",
85
75
  }
86
- message = create_user(
87
- self.non_admin_key,
76
+ result = create_account(
77
+ self.id_token,
88
78
  self.client_email,
89
79
  self.client_name,
90
- self.first_name,
91
- self.last_name,
92
80
  )
93
- assert message == "Not an admin user"
81
+ print(result)
82
+ assert result == "User already present in the group"
94
83
 
95
- @patch("willisapi_client.services.auth.login_manager.AuthUtils.signup")
96
- def test_signup_success(self, mocked_signup):
97
- mocked_signup.return_value = {"status_code": 200, "message": "User created"}
98
- message = create_user(
99
- self.admin_key,
84
+ @patch("willisapi_client.services.auth.user_group_manager.AuthUtils.create_account")
85
+ def test_create_account_failed(self, mocked_create_account):
86
+ mocked_create_account.return_value = {
87
+ "message": "Login failed",
88
+ }
89
+ result = create_account(
90
+ self.id_token,
100
91
  self.client_email,
101
92
  self.client_name,
102
- self.first_name,
103
- self.last_name,
104
93
  )
105
- assert message == "User created"
94
+ print(result)
95
+ assert result == None
106
96
 
107
- @patch("willisapi_client.services.auth.login_manager.AuthUtils.signup")
108
- def test_signup_failed_400_status(self, mocked_signup):
109
- mocked_signup.return_value = {
97
+ @patch("willisapi_client.services.auth.user_group_manager.AuthUtils.create_account")
98
+ def test_create_account_failed_400_status(self, mocked_create_account):
99
+ mocked_create_account.return_value = {
110
100
  "status_code": 400,
101
+ "message": "Python error",
111
102
  }
112
- message = create_user(
113
- self.admin_key,
103
+ result = create_account(
104
+ self.id_token,
114
105
  self.client_email,
115
106
  self.client_name,
116
- self.first_name,
117
- self.last_name,
118
107
  )
119
- assert message == None
108
+ print(result)
109
+ assert result == "Python error"
120
110
 
121
- @patch("willisapi_client.services.auth.login_manager.AuthUtils.signup")
122
- def test_signup_failed_500_status(self, mocked_signup):
123
- mocked_signup.return_value = {
124
- "status_code": 500,
111
+ @patch("willisapi_client.services.auth.user_group_manager.AuthUtils.create_account")
112
+ def test_create_account_failed_401_status(self, mocked_create_account):
113
+ mocked_create_account.return_value = {
114
+ "status_code": 401,
115
+ "message": "Not an Admin User",
125
116
  }
126
- message = create_user(
127
- self.admin_key,
117
+ result = create_account(
118
+ self.id_token,
128
119
  self.client_email,
129
120
  self.client_name,
130
- self.first_name,
131
- self.last_name,
132
121
  )
133
- assert message == None
134
-
135
- @patch("willisapi_client.services.auth.login_manager.AuthUtils.signup")
136
- def test_signup_failed_401_status(self, mocked_signup):
137
- mocked_signup.return_value = {
138
- "status_code": 401,
122
+ print(result)
123
+ assert result == "Not an Admin User"
124
+
125
+ @patch("willisapi_client.services.auth.user_group_manager.AuthUtils.create_account")
126
+ def test_create_account_failed_409_status(self, mocked_create_account):
127
+ mocked_create_account.return_value = {
128
+ "status_code": 409,
129
+ "message": "User already exists or already in some group",
139
130
  }
140
- message = create_user(
141
- self.admin_key,
131
+ result = create_account(
132
+ self.id_token,
142
133
  self.client_email,
143
134
  self.client_name,
144
- self.first_name,
145
- self.last_name,
146
135
  )
147
- assert message == None
148
-
149
- @patch("willisapi_client.services.auth.login_manager.AuthUtils.signup")
150
- def test_signup_failed_403_status(self, mocked_signup):
151
- mocked_signup.return_value = {
152
- "status_code": 403,
136
+ print(result)
137
+ assert result == "User already exists or already in some group"
138
+
139
+ @patch("willisapi_client.services.auth.user_group_manager.AuthUtils.create_account")
140
+ def test_create_account_failed_404_status(self, mocked_create_account):
141
+ mocked_create_account.return_value = {
142
+ "status_code": 404,
143
+ "message": "User not found",
153
144
  }
154
- message = create_user(
155
- self.admin_key,
145
+ result = create_account(
146
+ self.id_token,
156
147
  self.client_email,
157
148
  self.client_name,
158
- self.first_name,
159
- self.last_name,
160
149
  )
161
- assert message == None
150
+ print(result)
151
+ assert result == "User not found"
@@ -148,7 +148,7 @@ class TestCSVValidation:
148
148
  row = {
149
149
  "project_name": "project_name",
150
150
  "file_path": "file.mp4",
151
- "workflow_tags": "scale_abc,speech_transcription_dummy",
151
+ "workflow_tags": "scale_abc,speech_transcription_aws_dummy",
152
152
  "pt_id_external": "qwerty",
153
153
  "time_collected": "2023-02-02",
154
154
  "language": "en-US",
@@ -84,3 +84,22 @@ class TestUpload:
84
84
  assert df.iloc[0].filename == "video.mp4"
85
85
  assert df.iloc[0].upload_status == "success"
86
86
  assert df.iloc[0].upload_message == None
87
+
88
+ @patch("willisapi_client.services.upload.upload_utils.UploadUtils.upload")
89
+ @patch("willisapi_client.services.upload.csv_validation.CSVValidation.validate_row")
90
+ @patch(
91
+ "willisapi_client.services.upload.csv_validation.CSVValidation.get_dataframe"
92
+ )
93
+ @patch("willisapi_client.services.upload.csv_validation.CSVValidation._is_valid")
94
+ def test_upload_failed_no_credits_available(
95
+ self, mock_valid_csv, mocked_df, mock_row_validation, mocked_upload
96
+ ):
97
+ mock_valid_csv.return_value = True
98
+ mocked_df.return_value = pd.DataFrame([self.df_row], columns=self.df_cols)
99
+ mock_row_validation.return_value = True, None
100
+ mocked_upload.return_value = False, "Your account is using all allocated projects; further projects cannot be created."
101
+ df = upload(self.key, self.metadata)
102
+ num = len(df[df["upload_status"] == "fail"])
103
+ assert num == 1
104
+ assert list(df.columns) == self.response_df_cols
105
+ assert df.iloc[0].upload_status == "fail"
@@ -0,0 +1,11 @@
1
+ # website: https://www.brooklyn.health
2
+
3
+ # import the required packages
4
+ from willisapi_client.services.api import (
5
+ login,
6
+ upload,
7
+ download,
8
+ create_account,
9
+ )
10
+
11
+ __all__ = ["login", "upload", "download", "create_account"]
@@ -1,7 +1,7 @@
1
1
  """Version details for willisapi_client
2
2
  """
3
3
  __client__ = "willisapi_client"
4
- __latestVersion__ = "1.2"
4
+ __latestVersion__ = "1.5"
5
5
  __url__ = "https://github.com/bklynhlth/willsiapi_client"
6
6
  __short_description__ = "A Python client for willisapi"
7
7
  __content_type__ = "text/markdown"
@@ -1,6 +1,6 @@
1
1
  # website: https://www.brooklyn.health
2
2
 
3
3
  # import the required packages
4
- from willisapi_client.services.auth import login, create_user
4
+ from willisapi_client.services.auth import login, create_account
5
5
  from willisapi_client.services.upload import upload
6
6
  from willisapi_client.services.download import download
@@ -0,0 +1,7 @@
1
+ # website: https://www.brooklyn.health
2
+ from willisapi_client.services.auth.login_manager import (
3
+ login,
4
+ )
5
+ from willisapi_client.services.auth.user_group_manager import create_account
6
+
7
+ __all__ = ["login", "create_account"]
@@ -51,14 +51,14 @@ class AuthUtils:
51
51
  return res_json
52
52
 
53
53
  @staticmethod
54
- def signup(url, data, headers, try_number):
54
+ def create_account(url, data, headers, try_number):
55
55
  """
56
56
  ------------------------------------------------------------------------------------------------------
57
57
  Class: AuthUtils
58
58
 
59
- Function: signup
59
+ Function: create_account
60
60
 
61
- Description: This is an internal signup function which makes a POST API call to the brooklyn.health API server.
61
+ Description: This is an internal create_account function which makes a POST API call to the brooklyn.health API server.
62
62
 
63
63
  Parameters:
64
64
  ----------
@@ -86,6 +86,6 @@ class AuthUtils:
86
86
  if try_number == 3:
87
87
  raise UnableToOnboardClientError
88
88
  time.sleep(random.random() * 2)
89
- return AuthUtils.signup(url, data, headers, try_number=try_number + 1)
89
+ return AuthUtils.create_account(url, data, headers, try_number)
90
90
  else:
91
91
  return res_json
@@ -0,0 +1,67 @@
1
+ # website: https://www.brooklyn.health
2
+ from http import HTTPStatus
3
+
4
+ from willisapi_client.willisapi_client import WillisapiClient
5
+ from willisapi_client.services.auth.auth_utils import AuthUtils
6
+ from willisapi_client.logging_setup import logger as logger
7
+
8
+ from datetime import datetime
9
+
10
+
11
+ def create_account(
12
+ key: str,
13
+ client_email: str,
14
+ client_name: str,
15
+ **kwargs,
16
+ ) -> str:
17
+ """
18
+ ---------------------------------------------------------------------------------------------------
19
+ Function: create_account
20
+
21
+ Description: This function to add users to the expected group using willis create account API
22
+
23
+ Parameters:
24
+ ----------
25
+ key: Admin access token
26
+ client_email: User's client email id
27
+ client_name: User's client name (group)
28
+
29
+ Returns:
30
+ ----------
31
+ status : Onboard succes/fail message (str/None)
32
+ ---------------------------------------------------------------------------------------------------
33
+ """
34
+ wc = WillisapiClient(env=kwargs.get("env"))
35
+ url = wc.get_create_account_url()
36
+ headers = wc.get_headers()
37
+ headers["Authorization"] = key
38
+ data = dict(
39
+ client_email=client_email,
40
+ client_name=client_name,
41
+ )
42
+ # logger.info(f'{datetime.now().strftime("%H:%M:%S")}: Creating account')
43
+ response = AuthUtils.create_account(url, data, headers, try_number=1)
44
+ if response and "status_code" in response:
45
+ if response["status_code"] == HTTPStatus.BAD_REQUEST:
46
+ # Invalid argument
47
+ logger.error("Python error")
48
+ if response["status_code"] == HTTPStatus.UNAUTHORIZED:
49
+ logger.error("Not an Admin User")
50
+ if response["status_code"] == HTTPStatus.CONFLICT:
51
+ logger.error("User already exists or already in some group")
52
+ if response["status_code"] == HTTPStatus.NOT_FOUND:
53
+ # No user in cognito
54
+ logger.error("User not found")
55
+
56
+ if response["message"] == "User added in group.":
57
+ logger.info(
58
+ f'{datetime.now().strftime("%H:%M:%S")}: User added to the group successfully'
59
+ )
60
+ if response["message"] == "User already present in the group":
61
+ logger.info(
62
+ f'{datetime.now().strftime("%H:%M:%S")}: User already present in the group'
63
+ )
64
+ return response["message"]
65
+ else:
66
+ logger.error(f"Login Failed")
67
+ return None
@@ -5,10 +5,9 @@ import random
5
5
  import pandas as pd
6
6
  from typing import Tuple
7
7
 
8
- emotional_expressivity_summary = "emotional_expressivity_summary"
9
- facial_expressivity_summary = "facial_expressivity_summary"
10
- vocal_acoustic_summary = "vocal_acoustic_summary"
8
+ vocal_acoustic_summary = "vocal_acoustics_summary"
11
9
  speech_characteristics_summary = "speech_characteristics_summary"
10
+ rater_qa_summary = "rater_qa_summary"
12
11
 
13
12
 
14
13
  class DownloadUtils:
@@ -162,20 +161,17 @@ class DownloadUtils:
162
161
  measures_dict = response["items"]["project"]["participant"][pt]["results"][rec][
163
162
  "measures"
164
163
  ]
165
- if workflow_tag in measures_dict:
166
- if measures_dict[workflow_tag]:
167
- if workflow_tag in [
168
- emotional_expressivity_summary,
169
- facial_expressivity_summary,
170
- ]:
171
- return pd.read_json(
172
- json.dumps(measures_dict[workflow_tag][0])
173
- ).head(1)
174
- if workflow_tag in [
175
- vocal_acoustic_summary,
176
- speech_characteristics_summary,
177
- ]:
178
- return pd.read_json(json.dumps(measures_dict[workflow_tag][0]))
164
+ if (
165
+ workflow_tag in measures_dict
166
+ and measures_dict[workflow_tag]
167
+ and workflow_tag
168
+ in [
169
+ vocal_acoustic_summary,
170
+ speech_characteristics_summary,
171
+ rater_qa_summary,
172
+ ]
173
+ ):
174
+ return pd.read_json(json.dumps(measures_dict[workflow_tag][0]))
179
175
  return pd.DataFrame()
180
176
 
181
177
  def generate_response_df(response) -> Tuple[pd.DataFrame, str]:
@@ -216,16 +212,7 @@ class DownloadUtils:
216
212
  [[project_name, pt_id_ext, filename, time_collected]],
217
213
  columns=DownloadUtils._get_defined_columns(),
218
214
  )
219
- emotional_expressivity_summary_df = (
220
- DownloadUtils._get_summary_df_from_json(
221
- response, pt, rec, emotional_expressivity_summary
222
- )
223
- )
224
- facial_expressivity_summary_df = (
225
- DownloadUtils._get_summary_df_from_json(
226
- response, pt, rec, facial_expressivity_summary
227
- )
228
- )
215
+
229
216
  vocal_acoustics_summary_df = (
230
217
  DownloadUtils._get_summary_df_from_json(
231
218
  response, pt, rec, vocal_acoustic_summary
@@ -236,18 +223,21 @@ class DownloadUtils:
236
223
  response, pt, rec, speech_characteristics_summary
237
224
  )
238
225
  )
226
+ rater_qa_summary_df = DownloadUtils._get_summary_df_from_json(
227
+ response, pt, rec, rater_qa_summary
228
+ )
239
229
  df = pd.concat(
240
230
  [
241
231
  main_df,
242
- emotional_expressivity_summary_df,
243
- facial_expressivity_summary_df,
244
232
  vocal_acoustics_summary_df,
245
233
  speech_characteristics_summary_df,
234
+ rater_qa_summary_df,
246
235
  ],
247
236
  axis=1,
248
237
  )
249
238
  response_df = response_df._append(df, ignore_index=True)
250
- response_df = response_df.drop(["stats"], axis=1)
239
+ if "stats" in response_df.columns:
240
+ response_df = response_df.drop(["stats"], axis=1)
251
241
  except Exception as ex:
252
242
  return None, f"{ex}"
253
243
  else:
@@ -5,16 +5,13 @@ import pathlib
5
5
  import re
6
6
  from typing import Tuple
7
7
 
8
- from willisapi_client.services.exceptions import (
9
- InvalidFileType,
10
- InvalidFilePath,
11
- InvalidCSVColumns,
12
- )
13
8
  from willisapi_client.logging_setup import logger as logger
14
9
  from willisapi_client.services.upload.language_choices import (
15
10
  LANGUAGE_CHOICES,
16
11
  English_us,
17
12
  )
13
+ from dateutil.parser import parse, ParserError
14
+ from datetime import datetime
18
15
 
19
16
 
20
17
  class CSVValidation:
@@ -38,7 +35,7 @@ class CSVValidation:
38
35
  self.workflow_tags = [
39
36
  "vocal_acoustics",
40
37
  "speech_characteristics",
41
- "speech_transcription",
38
+ "speech_transcription_aws",
42
39
  "voice_and_speech",
43
40
  "facial_expressivity",
44
41
  "emotional_expressivity",
@@ -46,11 +43,13 @@ class CSVValidation:
46
43
  "speaker_separation",
47
44
  "speech_characteristics_from_json",
48
45
  "eye_blink_rate",
46
+ "rater_qa",
49
47
  ]
50
48
  self.dynamic_workflow_tags = [
51
- "speech_transcription_",
49
+ "speech_transcription_aws_",
52
50
  "speaker_separation_",
53
51
  "scale_",
52
+ "speech_characteristics_",
54
53
  "rater_qa_",
55
54
  ]
56
55
  self.collect_time_format = r"^\d{4}-\d{2}-\d{2}$"
@@ -255,11 +254,16 @@ class CSVValidation:
255
254
  error: A str error message if collect_time is invalid
256
255
  ------------------------------------------------------------------------------------------------------
257
256
  """
258
- if collect_time == None:
259
- return True, None
260
- if collect_time and bool(re.match(self.collect_time_format, collect_time)):
261
- return True, None
262
- return False, f"Invalid {self.time_collected} formatting"
257
+ date_pattern = re.compile(self.collect_time_format)
258
+ if collect_time and date_pattern.match(collect_time):
259
+ try:
260
+ date = parse(collect_time)
261
+ except ParserError:
262
+ return False, f"Invalid {self.time_collected} formatting"
263
+ else:
264
+ if date > datetime.now():
265
+ return False, f"Invalid {self.time_collected} formatting"
266
+ return True, None
263
267
 
264
268
  def _is_language_valid(self, language: str) -> Tuple[bool, str]:
265
269
  """
@@ -144,6 +144,7 @@ class UploadUtils:
144
144
  pass
145
145
  else:
146
146
  error = None
147
+ project_limit_error = "Your account is using all allocated projects; further projects cannot be created."
147
148
  if "status_code" in res_json:
148
149
  if res_json["status_code"] == HTTPStatus.OK:
149
150
  if index == 0:
@@ -157,6 +158,12 @@ class UploadUtils:
157
158
  ):
158
159
  if res_json["message"] == "Data already present in DB":
159
160
  error = "data is already available in our storage"
161
+ if (
162
+ "message" in res_json
163
+ and res_json["message"] == project_limit_error
164
+ ):
165
+ error = project_limit_error
166
+ logger.error(error)
160
167
  else:
161
168
  if "message" in res_json and res_json["message"] == "Unauthorized":
162
169
  logger.error(
@@ -37,5 +37,8 @@ class WillisapiClient:
37
37
  return f"https://{self.env}-{self.app_url}download"
38
38
  return f"https://{self.app_url}download"
39
39
 
40
+ def get_create_account_url(self):
41
+ return self.get_base_url() + "create-account"
42
+
40
43
  def get_headers(self):
41
44
  return {"Content-Type": "application/json", "Accept": "application/json"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: willisapi-client
3
- Version: 1.2
3
+ Version: 1.5
4
4
  Summary: A Python client for willisapi
5
5
  Home-page: https://github.com/bklynhlth/willsiapi_client
6
6
  Author: bklynhlth
@@ -26,7 +26,7 @@ willisapi_client/services/exceptions.py
26
26
  willisapi_client/services/auth/__init__.py
27
27
  willisapi_client/services/auth/auth_utils.py
28
28
  willisapi_client/services/auth/login_manager.py
29
- willisapi_client/services/auth/user_manager.py
29
+ willisapi_client/services/auth/user_group_manager.py
30
30
  willisapi_client/services/download/__init__.py
31
31
  willisapi_client/services/download/download_handler.py
32
32
  willisapi_client/services/download/download_utils.py
@@ -1,4 +1,4 @@
1
- aiohttp==3.8.5
1
+ aiohttp==3.9.0
2
2
  aiosignal==1.3.1
3
3
  async-timeout==4.0.2
4
4
  asyncio==3.4.3
@@ -15,7 +15,7 @@ pytz==2023.3
15
15
  requests==2.31.0
16
16
  six==1.16.0
17
17
  tzdata==2023.3
18
- urllib3==2.0.4
18
+ urllib3==2.0.7
19
19
  yarl==1.9.2
20
20
  tqdm==4.66.1
21
21
  nest-asyncio==1.5.7
@@ -1,37 +0,0 @@
1
- # website: https://www.brooklyn.health
2
-
3
- import setuptools
4
- import os
5
-
6
- # Version details
7
- current_dir = os.path.abspath(os.path.dirname(__file__))
8
- details = {}
9
- with open(os.path.join(current_dir, "willisapi_client", "__version__.py"), "r") as fv:
10
- exec(fv.read(), details)
11
-
12
- # Long description
13
- with open("README.md", "r") as fh:
14
- long_description = fh.read()
15
-
16
- # Dependencies
17
- with open("requirements.txt", "r") as fp:
18
- install_requires = fp.read().split("\n")
19
- while "" in install_requires:
20
- install_requires.remove("")
21
-
22
- setuptools.setup(
23
- name=details["__client__"],
24
- version=details["__latestVersion__"],
25
- description=details["__short_description__"],
26
- long_description=long_description,
27
- long_description_content_type=details["__content_type__"],
28
- url=details["__url__"],
29
- author="bklynhlth",
30
- python_requires=">=3.9",
31
- install_requires=install_requires,
32
- author_email="admin@brooklyn.health",
33
- packages=setuptools.find_packages(exclude=["tests*"]),
34
- include_package_data=True,
35
- zip_safe=False,
36
- license="Apache",
37
- )
@@ -1,6 +0,0 @@
1
- # website: https://www.brooklyn.health
2
-
3
- # import the required packages
4
- from willisapi_client.services.api import login, create_user, upload, download
5
-
6
- __all__ = ["login", "create_user", "upload", "download"]
@@ -1,9 +0,0 @@
1
- # website: https://www.brooklyn.health
2
- from willisapi_client.services.auth.login_manager import (
3
- login,
4
- )
5
- from willisapi_client.services.auth.user_manager import (
6
- create_user,
7
- )
8
-
9
- __all__ = ["login", "create_user"]
@@ -1,59 +0,0 @@
1
- # website: https://www.brooklyn.health
2
- from http import HTTPStatus
3
-
4
- from willisapi_client.willisapi_client import WillisapiClient
5
- from willisapi_client.services.auth.auth_utils import AuthUtils
6
- from willisapi_client.logging_setup import logger as logger
7
-
8
-
9
- def create_user(
10
- key: str,
11
- client_email: str,
12
- client_name: str,
13
- first_name: str,
14
- last_name: str,
15
- **kwargs,
16
- ) -> str:
17
- """
18
- ---------------------------------------------------------------------------------------------------
19
- Function: create_user
20
-
21
- Description: This is the signup function to access willisAPI signup API
22
-
23
- Parameters:
24
- ----------
25
- key: Admin access token
26
- client_email: string representation of client email id
27
- client_name: stringbrepresentation of expected client name without empty spaces
28
- first_name: User's first name
29
- last_name: User's last_name
30
-
31
- Returns:
32
- ----------
33
- status : Onboard succes/fail message (str/None)
34
- ---------------------------------------------------------------------------------------------------
35
- """
36
-
37
- wc = WillisapiClient(env=kwargs.get("env"))
38
- url = wc.get_signup_url()
39
- headers = wc.get_headers()
40
- headers["Authorization"] = key
41
- data = dict(
42
- client_email=client_email,
43
- client_name=client_name,
44
- first_name=first_name,
45
- last_name=last_name,
46
- )
47
- response = AuthUtils.signup(url, data, headers, try_number=1)
48
- if (
49
- response
50
- and "status_code" in response
51
- and response["status_code"] == HTTPStatus.OK
52
- ):
53
- logger.info(
54
- f"Signup Successful for client: {client_name}, client_email: {client_email}"
55
- )
56
- return response["message"]
57
- else:
58
- logger.error(f"Signup Failed")
59
- return None
File without changes
File without changes
File without changes