evalstate HF Staff commited on
Commit
b137fbb
·
verified ·
1 Parent(s): 114bead

Deploy PR search API contributor surface fallback

Browse files
Files changed (1) hide show
  1. src/slop_farmer/app/pr_search_api.py +67 -13
src/slop_farmer/app/pr_search_api.py CHANGED
@@ -152,8 +152,15 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
152
  settings = request.app.state.settings
153
  repo_slug = _repo_slug(settings, owner, repo)
154
  status = get_pr_search_status(settings.index_path, repo=repo_slug)
155
- snapshot_dir = _status_snapshot_dir(status)
156
- return {**status, "surfaces": get_snapshot_surfaces(snapshot_dir)}
 
 
 
 
 
 
 
157
 
158
  @app.get("/v1/repos/{owner}/{repo}/pulls/{number}/similar")
159
  async def pr_similar(
@@ -240,7 +247,10 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
240
  ) -> dict[str, Any]:
241
  settings = request.app.state.settings
242
  repo_slug = _repo_slug(settings, owner, repo)
243
- return get_issue_cluster_status(_active_snapshot_dir(settings, repo_slug), variant=variant)
 
 
 
244
 
245
  @app.get("/v1/repos/{owner}/{repo}/issues/clusters")
246
  async def issue_clusters(
@@ -253,7 +263,7 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
253
  settings = request.app.state.settings
254
  repo_slug = _repo_slug(settings, owner, repo)
255
  return list_issue_clusters(
256
- _active_snapshot_dir(settings, repo_slug),
257
  limit=_limit(
258
  limit,
259
  default=settings.issue_list_limit_default,
@@ -273,7 +283,7 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
273
  settings = request.app.state.settings
274
  repo_slug = _repo_slug(settings, owner, repo)
275
  return get_issue_cluster(
276
- _active_snapshot_dir(settings, repo_slug),
277
  cluster_id=cluster_id,
278
  variant=variant,
279
  )
@@ -289,7 +299,7 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
289
  settings = request.app.state.settings
290
  repo_slug = _repo_slug(settings, owner, repo)
291
  return get_issue_clusters_for_pr(
292
- _active_snapshot_dir(settings, repo_slug),
293
  pr_number=number,
294
  variant=variant,
295
  )
@@ -306,7 +316,7 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
306
  settings = request.app.state.settings
307
  repo_slug = _repo_slug(settings, owner, repo)
308
  return check_issue_cluster_membership(
309
- _active_snapshot_dir(settings, repo_slug),
310
  pr_number=number,
311
  cluster_id=cluster_id,
312
  variant=variant,
@@ -323,7 +333,7 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
323
  settings = request.app.state.settings
324
  repo_slug = _repo_slug(settings, owner, repo)
325
  return list_issue_duplicate_prs(
326
- _active_snapshot_dir(settings, repo_slug),
327
  limit=_limit(
328
  limit,
329
  default=settings.issue_list_limit_default,
@@ -341,7 +351,10 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
341
  ) -> dict[str, Any]:
342
  settings = request.app.state.settings
343
  repo_slug = _repo_slug(settings, owner, repo)
344
- return get_issue_best(_active_snapshot_dir(settings, repo_slug), variant=variant)
 
 
 
345
 
346
  @app.get("/v1/repos/{owner}/{repo}/contributors/status")
347
  async def contributor_status(
@@ -351,7 +364,7 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
351
  ) -> dict[str, Any]:
352
  settings = request.app.state.settings
353
  repo_slug = _repo_slug(settings, owner, repo)
354
- return get_contributor_status(_active_snapshot_dir(settings, repo_slug))
355
 
356
  @app.get("/v1/repos/{owner}/{repo}/contributors")
357
  async def contributors(
@@ -363,7 +376,7 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
363
  settings = request.app.state.settings
364
  repo_slug = _repo_slug(settings, owner, repo)
365
  return list_contributors(
366
- _active_snapshot_dir(settings, repo_slug),
367
  limit=_limit(
368
  limit,
369
  default=settings.contributor_list_limit_default,
@@ -380,7 +393,10 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
380
  ) -> dict[str, Any]:
381
  settings = request.app.state.settings
382
  repo_slug = _repo_slug(settings, owner, repo)
383
- return get_contributor(_active_snapshot_dir(settings, repo_slug), author_login=login)
 
 
 
384
 
385
  @app.get("/v1/repos/{owner}/{repo}/contributors/{login}/risk")
386
  async def contributor_risk(
@@ -391,7 +407,10 @@ def create_app(settings: PrSearchApiSettings | None = None) -> FastAPI:
391
  ) -> dict[str, Any]:
392
  settings = request.app.state.settings
393
  repo_slug = _repo_slug(settings, owner, repo)
394
- return get_contributor_risk(_active_snapshot_dir(settings, repo_slug), author_login=login)
 
 
 
395
 
396
  return app
397
 
@@ -474,6 +493,23 @@ def _active_snapshot_dir(settings: PrSearchApiSettings, repo_slug: str) -> Path:
474
  return _status_snapshot_dir(get_pr_search_status(settings.index_path, repo=repo_slug))
475
 
476
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  def _status_snapshot_dir(status: dict[str, Any]) -> Path:
478
  snapshot_dir = status.get("snapshot_dir")
479
  if not snapshot_dir:
@@ -481,6 +517,24 @@ def _status_snapshot_dir(status: dict[str, Any]) -> Path:
481
  return Path(str(snapshot_dir))
482
 
483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  def _limit(value: int | None, *, default: int, maximum: int) -> int:
485
  limit = default if value is None else value
486
  if limit < 1:
 
152
  settings = request.app.state.settings
153
  repo_slug = _repo_slug(settings, owner, repo)
154
  status = get_pr_search_status(settings.index_path, repo=repo_slug)
155
+ issue_snapshot_dir = _surface_snapshot_dir(settings, repo_slug, surface="issues")
156
+ contributor_snapshot_dir = _surface_snapshot_dir(
157
+ settings, repo_slug, surface="contributors"
158
+ )
159
+ surface_payload = {
160
+ "issues": get_snapshot_surfaces(issue_snapshot_dir)["issues"],
161
+ "contributors": get_snapshot_surfaces(contributor_snapshot_dir)["contributors"],
162
+ }
163
+ return {**status, "surfaces": surface_payload}
164
 
165
  @app.get("/v1/repos/{owner}/{repo}/pulls/{number}/similar")
166
  async def pr_similar(
 
247
  ) -> dict[str, Any]:
248
  settings = request.app.state.settings
249
  repo_slug = _repo_slug(settings, owner, repo)
250
+ return get_issue_cluster_status(
251
+ _surface_snapshot_dir(settings, repo_slug, surface="issues"),
252
+ variant=variant,
253
+ )
254
 
255
  @app.get("/v1/repos/{owner}/{repo}/issues/clusters")
256
  async def issue_clusters(
 
263
  settings = request.app.state.settings
264
  repo_slug = _repo_slug(settings, owner, repo)
265
  return list_issue_clusters(
266
+ _surface_snapshot_dir(settings, repo_slug, surface="issues"),
267
  limit=_limit(
268
  limit,
269
  default=settings.issue_list_limit_default,
 
283
  settings = request.app.state.settings
284
  repo_slug = _repo_slug(settings, owner, repo)
285
  return get_issue_cluster(
286
+ _surface_snapshot_dir(settings, repo_slug, surface="issues"),
287
  cluster_id=cluster_id,
288
  variant=variant,
289
  )
 
299
  settings = request.app.state.settings
300
  repo_slug = _repo_slug(settings, owner, repo)
301
  return get_issue_clusters_for_pr(
302
+ _surface_snapshot_dir(settings, repo_slug, surface="issues"),
303
  pr_number=number,
304
  variant=variant,
305
  )
 
316
  settings = request.app.state.settings
317
  repo_slug = _repo_slug(settings, owner, repo)
318
  return check_issue_cluster_membership(
319
+ _surface_snapshot_dir(settings, repo_slug, surface="issues"),
320
  pr_number=number,
321
  cluster_id=cluster_id,
322
  variant=variant,
 
333
  settings = request.app.state.settings
334
  repo_slug = _repo_slug(settings, owner, repo)
335
  return list_issue_duplicate_prs(
336
+ _surface_snapshot_dir(settings, repo_slug, surface="issues"),
337
  limit=_limit(
338
  limit,
339
  default=settings.issue_list_limit_default,
 
351
  ) -> dict[str, Any]:
352
  settings = request.app.state.settings
353
  repo_slug = _repo_slug(settings, owner, repo)
354
+ return get_issue_best(
355
+ _surface_snapshot_dir(settings, repo_slug, surface="issues"),
356
+ variant=variant,
357
+ )
358
 
359
  @app.get("/v1/repos/{owner}/{repo}/contributors/status")
360
  async def contributor_status(
 
364
  ) -> dict[str, Any]:
365
  settings = request.app.state.settings
366
  repo_slug = _repo_slug(settings, owner, repo)
367
+ return get_contributor_status(_surface_snapshot_dir(settings, repo_slug, surface="contributors"))
368
 
369
  @app.get("/v1/repos/{owner}/{repo}/contributors")
370
  async def contributors(
 
376
  settings = request.app.state.settings
377
  repo_slug = _repo_slug(settings, owner, repo)
378
  return list_contributors(
379
+ _surface_snapshot_dir(settings, repo_slug, surface="contributors"),
380
  limit=_limit(
381
  limit,
382
  default=settings.contributor_list_limit_default,
 
393
  ) -> dict[str, Any]:
394
  settings = request.app.state.settings
395
  repo_slug = _repo_slug(settings, owner, repo)
396
+ return get_contributor(
397
+ _surface_snapshot_dir(settings, repo_slug, surface="contributors"),
398
+ author_login=login,
399
+ )
400
 
401
  @app.get("/v1/repos/{owner}/{repo}/contributors/{login}/risk")
402
  async def contributor_risk(
 
407
  ) -> dict[str, Any]:
408
  settings = request.app.state.settings
409
  repo_slug = _repo_slug(settings, owner, repo)
410
+ return get_contributor_risk(
411
+ _surface_snapshot_dir(settings, repo_slug, surface="contributors"),
412
+ author_login=login,
413
+ )
414
 
415
  return app
416
 
 
493
  return _status_snapshot_dir(get_pr_search_status(settings.index_path, repo=repo_slug))
494
 
495
 
496
+ def _surface_snapshot_dir(
497
+ settings: PrSearchApiSettings,
498
+ repo_slug: str,
499
+ *,
500
+ surface: Literal["issues", "contributors"],
501
+ ) -> Path:
502
+ active_snapshot_dir = _active_snapshot_dir(settings, repo_slug)
503
+ if _surface_available(active_snapshot_dir, surface=surface):
504
+ return active_snapshot_dir
505
+ materialized_snapshot_dir = _materialized_snapshot_dir(settings)
506
+ if materialized_snapshot_dir is not None and _surface_available(
507
+ materialized_snapshot_dir, surface=surface
508
+ ):
509
+ return materialized_snapshot_dir
510
+ return active_snapshot_dir
511
+
512
+
513
  def _status_snapshot_dir(status: dict[str, Any]) -> Path:
514
  snapshot_dir = status.get("snapshot_dir")
515
  if not snapshot_dir:
 
517
  return Path(str(snapshot_dir))
518
 
519
 
520
+ def _materialized_snapshot_dir(settings: PrSearchApiSettings) -> Path | None:
521
+ if settings.hf_repo_id is None:
522
+ return None
523
+ return settings.hf_materialize_dir or default_hf_materialize_dir(
524
+ settings.output_dir,
525
+ settings.hf_repo_id,
526
+ settings.hf_revision,
527
+ )
528
+
529
+
530
+ def _surface_available(snapshot_dir: Path, *, surface: Literal["issues", "contributors"]) -> bool:
531
+ if not snapshot_dir.exists():
532
+ return False
533
+ if surface == "issues":
534
+ return any(snapshot_dir.glob("analysis-report*.json"))
535
+ return (snapshot_dir / "new-contributors-report.json").exists()
536
+
537
+
538
  def _limit(value: int | None, *, default: int, maximum: int) -> int:
539
  limit = default if value is None else value
540
  if limit < 1: