prediction-market-agent-tooling 0.64.2.dev603__py3-none-any.whl → 0.64.3.dev611__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prediction_market_agent_tooling/loggers.py +45 -42
- prediction_market_agent_tooling/tools/caches/db_cache.py +12 -0
- {prediction_market_agent_tooling-0.64.2.dev603.dist-info → prediction_market_agent_tooling-0.64.3.dev611.dist-info}/METADATA +2 -1
- {prediction_market_agent_tooling-0.64.2.dev603.dist-info → prediction_market_agent_tooling-0.64.3.dev611.dist-info}/RECORD +7 -7
- {prediction_market_agent_tooling-0.64.2.dev603.dist-info → prediction_market_agent_tooling-0.64.3.dev611.dist-info}/WHEEL +1 -1
- {prediction_market_agent_tooling-0.64.2.dev603.dist-info → prediction_market_agent_tooling-0.64.3.dev611.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.64.2.dev603.dist-info → prediction_market_agent_tooling-0.64.3.dev611.dist-info}/entry_points.txt +0 -0
@@ -4,6 +4,7 @@ import sys
|
|
4
4
|
import typing as t
|
5
5
|
import warnings
|
6
6
|
from enum import Enum
|
7
|
+
from pythonjsonlogger import jsonlogger
|
7
8
|
|
8
9
|
from loguru import logger
|
9
10
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
@@ -31,17 +32,35 @@ class LogConfig(BaseSettings):
|
|
31
32
|
LOG_LEVEL: LogLevel = LogLevel.DEBUG
|
32
33
|
|
33
34
|
|
34
|
-
class
|
35
|
-
def
|
36
|
-
|
37
|
-
|
35
|
+
class _CustomJsonFormatter(jsonlogger.JsonFormatter):
|
36
|
+
def add_fields(
|
37
|
+
self,
|
38
|
+
log_record: dict[str, t.Any],
|
39
|
+
record: logging.LogRecord,
|
40
|
+
message_dict: dict[str, t.Any],
|
41
|
+
) -> None:
|
42
|
+
super().add_fields(log_record, record, message_dict)
|
43
|
+
# Include "level" and "severity" with the same value as "levelname" to be friendly with log aggregators.
|
44
|
+
if log_record.get("levelname"):
|
45
|
+
log_record["level"] = log_record["levelname"]
|
46
|
+
log_record["severity"] = log_record["levelname"]
|
47
|
+
|
48
|
+
@staticmethod
|
49
|
+
def get_handler() -> logging.StreamHandler: # type: ignore # Seems correct, but mypy doesn't like it.
|
50
|
+
logHandler = logging.StreamHandler()
|
51
|
+
formatter = _CustomJsonFormatter("%(asctime)s %(levelname)s %(message)s")
|
52
|
+
logHandler.setFormatter(formatter)
|
53
|
+
return logHandler
|
54
|
+
|
55
|
+
|
56
|
+
def _handle_exception(
|
57
|
+
exc_type: type[BaseException], exc_value: BaseException, exc_traceback: t.Any
|
58
|
+
) -> None:
|
59
|
+
if issubclass(exc_type, KeyboardInterrupt):
|
60
|
+
sys.__excepthook__(exc_type, exc_value, exc_traceback)
|
61
|
+
return
|
38
62
|
|
39
|
-
|
40
|
-
"{level:<.1}{time:MMDD HH:mm:ss} {process} {name}:{line}] {message}"
|
41
|
-
)
|
42
|
-
GCP_LOG_LOGGING_FORMAT, GCP_LOG_FORMAT_LOGGING_DATEFMT = (
|
43
|
-
"%(levelname).1s%(asctime)s %(process)d %(name)s:%(lineno)d] %(message)s"
|
44
|
-
), "%m%d %H:%M:%S"
|
63
|
+
logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
|
45
64
|
|
46
65
|
|
47
66
|
def patch_logger() -> None:
|
@@ -57,49 +76,43 @@ def patch_logger() -> None:
|
|
57
76
|
config = LogConfig()
|
58
77
|
|
59
78
|
if config.LOG_FORMAT == LogFormat.GCP:
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
print_logging = print_using_loguru_info
|
64
|
-
handlers: list[logging.Handler] | None = [NoNewLineStreamHandler()]
|
79
|
+
handler = _CustomJsonFormatter.get_handler()
|
80
|
+
print_logging = print_using_logger_info
|
81
|
+
sys.excepthook = _handle_exception
|
65
82
|
|
66
83
|
elif config.LOG_FORMAT == LogFormat.DEFAULT:
|
67
|
-
|
84
|
+
handler = None
|
68
85
|
print_logging = None
|
69
|
-
handlers = None
|
70
86
|
|
71
87
|
else:
|
72
88
|
raise ValueError(f"Unknown log format: {config.LOG_FORMAT}")
|
73
89
|
|
74
90
|
# Change built-in logging.
|
75
|
-
if
|
91
|
+
if handler is not None:
|
76
92
|
logging.basicConfig(
|
77
93
|
level=config.LOG_LEVEL.value,
|
78
|
-
|
79
|
-
datefmt=datefmt_logging,
|
80
|
-
handlers=handlers,
|
94
|
+
handlers=[handler],
|
81
95
|
)
|
82
|
-
|
83
96
|
# Configure all existing loggers
|
84
97
|
for logger_name in logging.root.manager.loggerDict:
|
85
98
|
existing_logger = logging.getLogger(logger_name)
|
86
99
|
existing_logger.setLevel(config.LOG_LEVEL.value)
|
87
|
-
|
88
|
-
|
100
|
+
# Remove existing handlers
|
101
|
+
if existing_logger.hasHandlers():
|
102
|
+
existing_logger.handlers.clear()
|
103
|
+
# And add ours only
|
104
|
+
existing_logger.addHandler(handler)
|
89
105
|
existing_logger.propagate = False
|
90
106
|
|
91
107
|
# Change loguru.
|
92
|
-
if
|
108
|
+
if handler is not None:
|
93
109
|
logger.remove()
|
94
110
|
logger.add(
|
95
|
-
|
96
|
-
format=format_loguru,
|
111
|
+
handler,
|
97
112
|
level=config.LOG_LEVEL.value,
|
98
|
-
colorize=
|
113
|
+
colorize=False,
|
99
114
|
)
|
100
115
|
|
101
|
-
# Change warning formatting to a simpler one (no source code in a new line).
|
102
|
-
warnings.formatwarning = simple_warning_format
|
103
116
|
# Use logging module for warnings.
|
104
117
|
logging.captureWarnings(True)
|
105
118
|
|
@@ -110,23 +123,13 @@ def patch_logger() -> None:
|
|
110
123
|
logger.info(f"Patched logger for {config.LOG_FORMAT.value} format.")
|
111
124
|
|
112
125
|
|
113
|
-
def
|
126
|
+
def print_using_logger_info(
|
114
127
|
*values: object,
|
115
128
|
sep: str = " ",
|
116
129
|
end: str = "\n",
|
117
130
|
**kwargs: t.Any,
|
118
131
|
) -> None:
|
119
|
-
|
120
|
-
message = message.strip().replace(
|
121
|
-
"\n", "\\n"
|
122
|
-
) # Escape new lines, because otherwise logs will be broken.
|
123
|
-
logger.info(message)
|
124
|
-
|
125
|
-
|
126
|
-
def simple_warning_format(message, category, filename, lineno, line=None): # type: ignore[no-untyped-def] # Not typed in the standard library neither.
|
127
|
-
return f"{category.__name__}: {message}".strip().replace(
|
128
|
-
"\n", "\\n"
|
129
|
-
) # Escape new lines, because otherwise logs will be broken.
|
132
|
+
logger.info(sep.join(map(str, values)) + end)
|
130
133
|
|
131
134
|
|
132
135
|
patch_logger()
|
@@ -3,6 +3,7 @@ import inspect
|
|
3
3
|
import json
|
4
4
|
from datetime import timedelta
|
5
5
|
from functools import wraps
|
6
|
+
from types import UnionType
|
6
7
|
from typing import (
|
7
8
|
Any,
|
8
9
|
Callable,
|
@@ -276,6 +277,17 @@ def convert_cached_output_to_pydantic(return_type: Any, data: Any) -> Any:
|
|
276
277
|
): convert_cached_output_to_pydantic(value_type, v)
|
277
278
|
for k, v in data.items()
|
278
279
|
}
|
280
|
+
# If the origin is a union and one of the unions is basemodel, convert it to it.
|
281
|
+
elif (
|
282
|
+
origin is UnionType
|
283
|
+
and (
|
284
|
+
base_model_from_args := next(
|
285
|
+
(x for x in args if issubclass(x, BaseModel)), None
|
286
|
+
)
|
287
|
+
)
|
288
|
+
is not None
|
289
|
+
):
|
290
|
+
return base_model_from_args.model_validate(data)
|
279
291
|
else:
|
280
292
|
# If the origin is not a dictionary, return the data as is
|
281
293
|
return data
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: prediction-market-agent-tooling
|
3
|
-
Version: 0.64.
|
3
|
+
Version: 0.64.3.dev611
|
4
4
|
Summary: Tools to benchmark, deploy and monitor prediction market agents.
|
5
5
|
Author: Gnosis
|
6
6
|
Requires-Python: >=3.10,<3.13
|
@@ -46,6 +46,7 @@ Requires-Dist: pydantic-settings (>=2.4.0,<3.0.0)
|
|
46
46
|
Requires-Dist: pymongo (>=4.8.0,<5.0.0)
|
47
47
|
Requires-Dist: pytest-postgresql (>=6.1.1,<7.0.0)
|
48
48
|
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
49
|
+
Requires-Dist: python-json-logger (>=3.3.0,<4.0.0)
|
49
50
|
Requires-Dist: safe-cli (>=1.0.0,<2.0.0)
|
50
51
|
Requires-Dist: safe-eth-py (>=6.0.0b41,<7.0.0)
|
51
52
|
Requires-Dist: scikit-learn (>=1.3.1,<2.0.0)
|
@@ -35,7 +35,7 @@ prediction_market_agent_tooling/gtypes.py,sha256=bUIZfZIGvIi3aiZNu5rVE9kRevw8sfM
|
|
35
35
|
prediction_market_agent_tooling/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
prediction_market_agent_tooling/jobs/jobs_models.py,sha256=8vYafsK1cqMWQtjBoq9rruroF84xAVD00vBTMWH6QMg,2166
|
37
37
|
prediction_market_agent_tooling/jobs/omen/omen_jobs.py,sha256=Pf6QxPXGyie-2l_wZUjaGPTjZTlpv50_JhP40mULBaU,5048
|
38
|
-
prediction_market_agent_tooling/loggers.py,sha256=
|
38
|
+
prediction_market_agent_tooling/loggers.py,sha256=ae6v2xUIARZ1CYO_z2W5tvtonEtqxozdFQFz5D3oDrE,4104
|
39
39
|
prediction_market_agent_tooling/markets/agent_market.py,sha256=1NomilM0GCXcRq_1N_cr2AbSK5ONTowFeRbrhc7V5zE,14929
|
40
40
|
prediction_market_agent_tooling/markets/base_subgraph_handler.py,sha256=7RaYO_4qAmQ6ZGM8oPK2-CkiJfKmV9MxM-rJlduaecU,1971
|
41
41
|
prediction_market_agent_tooling/markets/blockchain_utils.py,sha256=qm21scopQ6dfewkoqQF6lWLDGg2BblsKUdC9aG93Hmc,2249
|
@@ -86,7 +86,7 @@ prediction_market_agent_tooling/tools/betting_strategies/market_moving.py,sha256
|
|
86
86
|
prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py,sha256=-FUSuQQgjcWSSnoFxnlAyTeilY6raJABJVM2QKkFqAY,438
|
87
87
|
prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py,sha256=THMXwFlskvzbjnX_OiYtDSzI8XVFyULWfP2525_9UGc,429
|
88
88
|
prediction_market_agent_tooling/tools/betting_strategies/utils.py,sha256=68zFWUj43GUaSpOPowVrbI-t6qbCE29RsVHNzCVuJ9U,175
|
89
|
-
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=
|
89
|
+
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=e7CLFPTlxYFx0pM3x5sWyn_g9pIigPSvrP0mMmiOhUg,11859
|
90
90
|
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=ZW5iI5rmjqeAebu5T7ftRnlkxiL02IC-MxCfDB80x7w,1506
|
91
91
|
prediction_market_agent_tooling/tools/caches/serializers.py,sha256=vFDx4fsPxclXp2q0sv27j4al_M_Tj9aR2JJP-xNHQXA,2151
|
92
92
|
prediction_market_agent_tooling/tools/contract.py,sha256=Yex8MVYvdBTMZLESLqKpwEyT8EGAfkJRri5kCaPqrBM,21235
|
@@ -124,8 +124,8 @@ prediction_market_agent_tooling/tools/tokens/usd.py,sha256=yuW8iPPtcpP4eLH2nORMD
|
|
124
124
|
prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
|
125
125
|
prediction_market_agent_tooling/tools/utils.py,sha256=AC2a68jwASMWuQi-w8twl8b_M52YwrEJ81abmuEaqMY,6661
|
126
126
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=zRq-eeBGWt8uUGN9G_WfjmJ0eVvO8aWE9S0Pz_Y6AOA,12342
|
127
|
-
prediction_market_agent_tooling-0.64.
|
128
|
-
prediction_market_agent_tooling-0.64.
|
129
|
-
prediction_market_agent_tooling-0.64.
|
130
|
-
prediction_market_agent_tooling-0.64.
|
131
|
-
prediction_market_agent_tooling-0.64.
|
127
|
+
prediction_market_agent_tooling-0.64.3.dev611.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
128
|
+
prediction_market_agent_tooling-0.64.3.dev611.dist-info/METADATA,sha256=CNc9oHj3mAyUZQN9ElRLGAzvRhHaxkJc9gs-nr3VGbM,8748
|
129
|
+
prediction_market_agent_tooling-0.64.3.dev611.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
130
|
+
prediction_market_agent_tooling-0.64.3.dev611.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
131
|
+
prediction_market_agent_tooling-0.64.3.dev611.dist-info/RECORD,,
|
File without changes
|