-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat:
DANKMIDS_DEBUG
env to record failures to csv (#175)
- Loading branch information
1 parent
eedfb20
commit f2e775a
Showing
7 changed files
with
125 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
"""This module is private for now but will eventually be made public when the api ossifies""" | ||
|
||
from dank_mids._debugging import failures | ||
|
||
__all__ = ['failures'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
|
||
import abc | ||
import logging | ||
import os | ||
from functools import cached_property, lru_cache | ||
from typing import Any, Iterable | ||
|
||
import aiofiles | ||
from aiofiles.base import AiofilesContextManager | ||
from aiofiles.threadpool.text import AsyncTextIOWrapper | ||
from async_lru import alru_cache | ||
|
||
logger = logging.getLogger("dank_mids.debugging") | ||
|
||
class _FileHelper(metaclass=abc.ABCMeta): | ||
path = f"{os.path.expanduser( '~' )}/.dank_mids/debug" | ||
def __init__(self, chainid: int): | ||
if not isinstance(chainid, int): | ||
raise TypeError(f"`chainid` must be an integer. You passed {chainid}") from None | ||
self.chainid = chainid | ||
self.path = self.path + f"/{self.chainid}" | ||
self.ensure_dir() | ||
@lru_cache(maxsize=1) | ||
def ensure_dir(self) -> None: | ||
os.makedirs(self.path, exist_ok=True) | ||
def open(self) -> "AiofilesContextManager[None, None, AsyncTextIOWrapper]": | ||
logger.info("opening %s with mode %s", self.uri, self.mode) | ||
return aiofiles.open(self.uri, self.mode) | ||
@abc.abstractproperty | ||
def uri(self) -> str: | ||
... | ||
@abc.abstractproperty | ||
def mode(self) -> str: | ||
... | ||
|
||
class _CSVWriter(_FileHelper): | ||
mode = "a" | ||
@cached_property | ||
def uri(self) -> str: | ||
return f"{self.path}/{self.filename}" | ||
async def write_row(self, *values: Any) -> None: | ||
await self._ensure_headers() | ||
await self._write_row(*values) | ||
@alru_cache(maxsize=None) | ||
async def _ensure_headers(self) -> None: | ||
await self._write_row(*self.column_names, new_line=False) | ||
async def _write_row(self, *values: Any, new_line: bool = True) -> None: | ||
row = ','.join(str(obj) for obj in values) | ||
if new_line: | ||
row = f'\n{row}' | ||
async with self.open() as file: | ||
logger.debug("writing row %s to file %s", row, file) | ||
await file.write(row) | ||
@abc.abstractproperty | ||
def filename(self) -> str: | ||
... | ||
@abc.abstractproperty | ||
def column_names(self) -> Iterable[str]: | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
from datetime import datetime | ||
from functools import cached_property, lru_cache | ||
from typing import TYPE_CHECKING, List, Type, Union | ||
|
||
from a_sync import ProcessingQueue | ||
|
||
from dank_mids._debugging._base import _CSVWriter | ||
|
||
if TYPE_CHECKING: | ||
from dank_mids.types import PartialRequest, Request | ||
|
||
@lru_cache(maxsize=None) | ||
class FailedRequestWriter(_CSVWriter): | ||
column_names = "request_type", "request_uid", "error", "request_data" | ||
def __init__(self, chainid: int, failure_type: Type[BaseException]): | ||
super().__init__(chainid) | ||
if not issubclass(failure_type, BaseException): | ||
raise TypeError(f"`failure_type` must be an Exception type. You passed {failure_type}") | ||
self.failure_type = failure_type | ||
self.record_failure = ProcessingQueue(self._record_failure, num_workers=1, return_data=True) | ||
@cached_property | ||
def filename(self) -> str: | ||
return f"{int(datetime.now().timestamp())}_{self.failure_type.__name__}s.csv" | ||
async def _record_failure(self, e: Exception, request_type: str, request_uid: Union[str, int], request_data: Union[List["Request"], List["PartialRequest"], bytes]): | ||
if not isinstance(e, self.failure_type): | ||
raise TypeError(e, self.failure_type) | ||
await self.write_row(request_type, request_uid, e, request_data) | ||
|
||
def record(chainid: int, e: Exception, request_type: str, request_uid: Union[int, str], request_data: Union[List["Request"], List["PartialRequest"], bytes]) -> None: | ||
FailedRequestWriter(chainid, type(e)).record_failure(e, request_type, request_uid, request_data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters