Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/boto/fps/connection.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler | 
|---|---|
| date | Fri, 31 Jul 2020 00:18:57 -0400 | 
| parents | |
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| -1:000000000000 | 0:d30785e31577 | 
|---|---|
| 1 # Copyright (c) 2012 Andy Davidoff http://www.disruptek.com/ | |
| 2 # Copyright (c) 2010 Jason R. Coombs http://www.jaraco.com/ | |
| 3 # Copyright (c) 2008 Chris Moyer http://coredumped.org/ | |
| 4 # | |
| 5 # Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 # copy of this software and associated documentation files (the | |
| 7 # "Software"), to deal in the Software without restriction, including | |
| 8 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
| 9 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
| 10 # persons to whom the Software is furnished to do so, subject to the fol- | |
| 11 # lowing conditions: | |
| 12 # | |
| 13 # The above copyright notice and this permission notice shall be included | |
| 14 # in all copies or substantial portions of the Software. | |
| 15 # | |
| 16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 17 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
| 18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
| 19 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
| 20 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 22 # IN THE SOFTWARE. | |
| 23 | |
| 24 import urllib | |
| 25 import uuid | |
| 26 from boto.connection import AWSQueryConnection | |
| 27 from boto.fps.exception import ResponseErrorFactory | |
| 28 from boto.fps.response import ResponseFactory | |
| 29 import boto.fps.response | |
| 30 | |
| 31 __all__ = ['FPSConnection'] | |
| 32 | |
| 33 decorated_attrs = ('action', 'response') | |
| 34 | |
| 35 | |
| 36 def add_attrs_from(func, to): | |
| 37 for attr in decorated_attrs: | |
| 38 setattr(to, attr, getattr(func, attr, None)) | |
| 39 return to | |
| 40 | |
| 41 | |
| 42 def complex_amounts(*fields): | |
| 43 def decorator(func): | |
| 44 def wrapper(self, *args, **kw): | |
| 45 for field in filter(kw.has_key, fields): | |
| 46 amount = kw.pop(field) | |
| 47 kw[field + '.Value'] = getattr(amount, 'Value', str(amount)) | |
| 48 kw[field + '.CurrencyCode'] = getattr(amount, 'CurrencyCode', | |
| 49 self.currencycode) | |
| 50 return func(self, *args, **kw) | |
| 51 wrapper.__doc__ = "{0}\nComplex Amounts: {1}".format(func.__doc__, | |
| 52 ', '.join(fields)) | |
| 53 return add_attrs_from(func, to=wrapper) | |
| 54 return decorator | |
| 55 | |
| 56 | |
| 57 def requires(*groups): | |
| 58 | |
| 59 def decorator(func): | |
| 60 | |
| 61 def wrapper(*args, **kw): | |
| 62 hasgroup = lambda x: len(x) == len(filter(kw.has_key, x)) | |
| 63 if 1 != len(filter(hasgroup, groups)): | |
| 64 message = ' OR '.join(['+'.join(g) for g in groups]) | |
| 65 message = "{0} requires {1} argument(s)" \ | |
| 66 "".format(getattr(func, 'action', 'Method'), message) | |
| 67 raise KeyError(message) | |
| 68 return func(*args, **kw) | |
| 69 message = ' OR '.join(['+'.join(g) for g in groups]) | |
| 70 wrapper.__doc__ = "{0}\nRequired: {1}".format(func.__doc__, | |
| 71 message) | |
| 72 return add_attrs_from(func, to=wrapper) | |
| 73 return decorator | |
| 74 | |
| 75 | |
| 76 def needs_caller_reference(func): | |
| 77 | |
| 78 def wrapper(*args, **kw): | |
| 79 kw.setdefault('CallerReference', uuid.uuid4()) | |
| 80 return func(*args, **kw) | |
| 81 wrapper.__doc__ = "{0}\nUses CallerReference, defaults " \ | |
| 82 "to uuid.uuid4()".format(func.__doc__) | |
| 83 return add_attrs_from(func, to=wrapper) | |
| 84 | |
| 85 | |
| 86 def api_action(*api): | |
| 87 | |
| 88 def decorator(func): | |
| 89 action = ''.join(api or map(str.capitalize, func.__name__.split('_'))) | |
| 90 response = ResponseFactory(action) | |
| 91 if hasattr(boto.fps.response, action + 'Response'): | |
| 92 response = getattr(boto.fps.response, action + 'Response') | |
| 93 | |
| 94 def wrapper(self, *args, **kw): | |
| 95 return func(self, action, response, *args, **kw) | |
| 96 wrapper.action, wrapper.response = action, response | |
| 97 wrapper.__doc__ = "FPS {0} API call\n{1}".format(action, | |
| 98 func.__doc__) | |
| 99 return wrapper | |
| 100 return decorator | |
| 101 | |
| 102 | |
| 103 class FPSConnection(AWSQueryConnection): | |
| 104 | |
| 105 APIVersion = '2010-08-28' | |
| 106 ResponseError = ResponseErrorFactory | |
| 107 currencycode = 'USD' | |
| 108 | |
| 109 def __init__(self, *args, **kw): | |
| 110 self.currencycode = kw.pop('CurrencyCode', self.currencycode) | |
| 111 kw.setdefault('host', 'fps.sandbox.amazonaws.com') | |
| 112 super(FPSConnection, self).__init__(*args, **kw) | |
| 113 | |
| 114 def _required_auth_capability(self): | |
| 115 return ['fps'] | |
| 116 | |
| 117 @needs_caller_reference | |
| 118 @complex_amounts('SettlementAmount') | |
| 119 @requires(['CreditInstrumentId', 'SettlementAmount.Value', | |
| 120 'SenderTokenId', 'SettlementAmount.CurrencyCode']) | |
| 121 @api_action() | |
| 122 def settle_debt(self, action, response, **kw): | |
| 123 """ | |
| 124 Allows a caller to initiate a transaction that atomically transfers | |
| 125 money from a sender's payment instrument to the recipient, while | |
| 126 decreasing corresponding debt balance. | |
| 127 """ | |
| 128 return self.get_object(action, kw, response) | |
| 129 | |
| 130 @requires(['TransactionId']) | |
| 131 @api_action() | |
| 132 def get_transaction_status(self, action, response, **kw): | |
| 133 """ | |
| 134 Gets the latest status of a transaction. | |
| 135 """ | |
| 136 return self.get_object(action, kw, response) | |
| 137 | |
| 138 @requires(['StartDate']) | |
| 139 @api_action() | |
| 140 def get_account_activity(self, action, response, **kw): | |
| 141 """ | |
| 142 Returns transactions for a given date range. | |
| 143 """ | |
| 144 return self.get_object(action, kw, response) | |
| 145 | |
| 146 @requires(['TransactionId']) | |
| 147 @api_action() | |
| 148 def get_transaction(self, action, response, **kw): | |
| 149 """ | |
| 150 Returns all details of a transaction. | |
| 151 """ | |
| 152 return self.get_object(action, kw, response) | |
| 153 | |
| 154 @api_action() | |
| 155 def get_outstanding_debt_balance(self, action, response): | |
| 156 """ | |
| 157 Returns the total outstanding balance for all the credit instruments | |
| 158 for the given creditor account. | |
| 159 """ | |
| 160 return self.get_object(action, {}, response) | |
| 161 | |
| 162 @requires(['PrepaidInstrumentId']) | |
| 163 @api_action() | |
| 164 def get_prepaid_balance(self, action, response, **kw): | |
| 165 """ | |
| 166 Returns the balance available on the given prepaid instrument. | |
| 167 """ | |
| 168 return self.get_object(action, kw, response) | |
| 169 | |
| 170 @api_action() | |
| 171 def get_total_prepaid_liability(self, action, response): | |
| 172 """ | |
| 173 Returns the total liability held by the given account corresponding to | |
| 174 all the prepaid instruments owned by the account. | |
| 175 """ | |
| 176 return self.get_object(action, {}, response) | |
| 177 | |
| 178 @api_action() | |
| 179 def get_account_balance(self, action, response): | |
| 180 """ | |
| 181 Returns the account balance for an account in real time. | |
| 182 """ | |
| 183 return self.get_object(action, {}, response) | |
| 184 | |
| 185 @needs_caller_reference | |
| 186 @requires(['PaymentInstruction', 'TokenType']) | |
| 187 @api_action() | |
| 188 def install_payment_instruction(self, action, response, **kw): | |
| 189 """ | |
| 190 Installs a payment instruction for caller. | |
| 191 """ | |
| 192 return self.get_object(action, kw, response) | |
| 193 | |
| 194 @needs_caller_reference | |
| 195 @requires(['returnURL', 'pipelineName']) | |
| 196 def cbui_url(self, **kw): | |
| 197 """ | |
| 198 Generate a signed URL for the Co-Branded service API given arguments as | |
| 199 payload. | |
| 200 """ | |
| 201 sandbox = 'sandbox' in self.host and 'payments-sandbox' or 'payments' | |
| 202 endpoint = 'authorize.{0}.amazon.com'.format(sandbox) | |
| 203 base = '/cobranded-ui/actions/start' | |
| 204 | |
| 205 validpipelines = ('SingleUse', 'MultiUse', 'Recurring', 'Recipient', | |
| 206 'SetupPrepaid', 'SetupPostpaid', 'EditToken') | |
| 207 assert kw['pipelineName'] in validpipelines, "Invalid pipelineName" | |
| 208 kw.update({ | |
| 209 'signatureMethod': 'HmacSHA256', | |
| 210 'signatureVersion': '2', | |
| 211 }) | |
| 212 kw.setdefault('callerKey', self.aws_access_key_id) | |
| 213 | |
| 214 safestr = lambda x: x is not None and str(x) or '' | |
| 215 safequote = lambda x: urllib.quote(safestr(x), safe='~') | |
| 216 payload = sorted([(k, safequote(v)) for k, v in kw.items()]) | |
| 217 | |
| 218 encoded = lambda p: '&'.join([k + '=' + v for k, v in p]) | |
| 219 canonical = '\n'.join(['GET', endpoint, base, encoded(payload)]) | |
| 220 signature = self._auth_handler.sign_string(canonical) | |
| 221 payload += [('signature', safequote(signature))] | |
| 222 payload.sort() | |
| 223 | |
| 224 return 'https://{0}{1}?{2}'.format(endpoint, base, encoded(payload)) | |
| 225 | |
| 226 @needs_caller_reference | |
| 227 @complex_amounts('TransactionAmount') | |
| 228 @requires(['SenderTokenId', 'TransactionAmount.Value', | |
| 229 'TransactionAmount.CurrencyCode']) | |
| 230 @api_action() | |
| 231 def reserve(self, action, response, **kw): | |
| 232 """ | |
| 233 Reserve API is part of the Reserve and Settle API conjunction that | |
| 234 serve the purpose of a pay where the authorization and settlement have | |
| 235 a timing difference. | |
| 236 """ | |
| 237 return self.get_object(action, kw, response) | |
| 238 | |
| 239 @needs_caller_reference | |
| 240 @complex_amounts('TransactionAmount') | |
| 241 @requires(['SenderTokenId', 'TransactionAmount.Value', | |
| 242 'TransactionAmount.CurrencyCode']) | |
| 243 @api_action() | |
| 244 def pay(self, action, response, **kw): | |
| 245 """ | |
| 246 Allows calling applications to move money from a sender to a recipient. | |
| 247 """ | |
| 248 return self.get_object(action, kw, response) | |
| 249 | |
| 250 @requires(['TransactionId']) | |
| 251 @api_action() | |
| 252 def cancel(self, action, response, **kw): | |
| 253 """ | |
| 254 Cancels an ongoing transaction and puts it in cancelled state. | |
| 255 """ | |
| 256 return self.get_object(action, kw, response) | |
| 257 | |
| 258 @complex_amounts('TransactionAmount') | |
| 259 @requires(['ReserveTransactionId', 'TransactionAmount.Value', | |
| 260 'TransactionAmount.CurrencyCode']) | |
| 261 @api_action() | |
| 262 def settle(self, action, response, **kw): | |
| 263 """ | |
| 264 The Settle API is used in conjunction with the Reserve API and is used | |
| 265 to settle previously reserved transaction. | |
| 266 """ | |
| 267 return self.get_object(action, kw, response) | |
| 268 | |
| 269 @complex_amounts('RefundAmount') | |
| 270 @requires(['TransactionId', 'RefundAmount.Value', | |
| 271 'CallerReference', 'RefundAmount.CurrencyCode']) | |
| 272 @api_action() | |
| 273 def refund(self, action, response, **kw): | |
| 274 """ | |
| 275 Refunds a previously completed transaction. | |
| 276 """ | |
| 277 return self.get_object(action, kw, response) | |
| 278 | |
| 279 @requires(['RecipientTokenId']) | |
| 280 @api_action() | |
| 281 def get_recipient_verification_status(self, action, response, **kw): | |
| 282 """ | |
| 283 Returns the recipient status. | |
| 284 """ | |
| 285 return self.get_object(action, kw, response) | |
| 286 | |
| 287 @requires(['CallerReference'], ['TokenId']) | |
| 288 @api_action() | |
| 289 def get_token_by_caller(self, action, response, **kw): | |
| 290 """ | |
| 291 Returns the details of a particular token installed by this calling | |
| 292 application using the subway co-branded UI. | |
| 293 """ | |
| 294 return self.get_object(action, kw, response) | |
| 295 | |
| 296 @requires(['UrlEndPoint', 'HttpParameters']) | |
| 297 @api_action() | |
| 298 def verify_signature(self, action, response, **kw): | |
| 299 """ | |
| 300 Verify the signature that FPS sent in IPN or callback urls. | |
| 301 """ | |
| 302 return self.get_object(action, kw, response) | |
| 303 | |
| 304 @api_action() | |
| 305 def get_tokens(self, action, response, **kw): | |
| 306 """ | |
| 307 Returns a list of tokens installed on the given account. | |
| 308 """ | |
| 309 return self.get_object(action, kw, response) | |
| 310 | |
| 311 @requires(['TokenId']) | |
| 312 @api_action() | |
| 313 def get_token_usage(self, action, response, **kw): | |
| 314 """ | |
| 315 Returns the usage of a token. | |
| 316 """ | |
| 317 return self.get_object(action, kw, response) | |
| 318 | |
| 319 @requires(['TokenId']) | |
| 320 @api_action() | |
| 321 def cancel_token(self, action, response, **kw): | |
| 322 """ | |
| 323 Cancels any token installed by the calling application on its own | |
| 324 account. | |
| 325 """ | |
| 326 return self.get_object(action, kw, response) | |
| 327 | |
| 328 @needs_caller_reference | |
| 329 @complex_amounts('FundingAmount') | |
| 330 @requires(['PrepaidInstrumentId', 'FundingAmount.Value', | |
| 331 'SenderTokenId', 'FundingAmount.CurrencyCode']) | |
| 332 @api_action() | |
| 333 def fund_prepaid(self, action, response, **kw): | |
| 334 """ | |
| 335 Funds the prepaid balance on the given prepaid instrument. | |
| 336 """ | |
| 337 return self.get_object(action, kw, response) | |
| 338 | |
| 339 @requires(['CreditInstrumentId']) | |
| 340 @api_action() | |
| 341 def get_debt_balance(self, action, response, **kw): | |
| 342 """ | |
| 343 Returns the balance corresponding to the given credit instrument. | |
| 344 """ | |
| 345 return self.get_object(action, kw, response) | |
| 346 | |
| 347 @needs_caller_reference | |
| 348 @complex_amounts('AdjustmentAmount') | |
| 349 @requires(['CreditInstrumentId', 'AdjustmentAmount.Value', | |
| 350 'AdjustmentAmount.CurrencyCode']) | |
| 351 @api_action() | |
| 352 def write_off_debt(self, action, response, **kw): | |
| 353 """ | |
| 354 Allows a creditor to write off the debt balance accumulated partially | |
| 355 or fully at any time. | |
| 356 """ | |
| 357 return self.get_object(action, kw, response) | |
| 358 | |
| 359 @requires(['SubscriptionId']) | |
| 360 @api_action() | |
| 361 def get_transactions_for_subscription(self, action, response, **kw): | |
| 362 """ | |
| 363 Returns the transactions for a given subscriptionID. | |
| 364 """ | |
| 365 return self.get_object(action, kw, response) | |
| 366 | |
| 367 @requires(['SubscriptionId']) | |
| 368 @api_action() | |
| 369 def get_subscription_details(self, action, response, **kw): | |
| 370 """ | |
| 371 Returns the details of Subscription for a given subscriptionID. | |
| 372 """ | |
| 373 return self.get_object(action, kw, response) | |
| 374 | |
| 375 @needs_caller_reference | |
| 376 @complex_amounts('RefundAmount') | |
| 377 @requires(['SubscriptionId']) | |
| 378 @api_action() | |
| 379 def cancel_subscription_and_refund(self, action, response, **kw): | |
| 380 """ | |
| 381 Cancels a subscription. | |
| 382 """ | |
| 383 message = "If you specify a RefundAmount, " \ | |
| 384 "you must specify CallerReference." | |
| 385 assert not 'RefundAmount.Value' in kw \ | |
| 386 or 'CallerReference' in kw, message | |
| 387 return self.get_object(action, kw, response) | |
| 388 | |
| 389 @requires(['TokenId']) | |
| 390 @api_action() | |
| 391 def get_payment_instruction(self, action, response, **kw): | |
| 392 """ | |
| 393 Gets the payment instruction of a token. | |
| 394 """ | |
| 395 return self.get_object(action, kw, response) | 
