Coverage for application / util / functions.py: 97%
31 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-23 05:22 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-23 05:22 +0000
1import re
2from datetime import datetime, timedelta
5def parse_datetime(timestamp: str) -> datetime:
6 """
7 Returns a datetime object given a timestamp string.
9 :param str timestamp: The timestamp to parse.
10 :return datetime: The timestamp parsed as a datetime object.
11 """
12 if '.' in timestamp:
13 return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%fZ')
14 return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ')
17def extract_recorded_datetime(json_object: dict) -> datetime | None:
18 """
19 Returns a datetime object of the recorded timestamp given a JSON annotation record.
21 :param Dict json_object: An annotation record.
22 :return datetime: A datetime object of the timestamp from the json object.
23 """
24 if not json_object:
25 return None
26 if '.' in json_object['recorded_timestamp']:
27 timestamp = datetime.strptime(json_object['recorded_timestamp'], '%Y-%m-%dT%H:%M:%S.%fZ')
28 if timestamp.microsecond >= 500000:
29 return timestamp.replace(microsecond=0) + timedelta(seconds=1)
30 return timestamp.replace(microsecond=0)
31 return datetime.strptime(json_object['recorded_timestamp'], '%Y-%m-%dT%H:%M:%SZ')
34def get_association(annotation: dict, link_name: str) -> dict:
35 """
36 Obtains an association value from the annotation data structure.
38 :param Dict annotation: The complete annotation dictionary.
39 :param str link_name: The specific key we want to get the value for.
40 :return dict: The matching value dict.
41 """
42 if 'associations' not in annotation.keys():
43 return {}
44 for association in annotation['associations']:
45 if association['link_name'] == link_name:
46 return association
47 return {}
50def format_annotator(annotator: str) -> str:
51 """
52 Format VARS annotator name. Most are formatted as "FirstnameLastname", with some exceptions.
54 :param str annotator: VARS username to format
55 :return str: Formatted name
56 """
57 if annotator == 'hcarlson':
58 return 'Harold Carlson'
59 else:
60 return re.sub('([a-zA-Z]+)([A-Z])', r'\1 \2', annotator)
63def flatten_taxa_tree(tree: dict, flat: dict):
64 """
65 Recursive function taking a taxonomy tree returned from WoRMS API and flattening it into a single dictionary.
67 :param Dict tree: The nested taxon tree from WoRMS.
68 :param Dict flat: The newly created flat taxon tree.
69 """
70 flat[tree['rank'].lower()] = tree['scientificname']
71 if tree['child'] is not None:
72 flatten_taxa_tree(tree['child'], flat)
73 return flat