Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/smart_open/transport.py: 94%
50 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:57 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:57 +0000
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.
10The main entrypoint is :func:`get_transport`. See also :file:`extending.md`.
12"""
13import importlib
14import logging
16import smart_open.local_file
18logger = logging.getLogger(__name__)
20NO_SCHEME = ''
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:
27 pip install smart_open[%(module)s]
29"""
32def register_transport(submodule):
33 """Register a submodule as a transport mechanism for ``smart_open``.
35 This module **must** have:
37 - `SCHEME` attribute (or `SCHEMES`, if the submodule supports multiple schemes)
38 - `open` function
39 - `open_uri` function
40 - `parse_uri' function
42 Once registered, you can get the submodule by calling :func:`get_transport`.
44 """
45 global _REGISTRY, _ERRORS
46 module_name = submodule
47 if isinstance(submodule, str):
48 try:
49 submodule = importlib.import_module(submodule)
50 except ImportError:
51 return
52 else:
53 module_name = submodule.__name__
54 # Save only the last module name piece
55 module_name = module_name.rsplit(".")[-1]
57 if hasattr(submodule, "SCHEME"):
58 schemes = [submodule.SCHEME]
59 elif hasattr(submodule, "SCHEMES"):
60 schemes = submodule.SCHEMES
61 else:
62 raise ValueError("%r does not have a .SCHEME or .SCHEMES attribute" % submodule)
64 for f in ("open", "open_uri", "parse_uri"):
65 assert hasattr(submodule, f), "%r is missing %r" % (submodule, f)
67 for scheme in schemes:
68 assert scheme not in _REGISTRY
69 if getattr(submodule, "MISSING_DEPS", False):
70 _ERRORS[scheme] = module_name
71 else:
72 _REGISTRY[scheme] = submodule
75def get_transport(scheme):
76 """Get the submodule that handles transport for the specified scheme.
78 This submodule must have been previously registered via :func:`register_transport`.
80 """
81 global _ERRORS, _MISSING_DEPS_ERROR, _REGISTRY, SUPPORTED_SCHEMES
82 expected = SUPPORTED_SCHEMES
83 readme_url = (
84 "https://github.com/RaRe-Technologies/smart_open/blob/master/README.rst"
85 )
86 message = (
87 "Unable to handle scheme %(scheme)r, expected one of %(expected)r. "
88 "Extra dependencies required by %(scheme)r may be missing. "
89 "See <%(readme_url)s> for details." % locals()
90 )
91 if scheme in _ERRORS:
92 raise ImportError(_MISSING_DEPS_ERROR % dict(module=_ERRORS[scheme]))
93 if scheme in _REGISTRY:
94 return _REGISTRY[scheme]
95 raise NotImplementedError(message)
98register_transport(smart_open.local_file)
99register_transport("smart_open.azure")
100register_transport("smart_open.ftp")
101register_transport("smart_open.gcs")
102register_transport("smart_open.hdfs")
103register_transport("smart_open.http")
104register_transport("smart_open.s3")
105register_transport("smart_open.ssh")
106register_transport("smart_open.webhdfs")
108SUPPORTED_SCHEMES = tuple(sorted(_REGISTRY.keys()))
109"""The transport schemes that the local installation of ``smart_open`` supports."""