Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
pkdash committed Jan 20, 2017
2 parents b560fad + bf5d309 commit 4ab9cf8
Show file tree
Hide file tree
Showing 25 changed files with 580 additions and 43 deletions.
8 changes: 8 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 1.2.6 - 1/20/2017
- Add getScienceMetadataRDF (/hsapi/scimeta/\<pid\>/)
- Add getScienceMetadata (/hsapi/resource/\<pid\>/scimeta/elements)
- Add updateScienceMetadata (/hsapi/resource/\<pid\>/scimeta/elements)
- Add getResourceFolderContents (/hsapi/resource/\<pid\>/folders/\<path\>)
- Add createResourceFolder (/hsapi/resource/\<pid\>/folders/\<path\>)
- Add deleteResourceFolder (/hsapi/resource/\<pid\>/folders/\<path\>)

# 1.2.5 - 12/7/2016
- Add ability to supply key/value metadata (in addition to 'title', 'abstract', 'keywords', and 'metadata')
to createResource()
Expand Down
52 changes: 50 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,60 @@ To get resource map xml data for a resource:
>>> hs = HydroShare(auth=auth)
>>> resource_map_xml = hs.getResourceMap('ID OF RESOURCE GOES HERE')

To get science xml data for a resource:
To get the contents of a specific folder of a resource:

>>> from hs_restclient import HydroShare, HydroShareAuthBasic
>>> auth = HydroShareAuthBasic(username='myusername', password='mypassword')
>>> hs = HydroShare(auth=auth)
>>> science_metadata_xml = hs.getScienceMetadata('ID OF RESOURCE GOES HERE')
>>> folder_name = 'some_folder'
>>> folder_contents_json = hs.getResourceFolderContents('ID OF RESOURCE GOES HERE', pathname=folder_name)

To create a folder for a resource:

>>> from hs_restclient import HydroShare, HydroShareAuthBasic
>>> auth = HydroShareAuthBasic(username='myusername', password='mypassword')
>>> hs = HydroShare(auth=auth)
>>> folder_to_create = "folder_1/folder_2"
>>> response_json = hs.createResourceFolder('ID OF RESOURCE GOES HERE', pathname=folder_to_create)

To delete a folder for a resource:

>>> from hs_restclient import HydroShare, HydroShareAuthBasic
>>> auth = HydroShareAuthBasic(username='myusername', password='mypassword')
>>> hs = HydroShare(auth=auth)
>>> folder_to_delete = "folder_1/folder_2"
>>> response_json = hs.deleteResourceFolder('ID OF RESOURCE GOES HERE', pathname=folder_to_delete)

To get science metadata as xml+rdf data for a resource:

>>> from hs_restclient import HydroShare, HydroShareAuthBasic
>>> auth = HydroShareAuthBasic(username='myusername', password='mypassword')
>>> hs = HydroShare(auth=auth)
>>> science_metadata_xml = hs.getScienceMetadataRDF('ID OF RESOURCE GOES HERE')

To get science metadata as json data (Dublin core metadata only) for a resource:

>>> from hs_restclient import HydroShare, HydroShareAuthBasic
>>> auth = HydroShareAuthBasic(username='myusername', password='mypassword')
>>> hs = HydroShare(auth=auth)
>>> science_metadata_json = hs.getScienceMetadata('ID OF RESOURCE GOES HERE')

To update science metadata (Dublin core metadata only) for a resource:

>>> from hs_restclient import HydroShare, HydroShareAuthBasic
>>> auth = HydroShareAuthBasic(username='myusername', password='mypassword')
>>> hs = HydroShare(auth=auth)
>>> metadata = {
"title": "A new title for my resource",
"coverages": [
{"type": "period", "value": {"start": "01/01/2000", "end": "12/12/2010"}}
],
"creators": [
{"name": "John Smith", "organization": "USU"},
{"name": "Lisa Miller", "email": "lisa_miller@gmail.com"}
]
}
>>> science_metadata_json = hs.updateScienceMetadata('ID OF RESOURCE GOES HERE', metadata=metadata)

Index
-----
Expand Down
313 changes: 287 additions & 26 deletions hs_restclient/__init__.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version='1.2.5',
version='1.2.6',

description='HydroShare REST API client library',
long_description=long_description,
Expand Down
77 changes: 71 additions & 6 deletions tests/mocks/hydroshare.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
GET = 'get'
POST = 'post'
PUT = 'put'
DELETE = 'delete'


