diff --git a/civicpy/__version__.py b/civicpy/__version__.py index 4a147bc..9b1e505 100644 --- a/civicpy/__version__.py +++ b/civicpy/__version__.py @@ -5,10 +5,10 @@ __minor__ = '0' __patch__ = '1' __meta_label__ = '' -__short_version__ = f"{__major__}.{__minor__}" -__version__ = f"{__short_version__}.{__patch__}" +__short_version__ = "{}.{}".format(__major__, __minor__) +__version__ = "{}.{}".format(__short_version__, __patch__) if __meta_label__: - __version__ += f"-{__meta_label__}" + __version__ += "-{}".format(__meta_label__) __authors__ = ['Alex H. Wagner', 'Susanna Kiwala'] __author_email__ = 'help@civicpy.org' __license__ = 'MIT' diff --git a/civicpy/civic.py b/civicpy/civic.py index 62a5520..51b0ad8 100644 --- a/civicpy/civic.py +++ b/civicpy/civic.py @@ -1,7 +1,6 @@ import requests import importlib import logging -import datetime import pandas as pd import pickle import os @@ -10,6 +9,9 @@ from civicpy import REMOTE_CACHE_URL, LOCAL_CACHE_PATH, CACHE_TIMEOUT_DAYS import requests from civicpy.exports import VCFWriter +from datetime import datetime, timedelta +from backports.datetime_fromisoformat import MonkeyPatch +MonkeyPatch.patch_fromisoformat() CACHE = dict() @@ -21,7 +23,7 @@ HPO_TERMS = dict() -FRESH_DELTA = datetime.timedelta(days=CACHE_TIMEOUT_DAYS) +FRESH_DELTA = timedelta(days=CACHE_TIMEOUT_DAYS) MODULE = importlib.import_module('civicpy.civic') @@ -36,7 +38,8 @@ } -_CoordinateQuery = namedtuple('CoordinateQuery', ['chr', 'start', 'stop', 'alt', 'ref', 'build', 'key'], defaults=(None, None, "GRCh37", None)) +_CoordinateQuery = namedtuple('CoordinateQuery', ['chr', 'start', 'stop', 'alt', 'ref', 'build', 'key']) +_CoordinateQuery.__new__.__defaults__ = (None, None, "GRCh37", None) class CoordinateQuery(_CoordinateQuery): # Wrapping for documentation @@ -57,7 +60,7 @@ class CoordinateQuery(_CoordinateQuery): # Wrapping for documentation def pluralize(string): if string in UNMARKED_PLURALS: - return f'{string}_items' + return '{}_items'.format(string) if string.endswith('s'): return string return string + 's' @@ -269,7 +272,7 @@ def update_cache(from_remote_cache=True, remote_cache_url=REMOTE_CACHE_URL, v.update() _get_elements_by_ids('assertion', allow_cached=False, get_all=True) _get_elements_by_ids('variant_group', allow_cached=False, get_all=True) - CACHE['full_cached'] = datetime.datetime.now() + CACHE['full_cached'] = datetime.now() _build_coordinate_table(variants) save_cache(local_cache_path=local_cache_path) @@ -316,7 +319,7 @@ def __init__(self, partial=False, **kwargs): if (partial and field not in CivicRecord._SIMPLE_FIELDS) or field in self._OPTIONAL_FIELDS: self._incomplete.add(field) # Allow for incomplete data when partial flag set else: - raise AttributeError(f'Expected {field} attribute for {self.type}, none found.') + raise AttributeError('Expected {} attribute for {}, none found.'.format(field, self.type)) for field in self._COMPLEX_FIELDS: try: @@ -328,7 +331,7 @@ def __init__(self, partial=False, **kwargs): self._incomplete.add(field) continue else: - raise AttributeError(f'Expected {field} attribute for {self.type}, none found.') + raise AttributeError('Expected {} attribute for {}, none found.'.format(field, self.type)) is_compound = isinstance(v, list) cls = get_class(field) if is_compound: @@ -358,7 +361,7 @@ def __dir__(self): return [attribute for attribute in super().__dir__() if not attribute.startswith('_')] def __repr__(self): - return f'' + return ''.format(self.type, self.id) def __getattr__(self, item): if self._partial and item in self._incomplete: @@ -366,7 +369,7 @@ def __getattr__(self, item): return object.__getattribute__(self, item) def __hash__(self): - return hash(f'{self.type}:{self.id}') + return hash('{}:{}'.format(self.type, self.id)) def __eq__(self, other): return hash(self) == hash(other) @@ -394,7 +397,7 @@ def update(self, allow_partial=True, force=False, **kwargs): v = getattr(cached, field) setattr(self, field, v) self._partial = False - logging.info(f'Loading {str(self)} from cache') + logging.info('Loading {} from cache'.format(str(self))) return True resp_dict = element_lookup_by_id(self.type, self.id) self.__init__(partial=False, **resp_dict) @@ -833,7 +836,7 @@ def __init__(self, **kwargs): @property def created_at(self): assert self._created_at[-1] == 'Z' - return datetime.datetime.fromisoformat(self._created_at[:-1]) + return datetime.fromisoformat(self._created_at[:-1]) @created_at.setter def created_at(self, value): @@ -862,9 +865,9 @@ def __repr__(self): try: _id = self.id except AttributeError: - return f'' + return ''.format(self.type) else: - return f'' + return ''.format(self.type, self.id) def __init__(self, **kwargs): kwargs['partial'] = False @@ -927,7 +930,7 @@ def __init__(self, **kwargs): @property def timestamp(self): assert self._timestamp[-1] == 'Z' - return datetime.datetime.fromisoformat(self._timestamp[:-1]) + return datetime.fromisoformat(self._timestamp[:-1]) @timestamp.setter def timestamp(self, value): @@ -959,7 +962,7 @@ def get_cached(element_type, element_id): def _has_full_cached_fresh(delta=FRESH_DELTA): s = 'full_cached' if CACHE.get(s, False): - return CACHE[s] + delta > datetime.datetime.now() + return CACHE[s] + delta > datetime.now() return False @@ -970,11 +973,11 @@ def _get_elements_by_ids(element, id_list=[], allow_cached=True, get_all=False): if not get_all: cached = [get_cached(element, element_id) for element_id in id_list] if all(cached): - logging.info(f'Loading {pluralize(element)} from cache') + logging.info('Loading {} from cache'.format(pluralize(element))) return cached else: cached = [get_cached(element, element_id) for element_id in CACHE['{}_all_ids'.format(pluralize(element))]] - logging.info(f'Loading {pluralize(element)} from cache') + logging.info('Loading {} from cache'.format(pluralize(element))) return cached if id_list and get_all: raise ValueError('Please pass list of ids or use the get_all flag, not both.') @@ -1411,7 +1414,7 @@ def get_all_variant_ids(): def _get_all_element_ids(element): - url = f'https://civicdb.org/api/{element}?count=100000' + url = 'https://civicdb.org/api/{}?count=100000'.format(element) resp = requests.get(url) resp.raise_for_status() return [x['id'] for x in resp.json()['records']] diff --git a/civicpy/cli.py b/civicpy/cli.py index ac81560..2430710 100644 --- a/civicpy/cli.py +++ b/civicpy/cli.py @@ -20,7 +20,7 @@ def cli(): help='Hard-update from live API (slow) or \ soft-update from daily precache (fast; default)') @click.option('--cache-save-path', - help=f'Filepath to save cache to. Default: {LOCAL_CACHE_PATH}', + help='Filepath to save cache to. Default: {}'.format(LOCAL_CACHE_PATH), default=LOCAL_CACHE_PATH) def update(soft, cache_save_path): """Updates CIViC content from server and stores to local cache file""" diff --git a/civicpy/exports.py b/civicpy/exports.py index 1dc5ecf..5fc33a9 100644 --- a/civicpy/exports.py +++ b/civicpy/exports.py @@ -204,7 +204,7 @@ def writerecords(self, with_header=True): assert ';' not in v assert '=' not in v if v: - out.append(f'{field}={v}') + out.append('{}={}'.format(field, v)) out_dict['INFO'] = ';'.join(out) super().writerow(out_dict) @@ -212,13 +212,13 @@ def writerecords(self, with_header=True): return rows def _write_meta_file_lines(self): - self._f.write(f'##fileformat=VCFv{self.version}\n') + self._f.write('##fileformat=VCFv{}\n'.format(self.version)) self._f.write('##fileDate={}\n'.format( datetime.date.today().strftime('%Y%m%d') )) self._f.write('##reference=ftp://ftp.ncbi.nih.gov/genbank/genomes/Eukaryotes/vertebrates_mammals/Homo_sapiens/GRCh37/special_requests/GRCh37-lite.fa.gz\n') - self._f.write(f'##source=CIViCpy_v{__version__}\n') - self._f.write(f'##aboutURL=https://civicdb.org/help/evidence/overview\n') + self._f.write('##source=CIViCpy_v{}\n'.format(__version__)) + self._f.write('##aboutURL=https://civicdb.org/help/evidence/overview\n') def _write_meta_info_lines(self): # Gene @@ -232,10 +232,10 @@ def _write_meta_info_line(self, id_, number, type_, description, **kwargs): assert id_ not in self.meta_info_fields assert id_ not in self.VCF_RESERVED_FIELDS self.meta_info_fields.append(id_) - s = [f'ID={id_},Number={number},Type={type_},Description="{description}"'] - s.extend([f'{k}={v}' for k, v in kwargs]) + s = ['ID={},Number={},Type={},Description="{}"'.format(id_, number, type_, description)] + s.extend(['{}={}'.format(k, v) for k, v in kwargs]) out = ','.join(s) - self._f.write(f'##INFO=<{out}>\n') + self._f.write('##INFO=<{}>\n'.format(out)) def _add_variant_record(self, variant_record): self.variant_records.add(variant_record) diff --git a/setup.py b/setup.py index c6e2127..89ad238 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,8 @@ 'pandas', 'Click', 'vcfpy', - 'pysam' + 'pysam', + 'backports-datetime-fromisoformat', ], extras_require={ 'test': [ @@ -40,7 +41,7 @@ 'sphinxcontrib.programoutput' ] }, - python_requires='>=3.7', + python_requires='>=3.5', entry_points={ 'console_scripts': [ 'civicpy=civicpy.cli:cli'