Skip to main content

Python SDK for the bypass-vuotlink API

Project description

bypass-vuotlink-sdk

Python SDK for the bypass-vuotlink API — a service that resolves shortlink/safelink URLs (e.g. vuotnhanh.com) to their final destination by running a real browser workflow.

Install

pip install bypass-vuotlink-sdk

Quick start

from bypass_vuotlink_sdk import BypassVuotLink

with BypassVuotLink(base_url="http://localhost:8000") as client:
    result = client.resolve("https://vuotnhanh.com/abc123")
    print(result.final_url)

Async

from bypass_vuotlink_sdk import AsyncBypassVuotLink

async with AsyncBypassVuotLink(base_url="http://localhost:8000") as client:
    result = await client.resolve("https://vuotnhanh.com/abc123")
    print(result.final_url)

Configuration

from bypass_vuotlink_sdk import BypassVuotLink, ClientConfig

# Pass parameters directly
client = BypassVuotLink(
    base_url="http://localhost:8000",
    timeout=90.0,
    api_key="secret",
)

# Or via a config object
config = ClientConfig(base_url="http://localhost:8000", api_key="secret")
client = BypassVuotLink.from_config(config)

# Or from environment variables
# BYPASS_BASE_URL, BYPASS_TIMEOUT, BYPASS_API_KEY
client = BypassVuotLink.from_env()

Result

result.requested_url  # the URL you passed in
result.final_url      # resolved destination
result.status_code    # HTTP status at final_url
result.title          # page title
result.workflow       # workflow used (e.g. "vuotnhanh")
result.hops_used      # how many workflow hops were actually followed
result.hops_exceeded  # True if max_hops was hit before a terminal workflow was reached

Supported workflows

workflows = client.list_workflows()

for workflow in workflows.workflows:
    print(workflow.name)
    print(workflow.link_formats)

Example item:

workflow.name          # "funlink"
workflow.link_formats  # ["https://funlink.io/..."]

Chained links (max_hops)

Some links resolve through more than one bypass workflow in a row (e.g. a shortlink resolving to a funlink link, which itself resolves to a toplinks link). By default resolve() follows up to 10 such hops before returning. Pass max_hops to cap that:

# Solve only the first link and return immediately, without following any
# further chained hop.
result = client.resolve(url, max_hops=1)

result.hops_used reports how many hops were actually followed. If the chain doesn't reach a terminal workflow within max_hops, result.hops_exceeded is True (hops_used == max_hops) and result.final_url is just wherever the last hop left off, not necessarily the fully-resolved destination.

Fetch a code without submitting it

result = client.fetch_code(
    "https://funlink.io/some/destination",
    "funlink",  # or "toplinks"
    source="live",  # or "background"
)
result.code       # confirmation code
result.dest_url   # the destination it was fetched from

Code pool

# Pop a prefetched code for a cached keyword_text/image_url pair.
result = client.consume_code("some keyword", image_url="https://...")
result.code
result.resolved_url

Not-found tasks (manual search fallback)

When a keyword's destination link couldn't be auto-resolved (e.g. via OCR + Google search), it's marked not_found in the cache. These helpers let a human/worker claim one, search the web manually, and report back a candidate:

task = client.claim_not_found_task(lease_seconds=900)
task.keyword_id
task.keyword_text
task.image_url
task.search_query

# ... search the web manually, find a candidate destination URL ...

result = client.verify_not_found_task(task.keyword_id, "https://found-it.example/page")
if result.verified:
    print("Accepted:", result.resolved_url)
else:
    print("Rejected:", result.reason)

claim_not_found_task() raises ApiError (status_code 404) when there are no claimable not-found entries. The lease (lease_seconds) auto-expires if never reported back, so an unreported claim becomes claimable by someone else again without any explicit release call.

# Re-open every not-found entry for another search attempt.
result = client.reset_not_found()
result.reset_count

Error handling

from bypass_vuotlink_sdk import (
    UnsupportedUrlError,
    UnsafeUrlError,
    BrowserExecutionError,
    BypassVuotlinkError,
)

try:
    result = client.resolve(url)
except UnsupportedUrlError:
    ...  # no workflow supports this URL type (HTTP 422)
except UnsafeUrlError:
    ...  # URL is private or unsafe (HTTP 400)
except BrowserExecutionError:
    ...  # browser workflow failed (HTTP 502)
except BypassVuotlinkError:
    ...  # catch-all

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bypass_vuotlink_sdk-0.3.0.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bypass_vuotlink_sdk-0.3.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page