django-api-usage 0.1.1__tar.gz → 0.1.2__tar.gz

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.
Files changed (37) hide show
  1. {django_api_usage-0.1.1/src/django_api_usage.egg-info → django_api_usage-0.1.2}/PKG-INFO +1 -1
  2. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/pyproject.toml +1 -1
  3. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/__init__.py +1 -1
  4. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/admin.py +11 -0
  5. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/templates/admin/django_api_usage/endpointstat/change_list.html +1 -1
  6. {django_api_usage-0.1.1 → django_api_usage-0.1.2/src/django_api_usage.egg-info}/PKG-INFO +1 -1
  7. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/tests/test_admin.py +60 -1
  8. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/LICENSE +0 -0
  9. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/README.md +0 -0
  10. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/setup.cfg +0 -0
  11. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/apps.py +0 -0
  12. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/buffers.py +0 -0
  13. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/checks.py +0 -0
  14. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/conf.py +0 -0
  15. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/deprecation.py +0 -0
  16. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/drf.py +0 -0
  17. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/maintenance.py +0 -0
  18. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/management/__init__.py +0 -0
  19. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/management/commands/__init__.py +0 -0
  20. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/management/commands/api_usage_flush.py +0 -0
  21. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/management/commands/api_usage_report.py +0 -0
  22. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/middleware.py +0 -0
  23. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/migrations/0001_initial.py +0 -0
  24. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/migrations/__init__.py +0 -0
  25. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/models.py +0 -0
  26. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/resolvers.py +0 -0
  27. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/tasks.py +0 -0
  28. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage/templates/admin/django_api_usage/endpointstat/confirm_clear.html +0 -0
  29. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage.egg-info/SOURCES.txt +0 -0
  30. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage.egg-info/dependency_links.txt +0 -0
  31. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage.egg-info/requires.txt +0 -0
  32. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/src/django_api_usage.egg-info/top_level.txt +0 -0
  33. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/tests/test_checks.py +0 -0
  34. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/tests/test_commands.py +0 -0
  35. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/tests/test_drf.py +0 -0
  36. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/tests/test_middleware.py +0 -0
  37. {django_api_usage-0.1.1 → django_api_usage-0.1.2}/tests/test_models.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-api-usage
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Lightweight, privacy-first usage metering for Django APIs, with an optional deprecation lifecycle layer.
5
5
  Author-email: CodeSyntax <teknika@codesyntax.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "django-api-usage"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Lightweight, privacy-first usage metering for Django APIs, with an optional deprecation lifecycle layer."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,3 +1,3 @@
1
1
  """django-api-usage: usage metering for Django APIs, with deprecation support."""
2
2
 
3
- __version__ = "0.1.1"
3
+ __version__ = "0.1.2"
@@ -44,6 +44,17 @@ class EndpointStatAdmin(admin.ModelAdmin):
44
44
  list_filter = ("date", "client_type", "status_class")
45
45
  list_select_related = ("endpoint",)
46
46
  date_hierarchy = "date"
47
+ # Search across the related endpoint (case-insensitive "contains").
48
+ search_fields = (
49
+ "endpoint__route_name",
50
+ "endpoint__app_label",
51
+ "endpoint__method",
52
+ "endpoint__replacement",
53
+ )
54
+ search_help_text = _(
55
+ "Search by endpoint route, app, method or replacement (for example "
56
+ "'artikuluak' or 'gida')."
57
+ )
47
58
  change_list_template = "admin/django_api_usage/endpointstat/change_list.html"
48
59
 
49
60
  def has_add_permission(self, request):
@@ -18,7 +18,7 @@
18
18
  {{ block.super }}
19
19
  {% if usage_total is not None %}
20
20
  <p class="help" style="text-align: right; padding: 0.5em 1em; font-weight: bold;">
