/
tool_shed_repositories.py
600 lines (561 loc) · 40.7 KB
/
tool_shed_repositories.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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
import logging
from paste.httpexceptions import HTTPBadRequest, HTTPForbidden
from time import strftime
from galaxy import util
from galaxy import web
from galaxy.util import json
from galaxy.web.base.controller import BaseAPIController
from tool_shed.galaxy_install import repository_util
from tool_shed.util import common_util
from tool_shed.util import encoding_util
from tool_shed.util import metadata_util
from tool_shed.util import workflow_util
from tool_shed.util import tool_util
import tool_shed.util.shed_util_common as suc
log = logging.getLogger( __name__ )
def get_message_for_no_shed_tool_config():
# This Galaxy instance is not configured with a shed-related tool panel configuration file.
message = 'The tool_config_file setting in universe_wsgi.ini must include at least one shed tool configuration file name with a <toolbox> '
message += 'tag that includes a tool_path attribute value which is a directory relative to the Galaxy installation directory in order to '
message += 'automatically install tools from a tool shed into Galaxy (e.g., the file name shed_tool_conf.xml whose <toolbox> tag is '
message += '<toolbox tool_path="../shed_tools">). For details, see the "Installation of Galaxy tool shed repository tools into a local '
message += 'Galaxy instance" section of the Galaxy tool shed wiki at http://wiki.galaxyproject.org/InstallingRepositoriesToGalaxy#'
message += 'Installing_Galaxy_tool_shed_repository_tools_into_a_local_Galaxy_instance.'
return message
class ToolShedRepositoriesController( BaseAPIController ):
"""RESTful controller for interactions with tool shed repositories."""
@web.expose_api
def exported_workflows( self, trans, id, **kwd ):
"""
GET /api/tool_shed_repositories/{encoded_tool_shed_repository_id}/exported_workflows
Display a list of dictionaries containing information about this tool shed repository's exported workflows.
:param id: the encoded id of the ToolShedRepository object
"""
# Example URL: http://localhost:8763/api/tool_shed_repositories/f2db41e1fa331b3e/exported_workflows
# Since exported workflows are dictionaries with very few attributes that differentiate them from each
# other, we'll build the list based on the following dictionary of those few attributes.
exported_workflows = []
repository = suc.get_tool_shed_repository_by_id( trans, id )
metadata = repository.metadata
if metadata:
exported_workflow_tups = metadata.get( 'workflows', [] )
else:
exported_workflow_tups = []
for index, exported_workflow_tup in enumerate( exported_workflow_tups ):
# The exported_workflow_tup looks like ( relative_path, exported_workflow_dict ), where the value of
# relative_path is the location on disk (relative to the root of the installed repository) where the
# exported_workflow_dict file (.ga file) is located.
exported_workflow_dict = exported_workflow_tup[ 1 ]
annotation = exported_workflow_dict.get( 'annotation', '' )
format_version = exported_workflow_dict.get( 'format-version', '' )
workflow_name = exported_workflow_dict.get( 'name', '' )
# Since we don't have an in-memory object with an id, we'll identify the exported workflow via its
# location (i.e., index) in the list.
display_dict = dict( index=index, annotation=annotation, format_version=format_version, workflow_name=workflow_name )
exported_workflows.append( display_dict )
return exported_workflows
@web.expose_api
def get_latest_installable_revision( self, trans, payload, **kwd ):
"""
POST /api/tool_shed_repositories/get_latest_installable_revision
Get the latest installable revision of a specified repository from a specified Tool Shed.
:param key: the current Galaxy admin user's API key
The following parameters are included in the payload.
:param tool_shed_url (required): the base URL of the Tool Shed from which to retrieve the Repository revision.
:param name (required): the name of the Repository
:param owner (required): the owner of the Repository
"""
# Get the information about the repository to be installed from the payload.
tool_shed_url = payload.get( 'tool_shed_url', '' )
if not tool_shed_url:
raise HTTPBadRequest( detail="Missing required parameter 'tool_shed_url'." )
name = payload.get( 'name', '' )
if not name:
raise HTTPBadRequest( detail="Missing required parameter 'name'." )
owner = payload.get( 'owner', '' )
if not owner:
raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
# Make sure the current user's API key proves he is an admin user in this Galaxy instance.
if not trans.user_is_admin():
raise HTTPForbidden( detail='You are not authorized to request the latest installable revision for a repository in this Galaxy instance.' )
params = '?name=%s&owner=%s' % ( name, owner )
url = common_util.url_join( tool_shed_url,
'api/repositories/get_ordered_installable_revisions%s' % params )
try:
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
except Exception, e:
message = "Error attempting to retrieve the latest installable revision from tool shed %s for repository %s owned by %s: %s" % \
( str( tool_shed_url ), str( name ), str( owner ), str( e ) )
log.debug( message )
return dict( status='error', error=message )
if raw_text:
# If successful, the response from get_ordered_installable_revisions will be a list of
# changeset_revision hash strings.
changeset_revisions = json.from_json_string( raw_text )
if len( changeset_revisions ) >= 1:
return changeset_revisions[ -1 ]
return suc.INITIAL_CHANGELOG_HASH
def __get_value_mapper( self, trans, tool_shed_repository ):
value_mapper={ 'id' : trans.security.encode_id( tool_shed_repository.id ),
'error_message' : tool_shed_repository.error_message or '' }
return value_mapper
@web.expose_api
def import_workflow( self, trans, payload, **kwd ):
"""
POST /api/tool_shed_repositories/import_workflow
Import the specified exported workflow contained in the specified installed tool shed repository into Galaxy.
:param key: the API key of the Galaxy user with which the imported workflow will be associated.
:param id: the encoded id of the ToolShedRepository object
The following parameters are included in the payload.
:param index: the index location of the workflow tuple in the list of exported workflows stored in the metadata for the specified repository
"""
api_key = kwd.get( 'key', None )
if api_key is None:
raise HTTPBadRequest( detail="Missing required parameter 'key' whose value is the API key for the Galaxy user importing the specified workflow." )
tool_shed_repository_id = kwd.get( 'id', '' )
if not tool_shed_repository_id:
raise HTTPBadRequest( detail="Missing required parameter 'id'." )
index = payload.get( 'index', None )
if index is None:
raise HTTPBadRequest( detail="Missing required parameter 'index'." )
repository = suc.get_tool_shed_repository_by_id( trans, tool_shed_repository_id )
exported_workflows = json.from_json_string( self.exported_workflows( trans, tool_shed_repository_id ) )
# Since we don't have an in-memory object with an id, we'll identify the exported workflow via its location (i.e., index) in the list.
exported_workflow = exported_workflows[ int( index ) ]
workflow_name = exported_workflow[ 'workflow_name' ]
workflow, status, error_message = workflow_util.import_workflow( trans, repository, workflow_name )
if status == 'error':
log.debug( error_message )
return {}
return workflow.to_dict( view='element' )
@web.expose_api
def import_workflows( self, trans, **kwd ):
"""
POST /api/tool_shed_repositories/import_workflows
Import all of the exported workflows contained in the specified installed tool shed repository into Galaxy.
:param key: the API key of the Galaxy user with which the imported workflows will be associated.
:param id: the encoded id of the ToolShedRepository object
"""
api_key = kwd.get( 'key', None )
if api_key is None:
raise HTTPBadRequest( detail="Missing required parameter 'key' whose value is the API key for the Galaxy user importing the specified workflow." )
tool_shed_repository_id = kwd.get( 'id', '' )
if not tool_shed_repository_id:
raise HTTPBadRequest( detail="Missing required parameter 'id'." )
repository = suc.get_tool_shed_repository_by_id( trans, tool_shed_repository_id )
exported_workflows = json.from_json_string( self.exported_workflows( trans, tool_shed_repository_id ) )
imported_workflow_dicts = []
for exported_workflow_dict in exported_workflows:
workflow_name = exported_workflow_dict[ 'workflow_name' ]
workflow, status, error_message = workflow_util.import_workflow( trans, repository, workflow_name )
if status == 'error':
log.debug( error_message )
else:
imported_workflow_dicts.append( workflow.to_dict( view='element' ) )
return imported_workflow_dicts
@web.expose_api
def index( self, trans, **kwd ):
"""
GET /api/tool_shed_repositories
Display a list of dictionaries containing information about installed tool shed repositories.
"""
# Example URL: http://localhost:8763/api/tool_shed_repositories
tool_shed_repository_dicts = []
for tool_shed_repository in trans.install_model.context.query( trans.app.install_model.ToolShedRepository ) \
.order_by( trans.app.install_model.ToolShedRepository.table.c.name ):
tool_shed_repository_dict = \
tool_shed_repository.to_dict( value_mapper=self.__get_value_mapper( trans, tool_shed_repository ) )
tool_shed_repository_dict[ 'url' ] = web.url_for( controller='tool_shed_repositories',
action='show',
id=trans.security.encode_id( tool_shed_repository.id ) )
tool_shed_repository_dicts.append( tool_shed_repository_dict )
return tool_shed_repository_dicts
@web.expose_api
def install_repository_revision( self, trans, payload, **kwd ):
"""
POST /api/tool_shed_repositories/install_repository_revision
Install a specified repository revision from a specified tool shed into Galaxy.
:param key: the current Galaxy admin user's API key
The following parameters are included in the payload.
:param tool_shed_url (required): the base URL of the Tool Shed from which to install the Repository
:param name (required): the name of the Repository
:param owner (required): the owner of the Repository
:param changeset_revision (required): the changeset_revision of the RepositoryMetadata object associated with the Repository
:param new_tool_panel_section_label (optional): label of a new section to be added to the Galaxy tool panel in which to load
tools contained in the Repository. Either this parameter must be an empty string or
the tool_panel_section_id parameter must be an empty string or both must be an empty
string (both cannot be used simultaneously).
:param tool_panel_section_id (optional): id of the Galaxy tool panel section in which to load tools contained in the Repository.
If this parameter is an empty string and the above new_tool_panel_section_label parameter is an
empty string, tools will be loaded outside of any sections in the tool panel. Either this
parameter must be an empty string or the tool_panel_section_id parameter must be an empty string
of both must be an empty string (both cannot be used simultaneously).
:param install_repository_dependencies (optional): Set to True if you want to install repository dependencies defined for the specified
repository being installed. The default setting is False.
:param install_tool_dependencies (optional): Set to True if you want to install tool dependencies defined for the specified repository being
installed. The default setting is False.
:param shed_tool_conf (optional): The shed-related tool panel configuration file configured in the "tool_config_file" setting in the Galaxy config file
(e.g., universe_wsgi.ini). At least one shed-related tool panel config file is required to be configured. Setting
this parameter to a specific file enables you to choose where the specified repository will be installed because
the tool_path attribute of the <toolbox> from the specified file is used as the installation location
(e.g., <toolbox tool_path="../shed_tools">). If this parameter is not set, a shed-related tool panel configuration
file will be selected automatically.
"""
# Get the information about the repository to be installed from the payload.
tool_shed_url = payload.get( 'tool_shed_url', '' )
if not tool_shed_url:
raise HTTPBadRequest( detail="Missing required parameter 'tool_shed_url'." )
name = payload.get( 'name', '' )
if not name:
raise HTTPBadRequest( detail="Missing required parameter 'name'." )
owner = payload.get( 'owner', '' )
if not owner:
raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
changeset_revision = payload.get( 'changeset_revision', '' )
if not changeset_revision:
raise HTTPBadRequest( detail="Missing required parameter 'changeset_revision'." )
# Make sure this Galaxy instance is configured with a shed-related tool panel configuration file.
if not suc.have_shed_tool_conf_for_install( trans ):
message = get_message_for_no_shed_tool_config()
log.debug( message )
return dict( status='error', error=message )
# Make sure the current user's API key proves he is an admin user in this Galaxy instance.
if not trans.user_is_admin():
raise HTTPForbidden( detail='You are not authorized to install a tool shed repository into this Galaxy instance.' )
# Keep track of all repositories that are installed - there may be more than one if repository dependencies are installed.
installed_tool_shed_repositories = []
# Get all of the information necessary for installing the repository from the specified tool shed.
params = '?name=%s&owner=%s&changeset_revision=%s' % ( name, owner, changeset_revision )
url = common_util.url_join( tool_shed_url,
'api/repositories/get_repository_revision_install_info%s' % params )
try:
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
except Exception, e:
message = "Error attempting to retrieve installation information from tool shed %s for revision %s of repository %s owned by %s: %s" % \
( str( tool_shed_url ), str( changeset_revision ), str( name ), str( owner ), str( e ) )
log.debug( message )
return dict( status='error', error=message )
if raw_text:
# If successful, the response from get_repository_revision_install_info will be 3
# dictionaries, a dictionary defining the Repository, a dictionary defining the
# Repository revision (RepositoryMetadata), and a dictionary including the additional
# information required to install the repository.
items = json.from_json_string( raw_text )
repository_revision_dict = items[ 1 ]
repo_info_dict = items[ 2 ]
else:
message = "Unable to retrieve installation information from tool shed %s for revision %s of repository %s owned by %s: %s" % \
( str( tool_shed_url ), str( changeset_revision ), str( name ), str( owner ), str( e ) )
log.debug( message )
return dict( status='error', error=message )
# Make sure the tool shed returned everything we need for installing the repository.
if not repository_revision_dict or not repo_info_dict:
key = kwd.get( 'key', None )
invalid_parameter_message = "No information is available for the requested repository revision.\n"
invalid_parameter_message += "One or more of the following parameter values is likely invalid:\n"
invalid_parameter_message += "key: %s\n" % str( key )
invalid_parameter_message += "tool_shed_url: %s\n" % str( tool_shed_url )
invalid_parameter_message += "name: %s\n" % str( name )
invalid_parameter_message += "owner: %s\n" % str( owner )
invalid_parameter_message += "changeset_revision: %s\n" % str( changeset_revision )
raise HTTPBadRequest( detail=invalid_parameter_message )
repo_info_dicts = [ repo_info_dict ]
try:
has_repository_dependencies = repository_revision_dict[ 'has_repository_dependencies' ]
except:
raise HTTPBadRequest( detail="Missing required parameter 'has_repository_dependencies'." )
try:
includes_tools = repository_revision_dict[ 'includes_tools' ]
except:
raise HTTPBadRequest( detail="Missing required parameter 'includes_tools'." )
try:
includes_tool_dependencies = repository_revision_dict[ 'includes_tool_dependencies' ]
except:
raise HTTPBadRequest( detail="Missing required parameter 'includes_tool_dependencies'." )
try:
includes_tools_for_display_in_tool_panel = repository_revision_dict[ 'includes_tools_for_display_in_tool_panel' ]
except:
raise HTTPBadRequest( detail="Missing required parameter 'includes_tools_for_display_in_tool_panel'." )
# Get the information about the Galaxy components (e.g., tool pane section, tool config file, etc) that will contain the repository information.
install_repository_dependencies = payload.get( 'install_repository_dependencies', False )
install_tool_dependencies = payload.get( 'install_tool_dependencies', False )
if install_tool_dependencies:
if trans.app.config.tool_dependency_dir is None:
no_tool_dependency_dir_message = "Tool dependencies can be automatically installed only if you set the value of your 'tool_dependency_dir' "
no_tool_dependency_dir_message += "setting in your Galaxy configuration file (universe_wsgi.ini) and restart your Galaxy server."
raise HTTPBadRequest( detail=no_tool_dependency_dir_message )
new_tool_panel_section_label = payload.get( 'new_tool_panel_section_label', '' )
shed_tool_conf = payload.get( 'shed_tool_conf', None )
if shed_tool_conf:
# Get the tool_path setting.
index, shed_conf_dict = suc.get_shed_tool_conf_dict( trans.app, shed_tool_conf )
tool_path = shed_conf_dict[ 'tool_path' ]
else:
# Pick a semi-random shed-related tool panel configuration file and get the tool_path setting.
for shed_config_dict in trans.app.toolbox.shed_tool_confs:
# Don't use migrated_tools_conf.xml.
if shed_config_dict[ 'config_filename' ] != trans.app.config.migrated_tools_config:
break
shed_tool_conf = shed_config_dict[ 'config_filename' ]
tool_path = shed_config_dict[ 'tool_path' ]
if not shed_tool_conf:
raise HTTPBadRequest( detail="Missing required parameter 'shed_tool_conf'." )
tool_panel_section_id = payload.get( 'tool_panel_section_id', '' )
if tool_panel_section_id not in [ None, '' ]:
if tool_panel_section_id not in trans.app.toolbox.tool_panel:
fixed_tool_panel_section_id = 'section_%s' % tool_panel_section_id
if fixed_tool_panel_section_id in trans.app.toolbox.tool_panel:
tool_panel_section_id = fixed_tool_panel_section_id
else:
tool_panel_section_id = ''
else:
tool_panel_section_id = ''
# Build the dictionary of information necessary for creating tool_shed_repository database records for each repository being installed.
installation_dict = dict( install_repository_dependencies=install_repository_dependencies,
new_tool_panel_section_label=new_tool_panel_section_label,
no_changes_checked=False,
repo_info_dicts=repo_info_dicts,
tool_panel_section_id=tool_panel_section_id,
tool_path=tool_path,
tool_shed_url=tool_shed_url )
# Create the tool_shed_repository database records and gather additional information for repository installation.
created_or_updated_tool_shed_repositories, tool_panel_section_keys, repo_info_dicts, filtered_repo_info_dicts = \
repository_util.handle_tool_shed_repositories( trans, installation_dict, using_api=True )
if created_or_updated_tool_shed_repositories:
# Build the dictionary of information necessary for installing the repositories.
installation_dict = dict( created_or_updated_tool_shed_repositories=created_or_updated_tool_shed_repositories,
filtered_repo_info_dicts=filtered_repo_info_dicts,
has_repository_dependencies=has_repository_dependencies,
includes_tool_dependencies=includes_tool_dependencies,
includes_tools=includes_tools,
includes_tools_for_display_in_tool_panel=includes_tools_for_display_in_tool_panel,
install_repository_dependencies=install_repository_dependencies,
install_tool_dependencies=install_tool_dependencies,
message='',
new_tool_panel_section_label=new_tool_panel_section_label,
shed_tool_conf=shed_tool_conf,
status='done',
tool_panel_section_id=tool_panel_section_id,
tool_panel_section_keys=tool_panel_section_keys,
tool_path=tool_path,
tool_shed_url=tool_shed_url )
# Prepare the repositories for installation. Even though this method receives a single combination of tool_shed_url, name, owner and
# changeset_revision, there may be multiple repositories for installation at this point because repository dependencies may have added
# additional repositories for installation along with the single specified repository.
encoded_kwd, query, tool_shed_repositories, encoded_repository_ids = \
repository_util.initiate_repository_installation( trans, installation_dict )
# Some repositories may have repository dependencies that are required to be installed before the dependent repository, so we'll
# order the list of tsr_ids to ensure all repositories install in the required order.
tsr_ids = [ trans.security.encode_id( tool_shed_repository.id ) for tool_shed_repository in tool_shed_repositories ]
ordered_tsr_ids, ordered_repo_info_dicts, ordered_tool_panel_section_keys = \
repository_util.order_components_for_installation( trans, tsr_ids, repo_info_dicts, tool_panel_section_keys=tool_panel_section_keys )
# Install the repositories, keeping track of each one for later display.
for index, tsr_id in enumerate( ordered_tsr_ids ):
tool_shed_repository = trans.install_model.context.query( trans.install_model.ToolShedRepository ).get( trans.security.decode_id( tsr_id ) )
if tool_shed_repository.status in [ trans.install_model.ToolShedRepository.installation_status.NEW,
trans.install_model.ToolShedRepository.installation_status.UNINSTALLED ]:
repo_info_dict = ordered_repo_info_dicts[ index ]
tool_panel_section_key = ordered_tool_panel_section_keys[ index ]
repository_util.install_tool_shed_repository( trans,
tool_shed_repository,
repo_info_dict,
tool_panel_section_key,
shed_tool_conf,
tool_path,
install_tool_dependencies,
reinstalling=False )
tool_shed_repository_dict = tool_shed_repository.as_dict( value_mapper=self.__get_value_mapper( trans, tool_shed_repository ) )
tool_shed_repository_dict[ 'url' ] = web.url_for( controller='tool_shed_repositories',
action='show',
id=trans.security.encode_id( tool_shed_repository.id ) )
installed_tool_shed_repositories.append( tool_shed_repository_dict )
else:
# We're attempting to install more than 1 repository, and all of them have already been installed.
return dict( status='error', error='All repositories that you are attempting to install have been previously installed.' )
# Display the list of installed repositories.
return installed_tool_shed_repositories
@web.expose_api
def install_repository_revisions( self, trans, payload, **kwd ):
"""
POST /api/tool_shed_repositories/install_repository_revisions
Install one or more specified repository revisions from one or more specified tool sheds into Galaxy. The received parameters
must be ordered lists so that positional values in tool_shed_urls, names, owners and changeset_revisions are associated.
It's questionable whether this method is needed as the above method for installing a single repository can probably cover all
desired scenarios. We'll keep this one around just in case...
:param key: the current Galaxy admin user's API key
The following parameters are included in the payload.
:param tool_shed_urls: the base URLs of the Tool Sheds from which to install a specified Repository
:param names: the names of the Repositories to be installed
:param owners: the owners of the Repositories to be installed
:param changeset_revisions: the changeset_revisions of each RepositoryMetadata object associated with each Repository to be installed
:param new_tool_panel_section_label: optional label of a new section to be added to the Galaxy tool panel in which to load
tools contained in the Repository. Either this parameter must be an empty string or
the tool_panel_section_id parameter must be an empty string, as both cannot be used.
:param tool_panel_section_id: optional id of the Galaxy tool panel section in which to load tools contained in the Repository.
If not set, tools will be loaded outside of any sections in the tool panel. Either this
parameter must be an empty string or the tool_panel_section_id parameter must be an empty string,
as both cannot be used.
:param install_repository_dependencies (optional): Set to True if you want to install repository dependencies defined for the specified
repository being installed. The default setting is False.
:param install_tool_dependencies (optional): Set to True if you want to install tool dependencies defined for the specified repository being
installed. The default setting is False.
:param shed_tool_conf (optional): The shed-related tool panel configuration file configured in the "tool_config_file" setting in the Galaxy config file
(e.g., universe_wsgi.ini). At least one shed-related tool panel config file is required to be configured. Setting
this parameter to a specific file enables you to choose where the specified repository will be installed because
the tool_path attribute of the <toolbox> from the specified file is used as the installation location
(e.g., <toolbox tool_path="../shed_tools">). If this parameter is not set, a shed-related tool panel configuration
file will be selected automatically.
"""
if not suc.have_shed_tool_conf_for_install( trans ):
# This Galaxy instance is not configured with a shed-related tool panel configuration file.
message = get_message_for_no_shed_tool_config()
log.debug( message )
return dict( status='error', error=message )
if not trans.user_is_admin():
raise HTTPForbidden( detail='You are not authorized to install a tool shed repository into this Galaxy instance.' )
# Get the information about all of the repositories to be installed.
tool_shed_urls = util.listify( payload.get( 'tool_shed_urls', '' ) )
names = util.listify( payload.get( 'names', '' ) )
owners = util.listify( payload.get( 'owners', '' ) )
changeset_revisions = util.listify( payload.get( 'changeset_revisions', '' ) )
num_specified_repositories = len( tool_shed_urls )
if len( names ) != num_specified_repositories or \
len( owners ) != num_specified_repositories or \
len( changeset_revisions ) != num_specified_repositories:
message = 'Error in tool_shed_repositories API in install_repository_revisions: the received parameters must be ordered '
message += 'lists so that positional values in tool_shed_urls, names, owners and changeset_revisions are associated.'
log.debug( message )
return dict( status='error', error=message )
# Get the information about the Galaxy components (e.g., tool pane section, tool config file, etc) that will contain information
# about each of the repositories being installed.
# TODO: we may want to enhance this method to allow for each of the following to be associated with each repository instead of
# forcing all repositories to use the same settings.
install_repository_dependencies = payload.get( 'install_repository_dependencies', False )
install_tool_dependencies = payload.get( 'install_tool_dependencies', False )
new_tool_panel_section_label = payload.get( 'new_tool_panel_section_label', '' )
shed_tool_conf = payload.get( 'shed_tool_conf', None )
tool_panel_section_id = payload.get( 'tool_panel_section_id', '' )
all_installed_tool_shed_repositories = []
for index, tool_shed_url in enumerate( tool_shed_urls ):
current_payload = {}
current_payload[ 'tool_shed_url' ] = tool_shed_url
current_payload[ 'name' ] = names[ index ]
current_payload[ 'owner' ] = owners[ index ]
current_payload[ 'changeset_revision' ] = changeset_revisions[ index ]
current_payload[ 'new_tool_panel_section_label' ] = new_tool_panel_section_label
current_payload[ 'tool_panel_section_id' ] = tool_panel_section_id
current_payload[ 'install_repository_dependencies' ] = install_repository_dependencies
current_payload[ 'install_tool_dependencies' ] = install_tool_dependencies
current_payload[ 'shed_tool_conf' ] = shed_tool_conf
installed_tool_shed_repositories = self.install_repository_revision( trans, **current_payload )
if isinstance( installed_tool_shed_repositories, dict ):
# We encountered an error.
return installed_tool_shed_repositories
elif isinstance( installed_tool_shed_repositories, list ):
all_installed_tool_shed_repositories.extend( installed_tool_shed_repositories )
return all_installed_tool_shed_repositories
@web.expose_api
def repair_repository_revision( self, trans, payload, **kwd ):
"""
POST /api/tool_shed_repositories/repair_repository_revision
Repair a specified repository revision previously installed into Galaxy.
:param key: the current Galaxy admin user's API key
The following parameters are included in the payload.
:param tool_shed_url (required): the base URL of the Tool Shed from which the Repository was installed
:param name (required): the name of the Repository
:param owner (required): the owner of the Repository
:param changeset_revision (required): the changeset_revision of the RepositoryMetadata object associated with the Repository
"""
# Get the information about the repository to be installed from the payload.
tool_shed_url = payload.get( 'tool_shed_url', '' )
if not tool_shed_url:
raise HTTPBadRequest( detail="Missing required parameter 'tool_shed_url'." )
name = payload.get( 'name', '' )
if not name:
raise HTTPBadRequest( detail="Missing required parameter 'name'." )
owner = payload.get( 'owner', '' )
if not owner:
raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
changeset_revision = payload.get( 'changeset_revision', '' )
if not changeset_revision:
raise HTTPBadRequest( detail="Missing required parameter 'changeset_revision'." )
tool_shed_repositories = []
tool_shed_repository = suc.get_tool_shed_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed_url, name, owner, changeset_revision )
repair_dict = repository_util.get_repair_dict( trans, tool_shed_repository )
ordered_tsr_ids = repair_dict.get( 'ordered_tsr_ids', [] )
ordered_repo_info_dicts = repair_dict.get( 'ordered_repo_info_dicts', [] )
if ordered_tsr_ids and ordered_repo_info_dicts:
for index, tsr_id in enumerate( ordered_tsr_ids ):
repository = trans.install_model.context.query( trans.install_model.ToolShedRepository ).get( trans.security.decode_id( tsr_id ) )
repo_info_dict = ordered_repo_info_dicts[ index ]
# TODO: handle errors in repair_dict.
repair_dict = repository_util.repair_tool_shed_repository( trans,
repository,
encoding_util.tool_shed_encode( repo_info_dict ) )
repository_dict = repository.to_dict( value_mapper=self.__get_value_mapper( trans, repository ) )
repository_dict[ 'url' ] = web.url_for( controller='tool_shed_repositories',
action='show',
id=trans.security.encode_id( repository.id ) )
if repair_dict:
errors = repair_dict.get( repository.name, [] )
repository_dict[ 'errors_attempting_repair' ] = ' '.join( errors )
tool_shed_repositories.append( repository_dict )
# Display the list of repaired repositories.
return tool_shed_repositories
@web.expose_api
def reset_metadata_on_installed_repositories( self, trans, payload, **kwd ):
"""
PUT /api/tool_shed_repositories/reset_metadata_on_installed_repositories
Resets all metadata on all repositories installed into Galaxy in an "orderly fashion".
:param key: the API key of the Galaxy admin user.
"""
start_time = strftime( "%Y-%m-%d %H:%M:%S" )
results = dict( start_time=start_time,
successful_count=0,
unsuccessful_count=0,
repository_status=[] )
# Make sure the current user's API key proves he is an admin user in this Galaxy instance.
if not trans.user_is_admin():
raise HTTPForbidden( detail='You are not authorized to reset metadata on repositories installed into this Galaxy instance.' )
query = suc.get_query_for_setting_metadata_on_repositories( trans, my_writable=False, order=False )
# Now reset metadata on all remaining repositories.
for repository in query:
repository_id = trans.security.encode_id( repository.id )
try:
invalid_file_tups, metadata_dict = metadata_util.reset_all_metadata_on_installed_repository( trans, repository_id )
if invalid_file_tups:
message = tool_util.generate_message_for_invalid_tools( trans,
invalid_file_tups,
repository,
None,
as_html=False )
results[ 'unsuccessful_count' ] += 1
else:
message = "Successfully reset metadata on repository %s owned by %s" % \
( str( repository.name ), str( repository.owner ) )
results[ 'successful_count' ] += 1
except Exception, e:
message = "Error resetting metadata on repository %s owned by %s: %s" % \
( str( repository.name ), str( repository.owner ), str( e ) )
results[ 'unsuccessful_count' ] += 1
results[ 'repository_status' ].append( message )
stop_time = strftime( "%Y-%m-%d %H:%M:%S" )
results[ 'stop_time' ] = stop_time
return json.to_json_string( results, sort_keys=True, indent=4 )
@web.expose_api
def show( self, trans, id, **kwd ):
"""
GET /api/tool_shed_repositories/{encoded_tool_shed_repsository_id}
Display a dictionary containing information about a specified tool_shed_repository.
:param id: the encoded id of the ToolShedRepository object
"""
# Example URL: http://localhost:8763/api/tool_shed_repositories/df7a1f0c02a5b08e
tool_shed_repository = suc.get_tool_shed_repository_by_id( trans, id )
if tool_shed_repository is None:
log.debug( "Unable to locate tool_shed_repository record for id %s." % ( str( id ) ) )
return {}
tool_shed_repository_dict = tool_shed_repository.as_dict( value_mapper=self.__get_value_mapper( trans, tool_shed_repository ) )
tool_shed_repository_dict[ 'url' ] = web.url_for( controller='tool_shed_repositories',
action='show',
id=trans.security.encode_id( tool_shed_repository.id ) )
return tool_shed_repository_dict