Skip to content

Commit 0e3596a

Browse files
authored
Fix backend lint errors (#836)
* Fix backend lint errors * Post-review update
1 parent d8d611e commit 0e3596a

35 files changed

+270
-87
lines changed

backend/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ dependencies = { file = ["requirements.txt"] }
3434
# Ruff
3535
[tool.ruff]
3636
line-length = 120
37-
3837
# Exclude a variety of commonly ignored directories.
3938
exclude = [
4039
".bzr",
@@ -57,6 +56,7 @@ exclude = [
5756
"dist",
5857
"node_modules",
5958
"venv",
59+
"src/appointment/migrations"
6060
]
6161

6262
# Always generate Python 3.12-compatible code.

backend/src/appointment/controller/apis/fxa_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from requests_oauthlib import OAuth2Session
77
import requests
88
from ...database import models, repo
9-
from ...exceptions.fxa_api import NotInAllowListException, MissingRefreshTokenException
9+
from ...exceptions.fxa_api import MissingRefreshTokenException
1010

1111

1212
class FxaConfig:

backend/src/appointment/controller/apis/google_client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ def get_free_busy(self, calendar_ids, time_min, time_max, token):
113113
perf_start = time.perf_counter_ns()
114114
with build('calendar', 'v3', credentials=token, cache_discovery=False) as service:
115115
request = service.freebusy().query(
116-
body=dict(timeMin=time_min, timeMax=time_max, items=[{'id': calendar_id} for calendar_id in calendar_ids])
116+
body=dict(
117+
timeMin=time_min,
118+
timeMax=time_max,
119+
items=[{'id': calendar_id} for calendar_id in calendar_ids]
120+
)
117121
)
118122

119123
while request is not None:

backend/src/appointment/controller/auth.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ def schedule_links_by_subscriber(db, subscriber: models.Subscriber):
7373
url_safe_username = urllib.parse.quote_plus(subscriber.username)
7474

7575
# Empty space at join is for trailing slash!
76-
return list(map(lambda sch: '/'.join([short_url, url_safe_username, urllib.parse.quote_plus(sch.slug), '']), schedules))
76+
return list(map(
77+
lambda sch: '/'.join([short_url, url_safe_username, urllib.parse.quote_plus(sch.slug), '']),
78+
schedules)
79+
)

backend/src/appointment/controller/calendar.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import time
99
import zoneinfo
1010
import os
11-
from socket import getaddrinfo
1211
from urllib.parse import urlparse, urljoin
1312

1413
import caldav.lib.error
@@ -27,8 +26,7 @@
2726
from sqlalchemy.orm import Session
2827

2928
from .. import utils
30-
from ..database.schemas import CalendarConnection
31-
from ..defines import REDIS_REMOTE_EVENTS_KEY, DATEFMT, DEFAULT_CALENDAR_COLOUR, DATETIMEFMT
29+
from ..defines import REDIS_REMOTE_EVENTS_KEY, DATEFMT, DEFAULT_CALENDAR_COLOUR
3230
from .apis.google_client import GoogleClient
3331
from ..database.models import CalendarProvider, BookingStatus
3432
from ..database import schemas, models, repo
@@ -82,7 +80,12 @@ def get_cached_events(self, key_scope):
8280

8381
return [schemas.Event.model_load_redis(blob) for blob in json.loads(encrypted_events)]
8482

85-
def put_cached_events(self, key_scope, events: list[schemas.Event], expiry=os.getenv('REDIS_EVENT_EXPIRE_SECONDS', 900)):
83+
def put_cached_events(
84+
self,
85+
key_scope,
86+
events: list[schemas.Event],
87+
expiry=os.getenv('REDIS_EVENT_EXPIRE_SECONDS', 900)
88+
):
8689
"""Sets the passed cached events with an option to set a custom expiry time."""
8790
if self.redis_instance is None:
8891
return False
@@ -291,7 +294,11 @@ def save_event(
291294
},
292295
}
293296

294-
new_event = self.google_client.save_event(calendar_id=self.remote_calendar_id, body=body, token=self.google_token)
297+
new_event = self.google_client.save_event(
298+
calendar_id=self.remote_calendar_id,
299+
body=body,
300+
token=self.google_token
301+
)
295302

296303
# Fill in the external_id so we can delete events later!
297304
event.external_id = new_event.get('id')
@@ -314,7 +321,16 @@ def delete_events(self, start):
314321

315322

316323
class CalDavConnector(BaseConnector):
317-
def __init__(self, db: Session, subscriber_id: int, calendar_id: int, redis_instance, url: str, user: str, password: str):
324+
def __init__(
325+
self,
326+
db: Session,
327+
subscriber_id: int,
328+
calendar_id: int,
329+
redis_instance,
330+
url: str,
331+
user: str,
332+
password: str
333+
):
318334
super().__init__(subscriber_id, calendar_id, redis_instance)
319335

320336
self.db = db
@@ -343,8 +359,8 @@ def get_busy_time(self, calendar_ids: list, start: str, end: str):
343359

344360
items = []
345361

346-
# This is sort of dumb, freebusy object isn't exposed in the icalendar instance except through a list of tuple props
347-
# Luckily the value is a vPeriod which is a tuple of date times/timedelta (0 = Start, 1 = End)
362+
# This is sort of dumb, freebusy object isn't exposed in the icalendar instance except through a list of tuple
363+
# props; luckily the value is a vPeriod which is a tuple of date times/timedelta (0 = Start, 1 = End)
348364
for prop in response.icalendar_instance.property_items():
349365
if prop[0].lower() != 'freebusy':
350366
continue
@@ -904,7 +920,11 @@ def existing_events_for_schedule(
904920
start=busy.get('start'),
905921
end=busy.get('end'),
906922
title='Busy'
907-
) for busy in con.get_busy_time([calendar.user for calendar in google_calendars], start.strftime(DATEFMT), end.strftime(DATEFMT))
923+
) for busy in con.get_busy_time(
924+
[calendar.user for calendar in google_calendars],
925+
start.strftime(DATEFMT),
926+
end.strftime(DATEFMT)
927+
)
908928
])
909929

910930
# handle already requested time slots

backend/src/appointment/controller/mailer.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,15 @@ def __init__(self, name, email, date, duration, schedule_name, *args, **kwargs):
352352
self.schedule_name = schedule_name
353353
lang = kwargs['lang'] if 'lang' in kwargs else None
354354
default_kwargs = {'subject': l10n('new-booking-subject', {'name': name}, lang)}
355-
super(NewBookingMail, self).__init__(name=name, email=email, date=date, duration=duration, *args, **default_kwargs, **kwargs)
355+
super(NewBookingMail, self).__init__(
356+
name=name,
357+
email=email,
358+
date=date,
359+
duration=duration,
360+
*args,
361+
**default_kwargs,
362+
**kwargs
363+
)
356364
self.reply_to = email
357365

358366
def text(self):
@@ -391,7 +399,12 @@ def __init__(self, requestee_name, requestee_email, topic, details, *args, **kwa
391399
self.topic = topic
392400
self.details = details
393401
default_kwargs = {'subject': l10n('support-mail-subject', {'topic': topic})}
394-
super(SupportRequestMail, self).__init__(os.getenv('SUPPORT_EMAIL', 'help@tb.net'), *args, **default_kwargs, **kwargs)
402+
super(SupportRequestMail, self).__init__(
403+
os.getenv('SUPPORT_EMAIL', 'help@tb.net'),
404+
*args,
405+
**default_kwargs,
406+
**kwargs
407+
)
395408
self.reply_to = requestee_email
396409

397410
def text(self):

backend/src/appointment/database/models.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,20 @@ class Subscriber(HasSoftDelete, Base):
164164
external_connections = relationship('ExternalConnections', cascade='all,delete', back_populates='owner')
165165

166166
# FIXME: Invite will be deleted if either the owner or the invited subscriber is deleted.
167-
invite: Mapped['Invite'] = relationship('Invite', cascade='all,delete', back_populates='subscriber', uselist=False, foreign_keys='Invite.subscriber_id')
168-
owned_invites: Mapped[list['Invite']] = relationship('Invite', cascade='all,delete', back_populates='owner', foreign_keys='[Invite.owner_id]')
167+
invite: Mapped['Invite'] = relationship(
168+
'Invite',
169+
cascade='all,delete',
170+
back_populates='subscriber',
171+
uselist=False,
172+
foreign_keys='Invite.subscriber_id'
173+
)
174+
175+
owned_invites: Mapped[list['Invite']] = relationship(
176+
'Invite',
177+
cascade='all,delete',
178+
back_populates='owner',
179+
foreign_keys='[Invite.owner_id]'
180+
)
169181

170182
def get_external_connection(self, type: ExternalConnectionType) -> 'ExternalConnections':
171183
"""Retrieves the first found external connection by type or returns None if not found"""
@@ -242,7 +254,12 @@ class Appointment(Base):
242254
)
243255

244256
calendar: Mapped[Calendar] = relationship('Calendar', back_populates='appointments')
245-
slots: Mapped[list['Slot']] = relationship('Slot', cascade='all,delete', back_populates='appointment', lazy='joined')
257+
slots: Mapped[list['Slot']] = relationship(
258+
'Slot',
259+
cascade='all,delete',
260+
back_populates='appointment',
261+
lazy='joined'
262+
)
246263

