Skip to content

Commit 852c095

Browse files
committed
Merge pull request #2 from codersquid/master
readme, install, and test improvements
2 parents c085fb3 + 027ff4d commit 852c095

6 files changed

Lines changed: 117 additions & 45 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
.vagrant
22
.DS_Store
33
*pyc
4+
venv
5+
.cache

dvn_client/src/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@
22
DEFAULT_PASSWORD = "FIXME"
33
DEFAULT_HOST = "dvn-4.hmdc.harvard.edu"
44
DEFAULT_CERT = "../resources/dvn-4.hmdc.harvard.edu"
5+
6+
try:
7+
from config_local import *
8+
except ImportError:
9+
pass

dvn_client/src/dvn_client.py

100644100755
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#!/usr/bin/env python
2+
13
# DVN client for SWORD API
24
# Prereqs: Python, sword2 Module (available using easy_install)
35
# Adapted from: https://bitbucket.org/beno/python-sword2/wiki/Quickstart
@@ -31,16 +33,19 @@ def parse_arguments():
3133
# parser.add_argument('-u','--username', default=None, help='Description for foo argument')
3234
# parser.add_argument('-p','--password', default=None, help='Description for bar argument')
3335

34-
parser.add_argument('--runTests', action="store", help='Path to a file with test definitions.')
35-
parser.add_argument('--config', action="store", help="Path to a file that contains configuration information.")
36+
parser.add_argument('--runTests', action="store", default='tests.py',
37+
help='Path to a file with test definitions. (default: tests.py)')
38+
parser.add_argument('--config', action="store", default='config.py',
39+
help="Path to a file that contains configuration information. (default: config.py)")
3640
return parser.parse_args()
3741

3842
def main():
3943
# Get the command line arguments.
4044
args = parse_arguments()
41-
42-
if args.runTests and args.config:
45+
46+
if args.config:
4347
execfile(args.config, globals())
48+
if args.runTests:
4449
execfile(args.runTests, globals())
4550

4651
dv = None #declare outside so except clause has access
@@ -63,7 +68,7 @@ def main():
6368
print "RELEASED: ", dv.is_released()
6469

6570
#s = Study.CreateStudyFromDict(PICS_OF_CATS_STUDY)
66-
s = Study.CreateStudyFromAtomEntryXmlFile("/home/vagrant/dvn_client/resources/atom-entry-study.xml")
71+
s = Study.CreateStudyFromAtomEntryXmlFile(ATOM_STUDY)
6772
dv.add_study(s)
6873
#s.add_files([INGEST_FILES])
6974
print s.get_citation()

dvn_client/src/dvn_test.py

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,44 @@
44
__author__="peterbull"
55
__date__ ="$Aug 21, 2013 2:56:25 PM$"
66

7-
from operator import eq
87
import os
98
import sys
109
from time import sleep
1110
import unittest
11+
import zipfile
1212

1313
import logging
1414
logging.basicConfig(level=logging.ERROR)
1515

1616
#local modules
17+
import config
18+
import tests as testdata
1719
from study import Study
1820
from connection import DvnConnection
19-
21+
22+
2023
class TestStudyOperations(unittest.TestCase):
24+
2125
@classmethod
2226
def setUpClass(self):
23-
# LOAD TEST DATA
24-
25-
print "Loading test data."
26-
testModulePath = os.path.dirname(__file__)
27-
execfile(os.path.join(testModulePath, "config.py"), globals()) #CREDS - This file is not committed.
28-
execfile(os.path.join(testModulePath, "tests.py"), globals()) #TEST DATA
29-
27+
28+
print "Verifying test data."
29+
assert zipfile.is_zipfile(testdata.INGEST_FILES), 'Invalid tests configuration. %s is not a zipfile' % testdata.INGEST_FILES
30+
assert os.path.isfile(testdata.PIC_OF_CAT), 'Invalid tests configuration. %s is not a file' % testdata.PIC_OF_CAT
31+
assert os.path.isfile(testdata.ATOM_STUDY), 'Invalid tests configuration. %s is not a file' % testdata.ATOM_STUDY
32+
3033
print "Connecting to DVN."
31-
self.dvc = DvnConnection(username=DEFAULT_USERNAME,
32-
password=DEFAULT_PASSWORD,
33-
host=DEFAULT_HOST,
34-
cert=DEFAULT_CERT)
35-
34+
self.dvc = DvnConnection(username=config.DEFAULT_USERNAME,
35+
password=config.DEFAULT_PASSWORD,
36+
host=config.DEFAULT_HOST,
37+
cert=config.DEFAULT_CERT)
38+
3639
print "Getting Dataverse"
3740
self.dv = self.dvc.get_dataverses()[0]
38-
39-
print "Removing any existing studies."
40-
self.dv.delete_all_studies(ignoreExceptions=True)
41-
41+
4242
def setUp(self):
43-
#runs before each test method
44-
4543
#create a study for each test
46-
s = Study.CreateStudyFromDict(PICS_OF_CATS_STUDY)
44+
s = Study.CreateStudyFromDict(testdata.PICS_OF_CATS_STUDY)
4745
self.dv.add_study(s)
4846
id = s.get_id()
4947
self.s = self.dv.get_study_by_hdl(id)
@@ -57,20 +55,20 @@ def tearDown(self):
5755
return
5856

