Skip to content

Commit

Permalink
Make CIViCpy Python >=3.5 compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
susannasiebert committed May 28, 2020
1 parent d12c2c3 commit 6a71d6d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 31 deletions.
6 changes: 3 additions & 3 deletions civicpy/__version__.py
Expand Up @@ -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'
Expand Down
39 changes: 21 additions & 18 deletions civicpy/civic.py
@@ -1,7 +1,6 @@
import requests
import importlib
import logging
import datetime
import pandas as pd
import pickle
import os
Expand All @@ -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()
Expand All @@ -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')

Expand All @@ -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
Expand All @@ -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'
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -358,15 +361,15 @@ def __dir__(self):
return [attribute for attribute in super().__dir__() if not attribute.startswith('_')]

def __repr__(self):
return f'<CIViC {self.type} {self.id}>'
return '<CIViC {} {}>'.format(self.type, self.id)

def __getattr__(self, item):
if self._partial and item in self._incomplete:
self.update()
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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -862,9 +865,9 @@ def __repr__(self):
try:
_id = self.id
except AttributeError:
return f'<CIViC Attribute {self.type}>'
return '<CIViC Attribute {}>'.format(self.type)
else:
return f'<CIViC Attribute {self.type} {self.id}>'
return '<CIViC Attribute {} {}>'.format(self.type, self.id)

def __init__(self, **kwargs):
kwargs['partial'] = False
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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


Expand All @@ -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.')
Expand Down Expand Up @@ -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']]
Expand Down
2 changes: 1 addition & 1 deletion civicpy/cli.py
Expand Up @@ -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"""
Expand Down
14 changes: 7 additions & 7 deletions civicpy/exports.py
Expand Up @@ -204,21 +204,21 @@ 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)
rows.append(out_dict)
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
Expand All @@ -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)
5 changes: 3 additions & 2 deletions setup.py
Expand Up @@ -25,7 +25,8 @@
'pandas',
'Click',
'vcfpy',
'pysam'
'pysam',
'backports-datetime-fromisoformat',
],
extras_require={
'test': [
Expand All @@ -40,7 +41,7 @@
'sphinxcontrib.programoutput'
]
},
python_requires='>=3.7',
python_requires='>=3.5',
entry_points={
'console_scripts': [
'civicpy=civicpy.cli:cli'
Expand Down

0 comments on commit 6a71d6d

Please sign in to comment.