110 lines
3.0 KiB
Python
110 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
API Vault Lookup — search Tony's Notion APIs database for a specific service key.
|
|
|
|
Usage:
|
|
python3 lookup.py <service-name>
|
|
python3 lookup.py all # dump everything
|
|
|
|
Environment:
|
|
MATON_API_KEY must be set (it's in ~/.bashrc)
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
MATON_API_KEY = os.environ.get("MATON_API_KEY")
|
|
DATASOURCE_ID = "c7c74f00-3e35-4040-af9a-5caac7f2ca95"
|
|
|
|
if not MATON_API_KEY:
|
|
print("ERROR: MATON_API_KEY not set in environment.")
|
|
print("Run: source ~/.bashrc or export it directly.")
|
|
sys.exit(1)
|
|
|
|
|
|
def query_database() -> list[dict]:
|
|
"""Query the full Notion APIs database and return all entries."""
|
|
cmd = [
|
|
"maton", "notion", "data-source", "query", DATASOURCE_ID,
|
|
]
|
|
env = {**os.environ, "MATON_API_KEY": MATON_API_KEY}
|
|
try:
|
|
result = subprocess.run(cmd, capture_output=True, text=True, env=env, timeout=30)
|
|
result.check_returncode()
|
|
data = json.loads(result.stdout)
|
|
except subprocess.TimeoutExpired:
|
|
print("ERROR: Maton query timed out.")
|
|
sys.exit(1)
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"ERROR: Maton CLI failed:\n{e.stderr}")
|
|
sys.exit(1)
|
|
except json.JSONDecodeError:
|
|
print(f"ERROR: Could not parse Maton output:\n{result.stdout[:500]}")
|
|
sys.exit(1)
|
|
|
|
results = data.get("results", data.get("page_or_data_source", {}).get("results", []))
|
|
entries = []
|
|
for r in results:
|
|
props = r.get("properties", {})
|
|
svc = _get_text(props, "Service", "title")
|
|
key = _get_text(props, "API", "rich_text")
|
|
notes = _get_text(props, "notes", "rich_text")
|
|
entries.append({"service": svc, "key": key, "notes": notes})
|
|
return entries
|
|
|
|
|
|
def _get_text(props: dict, field: str, field_type: str) -> str:
|
|
"""Extract plain text from a Notion property."""
|
|
if field not in props:
|
|
return ""
|
|
if field_type == "title":
|
|
texts = props[field].get("title", [])
|
|
else:
|
|
texts = props[field].get("rich_text", [])
|
|
if texts:
|
|
return texts[0].get("plain_text", "")
|
|
return ""
|
|
|
|
|
|
def main():
|
|
query = " ".join(sys.argv[1:]).lower().strip()
|
|
if not query:
|
|
print("Usage: python3 lookup.py <service-name>")
|
|
print(" python3 lookup.py all")
|
|
sys.exit(1)
|
|
|
|
entries = query_database()
|
|
|
|
if query == "all":
|
|
for e in entries:
|
|
_print_entry(e)
|
|
return
|
|
|
|
# Filter by case-insensitive partial match on service name
|
|
matches = [e for e in entries if query in e["service"].lower()]
|
|
|
|
if not matches:
|
|
print(f"No entries found matching '{query}'.")
|
|
print("Try: python3 lookup.py all (to see everything)")
|
|
return
|
|
|
|
for e in matches:
|
|
_print_entry(e)
|
|
|
|
|
|
def _print_entry(e: dict):
|
|
svc = e["service"] or "(unnamed)"
|
|
key = e["key"] or "(no key)"
|
|
notes = e["notes"]
|
|
print(f"── {svc}")
|
|
print(f" Key: {key}")
|
|
if notes:
|
|
print(f" Notes: {notes}")
|
|
print()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|