5957
def test_create_study_from_xml(self):
60-
xmlStudy = Study.CreateStudyFromAtomEntryXmlFile(ATOM_STUDY)
58+
xmlStudy = Study.CreateStudyFromAtomEntryXmlFile(testdata.ATOM_STUDY)
6159
self.dv.add_study(xmlStudy)
6260
atomStudy = self.dv.get_study_by_string_in_entry("The first study for the New England Journal of Coffee dataverse")
6361
self.assertTrue(atomStudy)
6462
self.dv.delete_study(atomStudy)
6563

6664
def test_add_files_to_study(self):
67-
expected_files = ["char_r.tab",
68-
"float_new_r.tab",
69-
"int_r.tab",
70-
"min_date_r.tab"]
71-
self.s.add_files([INGEST_FILES])
65+
zipped_file = zipfile.ZipFile(testdata.INGEST_FILES, 'r')
66+
expected_files = [os.path.basename(f) for f in zipped_file.namelist()]
67+
self.s.add_files([testdata.INGEST_FILES])
7268
sleep(3) #wait for ingest
7369
actual_files = [f.name for f in self.s.get_files()]
70+
print 'actual', actual_files
71+
print 'expected', expected_files
7472

7573
expected_files.sort()
7674
actual_files.sort()
@@ -90,21 +88,22 @@ def test_display_study_statement(self):
9088
self.assertTrue(self.s.get_statement())
9189

9290
def test_delete_a_file(self):
93-
self.s.add_file(PIC_OF_CAT)
91+
self.s.add_file(testdata.PIC_OF_CAT)
92+
test_file = os.path.basename(testdata.PIC_OF_CAT)
9493

9594
#add file and confirm
9695
files = self.s.get_files()
97-
catFile = [f for f in files if f.name == "cat.jpg"]
96+
catFile = [f for f in files if f.name == test_file]
9897
self.assertTrue(len(catFile) == 1)
9998

10099
#delete file and confirm
101100
self.s.delete_file(catFile[0])
102101
files = self.s.get_files()
103-
catFile = [f for f in files if f.name == "cat.jpg"]
102+
catFile = [f for f in files if f.name == test_file]
104103
self.assertTrue(len(catFile) == 0)
105-
104+
106105
def test_delete_a_study(self):
107-
xmlStudy = Study.CreateStudyFromAtomEntryXmlFile(ATOM_STUDY)
106+
xmlStudy = Study.CreateStudyFromAtomEntryXmlFile(testdata.ATOM_STUDY)
108107
self.dv.add_study(xmlStudy)
109108
atomStudy = self.dv.get_study_by_string_in_entry("The first study for the New England Journal of Coffee dataverse")
110109
self.assertTrue(atomStudy)
@@ -113,19 +112,19 @@ def test_delete_a_study(self):
113112
self.assertTrue(startingNumberOfStudies > 0)
114113
self.dv.delete_study(atomStudy)
115114
self.assertEqual(len(self.dv.get_studies()), startingNumberOfStudies - 1)
116-
115+
117116
def test_release_study(self):
118117
self.assertTrue(self.s.get_state() == "DRAFT")
119118
self.s.release()
120119
self.assertTrue(self.s.get_state() == "RELEASED")
121120
self.dv.delete_study(self.s) #this should deaccession
122121
self.assertTrue(self.s.get_state() == "DEACCESSIONED")
123-
122+
124123
def test_dataverse_released(self):
125124
self.assertTrue(self.dv.is_released())
126-
125+
126+
127127
if __name__ == "__main__":
128128
__file__ = sys.argv[0]
129129
suite = unittest.TestLoader().loadTestsFromTestCase(TestStudyOperations)
130130
unittest.TextTestRunner(verbosity=2).run(suite)
131-

