Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit 47a0933

Browse files
authored
API Improvements: Fix typings for various files pt5 (#1087)
1 parent 8660eab commit 47a0933

File tree

15 files changed

+131
-87
lines changed

15 files changed

+131
-87
lines changed

api/internal/feature/views.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import logging
22
import pickle
3+
from typing import Any, Dict, List
34

45
from rest_framework import status
6+
from rest_framework.request import Request
57
from rest_framework.response import Response
68
from rest_framework.views import APIView
79
from shared.django_apps.rollouts.models import FeatureFlag
@@ -20,15 +22,15 @@ class FeaturesView(APIView):
2022
skip_feature_cache = get_config("setup", "skip_feature_cache", default=False)
2123
timeout = 300
2224

23-
def __init__(self, *args, **kwargs):
25+
def __init__(self, *args: Any, **kwargs: Any) -> None:
2426
self.redis = get_redis_connection()
2527
super().__init__(*args, **kwargs)
2628

27-
def get_many_from_redis(self, keys):
29+
def get_many_from_redis(self, keys: List) -> Dict[str, Any]:
2830
ret = self.redis.mget(keys)
2931
return {k: pickle.loads(v) for k, v in zip(keys, ret) if v is not None}
3032

31-
def set_many_to_redis(self, data):
33+
def set_many_to_redis(self, data: Dict[str, Any]) -> None:
3234
pipeline = self.redis.pipeline()
3335
pipeline.mset({k: pickle.dumps(v) for k, v in data.items()})
3436

@@ -38,7 +40,7 @@ def set_many_to_redis(self, data):
3840
pipeline.expire(key, self.timeout)
3941
pipeline.execute()
4042

41-
def post(self, request):
43+
def post(self, request: Request) -> Response:
4244
serializer = FeatureRequestSerializer(data=request.data)
4345
if serializer.is_valid():
4446
flag_evaluations = {}

api/internal/owner/serializers.py

+20-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from datetime import datetime
3+
from typing import Any, Dict
34

45
from dateutil.relativedelta import relativedelta
56
from django.conf import settings
@@ -37,7 +38,7 @@ class Meta:
3738

3839
read_only_fields = fields
3940

40-
def get_stats(self, obj):
41+
def get_stats(self, obj: Owner) -> str | None:
4142
if obj.cache and "stats" in obj.cache:
4243
return obj.cache["stats"]
4344

@@ -50,7 +51,7 @@ class StripeLineItemSerializer(serializers.Serializer):
5051
plan_name = serializers.SerializerMethodField()
5152
quantity = serializers.IntegerField()
5253

53-
def get_plan_name(self, line_item):
54+
def get_plan_name(self, line_item: Dict[str, str]) -> str | None:
5455
plan = line_item.get("plan")
5556
if plan:
5657
return plan.get("name")
@@ -85,7 +86,7 @@ class StripeDiscountSerializer(serializers.Serializer):
8586
duration_in_months = serializers.IntegerField(source="coupon.duration_in_months")
8687
expires = serializers.SerializerMethodField()
8788

88-
def get_expires(self, customer):
89+
def get_expires(self, customer: Dict[str, Dict]) -> int | None:
8990
coupon = customer.get("coupon")
9091
if coupon:
9192
months = coupon.get("duration_in_months")
@@ -121,7 +122,7 @@ class PlanSerializer(serializers.Serializer):
121122
benefits = serializers.JSONField(read_only=True)
122123
quantity = serializers.IntegerField(required=False)
123124

124-
def validate_value(self, value):
125+
def validate_value(self, value: str) -> str:
125126
current_org = self.context["view"].owner
126127
current_owner = self.context["request"].current_owner
127128

@@ -140,7 +141,7 @@ def validate_value(self, value):
140141
)
141142
return value
142143

