|
1 | 1 | import os
|
2 | 2 | import json
|
| 3 | +import subprocess |
| 4 | +import yaml |
| 5 | +from urllib import urlopen |
3 | 6 |
|
4 |
| - |
5 |
| -def wf_type(workflow_file): |
6 |
| - if workflow_file.lower().endswith('wdl'): |
7 |
| - return 'WDL' |
8 |
| - elif workflow_file.lower().endswith('cwl'): |
9 |
| - return 'CWL' |
10 |
| - elif workflow_file.lower().endswith('py'): |
11 |
| - return 'PY' |
12 |
| - else: |
13 |
| - raise ValueError('Unrecognized/unsupported workflow file extension: %s' % workflow_file.lower().split('.')[-1]) |
| 7 | +def _twoSevenCompatible(filePath): |
| 8 | + """Determines if a python file is 2.7 compatible by seeing if it compiles in a subprocess""" |
| 9 | + try: |
| 10 | + passes = not subprocess.call(['python2', '-m', 'py_compile', filePath]) |
| 11 | + except: |
| 12 | + raise RuntimeError('Python files must be 2.7 compatible') |
| 13 | + return passes |
14 | 14 |
|
15 | 15 |
|
16 |
| -def wf_version(workflow_file): |
17 |
| - # TODO: Check inside of the file, handling local/http/etc. |
18 |
| - if wf_type(workflow_file) == 'PY': |
| 16 | +def _getVersion(extension, workflow_file): |
| 17 | + '''Determines the version of a .py, .wdl, or .cwl file.''' |
| 18 | + if extension == 'py' and _twoSevenCompatible(workflow_file): |
19 | 19 | return '2.7'
|
20 |
| - # elif wf_type(workflow_file) == 'CWL': |
21 |
| - # # only works locally |
22 |
| - # return yaml.load(open(workflow_file))['cwlVersion'] |
| 20 | + elif extension == 'cwl': |
| 21 | + return yaml.load(open(workflow_file))['cwlVersion'] |
| 22 | + else: # Must be a wdl file. |
| 23 | + # Borrowed from https://github.com/Sage-Bionetworks/synapse-orchestrator/blob/develop/synorchestrator/util.py#L142 |
| 24 | + try: |
| 25 | + return [l.lstrip('version') for l in workflow_file.splitlines() if 'version' in l.split(' ')][0] |
| 26 | + except IndexError: |
| 27 | + return 'draft-2' |
| 28 | + |
| 29 | + |
| 30 | +def wf_info(workflow_file): |
| 31 | + """ |
| 32 | + Returns the version of the file and the file extension. |
| 33 | +
|
| 34 | + Assumes that the file path is to the file directly ie, ends with a valid file extension.Supports checking local |
| 35 | + files as well as files at http:// and https:// locations. Files at these remote locations are recreated locally to |
| 36 | + enable our approach to version checking, then removed after version is extracted. |
| 37 | + """ |
| 38 | + |
| 39 | + supportedFormats = ['py', 'wdl', 'cwl'] |
| 40 | + fileType = workflow_file.lower().split('.')[-1] # Grab the file extension |
| 41 | + workflow_file = workflow_file if ':' in workflow_file else 'file://' + workflow_file |
| 42 | + |
| 43 | + if fileType in supportedFormats: |
| 44 | + if workflow_file.startswith('file://'): |
| 45 | + version = _getVersion(fileType, workflow_file[7:]) |
| 46 | + elif workflow_file.startswith('https://') or workflow_file.startswith('http://'): # If file not local go fetch it. |
| 47 | + html = urlopen(workflow_file).read() |
| 48 | + localLoc = os.path.join(os.getcwd(), 'fetchedFromRemote.' + fileType) |
| 49 | + with open(localLoc, 'w') as f: |
| 50 | + f.write(html) |
| 51 | + version = wf_info('file://' + localLoc)[0] # Dont take the filetype here. |
| 52 | + os.remove(localLoc) # TODO: Find a way to avoid recreating file before version determination. |
| 53 | + else: |
| 54 | + raise NotImplementedError('Unsupported workflow file location: {}. Must be local or HTTP(S).'.format(workflow_file)) |
23 | 55 | else:
|
24 |
| - # TODO: actually check the wdl file |
25 |
| - return "v1.0" |
| 56 | + raise TypeError('Unsupported workflow type: .{}. Must be {}.'.format(fileType, '.py, .cwl, or .wdl')) |
| 57 | + return version, fileType.upper() |
26 | 58 |
|
27 | 59 |
|
28 | 60 | def build_wes_request(workflow_file, json_path, attachments=None):
|
|
0 commit comments