Commit 7326cbd8 authored by abuddenberg's avatar abuddenberg
Browse files

Refactored HTTP requests to properly use Sessions to hold authenticate data. ...

Refactored HTTP requests to properly use Sessions to hold authenticate data.  Added support for associating contributors with figures and images
parent 82bdf74c
from base64 import b64encode
import urllib
import json
from os.path import exists, basename
import re
import requests
from requests.exceptions import ConnectionError
from domain import Figure, Image, Dataset, Activity, Person, Organization
......@@ -52,12 +50,10 @@ class AssociationException(Exception):
class GcisClient(object):
def __init__(self, url, username, password):
self.headers = {
'Accept': 'application/json'
}
self.base_url = url
self.headers['Authorization'] = 'Basic ' + b64encode(username + ':' + password)
self.s = requests.Session()
self.s.auth = (username, password)
self.s.headers.update({'Accept': 'application/json'})
@http_resp
def create_figure(self, report_id, chapter_id, figure, skip_images=False):
......@@ -72,7 +68,7 @@ class GcisClient(object):
b=self.base_url, rpt=report_id, chp=chapter_id
)
resp = requests.post(url, data=figure.as_json(), headers=self.headers, verify=False)
resp = self.s.post(url, data=figure.as_json(), verify=False)
if skip_images is False:
for image in figure.images:
......@@ -94,23 +90,26 @@ class GcisClient(object):
b=self.base_url, rpt=report_id, chp=chapter_id, fig=figure.identifier
)
resp = requests.post(update_url, data=figure.as_json(), headers=self.headers, verify=False)
resp = self.s.post(update_url, data=figure.as_json(), verify=False)
if skip_images is False:
for image in figure.images:
self.update_image(image)
for c in figure.contributors:
self.associate_contributor_with_figure(c, report_id, chapter_id, figure.identifier)
return resp
@http_resp
def delete_figure(self, report_id, figure_id):
url = '{b}/report/{rpt}/figure/{fig}'.format(b=self.base_url, rpt=report_id, fig=figure_id)
return requests.delete(url, headers=self.headers, verify=False)
return self.s.delete(url, verify=False)
@check_image
def create_image(self, image, report_id=None, figure_id=None):
url = '{b}/image/'.format(b=self.base_url)
resp = requests.post(url, data=image.as_json(), headers=self.headers, verify=False)
resp = self.s.post(url, data=image.as_json(), verify=False)
if image.local_path is not None:
self.upload_image_file(image.identifier, image.local_path)
......@@ -132,29 +131,31 @@ class GcisClient(object):
self.update_activity(dataset.activity)
self.associate_dataset_with_image(dataset.identifier, image.identifier,
activity_id=dataset.activity.identifier)
for c in image.contributors:
self.associate_contributor_with_image(c, image.identifier)
return requests.post(update_url, data=image.as_json(), headers=self.headers, verify=False)
return self.s.post(update_url, data=image.as_json(), verify=False)
@check_image
@http_resp
def delete_image(self, image):
delete_url = '{b}/image/{img}'.format(b=self.base_url, img=image.identifier)
return requests.delete(delete_url, headers=self.headers, verify=False)
return self.s.delete(delete_url, verify=False)
@http_resp
def associate_image_with_figure(self, image_id, report_id, figure_id):
url = '{b}/report/{rpt}/figure/rel/{fig}'.format(b=self.base_url, rpt=report_id, fig=figure_id)
return requests.post(url, data=json.dumps({'add_image_identifier': image_id}), headers=self.headers, verify=False)
return self.s.post(url, data=json.dumps({'add_image_identifier': image_id}), verify=False)
@http_resp
def upload_image_file(self, image_id, local_path):
url = '{b}/image/files/{id}/{fn}'.format(b=self.base_url, id=image_id, fn=basename(local_path))
# For future multi-part encoding support
# return requests.put(url, headers=headers, files={'file': (filename, open(filepath, 'rb'))})
# return self.s.put(url, headers=headers, files={'file': (filename, open(filepath, 'rb'))})
if not exists(local_path):
raise Exception('File not found: ' + local_path)
return requests.put(url, data=open(local_path, 'rb'), headers=self.headers, verify=False)
return self.s.put(url, data=open(local_path, 'rb'), verify=False)
#Full listing
def get_figure_listing(self, report_id, chapter_id=None):
......@@ -163,7 +164,7 @@ class GcisClient(object):
url = '{b}/report/{rpt}{chap}/figure?{p}'.format(
b=self.base_url, rpt=report_id, chap=chapter_filter, p=urllib.urlencode({'all': '1'})
)
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, verify=False)
try:
return [Figure(figure) for figure in resp.json()]
......@@ -173,10 +174,10 @@ class GcisClient(object):
def get_figure(self, report_id, figure_id, chapter_id=None):
chapter_filter = '/chapter/' + chapter_id if chapter_id else ''
url = '{b}/report/{rpt}{chap}/figure/{fig}?{p}'.format(
b=self.base_url, rpt=report_id, chap=chapter_filter, fig=figure_id, p=urllib.urlencode({'all': '1'})
url = '{b}/report/{rpt}{chap}/figure/{fig}'.format(
b=self.base_url, rpt=report_id, chap=chapter_filter, fig=figure_id
)
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, params={'all': '1'}, verify=False)
try:
return Figure(resp.json())
......@@ -190,11 +191,11 @@ class GcisClient(object):
url = '{b}/report/{rpt}{chap}/figure/{fig}?{p}'.format(
b=self.base_url, rpt=report_id, chap=chapter_filter, fig=figure_id, p=urllib.urlencode({'all': '1'})
)
return requests.head(url, headers=self.headers, verify=False)
return self.s.head(url, verify=False)
def get_image(self, image_id):
url = '{b}/image/{img}'.format(b=self.base_url, img=image_id)
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, verify=False)
try:
return Image(resp.json())
......@@ -204,7 +205,7 @@ class GcisClient(object):
@exists
def image_exists(self, image_id):
url = '{b}/image/{img}'.format(b=self.base_url, img=image_id)
return requests.head(url, headers=self.headers, verify=False)
return self.s.head(url, verify=False)
def has_all_associated_images(self, report_id, figure_id, target_image_ids):
try:
......@@ -224,26 +225,26 @@ class GcisClient(object):
def test_login(self):
url = '{b}/login.json'.format(b=self.base_url)
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, verify=False)
return resp.status_code, resp.text
def get_keyword_listing(self):
url = '{b}/gcmd_keyword?{p}'.format(b=self.base_url, p=urllib.urlencode({'all': '1'}))
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, verify=False)
return resp.json()
def get_keyword(self, key_id):
url = '{b}/gcmd_keyword/{k}'.format(b=self.base_url, k=key_id)
return requests.get(url, headers=self.headers, verify=False).json()
return self.s.get(url, verify=False).json()
def associate_keyword_with_figure(self, keyword_id, report_id, figure_id):
url = '{b}/report/{rpt}/figure/keywords/{fig}'.format(b=self.base_url, rpt=report_id, fig=figure_id)
return requests.post(url, data=json.dumps({'identifier': keyword_id}), headers=self.headers, verify=False)
return self.s.post(url, data=json.dumps({'identifier': keyword_id}), verify=False)
def get_dataset(self, dataset_id):
url = '{b}/dataset/{ds}'.format(b=self.base_url, ds=dataset_id)
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, verify=False)
try:
return Dataset(resp.json())
except ValueError:
......@@ -252,19 +253,19 @@ class GcisClient(object):
@exists
def dataset_exists(self, dataset_id):
url = '{b}/dataset/{ds}'.format(b=self.base_url, ds=dataset_id)
return requests.head(url, headers=self.headers, verify=False)
return self.s.head(url, verify=False)
def create_dataset(self, dataset):
url = '{b}/dataset/'.format(b=self.base_url)
return requests.post(url, data=dataset.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=dataset.as_json(), verify=False)
def update_dataset(self, dataset):
url = '{b}/dataset/{ds}'.format(b=self.base_url, ds=dataset.identifier)
return requests.post(url, data=dataset.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=dataset.as_json(), verify=False)
def delete_dataset(self, dataset):
url = '{b}/dataset/{ds}'.format(b=self.base_url, ds=dataset.identifier)
return requests.delete(url, headers=self.headers, verify=False)
return self.s.delete(url, verify=False)
def associate_dataset_with_image(self, dataset_id, image_id, activity_id=None):
url = '{b}/image/prov/{img}'.format(b=self.base_url, img=image_id)
......@@ -281,7 +282,7 @@ class GcisClient(object):
except AssociationException as e:
print e.value
resp = requests.post(url, data=json.dumps(data), headers=self.headers, verify=False)
resp = self.s.post(url, data=json.dumps(data), verify=False)
if resp.status_code == 200:
return resp
......@@ -297,7 +298,7 @@ class GcisClient(object):
'parent_rel': 'prov:wasDerivedFrom'
}
}
resp = requests.post(url, data=json.dumps(data), headers=self.headers, verify=False)
resp = self.s.post(url, data=json.dumps(data), verify=False)
if resp.status_code == 200:
return resp
......@@ -317,7 +318,7 @@ class GcisClient(object):
# @exists
def activity_exists(self, activity_id):
url = '{b}/activity/{act}'.format(b=self.base_url, act=activity_id)
resp = requests.head(url, headers=self.headers, verify=False)
resp = self.s.head(url, verify=False)
if resp.status_code == 200:
return True
else:
......@@ -325,7 +326,7 @@ class GcisClient(object):
def get_activity(self, activity_id):
url = '{b}/activity/{act}'.format(b=self.base_url, act=activity_id)
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, verify=False)
try:
return Activity(resp.json())
except ValueError:
......@@ -334,17 +335,17 @@ class GcisClient(object):
@http_resp
def create_activity(self, activity):
url = '{b}/activity/'.format(b=self.base_url)
return requests.post(url, data=activity.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=activity.as_json(), verify=False)
@http_resp
def update_activity(self, activity):
url = '{b}/activity/{act}'.format(b=self.base_url, act=activity.identifier)
return requests.post(url, data=activity.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=activity.as_json(), verify=False)
@http_resp
def delete_activity(self, activity):
url = '{b}/activity/{act}'.format(b=self.base_url, act=activity.identifier)
return requests.delete(url, headers=self.headers, verify=False)
return self.s.delete(url, verify=False)
def create_or_update_activity(self, activity):
if self.activity_exists(activity.identifier):
......@@ -355,11 +356,11 @@ class GcisClient(object):
@exists
def person_exists(self, person_id):
url = '{b}/person/{pid}'.format(b=self.base_url, pid=person_id)
return requests.head(url, headers=self.headers, verfiy=False)
return self.s.head(url, verfiy=False)
def get_person(self, person_id):
url = '{b}/person/{pid}'.format(b=self.base_url, pid=person_id)
resp = requests.get(url, headers=self.headers, verify=False)
resp = self.s.get(url, verify=False)
try:
return Person(resp.json())
except ValueError:
......@@ -367,7 +368,7 @@ class GcisClient(object):
def lookup_person(self, name):
url = '{b}/autocomplete'.format(b=self.base_url)
resp = requests.get(url, params={'q': name, 'items': 15, 'type': 'person'}, headers=self.headers, verify=False)
resp = self.s.get(url, params={'q': name, 'items': 15, 'type': 'person'}, verify=False)
if resp.status_code == 200:
return [re.match(r'\[person\] \{(\d+)\} (.*)', r).groups() for r in resp.json()]
......@@ -377,26 +378,26 @@ class GcisClient(object):
@http_resp
def create_person(self, person):
url = '{b}/person/'.format(b=self.base_url)
return requests.post(url, data=person.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=person.as_json(), verify=False)
@http_resp
def update_person(self, person):
url = '{b}/person/{pid}'.format(b=self.base_url, pid=person.identifier)
return requests.post(url, data=person.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=person.as_json(), verify=False)
@http_resp
def delete_person(self, person):
url = '{b}/person/{pid}'.format(b=self.base_url, pid=person.identifier)
return requests.delete(url, headers=self.headers, verify=False)
return self.s.delete(url, verify=False)
@exists
def organization_exists(self, org_id):
url = '{b}/organization/{org_id)'.format(b=self.base_url, org_id=org_id)
return requests.head(url, headers=self.headers, verify=False)
return self.s.head(url, verify=False)
def get_organization(self, org_id):
url = '{b}/organization/{org_id)'.format(b=self.base_url, org_id=org_id)
resp = requests.get(url, headers=self.headers, verify=False)
url = '{b}/organization/{org_id}'.format(b=self.base_url, org_id=org_id)
resp = self.s.get(url, verify=False)
try:
return Organization(resp.json())
......@@ -405,7 +406,7 @@ class GcisClient(object):
def lookup_organization(self, name):
url = '{b}/autocomplete'.format(b=self.base_url)
resp = requests.get(url, params={'q': name, 'items': 15, 'type': 'organization'}, headers=self.headers, verify=False)
resp = self.s.get(url, params={'q': name, 'items': 15, 'type': 'organization'}, verify=False)
if resp.status_code == 200:
return [re.match(r'\[organization\] \{(.*)\} (.*)', r).groups() for r in resp.json()]
......@@ -415,23 +416,73 @@ class GcisClient(object):
@http_resp
def create_organization(self, org):
url = '{b}/organization/'.format(b=self.base_url)
return requests.post(url, data=org.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=org.as_json(), verify=False)
@http_resp
def update_organization(self, org):
url = '{b}/organization/{org_id}'.format(b=self.base_url, org_id=org.identifier)
return requests.post(url, data=org.as_json(), headers=self.headers, verify=False)
return self.s.post(url, data=org.as_json(), verify=False)
@http_resp
def delete_organization(self, org):
url = '{b}/organization/{org_id}'.format(b=self.base_url, org_id=org.identifier)
return requests.delete(url, headers=self.headers, verify=False)
return self.s.delete(url, verify=False)
@http_resp
def associate_contributor_with_figure(self, contrib, report_id, chapter_id, figure_id):
url = '{b}/report/{rpt}/chapter/{chp}/figure/contributors/{fig}'.format(b=self.base_url, rpt=report_id, chp=chapter_id, fig=figure_id)
data = {}
data = {
'role': contrib.role.type_id,
}
if contrib.person is not None and contrib.person.id is not None:
data['person_id'] = contrib.person.id
if contrib.organization is not None and contrib.organization.identifier:
data['organization_identifier'] = contrib.organization.identifier
resp = self.s.post(url, data=json.dumps(data), verify=False)
return resp
@http_resp
def delete_contributor_figure_assoc(self, contrib, report_id, chapter_id, figure_id):
url = '{b}/report/{rpt}/chapter/{chp}/figure/contributors/{fig}'.format(b=self.base_url, rpt=report_id, chp=chapter_id, fig=figure_id)
data = {
'delete': {
'role': contrib.role.type_id,
'organization_identifier': contrib.organization.identifier,
'person_id': contrib.person.identifier
}
}
return self.s.post(url, data=json.dumps(data), verify=False)
@http_resp
def associate_contributor_with_image(self, contrib, image_id):
url = '{b}/image/contributors/{img}'.format(b=self.base_url, img=image_id)
data = {
'role': contrib.role.type_id,
}
if contrib.person is not None and contrib.person.id is not None:
data['person_id'] = contrib.person.id
if contrib.organization is not None and contrib.organization.identifier:
data['organization_identifier'] = contrib.organization.identifier
return self.s.post(url, data=json.dumps(data), verify=False)
@http_resp
def delete_contributor_image_assoc(self, contrib, image_id):
url = '{b}/image/contributors/{img}'.format(b=self.base_url, img=image_id)
data = {
'delete': {
'role': contrib.role.type_id,
'organization_identifier': contrib.organization.identifier,
'person_id': contrib.person.identifier
}
}
return requests.post(url, data=json.dumps(data), headers=self.headers, verify=False)
return self.s.post(url, data=json.dumps(data), verify=False)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment