Skip to content

Commit

Permalink
Depublicize boundaries API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Jan 14, 2025
1 parent 00f3b4b commit 344a6fa
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 103 deletions.
4 changes: 0 additions & 4 deletions temba/api/v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,13 @@ def run_validation(self, data=serializers.empty):
class AdminBoundaryReadSerializer(ReadSerializer):
parent = serializers.SerializerMethodField()
aliases = serializers.SerializerMethodField()
geometry = serializers.SerializerMethodField()

def get_parent(self, obj):
return {"osm_id": obj.parent.osm_id, "name": obj.parent.name} if obj.parent else None

def get_aliases(self, obj):
return [alias.name for alias in obj.aliases.all()]

def get_geometry(self, obj):
return obj.geometry if self.context["include_geometry"] else None

class Meta:
model = AdminBoundary
fields = ("osm_id", "name", "parent", "level", "aliases", "geometry")
Expand Down
36 changes: 4 additions & 32 deletions temba/api/v2/tests/test_boundaries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django.urls import reverse

from temba.locations.models import BoundaryAlias
from temba.tests import matchers

from . import APITest

Expand All @@ -23,7 +22,6 @@ def test_endpoint(self):
self.state1.geometry = {"type": "MultiPolygon", "coordinates": [[[[1, 1], [1, -1], [-1, -1], [-1, 1], [1, 1]]]]}
self.state1.save()

# test without geometry
self.assertGet(
endpoint_url,
[self.user, self.editor, self.admin],
Expand All @@ -34,7 +32,10 @@ def test_endpoint(self):
"parent": {"osm_id": "171496", "name": "Rwanda"},
"level": 1,
"aliases": ["Kigali", "Kigari"],
"geometry": None,
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[[1.0, 1.0], [1.0, -1.0], [-1.0, -1.0], [-1.0, 1.0], [1.0, 1.0]]]],
},
},
{
"osm_id": "171113181",
Expand Down Expand Up @@ -105,35 +106,6 @@ def test_endpoint(self):
num_queries=self.BASE_SESSION_QUERIES + 3,
)

# test with geometry
self.assertGet(
endpoint_url + "?geometry=true",
[self.admin],
results=[
{
"osm_id": "1708283",
"name": "Kigali City",
"parent": {"osm_id": "171496", "name": "Rwanda"},
"level": 1,
"aliases": ["Kigali", "Kigari"],
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[[1.0, 1.0], [1.0, -1.0], [-1.0, -1.0], [-1.0, 1.0], [1.0, 1.0]]]],
},
},
matchers.Dict(),
matchers.Dict(),
matchers.Dict(),
matchers.Dict(),
matchers.Dict(),
matchers.Dict(),
matchers.Dict(),
matchers.Dict(),
matchers.Dict(),
],
num_queries=self.BASE_SESSION_QUERIES + 3,
)

# if org doesn't have a country, just return no results
self.org.country = None
self.org.save(update_fields=("country",))
Expand Down
69 changes: 2 additions & 67 deletions temba/api/v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ def get_context_data(self, **kwargs):

context["endpoints"] = [
ArchivesEndpoint.get_read_explorer(),
BoundariesEndpoint.get_read_explorer(),
BroadcastsEndpoint.get_read_explorer(),
BroadcastsEndpoint.get_write_explorer(),
CampaignsEndpoint.get_read_explorer(),
Expand Down Expand Up @@ -170,7 +169,6 @@ class RootView(BaseEndpoint):
are available:
* [/api/v2/archives](/api/v2/archives) - to list archives of messages and runs
* [/api/v2/boundaries](/api/v2/boundaries) - to list administrative boundaries
* [/api/v2/broadcasts](/api/v2/broadcasts) - to list and send broadcasts
* [/api/v2/campaigns](/api/v2/campaigns) - to list, create, or update campaigns
* [/api/v2/campaign_events](/api/v2/campaign_events) - to list, create, update or delete campaign events
Expand Down Expand Up @@ -279,7 +277,6 @@ def get(self, request, *args, **kwargs):
return Response(
{
"archives": reverse("api.v2.archives", request=request),
"boundaries": reverse("api.v2.boundaries", request=request),
"broadcasts": reverse("api.v2.broadcasts", request=request),
"campaigns": reverse("api.v2.campaigns", request=request),
"campaign_events": reverse("api.v2.campaign_events", request=request),
Expand Down Expand Up @@ -400,54 +397,7 @@ def get_read_explorer(cls):

class BoundariesEndpoint(ListAPIMixin, BaseEndpoint):
"""
This endpoint allows you to list the administrative boundaries for the country associated with your account,
along with the simplified GPS geometry for those boundaries in GEOJSON format.
## Listing Boundaries
A `GET` returns the boundaries for your organization with the following fields. To include geometry,
specify `geometry=true`.
* **osm_id** - the OSM ID for this boundary prefixed with the element type (string).
* **name** - the name of the administrative boundary (string).
* **parent** - the id of the containing parent of this boundary or null if this boundary is a country (string).
* **level** - the level: 0 for country, 1 for state, 2 for district (int).
* **geometry** - the geometry for this boundary, which will usually be a MultiPolygon (GEOJSON).
**Note that including geometry may produce a very large result so it is recommended to cache the results on the
client side.**
Example:
GET /api/v2/boundaries.json?geometry=true
Response is a list of the boundaries on your account
{
"next": null,
"previous": null,
"results": [
{
"osm_id": "1708283",
"name": "Kigali City",
"parent": {"osm_id": "171496", "name": "Rwanda"},
"level": 1,
"aliases": ["Kigari"],
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[7.5251021, 5.0504713],
[7.5330272, 5.0423498]
]
]
]
}
},
...
}
Unpublicized endpoint to list administrative boundaries.
"""

class Pagination(CursorPagination):
Expand All @@ -468,22 +418,7 @@ def derive_queryset(self):
Prefetch("aliases", queryset=BoundaryAlias.objects.filter(org=org).order_by("name"))
)

return queryset.defer(None).select_related("parent")

def get_serializer_context(self):
context = super().get_serializer_context()
context["include_geometry"] = str_to_bool(self.request.query_params.get("geometry", "false"))
return context

@classmethod
def get_read_explorer(cls):
return {
"method": "GET",
"title": "List Administrative Boundaries",
"url": reverse("api.v2.boundaries"),
"slug": "boundary-list",
"params": [],
}
return queryset.select_related("parent")


class BroadcastsEndpoint(ListAPIMixin, WriteAPIMixin, BaseEndpoint):
Expand Down

0 comments on commit 344a6fa

Please sign in to comment.