Skip to content

Commit e8fc9e3

Browse files
mariuspruvotclaude
andcommitted
fix: lint and format fixes (ruff check + ruff format)
Remove unused imports, fix import sorting, apply ruff formatter to all Python source and test files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 70483d7 commit e8fc9e3

17 files changed

Lines changed: 93 additions & 165 deletions

File tree

apps/api/src/helprs/admin/views.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010

1111
class GitHubUserAdmin(ModelView, model=GitHubUser):
1212
column_list = [
13-
GitHubUser.id, GitHubUser.github_id, GitHubUser.github_login, GitHubUser.email, GitHubUser.created_at,
13+
GitHubUser.id,
14+
GitHubUser.github_id,
15+
GitHubUser.github_login,
16+
GitHubUser.email,
17+
GitHubUser.created_at,
1418
]
1519
column_searchable_list = [GitHubUser.github_login, GitHubUser.email]
1620
column_sortable_list = [GitHubUser.github_id, GitHubUser.github_login, GitHubUser.created_at]
@@ -70,9 +74,7 @@ async def login(self, request: Request) -> bool:
7074
settings = get_settings()
7175
# For MVP: accept any login if ENVIRONMENT is development,
7276
# otherwise require ADMIN_PASSWORD
73-
if settings.ENVIRONMENT == "development" or (
74-
settings.ADMIN_PASSWORD and password == settings.ADMIN_PASSWORD
75-
):
77+
if settings.ENVIRONMENT == "development" or (settings.ADMIN_PASSWORD and password == settings.ADMIN_PASSWORD):
7678
request.session.update({"authenticated": True})
7779
return True
7880
return False