dvn_client/src/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-e git+https://github.com/pjbull/python-client-sword2.git#egg=sword2
2+
argparse # for python 2.6
3+
lxml

readme.md

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,65 @@
1-
This is a library for writing Python applications that make use of Dataverse Network (DVN) APIs.
1+
## Dataverse Network (DVN) API Client
22

3-
The code was originally written as a "proof of concept" at https://github.com/dvn/swordpoc/tree/master/dvn_client but the intention is to eventually publish the code on https://pypi.python.org so users can run `pip install dvn-client` to use the Python library.
3+
This is a library for writing Python applications that make use of Dataverse
4+
Network (DVN) APIs. The code started as a "proof of concept" in the
5+
[dvn/swordpoc](https://github.com/dvn/swordpoc) repo and the intent is to
6+
publish the python client on https://pypi.python.org.
47

5-
For now https://github.com/dvn/swordpoc/blob/master/dvn_client/README.md has some tips but they should be incorporated into this repo.
8+
The proof of concept
9+
[README.md](https://github.com/dvn/swordpoc/blob/master/dvn_client/README.md)
10+
has some tips that have not been incorporated in to this readme yet.
11+
12+
We have been trying to target Python 2.6 because that's the version that ships
13+
with the latest version (6) of Red Hat Enterprise Linux (RHEL) and CentOS. For
14+
testing backward compatibility with Python 2.6, this repo includes a Vagrant
15+
environment. Please note that before you run `vagrant up` you'll need to run
16+
`git submodule init` and `git submodule update` once after cloning this repo.
17+
18+
## Installation
19+
20+
You will need:
21+
22+
* Python 2.6+
23+
* [pip](http://www.pip-installer.org/en/latest/)
24+
* gcc compiler (For OSX you will need xcode + command line tools, or [standalone install](https://github.com/kennethreitz/osx-gcc-installer#readme))
25+
* Dataverse account
26+
27+
Once you have satisfied the above requirements, try the following commands.
28+
29+
$ git clone https://github.com/IQSS/dvn-client-python.git
30+
$ cd dvn-client-python
31+
$ virtualenv venv
32+
$ source venv/bin/activate
33+
$ pip install -r dvn_client/src/requirements.txt
34+
35+
You may wish to manage virtualenvs using [virtualenvwrapper](http://virtualenvwrapper.readthedocs.org/en/latest/) instead.
36+
37+
## Configuration
38+
39+
Make a `config_local.py` file and fill out the config elements as appropriate. Do not commit this file.
40+
41+
```python
42+
DEFAULT_USERNAME = ""
43+
DEFAULT_PASSWORD = ""
44+
DEFAULT_HOST = "dvn-4.hmdc.harvard.ed"
45+
DEFAULT_CERT = "../resources/dvn-4.hmdc.harvard.edu" #see below for info on the cert
46+
```
47+
48+
## Installation Test
49+
50+
* Navigate to `dvn-client-python/dvn-client/src/`
51+
* Edit test data in `tests.py` as appropriate
52+
* Run the client `python dvn_client.py`
53+
* To run all of the tests, run `python dvn_test.py` (for more options see [unittest](http://docs.python.org/2/library/unittest.html#assert-methods))
54+
55+
## PEM Certificate (optional)
56+
57+
If you are using a self-signed certificate, you may see an SSL error when you
58+
try to hit the server. In that case, follow these instructions.
59+
60+
1. Open private/incognito window (in case you have already added a security exception) in FireFox (instructions will be slightly different for other browsers)
61+
2. Go to: https://{SERVER}/dvn/api/data-deposit/swordv2/service-document
62+
3. Add Exception > View > Details > Export
63+
4. Save the PEM to the “resources” folder of the dvn\_client project
64+
5. When calling `Dataverse.connect()` or `Dataverse()` constructor, pass a path to this file as `cert=[PATH_TO_CERTIFICATE]`
665

7-
We have been trying to target Python 2.6 because that's the version that ships with the latest version (6) of Red Hat Enterprise Linux (RHEL) and CentOS. For testing backward compatibility with Python 2.6, this repo includes a Vagrant environment. Please note that before you run `vagrant up` you'll need to run `git submodule init` and `git submodule update` once after cloning this repo.

0 commit comments

Comments
 (0)