class Resource:
Expand Down Expand Up @@ -115,13 +116,13 @@ def createResourceCRUD(url, request):
# This gets tricky. HydroShare.createResource() can implicitly
# call HydroShare.getResourceTypes(), so we need to handle those requests too
if request.method == 'GET':
if url.path == '/hsapi/resourceTypes/':
if url.path == '/hsapi/resource/types':
file_path = url.netloc + url.path
# Remove trailing slash so that we can open the file
file_path = file_path.strip('/')
response_status = 200
if url.path == '/hsapi/sysmeta/511debf8858a4ea081f78d66870da76c/':
file_path = url.netloc + url.path
if url.path == '/hsapi/resource/511debf8858a4ea081f78d66870da76c/sysmeta/':
file_path = url.netloc + url.path + '511debf8858a4ea081f78d66870da76c'
# Remove trailing slash so that we can open the file
file_path = file_path.strip('/')
response_status = 200
Expand Down Expand Up @@ -181,8 +182,8 @@ def accessRules_put(url, request):
else:
file_path = ''
elif request.method == 'GET':
if url.path == '/hsapi/sysmeta/511debf8858a4ea081f78d66870da76c/':
file_path = url.netloc + url.path
if url.path == '/hsapi/resource/511debf8858a4ea081f78d66870da76c/sysmeta/':
file_path = url.netloc + url.path + '511debf8858a4ea081f78d66870da76c'
# Remove trailing slash so that we can open the file
file_path = file_path.strip('/') + '-public'
else:
Expand All @@ -207,8 +208,9 @@ def userInfo_get(url, request):
return response(404, {}, HEADERS, None, 5, request)
return response(200, content, HEADERS, None, 5, request)


@urlmatch(netloc=NETLOC, method=GET)
def scimeta_get(url, request):
def scimeta_xml_get(url, request):
file_path = url.netloc + url.path + 'scimeta.xml'

try:
Expand All @@ -219,6 +221,33 @@ def scimeta_get(url, request):
return response(404, {}, HEADERS, None, 5, request)
return response(200, content, HEADERS, None, 5, request)


@urlmatch(netloc=NETLOC, method=GET)
def scimeta_json_get(url, request):
file_path = url.netloc + url.path + '/scimeta-get-response'

try:
content = Resource(file_path).get()
except EnvironmentError:
# catch any environment errors (i.e. file does not exist) and return a
# 404.
return response(404, {}, HEADERS, None, 5, request)
return response(200, content, HEADERS, None, 5, request)


@urlmatch(netloc=NETLOC, method=PUT)
def scimeta_json_put(url, request):
file_path = url.netloc + url.path + '/scimeta-update-response'

try:
content = Resource(file_path).get()
except EnvironmentError:
# catch any environment errors (i.e. file does not exist) and return a
# 404.
return response(404, {}, HEADERS, None, 5, request)
return response(202, content, HEADERS, None, 5, request)


@urlmatch(netloc=NETLOC, method=GET)
def resourcemap_get(url, request):
file_path = url.netloc + url.path + 'resourcemap.xml'
Expand Down Expand Up @@ -246,3 +275,39 @@ def resourceFileList_get(url, request):
# 404.
return response(404, {}, HEADERS, None, 5, request)
return response(200, content, HEADERS, None, 5, request)


@urlmatch(netloc=NETLOC, method=GET)
def resourceFolderContents_get(url, request):
file_path = url.netloc + url.path + 'folder-content-response'
try:
content = Resource(file_path).get()
except EnvironmentError:
# catch any environment errors (i.e. file does not exist) and return a
# 404.
return response(404, {}, HEADERS, None, 5, request)
return response(200, content, HEADERS, None, 5, request)


@urlmatch(netloc=NETLOC, method=PUT)
def resourceFolderCreate_put(url, request):
file_path = url.netloc + url.path + 'create-folder-response'
try:
content = Resource(file_path).get()
except EnvironmentError:
# catch any environment errors (i.e. file does not exist) and return a
# 404.
return response(404, {}, HEADERS, None, 5, request)
return response(201, content, HEADERS, None, 5, request)


