Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [1.3.0] - 2026-05-27

### Added

- New `mlstdb ping` subcommand for probing a single API endpoint and displaying the HTTP status and response body. Authentication is attempted automatically in priority order: personal API key, OAuth session token, unauthenticated fallback (with a warning). The `--no-auth` flag skips all authentication, matching the behaviour of `mlstdb update --no-auth`.
- New `ping_url()` function in `mlstdb.core.auth` encapsulates the auth-priority logic shared by the ping command.

## [1.2.0] - 2026-05-22

### Added
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ mlst --blastdb blast/mlst.fa --datadir pubmlst your_assembly.fasta

That's it. For advanced scheme exploration, custom filtering, and detailed option reference, see the [full documentation](https://MDU-PHL.github.io/mlstdb).

## Probing API endpoints

To verify that a specific API endpoint is reachable and your credentials are working, use `mlstdb ping`:

```sh
mlstdb ping https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes/67/profiles_csv --db pubmlst
```

See the [ping documentation](https://MDU-PHL.github.io/mlstdb/usage/ping/) for the full reference.

## Removing contaminated STs or alleles

Discovered a dodgy sequence type or allele in your local database? You can remove it without re-downloading the whole scheme:
Expand Down
21 changes: 20 additions & 1 deletion docs/usage/overview.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Usage Overview

`mlstdb` has three commands. Most users only need the first two.
`mlstdb` has four commands. Most users only need the first two.

---

Expand All @@ -22,6 +22,9 @@
├──────────────────────────────────────────────────────────────┤
│ OPTIONAL │
│ │
│ mlstdb ping ──► Probe a single API endpoint │
│ to verify credentials or explore data │
│ │
│ mlstdb purge ──► Remove contaminated STs or alleles │
│ │ from your local database │
│ ▼ │
Expand Down Expand Up @@ -75,6 +78,22 @@ By default, it uses the built-in curated list of ~170 MLST schemes from both Pub

---

### `mlstdb ping` — Probe an API endpoint

Sends a single GET request to any BIGSdb API endpoint and displays the HTTP status code and response body. Useful for checking that credentials are working or inspecting raw API data.

```sh
# Probe a public endpoint without authentication
mlstdb ping https://rest.pubmlst.org/db --no-auth

# Probe an authenticated endpoint
mlstdb ping https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes/67/profiles_csv --db pubmlst
```

[Full ping reference →](ping.md)

---

### `mlstdb purge` — Remove contaminated entries

If a sequence type or allele in your local database turns out to be erroneous or contaminated, `mlstdb purge` lets you remove it without re-downloading the entire scheme.
Expand Down
153 changes: 153 additions & 0 deletions docs/usage/ping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Ping

The `ping` command sends a single GET request to an API endpoint and displays the HTTP status code and response body. It is useful for verifying that your credentials are working or for exploring raw API responses.

## Basic Usage

```sh
mlstdb ping <URL> [--db pubmlst|pasteur] [--no-auth] [--verbose]
```

## Options

| Option | Description |
|--------|-------------|
| `URL` | The API endpoint to probe (required). |
| `--db`, `-d` | Database whose stored credentials should be used: `pubmlst` or `pasteur`. If omitted and authentication is needed, you will be prompted to choose. |
| `--no-auth` | Skip all authentication and send an unauthenticated request. |
| `--verbose`, `-v` | Print the auth mode, full URL, and status code before the response body. |
| `-h`, `--help` | Show help message. |

## Authentication Priority

Unless `--no-auth` is set, `ping` attempts authentication in the following order:

1. **API key** stored by `mlstdb connect --api-key` (sent as an `X-API-Key` header).
2. **OAuth session token** stored by `mlstdb connect`.
3. **Unauthenticated fallback** if no credentials are found. A warning is printed before sending the request.

This mirrors the same authentication logic used by `mlstdb update`.

## Examples

### Probe a public endpoint without authentication

```sh
mlstdb ping https://rest.pubmlst.org/db --no-auth
```

Expected output:

```
HTTP 200 https://rest.pubmlst.org/db

[
{
"description": "Achromobacter spp.",
"databases": [
{
"name": "pubmlst_achromobacter_isolates",
"description": "Achromobacter spp. isolates",
"href": "https://rest.pubmlst.org/db/pubmlst_achromobacter_isolates"
},
{
"name": "pubmlst_achromobacter_seqdef",
"href": "https://rest.pubmlst.org/db/pubmlst_achromobacter_seqdef",
"description": "Achromobacter spp. sequence/profile definitions"
}
],
"name": "achromobacter"
},
...
]
```

### Probe an authenticated endpoint using a stored API key

```sh
mlstdb ping https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes/1/profiles_csv --db pubmlst
```

Expected output (first few lines of a profile CSV):

```
HTTP 200 https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes/1/profiles_csv

ST abcZ adk aroE fumC gdh pdhC pgm clonal_complex
1 1 3 1 1 1 1 3 ST-1 complex
2 1 3 4 7 1 1 3 ST-1 complex
3 1 3 1 1 1 23 13 ST-1 complex
...
```

### Probe a Pasteur endpoint with verbose output

```sh
mlstdb ping https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/schemes/3 --db pasteur --verbose
```

Expected output:

```
Auth mode: api-key
Requesting: https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/schemes/3
Status: 200

HTTP 200 https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/schemes/3

{
"profiles": "https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/schemes/3/profiles",
"message": "Please note that you are currently restricted to accessing data that was submitted on or prior to 2024-12-31. Please authenticate to access the full dataset.",
"description": "MLST",
"has_primary_key_field": true,
"loci": [
"https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/loci/adk",
"https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/loci/fumC",
"https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/loci/glyA",
"https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/loci/tyrB",
"https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/loci/icd",
"https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/loci/pepA",
"https://bigsdb.pasteur.fr/api/db/pubmlst_bordetella_seqdef/loci/pgm"
],
"records": 118,
...
}
```

### Unauthenticated fallback when no credentials are stored

If no credentials are stored for the specified database, `ping` falls back to an unauthenticated request and prints a warning:

```sh
mlstdb ping https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes --db pubmlst
```

```
Warning: No credentials found for 'pubmlst', trying unauthenticated...

HTTP 200 https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes

{
"schemes": [
{
"description": "MLST",
"scheme": "https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes/1"
},
...
],
}
```

## Tips

If the server returns a 401 or 403, `ping` prints a short hint:

```
Hint: run 'mlstdb connect --db <db>' to configure credentials, or use --no-auth for unauthenticated access.
```

Use `ping` with `| less` to page through long profile CSV responses:

```sh
mlstdb ping https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes/67/profiles_csv --db pubmlst | less
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ nav:
- Overview: usage/overview.md
- Connect: usage/connect.md
- Update: usage/update.md
- Ping: usage/ping.md
- Purge: usage/purge.md
- Fetch (Advanced): usage/fetch.md
- Disclaimer: disclaimer.md
Expand Down
2 changes: 1 addition & 1 deletion src/mlstdb/__about__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2025-present Himal Shrestha <himal2007@duck.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
__version__ = "1.2.0"
__version__ = "1.3.0"
2 changes: 2 additions & 0 deletions src/mlstdb/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from mlstdb.__about__ import __version__
from mlstdb.cli.connect import connect
from mlstdb.cli.fetch import fetch
from mlstdb.cli.ping import ping
from mlstdb.cli.purge import purge
from mlstdb.cli.update import update

Expand All @@ -30,6 +31,7 @@ def mlstdb():


mlstdb.add_command(connect)
mlstdb.add_command(ping)
mlstdb.add_command(update)
mlstdb.add_command(fetch)
mlstdb.add_command(purge)
83 changes: 83 additions & 0 deletions src/mlstdb/cli/ping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import json

import click

from mlstdb.core.auth import ping_url


@click.command()
@click.help_option("-h", "--help")
@click.argument("url")
@click.option(
"--db",
"-d",
type=click.Choice(["pubmlst", "pasteur"]),
default=None,
help="Database whose stored credentials are used for authentication.",
)
@click.option(
"--no-auth",
"no_auth",
is_flag=True,
default=False,
help="Skip authentication and send an unauthenticated request.",
)
@click.option(
"--verbose",
"-v",
is_flag=True,
default=False,
help="Print extra request detail (auth mode, full URL, status code).",
)
def ping(url: str, db: str, no_auth: bool, verbose: bool):
"""Probe an API endpoint and display the response.

\b
Makes a single GET request to URL and prints the HTTP status and
response body. Authentication is attempted automatically in this order:

\b
1. API key (stored by 'mlstdb connect --api-key')
2. OAuth session token (stored by 'mlstdb connect')
3. Unauthenticated fallback (with a warning)

Use --no-auth to skip all authentication, equivalent to the
--no-auth flag on 'mlstdb update'.

\b
Examples:
mlstdb ping https://rest.pubmlst.org/db --no-auth
mlstdb ping https://rest.pubmlst.org/db/pubmlst_neisseria_seqdef/schemes --db pubmlst
mlstdb ping https://bigsdb.pasteur.fr/api/db --db pasteur --verbose
"""
# Prompt for --db when authentication is needed and it was not supplied
if not no_auth and db is None:
db = click.prompt(
"Which database holds your credentials for this URL?",
type=click.Choice(["pubmlst", "pasteur"]),
default="pubmlst",
)

try:
status_code, body, json_payload = ping_url(
url=url,
db=db,
verbose=verbose,
no_auth=no_auth,
)
except Exception as exc:
error(f"\n{exc}")
raise SystemExit(1)

click.echo(f"\nHTTP {status_code} {url}\n")

if json_payload is not None:
click.echo(json.dumps(json_payload, indent=2))
else:
click.echo(body)

if status_code in (401, 403):
click.echo(
"\nHint: run 'mlstdb connect --db <db>' to configure credentials, "
"or use --no-auth for unauthenticated access."
)
Loading
Loading