SDK for the LunarTools remote APIs: captcha solving, inbox OTP retrieval, and Discord webhook forwarding.
Project description
lunartools-py
Python SDK for the LunarTools remote APIs: captcha solving, inbox OTP retrieval, and Discord webhook forwarding.
Requests are routed to a specific user's running LunarTools toolbox. The toolbox must be open and connected.
pip install lunartools-py
The package installs as lunartools:
from lunartools import LunarTools
Quick start
Create a client, then pass an API key per call. The key is created in the toolbox and identifies both the key and the toolbox it belongs to, so no Client ID is needed.
from lunartools import LunarTools
client = LunarTools()
otp = client.otp("lt_ik_...", email="softies_archaic_8x@icloud.com", site="nike")
print(otp.otp_code, "from", otp.imap_email)
Inbox API
otp() waits for a one-time code to arrive and returns it. Only unread mail is searched, newest first, and the matched message is marked read.
otp = client.otp(
api_key,
email="alias@icloud.com", # required - indexes the inbox
imap_email="mailbox@icloud.com", # optional - omit to search every connected account
site="nike", # optional - use a built-in parser
regex=None, # optional - your own pattern, first capture group wins
from_=None, # optional - filter by sender
timeout_ms=60_000, # optional - default 60s, max 120s
)
Omit imap_email and the toolbox searches every connected account, then reports which one served the code in otp.imap_email.
With no site and no regex, the toolbox auto-detects the code (4, 6, or 8 characters), falling back to AI if the heuristic finds nothing.
Built-in sites: bestbuy, crunchyroll, disney, eql, funko, goat, nike, privacy, samsclub, target, topps, walmart, zumiez.
from_ has a trailing underscore because from is a Python keyword. It is sent as from on the wire.
Counting by subject
Pass a subject to count matching mail instead of extracting a code. Useful for win trackers. Returns immediately and marks nothing read.
result = client.count(api_key, email="alias@icloud.com", subject="WINNER")
print(result.count)
Solving API
result = client.solve(
api_key,
captcha_type="hcaptcha",
page_url="https://example.com/checkout",
site_key="e94865c2-4231-4c25-9c6e-2b797b2b56cf",
proxy_url=None, # optional - omit to use the harvester's own proxy
)
print(result.token, result.solve_ms)
Webhooks
Posts a Discord-shaped payload to your forwarder token, which fans out to every Discord URL configured for it. Embeds without a timestamp get one automatically.
from lunartools import WebhookPayload, Embed, EmbedField
result = client.webhook("your-webhook-token", WebhookPayload(
username="LunarTools",
embeds=[Embed(
title="Checkout Success",
color=0x5865F2,
fields=[EmbedField(name="Site", value="Nike", inline=True)],
)],
))
print(f"{result.delivered} of {result.count} delivered")
The webhook token comes from the toolbox and is not the same as an API key.
Errors
Every failure raises a LunarToolsError carrying the API's code.
from lunartools import LunarToolsError
try:
otp = client.otp(api_key, email="alias@icloud.com")
except LunarToolsError as error:
if error.retryable:
... # client_offline, client_disconnected, auth_unavailable, too_many_inflight
print(error.code, error.status_code)
| Code | Meaning |
|---|---|
invalid_key |
Unknown API key for this client |
key_disabled |
The key exists but is disabled |
client_offline |
The toolbox is not connected |
imap_not_connected |
No matching IMAP account is connected |
unsupported_site |
site is not a built-in parser |
invalid_regex |
regex failed to compile |
otp_timeout |
No code arrived before the deadline |
no_harvester |
No accepting harvester of that captcha type is open |
solve_timeout |
The solve did not finish before the deadline |
too_many_inflight |
Too many concurrent requests for this client |
Options
client = LunarTools(
base_url="https://remote.lunaraio.com",
timeout=150.0,
)
Requests are long-polled and can take up to 120s, so keep timeout above your per-request timeout_ms. The client is also a context manager:
with LunarTools() as client:
...
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lunartools_py-0.2.0.tar.gz.
File metadata
- Download URL: lunartools_py-0.2.0.tar.gz
- Upload date:
- Size: 5.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f41ace4fd77e7237f2017a32b7194290ebf559ea8000cd0f779399c3c03588f0
|
|
| MD5 |
bf218a9d7447579a718365aea014622a
|
|
| BLAKE2b-256 |
908f5992e7dcfac310770b16479894262e2f31b3a326c1ca4b3995c4d236e9d3
|
File details
Details for the file lunartools_py-0.2.0-py3-none-any.whl.
File metadata
- Download URL: lunartools_py-0.2.0-py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29e4a6dd314bc7c592071c675110762e95f673fc0648d7a7aafa3777ffd3d7fd
|
|
| MD5 |
ccebe32169a0bee5088ae4fe11bbdd3e
|
|
| BLAKE2b-256 |
0a7ef55928394c5d12a508c25b2795bcff9c60f54ed4a35cae2ff3fbedaae880
|