Compare commits

...

42 Commits

Author SHA1 Message Date
renovate[bot]
962c369b88 Update python:3.13-slim Docker digest to 27f90d7 (#170)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 18:31:07 +00:00
renovate[bot]
87ed08d250 Update docker/setup-buildx-action digest to 4cc794f (#169)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 13:16:37 +00:00
renovate[bot]
37ddfd24c3 Update python:3.13-slim Docker digest to 4d55aff (#168)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-16 04:36:35 +00:00
renovate[bot]
3c0638ba47 Update python:3.13-slim Docker digest to 4112a75 (#167)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-16 00:49:59 +00:00
renovate[bot]
5dbac43b27 Update astral-sh/setup-uv digest to c0e7e93 (#165)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-15 02:06:42 +00:00
renovate[bot]
3a268c0cb5 Update python:3.13-slim Docker digest to 2a928e1 (#166)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 21:34:12 +00:00
renovate[bot]
d8d57a6581 Update astral-sh/setup-uv digest to fda2399 (#164)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 10:32:58 +00:00
renovate[bot]
35b1874714 Update python:3.13-slim Docker digest to 201e1ab (#163)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-13 21:30:58 +00:00
renovate[bot]
1fc3482c36 Update actions/checkout digest to ff7abcd (#162)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-13 16:32:16 +00:00
renovate[bot]
dd7e51fc3f Update python:3.13-slim Docker digest to 6a135f8 (#161)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-13 10:48:19 +00:00
renovate[bot]
ea4f3882f9 Update python:3.13-slim Docker digest to faa4eb6 (#160)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-13 07:07:37 +00:00
renovate[bot]
c89faf85db Update astral-sh/setup-uv digest to d9e0f98 (#159)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-13 04:08:19 +00:00
renovate[bot]
364f1b8aea Update astral-sh/setup-uv digest to e5d42a2 (#158)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 20:39:58 +00:00
renovate[bot]
ffaae102c5 Update astral-sh/setup-uv digest to 1463845 (#157)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 10:35:48 +00:00
renovate[bot]
3f489edb37 Update docker/setup-buildx-action digest to af1b253 (#156)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 16:50:56 +00:00
renovate[bot]
ca29c06c81 Update actions/checkout digest to 08c6903 (#155)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 13:53:33 +00:00
renovate[bot]
dd9dab3f8b Update astral-sh/setup-uv digest to ad5ded2 (#154)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-09 09:13:19 +00:00
renovate[bot]
a0a7519f14 Update python:3.13-slim Docker digest to 6f79e7a (#153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-07 21:45:55 +00:00
renovate[bot]
4ef58a394b Update docker/setup-buildx-action digest to 2c8bcda (#152)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-07 08:49:49 +00:00
renovate[bot]
d2ffd0c9c5 Update docker/setup-buildx-action digest to c65d441 (#151)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-06 17:40:43 +00:00
renovate[bot]
e81db87cd4 Update astral-sh/setup-uv digest to 1422404 (#150)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-06 12:47:16 +00:00
renovate[bot]
c11714fe8c Update docker/setup-buildx-action digest to ae7d689 (#149)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-05 17:31:50 +00:00
renovate[bot]
d46b648134 Update docker/login-action digest to 184bdaa (#148)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 16:26:58 +00:00
renovate[bot]
747b031eca Update docker/login-action digest to ef38ec3 (#147)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 14:32:52 +00:00
renovate[bot]
ae0a83c1f0 Update astral-sh/setup-uv digest to 6324490 (#146)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 01:31:56 +00:00
renovate[bot]
d799845ba7 Update astral-sh/setup-uv digest to 2a967c9 (#145)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-31 08:55:33 +00:00
renovate[bot]
84ec0e673b Update astral-sh/setup-uv digest to 43f3736 (#144)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-26 13:38:51 +00:00
renovate[bot]
963c8f4e3a Update astral-sh/setup-uv digest to 4fb0c07 (#143)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-25 05:27:25 +00:00
renovate[bot]
28bf3679de Update python:3.13-slim Docker digest to 4c2cf99 (#142)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 02:09:28 +00:00
renovate[bot]
cb8213aa74 Update astral-sh/setup-uv digest to e92bafb (#141)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 23:07:25 +00:00
renovate[bot]
c5de3bfe71 Update actions/checkout digest to 8edcb1b (#140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 17:56:54 +00:00
renovate[bot]
7025fafb72 Update astral-sh/setup-uv digest to 23482a3 (#139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 11:59:04 +00:00
renovate[bot]
453a44f125 Update python:3.13-slim Docker digest to 1020ca4 (#138)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-22 21:10:35 +00:00
renovate[bot]
1cdbcf1d96 Update python:3.13-slim Docker digest to 9248661 (#137)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-22 15:04:51 +00:00
renovate[bot]
e930a3bd9b Update python:3.13-slim Docker digest to 97fe872 (#136)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-22 07:57:32 +00:00
renovate[bot]
3a340d622f Update python:3.13-slim Docker digest to ed8ae2e (#135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-22 03:33:13 +00:00
c665ea9ea9 Add Sentry log filtering to reduce noise in error reporting 2025-07-19 00:40:41 +02:00
c8d7e059b2 Refactor Sentry integration: move initialization to RemindBotClient and enhance error context logging 2025-07-18 23:03:49 +02:00
a99c381bec Enhance message sending reliability by adding a delay before sending and improving error logging for bot state issues 2025-07-18 21:37:14 +02:00
bb752cd6cc Merge branch 'master' of https://github.com/TheLovinator1/discord-reminder-bot 2025-07-18 21:24:10 +02:00
c3161c2e0a Update dependencies: aiohttp to 3.12.14, certifi to 2025.7.14, orjson to 3.11.0, and sentry-sdk to 2.33.0 2025-07-18 21:24:04 +02:00
ca3c3bbb1b Enhance error handling and logging in Discord message sending functions
- Added detailed bot state information to error messages when sending fails.
- Implemented early validation of bot readiness and closure in `send_to_discord`.
- Introduced `safe_send_to_discord` to manage bot state issues and prevent '_MissingSentinel' errors.
- Improved logging for better debugging of bot state and HTTP client status.
2025-07-18 21:23:35 +02:00
5 changed files with 189 additions and 66 deletions

View File

@@ -20,22 +20,22 @@ jobs:
contents: read contents: read
packages: write packages: write
steps: steps:
- uses: docker/login-action@3d100841f68d4548bf57e52eb27bd33ec5069f55 - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: docker/login-action@3d100841f68d4548bf57e52eb27bd33ec5069f55 - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493
- uses: astral-sh/setup-uv@4ac06a054e1a82147502e6128c4eab873ab38aa1 - uses: astral-sh/setup-uv@c0e7e93474eb09a343746f2a2742979d0cba523c
with: with:
python-version: 3.13 python-version: 3.13
@@ -46,7 +46,7 @@ jobs:
with: with:
platforms: all platforms: all
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 - uses: docker/setup-buildx-action@4cc794f83e4b7488282e879f4469e86246e52ddd
- uses: docker/build-push-action@v6 - uses: docker/build-push-action@v6
with: with:

View File

@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
# check=error=true;experimental=all # check=error=true;experimental=all
FROM python:3.13-slim@sha256:6544e0e002b40ae0f59bc3618b07c1e48064c4faed3a15ae2fbd2e8f663e8283 FROM python:3.13-slim@sha256:27f90d79cc85e9b7b2560063ef44fa0e9eaae7a7c3f5a9f74563065c5477cc24
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONDONTWRITEBYTECODE=1

View File

@@ -1,8 +1,10 @@
from __future__ import annotations from __future__ import annotations
import asyncio
import datetime import datetime
import json import json
import os import os
import platform
import sys import sys
import tempfile import tempfile
from functools import partial from functools import partial
@@ -23,6 +25,9 @@ from discord.abc import PrivateChannel
from discord.utils import escape_markdown from discord.utils import escape_markdown
from discord_webhook import DiscordWebhook from discord_webhook import DiscordWebhook
from loguru import logger from loguru import logger
from sentry_sdk.integrations.asyncio import AsyncioIntegration
from sentry_sdk.integrations.loguru import LoggingLevels, LoguruIntegration
from sentry_sdk.integrations.sys_exit import SysExitIntegration
from discord_reminder_bot.helpers import calculate, generate_markdown_state, generate_state, get_human_readable_time, parse_time from discord_reminder_bot.helpers import calculate, generate_markdown_state, generate_state, get_human_readable_time, parse_time
from discord_reminder_bot.modals import CronReminderModifyModal, DateReminderModifyModal, IntervalReminderModifyModal from discord_reminder_bot.modals import CronReminderModifyModal, DateReminderModifyModal, IntervalReminderModifyModal
@@ -36,6 +41,7 @@ if TYPE_CHECKING:
from discord.guild import GuildChannel from discord.guild import GuildChannel
from discord.interactions import InteractionChannel from discord.interactions import InteractionChannel
from requests import Response from requests import Response
from sentry_sdk.types import Hint, Log
def my_listener(event: JobExecutionEvent) -> None: def my_listener(event: JobExecutionEvent) -> None:
@@ -64,15 +70,25 @@ def my_listener(event: JobExecutionEvent) -> None:
send_webhook(custom_url="", message=msg) send_webhook(custom_url="", message=msg)
if event.exception: if event.exception:
with sentry_sdk.push_scope() as scope: with sentry_sdk.new_scope() as scope:
scope.set_extra("job_id", event.job_id) scope.set_extra("job_id", event.job_id)
scope.set_extra("scheduled_run_time", event.scheduled_run_time.isoformat() if event.scheduled_run_time else "None") scope.set_extra("scheduled_run_time", event.scheduled_run_time.isoformat() if event.scheduled_run_time else "None")
scope.set_extra("event_code", event.code) scope.set_extra("event_code", event.code)
scope.set_extra("bot_is_ready", bot.is_ready() if "bot" in globals() else "Unknown")
scope.set_extra("bot_is_closed", bot.is_closed() if "bot" in globals() else "Unknown")
sentry_sdk.capture_exception(event.exception) sentry_sdk.capture_exception(event.exception)
# Create detailed error message with bot state information
bot_state_info = ""
if "bot" in globals():
bot_state_info = f"\nBot State: ready={bot.is_ready()}, closed={bot.is_closed()}, user={bot.user}"
if hasattr(bot, "http") and bot.http:
global_over = getattr(bot.http, "_global_over", None)
bot_state_info += f"\nHTTP State: _global_over type={type(global_over)}"
send_webhook( send_webhook(
custom_url="", custom_url="",
message=f"discord-reminder-bot failed to send message to Discord\n{event.exception}\n{event.traceback}", message=f"discord-reminder-bot failed to send message to Discord\nJob ID: {event.job_id}\nScheduled Time: {event.scheduled_run_time.isoformat() if event.scheduled_run_time else 'None'}{bot_state_info}\n{event.exception}\n{event.traceback}",
) )
@@ -91,7 +107,16 @@ class RemindBotClient(discord.Client):
async def on_error(self, event_method: str, *args: list[Any], **kwargs: dict[str, Any]) -> None: async def on_error(self, event_method: str, *args: list[Any], **kwargs: dict[str, Any]) -> None:
"""Log errors that occur in the bot.""" """Log errors that occur in the bot."""
logger.exception(f"An error occurred in {event_method} with args: {args} and kwargs: {kwargs}") logger.exception(f"An error occurred in {event_method} with args: {args} and kwargs: {kwargs}")
sentry_sdk.capture_exception() # TODO(TheLovinator): Add more context to the error # noqa: TD003
with sentry_sdk.new_scope() as scope:
scope.set_extra("event_method", event_method)
scope.set_extra("args", args)
scope.set_extra("kwargs", kwargs)
scope.set_extra("bot_is_ready", self.is_ready())
scope.set_extra("bot_is_closed", self.is_closed())
if hasattr(self, "ws") and self.ws:
scope.set_extra("session_id", self.ws.session_id)
sentry_sdk.capture_exception()
async def on_ready(self) -> None: async def on_ready(self) -> None:
"""Called when the client is done preparing the data received from Discord. Usually after login is successful and the Client.guilds and co. are filled up. """Called when the client is done preparing the data received from Discord. Usually after login is successful and the Client.guilds and co. are filled up.
@@ -113,6 +138,45 @@ class RemindBotClient(discord.Client):
async def setup_hook(self) -> None: async def setup_hook(self) -> None:
"""Setup the bot.""" """Setup the bot."""
default_sentry_dsn: str = "https://c4c61a52838be9b5042144420fba5aaa@o4505228040339456.ingest.us.sentry.io/4508707268984832"
def before_send_log(log: Log, _hint: Hint) -> Log | None:
"""Filter out unwanted log messages before sending to Sentry.
Args:
log: The log object containing message and metadata.
_hint: Additional context about the log.
Returns:
The log object if it should be sent to Sentry, None to discard it.
"""
ignored_log_messages: list[str] = [
"has connected to Gateway",
"has successfully RESUMED session",
]
if log.get("body") and any(noisy_log in log["body"] for noisy_log in ignored_log_messages):
return None
return log
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN", default_sentry_dsn),
environment=platform.node() or "Unknown",
traces_sample_rate=1.0,
profile_session_sample_rate=1.0,
send_default_pii=True,
_experiments={
"enable_logs": True,
"before_send_log": before_send_log,
},
integrations=[
AsyncioIntegration(),
LoguruIntegration(sentry_logs_level=LoggingLevels.WARNING.value),
SysExitIntegration(capture_successful_exits=True),
],
)
scheduler.add_listener(my_listener, EVENT_JOB_MISSED | EVENT_JOB_ERROR) scheduler.add_listener(my_listener, EVENT_JOB_MISSED | EVENT_JOB_ERROR)
jobs: list[Job] = scheduler.get_jobs() jobs: list[Job] = scheduler.get_jobs()
if jobs: if jobs:
@@ -1217,19 +1281,62 @@ async def send_to_discord(channel_id: int, message: str, author_id: int) -> None
channel_id: The Discord channel ID. channel_id: The Discord channel ID.
message: The message. message: The message.
author_id: User we should mention in the message. author_id: User we should mention in the message.
Raises:
RuntimeError: If the bot is not ready or is closed.
""" """
logger.info(f"Sending message to channel '<#{channel_id}>' with message: '{message}'") logger.info(f"Sending message to channel '<#{channel_id}>' with message: '{message}'")
# Wait 3 seconds to ensure the bot is ready
logger.debug("Waiting for 3 seconds to ensure the bot is ready before sending the message.")
await asyncio.sleep(3)
# Early validation of bot state
if not bot.is_ready():
error_msg = f"Bot is not ready! Cannot send message to channel {channel_id}\nMessage: {message}\nAuthor ID: {author_id}"
logger.error(error_msg)
raise RuntimeError(error_msg)
if bot.is_closed():
error_msg = f"Bot is closed! Cannot send message to channel {channel_id}\nMessage: {message}\nAuthor ID: {author_id}"
logger.error(error_msg)
raise RuntimeError(error_msg)
# Debug bot state before attempting to fetch channel
_debug_bot_state()
try:
channel: GuildChannel | discord.Thread | PrivateChannel | None = bot.get_channel(channel_id) channel: GuildChannel | discord.Thread | PrivateChannel | None = bot.get_channel(channel_id)
logger.debug(f"bot.get_channel({channel_id}) returned: {channel}")
if channel is None: if channel is None:
logger.info(f"Channel {channel_id} not in cache, attempting to fetch from API")
channel = await bot.fetch_channel(channel_id) channel = await bot.fetch_channel(channel_id)
logger.debug(f"bot.fetch_channel({channel_id}) returned: {channel}")
except Exception as e:
logger.error(f"Failed to get/fetch channel {channel_id}: {type(e).__name__}: {e}")
logger.error(f"Bot state during error - is_ready: {bot.is_ready()}, is_closed: {bot.is_closed()}")
raise
# Channels we can't send messages to # Channels we can't send messages to
if isinstance(channel, discord.ForumChannel | discord.CategoryChannel | PrivateChannel): if isinstance(channel, discord.ForumChannel | discord.CategoryChannel | PrivateChannel):
logger.warning(f"We haven't implemented sending messages to this channel type {type(channel)}") logger.error(f"We haven't implemented sending messages to this channel type {type(channel)}")
return return
await channel.send(f"<@{author_id}>\n{message}") try:
logger.debug(f"Attempting to send message to channel {channel} (type: {type(channel)})")
message_content = f"<@{author_id}>\n{message}"
logger.debug(f"Message content length: {len(message_content)} characters")
sent_message = await channel.send(message_content)
logger.info(f"Successfully sent message to channel {channel_id}, message ID: {sent_message.id}")
except Exception as e:
logger.error(f"Failed to send message to channel {channel_id}: {type(e).__name__}: {e}")
logger.error(f"Channel: {channel}, Channel type: {type(channel)}")
logger.error(f"Bot state during send error - is_ready: {bot.is_ready()}, is_closed: {bot.is_closed()}")
if hasattr(channel, "guild"):
logger.error(f"Guild: {channel.guild}, Guild available: {getattr(channel.guild, 'available', 'Unknown')}")
raise
async def send_to_user(user_id: int, guild_id: int, message: str) -> None: async def send_to_user(user_id: int, guild_id: int, message: str) -> None:
@@ -1272,6 +1379,31 @@ async def send_to_user(user_id: int, guild_id: int, message: str) -> None:
logger.exception(f"Failed to send message '{message}' to user '{user_id}' in guild '{guild_id}'") logger.exception(f"Failed to send message '{message}' to user '{user_id}' in guild '{guild_id}'")
def _debug_bot_state() -> None:
"""Debug helper function to log bot state information."""
logger.debug(f"Bot is_ready: {bot.is_ready()}")
logger.debug(f"Bot is_closed: {bot.is_closed()}")
logger.debug(f"Bot user: {bot.user}")
logger.debug(f"Bot guilds count: {len(bot.guilds) if bot.guilds else 'None'}")
# Check bot's http client state
if hasattr(bot, "http") and bot.http:
logger.debug(f"Bot HTTP client state: connector_initialized={hasattr(bot.http, 'connector')}")
try:
# Safely check _global_over attribute which is causing the error
global_over = getattr(bot.http, "_global_over", None)
logger.debug(f"Bot HTTP _global_over type: {type(global_over)}")
logger.debug(f"Bot HTTP _global_over: {global_over}")
if global_over is not None and hasattr(global_over, "is_set"):
logger.debug(f"Bot HTTP _global_over.is_set(): {global_over.is_set()}")
else:
logger.warning("Bot HTTP _global_over missing is_set method - this is likely the cause of the error")
except (AttributeError, TypeError) as debug_error:
logger.warning(f"Could not inspect bot HTTP _global_over: {debug_error}")
else:
logger.error("Bot HTTP client is None or missing")
if __name__ == "__main__": if __name__ == "__main__":
bot_token: str = os.getenv("BOT_TOKEN", default="") bot_token: str = os.getenv("BOT_TOKEN", default="")
if not bot_token: if not bot_token:
@@ -1280,3 +1412,4 @@ if __name__ == "__main__":
logger.info("Starting bot.") logger.info("Starting bot.")
bot.run(bot_token) bot.run(bot_token)
logger.info("Bot has been stopped.")

View File

@@ -1,12 +1,10 @@
from __future__ import annotations from __future__ import annotations
import os import os
import platform
from pathlib import Path from pathlib import Path
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
import pytz import pytz
import sentry_sdk
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.schedulers.asyncio import AsyncIOScheduler
from dotenv import load_dotenv from dotenv import load_dotenv
@@ -16,14 +14,6 @@ from discord_reminder_bot.helpers import generate_state
load_dotenv(verbose=True) load_dotenv(verbose=True)
default_sentry_dsn: str = "https://c4c61a52838be9b5042144420fba5aaa@o4505228040339456.ingest.us.sentry.io/4508707268984832"
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN", default_sentry_dsn),
environment=platform.node() or "Unknown",
traces_sample_rate=1.0,
send_default_pii=True,
)
def get_scheduler() -> AsyncIOScheduler: def get_scheduler() -> AsyncIOScheduler:
"""Return the scheduler instance. """Return the scheduler instance.

84
uv.lock generated
View File

@@ -25,7 +25,7 @@ wheels = [
[[package]] [[package]]
name = "aiohttp" name = "aiohttp"
version = "3.12.13" version = "3.12.14"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "aiohappyeyeballs" }, { name = "aiohappyeyeballs" },
@@ -36,25 +36,25 @@ dependencies = [
{ name = "propcache" }, { name = "propcache" },
{ name = "yarl" }, { name = "yarl" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/42/6e/ab88e7cb2a4058bed2f7870276454f85a7c56cd6da79349eb314fc7bbcaa/aiohttp-3.12.13.tar.gz", hash = "sha256:47e2da578528264a12e4e3dd8dd72a7289e5f812758fe086473fab037a10fcce", size = 7819160, upload-time = "2025-06-14T15:15:41.354Z" } sdist = { url = "https://files.pythonhosted.org/packages/e6/0b/e39ad954107ebf213a2325038a3e7a506be3d98e1435e1f82086eec4cde2/aiohttp-3.12.14.tar.gz", hash = "sha256:6e06e120e34d93100de448fd941522e11dafa78ef1a893c179901b7d66aa29f2", size = 7822921, upload-time = "2025-07-10T13:05:33.968Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/11/0f/db19abdf2d86aa1deec3c1e0e5ea46a587b97c07a16516b6438428b3a3f8/aiohttp-3.12.13-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d4a18e61f271127465bdb0e8ff36e8f02ac4a32a80d8927aa52371e93cd87938", size = 694910, upload-time = "2025-06-14T15:14:30.604Z" }, { url = "https://files.pythonhosted.org/packages/06/48/e0d2fa8ac778008071e7b79b93ab31ef14ab88804d7ba71b5c964a7c844e/aiohttp-3.12.14-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3143a7893d94dc82bc409f7308bc10d60285a3cd831a68faf1aa0836c5c3c767", size = 695471, upload-time = "2025-07-10T13:04:20.124Z" },
{ url = "https://files.pythonhosted.org/packages/d5/81/0ab551e1b5d7f1339e2d6eb482456ccbe9025605b28eed2b1c0203aaaade/aiohttp-3.12.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:532542cb48691179455fab429cdb0d558b5e5290b033b87478f2aa6af5d20ace", size = 472566, upload-time = "2025-06-14T15:14:32.275Z" }, { url = "https://files.pythonhosted.org/packages/8d/e7/f73206afa33100804f790b71092888f47df65fd9a4cd0e6800d7c6826441/aiohttp-3.12.14-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3d62ac3d506cef54b355bd34c2a7c230eb693880001dfcda0bf88b38f5d7af7e", size = 473128, upload-time = "2025-07-10T13:04:21.928Z" },
{ url = "https://files.pythonhosted.org/packages/34/3f/6b7d336663337672d29b1f82d1f252ec1a040fe2d548f709d3f90fa2218a/aiohttp-3.12.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d7eea18b52f23c050ae9db5d01f3d264ab08f09e7356d6f68e3f3ac2de9dfabb", size = 464856, upload-time = "2025-06-14T15:14:34.132Z" }, { url = "https://files.pythonhosted.org/packages/df/e2/4dd00180be551a6e7ee979c20fc7c32727f4889ee3fd5b0586e0d47f30e1/aiohttp-3.12.14-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:48e43e075c6a438937c4de48ec30fa8ad8e6dfef122a038847456bfe7b947b63", size = 465426, upload-time = "2025-07-10T13:04:24.071Z" },
{ url = "https://files.pythonhosted.org/packages/26/7f/32ca0f170496aa2ab9b812630fac0c2372c531b797e1deb3deb4cea904bd/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad7c8e5c25f2a26842a7c239de3f7b6bfb92304593ef997c04ac49fb703ff4d7", size = 1703683, upload-time = "2025-06-14T15:14:36.034Z" }, { url = "https://files.pythonhosted.org/packages/de/dd/525ed198a0bb674a323e93e4d928443a680860802c44fa7922d39436b48b/aiohttp-3.12.14-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:077b4488411a9724cecc436cbc8c133e0d61e694995b8de51aaf351c7578949d", size = 1704252, upload-time = "2025-07-10T13:04:26.049Z" },
{ url = "https://files.pythonhosted.org/packages/ec/53/d5513624b33a811c0abea8461e30a732294112318276ce3dbf047dbd9d8b/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6af355b483e3fe9d7336d84539fef460120c2f6e50e06c658fe2907c69262d6b", size = 1684946, upload-time = "2025-06-14T15:14:38Z" }, { url = "https://files.pythonhosted.org/packages/d8/b1/01e542aed560a968f692ab4fc4323286e8bc4daae83348cd63588e4f33e3/aiohttp-3.12.14-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d8c35632575653f297dcbc9546305b2c1133391089ab925a6a3706dfa775ccab", size = 1685514, upload-time = "2025-07-10T13:04:28.186Z" },
{ url = "https://files.pythonhosted.org/packages/37/72/4c237dd127827b0247dc138d3ebd49c2ded6114c6991bbe969058575f25f/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a95cf9f097498f35c88e3609f55bb47b28a5ef67f6888f4390b3d73e2bac6177", size = 1737017, upload-time = "2025-06-14T15:14:39.951Z" }, { url = "https://files.pythonhosted.org/packages/b3/06/93669694dc5fdabdc01338791e70452d60ce21ea0946a878715688d5a191/aiohttp-3.12.14-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b8ce87963f0035c6834b28f061df90cf525ff7c9b6283a8ac23acee6502afd4", size = 1737586, upload-time = "2025-07-10T13:04:30.195Z" },
{ url = "https://files.pythonhosted.org/packages/0d/67/8a7eb3afa01e9d0acc26e1ef847c1a9111f8b42b82955fcd9faeb84edeb4/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8ed8c38a1c584fe99a475a8f60eefc0b682ea413a84c6ce769bb19a7ff1c5ef", size = 1786390, upload-time = "2025-06-14T15:14:42.151Z" }, { url = "https://files.pythonhosted.org/packages/a5/3a/18991048ffc1407ca51efb49ba8bcc1645961f97f563a6c480cdf0286310/aiohttp-3.12.14-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0a2cf66e32a2563bb0766eb24eae7e9a269ac0dc48db0aae90b575dc9583026", size = 1786958, upload-time = "2025-07-10T13:04:32.482Z" },
{ url = "https://files.pythonhosted.org/packages/48/19/0377df97dd0176ad23cd8cad4fd4232cfeadcec6c1b7f036315305c98e3f/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0b9170d5d800126b5bc89d3053a2363406d6e327afb6afaeda2d19ee8bb103", size = 1708719, upload-time = "2025-06-14T15:14:44.039Z" }, { url = "https://files.pythonhosted.org/packages/30/a8/81e237f89a32029f9b4a805af6dffc378f8459c7b9942712c809ff9e76e5/aiohttp-3.12.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdea089caf6d5cde975084a884c72d901e36ef9c2fd972c9f51efbbc64e96fbd", size = 1709287, upload-time = "2025-07-10T13:04:34.493Z" },
{ url = "https://files.pythonhosted.org/packages/61/97/ade1982a5c642b45f3622255173e40c3eed289c169f89d00eeac29a89906/aiohttp-3.12.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:372feeace612ef8eb41f05ae014a92121a512bd5067db8f25101dd88a8db11da", size = 1622424, upload-time = "2025-06-14T15:14:45.945Z" }, { url = "https://files.pythonhosted.org/packages/8c/e3/bd67a11b0fe7fc12c6030473afd9e44223d456f500f7cf526dbaa259ae46/aiohttp-3.12.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7865f27db67d49e81d463da64a59365ebd6b826e0e4847aa111056dcb9dc88", size = 1622990, upload-time = "2025-07-10T13:04:36.433Z" },
{ url = "https://files.pythonhosted.org/packages/99/ab/00ad3eea004e1d07ccc406e44cfe2b8da5acb72f8c66aeeb11a096798868/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a946d3702f7965d81f7af7ea8fb03bb33fe53d311df48a46eeca17e9e0beed2d", size = 1675447, upload-time = "2025-06-14T15:14:47.911Z" }, { url = "https://files.pythonhosted.org/packages/83/ba/e0cc8e0f0d9ce0904e3cf2d6fa41904e379e718a013c721b781d53dcbcca/aiohttp-3.12.14-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0ab5b38a6a39781d77713ad930cb5e7feea6f253de656a5f9f281a8f5931b086", size = 1676015, upload-time = "2025-07-10T13:04:38.958Z" },
{ url = "https://files.pythonhosted.org/packages/3f/fe/74e5ce8b2ccaba445fe0087abc201bfd7259431d92ae608f684fcac5d143/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a0c4725fae86555bbb1d4082129e21de7264f4ab14baf735278c974785cd2041", size = 1707110, upload-time = "2025-06-14T15:14:50.334Z" }, { url = "https://files.pythonhosted.org/packages/d8/b3/1e6c960520bda094c48b56de29a3d978254637ace7168dd97ddc273d0d6c/aiohttp-3.12.14-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9b3b15acee5c17e8848d90a4ebc27853f37077ba6aec4d8cb4dbbea56d156933", size = 1707678, upload-time = "2025-07-10T13:04:41.275Z" },
{ url = "https://files.pythonhosted.org/packages/ef/c4/39af17807f694f7a267bd8ab1fbacf16ad66740862192a6c8abac2bff813/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9b28ea2f708234f0a5c44eb6c7d9eb63a148ce3252ba0140d050b091b6e842d1", size = 1649706, upload-time = "2025-06-14T15:14:52.378Z" }, { url = "https://files.pythonhosted.org/packages/0a/19/929a3eb8c35b7f9f076a462eaa9830b32c7f27d3395397665caa5e975614/aiohttp-3.12.14-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e4c972b0bdaac167c1e53e16a16101b17c6d0ed7eac178e653a07b9f7fad7151", size = 1650274, upload-time = "2025-07-10T13:04:43.483Z" },
{ url = "https://files.pythonhosted.org/packages/38/e8/f5a0a5f44f19f171d8477059aa5f28a158d7d57fe1a46c553e231f698435/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d4f5becd2a5791829f79608c6f3dc745388162376f310eb9c142c985f9441cc1", size = 1725839, upload-time = "2025-06-14T15:14:54.617Z" }, { url = "https://files.pythonhosted.org/packages/22/e5/81682a6f20dd1b18ce3d747de8eba11cbef9b270f567426ff7880b096b48/aiohttp-3.12.14-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7442488b0039257a3bdbc55f7209587911f143fca11df9869578db6c26feeeb8", size = 1726408, upload-time = "2025-07-10T13:04:45.577Z" },
{ url = "https://files.pythonhosted.org/packages/fd/ac/81acc594c7f529ef4419d3866913f628cd4fa9cab17f7bf410a5c3c04c53/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:60f2ce6b944e97649051d5f5cc0f439360690b73909230e107fd45a359d3e911", size = 1759311, upload-time = "2025-06-14T15:14:56.597Z" }, { url = "https://files.pythonhosted.org/packages/8c/17/884938dffaa4048302985483f77dfce5ac18339aad9b04ad4aaa5e32b028/aiohttp-3.12.14-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f68d3067eecb64c5e9bab4a26aa11bd676f4c70eea9ef6536b0a4e490639add3", size = 1759879, upload-time = "2025-07-10T13:04:47.663Z" },
{ url = "https://files.pythonhosted.org/packages/38/0d/aabe636bd25c6ab7b18825e5a97d40024da75152bec39aa6ac8b7a677630/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69fc1909857401b67bf599c793f2183fbc4804717388b0b888f27f9929aa41f3", size = 1708202, upload-time = "2025-06-14T15:14:58.598Z" }, { url = "https://files.pythonhosted.org/packages/95/78/53b081980f50b5cf874359bde707a6eacd6c4be3f5f5c93937e48c9d0025/aiohttp-3.12.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f88d3704c8b3d598a08ad17d06006cb1ca52a1182291f04979e305c8be6c9758", size = 1708770, upload-time = "2025-07-10T13:04:49.944Z" },
{ url = "https://files.pythonhosted.org/packages/1f/ab/561ef2d8a223261683fb95a6283ad0d36cb66c87503f3a7dde7afe208bb2/aiohttp-3.12.13-cp313-cp313-win32.whl", hash = "sha256:7d7e68787a2046b0e44ba5587aa723ce05d711e3a3665b6b7545328ac8e3c0dd", size = 420794, upload-time = "2025-06-14T15:15:00.939Z" }, { url = "https://files.pythonhosted.org/packages/ed/91/228eeddb008ecbe3ffa6c77b440597fdf640307162f0c6488e72c5a2d112/aiohttp-3.12.14-cp313-cp313-win32.whl", hash = "sha256:a3c99ab19c7bf375c4ae3debd91ca5d394b98b6089a03231d4c580ef3c2ae4c5", size = 421688, upload-time = "2025-07-10T13:04:51.993Z" },
{ url = "https://files.pythonhosted.org/packages/9d/47/b11d0089875a23bff0abd3edb5516bcd454db3fefab8604f5e4b07bd6210/aiohttp-3.12.13-cp313-cp313-win_amd64.whl", hash = "sha256:5a178390ca90419bfd41419a809688c368e63c86bd725e1186dd97f6b89c2706", size = 446735, upload-time = "2025-06-14T15:15:02.858Z" }, { url = "https://files.pythonhosted.org/packages/66/5f/8427618903343402fdafe2850738f735fd1d9409d2a8f9bcaae5e630d3ba/aiohttp-3.12.14-cp313-cp313-win_amd64.whl", hash = "sha256:3f8aad695e12edc9d571f878c62bedc91adf30c760c8632f09663e5f564f4baa", size = 448098, upload-time = "2025-07-10T13:04:53.999Z" },
] ]
[[package]] [[package]]
@@ -152,11 +152,11 @@ wheels = [
[[package]] [[package]]
name = "certifi" name = "certifi"
version = "2025.6.15" version = "2025.7.14"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } sdist = { url = "https://files.pythonhosted.org/packages/b3/76/52c535bcebe74590f296d6c77c86dabf761c41980e1347a2422e4aa2ae41/certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995", size = 163981, upload-time = "2025-07-14T03:29:28.449Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, { url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722, upload-time = "2025-07-14T03:29:26.863Z" },
] ]
[[package]] [[package]]
@@ -440,25 +440,25 @@ wheels = [
[[package]] [[package]]
name = "orjson" name = "orjson"
version = "3.10.18" version = "3.11.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/81/0b/fea456a3ffe74e70ba30e01ec183a9b26bec4d497f61dcfce1b601059c60/orjson-3.10.18.tar.gz", hash = "sha256:e8da3947d92123eda795b68228cafe2724815621fe35e8e320a9e9593a4bcd53", size = 5422810, upload-time = "2025-04-29T23:30:08.423Z" } sdist = { url = "https://files.pythonhosted.org/packages/29/87/03ababa86d984952304ac8ce9fbd3a317afb4a225b9a81f9b606ac60c873/orjson-3.11.0.tar.gz", hash = "sha256:2e4c129da624f291bcc607016a99e7f04a353f6874f3bd8d9b47b88597d5f700", size = 5318246, upload-time = "2025-07-15T16:08:29.194Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/04/f0/8aedb6574b68096f3be8f74c0b56d36fd94bcf47e6c7ed47a7bd1474aaa8/orjson-3.10.18-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:69c34b9441b863175cc6a01f2935de994025e773f814412030f269da4f7be147", size = 249087, upload-time = "2025-04-29T23:29:19.083Z" }, { url = "https://files.pythonhosted.org/packages/31/63/82d9b6b48624009d230bc6038e54778af8f84dfd54402f9504f477c5cfd5/orjson-3.11.0-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a8ba9698655e16746fdf5266939427da0f9553305152aeb1a1cc14974a19cfb", size = 240125, upload-time = "2025-07-15T16:07:35.976Z" },
{ url = "https://files.pythonhosted.org/packages/bc/f7/7118f965541aeac6844fcb18d6988e111ac0d349c9b80cda53583e758908/orjson-3.10.18-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:1ebeda919725f9dbdb269f59bc94f861afbe2a27dce5608cdba2d92772364d1c", size = 133273, upload-time = "2025-04-29T23:29:20.602Z" }, { url = "https://files.pythonhosted.org/packages/16/3a/d557ed87c63237d4c97a7bac7ac054c347ab8c4b6da09748d162ca287175/orjson-3.11.0-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:67133847f9a35a5ef5acfa3325d4a2f7fe05c11f1505c4117bb086fc06f2a58f", size = 129189, upload-time = "2025-07-15T16:07:37.486Z" },
{ url = "https://files.pythonhosted.org/packages/fb/d9/839637cc06eaf528dd8127b36004247bf56e064501f68df9ee6fd56a88ee/orjson-3.10.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5adf5f4eed520a4959d29ea80192fa626ab9a20b2ea13f8f6dc58644f6927103", size = 136779, upload-time = "2025-04-29T23:29:22.062Z" }, { url = "https://files.pythonhosted.org/packages/69/5e/b2c9e22e2cd10aa7d76a629cee65d661e06a61fbaf4dc226386f5636dd44/orjson-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f797d57814975b78f5f5423acb003db6f9be5186b72d48bd97a1000e89d331d", size = 131953, upload-time = "2025-07-15T16:07:39.254Z" },
{ url = "https://files.pythonhosted.org/packages/2b/6d/f226ecfef31a1f0e7d6bf9a31a0bbaf384c7cbe3fce49cc9c2acc51f902a/orjson-3.10.18-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7592bb48a214e18cd670974f289520f12b7aed1fa0b2e2616b8ed9e069e08595", size = 132811, upload-time = "2025-04-29T23:29:23.602Z" }, { url = "https://files.pythonhosted.org/packages/e2/60/760fcd9b50eb44d1206f2b30c8d310b79714553b9d94a02f9ea3252ebe63/orjson-3.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:28acd19822987c5163b9e03a6e60853a52acfee384af2b394d11cb413b889246", size = 126922, upload-time = "2025-07-15T16:07:41.282Z" },
{ url = "https://files.pythonhosted.org/packages/73/2d/371513d04143c85b681cf8f3bce743656eb5b640cb1f461dad750ac4b4d4/orjson-3.10.18-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f872bef9f042734110642b7a11937440797ace8c87527de25e0c53558b579ccc", size = 137018, upload-time = "2025-04-29T23:29:25.094Z" }, { url = "https://files.pythonhosted.org/packages/6a/7a/8c46daa867ccc92da6de9567608be62052774b924a77c78382e30d50b579/orjson-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8d38d9e1e2cf9729658e35956cf01e13e89148beb4cb9e794c9c10c5cb252f8", size = 128787, upload-time = "2025-07-15T16:07:42.681Z" },
{ url = "https://files.pythonhosted.org/packages/69/cb/a4d37a30507b7a59bdc484e4a3253c8141bf756d4e13fcc1da760a0b00cb/orjson-3.10.18-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0315317601149c244cb3ecef246ef5861a64824ccbcb8018d32c66a60a84ffbc", size = 138368, upload-time = "2025-04-29T23:29:26.609Z" }, { url = "https://files.pythonhosted.org/packages/f2/14/a2f1b123d85f11a19e8749f7d3f9ed6c9b331c61f7b47cfd3e9a1fedb9bc/orjson-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05f094edd2b782650b0761fd78858d9254de1c1286f5af43145b3d08cdacfd51", size = 131895, upload-time = "2025-07-15T16:07:44.519Z" },
{ url = "https://files.pythonhosted.org/packages/1e/ae/cd10883c48d912d216d541eb3db8b2433415fde67f620afe6f311f5cd2ca/orjson-3.10.18-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0da26957e77e9e55a6c2ce2e7182a36a6f6b180ab7189315cb0995ec362e049", size = 142840, upload-time = "2025-04-29T23:29:28.153Z" }, { url = "https://files.pythonhosted.org/packages/c8/10/362e8192df7528e8086ea712c5cb01355c8d4e52c59a804417ba01e2eb2d/orjson-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d09176a4a9e04a5394a4a0edd758f645d53d903b306d02f2691b97d5c736a9e", size = 133868, upload-time = "2025-07-15T16:07:46.227Z" },
{ url = "https://files.pythonhosted.org/packages/6d/4c/2bda09855c6b5f2c055034c9eda1529967b042ff8d81a05005115c4e6772/orjson-3.10.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb70d489bc79b7519e5803e2cc4c72343c9dc1154258adf2f8925d0b60da7c58", size = 133135, upload-time = "2025-04-29T23:29:29.726Z" }, { url = "https://files.pythonhosted.org/packages/f8/4e/ef43582ef3e3dfd2a39bc3106fa543364fde1ba58489841120219da6e22f/orjson-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a585042104e90a61eda2564d11317b6a304eb4e71cd33e839f5af6be56c34d3", size = 128234, upload-time = "2025-07-15T16:07:48.123Z" },
{ url = "https://files.pythonhosted.org/packages/13/4a/35971fd809a8896731930a80dfff0b8ff48eeb5d8b57bb4d0d525160017f/orjson-3.10.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9e86a6af31b92299b00736c89caf63816f70a4001e750bda179e15564d7a034", size = 134810, upload-time = "2025-04-29T23:29:31.269Z" }, { url = "https://files.pythonhosted.org/packages/d7/fa/02dabb2f1d605bee8c4bb1160cfc7467976b1ed359a62cc92e0681b53c45/orjson-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d2218629dbfdeeb5c9e0573d59f809d42f9d49ae6464d2f479e667aee14c3ef4", size = 130232, upload-time = "2025-07-15T16:07:50.197Z" },
{ url = "https://files.pythonhosted.org/packages/99/70/0fa9e6310cda98365629182486ff37a1c6578e34c33992df271a476ea1cd/orjson-3.10.18-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c382a5c0b5931a5fc5405053d36c1ce3fd561694738626c77ae0b1dfc0242ca1", size = 413491, upload-time = "2025-04-29T23:29:33.315Z" }, { url = "https://files.pythonhosted.org/packages/16/76/951b5619605c8d2ede80cc989f32a66abc954530d86e84030db2250c63a1/orjson-3.11.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:613e54a2b10b51b656305c11235a9c4a5c5491ef5c283f86483d4e9e123ed5e4", size = 403648, upload-time = "2025-07-15T16:07:52.136Z" },
{ url = "https://files.pythonhosted.org/packages/32/cb/990a0e88498babddb74fb97855ae4fbd22a82960e9b06eab5775cac435da/orjson-3.10.18-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8e4b2ae732431127171b875cb2668f883e1234711d3c147ffd69fe5be51a8012", size = 153277, upload-time = "2025-04-29T23:29:34.946Z" }, { url = "https://files.pythonhosted.org/packages/96/e2/5fa53bb411455a63b3713db90b588e6ca5ed2db59ad49b3fb8a0e94e0dda/orjson-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9dac7fbf3b8b05965986c5cfae051eb9a30fced7f15f1d13a5adc608436eb486", size = 144572, upload-time = "2025-07-15T16:07:54.004Z" },
{ url = "https://files.pythonhosted.org/packages/92/44/473248c3305bf782a384ed50dd8bc2d3cde1543d107138fd99b707480ca1/orjson-3.10.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d808e34ddb24fc29a4d4041dcfafbae13e129c93509b847b14432717d94b44f", size = 137367, upload-time = "2025-04-29T23:29:36.52Z" }, { url = "https://files.pythonhosted.org/packages/ad/d0/7d6f91e1e0f034258c3a3358f20b0c9490070e8a7ab8880085547274c7f9/orjson-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b64b254414e2be55ac5257124b5602c5f0b4d06b80bd27d1165efe8f36e836", size = 132766, upload-time = "2025-07-15T16:07:55.936Z" },
{ url = "https://files.pythonhosted.org/packages/ad/fd/7f1d3edd4ffcd944a6a40e9f88af2197b619c931ac4d3cfba4798d4d3815/orjson-3.10.18-cp313-cp313-win32.whl", hash = "sha256:ad8eacbb5d904d5591f27dee4031e2c1db43d559edb8f91778efd642d70e6bea", size = 142687, upload-time = "2025-04-29T23:29:38.292Z" }, { url = "https://files.pythonhosted.org/packages/ff/f8/4d46481f1b3fb40dc826d62179f96c808eb470cdcc74b6593fb114d74af3/orjson-3.11.0-cp313-cp313-win32.whl", hash = "sha256:359cbe11bc940c64cb3848cf22000d2aef36aff7bfd09ca2c0b9cb309c387132", size = 134638, upload-time = "2025-07-15T16:07:57.343Z" },
{ url = "https://files.pythonhosted.org/packages/4b/03/c75c6ad46be41c16f4cfe0352a2d1450546f3c09ad2c9d341110cd87b025/orjson-3.10.18-cp313-cp313-win_amd64.whl", hash = "sha256:aed411bcb68bf62e85588f2a7e03a6082cc42e5a2796e06e72a962d7c6310b52", size = 134794, upload-time = "2025-04-29T23:29:40.349Z" }, { url = "https://files.pythonhosted.org/packages/85/3f/544938dcfb7337d85ee1e43d7685cf8f3bfd452e0b15a32fe70cb4ca5094/orjson-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:0759b36428067dc777b202dd286fbdd33d7f261c6455c4238ea4e8474358b1e6", size = 129411, upload-time = "2025-07-15T16:07:58.852Z" },
{ url = "https://files.pythonhosted.org/packages/c2/28/f53038a5a72cc4fd0b56c1eafb4ef64aec9685460d5ac34de98ca78b6e29/orjson-3.10.18-cp313-cp313-win_arm64.whl", hash = "sha256:f54c1385a0e6aba2f15a40d703b858bedad36ded0491e55d35d905b2c34a4cc3", size = 131186, upload-time = "2025-04-29T23:29:41.922Z" }, { url = "https://files.pythonhosted.org/packages/43/0c/f75015669d7817d222df1bb207f402277b77d22c4833950c8c8c7cf2d325/orjson-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:51cdca2f36e923126d0734efaf72ddbb5d6da01dbd20eab898bdc50de80d7b5a", size = 126349, upload-time = "2025-07-15T16:08:00.322Z" },
] ]
[[package]] [[package]]
@@ -647,15 +647,15 @@ wheels = [
[[package]] [[package]]
name = "sentry-sdk" name = "sentry-sdk"
version = "2.32.0" version = "2.33.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "certifi" }, { name = "certifi" },
{ name = "urllib3" }, { name = "urllib3" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/10/59/eb90c45cb836cf8bec973bba10230ddad1c55e2b2e9ffa9d7d7368948358/sentry_sdk-2.32.0.tar.gz", hash = "sha256:9016c75d9316b0f6921ac14c8cd4fb938f26002430ac5be9945ab280f78bec6b", size = 334932, upload-time = "2025-06-27T08:10:02.89Z" } sdist = { url = "https://files.pythonhosted.org/packages/09/0b/6139f589436c278b33359845ed77019cd093c41371f898283bbc14d26c02/sentry_sdk-2.33.0.tar.gz", hash = "sha256:cdceed05e186846fdf80ceea261fe0a11ebc93aab2f228ed73d076a07804152e", size = 335233, upload-time = "2025-07-15T12:07:42.413Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/01/a1/fc4856bd02d2097324fb7ce05b3021fb850f864b83ca765f6e37e92ff8ca/sentry_sdk-2.32.0-py2.py3-none-any.whl", hash = "sha256:6cf51521b099562d7ce3606da928c473643abe99b00ce4cb5626ea735f4ec345", size = 356122, upload-time = "2025-06-27T08:10:01.424Z" }, { url = "https://files.pythonhosted.org/packages/93/e5/f24e9f81c9822a24a2627cfcb44c10a3971382e67e5015c6e068421f5787/sentry_sdk-2.33.0-py2.py3-none-any.whl", hash = "sha256:a762d3f19a1c240e16c98796f2a5023f6e58872997d5ae2147ac3ed378b23ec2", size = 356397, upload-time = "2025-07-15T12:07:40.729Z" },
] ]
[[package]] [[package]]