chenchaoyun commited on
Commit
8f26f9a
·
1 Parent(s): 9a7c81e

feat: 增加 app_analyze 接口异步记录设备信息功能

Browse files
Files changed (2) hide show
  1. api_routes.py +30 -0
  2. database.py +79 -0
api_routes.py CHANGED
@@ -53,6 +53,7 @@ from database import (
53
  fetch_records_by_paths,
54
  infer_category_from_filename,
55
  fetch_today_category_counts,
 
56
  )
57
 
58
  SERVER_HOSTNAME = os.environ.get("HOSTNAME", "")
@@ -1574,6 +1575,35 @@ async def app_analyze_face(
1574
  """
1575
  App专用人脸分析接口,参数与原 /analyze 保持完全一致并透传。
1576
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1577
  return await analyze_face(
1578
  request=request,
1579
  file=file,
 
53
  fetch_records_by_paths,
54
  infer_category_from_filename,
55
  fetch_today_category_counts,
56
+ upsert_device_record,
57
  )
58
 
59
  SERVER_HOSTNAME = os.environ.get("HOSTNAME", "")
 
1575
  """
1576
  App专用人脸分析接口,参数与原 /analyze 保持完全一致并透传。
1577
  """
1578
+ # 异步记录设备信息
1579
+ device_id = request.headers.get("x-device-id")
1580
+ if device_id:
1581
+ try:
1582
+ # 提取公共头
1583
+ ts_str = request.headers.get("x-timestamp")
1584
+ ts_ms = int(ts_str) if ts_str and ts_str.isdigit() else None
1585
+
1586
+ device_info = {
1587
+ "device_id": device_id,
1588
+ "device_type": request.headers.get("x-device-type"),
1589
+ "device_model": request.headers.get("x-device-model"),
1590
+ "os_version": request.headers.get("x-os-version"),
1591
+ "app_id": request.headers.get("x-app-id"),
1592
+ "app_version": request.headers.get("x-app-version"),
1593
+ "bundle_id": request.headers.get("x-bundle-id"),
1594
+ "timezone": request.headers.get("x-timezone"),
1595
+ "region": request.headers.get("x-region"),
1596
+ "language": request.headers.get("Accept-Language"),
1597
+ "request_id": request.headers.get("x-request-id"),
1598
+ "timestamp_ms": ts_ms,
1599
+ "nonce": request.headers.get("x-nonce"),
1600
+ "nickname": nickname
1601
+ }
1602
+ # 创建异步任务,不阻塞当前请求
1603
+ asyncio.create_task(upsert_device_record(**device_info))
1604
+ except Exception as e:
1605
+ logger.warning(f"Failed to record device info for {device_id}: {e}")
1606
+
1607
  return await analyze_face(
1608
  request=request,
1609
  file=file,
database.py CHANGED
@@ -334,6 +334,85 @@ def infer_category_from_filename(filename: str, default: str = "other") -> str:
334
 
335
  from config import HOSTNAME
336
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  async def record_image_creation(
338
  *,
339
  file_path: str,
 
334
 
335
  from config import HOSTNAME
336
 
337
+ async def upsert_device_record(
338
+ *,
339
+ device_id: str,
340
+ device_type: Optional[str] = None,
341
+ device_model: Optional[str] = None,
342
+ os_version: Optional[str] = None,
343
+ app_id: Optional[str] = None,
344
+ app_version: Optional[str] = None,
345
+ bundle_id: Optional[str] = None,
346
+ timezone: Optional[str] = None,
347
+ region: Optional[str] = None,
348
+ language: Optional[str] = None,
349
+ request_id: Optional[str] = None,
350
+ timestamp_ms: Optional[int] = None,
351
+ nonce: Optional[str] = None,
352
+ nickname: Optional[str] = None,
353
+ ) -> None:
354
+ """写入或更新设备记录"""
355
+ query = """
356
+ INSERT INTO tpl_app_user_devices (
357
+ device_id,
358
+ device_type,
359
+ device_model,
360
+ os_version,
361
+ app_id,
362
+ app_version,
363
+ bundle_id,
364
+ timezone,
365
+ region,
366
+ language,
367
+ request_id,
368
+ timestamp_ms,
369
+ nonce,
370
+ nickname
371
+ ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
372
+ ON DUPLICATE KEY UPDATE
373
+ device_type = VALUES(device_type),
374
+ device_model = VALUES(device_model),
375
+ os_version = VALUES(os_version),
376
+ app_id = VALUES(app_id),
377
+ app_version = VALUES(app_version),
378
+ bundle_id = VALUES(bundle_id),
379
+ timezone = VALUES(timezone),
380
+ region = VALUES(region),
381
+ language = VALUES(language),
382
+ request_id = VALUES(request_id),
383
+ timestamp_ms = VALUES(timestamp_ms),
384
+ nonce = VALUES(nonce),
385
+ nickname = VALUES(nickname),
386
+ updated_at = CURRENT_TIMESTAMP
387
+ """
388
+ import time
389
+ start_time = time.perf_counter()
390
+ try:
391
+ await execute(
392
+ query,
393
+ (
394
+ device_id,
395
+ device_type,
396
+ device_model,
397
+ os_version,
398
+ app_id,
399
+ app_version,
400
+ bundle_id,
401
+ timezone,
402
+ region,
403
+ language,
404
+ request_id,
405
+ timestamp_ms,
406
+ nonce,
407
+ nickname,
408
+ ),
409
+ )
410
+ duration = (time.perf_counter() - start_time) * 1000
411
+ logger.info(f"Device record updated for {device_id}, cost: {duration:.2f}ms")
412
+ except Exception as exc:
413
+ logger.warning(f"写入设备记录失败: {exc}")
414
+
415
+
416
  async def record_image_creation(
417
  *,
418
  file_path: str,