@urlmatch(netloc=NETLOC, method=DELETE)
def resourceFolderDelete_delete(url, request):
file_path = url.netloc + url.path + 'delete-folder-response'
try:
content = Resource(file_path).get()
except EnvironmentError:
# catch any environment errors (i.e. file does not exist) and return a
# 404.
return response(404, {}, HEADERS, None, 5, request)
return response(200, content, HEADERS, None, 5, request)
82 changes: 78 additions & 4 deletions tests/test_hs_restclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,60 @@ def test_get_user_info(self):
self.assertEqual(user_info['email'], 'user@domain.com')


class TestGetScimeta(unittest.TestCase):
class TestScimeta(unittest.TestCase):

@with_httmock(mocks.hydroshare.scimeta_get)
def test_get_scimeta(self):
@with_httmock(mocks.hydroshare.scimeta_xml_get)
def test_get_scimeta_xml(self):
hs = HydroShare()
scimeta = hs.getScienceMetadata('6dbb0dfb8f3a498881e4de428cb1587c')
scimeta = hs.getScienceMetadataRDF('6dbb0dfb8f3a498881e4de428cb1587c')
self.assertTrue(scimeta.find("""<rdf:Description rdf:about="http://www.hydroshare.org/resource/6dbb0dfb8f3a498881e4de428cb1587c">""") != -1)

@with_httmock(mocks.hydroshare.scimeta_json_get)
def test_get_scimeta_json(self):
hs = HydroShare()
scimeta = hs.getScienceMetadata('511debf8858a4ea081f78d66870da76c')

self.assertEqual(scimeta['title'], 'Great Salt Lake Level and Volume')
self.assertEqual(len(scimeta['creators']), 2)
self.assertEqual(len(scimeta['contributors']), 1)
self.assertEqual(len(scimeta['coverages']), 1)
self.assertEqual(len(scimeta['dates']), 2)
self.assertEqual(scimeta['description'], 'Time series of level, area and volume in the Great Salt Lake. Volume and area of the Great Salt Lake are derived from recorded levels')
self.assertEqual(scimeta['formats'][0]['value'], 'image/tiff')
self.assertEqual(len(scimeta['funding_agencies']), 1)
self.assertEqual(len(scimeta['identifiers']), 1)
self.assertEqual(scimeta['language'], 'eng')
self.assertEqual(scimeta['rights'], 'This resource is shared under the Creative Commons Attribution CC BY. http://creativecommons.org/licenses/by/4.0/')
self.assertEqual(scimeta['type'], 'http://www.hydroshare.org/terms/GenericResource')
self.assertEqual(scimeta['publisher'], None)
self.assertEqual(len(scimeta['sources']), 0)
self.assertEqual(len(scimeta['relations']), 0)
self.assertEqual(len(scimeta['subjects']), 2)

@with_httmock(mocks.hydroshare.scimeta_json_put)
def test_update_scimeta(self):
hs = HydroShare()
metadata_to_update = {'title': 'Updated resource title'}
scimeta = hs.updateScienceMetadata('511debf8858a4ea081f78d66870da76c', metadata=metadata_to_update)

self.assertEqual(scimeta['title'], 'Updated resource title')
self.assertEqual(len(scimeta['creators']), 2)
self.assertEqual(len(scimeta['contributors']), 1)
self.assertEqual(len(scimeta['coverages']), 1)
self.assertEqual(len(scimeta['dates']), 2)
self.assertEqual(scimeta['description'],
'Time series of level, area and volume in the Great Salt Lake. Volume and area of the Great Salt Lake are derived from recorded levels')
self.assertEqual(scimeta['formats'][0]['value'], 'image/tiff')
self.assertEqual(len(scimeta['funding_agencies']), 1)
self.assertEqual(len(scimeta['identifiers']), 1)
self.assertEqual(scimeta['language'], 'eng')
self.assertEqual(scimeta['rights'],
'This resource is shared under the Creative Commons Attribution CC BY. http://creativecommons.org/licenses/by/4.0/')
self.assertEqual(scimeta['type'], 'http://www.hydroshare.org/terms/GenericResource')
self.assertEqual(scimeta['publisher'], None)
self.assertEqual(len(scimeta['sources']), 0)
self.assertEqual(len(scimeta['relations']), 0)
self.assertEqual(len(scimeta['subjects']), 2)

class TestGetResourceMap(unittest.TestCase):

Expand Down Expand Up @@ -240,5 +286,33 @@ def test_get_resource_file_list(self):
self.assertEqual(r['content_type'], self.content_types[i])


class TestResourceFolderCRUD(unittest.TestCase):

