# Expected Function Signature for Email Scanning Modules in user-scanner

> Discover the expected function signature for email scanning modules in user-scanner. Learn how to create custom validators to enhance your email analysis.

- Repository: [Kaif/user-scanner](https://github.com/kaifcodec/user-scanner)
- Tags: api-reference
- Published: 2026-09-02

---

**Every email-scanning module in user-scanner must expose a single asynchronous validator function named `validate_<service>` that takes an email string and returns a `Result` object.**

The kaifcodec/user-scanner repository defines a strict, uniform interface for all email validation modules. This design pattern enables the core orchestrator to dynamically discover and invoke any email-checking module without service-specific logic.

## Mandatory Function Signature

All email-scanning modules implement the following asynchronous signature:

```python
async def validate_<service>(email: str) -> Result

```

- **`email: str`** — the email address to validate
- **`Result`** — a return type class defined in [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py) that encapsulates three possible states: `available()`, `taken(...)`, or `error(...)`

The function name follows the pattern `validate_<service>` where `<service>` is the lowercase identifier of the target platform.

## Real Implementations in the Codebase

The user-scanner source code demonstrates this pattern across multiple service categories:

| Service | File Path | Function |
|---------|-----------|----------|
| Instagram | [`user_scanner/email_scan/social/instagram.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/email_scan/social/instagram.py) | `validate_instagram` |
| WomanLog | [`user_scanner/email_scan/women_health/womanlog.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/email_scan/women_health/womanlog.py) | `validate_womanlog` |
| Skyscanner | [`user_scanner/email_scan/travel/skyscanner.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/email_scan/travel/skyscanner.py) | `validate_skyscanner` |

As implemented in kaifcodec/user-scanner, these validators reside under `user_scanner/email_scan/<category>/<service>.py` and are dynamically imported by the engine at runtime.

## The Result Class Contract

The `Result` class in [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py) provides three factory methods for consistent status reporting:

- **`Result.available()`** — email not found on the service
- **`Result.taken(extra={...})`** — email registered; optional `extra` dict for profile metadata
- **`Result.error(message)`** — validation failed due to network or parsing issues

## Minimal Working Example

Create a new email-scanning module by following this template:

```python

# user_scanner/email_scan/productivity/examplemail.py

from user_scanner.core.result import Result


async def validate_examplemail(email: str) -> Result:
    """
    Check if email is registered on ExampleMail service.
    """
    # Perform HTTP request or API lookup

    response = await fetch_email_status(email)
    
    if response.status == 200:
        return Result.taken(extra={"profile_url": response.data["url"]})
    elif response.status == 404:
        return Result.available()
    else:
        return Result.error(f"Unexpected status: {response.status}")

```

## Invoking Validators Through the Engine

The core orchestrator in [`user_scanner/engine.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/engine.py) loads modules and executes validators without hardcoded service logic:

```python
from user_scanner.engine import Engine

engine = Engine()

# Automatically routes to the correct validate_<service> function

result = await engine.validate_email("user@examplemail.com")

print(result.status)        # "available" | "taken" | "error"

print(result.extra)         # dict with additional metadata (if taken)

```

## Architecture Benefits

The expected function signature for email scanning modules delivers three critical advantages:

1. **Automatic discovery** — the engine scans `user_scanner/email_scan/` subdirectories and imports any module matching the naming convention
2. **Type safety** — consistent `Result` return type eliminates brittle string parsing across the codebase
3. **Testability** — isolated async functions with no external dependencies are straightforward to mock and unit test

## Summary

- All email-scanning modules must define **`async def validate_<service>(email: str) -> Result`**
- Validator functions live in **`user_scanner/email_scan/<category>/<service>.py`**
- The **`Result`** class from [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py) standardizes return values
- The engine in **[`user_scanner/engine.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/engine.py)** dynamically imports and executes validators
- This contract ensures uniform behavior across Instagram, Skyscanner, WomanLog, and any future services

## Frequently Asked Questions

### What happens if a module doesn't follow the validate_<service> naming convention?

The dynamic import mechanism in [`user_scanner/engine.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/engine.py) will fail to discover the function. Only modules exporting the exact `validate_<service>` pattern are registered as validators.

### Can validate_<service> functions accept additional parameters beyond email?

No — the core orchestrator invokes all validators with a single positional email argument. Pass configuration through module-level constants or environment variables instead.

### Is the Result class a dataclass or a custom object?

According to [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py), `Result` is a custom class with static factory methods. It encapsulates state internally and exposes `status`, `extra`, and boolean properties like `is_available` for caller inspection.

### Why must email validators be asynchronous?

Network I/O dominates email validation workflows. The async design in kaifcodec/user-scanner allows the engine to run hundreds of concurrent checks across different services without thread overhead.