def _check_source_meta(m: List[SourceMetadata], controlled_metadata): _not_falsy_in_iterable(m, 'source_metadata') # it doesn't make sense to turn the whole thing into json as a rough measure of size as the # user is not responsible for the field names. total_bytes = 0 seen = set() for sm in m: if sm.key in seen: raise IllegalParameterError( f'Duplicate source metadata key: {sm.key}') seen.add(sm.key) # could check for duplicate sm.sourcekeys too, but possibly the source data is split into # two metadata keys? if sm.key not in controlled_metadata: raise IllegalParameterError( f'Source metadata key {sm.key} does not appear in the controlled metadata' ) total_bytes += len(sm.key.encode('utf-8')) + len( sm.sourcekey.encode('utf-8')) total_bytes += len( _json.dumps(dict(sm.sourcevalue), ensure_ascii=False).encode('utf-8')) # Would be nice if that could be streamed so we don't make a new byte array # This calculation is more convoluted than I would like and hard to reproduce for users # but it's really unlikely the limit is ever going to be hit so YAGNI re improvements, # at least for now. if total_bytes > _META_MAX_SIZE_B: raise IllegalParameterError( f'Source metadata is larger than maximum of {_META_MAX_SIZE_B}B')
def _to_tuple(self, seq, name): # dict.fromkeys removes dupes return tuple( dict.fromkeys( _cast(Sequence[UserID], _not_falsy_in_iterable([] if seq is None else seq, name))))
def _to_tuple(seq, name) -> _Tuple[UserID, ...]: # dict.fromkeys removes dupes return tuple( dict.fromkeys( sorted( # sort to make equals and hash consistent _cast(Sequence[UserID], _not_falsy_in_iterable([] if seq is None else seq, name)), key=lambda u: u.id))) # add comparison methods to user?
def links_to_dicts(links: List[DataLink]) -> List[Dict[str, Any]]: ''' Translate a list of link objects to a list of dicts suitable for tranlating to JSON. :param links: the links. :returns: the list of dicts. ''' ret = [] for link in _cast(List[DataLink], _not_falsy_in_iterable(links, 'links')): ex = datetime_to_epochmilliseconds(link.expired) if link.expired else None ret.append({ 'linkid': str(link.id), 'upa': str(link.duid.upa), 'dataid': link.duid.dataid, 'id': str(link.sample_node_address.sampleid), 'version': link.sample_node_address.version, 'node': link.sample_node_address.node, 'createdby': str(link.created_by), 'created': datetime_to_epochmilliseconds(link.created), 'expiredby': str(link.expired_by) if link.expired_by else None, 'expired': ex }) return ret