Try to detect if an object is a file type on python python 2 & 3.
[htsworkflow.git] / htsworkflow / util / opener.py
1 """
2 Helpful utilities for turning random names/objects into streams.
3 """
4 import os
5 import gzip
6 import bz2
7 import six
8 from six.moves import urllib
9
10 if six.PY2:
11     import types
12     FILE_CLASS = types.FileType
13 else:
14     import io
15     FILE_CLASS = io.IOBase
16
17 def isfilelike(file_ref, mode):
18     """Does file_ref have the core file operations?
19     """
20     # if mode is w/a check to make sure we writeable ops
21     # but always check to see if we can read
22     read_operations = ['read', 'readline', 'readlines']
23     write_operations = [ 'write', 'writelines' ]
24     #random_operations = [ 'seek', 'tell' ]
25     if mode[0] in ('w', 'a'):
26         for o in write_operations:
27             if not hasattr(file_ref, o):
28                 return False
29     for o in read_operations:
30         if not hasattr(file_ref, o):
31             return False
32           
33     return True
34
35 def isurllike(file_ref, mode):
36     """
37     does file_ref look like a url?
38     (AKA does it start with protocol:// ?)
39     """
40     #what if mode is 'w'?
41     parsed = urllib.parse.urlparse(file_ref)
42     schema, netloc, path, params, query, fragment = parsed
43     
44     return len(schema) > 0
45
46 def autoopen(file_ref, mode='r'):
47     """
48     Attempt to intelligently turn file_ref into a readable stream
49     """
50     # catch being passed a file
51     if isinstance(file_ref, FILE_CLASS):
52         return file_ref
53     # does it look like a file?
54     elif isfilelike(file_ref, mode):
55         return file_ref
56     elif isurllike(file_ref, mode):
57         return urllib.request.urlopen(file_ref)
58     elif os.path.splitext(file_ref)[1] == ".gz":
59         return gzip.open(file_ref, mode)
60     elif os.path.splitext(file_ref)[1] == '.bz2':
61         return bz2.BZ2File(file_ref, mode)
62     else:
63         return open(file_ref,mode)
64