apps/api/src/helprs/core/dependencies.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ async def get_current_user(
6363
except (ValueError, AttributeError) as e:
6464
raise UnauthorizedError("Invalid token payload") from e
6565

66-
result = await session.execute(
67-
select(GitHubUser).where(GitHubUser.id == user_id)
68-
)
66+
result = await session.execute(select(GitHubUser).where(GitHubUser.id == user_id))
6967
user = result.scalar_one_or_none()
7068
if not user:
7169
raise UnauthorizedError("User not found")

apps/api/src/helprs/modules/identity/router.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ async def github_login(request: Request, settings: GetSettings):
2929
"""Redirect to GitHub OAuth authorization page."""
3030
state = secrets.token_urlsafe(32)
3131
# Store state in a cookie for CSRF validation on callback
32-
params = urlencode({
33-
"client_id": settings.GITHUB_CLIENT_ID,
34-
"scope": OAUTH_SCOPES,
35-
"state": state,
36-
})
32+
params = urlencode(
33+
{
34+
"client_id": settings.GITHUB_CLIENT_ID,
35+
"scope": OAUTH_SCOPES,
36+
"state": state,
37+
}
38+
)
3739
is_secure = settings.ENVIRONMENT != "development"
3840
response = RedirectResponse(url=f"{GITHUB_AUTHORIZE_URL}?{params}")
3941
response.set_cookie(

apps/api/src/helprs/modules/identity/service.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,7 @@ async def get_or_create_user(
7979
github_id = github_user_data["id"]
8080
encrypted_token = fernet_encrypt(access_token, settings.FERNET_KEY)
8181

82-
result = await session.execute(
83-
select(GitHubUser).where(GitHubUser.github_id == github_id)
84-
)
82+
result = await session.execute(select(GitHubUser).where(GitHubUser.github_id == github_id))
8583
user = result.scalar_one_or_none()
8684

8785
if user:
@@ -148,9 +146,7 @@ async def refresh_tokens(
148146
except (ValueError, AttributeError) as e:
149147
raise UnauthorizedError("Invalid refresh token payload") from e
150148

151-
result = await session.execute(
152-
select(GitHubUser).where(GitHubUser.id == user_id)
153-
)
149+
result = await session.execute(select(GitHubUser).where(GitHubUser.id == user_id))
154150
user = result.scalar_one_or_none()
155151
if not user:
156152
raise UnauthorizedError("User not found")

apps/api/src/helprs/modules/installation/models.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ class Installation(Base):
1414

1515
__tablename__ = "installations"
1616

17-
github_installation_id: Mapped[int] = mapped_column(
18-
BigInteger, unique=True, index=True, nullable=False
19-
)
17+
github_installation_id: Mapped[int] = mapped_column(BigInteger, unique=True, index=True, nullable=False)
2018
account_login: Mapped[str] = mapped_column(String(255), nullable=False)
2119
account_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
2220
account_type: Mapped[str] = mapped_column(String(50), nullable=False)
@@ -26,16 +24,10 @@ class Installation(Base):
2624
permissions: Mapped[dict | None] = mapped_column(JSON, nullable=True)
2725
events: Mapped[list | None] = mapped_column(JSON, nullable=True)
2826
suppression_labels: Mapped[list | None] = mapped_column(JSON, nullable=True, default=list)
29-
suspended_at: Mapped[datetime | None] = mapped_column(
30-
DateTime(timezone=True), nullable=True
31-
)
32-
deleted_at: Mapped[datetime | None] = mapped_column(
33-
DateTime(timezone=True), nullable=True
34-
)
27+
suspended_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
28+
deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
3529

36-
byok_config: Mapped["BYOKConfig | None"] = relationship(
37-
"BYOKConfig", back_populates="installation", uselist=False
38-
)
30+
byok_config: Mapped["BYOKConfig | None"] = relationship("BYOKConfig", back_populates="installation", uselist=False)
3931

4032

4133
class BYOKConfig(Base):
@@ -48,11 +40,7 @@ class BYOKConfig(Base):
4840
)
4941
encrypted_api_key: Mapped[str] = mapped_column(String(1024), nullable=False)
5042
key_status: Mapped[str] = mapped_column(String(20), default="valid")
51-
validated_at: Mapped[datetime | None] = mapped_column(
52-
DateTime(timezone=True), nullable=True
53-
)
43+
validated_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
5444
key_hint: Mapped[str | None] = mapped_column(String(20), nullable=True)
5545

56-
installation: Mapped["Installation"] = relationship(
57-
"Installation", back_populates="byok_config"
58-
)
46+
installation: Mapped["Installation"] = relationship("Installation", back_populates="byok_config")

apps/api/src/helprs/modules/installation/router.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from helprs.modules.installation.service import (
1818
configure_byok,
1919
delete_byok_config,
20-
get_byok_config,
2120
get_installation_by_github_id,
2221
get_installations_for_user,
2322
update_suppression_labels,
@@ -100,9 +99,7 @@ async def post_byok(
10099
if not installation:
101100
raise NotFoundError("Installation not found")
102101
await verify_admin_permission(user, installation, settings)
103-
config = await configure_byok(
104-
session, installation.id, body.api_key, settings.FERNET_KEY
105-
)
102+
config = await configure_byok(session, installation.id, body.api_key, settings.FERNET_KEY)
106103
return BYOKConfigResponse.model_validate(config)
107104

108105

apps/api/src/helprs/modules/installation/schemas.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ def validate_labels(cls, v: list[str]) -> list[str]:
4242
if len(label) > 50:
4343
raise ValueError(f"Label '{label}' exceeds maximum 50 characters")
4444
if not re.match(r"^[a-zA-Z0-9\-]+$", label):
45-
raise ValueError(
46-
f"Label '{label}' contains invalid characters. Only alphanumeric and hyphens allowed"
47-
)
45+
raise ValueError(f"Label '{label}' contains invalid characters. Only alphanumeric and hyphens allowed")
4846
return v
4947

5048

apps/api/src/helprs/modules/installation/service.py

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ async def get_installation_access_token(installation_id: int, app_jwt: str) -> d
4646
except httpx.HTTPStatusError as e:
4747
if e.response.status_code == 401:
4848
raise UnauthorizedError("GitHub App JWT is invalid or expired") from e
49-
raise ExternalServiceError(
50-
f"GitHub API error: {e.response.status_code}"
51-
) from e
49+
raise ExternalServiceError(f"GitHub API error: {e.response.status_code}") from e
5250
return resp.json()
5351

5452

@@ -106,9 +104,7 @@ async def create_installation(session: AsyncSession, webhook_data: dict) -> Inst
106104
return installation
107105

108106

109-
async def soft_delete_installation(
110-
session: AsyncSession, github_installation_id: int
111-
) -> Installation | None:
107+
async def soft_delete_installation(session: AsyncSession, github_installation_id: int) -> Installation | None:
112108
"""Soft-delete an installation by setting deleted_at. Returns None if not found."""
113109
result = await session.execute(
114110
select(Installation).where(
@@ -128,9 +124,7 @@ async def soft_delete_installation(
128124
return installation
129125

130126

131-
async def suspend_installation(
132-
session: AsyncSession, github_installation_id: int
133-
) -> Installation | None:
127+
async def suspend_installation(session: AsyncSession, github_installation_id: int) -> Installation | None:
134128
"""Set suspended_at on an installation."""
135129
result = await session.execute(
136130
select(Installation).where(
@@ -150,9 +144,7 @@ async def suspend_installation(
150144
return installation
151145

152146

153-
async def unsuspend_installation(
154-
session: AsyncSession, github_installation_id: int
155-
) -> Installation | None:
147+
async def unsuspend_installation(session: AsyncSession, github_installation_id: int) -> Installation | None:
156148
"""Clear suspended_at on an installation."""
157149
result = await session.execute(
158150
select(Installation).where(
@@ -172,9 +164,7 @@ async def unsuspend_installation(
172164
return installation
173165

174166

175-
async def get_installation_by_github_id(
176-
session: AsyncSession, github_installation_id: int
177-
) -> Installation | None:
167+
async def get_installation_by_github_id(session: AsyncSession, github_installation_id: int) -> Installation | None:
178168
"""Lookup installation by GitHub ID, excluding soft-deleted records."""
179169
result = await session.execute(
180170
select(Installation).where(
@@ -185,9 +175,7 @@ async def get_installation_by_github_id(
185175
return result.scalar_one_or_none()
186176

187177

188-
async def get_installations_for_user(
189-
session: AsyncSession, user, settings: Settings
190-
) -> list[Installation]:
178+
async def get_installations_for_user(session: AsyncSession, user, settings: Settings) -> list[Installation]:
191179
"""Get installations the user has access to via the GitHub API."""
192180
try:
193181
github_token = fernet_decrypt(user.github_access_token_enc, settings.FERNET_KEY)
@@ -210,13 +198,9 @@ async def get_installations_for_user(
210198
except httpx.HTTPStatusError as e:
211199
if e.response.status_code == 401:
212200
raise UnauthorizedError("GitHub token is invalid or revoked") from e
213-
raise ExternalServiceError(
214-
f"GitHub API error: {e.response.status_code}"
215-
) from e
201+
raise ExternalServiceError(f"GitHub API error: {e.response.status_code}") from e
216202

217-
user_installation_ids = {
218-
inst["id"] for inst in resp.json().get("installations", [])
219-
}
203+
user_installation_ids = {inst["id"] for inst in resp.json().get("installations", [])}
220204

221205
if not user_installation_ids:
222206
return []
@@ -230,9 +214,7 @@ async def get_installations_for_user(
230214
return list(result.scalars().all())
231215

232216

233-
async def verify_admin_permission(
234-
user, installation: Installation, settings: Settings
235-
) -> bool:
217+
async def verify_admin_permission(user, installation: Installation, settings: Settings) -> bool:
236218
"""Verify user has admin permission on the installation's org/repo."""
237219
try:
238220
github_token = fernet_decrypt(user.github_access_token_enc, settings.FERNET_KEY)
@@ -262,12 +244,8 @@ async def verify_admin_permission(
262244
if e.response.status_code == 401:
263245
raise UnauthorizedError("GitHub token is invalid or revoked") from e
264246
if e.response.status_code in (403, 404):
265-
raise ForbiddenError(
266-
"You do not have admin access to this installation"
267-
) from e
268-
raise ExternalServiceError(
269-
f"GitHub API error: {e.response.status_code}"
270-
) from e
247+
raise ForbiddenError("You do not have admin access to this installation") from e
248+
raise ExternalServiceError(f"GitHub API error: {e.response.status_code}") from e
271249

272250
membership = resp.json()
273251
if membership.get("role") != "admin" or membership.get("state") != "active":
@@ -298,9 +276,7 @@ async def validate_anthropic_api_key(api_key: str) -> bool:
298276
except httpx.TimeoutException as e:
299277
raise ExternalServiceError("Anthropic API is temporarily unavailable") from e
300278
except httpx.HTTPStatusError as e:
301-
raise ExternalServiceError(
302-
f"Anthropic API error: {e.response.status_code}"
303-
) from e
279+
raise ExternalServiceError(f"Anthropic API error: {e.response.status_code}") from e
304280
except httpx.TransportError as e:
305281
raise ExternalServiceError("Anthropic API is temporarily unavailable") from e
306282

@@ -314,9 +290,7 @@ async def configure_byok(
314290
"""Configure BYOK key for an installation. Validates, encrypts, and upserts."""
315291
is_valid = await validate_anthropic_api_key(api_key)
316292
if not is_valid:
317-
raise BYOKKeyInvalidError(
318-
"API key validation failed -- check your key and try again"
319-
)
293+
raise BYOKKeyInvalidError("API key validation failed -- check your key and try again")
320294

321295
encrypted_key = fernet_encrypt(api_key, fernet_key)
322296
key_hint = f"...{api_key[-4:]}"
@@ -346,13 +320,9 @@ async def configure_byok(
346320
return config
347321

348322

349-
async def get_byok_config(
350-
session: AsyncSession, installation_id: uuid.UUID
351-
) -> BYOKConfig | None:
323+
async def get_byok_config(session: AsyncSession, installation_id: uuid.UUID) -> BYOKConfig | None:
352324
"""Get BYOK config for an installation."""
353-
result = await session.execute(
354-
select(BYOKConfig).where(BYOKConfig.installation_id == installation_id)
355-
)
325+
result = await session.execute(select(BYOKConfig).where(BYOKConfig.installation_id == installation_id))
356326
return result.scalar_one_or_none()
357327

358328

@@ -364,9 +334,7 @@ def decrypt_byok_key(byok_config: BYOKConfig, fernet_key: str) -> str:
364334
raise BYOKKeyInvalidError("Stored API key could not be decrypted") from e
365335

366336

367-
async def delete_byok_config(
368-
session: AsyncSession, installation_id: uuid.UUID
369-
) -> bool:
337+
async def delete_byok_config(session: AsyncSession, installation_id: uuid.UUID) -> bool:
370338
"""Hard delete BYOK config for an installation."""
371339
config = await get_byok_config(session, installation_id)
372340
if not config:
@@ -395,9 +363,7 @@ async def update_suppression_labels(
395363
raise DomainValidationError("Maximum 20 suppression labels allowed")
396364
for label in labels:
397365
if len(label) > 50:
398-
raise DomainValidationError(
399-
f"Label '{label}' exceeds maximum length of 50 characters"
400-
)
366+
raise DomainValidationError(f"Label '{label}' exceeds maximum length of 50 characters")
401367
if not LABEL_PATTERN.match(label):
402368
raise DomainValidationError(
403369
f"Label '{label}' contains invalid characters. Only alphanumeric and hyphens allowed"

apps/api/src/helprs/modules/webhook/dispatcher.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@
2121
}
2222

2323

24-
async def dispatch_webhook(
25-
event_type: str, action: str, payload: dict, session: AsyncSession
26-
) -> None:
24+
async def dispatch_webhook(event_type: str, action: str, payload: dict, session: AsyncSession) -> None:
2725
"""Route webhook events to the appropriate handler."""
2826
handler = _HANDLERS.get((event_type, action))
2927
if handler:

apps/api/tests/modules/identity/test_router.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,7 @@ async def test_valid_callback(self, app_with_db):
116116
follow_redirects=False,
117117
) as client:
118118
client.cookies.set("oauth_state", state)
119-
resp = await client.get(
120-
f"/api/v1/auth/github/callback?code=test_code&state={state}"
121-
)
119+
resp = await client.get(f"/api/v1/auth/github/callback?code=test_code&state={state}")
122120
assert resp.status_code == 307
123121
location = resp.headers["location"]
124122
assert "access_token=" in location
@@ -130,9 +128,7 @@ async def test_invalid_state(self, app_with_db):
130128
base_url="http://test",
131129
follow_redirects=False,
132130
) as client:
133-
resp = await client.get(
134-
"/api/v1/auth/github/callback?code=test&state=invalid"
135-
)
131+
resp = await client.get("/api/v1/auth/github/callback?code=test&state=invalid")
136132
assert resp.status_code == 401
137133

138134

0 commit comments

Comments
 (0)