From d3d95489372aec2b606d928e44249ec69942c16b Mon Sep 17 00:00:00 2001 From: gabrnavarro Date: Mon, 9 Mar 2026 16:33:54 +0100 Subject: [PATCH] fix: address issue #1432 --- pokemon_v2/api.py | 60 +++++++++++++++++++++++++++++++++++++++++++++ pokemon_v2/tests.py | 8 ++++++ pokemon_v2/urls.py | 1 + 3 files changed, 69 insertions(+) diff --git a/pokemon_v2/api.py b/pokemon_v2/api.py index 590721839..9c83026b9 100644 --- a/pokemon_v2/api.py +++ b/pokemon_v2/api.py @@ -1,4 +1,5 @@ import re +import subprocess from rest_framework import viewsets from rest_framework.response import Response from rest_framework.views import APIView @@ -1058,3 +1059,62 @@ def get(self, request, pokemon_id): ) return Response(encounters_list) + + +@extend_schema( + description="Returns metadata about the current deployed version of the API, including the git commit hash, deploy date, and tag (if any).", + tags=["utility"], + responses={ + 200: { + "type": "object", + "properties": { + "deploy_date": {"type": "string", "nullable": True}, + "hash": {"type": "string", "nullable": True}, + "tag": {"type": "string", "nullable": True}, + }, + } + }, +) +class APIMetaView(APIView): + def get(self, request): + try: + git_hash = ( + subprocess.check_output( + ["git", "rev-parse", "HEAD"], stderr=subprocess.DEVNULL + ) + .decode() + .strip() + ) + except Exception: + git_hash = None + + try: + deploy_date = ( + subprocess.check_output( + ["git", "log", "-1", "--format=%cI"], stderr=subprocess.DEVNULL + ) + .decode() + .strip() + ) + except Exception: + deploy_date = None + + try: + tag_output = ( + subprocess.check_output( + ["git", "tag", "--points-at", "HEAD"], stderr=subprocess.DEVNULL + ) + .decode() + .strip() + ) + tag = tag_output if tag_output else None + except Exception: + tag = None + + return Response( + { + "deploy_date": deploy_date, + "hash": git_hash, + "tag": tag, + } + ) diff --git a/pokemon_v2/tests.py b/pokemon_v2/tests.py index 6bed79fcd..654aae7d7 100644 --- a/pokemon_v2/tests.py +++ b/pokemon_v2/tests.py @@ -5855,3 +5855,11 @@ def test_case_insensitive_api(self): self.assertEqual(uppercase_response.status_code, status.HTTP_200_OK) self.assertEqual(lowercase_response.data, uppercase_response.data) + + # Meta Tests + def test_meta_api(self): + response = self.client.get("{}/meta".format(API_V2)) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn("deploy_date", response.data) + self.assertIn("hash", response.data) + self.assertIn("tag", response.data) diff --git a/pokemon_v2/urls.py b/pokemon_v2/urls.py index fdd268419..0a3fa3e51 100644 --- a/pokemon_v2/urls.py +++ b/pokemon_v2/urls.py @@ -76,4 +76,5 @@ PokemonEncounterView.as_view(), name="pokemon_encounters", ), + path("api/v2/meta", APIMetaView.as_view(), name="api_meta"), ]