# hetzner.py from __future__ import annotations import json from os import environ from dotenv import load_dotenv from hcloud import Client from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt load_dotenv() def get_client(): return Client(token=environ["HCLOUD_TOKEN"]) # ── router ────────────────────────────────────────────────────────────────── @csrf_exempt def do_hetzner(request, action): routes = { "get_server_types": get_server_types, } handler = routes.get(action) if handler is None: return JsonResponse({"error": f"Action '{action}' not found"}, status=404) try: body = json.loads(request.body) if request.body else {} except json.JSONDecodeError: return JsonResponse({"error": "Invalid JSON body"}, status=400) return handler(request, body) # ── handlers ───────────────────────────────────────────────────────────────── def get_server_types(request, body): client = get_client() server_types = client.server_types.get_all() def serialize_server_type(st): dm = st.data_model return { "id": dm.id, "name": dm.name, "description": dm.description, "category": dm.category, "cores": dm.cores, "memory": dm.memory, "disk": dm.disk, "storage_type": dm.storage_type, "cpu_type": dm.cpu_type, "architecture": dm.architecture, "deprecated": dm.deprecated, "prices": dm.prices, "locations": [ { "id": loc.location.id, "name": loc.location.name, "deprecation": { "announced": loc.deprecation.announced.isoformat(), "unavailable_after": loc.deprecation.unavailable_after.isoformat(), } if loc.deprecation else None, } for loc in dm.locations ], } result = [serialize_server_type(st) for st in server_types] return JsonResponse(result, safe=False)