143-
def validate(self, plan):
144+
def validate(self, plan: Dict[str, Any]) -> Dict[str, Any]:
144145
current_org = self.context["view"].owner
145146
if current_org.account:
146147
raise serializers.ValidationError(
@@ -206,7 +207,7 @@ class StripeScheduledPhaseSerializer(serializers.Serializer):
206207
plan = serializers.SerializerMethodField()
207208
quantity = serializers.SerializerMethodField()
208209

209-
def get_plan(self, phase):
210+
def get_plan(self, phase: Dict[str, Any]) -> str:
210211
plan_id = phase["items"][0]["plan"]
211212
stripe_plan_dict = settings.STRIPE_PLAN_IDS
212213
plan_name = list(stripe_plan_dict.keys())[
@@ -215,15 +216,15 @@ def get_plan(self, phase):
215216
marketing_plan_name = PAID_PLANS[plan_name].billing_rate
216217
return marketing_plan_name
217218

218-
def get_quantity(self, phase):
219+
def get_quantity(self, phase: Dict[str, Any]) -> int:
219220
return phase["items"][0]["quantity"]
220221

221222

222223
class ScheduleDetailSerializer(serializers.Serializer):
223224
id = serializers.CharField()
224225
scheduled_phase = serializers.SerializerMethodField()
225226

226-
def get_scheduled_phase(self, schedule):
227+
def get_scheduled_phase(self, schedule: Dict[str, Any]) -> Dict[str, Any] | None:
227228
if len(schedule["phases"]) > 1:
228229
return StripeScheduledPhaseSerializer(schedule["phases"][-1]).data
229230
else:
@@ -291,44 +292,44 @@ class Meta:
291292
"uses_invoice",
292293
)
293294

294-
def _get_billing(self):
295+
def _get_billing(self) -> BillingService:
295296
current_owner = self.context["request"].current_owner
296297
return BillingService(requesting_user=current_owner)
297298

298-
def get_subscription_detail(self, owner):
299+
def get_subscription_detail(self, owner: Owner) -> Dict[str, Any] | None:
299300
subscription_detail = self._get_billing().get_subscription(owner)
300301
if subscription_detail:
301302
return SubscriptionDetailSerializer(subscription_detail).data
302303

303-
def get_schedule_detail(self, owner):
304+
def get_schedule_detail(self, owner: Owner) -> Dict[str, Any] | None:
304305
schedule_detail = self._get_billing().get_schedule(owner)
305306
if schedule_detail:
306307
return ScheduleDetailSerializer(schedule_detail).data
307308

308-
def get_checkout_session_id(self, _):
309+
def get_checkout_session_id(self, _: Any) -> str:
309310
return self.context.get("checkout_session_id")
310311

311-
def get_activated_student_count(self, owner):
312+
def get_activated_student_count(self, owner: Owner) -> int:
312313
if owner.account:
313314
return owner.account.activated_student_count
314315
return owner.activated_student_count
315316

316-
def get_activated_user_count(self, owner):
317+
def get_activated_user_count(self, owner: Owner) -> int:
317318
if owner.account:
318319
return owner.account.activated_user_count
319320
return owner.activated_user_count
320321

321-
def get_delinquent(self, owner):
322+
def get_delinquent(self, owner: Owner) -> bool:
322323
if owner.account:
323324
return owner.account.is_delinquent
324325
return owner.delinquent
325326

326-
def get_uses_invoice(self, owner):
327+
def get_uses_invoice(self, owner: Owner) -> bool:
327328
if owner.account:
328329
return owner.account.invoice_billing.filter(is_active=True).exists()
329330
return owner.uses_invoice
330331

331-
def update(self, instance, validated_data):
332+
def update(self, instance: Owner, validated_data: Dict[str, Any]) -> object:
332333
if "pretty_plan" in validated_data:
333334
desired_plan = validated_data.pop("pretty_plan")
334335
checkout_session_id_or_none = self._get_billing().update_plan(
@@ -367,7 +368,7 @@ class Meta:
367368
"last_pull_timestamp",
368369
)
369370

370-
def update(self, instance, validated_data):
371+
def update(self, instance: Owner, validated_data: Dict[str, Any]) -> object:
371372
owner = self.context["view"].owner
372373

373374
if "activated" in validated_data:
@@ -391,7 +392,7 @@ def update(self, instance, validated_data):
391392
# Re-fetch from DB to set activated and admin fields
392393
return self.context["view"].get_object()
393394

394-
def get_last_pull_timestamp(self, obj):
395+
def get_last_pull_timestamp(self, obj: Owner) -> str | None:
395396
# this field comes from an annotation that may not always be applied to the queryset
396397
if hasattr(obj, "last_pull_timestamp"):
397398
return obj.last_pull_timestamp

codecov_auth/commands/owner/interactors/set_yaml_on_owner.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def convert_yaml_to_dict(self, yaml_input: str) -> Optional[dict]:
5454
message = f"Error at {str(e.error_location)}: {e.error_message}"
5555
raise ValidationError(message)
5656

57-
def yaml_side_effects(self, old_yaml: dict, new_yaml: dict):
57+
def yaml_side_effects(self, old_yaml: dict | None, new_yaml: dict | None) -> None:
5858
old_yaml_branch = old_yaml and old_yaml.get("codecov", {}).get("branch")
5959
new_yaml_branch = new_yaml and new_yaml.get("codecov", {}).get("branch")
6060

codecov_auth/management/commands/set_trial_status_values.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import datetime
2+
from typing import Any
23

34
from django.core.management.base import BaseCommand, CommandParser
45
from django.db.models import Q
@@ -20,7 +21,7 @@ class Command(BaseCommand):
2021
def add_arguments(self, parser: CommandParser) -> None:
2122
parser.add_argument("trial_status_type", type=str)
2223

23-
def handle(self, *args, **options) -> None:
24+
def handle(self, *args: Any, **options: Any) -> None:
2425
trial_status_type = options.get("trial_status_type", {})
2526

2627
# NOT_STARTED

core/commands/pull/interactors/fetch_pull_request.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from datetime import datetime, timedelta
22

3-
from shared.django_apps.core.models import Pull
3+
from shared.django_apps.core.models import Pull, Repository
44

55
from codecov.commands.base import BaseInteractor
66
from codecov.db import sync_to_async
@@ -17,7 +17,7 @@ def _should_sync_pull(self, pull: Pull | None) -> bool:
1717
)
1818

