Corin1998 commited on
Commit
7bf301a
·
verified ·
1 Parent(s): 94e3048

Create navitia.py

Browse files
Files changed (1) hide show
  1. services/providers/navitia.py +70 -0
services/providers/navitia.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ from typing import Optional, Dict, Any
3
+ import os
4
+ import requests
5
+ from datetime import datetime
6
+
7
+ UA = {"User-Agent": "HF-Space-Trip-Planner/1.0 (+navitia)"}
8
+
9
+ def _navitia_token() -> Optional[str]:
10
+ # NavitiaのAPIキーを .env / Secrets に設定してください(例: NAVITIA_TOKEN=xxxxxxxx)
11
+ return os.getenv("NAVITIA_TOKEN")
12
+
13
+ def _fmt_datetime(when_iso: str) -> str:
14
+ """
15
+ 入力: "YYYY-MM-DDTHH:MM:SS" or "YYYY-MM-DD"
16
+ 出力: "YYYYMMDDTHHMMSS"(Navitia形式)
17
+ """
18
+ try:
19
+ if "T" in when_iso:
20
+ dt = datetime.fromisoformat(when_iso)
21
+ else:
22
+ dt = datetime.fromisoformat(when_iso + "T09:00:00")
23
+ return dt.strftime("%Y%m%dT%H%M%S")
24
+ except Exception:
25
+ return datetime.utcnow().strftime("%Y%m%dT%H%M%S")
26
+
27
+ def get_journey(
28
+ lat_from: float,
29
+ lon_from: float,
30
+ lat_to: float,
31
+ lon_to: float,
32
+ when_iso: str,
33
+ ) -> Optional[Dict[str, Any]]:
34
+ """
35
+ Navitiaで経路を取得(トークンが無い/失敗時は None を返すフェイルセーフ)。
36
+ 戻り:
37
+ {"duration_s": int, "fare": {...}} など(存在するもののみ)
38
+ 注意:
39
+ Navitiaは地域カバレッジに制約があります。対象外エリアではNoneになります。
40
+ """
41
+ token = _navitia_token()
42
+ if not token:
43
+ return None
44
+
45
+ url = "https://api.navitia.io/v1/journeys"
46
+ params = {
47
+ "from": f"{lon_from};{lat_from}",
48
+ "to": f"{lon_to};{lat_to}",
49
+ "datetime": _fmt_datetime(when_iso),
50
+ "count": 1,
51
+ }
52
+
53
+ try:
54
+ r = requests.get(url, params=params, headers=UA, auth=(token, ""), timeout=20)
55
+ if r.status_code >= 400:
56
+ return None
57
+ j = r.json()
58
+ js = j.get("journeys") or []
59
+ if not js:
60
+ return None
61
+ best = js[0]
62
+ out: Dict[str, Any] = {}
63
+ if "duration" in best:
64
+ out["duration_s"] = int(best["duration"])
65
+ fare = (best.get("fare") or {}).get("total") or best.get("fare")
66
+ if fare:
67
+ out["fare"] = fare
68
+ return out or None
69
+ except Exception:
70
+ return None