@with_httmock(mocks.hydroshare.resourceFolderContents_get)
def test_get_folder_contents(self):
hs = HydroShare()
folder_contents = hs.getResourceFolderContents('511debf8858a4ea081f78d66870da76c', pathname='model/initial/')

self.assertEqual(folder_contents['resource_id'], '511debf8858a4ea081f78d66870da76c')
self.assertEqual(folder_contents['path'], 'model/initial')
self.assertEqual(folder_contents['files'], ["model.exe", "param.txt"])
self.assertEqual(folder_contents['folders'], ["run/1", "run/2"])

@with_httmock(mocks.hydroshare.resourceFolderCreate_put)
def test_folder_create(self):
hs = HydroShare()
response = hs.createResourceFolder('511debf8858a4ea081f78d66870da76c', pathname='model/initial/')

self.assertEqual(response['resource_id'], '511debf8858a4ea081f78d66870da76c')
self.assertEqual(response['path'], 'model/initial')

@with_httmock(mocks.hydroshare.resourceFolderDelete_delete)
def test_folder_delete(self):
hs = HydroShare()
response = hs.deleteResourceFolder('511debf8858a4ea081f78d66870da76c', pathname='model/initial/')

self.assertEqual(response['resource_id'], '511debf8858a4ea081f78d66870da76c')
self.assertEqual(response['path'], 'model/initial')

if __name__ == '__main__':
unittest.main()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"count": 5,
"next": "http://www.hydroshare.org/hsapi/resource/511debf8858a4ea081f78d66870da76c/file_list/?page=2",
"next": "http://www.hydroshare.org/hsapi/resource/511debf8858a4ea081f78d66870da76c/files/?page=2",
"previous": null,
"results": [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"count": 5,
"next": null,
"previous": "http://www.hydroshare.org/hsapi/resource/511debf8858a4ea081f78d66870da76c/file_list/?page=1",
"previous": "http://www.hydroshare.org/hsapi/resource/511debf8858a4ea081f78d66870da76c/files/?page=1",
"results": [
{
"url": "http://www.hydroshare.org/django_irods/download/511debf8858a4ea081f78d66870da76c/data/contents/data.sqlite",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"resource_id": "511debf8858a4ea081f78d66870da76c", "path": "model/initial"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"resource_id": "511debf8858a4ea081f78d66870da76c", "path": "model/initial"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"resource_id": "511debf8858a4ea081f78d66870da76c",
"path": "model/initial",
"files": ["model.exe", "param.txt"],
"folders": ["run/1", "run/2"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"title":"Great Salt Lake Level and Volume",
"creators":[
{"name":"John Smith","description":"/user/24/","organization":"USU","email":"john.smith@usu.edu","address":"Engineering Building, USU, Logan, Utah","phone":"435-789-9087","homepage":null,"order":1},
{"name":"Lisa Miller","description":null,"organization":null,"email":null,"address":null,"phone":null,"homepage":null,"order":2}
],
"contributors":[
{"name":"Jenny Parker","description":"","organization":"Univesity of Utah","email":"jenny_parker@hotmail.com","address":"","phone":"","homepage":""}
],
"coverages":[
{"type":"period","value":{"start":"01/01/2000","end":"12/12/2010"}}
],
"dates":[
{"type":"created","start_date":"2017-01-03T17:06:18.932217Z","end_date":null},
{"type":"modified","start_date":"2017-01-03T17:06:19.162694Z","end_date":null}
],
"description":"Time series of level, area and volume in the Great Salt Lake. Volume and area of the Great Salt Lake are derived from recorded levels",
"formats":[
{"value":"image/tiff"}
],
"funding_agencies":[
{"agency_name":"National Science Foundation","award_title":"Model Execution Cyberinfrastructure ","award_number":"NSF_9087658_2017","agency_url":"http://www.nsf.gov"}
],
"identifiers":[
{"name":"hydroShareIdentifier","url":"http://www.hydroshare.org/resource/87ffb608900e407ab4b67d30c93b329e"}
],
"language":"eng",
"rights":"This resource is shared under the Creative Commons Attribution CC BY. http://creativecommons.org/licenses/by/4.0/",
"type":"http://www.hydroshare.org/terms/GenericResource",
"publisher":null,
"sources":[],
"subjects":[
{"value":"NSF"},
{"value":"Modeling"}
],
"relations":[]
}

0 comments on commit 4ab9cf8

Please sign in to comment.