def delay_task(task, kwargs=None, args=None, force_simulate=False, queue='high-priority'): if current_app.config['ENABLE_SIMULATOR_MODE'] or force_simulate: return worker_simulator.simulate(task, kwargs, args, queue) signature = celery_app.signature(task, kwargs=kwargs, args=args) async_result = signature.apply_async(queue=queue) return async_result
def save_photo_and_check_for_duplicate(url, new_filename, image_id): save_to_s3_from_url(url, new_filename) try: rekognition_task = celery_app.signature('worker.celery_tasks.check_for_duplicate_person', args=(new_filename, image_id)) # TODO: Standardize this task (pipe through execute_synchronous_celery) rekognition_task.delay() except Exception as e: print(e) sentry_sdk.capture_exception(e) pass
def save_photo_and_check_for_duplicate(url, new_filename, image_id): save_to_s3_from_url(url, new_filename) try: rekognition_task = celery_app.signature( 'worker.celery_tasks.check_for_duplicate_person', args=(new_filename, image_id)) rekognition_task.delay() except Exception as e: print(e) sentry.captureException() pass
def location(self, location): self._location = location if location is not None and location is not '': try: task = {'user_id': self.id, 'address': location} geolocate_task = celery_app.signature( 'worker.celery_tasks.geolocate_address', args=(task, )) geolocate_task.delay() except Exception as e: print(e) sentry.captureException() pass
def ip(self, ip): self._ip = ip if ip is not None: try: task = {'ip_address_id': self.id, 'ip': ip} ip_location_task = celery_app.signature( 'worker.celery_tasks.ip_location', args=(task, )) ip_location_task.delay() except Exception as e: print(e) sentry.captureException() pass
def get_usd_to_satoshi_rate(): blockchain_task = celery_app.signature( 'worker.celery_tasks.get_usd_to_satoshi_rate') # TODO: Convert to task_runner result = blockchain_task.apply_async() try: conversion_rate = result.wait(timeout=3, propagate=True, interval=0.5) except Exception as e: print(e) sentry_sdk.capture_exception(e) raise BlockchainError("Blockchain Error") finally: result.forget() return conversion_rate
def send_blockchain_payload_to_worker(self, is_retry=False): if self.transfer_type == TransferTypeEnum.DISBURSEMENT: if self.recipient_user and self.recipient_user.transfer_card: self.recipient_user.transfer_card.update_transfer_card() master_wallet_approval_status = self.recipient_transfer_account.master_wallet_approval_status elapsed_time('4.3.2: Approval Status calculated') if master_wallet_approval_status in ['NO_REQUEST', 'FAILED']: account_to_approve_pk = self.recipient_transfer_account.blockchain_address.encoded_private_key else: account_to_approve_pk = None blockchain_payload = { 'type': 'DISBURSEMENT', 'credit_transfer_id': self.id, 'transfer_amount': self.transfer_amount, 'recipient': self.recipient_transfer_account.blockchain_address.address, 'account_to_approve_pk': account_to_approve_pk, 'master_wallet_approval_status': master_wallet_approval_status, 'uncompleted_tasks': list(self.uncompleted_blockchain_tasks), 'is_retry': is_retry } elapsed_time('4.3.3: Payload made') elif self.transfer_type == TransferTypeEnum.PAYMENT: if self.recipient_transfer_account: recipient = self.recipient_transfer_account.blockchain_address.address else: recipient = self.recipient_blockchain_address.address try: master_wallet_approval_status = self.recipient_transfer_account.master_wallet_approval_status except AttributeError: master_wallet_approval_status = 'NOT_REQUIRED' if master_wallet_approval_status in ['NO_REQUEST', 'FAILED']: account_to_approve_pk = self.recipient_transfer_account.blockchain_address.encoded_private_key else: account_to_approve_pk = None blockchain_payload = { 'type': 'PAYMENT', 'credit_transfer_id': self.id, 'transfer_amount': self.transfer_amount, 'sender': self.sender_transfer_account.blockchain_address.address, 'recipient': recipient, 'account_to_approve_pk': account_to_approve_pk, 'master_wallet_approval_status': master_wallet_approval_status, 'uncompleted_tasks': list(self.uncompleted_blockchain_tasks), 'is_retry': is_retry } elif self.transfer_type == TransferTypeEnum.WITHDRAWAL: master_wallet_approval_status = self.sender_transfer_account.master_wallet_approval_status if master_wallet_approval_status == 'NO_REQUEST': account_to_approve_pk = self.sender_transfer_account.blockchain_address.encoded_private_key else: account_to_approve_pk = None blockchain_payload = { 'type': 'WITHDRAWAL', 'credit_transfer_id': self.id, 'transfer_amount': self.transfer_amount, 'sender': self.sender_transfer_account.blockchain_address.address, 'recipient': current_app.config['ETH_OWNER_ADDRESS'], 'account_to_approve_pk': account_to_approve_pk, 'master_wallet_approval_status': master_wallet_approval_status, 'uncompleted_tasks': list(self.uncompleted_blockchain_tasks), 'is_retry': is_retry } else: raise InvalidTransferTypeException("Invalid Transfer Type") if not is_retry or len(blockchain_payload['uncompleted_tasks']) > 0: try: blockchain_task = celery_app.signature( 'worker.celery_tasks.make_blockchain_transaction', kwargs={'blockchain_payload': blockchain_payload}) blockchain_task.delay() except Exception as e: print(e) sentry.captureException() pass
def master_wallet_funds_available(allowed_cache_age_seconds=60): """ IF refreshing cash THEN: return: [current blockchain balance] - [all transfers with blockchain state pending or unknown] save to cache: [funds available at last cache], [ID of highest transfer used in cache], [cache creation datetime] ELSE return: [funds available at last cache] - [all non-failed transfers since cache created] :param allowed_cache_age_seconds: how long between checking the blockchain for external funds added or removed :return: amount of funds available """ refresh_cache = False funds_available_cache = red.get('funds_available_cache') try: parsed_cache = json.loads(funds_available_cache) last_updated_datetime = datetime.datetime.fromtimestamp( float(parsed_cache['last_updated'])) earliest_allowed = datetime.datetime.utcnow() - datetime.timedelta( seconds=allowed_cache_age_seconds) if last_updated_datetime < earliest_allowed: refresh_cache = True except Exception as e: refresh_cache = True if refresh_cache: blockchain_task = celery_app.signature( 'worker.celery_tasks.get_master_balance') result = blockchain_task.apply_async() try: master_wallet_balance = result.wait(timeout=6, propagate=True, interval=0.5) except Exception as e: print(e) sentry.captureException() raise BlockchainError("Blockchain Error") finally: result.forget() highest_transfer_id_checked = 0 required_blockchain_statuses = ['PENDING', 'UNKNOWN'] else: cached_funds_available = parsed_cache['cached_funds_available'] highest_transfer_id_checked = parsed_cache[ 'highest_transfer_id_checked'] required_blockchain_statuses = ['PENDING', 'UNKNOWN', 'COMPLETE'] new_dibursements = (models.CreditTransfer.query.filter( models.CreditTransfer.transfer_type == models.TransferTypeEnum.DISBURSEMENT).filter( models.CreditTransfer.transfer_status == models.TransferStatusEnum.COMPLETE).filter( models.CreditTransfer.id > highest_transfer_id_checked ).filter( models.CreditTransfer.created > datetime.datetime.utcnow() - datetime.timedelta(hours=36)).all()) local_disbursement_value = 0 for disbursement in new_dibursements: status = disbursement.blockchain_status if status in required_blockchain_statuses: local_disbursement_value += disbursement.transfer_amount if refresh_cache: balance = master_wallet_balance - local_disbursement_value if len(new_dibursements) > 0: highest_transfer_id_checked = new_dibursements[-1].id else: all_transfers = models.CreditTransfer.query.all() if len(all_transfers) > 0: highest_transfer_id_checked = all_transfers[-1].id else: highest_transfer_id_checked = 0 cache_data = { 'cached_funds_available': balance, 'highest_transfer_id_checked': highest_transfer_id_checked, 'last_updated': datetime.datetime.utcnow().timestamp() } red.set('funds_available_cache', json.dumps(cache_data)) balance = master_wallet_balance - local_disbursement_value return balance else: balance = cached_funds_available - local_disbursement_value return balance
def post(self): post_data = request.get_json() call = post_data.get('call') if call == 'CREATE_RESPONSE': transaction_hash = post_data.get('transaction_hash') if transaction_hash is None: response_object = { 'message': 'No transaction hash supplied', } return make_response(jsonify(response_object)), 400 transaction = BlockchainTransaction.query.filter_by( hash=transaction_hash).first() if transaction is None: response_object = { 'message': 'Transaction not found for hash {}'.format( transaction_hash), } return make_response(jsonify(response_object)), 405 credit_transfer_id = transaction.credit_transfer_id if credit_transfer_id is None: response_object = { 'message': 'No credit transfer id for hash {}'.format( transaction_hash), } return make_response(jsonify(response_object)), 404 blockchain_task = celery_app.signature( 'worker.celery_tasks.create_transaction_response', kwargs={ 'previous_result': { 'transaction_hash': transaction_hash }, 'credit_transfer_id': credit_transfer_id }) blockchain_task.delay() response_object = { 'message': 'Starting Create Response', } return make_response(jsonify(response_object)), 200 elif call == 'COMPLETE_TASKS': credit_transfer_id = post_data.get('credit_transfer_id') if credit_transfer_id is None: response_object = { 'message': 'No credit transfer id supplied', } return make_response(jsonify(response_object)), 400 credit_transfer = CreditTransfer.query.get(credit_transfer_id) if credit_transfer is None: response_object = { 'message': 'No credit transfer not found', } return make_response(jsonify(response_object)), 404 credit_transfer.send_blockchain_payload_to_worker(is_retry=True) response_object = { 'message': 'Starting Complete Tasks', } return make_response(jsonify(response_object)), 200 response_object = { 'message': 'Call not recognised', } return make_response(jsonify(response_object)), 400
def delay_task(task, kwargs=None, args=None, force_simulate=False): if current_app.config['ENABLE_SIMULATOR_MODE'] or force_simulate: return worker_simulator.simulate(task, kwargs, args) signature = celery_app.signature(task, kwargs=kwargs, args=args) async_result = signature.delay() return async_result
def set_ip_location(ip_address_id, ip): # TODO: Standardize this task (pipe through execute_synchronous_celery) task = {'ip_address_id': ip_address_id, 'ip': ip} ip_location_task = celery_app.signature( 'worker.celery_tasks.ip_location', args=(task, )) ip_location_task.delay()