1919
@sync_to_async
20-
def execute(self, repository, id):
20+
def execute(self, repository: Repository, id: int) -> Pull:
2121
pull = repository.pull_requests.filter(pullid=id).first()
2222
if self._should_sync_pull(pull):
2323
TaskService().pulls_sync(repository.repoid, id)

core/commands/repository/interactors/erase_repository.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
class EraseRepositoryInteractor(BaseInteractor):
14-
def validate_owner(self, owner: Owner):
14+
def validate_owner(self, owner: Owner) -> None:
1515
if not current_user_part_of_org(self.current_owner, owner):
1616
raise Unauthorized()
1717

@@ -23,7 +23,7 @@ def validate_owner(self, owner: Owner):
2323
raise Unauthorized()
2424

2525
@sync_to_async
26-
def execute(self, repo_name: str, owner: Owner):
26+
def execute(self, repo_name: str, owner: Owner) -> None:
2727
self.validate_owner(owner)
2828
repo = Repository.objects.filter(author_id=owner.pk, name=repo_name).first()
2929
if not repo:

graphql_api/actions/flags.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from timeseries.models import Interval, MeasurementName
1111

1212

13-
def flags_for_repo(repository: Repository, filters: Mapping = None) -> QuerySet:
13+
def flags_for_repo(repository: Repository, filters: Mapping = {}) -> QuerySet:
1414
queryset = RepositoryFlag.objects.filter(
1515
repository=repository,
1616
deleted__isnot=True,

graphql_api/types/branch/branch.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Optional
22

33
from ariadne import ObjectType
4+
from graphql import GraphQLResolveInfo
45

56
from core.models import Branch, Commit
67
from graphql_api.dataloader.commit import CommitLoader
@@ -9,13 +10,15 @@
910

1011

1112
@branch_bindable.field("headSha")
12-
def resolve_head_sha(branch: Branch, info) -> str:
13+
def resolve_head_sha(branch: Branch, info: GraphQLResolveInfo) -> str:
1314
head = branch.head
1415
return head
1516

1617

1718
@branch_bindable.field("head")
18-
async def resolve_head_commit(branch: Branch, info) -> Optional[Commit]:
19+
async def resolve_head_commit(
20+
branch: Branch, info: GraphQLResolveInfo
21+
) -> Optional[Commit]:
1922
head = branch.head
2023
if head:
2124
loader = CommitLoader.loader(info, branch.repository_id)

graphql_api/types/mutation/save_okta_config/save_okta_config.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
from typing import Any, Dict
2+
13
from ariadne import UnionType
4+
from graphql import GraphQLResolveInfo
25

36
from graphql_api.helpers.mutation import (
47
require_authenticated,
@@ -9,7 +12,9 @@
912

1013
@wrap_error_handling_mutation
1114
@require_authenticated
12-
async def resolve_save_okta_config(_, info, input):
15+
async def resolve_save_okta_config(
16+
_: Any, info: GraphQLResolveInfo, input: Dict[str, Any]
17+
) -> None:
1318
command = info.context["executor"].get_command("owner")
1419
return await command.save_okta_config(input)
1520

graphs/mixins.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
from typing import Any
2+
13
from django.http import HttpResponse
24
from rest_framework import status
5+
from rest_framework.request import Request
36
from rest_framework.response import Response
47

58

69
class GraphBadgeAPIMixin(object):
7-
def get(self, request, *args, **kwargs):
10+
def get(self, request: Request, *args: Any, **kwargs: Any) -> Response:
811
ext = self.kwargs.get("ext")
912
if ext not in self.extensions:
1013
return Response(

0 commit comments

Comments
 (0)