prediction-market-agent-tooling 0.22.0__tar.gz → 0.24.0__tar.gz
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-0.22.0 → prediction_market_agent_tooling-0.24.0}/PKG-INFO +1 -1
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/deploy/agent.py +54 -44
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/deploy/agent_example.py +3 -3
- prediction_market_agent_tooling-0.24.0/prediction_market_agent_tooling/loggers.py +75 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/pyproject.toml +1 -1
- prediction_market_agent_tooling-0.22.0/prediction_market_agent_tooling/loggers.py +0 -54
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/README.md +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/abis/wxdai.abi.json +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/config.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/deploy/constants.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/gtypes.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/agent_market.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/categorize.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/data_models.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/manifold/manifold.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/markets.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/omen/data_models.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/omen/omen.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/monitor/langfuse/langfuse_wrapper.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/monitor/markets/manifold.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/monitor/markets/omen.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/monitor/markets/polymarket.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/monitor/monitor.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/monitor/monitor_app.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/monitor/monitor_settings.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/py.typed +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/balances.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/cache.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/contract.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/costs.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/gnosis_rpc.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/google.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/is_predictable.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/safe.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/singleton.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/utils.py +0 -0
- {prediction_market_agent_tooling-0.22.0 → prediction_market_agent_tooling-0.24.0}/prediction_market_agent_tooling/tools/web3_utils.py +0 -0
@@ -84,62 +84,30 @@ class Answer(BaseModel):
|
|
84
84
|
|
85
85
|
|
86
86
|
class DeployableAgent:
|
87
|
-
bet_on_n_markets_per_run: int = 1
|
88
|
-
|
89
87
|
def __init__(self) -> None:
|
90
88
|
self.langfuse_wrapper = LangfuseWrapper(agent_name=self.__class__.__name__)
|
91
89
|
self.load()
|
92
90
|
|
93
91
|
def __init_subclass__(cls, **kwargs: t.Any) -> None:
|
94
|
-
if
|
92
|
+
if "DeployableAgent" not in str(
|
93
|
+
cls.__init__
|
94
|
+
) and "DeployableTraderAgent" not in str(cls.__init__):
|
95
95
|
raise TypeError(
|
96
|
-
"Cannot override __init__ method of
|
96
|
+
"Cannot override __init__ method of deployable agent class, please override the `load` method to set up the agent."
|
97
97
|
)
|
98
98
|
|
99
99
|
def load(self) -> None:
|
100
100
|
pass
|
101
101
|
|
102
|
-
def have_bet_on_market_since(self, market: AgentMarket, since: timedelta) -> bool:
|
103
|
-
return have_bet_on_market_since(keys=APIKeys(), market=market, since=since)
|
104
|
-
|
105
|
-
def pick_markets(self, markets: t.Sequence[AgentMarket]) -> t.Sequence[AgentMarket]:
|
106
|
-
"""
|
107
|
-
Subclasses can implement their own logic instead of this one, or on top of this one.
|
108
|
-
By default, it picks only the first {n_markets_per_run} markets where user didn't bet recently and it's a reasonable question.
|
109
|
-
"""
|
110
|
-
picked: list[AgentMarket] = []
|
111
|
-
|
112
|
-
for market in markets:
|
113
|
-
if len(picked) >= self.bet_on_n_markets_per_run:
|
114
|
-
break
|
115
|
-
|
116
|
-
if self.have_bet_on_market_since(market, since=timedelta(hours=24)):
|
117
|
-
continue
|
118
|
-
|
119
|
-
# Do as a last check, as it uses paid OpenAI API.
|
120
|
-
if not is_predictable_binary(market.question):
|
121
|
-
continue
|
122
|
-
|
123
|
-
picked.append(market)
|
124
|
-
|
125
|
-
return picked
|
126
|
-
|
127
|
-
def answer_binary_market(self, market: AgentMarket) -> Answer | None:
|
128
|
-
"""
|
129
|
-
Answer the binary market. This method must be implemented by the subclass.
|
130
|
-
"""
|
131
|
-
raise NotImplementedError("This method must be implemented by the subclass")
|
132
|
-
|
133
102
|
def deploy_local(
|
134
103
|
self,
|
135
104
|
market_type: MarketType,
|
136
105
|
sleep_time: float,
|
137
106
|
timeout: float,
|
138
|
-
place_bet: bool,
|
139
107
|
) -> None:
|
140
108
|
start_time = time.time()
|
141
109
|
while True:
|
142
|
-
self.run(market_type=market_type
|
110
|
+
self.run(market_type=market_type)
|
143
111
|
time.sleep(sleep_time)
|
144
112
|
if time.time() - start_time > timeout:
|
145
113
|
break
|
@@ -223,6 +191,51 @@ def {entrypoint_function_name}(request) -> str:
|
|
223
191
|
if cron_schedule:
|
224
192
|
schedule_deployed_gcp_function(fname, cron_schedule=cron_schedule)
|
225
193
|
|
194
|
+
def run(self, market_type: MarketType) -> None:
|
195
|
+
raise NotImplementedError("This method must be implemented by the subclass.")
|
196
|
+
|
197
|
+
def get_gcloud_fname(self, market_type: MarketType) -> str:
|
198
|
+
return f"{self.__class__.__name__.lower()}-{market_type}-{datetime.now().strftime('%Y-%m-%d--%H-%M-%S')}"
|
199
|
+
|
200
|
+
|
201
|
+
class DeployableTraderAgent(DeployableAgent):
|
202
|
+
bet_on_n_markets_per_run: int = 1
|
203
|
+
|
204
|
+
def __init__(self, place_bet: bool = True) -> None:
|
205
|
+
super().__init__()
|
206
|
+
self.place_bet = place_bet
|
207
|
+
|
208
|
+
def have_bet_on_market_since(self, market: AgentMarket, since: timedelta) -> bool:
|
209
|
+
return have_bet_on_market_since(keys=APIKeys(), market=market, since=since)
|
210
|
+
|
211
|
+
def pick_markets(self, markets: t.Sequence[AgentMarket]) -> t.Sequence[AgentMarket]:
|
212
|
+
"""
|
213
|
+
Subclasses can implement their own logic instead of this one, or on top of this one.
|
214
|
+
By default, it picks only the first {n_markets_per_run} markets where user didn't bet recently and it's a reasonable question.
|
215
|
+
"""
|
216
|
+
picked: list[AgentMarket] = []
|
217
|
+
|
218
|
+
for market in markets:
|
219
|
+
if len(picked) >= self.bet_on_n_markets_per_run:
|
220
|
+
break
|
221
|
+
|
222
|
+
if self.have_bet_on_market_since(market, since=timedelta(hours=24)):
|
223
|
+
continue
|
224
|
+
|
225
|
+
# Do as a last check, as it uses paid OpenAI API.
|
226
|
+
if not is_predictable_binary(market.question):
|
227
|
+
continue
|
228
|
+
|
229
|
+
picked.append(market)
|
230
|
+
|
231
|
+
return picked
|
232
|
+
|
233
|
+
def answer_binary_market(self, market: AgentMarket) -> Answer | None:
|
234
|
+
"""
|
235
|
+
Answer the binary market. This method must be implemented by the subclass.
|
236
|
+
"""
|
237
|
+
raise NotImplementedError("This method must be implemented by the subclass")
|
238
|
+
|
226
239
|
def calculate_bet_amount(self, answer: Answer, market: AgentMarket) -> BetAmount:
|
227
240
|
"""
|
228
241
|
Calculate the bet amount. By default, it returns the minimum bet amount.
|
@@ -253,7 +266,7 @@ def {entrypoint_function_name}(request) -> str:
|
|
253
266
|
# Omen is specific, because the user (agent) needs to manually withdraw winnings from the market.
|
254
267
|
redeem_from_all_user_positions(private_credentials)
|
255
268
|
|
256
|
-
def process_bets(self, market_type: MarketType
|
269
|
+
def process_bets(self, market_type: MarketType) -> None:
|
257
270
|
"""
|
258
271
|
Processes bets placed by agents on a given market.
|
259
272
|
"""
|
@@ -264,7 +277,7 @@ def {entrypoint_function_name}(request) -> str:
|
|
264
277
|
if result is None:
|
265
278
|
logger.debug(f"Skipping market {market} as no answer was provided")
|
266
279
|
continue
|
267
|
-
if
|
280
|
+
if self.place_bet:
|
268
281
|
amount = self.calculate_bet_amount(result, market)
|
269
282
|
logger.debug(
|
270
283
|
f"Placing bet on {market} with result {result} and amount {amount}"
|
@@ -277,10 +290,7 @@ def {entrypoint_function_name}(request) -> str:
|
|
277
290
|
def after(self, market_type: MarketType) -> None:
|
278
291
|
pass
|
279
292
|
|
280
|
-
def run(self, market_type: MarketType
|
293
|
+
def run(self, market_type: MarketType) -> None:
|
281
294
|
self.before(market_type)
|
282
|
-
self.process_bets(market_type
|
295
|
+
self.process_bets(market_type)
|
283
296
|
self.after(market_type)
|
284
|
-
|
285
|
-
def get_gcloud_fname(self, market_type: MarketType) -> str:
|
286
|
-
return f"{self.__class__.__name__.lower()}-{market_type}-{datetime.now().strftime('%Y-%m-%d--%H-%M-%S')}"
|
@@ -3,13 +3,13 @@ import typing as t
|
|
3
3
|
|
4
4
|
from prediction_market_agent_tooling.deploy.agent import (
|
5
5
|
Answer,
|
6
|
-
|
6
|
+
DeployableTraderAgent,
|
7
7
|
Probability,
|
8
8
|
)
|
9
9
|
from prediction_market_agent_tooling.markets.agent_market import AgentMarket
|
10
10
|
|
11
11
|
|
12
|
-
class DeployableCoinFlipAgent(
|
12
|
+
class DeployableCoinFlipAgent(DeployableTraderAgent):
|
13
13
|
def pick_markets(self, markets: t.Sequence[AgentMarket]) -> t.Sequence[AgentMarket]:
|
14
14
|
return random.sample(markets, 1)
|
15
15
|
|
@@ -23,6 +23,6 @@ class DeployableCoinFlipAgent(DeployableAgent):
|
|
23
23
|
)
|
24
24
|
|
25
25
|
|
26
|
-
class DeployableAlwaysRaiseAgent(
|
26
|
+
class DeployableAlwaysRaiseAgent(DeployableTraderAgent):
|
27
27
|
def answer_binary_market(self, market: AgentMarket) -> Answer | None:
|
28
28
|
raise RuntimeError("I always raise!")
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import logging
|
2
|
+
import sys
|
3
|
+
import warnings
|
4
|
+
from enum import Enum
|
5
|
+
|
6
|
+
from loguru import logger
|
7
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
8
|
+
|
9
|
+
|
10
|
+
class LogFormat(str, Enum):
|
11
|
+
DEFAULT = "default"
|
12
|
+
GCP = "gcp"
|
13
|
+
|
14
|
+
|
15
|
+
class LogConfig(BaseSettings):
|
16
|
+
model_config = SettingsConfigDict(
|
17
|
+
env_file=".env", env_file_encoding="utf-8", extra="ignore"
|
18
|
+
)
|
19
|
+
|
20
|
+
LOG_FORMAT: LogFormat = LogFormat.DEFAULT
|
21
|
+
|
22
|
+
|
23
|
+
GCP_LOG_LOGURU_FORMAT = (
|
24
|
+
"{level:<.1}{time:MMDD HH:mm:ss} {process} {name}:{line}] {message}"
|
25
|
+
)
|
26
|
+
GCP_LOG_LOGGING_FORMAT, GCP_LOG_FORMAT_LOGGING_DATEFMT = (
|
27
|
+
"%(levelname).1s%(asctime)s %(process)d %(name)s:%(lineno)d] %(message)s"
|
28
|
+
), "%m%d %H:%M:%S"
|
29
|
+
|
30
|
+
|
31
|
+
def patch_logger() -> None:
|
32
|
+
config = LogConfig()
|
33
|
+
|
34
|
+
if config.LOG_FORMAT == LogFormat.GCP:
|
35
|
+
format_loguru = GCP_LOG_LOGURU_FORMAT
|
36
|
+
format_logging = GCP_LOG_LOGGING_FORMAT
|
37
|
+
datefmt_logging = GCP_LOG_FORMAT_LOGGING_DATEFMT
|
38
|
+
|
39
|
+
elif config.LOG_FORMAT == LogFormat.DEFAULT:
|
40
|
+
format_loguru, format_logging, datefmt_logging = None, None, None
|
41
|
+
|
42
|
+
else:
|
43
|
+
raise ValueError(f"Unknown log format: {config.LOG_FORMAT}")
|
44
|
+
|
45
|
+
# Change built-in logging.
|
46
|
+
if format_logging is not None:
|
47
|
+
logging.basicConfig(
|
48
|
+
level=logging.DEBUG, format=format_logging, datefmt=datefmt_logging
|
49
|
+
)
|
50
|
+
|
51
|
+
# Change loguru.
|
52
|
+
if format_loguru is not None:
|
53
|
+
logger.remove()
|
54
|
+
logger.add(
|
55
|
+
sys.stdout,
|
56
|
+
format=format_loguru,
|
57
|
+
level="DEBUG", # Can be the lowest level, higher ones will use by default this one.
|
58
|
+
colorize=True,
|
59
|
+
)
|
60
|
+
|
61
|
+
# Change warning formatting to a simpler one (no source code in a new line).
|
62
|
+
warnings.formatwarning = simple_warning_format
|
63
|
+
# Use logging module for warnings.
|
64
|
+
logging.captureWarnings(True)
|
65
|
+
|
66
|
+
logger.info(f"Patched logger for {config.LOG_FORMAT.value} format.")
|
67
|
+
|
68
|
+
|
69
|
+
def simple_warning_format(message, category, filename, lineno, line=None): # type: ignore[no-untyped-def] # Not typed in the standard library neither.
|
70
|
+
return f"{category.__name__}: {message}"
|
71
|
+
|
72
|
+
|
73
|
+
if not getattr(logger, "_patched", False):
|
74
|
+
patch_logger()
|
75
|
+
logger._patched = True # type: ignore[attr-defined] # Hacky way to store a flag on the logger object, to not patch it multiple times.
|
@@ -1,54 +0,0 @@
|
|
1
|
-
import sys
|
2
|
-
import typing as t
|
3
|
-
from enum import Enum
|
4
|
-
|
5
|
-
from loguru import logger
|
6
|
-
from pydantic_settings import BaseSettings, SettingsConfigDict
|
7
|
-
|
8
|
-
if t.TYPE_CHECKING:
|
9
|
-
from loguru import Logger
|
10
|
-
|
11
|
-
|
12
|
-
class LogFormat(str, Enum):
|
13
|
-
DEFAULT = "default"
|
14
|
-
GCP = "gcp"
|
15
|
-
|
16
|
-
|
17
|
-
class LogConfig(BaseSettings):
|
18
|
-
model_config = SettingsConfigDict(
|
19
|
-
env_file=".env", env_file_encoding="utf-8", extra="ignore"
|
20
|
-
)
|
21
|
-
|
22
|
-
LOG_FORMAT: LogFormat = LogFormat.DEFAULT
|
23
|
-
|
24
|
-
|
25
|
-
GCP_LOG_FORMAT = "{level:<.1}{time:MMDD HH:mm:ss.SSSSSS} {process} {name}:{line}] {message} | {extra}"
|
26
|
-
|
27
|
-
|
28
|
-
def patch_logger(logger: "Logger") -> None:
|
29
|
-
config = LogConfig()
|
30
|
-
|
31
|
-
if config.LOG_FORMAT == LogFormat.GCP:
|
32
|
-
format_ = GCP_LOG_FORMAT
|
33
|
-
|
34
|
-
elif config.LOG_FORMAT == LogFormat.DEFAULT:
|
35
|
-
format_ = None
|
36
|
-
|
37
|
-
else:
|
38
|
-
raise ValueError(f"Unknown log format: {config.LOG_FORMAT}")
|
39
|
-
|
40
|
-
if format_ is not None:
|
41
|
-
logger.remove()
|
42
|
-
logger.add(
|
43
|
-
sys.stdout,
|
44
|
-
format=format_,
|
45
|
-
level="DEBUG", # Can be the lowest level, higher ones will use by default this one.
|
46
|
-
colorize=True,
|
47
|
-
)
|
48
|
-
|
49
|
-
logger.info(f"Patched logger for {config.LOG_FORMAT.value} format.")
|
50
|
-
|
51
|
-
|
52
|
-
if not getattr(logger, "_patched", False):
|
53
|
-
patch_logger(logger)
|
54
|
-
logger._patched = True # type: ignore[attr-defined] # Hacky way to store a flag on the logger object, to not patch it multiple times.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|