diff --git a/pyproject.toml b/pyproject.toml index 4d323c49836886..704559ec8e75d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ dependencies = [ "mmh3>=4.0.0", "msgspec>=0.19.0", "msgpack>=1.1.0", - "objectstore-client>=0.1.1", + "objectstore-client>=0.1.5", "openai>=1.3.5", "orjson>=3.10.10", "p4python>=2025.1.2767466", diff --git a/src/sentry/lang/native/symbolicator.py b/src/sentry/lang/native/symbolicator.py index 9e2d701837d5e1..5d788dd104b1a8 100644 --- a/src/sentry/lang/native/symbolicator.py +++ b/src/sentry/lang/native/symbolicator.py @@ -114,11 +114,21 @@ def __init__( self.project = project self.event_id = event_id - def _process(self, task_name: str, path: str, **kwargs): + def _process( + self, + task_name: str, + path: str, + kwargs_cb: Callable[[], dict[str, Any]] | None = None, + **kwargs: Any, + ) -> Any: """ This function will submit a symbolication task to a Symbolicator and handle polling it using the `SymbolicatorSession`. It will also correctly handle `TaskIdNotFound` and `ServiceUnavailable` errors. + + `kwargs_cb`, if provided, is called on every new task submission and its result + is merged over `kwargs`. Use this for values that must be fresh on each + (re)submission, such as expiring tokens. """ session = SymbolicatorSession( url=self.base_url, @@ -137,7 +147,8 @@ def _process(self, task_name: str, path: str, **kwargs): try: if not task_id: # We are submitting a new task to Symbolicator - json_response = session.create_task(path, **kwargs) + create_kwargs = {**kwargs, **(kwargs_cb() if kwargs_cb else {})} + json_response = session.create_task(path, **create_kwargs) else: # The task has already been submitted to Symbolicator and we are polling json_response = session.query_task(task_id) @@ -201,7 +212,12 @@ def process_minidump( "rewrite_first_module": rewrite_first_module, }, } - res = self._process("process_minidump", "symbolicate-any", json=json) + + def cb() -> dict[str, Any]: + json["symbolicate"]["storage_token"] = session.mint_token() + return {"json": json} + + res = self._process("process_minidump", "symbolicate-any", kwargs_cb=cb) return process_response(res) data = { @@ -233,7 +249,12 @@ def process_applecrashreport(self, platform: str, report: CachedAttachment): "storage_url": storage_url, }, } - res = self._process("process_applecrashreport", "symbolicate-any", json=json) + + def cb() -> dict[str, Any]: + json["symbolicate"]["storage_token"] = session.mint_token() + return {"json": json} + + res = self._process("process_applecrashreport", "symbolicate-any", kwargs_cb=cb) return process_response(res) data = { diff --git a/uv.lock b/uv.lock index cb70c310833363..d4c5e7b677ace0 100644 --- a/uv.lock +++ b/uv.lock @@ -1322,7 +1322,7 @@ wheels = [ [[package]] name = "objectstore-client" -version = "0.1.1" +version = "0.1.5" source = { registry = "https://pypi.devinfra.sentry.io/simple" } dependencies = [ { name = "filetype", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, @@ -1332,7 +1332,7 @@ dependencies = [ { name = "zstandard", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/objectstore_client-0.1.1-py3-none-any.whl", hash = "sha256:fb63e88b6db101440b45f951810a35df41ade599f90791a1068e4da4e8e10691" }, + { url = "https://pypi.devinfra.sentry.io/wheels/objectstore_client-0.1.5-py3-none-any.whl", hash = "sha256:19ffcef5e33070d418268067e424fcb8de0739bfd2d310bc2de95a6791845857" }, ] [[package]] @@ -2337,7 +2337,7 @@ requires-dist = [ { name = "mmh3", specifier = ">=4.0.0" }, { name = "msgpack", specifier = ">=1.1.0" }, { name = "msgspec", specifier = ">=0.19.0" }, - { name = "objectstore-client", specifier = ">=0.1.1" }, + { name = "objectstore-client", specifier = ">=0.1.5" }, { name = "openai", specifier = ">=1.3.5" }, { name = "orjson", specifier = ">=3.10.10" }, { name = "p4python", specifier = ">=2025.1.2767466" },