Skip to content

Commit f6a18b7

Browse files
authored
Issue LIF-Initiative#853: Apply ruff formatting and lint auto-fixes (LIF-Initiative#855)
##### Description of Change Applies `ruff check --fix` and `ruff format` across the codebase to resolve accumulated formatting drift and lint auto-fixable issues. - **Problem:** Multiple files had accumulated formatting inconsistencies and auto-fixable lint issues (unused imports, trailing whitespace, missing blank lines, single-line vs multi-line expressions). - **Solution:** Ran `ruff check --fix` and `ruff format` against the full codebase. - **Side effects:** None — purely cosmetic/style changes with no logic modifications. 33 files reformatted across components, bases, tests, integration tests, scripts, and orchestrators. ##### Related Issues Closes LIF-Initiative#853 ##### Type of Change - [x] Code refactoring ##### Project Area(s) Affected - [x] bases/ - [x] components/ - [x] orchestrators/ - [x] Testing --- ##### Checklist - [x] code passes linting checks (`uv run ruff check`) - [x] code passes formatting checks (`uv run ruff format`) ##### Testing - No logic changes — formatting only. ##### Additional Notes 9 remaining lint warnings (E721, F823) are not auto-fixable and are pre-existing. They require manual review and are out of scope for this PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
2 parents df28156 + 84adc63 commit f6a18b7

File tree

32 files changed

+1001
-1355
lines changed

32 files changed

+1001
-1355
lines changed

bases/lif/semantic_search_mcp_server/core.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@
2424
from lif.lif_schema_config import DEFAULT_ATTRIBUTE_KEYS, LIFSchemaConfig
2525
from lif.logging import get_logger
2626
from lif.schema_state_manager import SchemaStateManager
27-
from lif.semantic_search_service.core import (
28-
run_mutation,
29-
run_semantic_search,
30-
)
27+
from lif.semantic_search_service.core import run_mutation, run_semantic_search
3128

3229
logger = get_logger(__name__)
3330

@@ -119,9 +116,7 @@ async def schema_refresh(request: Request) -> JSONResponse:
119116

120117

121118
@mcp.tool(
122-
name="lif_query",
123-
description="Use this tool to run a LIF data query",
124-
annotations={"title": "Execute LIF Query"},
119+
name="lif_query", description="Use this tool to run a LIF data query", annotations={"title": "Execute LIF Query"}
125120
)
126121
async def lif_query(
127122
filter: Annotated[Filter, Field(description="Parameters for LIF query")],

cloudformation/cf-env-check.py

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@
1919

2020
import argparse
2121
import difflib
22-
import os
2322
import re
2423
import sys
2524
from dataclasses import dataclass
2625
from pathlib import Path
27-
from typing import Iterable, List, Optional, Sequence, Tuple
26+
from typing import List, Optional, Sequence, Tuple
2827

2928
# -----------------------------
3029
# Config
@@ -35,9 +34,7 @@
3534
re.compile(r"arn:aws:[^:]+:[^:]*:[^:]*:"), # generic ARN noise
3635
]
3736

38-
ECR_IMAGE_REF_RE = re.compile(
39-
r'([0-9]{12}\.dkr\.ecr\.[a-z0-9-]+\.amazonaws\.com/[A-Za-z0-9._\-/]+):([A-Za-z0-9._-]+)'
40-
)
37+
ECR_IMAGE_REF_RE = re.compile(r"([0-9]{12}\.dkr\.ecr\.[a-z0-9-]+\.amazonaws\.com/[A-Za-z0-9._\-/]+):([A-Za-z0-9._-]+)")
4138

