def get(self, currency, address): """ Returns addresses' neighbors in the address graph as CSV """ args = neighbors_parser.parse_args() direction = args.get("direction") check_inputs(address=address, currency=currency) if "in" in direction: def query_function(page_state): return addressesDAO.list_address_incoming_relations( currency, address, page_state) direction = 'incoming' else: def query_function(page_state): return addressesDAO.list_address_outgoing_relations( currency, address, page_state) direction = 'outgoing' try: return Response(to_csv(query_function), mimetype="text/csv", headers=create_download_header( '{} neighbors of address {} ({}).csv' .format(direction, address, currency.upper()))) except ValueError: abort(404, "Address {} not found in currency {}" .format(address, currency))
def get(self, currency, address): """ Returns attribution tags for a given address """ check_inputs(address=address, currency=currency) # abort if fails address_tags = commonDAO.list_address_tags(currency, address) return address_tags # can be empty list
def get(self, currency, height): """ Returns a CSV with all the transactions of the block """ check_inputs(currency=currency, height=height) def query_function(_): result = blocksDAO.list_block_txs(currency, height) if result: txs = result["txs"] block_height = result["height"] for tx in txs: tx['block_height'] = block_height return None, txs abort(404, "Block {} not found in currency {}".format(height, currency)) try: return Response(to_csv(query_function), mimetype="text/csv", headers=create_download_header( 'transactions of block {} ({}).csv'.format( height, currency.upper()))) except ValueError: abort(404, "Block {} not found in currency {}".format(height, currency))
def get(self, currency, entity): """ Returns attribution tags for a given entity """ check_inputs(currency=currency, entity=entity) tags = entitiesDAO.list_entity_tags(currency, entity) return tags
def get(self, currency, address): """ Returns an addresses' neighbors in the address graph """ args = links_parser.parse_args() neighbor = args.get("neighbor") check_inputs(address=address, currency=currency, neighbor=neighbor) links = addressesDAO.list_addresses_links(currency, address, neighbor) return {'links': links}
def get(self, currency, height): """ Returns a list of all transactions within a given block. """ check_inputs(currency=currency, height=height) block_txs = blocksDAO.list_block_txs(currency, height) if block_txs: return block_txs abort(404, "Block {} not found in currency {}".format(height, currency))
def get(self, currency, height): """ Returns details of a specific block identified by its height """ check_inputs(currency=currency, height=height) block = blocksDAO.get_block(currency, height) if block: return block abort(404, "Block {} not found in currency {}".format(height, currency))
def get(self): """ Returns matching addresses, transactions and labels """ # TODO: too slow with bech32 address search args = search_parser.parse_args() currency = args['currency'] expression = args['q'] limit = args['limit'] currencies = [ c for c in current_app.config['MAPPING'] if c != 'tagpacks' ] if currency: check_inputs(currency=currency) currencies = [currency] can_be_label, can_be_tx_address = check_inputs(expression=expression) leading_zeros = 0 pos = 0 # leading zeros will be lost when casting to int while expression[pos] == "0": pos += 1 leading_zeros += 1 result = dict() result['currencies'] = [] if can_be_tx_address: for currency in currencies: element = dict() element['addresses'] = [] element['txs'] = [] element['currency'] = currency # Look for addresses and transactions if len(expression) >= txsDAO.TX_PREFIX_LENGTH: txs = txsDAO.list_matching_txs(currency, expression, leading_zeros) element["txs"] = txs[:limit] if len(expression) >= addressesDAO.ADDRESS_PREFIX_LENGTH: addresses = \ addressesDAO.list_matching_addresses(currency, expression) element["addresses"] = addresses[:limit] result['currencies'].append(element) result['labels'] = [] if can_be_label: for currency in currencies: labels = labelsDAO.list_labels(currency, expression)[:limit] if labels: result['labels'] += labels return result
def get(self, currency, address): """ Returns details and tags of a specific address """ check_inputs(address=address, currency=currency) # abort if fails addr = commonDAO.get_address(currency, address) if addr: addr['tags'] = commonDAO.list_address_tags(currency, address) return addr abort(404, "Address {} not found in currency {}".format(address, currency))
def get(self, currency, tx_hash): """ Returns details of a specific transaction identified by its hash. """ check_inputs(tx=tx_hash, currency=currency) tx = txsDAO.get_tx(currency, tx_hash) if tx: return tx abort( 404, "Transaction {} not found in currency {}".format( tx_hash, currency))
def get(self, currency, height): """ Returns exchange rate for a given height """ check_inputs(currency=currency, height=height) rates = ratesDAO.get_rates(currency, height) if not rates: abort( 404, "Exchange rate for height {} not found in currency {}".format( height, currency)) return rates
def get(self, currency): """ Returns a list of blocks (100 per page) """ args = page_parser.parse_args() page = args.get("page") check_inputs(currency=currency, page=page) paging_state = bytes.fromhex(page) if page else None paging_state, blocks = blocksDAO.list_blocks(currency, paging_state) return { "next_page": paging_state.hex() if paging_state else None, "blocks": blocks }
def get(self, currency, address): """ Returns the associated entity for a given address """ check_inputs(address=address, currency=currency) # abort if fails entity = addressesDAO.get_address_entity(currency, address) if entity: entity['tags'] = entitiesDAO.list_entity_tags(currency, entity['entity']) entity['tag_coherence'] = compute_tag_coherence(entity['tags']) return entity abort(404, "Address {} not found in currency {}".format(address, currency))
def get(self, currency): """ Returns a list of transactions (100 per page) """ args = page_parser.parse_args() page = args.get("page") check_inputs(currency=currency, page=page) paging_state = bytes.fromhex(page) if page else None paging_state, txs = txsDAO.list_txs(currency, paging_state) return { "next_page": paging_state.hex() if paging_state else None, "txs": txs }
def get(self, currency, entity): """ Returns details and optionally tags of a specific entity """ check_inputs(currency=currency, entity=entity) entity_stats = entitiesDAO.get_entity(currency, entity) if entity_stats: entity_stats['tags'] = entitiesDAO.\ list_entity_tags(currency, entity_stats['entity']) entity_stats['tag_coherence'] = compute_tag_coherence( entity_stats['tags']) return entity_stats abort(404, "Entity {} not found in currency {}".format(entity, currency))
def get(self, currency, entity): """ Returns attribution tags for a given entity as CSV """ check_inputs(currency=currency, entity=entity) def query_function(_): return (None, entitiesDAO.list_entity_tags(currency, int(entity))) return Response(to_csv(query_function), mimetype="text/csv", headers=create_download_header('tags of entity {} ' '({}).csv'.format( entity, currency.upper())))
def get(self, currency, address): """ Returns attribution tags for a given address as CSV """ check_inputs(address=address, currency=currency) # abort if fails def query_function(_): return (None, commonDAO.list_address_tags( currency, address)) return Response(to_csv(query_function), mimetype="text/csv", headers=create_download_header('tags of address {} ' '({}).csv' .format(address, currency .upper())))
def get(self, currency, address): """ Returns all transactions an address has been involved in """ args = page_size_parser.parse_args() page = args['page'] pagesize = args['pagesize'] check_inputs(address=address, currency=currency, page=page, pagesize=pagesize) # abort if fails paging_state = bytes.fromhex(page) if page else None paging_state, address_txs = addressesDAO.list_address_txs(currency, address, paging_state, pagesize) if address_txs: return {"next_page": paging_state.hex() if paging_state else None, "address_txs": address_txs} abort(404, "Address {} not found in currency {}".format(address, currency))
def get(self): """ Returns the tags associated with a given label """ currency = label_parser.parse_args()['currency'] label = label_parser.parse_args()['label'] check_inputs(label=label, currency_optional=currency) if currency: result = tagsDAO.list_tags(label, currency) else: result = [] for currency in current_app.config['MAPPING']: if currency != "tagpacks": tags = tagsDAO.list_tags(label, currency) if tags: result += tags if result: return result abort(404, "Label not found")
def get(self, currency, entity): """ Returns an entities' neighbors in the entity graph """ args = neighbors_parser.parse_args() direction = args.get("direction") page = args.get("page") pagesize = args.get("pagesize") targets = args.get("targets") if targets is not None: targets = targets.split(',') check_inputs(currency=currency, page=page, pagesize=pagesize) paging_state = bytes.fromhex(page) if page else None paging_state, relations = entitiesDAO\ .list_entity_relations(currency, entity, "out" in direction, targets, paging_state, pagesize) return { "next_page": paging_state.hex() if paging_state else None, "neighbors": relations }
def get(self, currency, entity): """ Returns an entities' neighbors in the entity graph as CSV """ # TODO: rather slow with 1NDyJtNTjmwk5xPNhjgAMu4HDHigtobu1s args = neighbors_parser.parse_args() direction = args.get("direction") check_inputs(currency=currency, entity=entity) is_outgoing = "out" in direction def query_function(page_state): return entitiesDAO.list_entity_relations(currency, entity, is_outgoing, None, page_state) direction = "outgoing" if is_outgoing else "incoming" return Response(to_csv(query_function), mimetype="text/csv", headers=create_download_header( '{} neighbors of entity {} ({}).csv'.format( direction, entity, currency.upper())))
def get(self, currency, entity): """ Returns all addresses associated with an entity """ args = page_size_parser.parse_args() page = args.get("page") pagesize = args.get("pagesize") check_inputs(currency=currency, entity=entity, page=page, pagesize=pagesize) paging_state = bytes.fromhex(page) if page else None paging_state, addresses = entitiesDAO\ .list_entity_addresses(currency, entity, paging_state, pagesize) if addresses: return { "next_page": paging_state.hex() if paging_state else None, "addresses": addresses } abort(404, "Entity {} not found in currency {}".format(entity, currency))
def get(self, currency, address): """ Returns an addresses' neighbors in the address graph """ args = neighbors_parser.parse_args() direction = args.get("direction") page = args.get("page") pagesize = args.get("pagesize") check_inputs(address=address, currency=currency, page=page, pagesize=pagesize) paging_state = bytes.fromhex(page) if page else None if "in" in direction: paging_state, relations = addressesDAO\ .list_address_incoming_relations(currency, address, paging_state, pagesize) else: paging_state, relations = addressesDAO\ .list_address_outgoing_relations(currency, address, paging_state, pagesize) if relations is not None: # None if address not found, else [] return {"next_page": paging_state.hex() if paging_state else None, "neighbors": relations} abort(404, "Address {} not found in currency {}".format(address, currency))
def mock_list_blocks(*args): check_inputs(currency=args[0]) # abort if fails return None, [block for block in TEST_BLOCKS.values()]
def mock_list_address_tags(*args): check_inputs(currency=args[0]) return []
def mock_get_address(*args): check_inputs(currency=args[0]) return TEST_ADDRESSES.get(args[1])
def mock_list_address_tags(*args): check_inputs(currency=args[0]) return TEST_ADDRESSES_TAGS.get(args[1])
def mock_list_address_txs(*args): check_inputs(currency=args[0]) return None, TEST_ADDRESSES_TXS.get(args[1])
def mock_list_blocks_paging(*args): check_inputs(currency=args[0]) # abort if fails return (bytes('example token', 'utf-8'), [block for block in TEST_BLOCKS.values()])
def get(self, currency, entity): """ Searches for specific types of nodes in an entities' neighborhood """ args = search_neighbors_parser.parse_args() direction = args['direction'] depth = args['depth'] # default and int breadth = args['breadth'] # default and int skip_num_addresses = args['skipNumAddresses'] # default and int category = args['category'] addresses = args['addresses'] field = args['field'] min_value = args['min'] max_value = args['max'] fieldcurrency = args['fieldcurrency'] if not [category, addresses, field].count(None) == 2: abort( 400, 'Invalid search arguments: one among category, ' 'addresses or field must be provided') params = dict() if field: if max_value is not None and min_value > max_value: abort(400, 'Min must not be greater than max') elif field not in ['final_balance', 'total_received']: abort(400, 'Field must be "final_balance" or "total_received"') elif fieldcurrency not in ['value', 'eur', 'usd']: abort( 400, 'Fieldcurrency must be one of "value", "eur" or ' '"usd"') params['field'] = (field, fieldcurrency, min_value, max_value) check_inputs(currency=currency, entity=entity, category=category, depth=depth, addresses=addresses) if category: params['category'] = category.replace(' ', '_') if addresses: addresses_list = [] for address in addresses.split(","): e = addressesDAO.get_address_entity_id(currency, address) if e: addresses_list.append({"address": address, "entity": e}) else: abort( 404, "Entity of address {} not found in currency {}".format( address, currency)) params['addresses'] = addresses_list outgoing = "out" in direction result = entitiesDAO.\ list_entity_search_neighbors(currency, entity, params, breadth, depth, skip_num_addresses, outgoing) def add_tag_coherence(paths): if not paths: return for path in paths: path['node']['tag_coherence'] = compute_tag_coherence( path['node']['tags']) add_tag_coherence(path['paths']) add_tag_coherence(result) return {"paths": result}