4c4a6e5c3dc156b49dea72e751e390d8a8435249
[htsworkflow.git] / htsworkflow / util / api.py
1 """Common functions for accessing the HTS Workflow REST API
2 """
3 from ConfigParser import SafeConfigParser
4 import logging
5
6 # try to deal with python <2.6
7 try:
8   import json
9 except ImportError:
10   import simplejson as json
11
12 import os
13 from optparse import OptionGroup
14 import urllib
15 import urllib2
16 import urlparse
17
18 LOGGER = logging.getLogger(__name__)
19
20 def add_auth_options(parser):
21     """Add options OptParser configure authentication options
22     """
23     # Load defaults from the config files
24     config = SafeConfigParser()
25     config.read([os.path.expanduser('~/.htsworkflow.ini'),
26                  '/etc/htsworkflow.ini'
27                  ])
28
29     sequence_archive = None
30     apiid = None
31     apikey = None
32     apihost = None
33     SECTION = 'sequence_archive'
34     if config.has_section(SECTION):
35         sequence_archive = config.get(SECTION, 'sequence_archive',sequence_archive)
36         sequence_archive = os.path.expanduser(sequence_archive)
37         apiid = config.get(SECTION, 'apiid', apiid)
38         apikey = config.get(SECTION, 'apikey', apikey)
39         apihost = config.get(SECTION, 'host', apihost)
40
41     # configuration options
42     group = OptionGroup(parser, "htsw api authentication")
43     group.add_option('--apiid', default=apiid, help="Specify API ID")
44     group.add_option('--apikey', default=apikey, help="Specify API KEY")
45     group.add_option('--host',  default=apihost,
46                      help="specify HTSWorkflow host",)
47     group.add_option('--sequence', default=sequence_archive,
48                      help="sequence repository")
49     parser.add_option_group(group)
50
51 def make_auth_from_opts(opts, parser):
52     """Create htsw auth info dictionary from optparse info
53     """
54     if opts.host is None or opts.apiid is None or opts.apikey is None:
55         parser.error("Please specify host url, apiid, apikey")
56
57     return {'apiid': opts.apiid, 'apikey': opts.apikey }
58
59
60 def library_url(root_url, library_id):
61     """
62     Return the url for retrieving information about a specific library.
63
64     Args:
65       library_id (str): the library id of interest
66       root_url (str): the root portion of the url, e.g. http://localhost
67
68     Returns:
69       str. The url to use for this REST api.
70
71     >>> print library_url('http://localhost', '12345')
72     http://localhost/samples/library/12345/json
73
74     """
75     url_fragment = '/samples/library/%s/json' % (library_id,)
76     url = urlparse.urljoin(root_url, url_fragment)
77
78     return url
79
80
81 def flowcell_url(root_url, flowcell_id):
82     """
83     Return the url for retrieving information about a specific flowcell.
84
85     Args:
86       root_url (str): the root portion of the url, e.g. http://localhost
87       flowcell_id (str): the flowcell id of interest
88
89     Returns:
90       str. The url to use for this REST api.
91
92     >>> print flowcell_url('http://localhost', '1234AAXX')
93     http://localhost/experiments/config/1234AAXX/json
94     """
95     url_fragment = '/experiments/config/%s/json' % (flowcell_id,)
96     url = urlparse.urljoin(root_url, url_fragment)
97
98     return url
99
100
101 def lanes_for_user_url(root_url, username):
102     """
103     Return the url for returning all the lanes associated with a username
104
105     Args:
106       username (str): a username in your target filesystem
107       root_url (str): the root portion of the url, e.g. http://localhost
108
109     Returns:
110       str. The url to use for this REST api.
111
112     >>> print lanes_for_user_url('http://localhost', 'diane')
113     http://localhost/lanes_for/diane/json
114
115     """
116     url_fragment = '/lanes_for/%s/json' % (username,)
117     url = urlparse.urljoin(root_url, url_fragment)
118
119     return url
120
121 def retrieve_info(url, apidata):
122     """
123     Return a dictionary from the HTSworkflow API
124     """
125     try:
126         apipayload = urllib.urlencode(apidata)
127         web = urllib2.urlopen(url, apipayload)
128     except urllib2.URLError, e:
129         if hasattr(e, 'code') and e.code == 404:
130             LOGGER.info("%s was not found" % (url,))
131             return None
132         else:
133             errmsg = 'URLError: %s' % (str(e))
134             raise IOError(errmsg)
135
136     contents = web.read()
137     headers = web.info()
138
139     return json.loads(contents)
140
141 class HtswApi(object):
142   def __init__(self, root_url, authdata):
143     self.root_url = root_url
144     self.authdata = authdata
145
146   def get_flowcell(self, flowcellId):
147     url = flowcell_url(self.root_url, flowcellId)
148     return retrieve_info(url, self.authdata)
149
150   def get_library(self, libraryId):
151     url = library_url(self.root_url, libraryId)
152     return retrieve_info(url, self.authdata)
153
154   def get_lanes_for_user(self, user):
155     url = lanes_for_user(self.root_url, user)
156     return retrieve_info(url, self.authdata)
157
158   def get_url(self, url):
159     return retrieve_info(url, self.authdata)
160