1
0
mirror of https://github.com/httpie/cli.git synced 2025-08-10 22:42:05 +02:00

Implement basic metrics layout & total elapsed time (#1250)

* Initial metadata processing

* Dynamic coloring and other stuff

* Use -vv / --meta

* More testing

* Cleanup

* Tweek message

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
This commit is contained in:
Batuhan Taskaya
2021-12-23 23:13:25 +03:00
committed by GitHub
parent e0e03f3237
commit f3b500119c
23 changed files with 334 additions and 94 deletions

View File

@@ -1,11 +1,18 @@
import requests
from enum import Enum, auto
from typing import Iterable, Union
from typing import Iterable, Union, NamedTuple
from urllib.parse import urlsplit
from .utils import split_cookies, parse_content_type_header
from .cli.constants import (
OUT_REQ_BODY,
OUT_REQ_HEAD,
OUT_RESP_BODY,
OUT_RESP_HEAD,
OUT_RESP_META
)
from .compat import cached_property
from .utils import split_cookies, parse_content_type_header
class HTTPMessage:
@@ -27,6 +34,11 @@ class HTTPMessage:
"""Return a `str` with the message's headers."""
raise NotImplementedError
@property
def metadata(self) -> str:
"""Return metadata about the current message."""
raise NotImplementedError
@cached_property
def encoding(self) -> str:
ct, params = parse_content_type_header(self.content_type)
@@ -81,6 +93,15 @@ class HTTPResponse(HTTPMessage):
)
return '\r\n'.join(headers)
@property
def metadata(self) -> str:
data = {}
data['Elapsed time'] = str(self._orig.elapsed.total_seconds()) + 's'
return '\n'.join(
f'{key}: {value}'
for key, value in data.items()
)
class HTTPRequest(HTTPMessage):
"""A :class:`requests.models.Request` wrapper."""
@@ -138,3 +159,50 @@ def infer_requests_message_kind(message: RequestsMessage) -> RequestsMessageKind
return RequestsMessageKind.RESPONSE
else:
raise TypeError(f"Unexpected message type: {type(message).__name__}")
OPTION_TO_PARAM = {
RequestsMessageKind.REQUEST: {
'headers': OUT_REQ_HEAD,
'body': OUT_REQ_BODY,
},
RequestsMessageKind.RESPONSE: {
'headers': OUT_RESP_HEAD,
'body': OUT_RESP_BODY,
'meta': OUT_RESP_META
}
}
class OutputOptions(NamedTuple):
kind: RequestsMessageKind
headers: bool
body: bool
meta: bool = False
def any(self):
return (
self.headers
or self.body
or self.meta
)
@classmethod
def from_message(
cls,
message: RequestsMessage,
raw_args: str = '',
**kwargs
):
kind = infer_requests_message_kind(message)
options = {
option: param in raw_args
for option, param in OPTION_TO_PARAM[kind].items()
}
options.update(kwargs)
return cls(
kind=kind,
**options
)