diff --git a/httpie/output/processing.py b/httpie/output/processing.py index 850c6810..98270985 100644 --- a/httpie/output/processing.py +++ b/httpie/output/processing.py @@ -1,6 +1,7 @@ import re +from typing import Optional, List -from httpie.plugins import plugin_manager +from httpie.plugins import plugin_manager, ConverterPlugin from httpie.context import Environment @@ -13,7 +14,8 @@ def is_valid_mime(mime): class Conversion: - def get_converter(self, mime): + @staticmethod + def get_converter(mime: str) -> Optional[ConverterPlugin]: if is_valid_mime(mime): for converter_class in plugin_manager.get_converters(): if converter_class.supports(mime): @@ -23,7 +25,7 @@ class Conversion: class Formatting: """A delegate class that invokes the actual processors.""" - def __init__(self, groups, env=Environment(), **kwargs): + def __init__(self, groups: List[str], env=Environment(), **kwargs): """ :param groups: names of processor groups to be applied :param env: Environment diff --git a/httpie/plugins/__init__.py b/httpie/plugins/__init__.py index 13b85650..38c2a66c 100644 --- a/httpie/plugins/__init__.py +++ b/httpie/plugins/__init__.py @@ -1,6 +1,6 @@ """ WARNING: The plugin API is still work in progress and will - probably be completely reworked by v1.0.0. + probably be completely reworked in the future. """ from httpie.plugins.base import ( @@ -15,8 +15,10 @@ from httpie.output.formatters.colors import ColorFormatter plugin_manager = PluginManager() -plugin_manager.register(BasicAuthPlugin, - DigestAuthPlugin) -plugin_manager.register(HeadersFormatter, - JSONFormatter, - ColorFormatter) +plugin_manager.register( + BasicAuthPlugin, + DigestAuthPlugin, + HeadersFormatter, + JSONFormatter, + ColorFormatter, +) diff --git a/httpie/plugins/base.py b/httpie/plugins/base.py index ef1475fd..5dc3bf1f 100644 --- a/httpie/plugins/base.py +++ b/httpie/plugins/base.py @@ -75,7 +75,7 @@ class TransportPlugin(BasePlugin): raise NotImplementedError() -class ConverterPlugin: +class ConverterPlugin(BasePlugin): def __init__(self, mime): self.mime = mime @@ -88,7 +88,7 @@ class ConverterPlugin: raise NotImplementedError -class FormatterPlugin: +class FormatterPlugin(BasePlugin): def __init__(self, **kwargs): """ @@ -100,7 +100,7 @@ class FormatterPlugin: self.enabled = True self.kwargs = kwargs - def format_headers(self, headers): + def format_headers(self, headers: str) -> str: """Return processed `headers` :param headers: The headers as text. @@ -108,7 +108,7 @@ class FormatterPlugin: """ return headers - def format_body(self, content, mime): + def format_body(self, content: str, mime: str) -> str: """Return processed `content`. :param mime: E.g., 'application/atom+xml'. diff --git a/httpie/plugins/builtin.py b/httpie/plugins/builtin.py index eb7b9fc0..1a01c902 100644 --- a/httpie/plugins/builtin.py +++ b/httpie/plugins/builtin.py @@ -7,37 +7,38 @@ from httpie.plugins.base import AuthPlugin # noinspection PyAbstractClass class BuiltinAuthPlugin(AuthPlugin): - package_name = '(builtin)' class HTTPBasicAuth(requests.auth.HTTPBasicAuth): - def __call__(self, r): + def __call__( + self, + request: requests.PreparedRequest + ) -> requests.PreparedRequest: """ Override username/password serialization to allow unicode. See https://github.com/jakubroztocil/httpie/issues/212 """ - r.headers['Authorization'] = type(self).make_header( + request.headers['Authorization'] = type(self).make_header( self.username, self.password).encode('latin1') - return r + return request @staticmethod - def make_header(username, password): + def make_header(username: str, password: str) -> str: credentials = u'%s:%s' % (username, password) token = b64encode(credentials.encode('utf8')).strip().decode('latin1') return 'Basic %s' % token class BasicAuthPlugin(BuiltinAuthPlugin): - name = 'Basic HTTP auth' auth_type = 'basic' # noinspection PyMethodOverriding - def get_auth(self, username, password): + def get_auth(self, username: str, password: str) -> HTTPBasicAuth: return HTTPBasicAuth(username, password) @@ -47,5 +48,9 @@ class DigestAuthPlugin(BuiltinAuthPlugin): auth_type = 'digest' # noinspection PyMethodOverriding - def get_auth(self, username, password): + def get_auth( + self, + username: str, + password: str + ) -> requests.auth.HTTPDigestAuth: return requests.auth.HTTPDigestAuth(username, password) diff --git a/httpie/plugins/manager.py b/httpie/plugins/manager.py index cde0e8ec..8d9bab47 100644 --- a/httpie/plugins/manager.py +++ b/httpie/plugins/manager.py @@ -1,7 +1,9 @@ from itertools import groupby +from typing import Type, Iterable, List, Dict + from pkg_resources import iter_entry_points from httpie.plugins import AuthPlugin, FormatterPlugin, ConverterPlugin -from httpie.plugins.base import TransportPlugin +from httpie.plugins.base import TransportPlugin, BasePlugin ENTRY_POINT_NAMES = [ @@ -20,11 +22,11 @@ class PluginManager: def __iter__(self): return iter(self._plugins) - def register(self, *plugins): + def register(self, *plugins: Type[BasePlugin]): for plugin in plugins: self._plugins.append(plugin) - def unregister(self, plugin): + def unregister(self, plugin: BasePlugin): self._plugins.remove(plugin) def load_installed_plugins(self): @@ -35,21 +37,25 @@ class PluginManager: self.register(entry_point.load()) # Auth - def get_auth_plugins(self): + def get_auth_plugins(self) -> List[Type[AuthPlugin]]: return [plugin for plugin in self if issubclass(plugin, AuthPlugin)] - def get_auth_plugin_mapping(self): - return {plugin.auth_type: plugin for plugin in self.get_auth_plugins()} + def get_auth_plugin_mapping(self) -> Dict[str, Type[AuthPlugin]]: + return { + plugin.auth_type: plugin for plugin in self.get_auth_plugins() + } - def get_auth_plugin(self, auth_type): + def get_auth_plugin(self, auth_type: str) -> Type[AuthPlugin]: return self.get_auth_plugin_mapping()[auth_type] # Output processing - def get_formatters(self): - return [plugin for plugin in self - if issubclass(plugin, FormatterPlugin)] + def get_formatters(self) -> List[Type[FormatterPlugin]]: + return [ + plugin for plugin in self + if issubclass(plugin, FormatterPlugin) + ] - def get_formatters_grouped(self): + def get_formatters_grouped(self) -> Dict[str, List[Type[FormatterPlugin]]]: groups = {} for group_name, group in groupby( self.get_formatters(), @@ -57,11 +63,15 @@ class PluginManager: groups[group_name] = list(group) return groups - def get_converters(self): - return [plugin for plugin in self - if issubclass(plugin, ConverterPlugin)] + def get_converters(self) -> List[Type[ConverterPlugin]]: + return [ + plugin for plugin in self + if issubclass(plugin, ConverterPlugin) + ] # Adapters - def get_transport_plugins(self): - return [plugin for plugin in self - if issubclass(plugin, TransportPlugin)] + def get_transport_plugins(self) -> List[Type[TransportPlugin]]: + return [ + plugin for plugin in self + if issubclass(plugin, TransportPlugin) + ]