plain.observer 0.0.0__py3-none-any.whl → 0.2.0__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.
- plain/observer/CHANGELOG.md +29 -0
- plain/observer/admin.py +0 -8
- plain/observer/cli.py +558 -5
- plain/observer/config.py +28 -20
- plain/observer/migrations/0002_trace_share_created_at_trace_share_id_trace_summary_and_more.py +58 -0
- plain/observer/models.py +56 -27
- plain/observer/otel.py +63 -2
- plain/observer/templates/observer/{_trace_detail.html → trace.html} +155 -98
- plain/observer/templates/observer/trace_detail.html +24 -0
- plain/observer/templates/observer/trace_share.html +19 -0
- plain/observer/templates/observer/traces.html +161 -135
- plain/observer/templates/toolbar/observer_button.html +27 -43
- plain/observer/urls.py +3 -1
- plain/observer/views.py +90 -56
- {plain_observer-0.0.0.dist-info → plain_observer-0.2.0.dist-info}/METADATA +1 -1
- plain_observer-0.2.0.dist-info/RECORD +25 -0
- plain/observer/templates/admin/observer/trace_detail.html +0 -10
- plain_observer-0.0.0.dist-info/RECORD +0 -23
- {plain_observer-0.0.0.dist-info → plain_observer-0.2.0.dist-info}/WHEEL +0 -0
- {plain_observer-0.0.0.dist-info → plain_observer-0.2.0.dist-info}/licenses/LICENSE +0 -0
plain/observer/views.py
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
from functools import cached_property
|
|
2
|
-
|
|
3
1
|
from plain.auth.views import AuthViewMixin
|
|
4
2
|
from plain.htmx.views import HTMXViewMixin
|
|
5
|
-
from plain.http import JsonResponse, Response
|
|
3
|
+
from plain.http import JsonResponse, Response
|
|
6
4
|
from plain.runtime import settings
|
|
7
|
-
from plain.
|
|
5
|
+
from plain.urls import reverse
|
|
6
|
+
from plain.views import DetailView, ListView
|
|
8
7
|
|
|
9
8
|
from .core import Observer
|
|
10
9
|
from .models import Trace
|
|
11
10
|
|
|
12
11
|
|
|
13
|
-
class ObserverTracesView(AuthViewMixin, HTMXViewMixin,
|
|
12
|
+
class ObserverTracesView(AuthViewMixin, HTMXViewMixin, ListView):
|
|
14
13
|
template_name = "observer/traces.html"
|
|
14
|
+
context_object_name = "traces"
|
|
15
15
|
admin_required = True
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"""Get the Observer instance for this request."""
|
|
20
|
-
return Observer(self.request)
|
|
17
|
+
def get_objects(self):
|
|
18
|
+
return Trace.objects.all()
|
|
21
19
|
|
|
22
20
|
def check_auth(self):
|
|
23
21
|
# Allow the view if we're in DEBUG
|
|
@@ -34,72 +32,108 @@ class ObserverTracesView(AuthViewMixin, HTMXViewMixin, TemplateView):
|
|
|
34
32
|
|
|
35
33
|
def get_template_context(self):
|
|
36
34
|
context = super().get_template_context()
|
|
37
|
-
context["observer"] = self.
|
|
38
|
-
context["traces"] = Trace.objects.all()
|
|
39
|
-
if trace_id := self.request.query_params.get("trace_id"):
|
|
40
|
-
context["trace"] = Trace.objects.filter(id=trace_id).first()
|
|
41
|
-
else:
|
|
42
|
-
context["trace"] = context["traces"].first()
|
|
35
|
+
context["observer"] = Observer(self.request)
|
|
43
36
|
return context
|
|
44
37
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if trace := Trace.objects.filter(id=trace_id).first():
|
|
50
|
-
return JsonResponse(trace.as_dict())
|
|
51
|
-
return JsonResponse({"error": "Trace not found"}, status=404)
|
|
52
|
-
|
|
53
|
-
return super().get()
|
|
38
|
+
def htmx_put_mode(self):
|
|
39
|
+
"""Set observer mode via HTMX PUT."""
|
|
40
|
+
mode = self.request.data.get("mode")
|
|
41
|
+
observer = Observer(self.request)
|
|
54
42
|
|
|
55
|
-
def htmx_post_enable_summary(self):
|
|
56
|
-
"""Enable summary mode via HTMX."""
|
|
57
43
|
response = Response(status_code=204)
|
|
58
44
|
response.headers["HX-Refresh"] = "true"
|
|
59
|
-
self.observer.enable_summary_mode(response)
|
|
60
|
-
return response
|
|
61
45
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
if mode == "summary":
|
|
47
|
+
observer.enable_summary_mode(response)
|
|
48
|
+
elif mode == "persist":
|
|
49
|
+
observer.enable_persist_mode(response)
|
|
50
|
+
elif mode == "disable":
|
|
51
|
+
observer.disable(response)
|
|
52
|
+
else:
|
|
53
|
+
return Response("Invalid mode", status_code=400)
|
|
68
54
|
|
|
69
|
-
def htmx_post_disable(self):
|
|
70
|
-
"""Disable observer via HTMX."""
|
|
71
|
-
response = Response(status_code=204)
|
|
72
|
-
response.headers["HX-Refresh"] = "true"
|
|
73
|
-
self.observer.disable(response)
|
|
74
55
|
return response
|
|
75
56
|
|
|
76
57
|
def htmx_delete_traces(self):
|
|
77
58
|
"""Clear all traces via HTMX DELETE."""
|
|
78
|
-
Trace.objects.
|
|
59
|
+
Trace.objects.filter(share_id="").delete()
|
|
79
60
|
response = Response(status_code=204)
|
|
80
61
|
response.headers["HX-Refresh"] = "true"
|
|
81
62
|
return response
|
|
82
63
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
64
|
+
|
|
65
|
+
class ObserverTraceDetailView(AuthViewMixin, HTMXViewMixin, DetailView):
|
|
66
|
+
"""Detail view for a specific trace."""
|
|
67
|
+
|
|
68
|
+
template_name = "observer/trace_detail.html"
|
|
69
|
+
context_object_name = "trace"
|
|
70
|
+
admin_required = True
|
|
71
|
+
|
|
72
|
+
def get_object(self):
|
|
73
|
+
return Trace.objects.get_or_none(trace_id=self.url_kwargs.get("trace_id"))
|
|
74
|
+
|
|
75
|
+
def check_auth(self):
|
|
76
|
+
# Allow the view if we're in DEBUG
|
|
77
|
+
if settings.DEBUG:
|
|
78
|
+
return
|
|
79
|
+
super().check_auth()
|
|
80
|
+
|
|
81
|
+
def get(self):
|
|
82
|
+
"""Return trace data as HTML or JSON based on content negotiation."""
|
|
83
|
+
if (
|
|
84
|
+
"application/json" in self.request.headers.get("Accept", "")
|
|
85
|
+
or self.request.query_params.get("format") == "json"
|
|
86
|
+
):
|
|
87
|
+
return self.get_object().as_dict()
|
|
88
|
+
|
|
89
|
+
return super().get()
|
|
90
|
+
|
|
91
|
+
def get_template_names(self):
|
|
92
|
+
if self.is_htmx_request():
|
|
93
|
+
# Use a different template for HTMX requests
|
|
94
|
+
return ["observer/trace.html"]
|
|
95
|
+
return super().get_template_names()
|
|
96
|
+
|
|
97
|
+
def htmx_delete(self):
|
|
98
|
+
trace = self.get_object()
|
|
99
|
+
trace.delete()
|
|
100
|
+
|
|
101
|
+
# Redirect to traces list after deletion
|
|
87
102
|
response = Response(status_code=204)
|
|
88
|
-
response.headers["HX-
|
|
103
|
+
response.headers["HX-Redirect"] = reverse("observer:traces")
|
|
89
104
|
return response
|
|
90
105
|
|
|
91
|
-
def
|
|
92
|
-
|
|
106
|
+
def htmx_post_share(self):
|
|
107
|
+
trace = self.get_object()
|
|
108
|
+
trace.generate_share_id()
|
|
109
|
+
return super().get()
|
|
93
110
|
|
|
94
|
-
|
|
111
|
+
def htmx_delete_share(self):
|
|
112
|
+
trace = self.get_object()
|
|
113
|
+
trace.remove_share_id()
|
|
114
|
+
return super().get()
|
|
95
115
|
|
|
96
|
-
response = ResponseRedirect(self.request.data.get("redirect_url", "."))
|
|
97
116
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
elif observe_action == "persist":
|
|
101
|
-
self.observer.enable_persist_mode(response)
|
|
102
|
-
elif observe_action == "disable":
|
|
103
|
-
self.observer.disable(response)
|
|
117
|
+
class ObserverTraceSharedView(DetailView):
|
|
118
|
+
"""Public view for shared trace data."""
|
|
104
119
|
|
|
105
|
-
|
|
120
|
+
template_name = "observer/trace_share.html"
|
|
121
|
+
context_object_name = "trace"
|
|
122
|
+
|
|
123
|
+
def get_object(self):
|
|
124
|
+
return Trace.objects.get_or_none(share_id=self.url_kwargs["share_id"])
|
|
125
|
+
|
|
126
|
+
def get_template_context(self):
|
|
127
|
+
context = super().get_template_context()
|
|
128
|
+
context["is_share_view"] = True
|
|
129
|
+
return context
|
|
130
|
+
|
|
131
|
+
def get(self):
|
|
132
|
+
"""Return trace data as HTML or JSON based on content negotiation."""
|
|
133
|
+
if (
|
|
134
|
+
"application/json" in self.request.headers.get("Accept", "")
|
|
135
|
+
or self.request.query_params.get("format") == "json"
|
|
136
|
+
):
|
|
137
|
+
return JsonResponse(self.get_object().as_dict())
|
|
138
|
+
|
|
139
|
+
return super().get()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
plain/observer/CHANGELOG.md,sha256=hpdLGk-BRxA-2gHzygAp0XrFvvM43IhJg8TT4AjWoIo,2055
|
|
2
|
+
plain/observer/README.md,sha256=5wM48-iE8i7xOjIK8KCgZ-Vmp2xpDtX73UnE5QeNnd4,31
|
|
3
|
+
plain/observer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
plain/observer/admin.py,sha256=sFg5YUAnw-zZJv3_xnMRtI9hFOLI6w77GEV4zhALhQo,2537
|
|
5
|
+
plain/observer/cli.py,sha256=-huHPj4xkrq4xemDo8XzoNtmE53g0YWuVLW66Gr1d88,20935
|
|
6
|
+
plain/observer/config.py,sha256=FuJi1jiDSvOTcmP-6Ea4OlGZt5cRf4iTp1e0dgpJ45E,1494
|
|
7
|
+
plain/observer/core.py,sha256=D9vX0GP8JBB8-NFAKrOwPSHl_wdZo1h0A5C6xKsJVjA,2245
|
|
8
|
+
plain/observer/default_settings.py,sha256=JN2jT2wfa6f80EqU0p4Ox_47xyxL-Ym5-_pftY7xj2U,197
|
|
9
|
+
plain/observer/models.py,sha256=uVmytQHCYilMfULGJHk63l48APOHqEcbcRtYoE7L_RU,13072
|
|
10
|
+
plain/observer/otel.py,sha256=nr4BYQb6rWF7uXsOVmBWV-8z5jLTPbDnYi6VSdVvUnE,14585
|
|
11
|
+
plain/observer/urls.py,sha256=oLJoDjB7YMUx8z-MGql_xXSXkfacVKFp-aHNXaKzs38,376
|
|
12
|
+
plain/observer/views.py,sha256=9TRvjfBk62nxlfZXXk-LsMXqnCxL_FIrQH4eUFIUN9A,4226
|
|
13
|
+
plain/observer/migrations/0001_initial.py,sha256=I-4DNr_WK2Gx428Ql3pG3-W8C0xvk0FVTZnd5swIAQ4,3376
|
|
14
|
+
plain/observer/migrations/0002_trace_share_created_at_trace_share_id_trace_summary_and_more.py,sha256=lgFqdn66zq7AoCvkC3MIvLXiE_Omup5EEMDSe1jpKOg,1765
|
|
15
|
+
plain/observer/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
plain/observer/templates/observer/trace.html,sha256=42yuvqAH7poRMFbueXT-MeSIClmUaLSHohG9LF0sepk,27098
|
|
17
|
+
plain/observer/templates/observer/trace_detail.html,sha256=86-YGCpg9gy31Pd2vDHB3LYRkJile-DsGD1Enjx9s5Y,943
|
|
18
|
+
plain/observer/templates/observer/trace_share.html,sha256=HrYLti5BpX96-6Bm_37OObFvAJSYbZ3GZD-MwCi9hgA,525
|
|
19
|
+
plain/observer/templates/observer/traces.html,sha256=cFnlIuCf6XJEpHRD2_yfVmPDGZfiqMq6Cg-iMlT3CWY,22184
|
|
20
|
+
plain/observer/templates/toolbar/observer.html,sha256=uaDKiWR7EYqC1kEXE-uHDlE7nfFEMR_zmOgvlKwQHJ4,1365
|
|
21
|
+
plain/observer/templates/toolbar/observer_button.html,sha256=xsHJSuOjW6ddnxlPlPKek22WrWnuVYGIcBfFdkb76pk,1199
|
|
22
|
+
plain_observer-0.2.0.dist-info/METADATA,sha256=8ZtRPghSC480Xb44R7nWlM3KWAfwWUH1vbt3v1CTWrg,429
|
|
23
|
+
plain_observer-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
24
|
+
plain_observer-0.2.0.dist-info/licenses/LICENSE,sha256=YZdq6Pz8ivjs97eSVLRmoGDI1hjEikX6N49DfM0DWio,1500
|
|
25
|
+
plain_observer-0.2.0.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
plain/observer/CHANGELOG.md,sha256=bOl9N42H3a0_nUQjhLCJR1Zqj2DOgRCLstzBbYpDmbw,27
|
|
2
|
-
plain/observer/README.md,sha256=5wM48-iE8i7xOjIK8KCgZ-Vmp2xpDtX73UnE5QeNnd4,31
|
|
3
|
-
plain/observer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
plain/observer/admin.py,sha256=d5ekU48GiiQ70K8ulSd0v_7P1v12U8rIQ8LbiNgKv0Y,2874
|
|
5
|
-
plain/observer/cli.py,sha256=JBJzOYl3V973WQbtj8AEde6zxfWdEZx-u3g7c15-4lU,544
|
|
6
|
-
plain/observer/config.py,sha256=ivLgpCD87VgE8FL095zIoTdIBsRhB0VPKxxaWc38Ouw,1078
|
|
7
|
-
plain/observer/core.py,sha256=D9vX0GP8JBB8-NFAKrOwPSHl_wdZo1h0A5C6xKsJVjA,2245
|
|
8
|
-
plain/observer/default_settings.py,sha256=JN2jT2wfa6f80EqU0p4Ox_47xyxL-Ym5-_pftY7xj2U,197
|
|
9
|
-
plain/observer/models.py,sha256=cD72rht7Bb-8YARYvylBc9W0garebWgFsH_vfx1ubT8,11999
|
|
10
|
-
plain/observer/otel.py,sha256=KmdMCJqUvm6OY8di5p3_0TnNC3pI_lDc8O9dbDRVPZ4,12501
|
|
11
|
-
plain/observer/urls.py,sha256=LcsKBWRqt8gs385tV9z-j6kSewzWsOWftadi59QqIIE,194
|
|
12
|
-
plain/observer/views.py,sha256=TrwatLFf9M67ax4EhF_P1Q3X_o3hzsAEr4Po48peiQM,3673
|
|
13
|
-
plain/observer/migrations/0001_initial.py,sha256=I-4DNr_WK2Gx428Ql3pG3-W8C0xvk0FVTZnd5swIAQ4,3376
|
|
14
|
-
plain/observer/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
plain/observer/templates/admin/observer/trace_detail.html,sha256=qW03sNNKGivPVQMI8rFtSCXGTOH_qw_nmXhpIZIu4zo,161
|
|
16
|
-
plain/observer/templates/observer/_trace_detail.html,sha256=q98IdA28m7vlel2ND090MoFE5Kmw8_yLExJd57-MUus,21631
|
|
17
|
-
plain/observer/templates/observer/traces.html,sha256=dJPp2pcFDJOLmHihH5-qnVAgAJEYGCBy6Fn1OreaWjw,20700
|
|
18
|
-
plain/observer/templates/toolbar/observer.html,sha256=uaDKiWR7EYqC1kEXE-uHDlE7nfFEMR_zmOgvlKwQHJ4,1365
|
|
19
|
-
plain/observer/templates/toolbar/observer_button.html,sha256=BXzka5LyvhQPBLFBY_QSNQOfdFtbIN3SUF3ZjSVGSjw,2565
|
|
20
|
-
plain_observer-0.0.0.dist-info/METADATA,sha256=Gt44f0UBXrlS1ln2oAFmD4dOVIic9oqGK85nytYniug,429
|
|
21
|
-
plain_observer-0.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
22
|
-
plain_observer-0.0.0.dist-info/licenses/LICENSE,sha256=YZdq6Pz8ivjs97eSVLRmoGDI1hjEikX6N49DfM0DWio,1500
|
|
23
|
-
plain_observer-0.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|