4239
# Heuristic: only count a non-env diff as a "warning" if it hits any of these.
4340
SUSPICIOUS_NONENV_PATTERNS = [
@@ -55,12 +52,14 @@
5552
# Data types
5653
# -----------------------------
5754

55+
5856
@dataclass(frozen=True)
5957
class Pair:
6058
key: str
6159
dev: Path
6260
demo: Path
6361

62+
6463
@dataclass
6564
class CheckResult:
6665
key: str
@@ -74,17 +73,21 @@ class CheckResult:
7473
docker_warnings: List[str]
7574
cross_env_warnings: List[str]
7675

76+
7777
# -----------------------------
7878
# Helpers
7979
# -----------------------------
8080

81+
8182
def read_text(path: Path) -> str:
8283
return path.read_text(encoding="utf-8", errors="replace")
8384

85+
8486
def split_lines_keepends(s: str) -> List[str]:
8587
# difflib wants lists of lines *with* newline endings to preserve formatting
8688
return s.splitlines(keepends=True)
8789

90+
8891
def canonicalize_env(s: str) -> str:
8992
"""
9093
Normalize common dev/demo markers -> __ENV__ so only unexpected diffs remain.
@@ -107,20 +110,15 @@ def canonicalize_env(s: str) -> str:
107110
s = ECR_IMAGE_REF_RE.sub(r"\1:__TAG__", s)
108111
return s
109112

113+
110114
def unified_diff(a_text: str, b_text: str, a_name: str, b_name: str) -> str:
111115
a_lines = split_lines_keepends(a_text)
112116
b_lines = split_lines_keepends(b_text)
113-
diff_lines = difflib.unified_diff(
114-
a_lines,
115-
b_lines,
116-
fromfile=a_name,
117-
tofile=b_name,
118-
lineterm="",
119-
n=3,
120-
)
117+
diff_lines = difflib.unified_diff(a_lines, b_lines, fromfile=a_name, tofile=b_name, lineterm="", n=3)
121118
# difflib.unified_diff already provides lines without trailing newline when lineterm=""
122119
return "\n".join(diff_lines)
123120

121+
124122
def diff_changed_lines(diff_text: str) -> List[str]:
125123
"""
126124
Return only changed lines from a unified diff:
@@ -132,6 +130,7 @@ def diff_changed_lines(diff_text: str) -> List[str]:
132130
out.append(line)
133131
return out
134132

133+
135134
def is_suspicious_nonenv(diff_text: str) -> bool:
136135
changed = diff_changed_lines(diff_text)
137136
for line in changed:
@@ -140,10 +139,14 @@ def is_suspicious_nonenv(diff_text: str) -> bool:
140139
return True
141140
return False
142141

142+
143143
def any_allowlisted(line: str, allowlist: Sequence[re.Pattern]) -> bool:
144144
return any(p.search(line) for p in allowlist)
145145

146-
def find_cross_env_leftovers(lines: Sequence[str], forbidden_token: str, allowlist: Sequence[re.Pattern]) -> List[Tuple[int, str]]:
146+
147+
def find_cross_env_leftovers(
148+
lines: Sequence[str], forbidden_token: str, allowlist: Sequence[re.Pattern]
149+
) -> List[Tuple[int, str]]:
147150
"""
148151
Find occurrences of forbidden_token as a whole word in lines that are not allowlisted.
149152
Returns list of (lineno, line).
@@ -155,6 +158,7 @@ def find_cross_env_leftovers(lines: Sequence[str], forbidden_token: str, allowli
155158
hits.append((i, line.rstrip("\n")))
156159
return hits
157160

161+
158162
def extract_ecr_images(content: str) -> List[Tuple[str, str]]:
159163
"""
160164
Return list of (image_repo, tag)
@@ -164,6 +168,7 @@ def extract_ecr_images(content: str) -> List[Tuple[str, str]]:
164168
hits.append((m.group(1), m.group(2)))
165169
return hits
166170

171+
167172
def check_docker_policy(env: str, filename: str, content: str) -> List[str]:
168173
"""
169174
env: 'dev' or 'demo'
@@ -176,6 +181,7 @@ def check_docker_policy(env: str, filename: str, content: str) -> List[str]:
176181
warnings.append(f"{filename}: demo files must NOT use :latest but found :latest ({image}:{tag})")
177182
return warnings
178183

184+
179185
def list_env_files(directory: Path) -> List[Path]:
180186
out: List[Path] = []
181187
for p in directory.iterdir():
@@ -185,14 +191,15 @@ def list_env_files(directory: Path) -> List[Path]:
185191
out.append(p)
186192
return out
187193

194+
188195
def pair_files(paths: Sequence[Path]) -> Tuple[List[Pair], List[str]]:
189196
dev_map = {}
190197
demo_map = {}
191198
for p in paths:
192199
if p.name.startswith("dev-"):
193-
dev_map[p.name[len("dev-"):]] = p
200+
dev_map[p.name[len("dev-") :]] = p
194201
elif p.name.startswith("demo-"):
195-
demo_map[p.name[len("demo-"):]] = p
202+
demo_map[p.name[len("demo-") :]] = p
196203

197204
keys = sorted(set(dev_map) | set(demo_map))
198205
pairs: List[Pair] = []
@@ -208,39 +215,32 @@ def pair_files(paths: Sequence[Path]) -> Tuple[List[Pair], List[str]]:
208215

209216
return pairs, orphans
210217

218+
211219
def print_section(title: str) -> None:
212220
print("\n" + "=" * 60)
213221
print(title)
214222
print("=" * 60)
215223

224+
216225
# -----------------------------
217226
# Main check logic
218227
# -----------------------------
219228

229+
220230
def check_pair(pair: Pair, allowlist: Sequence[re.Pattern], show_full_diff: bool) -> CheckResult:
221231
dev_text = read_text(pair.dev)
222232
demo_text = read_text(pair.demo)
223233

224234
# Full diff (demo vs dev) to match your usual reading order
225-
full = unified_diff(
226-
demo_text,
227-
dev_text,
228-
a_name=pair.demo.name,
229-
b_name=pair.dev.name,
230-
)
235+
full = unified_diff(demo_text, dev_text, a_name=pair.demo.name, b_name=pair.dev.name)
231236

232237
# Normalized diff
233238
demo_norm = canonicalize_env(demo_text)
234239
dev_norm = canonicalize_env(dev_text)
235-
norm = unified_diff(
236-
demo_norm,
237-
dev_norm,
238-
a_name=pair.demo.name + ".norm",
239-
b_name=pair.dev.name + ".norm",
240-
)
240+
norm = unified_diff(demo_norm, dev_norm, a_name=pair.demo.name + ".norm", b_name=pair.dev.name + ".norm")
241241

242-
env_only = (full != "" and norm == "")
243-
has_nonenv = (norm != "")
242+
env_only = full != "" and norm == ""
243+
has_nonenv = norm != ""
244244
suspicious = is_suspicious_nonenv(norm) if has_nonenv else False
245245

246246
# Docker policy warnings
@@ -285,10 +285,15 @@ def check_pair(pair: Pair, allowlist: Sequence[re.Pattern], show_full_diff: bool
285285
cross_env_warnings=cross_env_warnings,
286286
)
287287

288+
288289
def main(argv: Optional[Sequence[str]] = None) -> int:
289290
ap = argparse.ArgumentParser(add_help=True)
290291
ap.add_argument("--dir", default=".", help="Directory to scan for dev-* and demo-* files")
291-
ap.add_argument("--no-diff", action="store_true", help="Do not print full diffs; still prints normalized diffs for non-env cases")
292+
ap.add_argument(
293+
"--no-diff",
294+
action="store_true",
295+
help="Do not print full diffs; still prints normalized diffs for non-env cases",
296+
)
292297
ap.add_argument("--allow", action="append", default=[], help="Regex allowlist for cross-env leftovers (can repeat)")
293298
ap.add_argument("--show-env-only", action="store_true", help="Also print env-only full diffs (can be noisy)")
294299

@@ -391,5 +396,6 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
391396
print(" -", w)
392397
return 2
393398

399+
394400
if __name__ == "__main__":
395401
raise SystemExit(main())

components/lif/api_key_auth/core.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ class ApiKeyConfig:
4848
public_path_prefixes: Set[str] = field(default_factory=lambda: {"/docs", "/openapi.json"})
4949

5050
# HTTP methods that require authentication (empty set = no auth required)
51-
methods_requiring_auth: Set[str] = field(
52-
default_factory=lambda: {"GET", "POST", "PUT", "DELETE", "PATCH"}
53-
)
51+
methods_requiring_auth: Set[str] = field(default_factory=lambda: {"GET", "POST", "PUT", "DELETE", "PATCH"})
5452

5553
@classmethod
5654
def from_environment(cls, prefix: str = "API_AUTH") -> "ApiKeyConfig":
@@ -82,18 +80,10 @@ def from_environment(cls, prefix: str = "API_AUTH") -> "ApiKeyConfig":
8280
if key and name:
8381
api_keys[key] = name
8482

85-
public_paths = cls._parse_csv_set(
86-
os.environ.get(f"{prefix}__PUBLIC_PATHS", "/health,/health-check")
87-
)
88-
public_prefixes = cls._parse_csv_set(
89-
os.environ.get(f"{prefix}__PUBLIC_PATH_PREFIXES", "/docs,/openapi.json")
90-
)
83+
public_paths = cls._parse_csv_set(os.environ.get(f"{prefix}__PUBLIC_PATHS", "/health,/health-check"))
84+
public_prefixes = cls._parse_csv_set(os.environ.get(f"{prefix}__PUBLIC_PATH_PREFIXES", "/docs,/openapi.json"))
9185

92-
return cls(
93-
api_keys=api_keys,
94-
public_paths=public_paths,
95-
public_path_prefixes=public_prefixes,
96-
)
86+
return cls(api_keys=api_keys, public_paths=public_paths, public_path_prefixes=public_prefixes)
9787

9888
@staticmethod
9989
def _parse_csv_set(value: str) -> Set[str]:
@@ -158,9 +148,7 @@ async def dispatch(self, request: Request, call_next):
158148
if not client_name:
159149
logger.warning("Request to %s rejected: invalid API key", path)
160150
return JSONResponse(
161-
status_code=401,
162-
content={"detail": "Invalid API key."},
163-
headers={"WWW-Authenticate": "X-API-Key"},
151+
status_code=401, content={"detail": "Invalid API key."}, headers={"WWW-Authenticate": "X-API-Key"}
164152
)
165153

166154
# Store client info for downstream use (logging, auditing, etc.)

components/lif/datatypes/core.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,7 @@ class LIFQueryPersonFilter(BaseModel):
8282
model_config = ConfigDict(populate_by_name=True)
8383

8484
# Use alias="Person" to accept PascalCase from GraphQL API while keeping lowercase internally
85-
person: LIFPersonIdentifiers = Field(
86-
..., alias="Person", description="Person identifier for the query"
87-
)
85+
person: LIFPersonIdentifiers = Field(..., alias="Person", description="Person identifier for the query")
8886

8987

9088
class LIFQueryFilter(RootModel[LIFQueryPersonFilter]):

components/lif/lif_schema_config/__init__.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818
print(config.graphql_query_name) # "person"
1919
"""
2020

21-
from lif.lif_schema_config.core import (
22-
LIFSchemaConfig,
23-
LIFSchemaConfigError,
24-
)
21+
from lif.lif_schema_config.core import LIFSchemaConfig, LIFSchemaConfigError
2522
from lif.lif_schema_config.naming import (
2623
normalize_identifier_type,
2724
safe_identifier,
@@ -56,12 +53,7 @@
5653
list_schema_names,
5754
resolve_ref,
5855
)
59-
from lif.lif_schema_config.type_mappings import (
60-
PYTHON_TO_XSD,
61-
XSD_TO_PYTHON,
62-
python_type_for_xsd,
63-
xsd_type_for_python,
64-
)
56+
from lif.lif_schema_config.type_mappings import PYTHON_TO_XSD, XSD_TO_PYTHON, python_type_for_xsd, xsd_type_for_python
6557

6658
__all__ = [
6759
# Core config

components/lif/lif_schema_config/core.py

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ class LIFSchemaConfig:
8989

9090
# Root Type Configuration
9191
root_type_name: str = "Person"
92-
additional_root_types: List[str] = field(
93-
default_factory=lambda: ["Course", "Organization", "Credential"]
94-
)
92+
additional_root_types: List[str] = field(default_factory=lambda: ["Course", "Organization", "Credential"])
9593

9694
# Query Planner URLs
9795
query_planner_base_url: str = "http://localhost:8002"
@@ -170,21 +168,16 @@ def from_environment(cls) -> "LIFSchemaConfig":
170168
LIFSchemaConfig: Configuration loaded from environment.
171169
"""
172170
# Parse root types
173-
root_type_name = os.getenv("LIF_GRAPHQL_ROOT_TYPE_NAME",
174-
os.getenv("LIF_GRAPHQL_ROOT_NODE", "Person"))
171+
root_type_name = os.getenv("LIF_GRAPHQL_ROOT_TYPE_NAME", os.getenv("LIF_GRAPHQL_ROOT_NODE", "Person"))
175172

176173
# Parse additional root types (these serve as reference data)
177174
root_nodes_str = os.getenv("LIF_GRAPHQL_ROOT_NODES", "Course,Organization,Credential")
178175
additional_root_types = [
179-
node.strip() for node in root_nodes_str.split(",")
180-
if node.strip() and node.strip() != root_type_name
176+
node.strip() for node in root_nodes_str.split(",") if node.strip() and node.strip() != root_type_name
181177
]
182178

183179
# Support both new and old env var names for top_k
184-
top_k = int(os.getenv(
185-
"SEMANTIC_SEARCH__TOP_K",
186-
os.getenv("TOP_K", "200")
187-
))
180+
top_k = int(os.getenv("SEMANTIC_SEARCH__TOP_K", os.getenv("TOP_K", "200")))
188181

189182
return cls(
190183
# Root types
@@ -198,23 +191,12 @@ def from_environment(cls) -> "LIFSchemaConfig":
198191
mdr_api_auth_token=os.getenv("LIF_MDR_API_AUTH_TOKEN", "no_auth_token_set"),
199192
mdr_timeout_seconds=int(os.getenv("MDR_TIMEOUT_SECONDS", "30")),
200193
openapi_data_model_id=os.getenv("OPENAPI_DATA_MODEL_ID"),
201-
openapi_json_filename=os.getenv(
202-
"OPENAPI_JSON_FILENAME",
203-
"openapi_constrained_with_interactions.json"
204-
),
205-
use_openapi_from_file=os.getenv(
206-
"USE_OPENAPI_DATA_MODEL_FROM_FILE", "false"
207-
).lower() == "true",
194+
openapi_json_filename=os.getenv("OPENAPI_JSON_FILENAME", "openapi_constrained_with_interactions.json"),
195+
use_openapi_from_file=os.getenv("USE_OPENAPI_DATA_MODEL_FROM_FILE", "false").lower() == "true",
208196
# Semantic search
209-
semantic_search_model_name=os.getenv(
210-
"SEMANTIC_SEARCH__MODEL_NAME",
211-
"all-MiniLM-L6-v2"
212-
),
197+
semantic_search_model_name=os.getenv("SEMANTIC_SEARCH__MODEL_NAME", "all-MiniLM-L6-v2"),
213198
semantic_search_top_k=top_k,
214-
semantic_search_timeout=int(os.getenv(
215-
"SEMANTIC_SEARCH__GRAPHQL_TIMEOUT__READ",
216-
"300"
217-
)),
199+
semantic_search_timeout=int(os.getenv("SEMANTIC_SEARCH__GRAPHQL_TIMEOUT__READ", "300")),
218200
)
219201

220202
# Computed properties for convenience

0 commit comments

Comments
 (0)