import re import requests import gradio as gr BASE_URL = "https://laws.e-gov.go.jp/api/2/laws" LAW_IDS = { "民法": "429AC0000000089", "会社法": "429AC0000000086", "商法": "429AC0000000048", "刑法": "429AC0000000045", "不動産登記法": "429AC0000000092", } KANJI = "零一二三四五六七八九十百" def int_to_kanji(num): if num <= 10: return KANJI[num] elif num < 20: return "十" + (KANJI[num-10] if num % 10 else "") elif num < 100: tens, ones = divmod(num, 10) return (KANJI[tens] if tens > 1 else "") + "十" + (KANJI[ones] if ones else "") else: return str(num) def parse_query(q): q = q.strip().replace(" ", "") q = re.sub(r"(?<=\d)上$", "条", q) m = re.match(r"(?P[^0-9\s条]+)\s*(第?(?P\d+)条?)", q) if not m: raise ValueError("「民法3条」「会社法10条」みたいに入力して。") return m.group("law"), int(m.group("num")) def flatten_text(obj): """JSON全体から文字列だけを抽出""" if isinstance(obj, str): return obj elif isinstance(obj, dict): return "".join(flatten_text(v) for v in obj.values()) elif isinstance(obj, list): return "".join(flatten_text(i) for i in obj) return "" def get_article(law_id, article_label): url = f"{BASE_URL}?lawId={law_id}" r = requests.get(url, timeout=30) r.raise_for_status() data = r.json() text = flatten_text(data) idx = text.find(article_label) if idx == -1: return f"{article_label} が見つかりません。" snippet = text[idx : idx + 500] snippet = re.split(r"第[一二三四五六七八九十百]+条", snippet)[0] return snippet.strip() def run(q): try: law, num = parse_query(q) law_id = LAW_IDS.get(law) if not law_id: return f"法令が登録されていません:「{law}」" target = f"第{int_to_kanji(num)}条" text = get_article(law_id, target) return f"【{law}】{target}\n\n{text}" except Exception as e: return f"❌ エラー: {e}" demo = gr.Interface( fn=run, inputs=gr.Textbox(label="例)民法3条 / 会社法10条 / 不動産登記法47条"), outputs=gr.Textbox(label="結果", lines=20), title="e-Gov 法令API v2|条文検索", description="法令名+条番号を入力して該当条文を取得します(安定版API・全文走査)" ) demo.launch()