9 import apiclient.discovery
16 class CredentialsFromEnv(object):
18 def http_request(self, uri, **kwargs):
19 from httplib import BadStatusLine
20 if 'headers' not in kwargs:
21 kwargs['headers'] = {}
23 if config.get("ARVADOS_EXTERNAL_CLIENT", "") == "true":
24 kwargs['headers']['X-External-Client'] = '1'
26 kwargs['headers']['Authorization'] = 'OAuth2 %s' % config.get('ARVADOS_API_TOKEN', 'ARVADOS_API_TOKEN_not_set')
28 return self.orig_http_request(uri, **kwargs)
30 # This is how httplib tells us that it tried to reuse an
31 # existing connection but it was already closed by the
32 # server. In that case, yes, we would like to retry.
33 # Unfortunately, we are not absolutely certain that the
34 # previous call did not succeed, so this is slightly
36 return self.orig_http_request(uri, **kwargs)
37 def authorize(self, http):
38 http.orig_http_request = http.request
39 http.request = types.MethodType(self.http_request, http)
42 # Monkey patch discovery._cast() so objects and arrays get serialized
43 # with json.dumps() instead of str().
44 _cast_orig = apiclient.discovery._cast
45 def _cast_objects_too(value, schema_type):
47 if (type(value) != type('') and
48 (schema_type == 'object' or schema_type == 'array')):
49 return json.dumps(value)
51 return _cast_orig(value, schema_type)
52 apiclient.discovery._cast = _cast_objects_too
54 def http_cache(data_type):
55 path = os.environ['HOME'] + '/.cache/arvados/' + data_type
57 util.mkdir_dash_p(path)
62 def api(version=None, cache=True):
65 if 'ARVADOS_DEBUG' in config.settings():
66 logging.basicConfig(level=logging.DEBUG)
68 if not cache or not services.get(version):
72 logging.info("Using default API version. " +
73 "Call arvados.api('%s') instead." %
75 if 'ARVADOS_API_HOST' not in config.settings():
76 raise Exception("ARVADOS_API_HOST is not set. Aborting.")
77 url = ('https://%s/discovery/v1/apis/{api}/{apiVersion}/rest' %
78 config.get('ARVADOS_API_HOST'))
79 credentials = CredentialsFromEnv()
81 # Use system's CA certificates (if we find them) instead of httplib2's
82 ca_certs = '/etc/ssl/certs/ca-certificates.crt'
83 if not os.path.exists(ca_certs):
84 ca_certs = None # use httplib2 default
86 http = httplib2.Http(ca_certs=ca_certs,
87 cache=(http_cache('discovery') if cache else None))
88 http = credentials.authorize(http)
89 if re.match(r'(?i)^(true|1|yes)$',
90 config.get('ARVADOS_API_HOST_INSECURE', 'no')):
91 http.disable_ssl_certificate_validation=True
92 services[version] = apiclient.discovery.build(
93 'arvados', apiVersion, http=http, discoveryServiceUrl=url)
95 return services[version]