prediction-market-agent-tooling 0.64.2.dev604__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.
@@ -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 NoNewLineStreamHandler(logging.StreamHandler): # type: ignore # StreamHandler is not typed in the standard library.
35
- def format(self, record: logging.LogRecord) -> str:
36
- return super().format(record).replace("\n", " ")
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
- GCP_LOG_LOGURU_FORMAT = (
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
- format_loguru = GCP_LOG_LOGURU_FORMAT
61
- format_logging = GCP_LOG_LOGGING_FORMAT
62
- datefmt_logging = GCP_LOG_FORMAT_LOGGING_DATEFMT
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
- format_loguru, format_logging, datefmt_logging = None, None, None
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 format_logging is not None:
91
+ if handler is not None:
76
92
  logging.basicConfig(
77
93
  level=config.LOG_LEVEL.value,
78
- format=format_logging,
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
- if handlers is not None:
88
- existing_logger.handlers = handlers
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 format_loguru is not None:
108
+ if handler is not None:
93
109
  logger.remove()
94
110
  logger.add(
95
- sys.stdout,
96
- format=format_loguru,
111
+ handler,
97
112
  level=config.LOG_LEVEL.value,
98
- colorize=True,
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 print_using_loguru_info(
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
- message = sep.join(map(str, values)) + end
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()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.64.2.dev604
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=MvCkQSJL2_0yErNatqr81sJlc4aOgPzDp9VNrIhKUcc,4140
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
@@ -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.2.dev604.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
128
- prediction_market_agent_tooling-0.64.2.dev604.dist-info/METADATA,sha256=38NbTGoeHosQDE-geyMz6TINHrmiaueopsL_J1-ZU2g,8697
129
- prediction_market_agent_tooling-0.64.2.dev604.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
130
- prediction_market_agent_tooling-0.64.2.dev604.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
131
- prediction_market_agent_tooling-0.64.2.dev604.dist-info/RECORD,,
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.2
2
+ Generator: poetry-core 2.1.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any