def to_synapse_annotations(annotations): """Transforms a simple flat dictionary to a Synapse-style Annotation object.""" if is_synapse_annotations(annotations): return annotations synapseAnnos = {} for key, value in annotations.iteritems(): if key in ['id', 'etag', 'blobAnnotations', 'creationDate', 'uri']: synapseAnnos[key] = value elif key in ['stringAnnotations','longAnnotations','doubleAnnotations','dateAnnotations'] and isinstance(value, collections.Mapping): synapseAnnos.setdefault(key, {}).update({k:_to_list(v) for k,v in value.iteritems()}) else: elements = _to_list(value) if all((isinstance(elem, basestring) for elem in elements)): synapseAnnos.setdefault('stringAnnotations', {})[key] = elements elif all((isinstance(elem, bool) for elem in elements)): synapseAnnos.setdefault('stringAnnotations', {})[key] = [str(element).lower() for element in elements] elif all((isinstance(elem, int) or isinstance(elem, long) for elem in elements)): synapseAnnos.setdefault('longAnnotations', {})[key] = elements elif all((isinstance(elem, float) for elem in elements)): synapseAnnos.setdefault('doubleAnnotations', {})[key] = elements elif all((_is_date(elem) for elem in elements)): synapseAnnos.setdefault('dateAnnotations', {})[key] = [to_unix_epoch_time(elem) for elem in elements] ## TODO: support blob annotations # elif all((isinstance(elem, ???) for elem in elements)): # synapseAnnos.setdefault('blobAnnotations', {})[key] = [???(elem) for elem in elements] else: synapseAnnos.setdefault('stringAnnotations', {})[key] = [str(elem) for elem in elements] return synapseAnnos
def to_submission_status_annotations(annotations, is_private=True): """ Converts a normal dictionary to the format used to annotate submission statuses, which is different from the format used to annotate entities. :param annotations: A normal Python dictionary whose values are strings, floats, ints or doubles :param isPrivate: Set privacy on all annotations at once. These can be set individually using :py:func:`set_privacy`. Example:: from synapseclient.annotations import to_submission_status_annotations, from_submission_status_annotations from datetime import datetime as Datetime ## create a submission and get its status submission = syn.submit(evaluation, 'syn11111111') submission_status = syn.getSubmissionStatus(submission) ## add annotations submission_status.annotations = {'foo':'bar', 'shoe_size':12, 'IQ':12, 'timestamp':Datetime.now()} ## convert annotations submission_status.annotations = to_submission_status_annotations(submission_status.annotations) submission_status = syn.store(submission_status) Synapse categorizes these annotations by: stringAnnos, doubleAnnos, longAnnos. If date or blob annotations are supported, they are not `documented <http://rest.synapse.org/org/sagebionetworks/repo/model/annotation/Annotations.html>`_ """ if is_submission_status_annotations(annotations): return annotations synapseAnnos = {} for key, value in annotations.iteritems(): if key in ['objectId', 'scopeId', 'stringAnnos','longAnnos','doubleAnnos']: synapseAnnos[key] = value elif isinstance(value, bool): synapseAnnos.setdefault('stringAnnos', []).append({ 'key':key, 'value':unicode(value).lower(), 'isPrivate':is_private }) elif isinstance(value, int) or isinstance(value, long): synapseAnnos.setdefault('longAnnos', []).append({ 'key':key, 'value':value, 'isPrivate':is_private }) elif isinstance(value, float): synapseAnnos.setdefault('doubleAnnos', []).append({ 'key':key, 'value':value, 'isPrivate':is_private }) elif isinstance(value, basestring): synapseAnnos.setdefault('stringAnnos', []).append({ 'key':key, 'value':value, 'isPrivate':is_private }) elif _is_date(value): synapseAnnos.setdefault('longAnnos', []).append({ 'key':key, 'value':to_unix_epoch_time(value), 'isPrivate':is_private }) else: synapseAnnos.setdefault('stringAnnos', []).append({ 'key':key, 'value':unicode(value), 'isPrivate':is_private }) return synapseAnnos