Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/smart_open/transport.py: 92%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

51 statements  

1# -*- coding: utf-8 -*- 

2# 

3# Copyright (C) 2020 Radim Rehurek <me@radimrehurek.com> 

4# 

5# This code is distributed under the terms and conditions 

6# from the MIT License (MIT). 

7# 

8"""Maintains a registry of transport mechanisms. 

9 

10The main entrypoint is :func:`get_transport`. See also :file:`extending.md`. 

11 

12""" 

13import importlib 

14import logging 

15 

16import smart_open.local_file 

17 

18logger = logging.getLogger(__name__) 

19 

20NO_SCHEME = '' 

21 

22_REGISTRY = {NO_SCHEME: smart_open.local_file} 

23_ERRORS = {} 

24_MISSING_DEPS_ERROR = """You are trying to use the %(module)s functionality of smart_open 

25but you do not have the correct %(module)s dependencies installed. Try: 

26 

27 pip install smart_open[%(module)s] 

28 

29""" 

30 

31 

32def register_transport(submodule): 

33 """Register a submodule as a transport mechanism for ``smart_open``. 

34 

35 This module **must** have: 

36 

37 - `SCHEME` attribute (or `SCHEMES`, if the submodule supports multiple schemes) 

38 - `open` function 

39 - `open_uri` function 

40 - `parse_uri' function 

41 

42 Once registered, you can get the submodule by calling :func:`get_transport`. 

43 

44 """ 

45 module_name = submodule 

46 if isinstance(submodule, str): 

47 try: 

48 submodule = importlib.import_module(submodule) 

49 except ImportError: 

50 return 

51 else: 

52 module_name = submodule.__name__ 

53 # Save only the last module name piece 

54 module_name = module_name.rsplit(".")[-1] 

55 

56 if hasattr(submodule, "SCHEME"): 

57 schemes = [submodule.SCHEME] 

58 elif hasattr(submodule, "SCHEMES"): 

59 schemes = submodule.SCHEMES 

60 else: 

61 raise ValueError("%r does not have a .SCHEME or .SCHEMES attribute" % submodule) 

62 

63 for f in ("open", "open_uri", "parse_uri"): 

64 assert hasattr(submodule, f), "%r is missing %r" % (submodule, f) 

65 

66 for scheme in schemes: 

67 assert scheme not in _REGISTRY 

68 if getattr(submodule, "MISSING_DEPS", False): 

69 _ERRORS[scheme] = module_name 

70 else: 

71 _REGISTRY[scheme] = submodule 

72 

73 

74def get_transport(scheme): 

75 """Get the submodule that handles transport for the specified scheme. 

76 

77 This submodule must have been previously registered via :func:`register_transport`. 

78 

79 """ 

80 expected = SUPPORTED_SCHEMES 

81 readme_url = ( 

82 "https://github.com/piskvorky/smart_open/blob/master/README.rst" 

83 ) 

84 message = ( 

85 "Unable to handle scheme %(scheme)r, expected one of %(expected)r. " 

86 "Extra dependencies required by %(scheme)r may be missing. " 

87 "See <%(readme_url)s> for details." % locals() 

88 ) 

89 if scheme in _ERRORS: 

90 raise ImportError(_MISSING_DEPS_ERROR % dict(module=_ERRORS[scheme])) 

91 if scheme in _REGISTRY: 

92 return _REGISTRY[scheme] 

93 raise NotImplementedError(message) 

94 

95 

96register_transport(smart_open.local_file) 

97register_transport("smart_open.azure") 

98register_transport("smart_open.ftp") 

99register_transport("smart_open.gcs") 

100register_transport("smart_open.hdfs") 

101register_transport("smart_open.http") 

102register_transport("smart_open.s3") 

103register_transport("smart_open.ssh") 

104register_transport("smart_open.webhdfs") 

105 

106SUPPORTED_SCHEMES = tuple(sorted(_REGISTRY.keys())) 

107"""The transport schemes that the local installation of ``smart_open`` supports."""