Skip to content

Commit d6be954

Browse files
committed
Make more views async
1 parent 51b2f7a commit d6be954

File tree

8 files changed

+194
-164
lines changed

8 files changed

+194
-164
lines changed

cl/api/tests.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ async def test_api_info_page_can_display_different_versions_of_rest_docs(
125125

126126

127127
class CoverageTests(IndexedSolrTestCase):
128-
def test_coverage_data_view_provides_court_data(self) -> None:
129-
response = coverage_data(HttpRequest(), "v2", "ca1")
128+
async def test_coverage_data_view_provides_court_data(self) -> None:
129+
response = await coverage_data(HttpRequest(), "v2", "ca1")
130130
self.assertEqual(response.status_code, 200)
131131
self.assertIsInstance(response, JsonResponse)
132132
self.assertContains(response, "annual_counts")

cl/api/views.py

+85-67
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
from typing import Optional
44

55
import waffle
6-
from asgiref.sync import sync_to_async
6+
from asgiref.sync import async_to_sync, sync_to_async
77
from django.conf import settings
88
from django.http import HttpRequest, HttpResponse, JsonResponse
9-
from django.shortcuts import get_object_or_404, render
10-
from django.template import TemplateDoesNotExist
9+
from django.shortcuts import aget_object_or_404 # type: ignore[attr-defined]
1110
from django.template.response import TemplateResponse
1211
from django.views.decorators.cache import cache_page
1312
from requests import Session
@@ -31,7 +30,7 @@
3130
logger = logging.getLogger(__name__)
3231

3332

34-
def annotate_courts_with_counts(courts, court_count_tuples):
33+
async def annotate_courts_with_counts(courts, court_count_tuples):
3534
"""Solr gives us a response like:
3635
3736
court_count_tuples = [
@@ -47,54 +46,60 @@ def annotate_courts_with_counts(courts, court_count_tuples):
4746
for court_str, count in court_count_tuples:
4847
court_count_dict[court_str] = count
4948

50-
for court in courts:
49+
async for court in courts:
5150
court.count = court_count_dict.get(court.pk, 0)
5251

5352
return courts
5453

5554

56-
def make_court_variable():
55+
async def make_court_variable():
5756
courts = Court.objects.exclude(jurisdiction=Court.TESTING_COURT)
58-
with Session() as session:
59-
si = ExtraSolrInterface(
60-
settings.SOLR_OPINION_URL, http_connection=session, mode="r"
61-
)
62-
response = si.query().add_extra(**build_court_count_query()).execute()
57+
58+
@sync_to_async
59+
def court_count_query():
60+
with Session() as session:
61+
si = ExtraSolrInterface(
62+
settings.SOLR_OPINION_URL, http_connection=session, mode="r"
63+
)
64+
return si.query().add_extra(**build_court_count_query()).execute()
65+
66+
response = await court_count_query()
6367
court_count_tuples = response.facet_counts.facet_fields["court_exact"]
64-
courts = annotate_courts_with_counts(courts, court_count_tuples)
68+
courts = await annotate_courts_with_counts(courts, court_count_tuples)
6569
return courts
6670

6771

68-
def court_index(request: HttpRequest) -> HttpResponse:
72+
async def court_index(request: HttpRequest) -> HttpResponse:
6973
"""Shows the information we have available for the courts."""
70-
courts = make_court_variable()
71-
return render(
74+
courts = await make_court_variable()
75+
return TemplateResponse(
7276
request, "jurisdictions.html", {"courts": courts, "private": False}
7377
)
7478

7579

76-
def rest_docs(request, version=None):
80+
async def rest_docs(request, version=None):
7781
"""Show the correct version of the rest docs"""
78-
courts = make_court_variable()
82+
courts = await make_court_variable()
7983
court_count = len(courts)
8084
context = {"court_count": court_count, "courts": courts, "private": False}
81-
try:
82-
return render(request, f"rest-docs-{version}.html", context)
83-
except TemplateDoesNotExist:
84-
return render(request, "rest-docs-vlatest.html", context)
85+
return TemplateResponse(
86+
request,
87+
[f"rest-docs-{version}.html", "rest-docs-vlatest.html"],
88+
context,
89+
)
8590

8691

87-
def api_index(request: HttpRequest) -> HttpResponse:
88-
court_count = Court.objects.exclude(
92+
async def api_index(request: HttpRequest) -> HttpResponse:
93+
court_count = await Court.objects.exclude(
8994
jurisdiction=Court.TESTING_COURT
90-
).count()
91-
return render(
95+
).acount()
96+
return TemplateResponse(
9297
request, "docs.html", {"court_count": court_count, "private": False}
9398
)
9499

95100

96-
def replication_docs(request: HttpRequest) -> HttpResponse:
97-
return render(request, "replication.html", {"private": False})
101+
async def replication_docs(request: HttpRequest) -> HttpResponse:
102+
return TemplateResponse(request, "replication.html", {"private": False})
98103

99104

100105
async def bulk_data_index(request: HttpRequest) -> HttpResponse:
@@ -131,27 +136,32 @@ def strip_zero_years(data):
131136
return data[start : end + 1]
132137

133138

134-
def coverage_data(request, version, court):
139+
async def coverage_data(request, version, court):
135140
"""Provides coverage data for a court.
136141
137142
Responds to either AJAX or regular requests.
138143
"""
139144

140145
if court != "all":
141-
court_str = get_object_or_404(Court, pk=court).pk
146+
court_str = (await aget_object_or_404(Court, pk=court)).pk
142147
else:
143148
court_str = "all"
144149
q = request.GET.get("q")
145-
with Session() as session:
146-
si = ExtraSolrInterface(
147-
settings.SOLR_OPINION_URL, http_connection=session, mode="r"
148-
)
149-
facet_field = "dateFiled"
150-
response = (
151-
si.query()
152-
.add_extra(**build_coverage_query(court_str, q, facet_field))
153-
.execute()
154-
)
150+
151+
@sync_to_async
152+
def query_facets(c_str, q_str):
153+
with Session() as session:
154+
si = ExtraSolrInterface(
155+
settings.SOLR_OPINION_URL, http_connection=session, mode="r"
156+
)
157+
facet_field = "dateFiled"
158+
return facet_field, (
159+
si.query()
160+
.add_extra(**build_coverage_query(c_str, q_str, facet_field))
161+
.execute()
162+
)
163+
164+
facet_field, response = await query_facets(court_str, q)
155165
counts = response.facet_counts.facet_ranges[facet_field]["counts"]
156166
counts = strip_zero_years(counts)
157167

@@ -167,7 +177,7 @@ def coverage_data(request, version, court):
167177
)
168178

169179

170-
def fetch_first_last_date_filed(
180+
async def fetch_first_last_date_filed(
171181
court_id: str,
172182
) -> tuple[Optional[date], Optional[date]]:
173183
"""Fetch first and last date for court
@@ -178,14 +188,16 @@ def fetch_first_last_date_filed(
178188
query = OpinionCluster.objects.filter(docket__court=court_id).order_by(
179189
"date_filed"
180190
)
181-
first, last = query.first(), query.last()
191+
first, last = await query.afirst(), await query.alast()
182192
if first:
183193
return first.date_filed, last.date_filed
184194
return None, None
185195

186196

197+
@sync_to_async
187198
@cache_page(7 * 60 * 60 * 24, key_prefix="coverage")
188-
def coverage_data_opinions(request: HttpRequest):
199+
@async_to_sync
200+
async def coverage_data_opinions(request: HttpRequest):
189201
"""Generate Coverage Chart Data
190202
191203
Accept GET to query court data for timelines-chart on coverage page
@@ -196,7 +208,7 @@ def coverage_data_opinions(request: HttpRequest):
196208
chart_data = []
197209
if request.method == "GET":
198210
court_ids = request.GET.get("court_ids").split(",") # type: ignore
199-
chart_data = build_chart_data(court_ids)
211+
chart_data = await sync_to_async(build_chart_data)(court_ids)
200212
return JsonResponse(chart_data, safe=False)
201213

202214

@@ -235,21 +247,26 @@ async def get_result_count(request, version, day_count):
235247
s, _ = await sync_to_async(build_es_base_query)(search_query, cd)
236248
total_query_results = s.count()
237249
else:
238-
with Session() as session:
239-
try:
240-
si = get_solr_interface(cd, http_connection=session)
241-
except NotImplementedError:
242-
logger.error(
243-
"Tried getting solr connection for %s, but it's not "
244-
"implemented yet",
245-
cd["type"],
246-
)
247-
raise
248-
extra = await sync_to_async(build_alert_estimation_query)(
249-
cd, int(day_count)
250-
)
251-
response = si.query().add_extra(**extra).execute()
252-
total_query_results = response.result.numFound
250+
251+
@sync_to_async
252+
def get_total_query_results(cleaned_data, dc):
253+
with Session() as session:
254+
try:
255+
si = get_solr_interface(
256+
cleaned_data, http_connection=session
257+
)
258+
except NotImplementedError:
259+
logger.error(
260+
"Tried getting solr connection for %s, but it's not "
261+
"implemented yet",
262+
cleaned_data["type"],
263+
)
264+
raise
265+
extra = build_alert_estimation_query(cleaned_data, int(dc))
266+
response = si.query().add_extra(**extra).execute()
267+
return response.result.numFound
268+
269+
total_query_results = await get_total_query_results(cd, day_count)
253270
return JsonResponse({"count": total_query_results}, safe=True)
254271

255272

@@ -267,21 +284,22 @@ async def deprecated_api(request, v):
267284
)
268285

269286

270-
def rest_change_log(request):
287+
async def rest_change_log(request):
271288
context = {"private": False}
272-
return render(request, "rest-change-log.html", context)
289+
return TemplateResponse(request, "rest-change-log.html", context)
273290

274291

275-
def webhooks_getting_started(request):
292+
async def webhooks_getting_started(request):
276293
context = {"private": False}
277-
return render(request, "webhooks-getting-started.html", context)
294+
return TemplateResponse(request, "webhooks-getting-started.html", context)
278295

279296

280-
def webhooks_docs(request, version=None):
297+
async def webhooks_docs(request, version=None):
281298
"""Show the correct version of the webhooks docs"""
282299

283300
context = {"private": False}
284-
try:
285-
return render(request, f"webhooks-docs-{version}.html", context)
286-
except TemplateDoesNotExist:
287-
return render(request, "webhooks-docs-vlatest.html", context)
301+
return TemplateResponse(
302+
request,
303+
[f"webhooks-docs-{version}.html", "webhooks-docs-vlatest.html"],
304+
context,
305+
)

cl/corpus_importer/views.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from asgiref.sync import async_to_sync
12
from django.contrib.admin.views.decorators import staff_member_required
23
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
34
from django.db.models import Q
@@ -170,7 +171,7 @@ def ca_judges(request: AuthenticatedHttpRequest) -> HttpResponse:
170171
# The judge
171172
"judge_page": judge_page,
172173
"judge": judge,
173-
"title": make_title_str(judge),
174+
"title": async_to_sync(make_title_str)(judge),
174175
# Forms
175176
"person_form": person_form,
176177
"politics_formset": politics_formset,

cl/disclosures/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from cl.people_db.models import Person
33

44

5-
def make_disclosure_data(person: Person) -> tuple[str, str]:
5+
async def make_disclosure_data(person: Person) -> tuple[str, str]:
66
"""Make a CSV of the years and the IDs of somebody's disclosures
77
88
:param person: The Person we're making data for
@@ -16,7 +16,7 @@ def make_disclosure_data(person: Person) -> tuple[str, str]:
1616
)
1717
years = []
1818
ids = []
19-
for yr, id in forms:
19+
async for yr, id in forms:
2020
years.append((str(yr)))
2121
ids.append(str(id))
2222
for x in set(years):

cl/disclosures/views.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from django.http import HttpRequest, HttpResponse
2-
from django.shortcuts import get_object_or_404, render
2+
from django.shortcuts import aget_object_or_404
3+
from django.template.response import TemplateResponse
34

45
from cl.disclosures.models import FinancialDisclosure
56
from cl.disclosures.utils import make_disclosure_data
67
from cl.people_db.models import Person
78
from cl.people_db.utils import make_title_str
89

910

10-
def financial_disclosures_home(request: HttpRequest) -> HttpResponse:
11+
async def financial_disclosures_home(request: HttpRequest) -> HttpResponse:
1112
"""The home page for financial disclosures
1213
1314
This page shows:
@@ -18,9 +19,9 @@ def financial_disclosures_home(request: HttpRequest) -> HttpResponse:
1819
people_with_disclosures = Person.objects.filter(
1920
financial_disclosures__isnull=False,
2021
).distinct()
21-
disclosure_count = FinancialDisclosure.objects.all().count()
22-
people_count = people_with_disclosures.count()
23-
return render(
22+
disclosure_count = await FinancialDisclosure.objects.all().acount()
23+
people_count = await people_with_disclosures.acount()
24+
return TemplateResponse(
2425
request,
2526
"financial_disclosures_home.html",
2627
{
@@ -32,18 +33,18 @@ def financial_disclosures_home(request: HttpRequest) -> HttpResponse:
3233
)
3334

3435

35-
def financial_disclosures_viewer(
36+
async def financial_disclosures_viewer(
3637
request: HttpRequest,
3738
person_pk: int,
3839
pk: int,
3940
slug: str,
4041
) -> HttpResponse:
4142
"""Show the financial disclosures for a particular person"""
42-
person = get_object_or_404(Person, pk=person_pk)
43-
title = make_title_str(person)
44-
years, ids = make_disclosure_data(person)
43+
person = await aget_object_or_404(Person, pk=person_pk)
44+
title = await make_title_str(person)
45+
years, ids = await make_disclosure_data(person)
4546

46-
return render(
47+
return TemplateResponse(
4748
request,
4849
"financial_disclosures_viewer.html",
4950
{

cl/people_db/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
def make_title_str(person):
1+
async def make_title_str(person):
22
"""Make a nice title for somebody."""
33
locations = ", ".join(
4-
{p.court.short_name for p in person.positions.all() if p.court}
4+
{p.court.short_name async for p in person.positions.all() if p.court}
55
)
66
title = person.name_full
77
if locations:

0 commit comments

Comments
 (0)