forked from trungdong/notebooks
-
Notifications
You must be signed in to change notification settings - Fork 6
/
wrapper.py
167 lines (122 loc) · 5.22 KB
/
wrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/env python
'''
Python ProvStore API wrapper
Example usage:
api = Api() # uses settings provided in this file
# or
api = Api(api_location="https://provenance.ecs.soton.ac.uk/store/api/v0/",
api_username="provstoreusername",
api_key="yourapikey") # uses parameter settings
# Writing a document
prov_bundle = [some ProvBundle object]
document_id = api.submit_document(prov_bundle, identifier="identifier for document"[, public=True])
# Reading a document as a prov.model.ProvBundle
prov_bundle = api.get_document(document_id)
# Get information about a document
prov_bundle = api.get_document_meta(document_id)
# Reading a document as provn
prov_bundle = api.get_document(document_id, format='provn') # returns a string of the document in provn
# Adding a bundle to a document
api.add_bundle(document_id, prov_bundle, "identifier for bundle")
# Deleting a document
api.delete_document(document_id)
'''
import urllib2
import json
from prov.model import ProvDocument
API_LOCATION = "https://provenance.ecs.soton.ac.uk/store/api/v0/"
class ApiError(Exception):
pass
class ApiUnauthorizedError(ApiError):
pass
class ApiBadRequestError(ApiError):
pass
class ApiNotFoundError(ApiError):
pass
class ApiCannotConvertToTheRequestedFormat(ApiError):
pass
class Api(object):
def __init__(self, api_location=None, api_username=None, api_key=None):
self.api_location = api_location or API_LOCATION
self.api_username = api_username
self.api_key = api_key
def _authorization_header(self):
return "ApiKey %s:%s" % (self.api_username, self.api_key)
def request(self, path, data=None, method=None, raw=False):
headers = {
'Accept': 'application/json',
'Content-type': 'application/json'
}
if self.api_location and self.api_key:
headers['Authorization'] = self._authorization_header()
if data:
request = urllib2.Request(self.api_location + path, json.dumps(data), headers)
else:
request = urllib2.Request(self.api_location + path, None, headers)
if method:
request.get_method = lambda: method
try:
response = urllib2.urlopen(request)
except urllib2.HTTPError as e:
response_code = e.code
if response_code == 401:
raise ApiUnauthorizedError()
elif response_code == 400:
raise ApiBadRequestError()
elif response_code == 404:
raise ApiNotFoundError()
elif response_code == 422:
raise ApiNotFoundError()
else:
raise
response_string = response.read()
if response_string or raw:
if raw:
return response_string
else:
return json.loads(response_string)
else:
return True
def submit_document(self, prov_document, identifier, public=False):
"""Returns the ID of the newly inserted document"""
data = {
'content': prov_document.serialize(format='json'),
'public': public,
'rec_id': identifier
}
response = self.request("documents/", data)
return response['id']
def get_resource_uri(self, doc_id, format=None, flattened=False, view=None):
extension = '.' + format if format is not None else ''
view = "/views/%s" % view if view in ['data', 'process', 'responsibility'] else ""
url = "documents/%d%s%s%s" % (doc_id, "/flattened" if flattened else "", view, extension)
return self.api_location[:-7] + url
def get_document(self, doc_id, format=None, flattened=False, view=None):
"""Returns a ProvBundle object of the document with the ID provided or raises ApiNotFoundError"""
extension = format if format is not None else 'json'
view = "/views/%s" % view if view in ['data', 'process', 'responsibility'] else ""
url = "documents/%d%s%s.%s" % (doc_id, "/flattened" if flattened else "", view, extension)
response = self.request(url, raw=True)
if format is None:
# Try to decode it as a ProvDocument
result = ProvDocument.deserialize(content=response)
else:
# return the raw response
result = response
return result
def get_document_meta(self, doc_id):
"""Returns a JSON object containing information about the document or raises ApiNotFoundError"""
response = self.request("documents/" + str(doc_id) + "/")
return response
def add_bundle(self, doc_id, prov_document, identifier):
"""Adds a ProvBundle object to the document with the ID provided or raises ApiNotFoundError"""
data = {
'content': prov_document,
'rec_id': identifier
}
self.request("documents/" + str(doc_id) + "/bundles/", data)
return True
def delete_document(self, doc_id):
"""Removes a ProvBundle object with the provided ID from the ProvStore"""
self.request("documents/" + str(doc_id) + "/", method="DELETE")
return True