salespyforce 1.4.0.dev0__py3-none-any.whl

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.
@@ -0,0 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ :Package: salespyforce.errors
4
+ :Synopsis: This module includes custom exceptions and handlers
5
+ :Created By: Jeff Shurtliff
6
+ :Last Modified: Jeff Shurtliff
7
+ :Modified Date: 13 Mar 2023
8
+ """
9
+
10
+ __all__ = ['exceptions', 'handlers']
11
+
12
+ from . import exceptions, handlers
@@ -0,0 +1,389 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ :Module: salespyforce.errors.exceptions
4
+ :Synopsis: Collection of exception classes relating to the SalesPyForce library
5
+ :Created By: Jeff Shurtliff
6
+ :Last Modified: Jeff Shurtliff
7
+ :Modified Date: 13 Mar 2023
8
+ """
9
+
10
+ #################
11
+ # Base Exception
12
+ #################
13
+
14
+
15
+ # Define base exception class
16
+ class SalesPyForceError(Exception):
17
+ """This is the base class for SalesPyForce exceptions."""
18
+ pass
19
+
20
+
21
+ #####################
22
+ # General Exceptions
23
+ #####################
24
+
25
+
26
+ class CurrentlyUnsupportedError(SalesPyForceError):
27
+ """This exception is used when a feature or functionality being used is currently unsupported."""
28
+ def __init__(self, *args, **kwargs):
29
+ """This method defines the default or custom message for the exception."""
30
+ default_msg = "This feature is currently unsupported at this time."
31
+ if not (args or kwargs):
32
+ args = (default_msg,)
33
+ elif 'message' in kwargs:
34
+ args =(kwargs['message'],)
35
+ else:
36
+ custom_msg = f"The '{args[0]}' {default_msg.split('This ')[1]}"
37
+ args = (custom_msg,)
38
+ super().__init__(*args)
39
+
40
+
41
+ class DataMismatchError(SalesPyForceError):
42
+ """This exception is used when there is a mismatch between two data sources."""
43
+ def __init__(self, *args, **kwargs):
44
+ """This method defines the default or custom message for the exception."""
45
+ default_msg = "A data mismatch was found with the data sources."
46
+ if not (args or kwargs):
47
+ args = (default_msg,)
48
+ elif 'data' in kwargs:
49
+ multi_types = [list, tuple, set]
50
+ if type(kwargs['data']) == str:
51
+ custom_msg = f"{default_msg.split('the data')[0]}the '{kwargs['data']}'{default_msg.split('with the')[1]}"
52
+ custom_msg = custom_msg.replace('sources', 'source')
53
+ args = (custom_msg,)
54
+ elif type(kwargs['data']) in multi_types and len(kwargs['data']) == 2:
55
+ custom_section = f"'{kwargs['data'][0]}' and '{kwargs['data'][1]}'"
56
+ custom_msg = f"{default_msg.split('data sources')[0]}{custom_section}{default_msg.split('with the')[1]}"
57
+ args = (custom_msg,)
58
+ super().__init__(*args)
59
+
60
+
61
+ class InvalidParameterError(SalesPyForceError):
62
+ """This exception is used when an invalid parameter is provided."""
63
+ def __init__(self, *args, **kwargs):
64
+ """This method defines the default or custom message for the exception."""
65
+ default_msg = "The parameter that was provided is invalid."
66
+ if not (args or kwargs):
67
+ args = (default_msg,)
68
+ elif 'val' in kwargs:
69
+ custom_msg = f"{default_msg.split('parameter ')[0]}'{kwargs['val']}'{default_msg.split('The')[1]}"
70
+ args = (custom_msg,)
71
+ super().__init__(*args)
72
+
73
+
74
+ class InvalidFieldError(SalesPyForceError):
75
+ """This exception is used when an invalid field is provided."""
76
+ def __init__(self, *args, **kwargs):
77
+ """This method defines the default or custom message for the exception."""
78
+ default_msg = "The field that was provided is invalid."
79
+ if not (args or kwargs):
80
+ args = (default_msg,)
81
+ elif 'val' in kwargs:
82
+ custom_msg = f"{default_msg.split('field ')[0]}'{kwargs['val']}'{default_msg.split('The')[1]}"
83
+ args = (custom_msg,)
84
+ super().__init__(*args)
85
+
86
+
87
+ class InvalidURLError(SalesPyForceError):
88
+ """This exception is used when a provided URL is invalid."""
89
+ def __init__(self, *args, **kwargs):
90
+ """This method defines the default or custom message for the exception."""
91
+ default_msg = "The provided URL is invalid"
92
+ if not (args or kwargs):
93
+ args = (default_msg,)
94
+ elif 'url' in kwargs:
95
+ custom_msg = f"{default_msg.split('is')[0]}'{kwargs['url']}'{default_msg.split('URL')[1]}"
96
+ args = (custom_msg,)
97
+ super().__init__(*args)
98
+
99
+
100
+ class MissingRequiredDataError(SalesPyForceError):
101
+ """This exception is used when a function or method is missing one or more required arguments."""
102
+ def __init__(self, *args, **kwargs):
103
+ """This method defines the default or custom message for the exception."""
104
+ default_msg = "Missing one or more required parameters"
105
+ init_msg = "The object failed to initialize as it is missing one or more required arguments."
106
+ param_msg = "The required parameter 'PARAMETER_NAME' is not defined"
107
+ if not (args or kwargs):
108
+ args = (default_msg,)
109
+ elif 'init' in args or 'initialize' in args:
110
+ if 'object' in kwargs:
111
+ custom_msg = f"{init_msg.split('object')[0]}'{kwargs['object']}'{init_msg.split('The')[1]}"
112
+ args = (custom_msg,)
113
+ else:
114
+ args = (init_msg,)
115
+ elif 'param' in kwargs:
116
+ args = (param_msg.replace('PARAMETER_NAME', kwargs['param']),)
117
+ else:
118
+ args = (default_msg,)
119
+ super().__init__(*args)
120
+
121
+
122
+ class UnknownFileTypeError(SalesPyForceError):
123
+ """This exception is used when a file type for a given file cannot be identified."""
124
+ def __init__(self, *args, **kwargs):
125
+ """This method defines the default or custom message for the exception."""
126
+ default_msg = "The file type of the given file path cannot be identified."
127
+ if not (args or kwargs):
128
+ args = (default_msg,)
129
+ elif 'file' in kwargs:
130
+ custom_msg = f"{default_msg.split('path')[0]}'{kwargs['file']}'{default_msg.split('path')[1]}"
131
+ args = (custom_msg,)
132
+ super().__init__(*args)
133
+
134
+
135
+ #########################
136
+ # Generic API Exceptions
137
+ #########################
138
+
139
+
140
+ class APIConnectionError(SalesPyForceError):
141
+ """This exception is used when the API query could not be completed due to connection aborts and/or timeouts."""
142
+ def __init__(self, *args, **kwargs):
143
+ """This method defines the default or custom message for the exception."""
144
+ default_msg = "The API query could not be completed due to connection aborts and/or timeouts."
145
+ if not (args or kwargs):
146
+ args = (default_msg,)
147
+ super().__init__(*args)
148
+
149
+
150
+ class APIRequestError(SalesPyForceError):
151
+ """This exception is used for generic API request errors when there isn't a more specific exception.
152
+
153
+ .. versionchanged:: 4.5.0
154
+ Fixed an issue with the default message.
155
+ """
156
+ def __init__(self, *args, **kwargs):
157
+ """This method defines the default or custom message for the exception."""
158
+ default_msg = "The API request did not return a successful response."
159
+ if not (args or kwargs):
160
+ args = (default_msg,)
161
+ super().__init__(*args)
162
+
163
+
164
+ class DELETERequestError(SalesPyForceError):
165
+ """This exception is used for generic DELETE request errors when there isn't a more specific exception."""
166
+ def __init__(self, *args, **kwargs):
167
+ """This method defines the default or custom message for the exception."""
168
+ default_msg = "The DELETE request did not return a successful response."
169
+ if not (args or kwargs):
170
+ args = (default_msg,)
171
+ super().__init__(*args)
172
+
173
+
174
+ class FeatureNotConfiguredError(SalesPyForceError):
175
+ """This exception is used when an API request fails because a feature is not configured.
176
+
177
+ .. versionadded:: 4.0.0
178
+ """
179
+ def __init__(self, *args, **kwargs):
180
+ """This method defines the default or custom message for the exception."""
181
+ exc_msg = "The feature is not configured."
182
+ if 'identifier' in kwargs or 'feature' in kwargs:
183
+ if 'identifier' in kwargs:
184
+ exc_msg += f" Identifier: {kwargs['identifier']}"
185
+ if 'feature' in kwargs:
186
+ exc_msg = exc_msg.replace("feature", f"{kwargs['feature']} feature")
187
+ args = (exc_msg,)
188
+ elif not (args or kwargs):
189
+ args = (exc_msg,)
190
+ super().__init__(*args)
191
+
192
+
193
+ class GETRequestError(SalesPyForceError):
194
+ """This exception is used for generic GET request errors when there isn't a more specific exception.
195
+
196
+ .. versionchanged:: 3.2.0
197
+ Enabled the ability to optionally pass ``status_code`` and/or ``message`` arguments.
198
+ """
199
+ def __init__(self, *args, **kwargs):
200
+ """This method defines the default or custom message for the exception."""
201
+ default_msg = "The GET request did not return a successful response."
202
+ custom_msg = "The GET request failed with the following message:"
203
+ if 'status_code' in kwargs or 'message' in kwargs:
204
+ if 'status_code' in kwargs:
205
+ status_code_msg = f"returned the {kwargs['status_code']} status code"
206
+ custom_msg = custom_msg.replace('failed', status_code_msg)
207
+ if 'message' in kwargs:
208
+ custom_msg = f"{custom_msg} {kwargs['message']}"
209
+ else:
210
+ custom_msg = custom_msg.split(' with the following')[0] + "."
211
+ args = (custom_msg,)
212
+ elif not (args or kwargs):
213
+ args = (default_msg,)
214
+ super().__init__(*args)
215
+
216
+
217
+ class InvalidEndpointError(SalesPyForceError):
218
+ """This exception is used when an invalid API endpoint / service is provided.
219
+
220
+ .. versionchanged:: 5.1.2
221
+ Removed part of the default message that was specifically for Khoros JX, which is obsolete.
222
+ """
223
+ def __init__(self, *args, **kwargs):
224
+ """This method defines the default or custom message for the exception."""
225
+ default_msg = "The supplied endpoint for the API is not recognized."
226
+ if not (args or kwargs):
227
+ args = (default_msg,)
228
+ super().__init__(*args)
229
+
230
+
231
+ class InvalidLookupTypeError(SalesPyForceError):
232
+ """This exception is used when an invalid API lookup type is provided."""
233
+ def __init__(self, *args, **kwargs):
234
+ """This method defines the default or custom message for the exception."""
235
+ default_msg = "The supplied lookup type for the API is not recognized. (Examples of valid " + \
236
+ "lookup types include 'id' and 'email')"
237
+ if not (args or kwargs):
238
+ args = (default_msg,)
239
+ super().__init__(*args)
240
+
241
+
242
+ class InvalidPayloadValueError(SalesPyForceError):
243
+ """This exception is used when an invalid value is provided for a payload field.
244
+
245
+ .. versionadded:: 2.6.0
246
+ """
247
+ def __init__(self, *args, **kwargs):
248
+ """This method defines the default or custom message for the exception."""
249
+ default_msg = "An invalid payload value was provided."
250
+ custom_msg = "The invalid payload value 'X' was provided for the 'Y' field."
251
+ if not (args or kwargs):
252
+ args = (default_msg,)
253
+ elif 'value' in kwargs:
254
+ if 'field' in kwargs:
255
+ custom_msg = custom_msg.replace('X', kwargs['value']).replace('Y', kwargs['field'])
256
+ else:
257
+ custom_msg = f"{custom_msg.replace('X', kwargs['value']).split(' for the')[0]}."
258
+ args = (custom_msg,)
259
+ super().__init__(*args)
260
+
261
+
262
+ class InvalidRequestTypeError(SalesPyForceError):
263
+ """This exception is used when an invalid API request type is provided."""
264
+ def __init__(self, *args, **kwargs):
265
+ """This method defines the default or custom message for the exception."""
266
+ default_msg = "The supplied request type for the API is not recognized. (Examples of valid " + \
267
+ "request types include 'POST' and 'PUT')"
268
+ if not (args or kwargs):
269
+ args = (default_msg,)
270
+ super().__init__(*args)
271
+
272
+
273
+ class LookupMismatchError(SalesPyForceError):
274
+ """This exception is used when an a lookup value doesn't match the supplied lookup type."""
275
+ def __init__(self, *args, **kwargs):
276
+ """This method defines the default or custom message for the exception."""
277
+ default_msg = "The supplied lookup type for the API does not match the value that was provided."
278
+ if not (args or kwargs):
279
+ args = (default_msg,)
280
+ super().__init__(*args)
281
+
282
+
283
+ class NotFoundResponseError(SalesPyForceError):
284
+ """This exception is used when an API query returns a 404 response and there isn't a more specific class."""
285
+ def __init__(self, *args, **kwargs):
286
+ """This method defines the default or custom message for the exception."""
287
+ default_msg = "The API query returned a 404 response."
288
+ if not (args or kwargs):
289
+ args = (default_msg,)
290
+ super().__init__(*args)
291
+
292
+
293
+ class PayloadMismatchError(SalesPyForceError):
294
+ """This exception is used when more than one payload is supplied for an API request.
295
+
296
+ .. versionadded:: 3.2.0
297
+ """
298
+ def __init__(self, *args, **kwargs):
299
+ """This method defines the default or custom message for the exception."""
300
+ default_msg = "More than one payload was provided for the API call when only one is permitted."
301
+ if not (args or kwargs):
302
+ args = (default_msg,)
303
+ elif kwargs['request_type']:
304
+ custom_msg = default_msg.replace("API call", f"{kwargs['request_type'].upper()} request")
305
+ args = (custom_msg,)
306
+ super().__init__(*args)
307
+
308
+
309
+ class POSTRequestError(SalesPyForceError):
310
+ """This exception is used for generic POST request errors when there isn't a more specific exception.
311
+
312
+ .. versionchanged:: 3.2.0
313
+ Enabled the ability to optionally pass ``status_code`` and/or ``message`` arguments.
314
+ """
315
+ def __init__(self, *args, **kwargs):
316
+ """This method defines the default or custom message for the exception."""
317
+ default_msg = "The POST request did not return a successful response."
318
+ custom_msg = "The POST request failed with the following message:"
319
+ if 'status_code' in kwargs or 'message' in kwargs:
320
+ if 'status_code' in kwargs:
321
+ status_code_msg = f"returned the {kwargs['status_code']} status code"
322
+ custom_msg = custom_msg.replace('failed', status_code_msg)
323
+ if 'message' in kwargs:
324
+ custom_msg = f"{custom_msg} {kwargs['message']}"
325
+ else:
326
+ custom_msg = custom_msg.split(' with the following')[0] + "."
327
+ args = (custom_msg,)
328
+ elif not (args or kwargs):
329
+ args = (default_msg,)
330
+ super().__init__(*args)
331
+
332
+
333
+ class PUTRequestError(SalesPyForceError):
334
+ """This exception is used for generic PUT request errors when there isn't a more specific exception.
335
+
336
+ .. versionchanged:: 3.2.0
337
+ Enabled the ability to optionally pass ``status_code`` and/or ``message`` arguments.
338
+ """
339
+ def __init__(self, *args, **kwargs):
340
+ """This method defines the default or custom message for the exception."""
341
+ default_msg = "The PUT request did not return a successful response."
342
+ custom_msg = "The PUT request failed with the following message:"
343
+ if 'status_code' in kwargs or 'message' in kwargs:
344
+ if 'status_code' in kwargs:
345
+ status_code_msg = f"returned the {kwargs['status_code']} status code"
346
+ custom_msg = custom_msg.replace('failed', status_code_msg)
347
+ if 'message' in kwargs:
348
+ custom_msg = f"{custom_msg} {kwargs['message']}"
349
+ else:
350
+ custom_msg = custom_msg.split(' with the following')[0] + "."
351
+ args = (custom_msg,)
352
+ elif not (args or kwargs):
353
+ args = (default_msg,)
354
+ super().__init__(*args)
355
+
356
+
357
+ ####################
358
+ # Helper Exceptions
359
+ ####################
360
+
361
+
362
+ class InvalidHelperFileTypeError(SalesPyForceError, ValueError):
363
+ """This exception is used when an invalid file type is provided for the helper file."""
364
+ def __init__(self, *args, **kwargs):
365
+ """This method defines the default or custom message for the exception."""
366
+ default_msg = "The helper configuration file can only have the 'yaml' or 'json' file type."
367
+ if not (args or kwargs):
368
+ args = (default_msg,)
369
+ super().__init__(*args)
370
+
371
+
372
+ class InvalidHelperArgumentsError(SalesPyForceError):
373
+ """This exception is used when the helper function was supplied arguments instead of keyword arguments."""
374
+ def __init__(self, *args, **kwargs):
375
+ """This method defines the default or custom message for the exception."""
376
+ default_msg = "The helper configuration file only accepts basic keyword arguments. (e.g. arg_name='arg_value')"
377
+ if not (args or kwargs):
378
+ args = (default_msg,)
379
+ super().__init__(*args)
380
+
381
+
382
+ class HelperFunctionNotFoundError(SalesPyForceError):
383
+ """This exception is used when a function referenced in the helper config file does not exist."""
384
+ def __init__(self, *args, **kwargs):
385
+ """This method defines the default or custom message for the exception."""
386
+ default_msg = "The function referenced in the helper configuration file could not be found."
387
+ if not (args or kwargs):
388
+ args = (default_msg,)
389
+ super().__init__(*args)
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ :Module: salespyforce.errors.handlers
4
+ :Synopsis: Functions that handle various error situations within the namespace
5
+ :Created By: Jeff Shurtliff
6
+ :Last Modified: Jeff Shurtliff
7
+ :Modified Date: 22 Feb 2023
8
+ """
9
+
10
+ import sys
11
+
12
+
13
+ def eprint(*args, **kwargs):
14
+ """This function behaves the same as the ``print()`` function but is leveraged to print errors to ``sys.stderr``."""
15
+ print(*args, file=sys.stderr, **kwargs)