Skip to content

Naminter

Main class for username enumeration.

Basic Usage

import asyncio
from naminter import Naminter, CurlCFFISession, WMN_REMOTE_URL

async def main():
    async with CurlCFFISession() as http_client:
        wmn_data = (await http_client.get(WMN_REMOTE_URL)).json()

        async with Naminter(http_client=http_client, wmn_data=wmn_data) as naminter:
            async for result in naminter.enumerate_usernames(["username"]):
                print(f"{result.name}: {result.status.value}")

asyncio.run(main())

Test Usage

import asyncio
from naminter import Naminter, CurlCFFISession, WMN_REMOTE_URL

async def main():
    async with CurlCFFISession() as http_client:
        wmn_data = (await http_client.get(WMN_REMOTE_URL)).json()

        async with Naminter(http_client=http_client, wmn_data=wmn_data) as naminter:
            async for site_result in naminter.test_enumeration():
                if site_result.error:
                    print(f"ERROR {site_result.name}: {site_result.error}")
                else:
                    found = sum(1 for r in site_result.results if r.status.value == "exists")
                    total = len(site_result.results)
                    print(f"{site_result.name}: {found}/{total} known accounts found")

asyncio.run(main())

API Reference

naminter.core.main.Naminter

Naminter(http_client, wmn_data=None, wmn_schema=None, max_tasks=MAX_CONCURRENT_TASKS)

Main class for Naminter username enumeration.

Initialize Naminter with configuration parameters.

PARAMETER DESCRIPTION
http_client

Async HTTP session implementing the BaseSession protocol.

TYPE: BaseSession

wmn_data

Parsed WhatsMyName dataset dictionary.

TYPE: dict[str, Any] | None DEFAULT: None

wmn_schema

Optional JSON Schema dictionary for dataset validation.

TYPE: dict[str, Any] | None DEFAULT: None

max_tasks

Maximum number of concurrent enumeration tasks.

TYPE: int DEFAULT: MAX_CONCURRENT_TASKS

RAISES DESCRIPTION
WMNSchemaError

If the JSON schema is invalid.

open async

open()

Initialize the HTTP session and validate the WMN dataset.

Use this method for long-running services where you need explicit lifecycle control. For scripts and CLI usage, prefer the context manager pattern: async with Naminter(...) as naminter:.

RAISES DESCRIPTION
HttpSessionError

If HTTP session initialization fails.

WMNUninitializedError

If WMN data is not provided.

WMNDataError

If WMN data loading fails.

WMNValidationError

If dataset validation fails.

Example
# Long-running service (FastAPI, etc.)
naminter = Naminter(http_client, wmn_data)
await naminter.open()  # Call once at startup

# ... handle many requests ...

await naminter.close()  # Call once at shutdown

close async

close()

Close the HTTP session and release resources.

Use this method for long-running services to clean up at shutdown. For scripts and CLI usage, prefer the context manager pattern.

Handles errors gracefully during cleanup.

RAISES DESCRIPTION
CancelledError

Propagated to allow proper cancellation handling.

summary

summary(site_names=None, include_categories=None, exclude_categories=None)

Get enriched WMN metadata information for diagnostics and UI.

Retrieves comprehensive summary information about the loaded WhatsMyName dataset, including site counts, categories, authors, and license information. Filters can be applied to compute statistics on a subset of sites.

PARAMETER DESCRIPTION
site_names

Optional list of specific site names to include in the summary. If None, all sites are included (subject to category filters).

TYPE: list[str] | None DEFAULT: None

include_categories

Optional list of categories to include. Only sites in these categories will be counted. If None, all categories are included (subject to exclude_categories).

TYPE: list[str] | None DEFAULT: None

exclude_categories

Optional list of categories to exclude. Sites in these categories will not be counted.

TYPE: list[str] | None DEFAULT: None

RETURNS DESCRIPTION
WMNSummary

Summary object containing license, authors, site names, counts, categories, and known usernames count.

TYPE: WMNSummary

RAISES DESCRIPTION
WMNUninitializedError

If WMN data is not initialized.

WMNUnknownSiteError

If site_names contains unknown site names.

WMNUnknownCategoriesError

If include_categories or exclude_categories contains unknown categories.

Example
async with Naminter(http_client, wmn_data, wmn_schema) as naminter:
    # Get summary of all sites
    summary = naminter.summary()
    print(f"Total sites: {summary.sites_count}")

    # Get summary for specific categories
    summary = naminter.summary(
        include_categories=["social", "coding"],
    )
    print(f"Social/coding sites: {summary.sites_count}")

enumerate_site async

enumerate_site(site, username, mode=ALL, *, exclude_text=False)

Enumerate a single site for the given username.

Performs a single username lookup for a single site definition from the loaded WhatsMyName (WMN) dataset. It builds the URL and optional POST body using the site's configuration, sends an HTTP request, and then evaluates the response using the site's detection rules to determine whether the username is present on that site.

PARAMETER DESCRIPTION
site

A single site configuration dictionary from the WMN dataset. This dict must contain, at minimum, the following keys: "name" (site name), "cat" (site category), "uri_check" (URL template with "{account}" placeholder), "e_code" (expected HTTP status for an existing account), "e_string" (expected string in body for an existing account), "m_code" (expected HTTP status for a missing account), and "m_string" (expected string in body for a missing account). Optional keys include "headers" (dict of HTTP headers to send with the request), "post_body" (POST body template containing "{account}"), "strip_bad_char" (characters to strip from the username before substitution in the URL/body), "uri_pretty" (an optional "pretty" URL template for reporting), and "valid" (boolean flag; sites with valid=False are skipped and return NOT_VALID status).