247264

248265
class Attendee(Base):
@@ -305,7 +322,7 @@ class Schedule(Base):
305322
weekdays: str | dict = Column(JSON, default='[1,2,3,4,5]') # list of ISO weekdays, Mo-Su => 1-7
306323
slot_duration: int = Column(Integer, default=30) # defaults to 30 minutes
307324
booking_confirmation: bool = Column(Boolean, index=True, nullable=False, default=True)
308-
timezone: str = Column(encrypted_type(String), index=True, nullable=True) # Not used right now but will be in the future
325+
timezone: str = Column(encrypted_type(String), index=True, nullable=True) # Not used now but will be in the future
309326

310327
# What (if any) meeting link will we generate once the meeting is booked
311328
meeting_link_provider: MeetingLinkProviderType = Column(
@@ -385,9 +402,26 @@ class Invite(Base):
385402
code = Column(encrypted_type(String), index=False)
386403
status = Column(Enum(InviteStatus), index=True)
387404

388-
owner: Mapped['Subscriber'] = relationship('Subscriber', back_populates='invite', single_parent=True, foreign_keys=[owner_id])
389-
subscriber: Mapped['Subscriber'] = relationship('Subscriber', back_populates='invite', single_parent=True, foreign_keys=[subscriber_id])
390-
waiting_list: Mapped['WaitingList'] = relationship('WaitingList', cascade='all,delete', back_populates='invite', uselist=False)
405+
owner: Mapped['Subscriber'] = relationship(
406+
'Subscriber',
407+
back_populates='invite',
408+
single_parent=True,
409+
foreign_keys=[owner_id]
410+
)
411+
412+
subscriber: Mapped['Subscriber'] = relationship(
413+
'Subscriber',
414+
back_populates='invite',
415+
single_parent=True,
416+
foreign_keys=[subscriber_id]
417+
)
418+
419+
waiting_list: Mapped['WaitingList'] = relationship(
420+
'WaitingList',
421+
cascade='all,delete',
422+
back_populates='invite',
423+
uselist=False
424+
)
391425

392426
@property
393427
def is_used(self) -> bool:

backend/src/appointment/database/repo/calendar.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ def create(db: Session, calendar: schemas.CalendarConnection, subscriber_id: int
6666
return db_calendar
6767

6868

69-
def update_by_calendar(db: Session, calendar: schemas.CalendarConnection, db_calendar: models.Calendar) -> models.Calendar|None:
69+
def update_by_calendar(
70+
db: Session,
71+
calendar: schemas.CalendarConnection,
72+
db_calendar: models.Calendar
73+
) -> models.Calendar|None:
7074
"""Update a calendar from the database with calendar data."""
7175

7276
# list of all attributes that must never be updated
@@ -142,7 +146,12 @@ def delete_by_subscriber(db: Session, subscriber_id: int):
142146
return True
143147

144148

145-
def delete_by_subscriber_and_provider(db: Session, subscriber_id: int, provider: models.CalendarProvider, user: Optional[str] = None):
149+
def delete_by_subscriber_and_provider(
150+
db: Session,
151+
subscriber_id: int,
152+
provider: models.CalendarProvider,
153+
user: Optional[str] = None
154+
):
146155
"""Delete all subscriber's calendar by a provider"""
147156
calendars = get_by_subscriber(db, subscriber_id=subscriber_id)
148157
for calendar in calendars:

backend/src/appointment/database/repo/invite.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ def get_by_subscriber(db: Session, subscriber_id: int) -> models.Invite:
1515
return db.query(models.Invite).filter(models.Invite.subscriber_id == subscriber_id).first()
1616

1717

18-
def get_by_owner(db: Session, subscriber_id: int, status: Optional[InviteStatus] = None, only_unused: bool = False) -> list[models.Invite]:
18+
def get_by_owner(
19+
db: Session,
20+
subscriber_id: int,
21+
status: Optional[InviteStatus] = None,
22+
only_unused: bool = False
23+
) -> list[models.Invite]:
1924
"""Retrieve invites by the invite owner. Optionally filter by status, or unused."""
2025
query = db.query(models.Invite)
2126
filters = [models.Invite.owner_id == subscriber_id]

backend/src/appointment/database/repo/subscriber.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
Repository providing CRUD functions for subscriber database models.
44
"""
55

6-
import re
76
import datetime
87
import secrets
9-
import urllib.parse
108

119
from sqlalchemy.orm import Session
1210
from .. import models, schemas

0 commit comments

Comments
 (0)