- Updated DREAMS.md and MEMORY.md with new entries - Added daily dreaming session corpus (2026-07-05 through 2026-07-18) - Added deep/light/REM dream analysis files for July 6-19 - Added Intune rollout outputs for KMCC client - Added Vault API integration scripts and documentation - Added container update playbook (update-containers.yml) - Added .gitignore for generated/noise files
90 lines
2.7 KiB
Python
90 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Generic Grist API wrapper using Vault for token retrieval.
|
|
Usage: python3 vault_grist_api.py <METHOD> <API_PATH> [JSON_PAYLOAD]
|
|
Example: python3 vault_grist_api.py GET /api/docs/wmBGUbgBveCdeY8fZ6T6eL/tables/Intune/records
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
import urllib.request
|
|
import urllib.error
|
|
|
|
VAULT_URL = "https://beavault.beawit.net:8200"
|
|
GRIST_URL = "https://grist.beawit.net"
|
|
|
|
def vault_auth():
|
|
"""Authenticate to Vault and return client token."""
|
|
auth_data = json.dumps({
|
|
"role_id": "75d2dcfb-9c65-7f60-59b4-eee8c7f8dc0e",
|
|
"secret_id": "6202b465-2f25-547c-ec07-f47cfc4dda3e"
|
|
}).encode()
|
|
|
|
req = urllib.request.Request(
|
|
f"{VAULT_URL}/v1/auth/approle/login",
|
|
data=auth_data,
|
|
headers={"Content-Type": "application/json"},
|
|
method="POST"
|
|
)
|
|
|
|
with urllib.request.urlopen(req) as resp:
|
|
data = json.loads(resp.read())
|
|
return data["auth"]["client_token"]
|
|
|
|
def get_grist_token(vault_token):
|
|
"""Retrieve Grist API token from Vault."""
|
|
req = urllib.request.Request(
|
|
f"{VAULT_URL}/v1/kv/data/api/integration/grist",
|
|
headers={"X-Vault-Token": vault_token}
|
|
)
|
|
|
|
with urllib.request.urlopen(req) as resp:
|
|
data = json.loads(resp.read())
|
|
return data["data"]["data"]["token"]
|
|
|
|
def grist_api_call(method, api_path, payload=None):
|
|
"""Make authenticated Grist API call."""
|
|
# Step 1: Vault auth
|
|
vault_token = vault_auth()
|
|
|
|
# Step 2: Get Grist token
|
|
grist_token = get_grist_token(vault_token)
|
|
|
|
# Step 3: Make API call
|
|
url = f"{GRIST_URL}{api_path}"
|
|
headers = {
|
|
"Authorization": f"Bearer {grist_token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
if method == "GET":
|
|
req = urllib.request.Request(url, headers=headers)
|
|
with urllib.request.urlopen(req) as resp:
|
|
return json.loads(resp.read())
|
|
elif method == "PATCH":
|
|
data = json.dumps(payload).encode() if payload else None
|
|
req = urllib.request.Request(url, data=data, headers=headers, method="PATCH")
|
|
with urllib.request.urlopen(req) as resp:
|
|
return resp.read().decode()
|
|
else:
|
|
raise ValueError(f"Unsupported method: {method}")
|
|
|
|
def main():
|
|
if len(sys.argv) < 3:
|
|
print("Usage: python3 vault_grist_api.py <METHOD> <API_PATH> [JSON_PAYLOAD_FILE]")
|
|
sys.exit(1)
|
|
|
|
method = sys.argv[1].upper()
|
|
api_path = sys.argv[2]
|
|
payload = None
|
|
|
|
if len(sys.argv) > 3:
|
|
with open(sys.argv[3]) as f:
|
|
payload = json.load(f)
|
|
|
|
result = grist_api_call(method, api_path, payload)
|
|
print(json.dumps(result, indent=2))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|