How to Create a "Taken" Result Using the Result Factory Methods in user-scanner
Call Result.taken(extra=None, media=None) from user_scanner/core/result.py to return a fully-populated result indicating a username or email exists.
The Result class is the central data structure in the kaifcodec/user-scanner repository. Validators use its factory methods to communicate findings to the scan engine. This guide explains how to correctly create a "taken" result—the most common output when a username or email address is found to exist on a platform.
Understanding the Result Factory Methods
In user_scanner/core/result.py, the Result class provides three static factory methods:
| Method | Status | Purpose |
|---|---|---|
Result.available() |
Result.Status.AVAILABLE |
Username/email does not exist on the platform |
Result.taken(extra=None, media=None) |
Result.Status.TAKEN |
Username/email exists (is taken) |
Result.error(message) |
Result.Status.ERROR |
Scan failed due to network, captcha, or unexpected issue |
Each factory method constructs a Result instance with the correct status field pre-populated. The engine, formatters, and exporters depend on this consistent schema.
The Result.taken() Method Signature
The method is defined in user_scanner/core/result.py as a static method:
@staticmethod
def taken(extra: dict | None = None, media: list[str] | None = None) -> "Result":
Parameters
extra– Optional dictionary of metadata about the discovered account. Common fields includeprofile_url,full_name,bio,location, andfollowers_count.media– Optional list of image URLs (profile pictures, banners) discovered during the scan.
Both parameters default to None. When omitted, the method initializes empty containers ({} for extra, [] for media).
Code Examples: Creating Taken Results
Minimal Taken Result
Return a basic taken result with no additional data:
from user_scanner.core.result import Result
result = Result.taken()
# Result(status=Result.Status.TAKEN, extra={}, media=[])
Taken Result with Metadata
Populate the extra dictionary with account details:
result = Result.taken(
extra={
"profile_url": "https://github.com/octocat",
"full_name": "The Octocat",
"bio": "GitHub's mascot",
"location": "San Francisco, CA",
}
)
Taken Result with Media URLs
Include discovered image assets:
result = Result.taken(
extra={"profile_url": "https://twitter.com/example"},
media=[
"https://pbs.twimg.com/profile_images/1234567890/profile.jpg",
"https://pbs.twimg.com/profile_banners/1234567890/1234567890/1500x500",
]
)
Complete Validator Implementation
A real-world validator combining all patterns, as implemented in scanners consuming this API:
from user_scanner.core.result import Result
def validate_github(username: str) -> Result:
"""Check if a GitHub username exists."""
url = f"https://github.com/{username}"
response = generic_validate(url) # Platform-specific HTTP logic
if response.status_code == 200 and '"login":' in response.text:
# User exists—return taken result with extracted data
return Result.taken(
extra={
"profile_url": url,
"api_url": f"https://api.github.com/users/{username}",
},
media=[f"https://github.com/{username}.png"],
)
# User does not exist
return Result.available()
How the Engine Processes Taken Results
The scan engine in user_scanner/core/engine.py consumes Result objects returned by validators:
- Validation loop – Each platform validator returns a
ResultviaResult.taken(),Result.available(), orResult.error(). - Aggregation – The engine collects results across all platforms for a given query.
- Formatting – Results pass to
user_scanner/core/formatter.py, which serializes them for CLI, JSON, CSV, or PDF output. - Export – Formatters access
result.status,result.extra, andresult.mediato build the final report.
Using the factory method guarantees these components receive properly structured data.
Best Practices for Taken Results
- Always use the factory method rather than constructing
Resultobjects directly. This ensures thestatusfield is correctly set and future-proofs your code against schema changes. - Keep
extraJSON-serializable – The JSON and CSV formatters attempt to serialize this dictionary; avoid non-primitive objects. - Validate
mediaURLs – Provide only well-formed HTTP/HTTPS strings. The PDF generator renders these as embedded images. - Return early on errors – Use
Result.error()for timeouts, rate limits, or ambiguous responses; don't conflate these withtaken.
Summary
- Factory method:
Result.taken(extra=None, media=None)inuser_scanner/core/result.py - Purpose: Signal that a username or email exists on a platform
- Parameters: Optional
extradict for metadata,medialist for image URLs - Benefits: Guaranteed schema compliance, centralized validation, seamless integration with engine and formatters
Frequently Asked Questions
What happens if I omit both parameters to Result.taken()?
The method returns a valid Result with status=Result.Status.TAKEN, empty extra={}, and empty media=[]. This is useful when you only need to signal existence without additional details.
Can I modify a taken result after creation?
The Result class is typically implemented as a frozen dataclass or similar immutable structure. Modify data before passing it to Result.taken() rather than mutating the returned object.
How does the PDF formatter use the media field?
The PDF generator in user_scanner/core/formatter.py retrieves image URLs from Result.media and embeds them as thumbnails in the scan report. Invalid or unreachable URLs are skipped with a warning.
What's the difference between Result.taken() and raising an exception?
Result.taken() indicates successful discovery of an account. Exceptions or Result.error() indicate scan failure—the platform couldn't be checked. These are semantically distinct: a taken result answers "yes, it exists," while an error answers "we couldn't determine."
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →