sentry-relay 0.8.57__zip → 0.8.59__zip

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sentry-relay
3
- Version: 0.8.57
3
+ Version: 0.8.59
4
4
  Summary: A python library to access sentry relay functionality.
5
5
  Author: Sentry
6
6
  Author-email: hello@sentry.io
@@ -1,5 +1,7 @@
1
1
  import json
2
2
  import uuid
3
+ from typing import Callable, Any
4
+
3
5
  from sentry_relay._lowlevel import lib
4
6
  from sentry_relay.utils import (
5
7
  RustObject,
@@ -38,10 +40,16 @@ class PublicKey(RustObject):
38
40
  return self._methodcall(lib.relay_publickey_verify, buf, sig)
39
41
  return self._methodcall(lib.relay_publickey_verify_timestamp, buf, sig, max_age)
40
42
 
41
- def unpack(self, buf, sig, max_age=None):
43
+ def unpack(
44
+ self,
45
+ buf,
46
+ sig,
47
+ max_age=None,
48
+ json_loads: Callable[[str | bytes], Any] = json.loads,
49
+ ):
42
50
  if not self.verify(buf, sig, max_age):
43
51
  raise UnpackErrorBadSignature("invalid signature")
44
- return json.loads(buf)
52
+ return json_loads(buf)
45
53
 
46
54
  def __str__(self):
47
55
  return decode_str(self._methodcall(lib.relay_publickey_to_string), free=True)
@@ -64,7 +72,8 @@ class SecretKey(RustObject):
64
72
  return decode_str(self._methodcall(lib.relay_secretkey_sign, buf), free=True)
65
73
 
66
74
  def pack(self, data):
67
- packed = json.dumps(data, separators=(",", ":")).encode("utf8")
75
+ # TODO(@anonrig): Look into separators requirement
76
+ packed = json.dumps(data, separators=(",", ":")).encode()
68
77
  return packed, self.sign(packed)
69
78
 
70
79
  def __str__(self):
@@ -86,7 +95,13 @@ def generate_relay_id():
86
95
  return decode_uuid(rustcall(lib.relay_generate_relay_id))
87
96
 
88
97
 
89
- def create_register_challenge(data, signature, secret, max_age=60):
98
+ def create_register_challenge(
99
+ data,
100
+ signature,
101
+ secret,
102
+ max_age=60,
103
+ json_loads: Callable[[str | bytes], Any] = json.loads,
104
+ ):
90
105
  challenge_json = rustcall(
91
106
  lib.relay_create_register_challenge,
92
107
  make_buf(data),
@@ -95,14 +110,20 @@ def create_register_challenge(data, signature, secret, max_age=60):
95
110
  max_age,
96
111
  )
97
112
 
98
- challenge = json.loads(decode_str(challenge_json, free=True))
113
+ challenge = json_loads(decode_str(challenge_json, free=True))
99
114
  return {
100
115
  "relay_id": uuid.UUID(challenge["relay_id"]),
101
116
  "token": challenge["token"],
102
117
  }
103
118
 
104
119
 
105
- def validate_register_response(data, signature, secret, max_age=60):
120
+ def validate_register_response(
121
+ data,
122
+ signature,
123
+ secret,
124
+ max_age=60,
125
+ json_loads: Callable[[str | bytes], Any] = json.loads,
126
+ ):
106
127
  response_json = rustcall(
107
128
  lib.relay_validate_register_response,
108
129
  make_buf(data),
@@ -111,7 +132,7 @@ def validate_register_response(data, signature, secret, max_age=60):
111
132
  max_age,
112
133
  )
113
134
 
114
- response = json.loads(decode_str(response_json, free=True))
135
+ response = json_loads(decode_str(response_json, free=True))
115
136
  return {
116
137
  "relay_id": uuid.UUID(response["relay_id"]),
117
138
  "token": response["token"],
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import json
4
+ from typing import Callable, Any
4
5
 
5
6
  from sentry_relay._lowlevel import lib, ffi
6
7
  from sentry_relay.utils import (
@@ -12,7 +13,6 @@ from sentry_relay.utils import (
12
13
  make_buf,
13
14
  )
14
15
 
15
-
16
16
  __all__ = [
17
17
  "split_chunks",
18
18
  "meta_with_chunks",
@@ -31,6 +31,7 @@ __all__ = [
31
31
  "validate_sampling_condition",
32
32
  "validate_sampling_configuration",
33
33
  "validate_project_config",
34
+ "normalize_cardinality_limit_config",
34
35
  "normalize_global_config",
35
36
  ]
36
37
 
@@ -49,13 +50,18 @@ def _init_valid_platforms() -> frozenset[str]:
49
50
  VALID_PLATFORMS = _init_valid_platforms()
50
51
 
51
52
 
52
- def split_chunks(string, remarks):
53
+ def split_chunks(
54
+ string,
55
+ remarks,
56
+ json_dumps: Callable[[Any], Any] = json.dumps,
57
+ json_loads: Callable[[str | bytes], Any] = json.loads,
58
+ ):
53
59
  json_chunks = rustcall(
54
60
  lib.relay_split_chunks,
55
61
  encode_str(string),
56
- encode_str(json.dumps(remarks)),
62
+ encode_str(json_dumps(remarks)),
57
63
  )
58
- return json.loads(decode_str(json_chunks, free=True))
64
+ return json_loads(decode_str(json_chunks, free=True))
59
65
 
60
66
 
61
67
  def meta_with_chunks(data, meta):
@@ -101,8 +107,10 @@ class StoreNormalizer(RustObject):
101
107
  __init__ = object.__init__
102
108
  __slots__ = ("__weakref__",)
103
109
 
104
- def __new__(cls, geoip_lookup=None, **config):
105
- config = json.dumps(config)
110
+ def __new__(
111
+ cls, geoip_lookup=None, json_dumps: Callable[[Any], Any] = json.dumps, **config
112
+ ):
113
+ config = json_dumps(config)
106
114
  geoptr = geoip_lookup._get_objptr() if geoip_lookup is not None else ffi.NULL
107
115
  rv = cls._from_objptr(
108
116
  rustcall(lib.relay_store_normalizer_new, encode_str(config), geoptr)
@@ -111,16 +119,22 @@ class StoreNormalizer(RustObject):
111
119
  attached_refs[rv] = geoip_lookup
112
120
  return rv
113
121
 
114
- def normalize_event(self, event=None, raw_event=None):
122
+ def normalize_event(
123
+ self,
124
+ event=None,
125
+ raw_event=None,
126
+ json_loads: Callable[[str | bytes], Any] = json.loads,
127
+ ):
115
128
  if raw_event is None:
116
129
  raw_event = _serialize_event(event)
117
130
 
118
131
  event = _encode_raw_event(raw_event)
119
132
  rv = self._methodcall(lib.relay_store_normalizer_normalize_event, event)
120
- return json.loads(decode_str(rv, free=True))
133
+ return json_loads(decode_str(rv, free=True))
121
134
 
122
135
 
123
136
  def _serialize_event(event):
137
+ # TODO(@anonrig): Look into ensure_ascii requirement
124
138
  raw_event = json.dumps(event, ensure_ascii=False)
125
139
  if isinstance(raw_event, str):
126
140
  raw_event = raw_event.encode("utf-8", errors="replace")
@@ -194,39 +208,52 @@ def validate_pii_config(config):
194
208
  raise ValueError(error)
195
209
 
196
210
 
197
- def convert_datascrubbing_config(config):
211
+ def convert_datascrubbing_config(
212
+ config,
213
+ json_dumps: Callable[[Any], Any] = json.dumps,
214
+ json_loads: Callable[[str | bytes], Any] = json.loads,
215
+ ):
198
216
  """
199
217
  Convert an old datascrubbing config to the new PII config format.
200
218
  """
201
- raw_config = encode_str(json.dumps(config))
219
+ raw_config = encode_str(json_dumps(config))
202
220
  raw_rv = rustcall(lib.relay_convert_datascrubbing_config, raw_config)
203
- return json.loads(decode_str(raw_rv, free=True))
221
+ return json_loads(decode_str(raw_rv, free=True))
204
222
 
205
223
 
206
- def pii_strip_event(config, event):
224
+ def pii_strip_event(
225
+ config,
226
+ event,
227
+ json_dumps: Callable[[Any], Any] = json.dumps,
228
+ json_loads: Callable[[str | bytes], Any] = json.loads,
229
+ ):
207
230
  """
208
231
  Scrub an event using new PII stripping config.
209
232
  """
210
- raw_config = encode_str(json.dumps(config))
211
- raw_event = encode_str(json.dumps(event))
233
+ raw_config = encode_str(json_dumps(config))
234
+ raw_event = encode_str(json_dumps(event))
212
235
  raw_rv = rustcall(lib.relay_pii_strip_event, raw_config, raw_event)
213
- return json.loads(decode_str(raw_rv, free=True))
236
+ return json_loads(decode_str(raw_rv, free=True))
214
237
 
215
238
 
216
- def pii_selector_suggestions_from_event(event):
239
+ def pii_selector_suggestions_from_event(
240
+ event,
241
+ json_dumps: Callable[[Any], Any] = json.dumps,
242
+ json_loads: Callable[[str | bytes], Any] = json.loads,
243
+ ):
217
244
  """
218
245
  Walk through the event and collect selectors that can be applied to it in a
219
246
  PII config. This function is used in the UI to provide auto-completion of
220
247
  selectors.
221
248
  """
222
- raw_event = encode_str(json.dumps(event))
249
+ raw_event = encode_str(json_dumps(event))
223
250
  raw_rv = rustcall(lib.relay_pii_selector_suggestions_from_event, raw_event)
224
- return json.loads(decode_str(raw_rv, free=True))
251
+ return json_loads(decode_str(raw_rv, free=True))
225
252
 
226
253
 
227
- def parse_release(release):
254
+ def parse_release(release, json_loads: Callable[[str | bytes], Any] = json.loads):
228
255
  """Parses a release string into a dictionary of its components."""
229
- return json.loads(
256
+ return json_loads(
230
257
  decode_str(rustcall(lib.relay_parse_release, encode_str(release)), free=True)
231
258
  )
232
259
 
@@ -283,7 +310,39 @@ def validate_project_config(config, strict: bool):
283
310
  raise ValueError(error)
284
311
 
285
312
 
286
- def normalize_global_config(config):
313
+ def normalize_cardinality_limit_config(
314
+ config,
315
+ json_dumps: Callable[[Any], Any] = json.dumps,
316
+ json_loads: Callable[[str | bytes], Any] = json.loads,
317
+ ):
318
+ """Normalize the cardinality limit config.
319
+
320
+ Normalization consists of deserializing and serializing back the given
321
+ cardinality limit config. If deserializing fails, throw an exception. Note that even if
322
+ the roundtrip doesn't produce errors, the given config may differ from
323
+ normalized one.
324
+
325
+ :param config: the cardinality limit config to validate.
326
+ :param json_dumps: a function that stringifies python objects
327
+ :param json_loads: a function that parses and converts JSON strings
328
+ """
329
+ serialized = json_dumps(config)
330
+ normalized = rustcall(
331
+ lib.normalize_cardinality_limit_config, encode_str(serialized)
332
+ )
333
+ rv = decode_str(normalized, free=True)
334
+ try:
335
+ return json_loads(rv)
336
+ except Exception:
337
+ # Catch all errors since json.loads implementation can change.
338
+ raise ValueError(rv)
339
+
340
+
341
+ def normalize_global_config(
342
+ config,
343
+ json_dumps: Callable[[Any], Any] = json.dumps,
344
+ json_loads: Callable[[str | bytes], Any] = json.loads,
345
+ ):
287
346
  """Normalize the global config.
288
347
 
289
348
  Normalization consists of deserializing and serializing back the given
@@ -292,11 +351,14 @@ def normalize_global_config(config):
292
351
  normalized one.
293
352
 
294
353
  :param config: the global config to validate.
354
+ :param json_dumps: a function that stringifies python objects
355
+ :param json_loads: a function that parses and converts JSON strings
295
356
  """
296
- serialized = json.dumps(config)
357
+ serialized = json_dumps(config)
297
358
  normalized = rustcall(lib.normalize_global_config, encode_str(serialized))
298
359
  rv = decode_str(normalized, free=True)
299
360
  try:
300
- return json.loads(rv)
301
- except json.JSONDecodeError:
361
+ return json_loads(rv)
362
+ except Exception:
363
+ # Catch all errors since json.loads implementation can change.
302
364
  raise ValueError(rv)
@@ -0,0 +1 @@
1
+ 0.8.59
@@ -1 +0,0 @@
1
- 0.8.57
File without changes
File without changes