21
- {% blocktranslate with total=usage_total %}Total calls in the filtered rows: {{ total }}{% endblocktranslate %}
21
+ {% blocktranslate with total=usage_total %}TOTAL COUNT: {{ total }}{% endblocktranslate %}
22
22
  </p>
23
23
  {% endif %}
24
24
  {% endblock %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-api-usage
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Lightweight, privacy-first usage metering for Django APIs, with an optional deprecation lifecycle layer.
5
5
  Author-email: CodeSyntax <teknika@codesyntax.com>
6
6
  License-Expression: MIT
@@ -87,7 +87,7 @@ class AdminButtonsTest(UsageTestCase):
87
87
  response = self.client.get(reverse(CHANGELIST))
88
88
 
89
89
  self.assertEqual(response.context_data["usage_total"], 12)
90
- self.assertContains(response, "Total calls in the filtered rows")
90
+ self.assertContains(response, "TOTAL COUNT")
91
91
 
92
92
  def test_total_respects_the_selected_filters(self):
93
93
  api = Endpoint.objects.create(app_label="api", route_name="a", method="GET")
@@ -103,6 +103,65 @@ class AdminButtonsTest(UsageTestCase):
103
103
 
104
104
  self.assertEqual(response.context_data["usage_total"], 7)
105
105
 
106
+ def test_search_box_is_rendered(self):
107
+ response = self.client.get(reverse(CHANGELIST))
108
+
109
+ self.assertContains(response, 'id="searchbar"')
110
+
111
+ def test_search_filters_rows_by_endpoint_text(self):
112
+ api = Endpoint.objects.create(
113
+ app_label="api", route_name="artikuluak-list", method="GET"
114
+ )
115
+ gida = Endpoint.objects.create(
116
+ app_label="gida", route_name="gida-sailak-list", method="GET"
117
+ )
118
+ EndpointStat.objects.create(
119
+ endpoint=api, date="2026-10-08", client_type="anon", count=5
120
+ )
121
+ EndpointStat.objects.create(
122
+ endpoint=gida, date="2026-10-08", client_type="anon", count=7
123
+ )
124
+
125
+ response = self.client.get(reverse(CHANGELIST), {"q": "artikuluak"})
126
+
127
+ self.assertEqual(response.context_data["usage_total"], 5)
128
+ self.assertEqual(len(response.context_data["cl"].result_list), 1)
129
+
130
+ def test_search_matches_the_app_label(self):
131
+ api = Endpoint.objects.create(
132
+ app_label="api", route_name="artikuluak-list", method="GET"
133
+ )
134
+ gida = Endpoint.objects.create(
135
+ app_label="gida", route_name="gida-sailak-list", method="GET"
136
+ )
137
+ EndpointStat.objects.create(
138
+ endpoint=api, date="2026-10-08", client_type="anon", count=5
139
+ )
140
+ EndpointStat.objects.create(
141
+ endpoint=gida, date="2026-10-08", client_type="anon", count=7
142
+ )
143
+
144
+ response = self.client.get(reverse(CHANGELIST), {"q": "gida"})
145
+
146
+ self.assertEqual(response.context_data["usage_total"], 7)
147
+
148
+ def test_search_combines_with_list_filters(self):
149
+ api = Endpoint.objects.create(
150
+ app_label="api", route_name="artikuluak-list", method="GET"
151
+ )
152
+ EndpointStat.objects.create(
153
+ endpoint=api, date="2026-10-08", client_type="anon", count=5
154
+ )
155
+ EndpointStat.objects.create(
156
+ endpoint=api, date="2026-10-08", client_type="user", count=3
157
+ )
158
+
159
+ response = self.client.get(
160
+ reverse(CHANGELIST), {"q": "artikuluak", "client_type": "user"}
161
+ )
162
+
163
+ self.assertEqual(response.context_data["usage_total"], 3)
164
+
106
165
  def test_clear_is_not_available_without_admin_permission(self):
107
166
  self._make_stat()
108
167
  self.client.force_login(User.objects.create_user("plain", password="x"))