Compare commits
7 Commits
795dd9b5bd
...
600e58eb90
Author | SHA1 | Date | |
---|---|---|---|
600e58eb90 | |||
815aaca336 | |||
478f62cc08 | |||
cb53b5f719 | |||
fbb6ec9666 | |||
99daeb6ba0 | |||
f1d37d8eb4 |
71
README.md
71
README.md
@ -0,0 +1,71 @@
|
|||||||
|
# Example code
|
||||||
|
```python
|
||||||
|
# client.py
|
||||||
|
from api_client import BaseAPIClient
|
||||||
|
|
||||||
|
|
||||||
|
class LocalClient(BaseAPIClient):
|
||||||
|
name = "local"
|
||||||
|
_base_url = "https://obligari.serveo.net/ping/local"
|
||||||
|
|
||||||
|
def __init__(self, nonce=None):
|
||||||
|
super().__init__(nonce)
|
||||||
|
self._session.headers.update(
|
||||||
|
{"User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:123.0) Gecko/20100101 Firefox/123.0"}
|
||||||
|
)
|
||||||
|
|
||||||
|
def send_post_ping(self, var1: str, var2: int) -> bool:
|
||||||
|
res = self.post("/some-post", json={"variable_one": var1, "second_variable": var2})
|
||||||
|
return res.json().get("status")
|
||||||
|
|
||||||
|
def send_put_ping(self, var1: str, var2: int) -> bool:
|
||||||
|
res = self.put("/some-put", data={"variable_one": var1, "second_variable": var2})
|
||||||
|
return res.json().get("status")
|
||||||
|
|
||||||
|
def send_get_ping(self, var1: str, var2: int) -> bool:
|
||||||
|
res = self.get("/some-get", params={"variable_one": var1, "second_variable": var2})
|
||||||
|
return res.json().get("status")
|
||||||
|
|
||||||
|
def send_patch_ping(self, var1: str, var2: int) -> bool:
|
||||||
|
res = self.put("/some-patch", data=(("variable_one", var1), ("variable_one", var2)))
|
||||||
|
return res.json().get("status")
|
||||||
|
|
||||||
|
def send_trace_ping(self, var1: str, var2: int) -> bool:
|
||||||
|
res = self.trace("/some-trace", params=(("variable_one", var1), ("variable_one", var2)))
|
||||||
|
return res.json().get("status")
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
# main.py
|
||||||
|
from .client import LocalClient
|
||||||
|
|
||||||
|
|
||||||
|
client = LocalClient()
|
||||||
|
client.send_post_ping("asd", 123)
|
||||||
|
client.send_put_ping("asd", 123)
|
||||||
|
client.send_get_ping("asd", 123)
|
||||||
|
client.send_patch_ping("asd", 123)
|
||||||
|
client.send_trace_ping("asd", 123)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Log output
|
||||||
|
### Simple
|
||||||
|
```text
|
||||||
|
[14d709e02c0c] Preparing POST request to "https://obligari.serveo.net/ping/local/some-post"
|
||||||
|
[14d709e02c0c] Sending request with payload=b'{"variable_one": "asd", "second_variable": 123}'
|
||||||
|
[14d709e02c0c] Response response.status_code=200 str_repr_content='{"status":true,"request_id":62}'
|
||||||
|
[14d709e02c0c] Preparing GET request to "https://obligari.serveo.net/ping/local/some-get"
|
||||||
|
[14d709e02c0c] Sending request with payload=None
|
||||||
|
[14d709e02c0c] Response response.status_code=200 str_repr_content='{"status":true,"request_id":63}'
|
||||||
|
```
|
||||||
|
### Structured
|
||||||
|
```json
|
||||||
|
{"app": "dev", "level": "DEBUG", "name": "APIClient", "date_time": "2024-03-09 22:59:24", "location": "api_client/client.py:_request:71", "message": "[cfbdadc56f53] Preparing POST request to \"https://obligari.serveo.net/ping/local/some-post\"", "extra_data": {"hooks": {"response": []}, "method": "POST", "url": "https://obligari.serveo.net/ping/local/some-post", "headers": {}, "files": [], "data": [], "json": {"variable_one": "asd", "second_variable": 123}, "params": {}, "auth": null, "cookies": null}}
|
||||||
|
{"app": "dev", "level": "INFO", "name": "APIClient", "date_time": "2024-03-09 22:59:24", "location": "api_client/client.py:_request:74", "message": "[cfbdadc56f53] Sending request with payload=b'{\"variable_one\": \"asd\", \"second_variable\": 123}'", "extra_data": {"payload": "{\"variable_one\": \"asd\", \"second_variable\": 123}"}}
|
||||||
|
{"app": "dev", "level": "INFO", "name": "APIClient", "date_time": "2024-03-09 22:59:25", "location": "api_client/client.py:_request:81", "message": "[cfbdadc56f53] Response response.status_code=200 str_repr_content='{\"status\":true,\"request_id\":72}'", "extra_data": {"status_code": 200, "content": "{\"status\":true,\"request_id\":72}"}}
|
||||||
|
{"app": "dev", "level": "DEBUG", "name": "APIClient", "date_time": "2024-03-09 22:59:25", "location": "api_client/client.py:_request:71", "message": "[cfbdadc56f53] Preparing GET request to \"https://obligari.serveo.net/ping/local/some-get\"", "extra_data": {"hooks": {"response": []}, "method": "GET", "url": "https://obligari.serveo.net/ping/local/some-get", "headers": {}, "files": [], "data": [], "json": null, "params": {"variable_one": "asd", "second_variable": 123}, "auth": null, "cookies": null}}
|
||||||
|
{"app": "dev", "level": "INFO", "name": "APIClient", "date_time": "2024-03-09 22:59:25", "location": "api_client/client.py:_request:74", "message": "[cfbdadc56f53] Sending request with payload=None", "extra_data": {"payload": "{}"}}
|
||||||
|
{"app": "dev", "level": "INFO", "name": "APIClient", "date_time": "2024-03-09 22:59:25", "location": "api_client/client.py:_request:81", "message": "[cfbdadc56f53] Response response.status_code=200 str_repr_content='{\"status\":true,\"request_id\":74}'", "extra_data": {"status_code": 200, "content": "{\"status\":true,\"request_id\":73}"}}
|
||||||
|
```
|
||||||
|
@ -44,7 +44,7 @@ version = { attr = "api_client.__version__" }
|
|||||||
|
|
||||||
|
|
||||||
[tool.bumpversion]
|
[tool.bumpversion]
|
||||||
current_version = "0.1.5"
|
current_version = "0.1.8"
|
||||||
commit = true
|
commit = true
|
||||||
tag = true
|
tag = true
|
||||||
tag_name = "v{new_version}"
|
tag_name = "v{new_version}"
|
||||||
|
@ -1,29 +1,4 @@
|
|||||||
import logging.config
|
|
||||||
|
|
||||||
from .client import BaseAPIClient
|
from .client import BaseAPIClient
|
||||||
|
|
||||||
__version__ = "0.1.5"
|
__version__ = "0.1.8"
|
||||||
__all__ = ["BaseAPIClient"]
|
__all__ = ["BaseAPIClient"]
|
||||||
|
|
||||||
LOGGING: dict = {
|
|
||||||
"version": 1,
|
|
||||||
"disable_existing_loggers": False,
|
|
||||||
"filters": {},
|
|
||||||
"formatters": {
|
|
||||||
"api-client.structured": {
|
|
||||||
"()": "api_client.utils.APIClientLogJSONFormatter",
|
|
||||||
},
|
|
||||||
"api-client.simple": {
|
|
||||||
"format": "[%(asctime)s] %(levelname)s: %(message)s",
|
|
||||||
"datefmt": "%F %T",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"handlers": {
|
|
||||||
"api-client.structured": {
|
|
||||||
"level": "DEBUG",
|
|
||||||
"class": "logging.StreamHandler",
|
|
||||||
"formatter": "api-client.structured",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
logging.config.dictConfig(LOGGING)
|
|
||||||
|
@ -21,14 +21,32 @@ class BaseAPIClient(ABC):
|
|||||||
self._session = requests.Session()
|
self._session = requests.Session()
|
||||||
self._logger = get_logger("APIClient")
|
self._logger = get_logger("APIClient")
|
||||||
|
|
||||||
|
def get(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
|
return self._request("GET", endpoint, params=params, **kwargs)
|
||||||
|
|
||||||
def post(self, endpoint: str, *, json: Any = None, data: Any = None, **kwargs: Any) -> requests.Response:
|
def post(self, endpoint: str, *, json: Any = None, data: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
return self._request("POST", endpoint, json=json, data=data, **kwargs)
|
return self._request("POST", endpoint, json=json, data=data, **kwargs)
|
||||||
|
|
||||||
def put(self, endpoint: str, *, json: Any = None, data: Any = None, **kwargs: Any) -> requests.Response:
|
def put(self, endpoint: str, *, json: Any = None, data: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
return self._request("PUT", endpoint, json=json, data=data, **kwargs)
|
return self._request("PUT", endpoint, json=json, data=data, **kwargs)
|
||||||
|
|
||||||
def get(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
def patch(self, endpoint: str, *, json: Any = None, data: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
return self._request("GET", endpoint, params=params, **kwargs)
|
return self._request("PATCH", endpoint, json=json, data=data, **kwargs)
|
||||||
|
|
||||||
|
def delete(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
|
return self._request("DELETE", endpoint, params=params, **kwargs)
|
||||||
|
|
||||||
|
def head(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
|
return self._request("HEAD", endpoint, params=params, **kwargs)
|
||||||
|
|
||||||
|
def options(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
|
return self._request("OPTIONS", endpoint, params=params, **kwargs)
|
||||||
|
|
||||||
|
def trace(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
|
return self._request("TRACE", endpoint, params=params, **kwargs)
|
||||||
|
|
||||||
|
def connect(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
||||||
|
return self._request("CONNECT", endpoint, params=params, **kwargs)
|
||||||
|
|
||||||
def _make_full_url(self, endpoint: str) -> str:
|
def _make_full_url(self, endpoint: str) -> str:
|
||||||
return f"{self._base_url}{endpoint}"
|
return f"{self._base_url}{endpoint}"
|
||||||
@ -70,13 +88,16 @@ class BaseAPIClient(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def _info(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
def _info(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||||
self._logger.info(f"[{self._nonce}] {msg}", *args, **kwargs)
|
self._logger.info(f"[{self._nonce}] {msg}", *args, stacklevel=2, **kwargs)
|
||||||
|
|
||||||
def _debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
def _debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||||
self._logger.debug(f"[{self._nonce}] {msg}", *args, **kwargs)
|
self._logger.debug(f"[{self._nonce}] {msg}", *args, stacklevel=2, **kwargs)
|
||||||
|
|
||||||
def _warn(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
def _warn(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||||
self._logger.warning(f"[{self._nonce}] {msg}", *args, **kwargs)
|
self._logger.warning(f"[{self._nonce}] {msg}", *args, stacklevel=2, **kwargs)
|
||||||
|
|
||||||
def _error(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
def _error(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||||
self._logger.error(f"[{self._nonce}] {msg}", *args, **kwargs)
|
self._logger.error(f"[{self._nonce}] {msg}", *args, stacklevel=2, **kwargs)
|
||||||
|
|
||||||
|
def _critical(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||||
|
self._logger.critical(f"[{self._nonce}] {msg}", *args, stacklevel=2, **kwargs)
|
||||||
|
@ -49,6 +49,7 @@ class APIClientLogJSONFormatter(logging.Formatter):
|
|||||||
"levelname",
|
"levelname",
|
||||||
"levelno",
|
"levelno",
|
||||||
"pathname",
|
"pathname",
|
||||||
|
"exc_info",
|
||||||
"filename",
|
"filename",
|
||||||
"lineno",
|
"lineno",
|
||||||
"funcName",
|
"funcName",
|
||||||
@ -61,15 +62,18 @@ class APIClientLogJSONFormatter(logging.Formatter):
|
|||||||
"process",
|
"process",
|
||||||
"message",
|
"message",
|
||||||
"asctime",
|
"asctime",
|
||||||
|
"module",
|
||||||
|
"exc_text",
|
||||||
|
"stack_info",
|
||||||
]
|
]
|
||||||
structured_data = dict(
|
structured_data = dict(
|
||||||
app=os.environ.get("PROJECT_NAME", "dev"),
|
app=os.environ.get("APP_NAME", "dev"),
|
||||||
level=record.levelname,
|
level=record.levelname,
|
||||||
name=record.name,
|
name=record.name,
|
||||||
date_time=datetime.datetime.fromtimestamp(record.created).strftime(self.default_time_format),
|
date_time=datetime.datetime.fromtimestamp(record.created).strftime(self.default_time_format),
|
||||||
location=f"{record.pathname or record.filename}:{record.funcName}:{record.lineno}",
|
location=f"{record.pathname or record.filename}:{record.funcName}:{record.lineno}",
|
||||||
message=record.getMessage(),
|
message=record.getMessage(),
|
||||||
|
extra_data={k: record.__dict__[k] for k in record.__dict__.keys() if k not in record_default_keys},
|
||||||
)
|
)
|
||||||
structured_data.update(**{k: record.__dict__[k] for k in record.__dict__.keys() if k not in record_default_keys})
|
|
||||||
|
|
||||||
return json.dumps(structured_data, cls=APIClientJSONEncoder)
|
return json.dumps(structured_data, cls=APIClientJSONEncoder)
|
||||||
|
Reference in New Issue
Block a user