From 4b473d00d7bd9b2e6e023eadbb6f7e2a67fb4641 Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Sun, 13 Sep 2026 22:57:42 -0500 Subject: [PATCH 1/7] docs: link the staging health checks and the metrics dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The deployment section listed only production's health check page, so staging's — which exists and is already linked from CONTRIBUTING.md — was undiscoverable from the README. It is now beside production's. Adds the Grafana dashboard covering both environments, built on the counters `/metrics` exposes, and links it back to that section so a reader can see where the numbers come from. The existing status badges are labelled **Production**, since four unlabelled badges gave no indication of which environment or which check each one was. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 690016a..5c0afce 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,16 @@ returns the user's profile information. No personal data is stored. ## PESUAuth LIVE Deployment - You can access the PESUAuth API endpoints [here](https://pesu-auth.onrender.com/). -- You can view the health status of the API on the [PESUAuth Health Dashboard](https://xzlk85cp.status.cron-job.org/). +- You can view the health status of the API on the health check pages for + [production](https://xzlk85cp.status.cron-job.org) and [staging](https://6ns95sgb.status.cron-job.org). +- You can view detailed metrics and KPIs for both environments on the + [PESUAuth metrics dashboard](https://loyalplateau1250.grafana.net/public-dashboards/bd1df85e9420490f88978906b0d9fbdf), + built from the counters that [`/metrics`](#metrics) exposes. #### API Status +**Production** + ![Cron job status](https://api.cron-job.org/jobs/4424640/69701a6f8df1d307/status-7.svg)\ ![Cron job status](https://api.cron-job.org/jobs/6338038/9feb0f217be714ec/status-7.svg)\ ![Cron job status](https://api.cron-job.org/jobs/5672615/1d744f1dc18fb505/status-7.svg)\ From 698eb578c2b026a6f47f20aa3c41a0498dde3e6b Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Sun, 13 Sep 2026 22:57:42 -0500 Subject: [PATCH 2/7] chore: bump version to 4.5.0 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 01a8f69..ff63373 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "pesu-auth" -version = "4.4.0" +version = "4.5.0" description = "A simple API to authenticate PESU credentials using PESU Academy." readme = "README.md" requires-python = ">=3.14" diff --git a/uv.lock b/uv.lock index 8c62995..e33e842 100644 --- a/uv.lock +++ b/uv.lock @@ -630,7 +630,7 @@ wheels = [ [[package]] name = "pesu-auth" -version = "4.4.0" +version = "4.5.0" source = { editable = "." } dependencies = [ { name = "fastapi" }, From aa4198b33ae93e61e6d9ae8533e78d5dd624c26d Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Sun, 13 Sep 2026 23:05:06 -0500 Subject: [PATCH 3/7] docs: correct the deployment region to Singapore Both environments run in Singapore, not the United States. The claim predates this and was simply wrong; it also understated the service, since Singapore is a great deal closer than the US both to the users and to PESU Academy itself, which every authentication waits on. Reworded to cover both environments rather than "the live version", now that the README links staging as well. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c0afce..e346c69 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ returns the user's profile information. No personal data is stored. > All timestamps are in UTC. > [!WARNING] -> The live version is hosted on a free tier server located in the United States. As a result, you *might* experience higher latencies and slower response times, compared to running the API locally or on a server closer to your location. +> Both environments are hosted on free tier servers located in Singapore. As a result, you *might* experience higher latencies and slower response times, compared to running the API locally or on a server closer to your location. ## How to run PESUAuth locally From 53a8c6d03382423c9b8faef0f7c1db43714afb5e Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Sun, 13 Sep 2026 23:10:35 -0500 Subject: [PATCH 4/7] docs: put the status badges in a table and add a dashboard badge Four unlabelled badges in a row said nothing about which check each one was, and left no room for a second environment. A table names every check and gives staging a column to drop into. The metrics dashboard gets a badge of its own beneath it, so all the monitoring surfaces are in one place rather than split between prose and images. The staging column is not filled in. A cron-job.org badge URL carries a per-job token that exists only inside the owning account: the status page is a client-side app that returns the same HTML for every path, and its API (`X-API-Method: GetPublicStatusPage`) returns the four monitor titles with no identifiers attached. The URLs have to be copied out of the console. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e346c69..77b08e0 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,16 @@ returns the user's profile information. No personal data is stored. #### API Status -**Production** +Seven days of history per check, from [cron-job.org](https://cron-job.org). -![Cron job status](https://api.cron-job.org/jobs/4424640/69701a6f8df1d307/status-7.svg)\ -![Cron job status](https://api.cron-job.org/jobs/6338038/9feb0f217be714ec/status-7.svg)\ -![Cron job status](https://api.cron-job.org/jobs/5672615/1d744f1dc18fb505/status-7.svg)\ -![Cron job status](https://api.cron-job.org/jobs/4424663/d5a30351867acec9/status-7.svg) +| **Check** | **Production** | +| -------------------------------- | --------------------------------------------------------------------------------------------------- | +| Docs | ![Docs](https://api.cron-job.org/jobs/4424640/69701a6f8df1d307/status-7.svg) | +| Health | ![Health](https://api.cron-job.org/jobs/6338038/9feb0f217be714ec/status-7.svg) | +| Authentication | ![Authentication](https://api.cron-job.org/jobs/5672615/1d744f1dc18fb505/status-7.svg) | +| Authentication with Profile Data | ![Authentication with profile](https://api.cron-job.org/jobs/4424663/d5a30351867acec9/status-7.svg) | + +[![Grafana](https://img.shields.io/badge/Grafana-metrics%20%26%20KPIs-F46800?logo=grafana&logoColor=white)](https://loyalplateau1250.grafana.net/public-dashboards/bd1df85e9420490f88978906b0d9fbdf) > [!NOTE] > All timestamps are in UTC. From 10b0107a5d11f04d5cbb5aa7e33295f46666fe1b Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Mon, 14 Sep 2026 20:02:15 -0500 Subject: [PATCH 5/7] docs: one status table with an environment column Replaces the two-column layout with rows keyed by environment and check, and moves the metrics dashboard into the table as a row of its own so every monitoring surface is in one place. Drops the "seven days of history" line. Staging's four cells link to its status page rather than carrying badges, and they are identical because there is nothing yet to tell them apart: a cron-job.org badge URL carries a per-job token that only exists inside the owning account. They become real badges as soon as those four URLs are copied out of the console. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 77b08e0..4eae3a5 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,17 @@ returns the user's profile information. No personal data is stored. #### API Status -Seven days of history per check, from [cron-job.org](https://cron-job.org). - -| **Check** | **Production** | -| -------------------------------- | --------------------------------------------------------------------------------------------------- | -| Docs | ![Docs](https://api.cron-job.org/jobs/4424640/69701a6f8df1d307/status-7.svg) | -| Health | ![Health](https://api.cron-job.org/jobs/6338038/9feb0f217be714ec/status-7.svg) | -| Authentication | ![Authentication](https://api.cron-job.org/jobs/5672615/1d744f1dc18fb505/status-7.svg) | -| Authentication with Profile Data | ![Authentication with profile](https://api.cron-job.org/jobs/4424663/d5a30351867acec9/status-7.svg) | - -[![Grafana](https://img.shields.io/badge/Grafana-metrics%20%26%20KPIs-F46800?logo=grafana&logoColor=white)](https://loyalplateau1250.grafana.net/public-dashboards/bd1df85e9420490f88978906b0d9fbdf) +| **Environment** | **Check** | **Status** | +| --------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Production | Docs | ![Docs](https://api.cron-job.org/jobs/4424640/69701a6f8df1d307/status-7.svg) | +| Production | Health | ![Health](https://api.cron-job.org/jobs/6338038/9feb0f217be714ec/status-7.svg) | +| Production | Authentication | ![Authentication](https://api.cron-job.org/jobs/5672615/1d744f1dc18fb505/status-7.svg) | +| Production | Authentication with Profile Data | ![Authentication with profile](https://api.cron-job.org/jobs/4424663/d5a30351867acec9/status-7.svg) | +| Staging | Docs | [Status page](https://6ns95sgb.status.cron-job.org) | +| Staging | Health | [Status page](https://6ns95sgb.status.cron-job.org) | +| Staging | Authentication | [Status page](https://6ns95sgb.status.cron-job.org) | +| Staging | Authentication with Profile Data | [Status page](https://6ns95sgb.status.cron-job.org) | +| Both | Detailed metrics and KPIs | [![Grafana](https://img.shields.io/badge/Grafana-metrics%20%26%20KPIs-F46800?logo=grafana&logoColor=white)](https://loyalplateau1250.grafana.net/public-dashboards/bd1df85e9420490f88978906b0d9fbdf) | > [!NOTE] > All timestamps are in UTC. From e9b7064740391605906986a646046528613b424c Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Mon, 14 Sep 2026 20:06:35 -0500 Subject: [PATCH 6/7] docs: add the staging status badges Fills the four staging cells, so the table now carries all eight checks plus the dashboard. Each badge was fetched and matched by the job name embedded in its own SVG title rather than by the order it arrived in, which is how "Simple authentication" and "Profile data" were placed against the right rows. All eight return 200, and production's existing four were re-checked the same way. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4eae3a5..851ccdc 100644 --- a/README.md +++ b/README.md @@ -31,10 +31,10 @@ returns the user's profile information. No personal data is stored. | Production | Health | ![Health](https://api.cron-job.org/jobs/6338038/9feb0f217be714ec/status-7.svg) | | Production | Authentication | ![Authentication](https://api.cron-job.org/jobs/5672615/1d744f1dc18fb505/status-7.svg) | | Production | Authentication with Profile Data | ![Authentication with profile](https://api.cron-job.org/jobs/4424663/d5a30351867acec9/status-7.svg) | -| Staging | Docs | [Status page](https://6ns95sgb.status.cron-job.org) | -| Staging | Health | [Status page](https://6ns95sgb.status.cron-job.org) | -| Staging | Authentication | [Status page](https://6ns95sgb.status.cron-job.org) | -| Staging | Authentication with Profile Data | [Status page](https://6ns95sgb.status.cron-job.org) | +| Staging | Docs | ![Docs](https://api.cron-job.org/jobs/6382167/bc84078c3b85999c/status-7.svg) | +| Staging | Health | ![Health](https://api.cron-job.org/jobs/6382168/e38759ed59c0d9c1/status-7.svg) | +| Staging | Authentication | ![Authentication](https://api.cron-job.org/jobs/6382175/226ee5764400bf01/status-7.svg) | +| Staging | Authentication with Profile Data | ![Authentication with profile](https://api.cron-job.org/jobs/6382173/5cff341ab10ab962/status-7.svg) | | Both | Detailed metrics and KPIs | [![Grafana](https://img.shields.io/badge/Grafana-metrics%20%26%20KPIs-F46800?logo=grafana&logoColor=white)](https://loyalplateau1250.grafana.net/public-dashboards/bd1df85e9420490f88978906b0d9fbdf) | > [!NOTE] From 0a10caf89ecb3de7b4d958ffb940e30047f6b7c9 Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Mon, 14 Sep 2026 20:12:07 -0500 Subject: [PATCH 7/7] docs: document every endpoint's status codes, and fix two errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found auditing the README against the published schema rather than reading it. **Only `/metrics` documented its response codes.** `/authenticate` can answer with six — 200, 400, 401, 422, 500 and 502 — and the README named none of them, so a caller integrating against it had no way to learn that a `502` means PESU Academy is unreachable or that a `422` means their profile page changed shape. It now has a table. `/health` and `/readme` get a sentence each instead, since a table listing a success and the universal catch-all `500` would be padding. **Both example timestamps were malformed.** They showed `2024-07-28 22:30:10.103368+05:30` with a space, but the API serialises with `datetime.isoformat()`, which always separates with a `T`. A reader parsing against the documented shape would have failed on real responses. The OpenAPI examples had it right, so the two disagreed. **The cURL example's response heading was a level too shallow**, making it a sibling of `#### cURL` rather than part of it, so it read as a section of its own in the outline while Python's matching block was nested correctly. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 851ccdc..437e4db 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ returns the user's profile information. No personal data is stored. | Staging | Health | ![Health](https://api.cron-job.org/jobs/6382168/e38759ed59c0d9c1/status-7.svg) | | Staging | Authentication | ![Authentication](https://api.cron-job.org/jobs/6382175/226ee5764400bf01/status-7.svg) | | Staging | Authentication with Profile Data | ![Authentication with profile](https://api.cron-job.org/jobs/6382173/5cff341ab10ab962/status-7.svg) | -| Both | Detailed metrics and KPIs | [![Grafana](https://img.shields.io/badge/Grafana-metrics%20%26%20KPIs-F46800?logo=grafana&logoColor=white)](https://loyalplateau1250.grafana.net/public-dashboards/bd1df85e9420490f88978906b0d9fbdf) | +| | Detailed metrics and KPIs | [![Grafana](https://img.shields.io/badge/Grafana-metrics%20%26%20KPIs-F46800?logo=grafana&logoColor=white)](https://loyalplateau1250.grafana.net/public-dashboards/bd1df85e9420490f88978906b0d9fbdf) | > [!NOTE] > All timestamps are in UTC. @@ -130,6 +130,19 @@ object, with the user's profile information if requested. | `profile` | Yes | `boolean` | `False` | Whether to fetch profile information | | `fields` | Yes | `list[str]` | `None` | Which fields to fetch from the profile information. If not provided, all fields will be fetched | +#### Responses + +| **Code** | **When** | +| -------- | --------------------------------------------------------------------------------- | +| `200` | The credentials are valid. `profile` is included if it was requested | +| `400` | The request body failed validation — a missing field, or an unknown profile field | +| `401` | Invalid username or password, or the user does not exist | +| `422` | PESU Academy's profile page could not be parsed, which means their page changed | +| `500` | An unexpected failure, rendered by the catch-all handler | +| `502` | PESU Academy could not be reached, or did not answer with what was expected | + +Every non-`200` carries the same `{status, message, timestamp}` body, with `status` set to `false`. + #### Response Object On authentication, it returns the following parameters in a JSON object. If the authentication was successful and @@ -164,6 +177,8 @@ If the authentication fails, this field will not be present in the response. ### `/health` +Answers `200` whenever the process is serving; a `500` would come from the catch-all handler, as on any other endpoint. + This endpoint can be used to check the health of the API. It's useful for monitoring and uptime checks. This endpoint does not take any request parameters. @@ -620,7 +635,7 @@ scrape_configs: ### `/readme` -This endpoint redirects to the project's official GitHub repository. This endpoint does not take any request parameters. +This endpoint redirects to the project's official GitHub repository with a `308`, and takes no request parameters. A `500` would come from the catch-all handler, as on any other endpoint. ### Integrating your application with the PESUAuth API @@ -662,7 +677,7 @@ print(response.json()) "campus": "RR" }, "message": "Login successful.", - "timestamp": "2024-07-28 22:30:10.103368+05:30" + "timestamp": "2024-07-28T22:30:10.103368+05:30" } ``` @@ -679,13 +694,13 @@ curl -X POST http://localhost:5000/authenticate \ }' ``` -#### Response +##### Response ```json { "status": true, "message": "Login successful.", - "timestamp": "2024-07-28 22:30:10.103368+05:30" + "timestamp": "2024-07-28T22:30:10.103368+05:30" } ```