From e488f979c14bf0ff1a02c7a1bdf54f7cd2660985 Mon Sep 17 00:00:00 2001 From: Anson Date: Fri, 23 May 2025 12:02:31 -0600 Subject: [PATCH] Accidentally didn't push this stuff and deleted it last night lol --- .devcontainer/devcontainer.json | 33 +++++++++++++++------------ src/test/test_api.py | 40 +++++++++++++++++++++++++++++++++ src/two_chainz/__init__.py | 22 ++++++++++++++++++ 3 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 src/test/test_api.py create mode 100644 src/two_chainz/__init__.py diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 676d4f7..c5bad42 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,22 +1,27 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the // README at: https://github.com/devcontainers/templates/tree/main/src/debian { - "name": "Debian", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/base:bullseye", - "features": { - "ghcr.io/va-h/devcontainers-features/uv:1": {} - } + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/va-h/devcontainers-features/uv:1": {} + }, + "customizations": { + "vscode": { + "extensions": ["tamasfe.even-better-toml"] + } + } - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], - // Configure tool-specific properties. - // "customizations": {}, + // Configure tool-specific properties. + // "customizations": {}, - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" } diff --git a/src/test/test_api.py b/src/test/test_api.py new file mode 100644 index 0000000..4fca645 --- /dev/null +++ b/src/test/test_api.py @@ -0,0 +1,40 @@ +from fastapi.testclient import TestClient +from datetime import datetime +import time +import pytest +from unittest.mock import patch + +# Import your app here +from two_chainz import app + +client = TestClient(app) + +def test_api_endpoint(): + # Test the API endpoint returns 200 and correct structure + response = client.get("/api/") + assert response.status_code == 200 + + data = response.json() + assert "status" in data + assert data["status"] == "ok" + assert "timestamp" in data + assert "uptime_seconds" in data + + # Validate timestamp format (ISO format) + try: + datetime.fromisoformat(data["timestamp"]) + is_valid_timestamp = True + except ValueError: + is_valid_timestamp = False + + assert is_valid_timestamp + +@pytest.mark.parametrize("mocked_time,start_time,expected", [ + (100, 50, 50), # 100 - 50 = 50 seconds uptime + (200, 100, 100), # 200 - 100 = 100 seconds uptime +]) +def test_api_uptime_calculation(mocked_time, start_time, expected): + with patch('time.time', return_value=mocked_time): + with patch('two_chainz.start_time', start_time): + response = client.get("/api/") + assert response.json()["uptime_seconds"] == expected diff --git a/src/two_chainz/__init__.py b/src/two_chainz/__init__.py new file mode 100644 index 0000000..57b7b9d --- /dev/null +++ b/src/two_chainz/__init__.py @@ -0,0 +1,22 @@ +import time +from datetime import datetime +from fastapi import FastAPI +from fastapi.staticfiles import StaticFiles + + + + +app = FastAPI() +start_time = time.time() + +@app.get("/api/") +async def ping(): + return { + "status": "ok", + "timestamp": datetime.now().isoformat(), + "uptime_seconds": round(time.time() - start_time, 2), + } + + +# Mount static files +app.mount("/", StaticFiles(directory="website", html=True), name="static")