Skip to content

Commit

Permalink
Add redcap_version attribute to Project
Browse files Browse the repository at this point in the history
On Project initialization PyCap will attempt to determine the REDCap version that the project is associated with. If it cannot it will warn the user that version information is unavailable. This implements [python-semanticversion](https://github.com/rbarrois/python-semanticversion) which allows for easy version comparison and assumes that REDCap will stick with its versioning conventions to date. If for whatever reason they differ, PyCap will simply return the string representation of the version from REDCap's API. Fixes #43.
  • Loading branch information
Tyler Rivera committed Feb 11, 2015
1 parent d22fa01 commit b0d8a09
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 3 deletions.
18 changes: 17 additions & 1 deletion redcap/project.py
Expand Up @@ -6,9 +6,10 @@
__copyright__ = '2014, Vanderbilt University'

import json
import warnings

from .request import RCRequest, RedcapError, RequestException

import semantic_version

class Project(object):
"""Main class for interacting with REDCap projects"""
Expand All @@ -35,6 +36,10 @@ def __init__(self, url, token, name='', verify_ssl=True):
self.metadata = self.__md()
except RequestException:
raise RedcapError("Exporting metadata failed. Check your URL and token.")
try:
self.redcap_version = self.__rcv()
except:
raise RedcapError("Determination of REDCap version failed")
self.field_names = self.filter_metadata('field_name')
# we'll use the first field as the default id for each row
self.def_field = self.field_names[0]
Expand Down Expand Up @@ -69,6 +74,17 @@ def __basepl(self, content, rec_type='flat', format='json'):
d['type'] = rec_type
return d

def __rcv(self):
p_l = self.__basepl('version')
rcv = self._call_api(p_l, 'version')[0]
if 'error' in rcv:
warnings.warn('Version information not available for this REDCap instance')
return ''
if semantic_version.validate(rcv):
return semantic_version.Version(rcv)
else:
return rcv

def is_longitudinal(self):
"""
Returns
Expand Down
6 changes: 5 additions & 1 deletion redcap/request.py
Expand Up @@ -84,7 +84,9 @@ def validate(self):
'exp_fem': (['format'], 'formEventMapping',
'Exporting form-event mappings but content != formEventMapping'),
'exp_user': (['format'], 'user',
'Exporting users but content is not user')
'Exporting users but content is not user'),
'version': (['format'], 'version',
'Requesting version but content != version')
}
extra, req_content, err_msg = valid_data[self.type]
required.extend(extra)
Expand Down Expand Up @@ -127,6 +129,8 @@ def get_content(self, r):
if self.type == 'exp_file':
# don't use the decoded r.text
return r.content
elif self.type == 'version':
return r.content
else:
if self.fmt == 'json':
content = {}
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
@@ -1,5 +1,6 @@
Sphinx==1.2.1
nose==1.2.1
numpydoc==0.4
semantic-version==2.3.1
requests>=1.1.0
wheel==0.22.0
5 changes: 4 additions & 1 deletion setup.py
Expand Up @@ -20,7 +20,10 @@ def get_version():
exec(f.read())
return VERSION

required = ['requests>=1.0.0']
required = [
'requests>=1.0.0',
'semantic-version==2.3.1'
]

if __name__ == '__main__':
if os.path.exists('MANIFEST'):
Expand Down
5 changes: 5 additions & 0 deletions test/test_project.py
Expand Up @@ -2,6 +2,7 @@

import unittest
from redcap import Project, RedcapError
import semantic_version

skip_pd = False
try:
Expand Down Expand Up @@ -292,3 +293,7 @@ def import_factory(date_string):
import_mdy = import_factory('12/31/2000')
response = self.reg_proj.import_records(import_mdy, date_format='MDY')
self.assertEqual(response['count'], 1)

def test_get_version(self):
"""Testing retrieval of REDCap version associated with Project"""
self.assertTrue(isinstance(semantic_version.Version('1.0.0'), type(self.long_proj.redcap_version)))

0 comments on commit b0d8a09

Please sign in to comment.