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]
|
||||
current_version = "0.1.5"
|
||||
current_version = "0.1.8"
|
||||
commit = true
|
||||
tag = true
|
||||
tag_name = "v{new_version}"
|
||||
|
@ -1,29 +1,4 @@
|
||||
import logging.config
|
||||
|
||||
from .client import BaseAPIClient
|
||||
|
||||
__version__ = "0.1.5"
|
||||
__version__ = "0.1.8"
|
||||
__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._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:
|
||||
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:
|
||||
return self._request("PUT", endpoint, json=json, data=data, **kwargs)
|
||||
|
||||
def get(self, endpoint: str, *, params: Any = None, **kwargs: Any) -> requests.Response:
|
||||
return self._request("GET", endpoint, params=params, **kwargs)
|
||||
def patch(self, endpoint: str, *, json: Any = None, data: Any = None, **kwargs: Any) -> requests.Response:
|
||||
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:
|
||||
return f"{self._base_url}{endpoint}"
|
||||
@ -70,13 +88,16 @@ class BaseAPIClient(ABC):
|
||||
pass
|
||||
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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",
|
||||
"levelno",
|
||||
"pathname",
|
||||
"exc_info",
|
||||
"filename",
|
||||
"lineno",
|
||||
"funcName",
|
||||
@ -61,15 +62,18 @@ class APIClientLogJSONFormatter(logging.Formatter):
|
||||
"process",
|
||||
"message",
|
||||
"asctime",
|
||||
"module",
|
||||
"exc_text",
|
||||
"stack_info",
|
||||
]
|
||||
structured_data = dict(
|
||||
app=os.environ.get("PROJECT_NAME", "dev"),
|
||||
app=os.environ.get("APP_NAME", "dev"),
|
||||
level=record.levelname,
|
||||
name=record.name,
|
||||
date_time=datetime.datetime.fromtimestamp(record.created).strftime(self.default_time_format),
|
||||
location=f"{record.pathname or record.filename}:{record.funcName}:{record.lineno}",
|
||||
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)
|
||||
|
Reference in New Issue
Block a user