Mercurial > repos > bcclaywell > argo_navis
comparison venv/lib/python2.7/site-packages/bioblend/galaxyclient.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author | bcclaywell |
---|---|
date | Mon, 12 Oct 2015 17:43:33 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d67268158946 |
---|---|
1 """ | |
2 Helper class for Galaxy and ToolShed Instance object | |
3 | |
4 This class is primarily a helper for the library and user code | |
5 should not use it directly. | |
6 A base representation of an instance | |
7 """ | |
8 import base64 | |
9 import json | |
10 | |
11 import requests | |
12 from requests_toolbelt import MultipartEncoder | |
13 import six | |
14 from six.moves.urllib.parse import urljoin, urlparse | |
15 | |
16 from .galaxy.client import ConnectionError | |
17 | |
18 | |
19 class GalaxyClient(object): | |
20 | |
21 def __init__(self, url, key=None, email=None, password=None): | |
22 # Make sure the url scheme is defined (otherwise requests will not work) | |
23 if not urlparse(url).scheme: | |
24 url = "http://" + url | |
25 # All of Galaxy's and ToolShed's API's are rooted at <url>/api so make that the url | |
26 self.base_url = url | |
27 self.url = urljoin(url, 'api') | |
28 # If key has been supplied, use it; otherwise just set email and | |
29 # password and grab user's key before first request. | |
30 if key: | |
31 self._key = key | |
32 else: | |
33 self._key = None | |
34 self.email = email | |
35 self.password = password | |
36 self.json_headers = {'Content-Type': 'application/json'} | |
37 self.verify = True # Should SSL verification be done | |
38 | |
39 def _make_url(self, module, module_id=None, deleted=False, contents=False): | |
40 """ | |
41 Compose a URL based on the provided arguments. | |
42 | |
43 :type module: :class:`~.galaxy.Client` subclass | |
44 :param module: The base module for which to make the URL. For | |
45 example: an object of class LibraryClient, WorkflowClient, | |
46 HistoryClient, ToolShedClient | |
47 | |
48 :type module_id: str | |
49 :param module_id: The encoded ID for a specific module (eg, library ID) | |
50 | |
51 :type deleted: bool | |
52 :param deleted: If ``True``, include ``deleted`` in the URL, after the module | |
53 name (eg, ``<base_url>/api/libraries/deleted``) | |
54 | |
55 :type contents: bool | |
56 :param contents: If ``True``, include 'contents' in the URL, after the module ID: | |
57 ``<base_url>/api/libraries/<encoded_library_id>/contents`` | |
58 """ | |
59 c_url = self.url | |
60 c_url = '/'.join([c_url, module.module]) | |
61 if deleted is True: | |
62 c_url = '/'.join([c_url, 'deleted']) | |
63 if module_id is not None: | |
64 c_url = '/'.join([c_url, module_id]) | |
65 if contents is True: | |
66 c_url = '/'.join([c_url, 'contents']) | |
67 return c_url | |
68 | |
69 def make_get_request(self, url, **kwargs): | |
70 """ | |
71 Make a GET request using the provided ``url``. | |
72 | |
73 Keyword arguments are the same as in requests.request. | |
74 | |
75 If ``verify`` is not provided, ``self.verify`` will be used. | |
76 | |
77 If the ``params`` are not provided, use ``default_params`` class field. | |
78 If params are provided and the provided dict does not have ``key`` key, | |
79 the default ``self.key`` value will be included in what's passed to | |
80 the server via the request. | |
81 """ | |
82 params = kwargs.get('params') | |
83 if params is not None and params.get('key', False) is False: | |
84 params['key'] = self.key | |
85 else: | |
86 params = self.default_params | |
87 kwargs['params'] = params | |
88 kwargs.setdefault('verify', self.verify) | |
89 r = requests.get(url, **kwargs) | |
90 return r | |
91 | |
92 def make_post_request(self, url, payload, params=None, files_attached=False): | |
93 """ | |
94 Make a POST request using the provided ``url`` and ``payload``. | |
95 The ``payload`` must be a dict that contains the request values. | |
96 The payload dict may contain file handles (in which case the files_attached | |
97 flag must be set to true). | |
98 | |
99 If the ``params`` are not provided, use ``default_params`` class field. | |
100 If params are provided and the provided dict does not have ``key`` key, | |
101 the default ``self.key`` value will be included in what's passed to | |
102 the server via the request. | |
103 | |
104 The return value will contain the response body as a JSON object. | |
105 """ | |
106 if params is not None and params.get('key', False) is False: | |
107 params['key'] = self.key | |
108 else: | |
109 params = self.default_params | |
110 | |
111 # Compute data, headers, params arguments for request.post, | |
112 # leveraging the requests-toolbelt library if any files have | |
113 # been attached. | |
114 if files_attached: | |
115 payload.update(params) | |
116 payload = MultipartEncoder(fields=payload) | |
117 headers = self.json_headers.copy() | |
118 headers['Content-Type'] = payload.content_type | |
119 post_params = {} | |
120 else: | |
121 payload = json.dumps(payload) | |
122 headers = self.json_headers | |
123 post_params = params | |
124 | |
125 r = requests.post(url, data=payload, headers=headers, | |
126 verify=self.verify, params=post_params) | |
127 if r.status_code == 200: | |
128 return r.json() | |
129 # @see self.body for HTTP response body | |
130 raise ConnectionError("Unexpected response from galaxy: %s" % | |
131 r.status_code, body=r.text) | |
132 | |
133 def make_delete_request(self, url, payload=None, params=None): | |
134 """ | |
135 Make a DELETE request using the provided ``url`` and the optional | |
136 arguments. | |
137 The ``payload`` must be a dict that can be converted into a JSON | |
138 object (via ``json.dumps``) | |
139 | |
140 If the ``params`` are not provided, use ``default_params`` class field. | |
141 If params are provided and the provided dict does not have ``key`` key, | |
142 the default ``self.key`` value will be included in what's passed to | |
143 the server via the request. | |
144 """ | |
145 if params is not None and params.get('key', False) is False: | |
146 params['key'] = self.key | |
147 else: | |
148 params = self.default_params | |
149 r = requests.delete(url, verify=self.verify, data=payload, params=params) | |
150 return r | |
151 | |
152 def make_put_request(self, url, payload=None, params=None): | |
153 """ | |
154 Make a PUT request using the provided ``url`` with required payload. | |
155 The ``payload`` must be a dict that can be converted into a JSON | |
156 object (via ``json.dumps``) | |
157 """ | |
158 if params is not None and params.get('key', False) is False: | |
159 params['key'] = self.key | |
160 else: | |
161 params = self.default_params | |
162 | |
163 payload = json.dumps(payload) | |
164 r = requests.put(url, verify=self.verify, data=payload, params=params) | |
165 return r | |
166 | |
167 @property | |
168 def key(self): | |
169 if not self._key and self.email is not None and self.password is not None: | |
170 unencoded_credentials = "%s:%s" % (self.email, self.password) | |
171 authorization = base64.b64encode(unencoded_credentials) | |
172 headers = self.json_headers.copy() | |
173 headers["Authorization"] = authorization | |
174 auth_url = "%s/authenticate/baseauth" % self.url | |
175 # make_post_request uses default_params, which uses this and | |
176 # sets wrong headers - so using lower level method. | |
177 r = requests.get(auth_url, verify=self.verify, headers=headers) | |
178 if r.status_code != 200: | |
179 raise Exception("Failed to authenticate user.") | |
180 response = r.json() | |
181 if isinstance(response, (six.string_types, six.text_type)): | |
182 # bug in Tool Shed | |
183 response = json.loads(response) | |
184 self._key = response["api_key"] | |
185 return self._key | |
186 | |
187 @property | |
188 def default_params(self): | |
189 return {'key': self.key} |