TYPE: WMNSite

username

The raw username to test on this site. It is used to build the request URL and optional POST body. If the site defines "strip_bad_char", those characters are removed from the username before substitution.

TYPE: str

mode

Detection mode that controls how the "expected" (E) and "missing" (M) criteria are interpreted when classifying the HTTP response. WMNMode.ALL requires all configured conditions for a state to match (strict AND logic), while WMNMode.ANY allows any matching condition to be sufficient (looser OR logic).

TYPE: WMNMode DEFAULT: ALL

exclude_text

When True, omit response text from the returned result.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
WMNResult

A single WMNResult instance that encapsulates the site name (from "name"), category (from "cat"), the username that was tested, the uri_check and uri_pretty URLs, a high-level status classification (e.g. EXISTS, PARTIAL_EXISTS, PARTIAL_MISSING, CONFLICTING, MISSING, UNKNOWN, ERROR, or NOT_VALID), status_code, text, and elapsed time (if the HTTP request completed successfully), and an error message (if an error occurred).

TYPE: WMNResult

RAISES DESCRIPTION
CancelledError

Propagated if the caller cancels the task while the HTTP request is in progress.

HttpSessionError

Propagated if the HTTP session is not initialized or was closed.

Example
site = {
    "name": "GitHub",
    "uri_check": "https://github.com/{account}",
    "e_code": 200,
    "e_string": "GitHub Profile",
    "m_code": 404,
    "m_string": "Not Found",
    "cat": "coding",
}

async with Naminter(http_client, wmn_data, wmn_schema) as naminter:
    result = await naminter.enumerate_site(site, "torvalds")
    print(result.name, result.username, result.status, result.uri_pretty)

enumerate_usernames async

enumerate_usernames(usernames, site_names=None, include_categories=None, exclude_categories=None, mode=ALL, *, exclude_text=False)

Enumerate one or multiple usernames across one or multiple sites.

This is the high-level method for running bulk username checks. It takes one list of usernames and a selection of sites (by name and/or category filters), then runs enumerate_site for every (site, username) pair.

The method returns an async generator that yields WMNResult objects one by one as they finish, without waiting for all tasks to complete.

PARAMETER DESCRIPTION
usernames

A non-empty list of usernames to enumerate across sites. Each username is tested independently on every selected site.

TYPE: list[str]

site_names

Optional list of site names to restrict enumeration to a subset of sites. If None, all sites from the WMN dataset are considered (subject to category filters). If provided, every name must correspond to a known site; otherwise a WMNUnknownSiteError is raised.

TYPE: list[str] | None DEFAULT: None

include_categories

Optional list of site categories (values of the "cat" field) to include. When provided, only sites whose category is in this list are considered. This filter is applied in addition to site_names.

TYPE: list[str] | None DEFAULT: None

exclude_categories

Optional list of site categories (values of the "cat" field) to exclude. When provided, any site whose category is in this list is skipped. This filter is also applied in addition to site_names and include_categories.

TYPE: list[str] | None DEFAULT: None

mode

Detection mode forwarded to enumerate_site for each check. WMNMode.ALL uses strict evaluation where all "exists" indicators must match, while WMNMode.ANY uses relaxed evaluation where any "exists" indicator can match.

TYPE: WMNMode DEFAULT: ALL

exclude_text

When True, omit response text from each yielded result.

TYPE: bool DEFAULT: False

YIELDS DESCRIPTION
WMNResult

Result objects one at a time as tasks complete. This allows streaming processing of results. The order is not guaranteed to match submission order.

TYPE:: AsyncGenerator[WMNResult, None]

RAISES DESCRIPTION
WMNArgumentError

If usernames list is empty.

WMNUninitializedError

If WMN data is not initialized.

WMNUnknownSiteError

If any requested site name in site_names does not exist in the loaded WMN dataset.

WMNUnknownCategoriesError

If include_categories or exclude_categories contains unknown categories.

test_enumeration async

test_enumeration(site_names=None, include_categories=None, exclude_categories=None, mode=ALL, *, exclude_text=False)

Test site detection rules using known usernames from the dataset.

This method is intended for maintainers and automated health checks of the WMN dataset. It selects sites (optionally filtered by names and categories), tests each site using its "known" usernames, and yields a WMNTestResult per site.

PARAMETER DESCRIPTION
site_names

Optional list of site names to test. If None, all sites are tested (subject to category filters).

TYPE: list[str] | None DEFAULT: None

include_categories

Optional list of categories to include. Only sites in these categories are tested.

TYPE: list[str] | None DEFAULT: None

exclude_categories

Optional list of categories to exclude from testing.

TYPE: list[str] | None DEFAULT: None

mode

Detection mode for each test. WMNMode.ALL uses strict evaluation, WMNMode.ANY uses relaxed evaluation.

TYPE: WMNMode DEFAULT: ALL

exclude_text

When True, omit response text from results within each test.

TYPE: bool DEFAULT: False

YIELDS DESCRIPTION
WMNTestResult

Result for each site in completion order, containing the site name, category, list of WMNResult objects, aggregate status, and error message if testing failed.

TYPE:: AsyncGenerator[WMNTestResult, None]

RAISES DESCRIPTION
WMNUninitializedError

If WMN data is not initialized.

WMNUnknownSiteError

If site_names contains unknown sites.

WMNUnknownCategoriesError

If categories are unknown.