plain.observer 0.9.1__py3-none-any.whl → 0.10.1__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.

Potentially problematic release.


This version of plain.observer might be problematic. Click here for more details.

@@ -1,5 +1,27 @@
1
1
  # plain-observer changelog
2
2
 
3
+ ## [0.10.1](https://github.com/dropseed/plain/releases/plain-observer@0.10.1) (2025-10-08)
4
+
5
+ ### What's changed
6
+
7
+ - Fixed content negotiation priority in trace detail and shared views to prefer HTML over JSON by default ([00212835aa](https://github.com/dropseed/plain/commit/00212835aa))
8
+
9
+ ### Upgrade instructions
10
+
11
+ - No changes required
12
+
13
+ ## [0.10.0](https://github.com/dropseed/plain/releases/plain-observer@0.10.0) (2025-10-07)
14
+
15
+ ### What's changed
16
+
17
+ - Model configuration now uses `model_options` descriptor instead of `class Meta` for improved consistency with Plain framework patterns ([17a378d](https://github.com/dropseed/plain/commit/17a378dcfb))
18
+ - Custom QuerySet classes are now defined as descriptors on the model class instead of being configured in Meta ([2578301](https://github.com/dropseed/plain/commit/2578301819))
19
+ - Internal model metadata split into separate `model_options` and `_model_meta` attributes for better organization ([73ba469](https://github.com/dropseed/plain/commit/73ba469ba0))
20
+
21
+ ### Upgrade instructions
22
+
23
+ - No changes required
24
+
3
25
  ## [0.9.1](https://github.com/dropseed/plain/releases/plain-observer@0.9.1) (2025-10-06)
4
26
 
5
27
  ### What's changed
plain/observer/models.py CHANGED
@@ -63,21 +63,22 @@ class Trace(models.Model):
63
63
  spans: BaseRelatedManager
64
64
  logs: BaseRelatedManager
65
65
 
66
- class Meta:
67
- ordering = ["-start_time"]
68
- constraints = [
66
+ model_options = models.Options(
67
+ ordering=["-start_time"],
68
+ constraints=[
69
69
  models.UniqueConstraint(
70
70
  fields=["trace_id"],
71
71
  name="observer_unique_trace_id",
72
72
  )
73
- ]
74
- indexes = [
73
+ ],
74
+ indexes=[
75
75
  models.Index(fields=["trace_id"]),
76
76
  models.Index(fields=["start_time"]),
77
77
  models.Index(fields=["request_id"]),
78
78
  models.Index(fields=["share_id"]),
79
79
  models.Index(fields=["session_id"]),
80
- ]
80
+ ],
81
+ )
81
82
 
82
83
  def __str__(self) -> str:
83
84
  return self.trace_id
@@ -268,7 +269,7 @@ class Trace(models.Model):
268
269
  return sorted(events, key=lambda x: x["timestamp"])
269
270
 
270
271
 
271
- class SpanQuerySet(models.QuerySet):
272
+ class SpanQuerySet(models.QuerySet["Span"]):
272
273
  def annotate_spans(self) -> list[Span]:
273
274
  """Annotate spans with nesting levels and duplicate query warnings."""
274
275
  spans: list[Span] = list(self.order_by("start_time"))
@@ -329,21 +330,23 @@ class Span(models.Model):
329
330
  status = models.CharField(max_length=50, default="", required=False)
330
331
  span_data = models.JSONField(default=dict, required=False)
331
332
 
332
- class Meta:
333
- queryset_class = SpanQuerySet
334
- ordering = ["-start_time"]
335
- constraints = [
333
+ query = SpanQuerySet()
334
+
335
+ model_options = models.Options(
336
+ ordering=["-start_time"],
337
+ constraints=[
336
338
  models.UniqueConstraint(
337
339
  fields=["trace", "span_id"],
338
340
  name="observer_unique_span_id",
339
341
  )
340
- ]
341
- indexes = [
342
+ ],
343
+ indexes=[
342
344
  models.Index(fields=["span_id"]),
343
345
  models.Index(fields=["trace", "span_id"]),
344
346
  models.Index(fields=["trace"]),
345
347
  models.Index(fields=["start_time"]),
346
- ]
348
+ ],
349
+ )
347
350
 
348
351
  if TYPE_CHECKING:
349
352
  level: int
@@ -513,11 +516,12 @@ class Log(models.Model):
513
516
  level = models.CharField(max_length=20)
514
517
  message = models.TextField()
515
518
 
516
- class Meta:
517
- ordering = ["timestamp"]
518
- indexes = [
519
+ model_options = models.Options(
520
+ ordering=["timestamp"],
521
+ indexes=[
519
522
  models.Index(fields=["trace", "timestamp"]),
520
523
  models.Index(fields=["trace", "span"]),
521
524
  models.Index(fields=["timestamp"]),
522
525
  models.Index(fields=["trace"]),
523
- ]
526
+ ],
527
+ )
plain/observer/views.py CHANGED
@@ -95,7 +95,7 @@ class ObserverTraceDetailView(AuthViewMixin, HTMXViewMixin, DetailView):
95
95
 
96
96
  def get(self) -> Response | dict[str, Any]:
97
97
  """Return trace data as HTML, JSON, or logs based on content negotiation."""
98
- preferred = self.request.get_preferred_type("application/json", "text/html")
98
+ preferred = self.request.get_preferred_type("text/html", "application/json")
99
99
  if (
100
100
  preferred == "application/json"
101
101
  or self.request.query_params.get("format") == "json"
@@ -152,7 +152,7 @@ class ObserverTraceSharedView(DetailView):
152
152
 
153
153
  def get(self) -> Response:
154
154
  """Return trace data as HTML or JSON based on content negotiation."""
155
- preferred = self.request.get_preferred_type("application/json", "text/html")
155
+ preferred = self.request.get_preferred_type("text/html", "application/json")
156
156
  if (
157
157
  preferred == "application/json"
158
158
  or self.request.query_params.get("format") == "json"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain.observer
3
- Version: 0.9.1
3
+ Version: 0.10.1
4
4
  Summary: On-page telemetry and observability tools for Plain.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-Expression: BSD-3-Clause
@@ -1,4 +1,4 @@
1
- plain/observer/CHANGELOG.md,sha256=tzyY2QPhIi8SAY2YJCX_wZ_MZcpClPVTi6basGYWhfQ,12121
1
+ plain/observer/CHANGELOG.md,sha256=IXLAThjkA3UlFLMgIn0lei4Q_VFwxDjbC2Pl2xyW9pU,13178
2
2
  plain/observer/README.md,sha256=39RA17fgcyOkqeIWBOAg4Be6YZjoiDzK5PVOG-nseuY,988
3
3
  plain/observer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  plain/observer/admin.py,sha256=mSwJWfA9svhjZCzwqjD82Fv_iV9iENUtUiefV1s3lSE,3590
@@ -7,11 +7,11 @@ plain/observer/config.py,sha256=BJKsKNbfNSYmaxpUAkuR6gDMgNvD9tx19wpo3-1sksA,2542
7
7
  plain/observer/core.py,sha256=ouZUVX1ikBd-GpU_E6AuuE2h09vdizq6JS9O3CLwl1Y,2629
8
8
  plain/observer/default_settings.py,sha256=JN2jT2wfa6f80EqU0p4Ox_47xyxL-Ym5-_pftY7xj2U,197
9
9
  plain/observer/logging.py,sha256=amv5i06ghszoJ192vrZ0zFdnTajazMxei40ltf0kI50,3061
10
- plain/observer/models.py,sha256=viKVyzUQiu0hPVSOkx0YJsNDjTKoLvfU3PrrJxudGgw,18297
10
+ plain/observer/models.py,sha256=6hyPAjK-Uq24n-2TkN0eHW8xcDIMUprMAFMY6rlLXiI,18365
11
11
  plain/observer/otel.py,sha256=9srHheffXhw8EX8MLAHNZO56lEtSHn51wKPkwYKtnh4,17566
12
12
  plain/observer/toolbar.py,sha256=VZlMC2UJH0NfIh_AOWOQ18G9Ix-TZ4IivmkkHh8ndxw,707
13
13
  plain/observer/urls.py,sha256=oLJoDjB7YMUx8z-MGql_xXSXkfacVKFp-aHNXaKzs38,376
14
- plain/observer/views.py,sha256=oEQYOBX7SORc_3BCAflJMQIX1iGcBLP3b9g3cEORNF4,5385
14
+ plain/observer/views.py,sha256=y7z0Q9g0n3D78e3bG1XUu258loi-EL3uRIcUeQKyRbI,5385
15
15
  plain/observer/migrations/0001_initial.py,sha256=HVoSrd5V-IOqD1adADIAzqMH8xMlPwyLOFH6JcGFniI,3312
16
16
  plain/observer/migrations/0002_trace_share_created_at_trace_share_id_trace_summary_and_more.py,sha256=lgFqdn66zq7AoCvkC3MIvLXiE_Omup5EEMDSe1jpKOg,1765
17
17
  plain/observer/migrations/0003_span_plainobserv_span_id_e7ade3_idx.py,sha256=54G8GXi-PiFbcTU-HrXO14UN9PxhjDCY05TA9HHkkmk,527
@@ -27,7 +27,7 @@ plain/observer/templates/observer/partials/log.html,sha256=Vpp0j-GLBfwTBFyZp_cv0
27
27
  plain/observer/templates/observer/partials/span.html,sha256=PaWZONsABwlS7mdKsJlYbhMSOzidq_WyOp6ifvFUgmM,18672
28
28
  plain/observer/templates/toolbar/observer.html,sha256=uaDKiWR7EYqC1kEXE-uHDlE7nfFEMR_zmOgvlKwQHJ4,1365
29
29
  plain/observer/templates/toolbar/observer_button.html,sha256=FMBJHKMGqpHWs-3Ei2PBCdVYZ_6vFw6-eKH_i4jQu-Q,1215
30
- plain_observer-0.9.1.dist-info/METADATA,sha256=jWUYHMAGn0qkZYIOGtvlWKy-vKyj9zCndAGsbg3JrFQ,1386
31
- plain_observer-0.9.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- plain_observer-0.9.1.dist-info/licenses/LICENSE,sha256=YZdq6Pz8ivjs97eSVLRmoGDI1hjEikX6N49DfM0DWio,1500
33
- plain_observer-0.9.1.dist-info/RECORD,,
30
+ plain_observer-0.10.1.dist-info/METADATA,sha256=1abBSTaSWHc3pJe1N84Z2HDU2CNYs_CYT3lK0YzIKrc,1387
31
+ plain_observer-0.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ plain_observer-0.10.1.dist-info/licenses/LICENSE,sha256=YZdq6Pz8ivjs97eSVLRmoGDI1hjEikX6N49DfM0DWio,1500
33
+ plain_observer-0.10.1.dist-info/RECORD,,