Skip to main content

py-lmobile-toolkit

乐信(51welink)短信服务 Python SDK,提供同步和异步接口调用,支持签名认证机制(MD5 + SHA256)。

作者

Guolei

项目主页

功能特性

  • ✅ 同步客户端 SmsClient 与异步客户端 AsyncSmsClient(方法名完全一致)
  • ✅ 异步客户端支持 async with 上下文管理器
  • ✅ 请求签名认证机制(MD5 密码 + SHA256 签名,AccessKey)
  • ✅ 响应数据模型验证(Pydantic v2)
  • ✅ 覆盖官方文档导航中的全部客户端可调用接口(短信/模板短信/账号/其他 API)
  • ✅ 接口端点以常量集中管理,便于按官方文档精确对齐
  • ✅ 所有方法支持透传 **kwargs 给 httpx,方便覆盖 URL、请求头等

注意:账号、密码、产品 ID 等敏感信息请通过环境变量(.env 文件)配置,勿硬编码在代码中。

安装

推荐使用 uv 安装

uv add py-lmobile-toolkit

或从本地源码安装(开发模式):

uv pip install -e .

或者使用 pip 安装

pip install py-lmobile-toolkit

或从本地源码安装(开发模式):

pip install -e .

安装测试依赖:

uv pip install -e ".[dev]"

快速开始

from py_lmobile_toolkit.sms.client import SmsClient

# 创建同步客户端
sms = SmsClient(
    account_id="your_account_id",
    password="your_password",
    product_id="your_product_id",
)

# 发送单条短信
response = sms.send_sms(
    phone_nos="13800138000",
    content="【乐信】您的验证码是:123456,请于 5 分钟内正确输入",
)
print(f"成功: {response.ok}, 结果码: {response.Result}")

sms.close()

异步调用

import asyncio
from py_lmobile_toolkit.sms.client import AsyncSmsClient


async def main():
    async with AsyncSmsClient(
        account_id="your_account_id",
        password="your_password",
        product_id="your_product_id",
    ) as sms:
        response = await sms.send_sms(
            phone_nos=["13800138000", "13900139000"],
            content="【乐信】批量发送测试",
        )
        print(f"成功: {response.ok}, 结果码: {response.Result}")


asyncio.run(main())

已实现的接口

分类 接口 同步方法 异步方法 响应模型 端点状态
短信API 提交短信 send_sms / send send_sms / send SmsSendSmsResponse ✅ 已知可靠
短信API 提交个性化短信(变量XML格式) send_personalized_xml send_personalized_xml SmsBaseResponse [待核实]
短信API 提交个性化短信(变量Json格式) send_personalized_json send_personalized_json SmsBaseResponse [待核实]
短信API 拉取状态报告 pull_status_report pull_status_report SmsPullReportResponse [待核实]
短信API 拉取上行信息 pull_mo_message pull_mo_message SmsPullMoResponse [待核实]
短信API 取消定时消息发送 cancel_scheduled_sms cancel_scheduled_sms SmsCancelScheduledResponse [待核实]
模板短信API 提交模板短信 submit_template_sms submit_template_sms SmsSubmitTemplateSmsResponse [待核实]
模板短信API 提交个性化模板短信 submit_personalized_template_sms submit_personalized_template_sms SmsBaseResponse [待核实]
模板短信API 短信模板报备 register_template register_template SmsRegisterTemplateResponse [待核实]
模板短信API 视频短信模板报备 register_video_template register_video_template SmsRegisterVideoTemplateResponse [待核实]
模板短信API 删除模板 delete_template delete_template SmsDeleteTemplateResponse [待核实]
模板短信API 查询模板 query_template query_template SmsQueryTemplateResponse [待核实]
账号API 查询余量 query_balance query_balance SmsBalanceResponse [待核实]
账号API 查询计费量 query_billing query_billing SmsBillingResponse [待核实]
其他API H5跳转小程序短链生成 generate_h5_miniprogram_short_link generate_h5_miniprogram_short_link SmsH5ShortLinkResponse [待核实]
其他API 更新H5跳小程序的AccessToken update_h5_miniprogram_access_token update_h5_miniprogram_access_token SmsUpdateAccessTokenResponse [待核实]

回调类接口(状态报告推送、上行推送、模板审核结果推送)为服务端 Webhook,非客户端调用接口,此处不提供客户端方法。如需接收推送,请在业务服务器上实现对应 HTTP 接口并解析请求体。

端点说明

  • 提交短信 端点 /EncryptionSubmit/SendSms.ashx 为已知可靠(与历史版本一致)。
  • 其余接口端点基于官方文档接口名称推断,均标注 [待核实],定义在 src/py_lmobile_toolkit/sms/client.py 的顶部常量中,请以 https://www.lmobile.cn/ApiPages/index.html 实际文档的请求地址与参数为准进行调整。
  • 每个方法均接受 url 关键字参数可覆盖默认端点,亦可通过 **kwargs 透传 httpx 参数。

响应模型

所有响应均继承 SmsBaseResponse,包含 Result 字段,Result 为 "succ" 表示成功,可通过 ok 属性判断:

from py_lmobile_toolkit.sms.models import SmsSendSmsResponse

response: SmsSendSmsResponse = sms.send_sms(...)
if response.ok:
    print("发送成功")
else:
    print(f"发送失败,结果码: {response.Result}")

所有模型均开启 extra="allow",兼容 API 返回的扩展字段。

签名生成算法

签名生成遵循以下步骤:

  1. 密码 MD5 加密:MD5(password + smms_encrypt_key),结果转大写
  2. 参数拼接(按顺序):
    AccountId={account_id}&PhoneNos={first_phone}&Password={md5_password}&Random={random}&Timestamp={timestamp}
    
    注意:PhoneNos 只取第一个手机号用于签名
  3. SHA256 加密:对拼接后的字符串进行 SHA256 哈希,作为 AccessKey
from py_lmobile_toolkit.sms.auth import timestamp, random_digits, sha256_signature

ts = timestamp()
digits = random_digits()
signature = sha256_signature(
    account_id="your_account_id",
    password="your_password",
    phone_nos="13800138000",
    random_digits=digits,
    timestamp=ts,
    smms_encrypt_key="SMmsEncryptKey",
)

示例代码 (examples/)

完整可运行示例位于 examples/sms/,文件命名规则为 example_*.py(同步)与 example_async_*.py(异步)。

运行示例前,请复制模板并填写真实账号:

cp examples/sms/.env.example examples/sms/.env

示例文件列表:

同步示例 异步示例 说明
example_send_sms.py example_async_send_sms.py 提交短信
example_personalized_xml.py example_async_personalized_xml.py 提交个性化短信(XML)
example_personalized_json.py example_async_personalized_json.py 提交个性化短信(Json)
example_pull_report.py example_async_pull_report.py 拉取状态报告
example_pull_mo.py example_async_pull_mo.py 拉取上行信息
example_cancel_scheduled.py example_async_cancel_scheduled.py 取消定时消息
example_submit_template_sms.py example_async_submit_template_sms.py 提交模板短信
example_register_template.py example_async_register_template.py 短信模板报备
example_query_template.py example_async_query_template.py 查询模板
example_delete_template.py example_async_delete_template.py 删除模板
example_query_balance.py example_async_query_balance.py 查询余量
example_query_billing.py example_async_query_billing.py 查询计费量
example_h5_short_link.py example_async_h5_short_link.py H5 小程序短链
example_update_access_token.py example_async_update_access_token.py 更新 AccessToken

测试 (tests/)

测试用例位于 tests/sms/,基于 pytest + pytest-asyncio,统一从 tests/sms/.env 读取配置,公共夹具定义在 tests/sms/conftest.py。

运行测试前,请复制模板并填写真实账号:

cp tests/sms/.env.example tests/sms/.env

安装测试依赖并运行:

uv pip install -e ".[dev]"
pytest tests/sms -q

未配置 SMS_ACCOUNT_ID / SMS_PASSWORD 时,测试会自动跳过。

目录结构

py_lmobile_toolkit/
├── README.md
├── pyproject.toml
├── LICENSE
├── .gitignore
├── src/
│   └── py_lmobile_toolkit/
│       ├── __init__.py        # 顶层包
│       ├── py.typed           # PEP 561 类型标记
│       └── sms/               # 子包,供他人调用
│           ├── __init__.py
│           ├── auth.py        # 签名生成工具(md5/sha256/timestamp/random_digits)
│           ├── client.py      # SmsClient(同步)与 AsyncSmsClient(异步)
│           └── models.py      # pydantic 响应模型
├── tests/
│   └── sms/
│       ├── __init__.py
│       ├── conftest.py        # 公共夹具(客户端、查询条件)
│       ├── .env.example       # 测试配置模板
│       └── test_*.py          # 各接口的同步 / 异步测试用例
└── examples/
    └── sms/
        ├── .env.example       # 示例配置模板
        ├── example_common.py  # 示例公共辅助(读取配置、构造客户端)
        ├── example_*.py       # 各接口同步示例
        └── example_async_*.py # 各接口异步示例

许可证

MIT License

Metadata

Release files for py-lmobile-toolkit 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for py-lmobile-toolkit 3.0.0
File Size Uploaded Provenance
py_lmobile_toolkit-3.0.0.tar.gz 17.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for py-lmobile-toolkit 3.0.0
File Interpreter ABI Platform
py_lmobile_toolkit-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 33.8 kB

Release files / py_lmobile_toolkit-3.0.0.tar.gz

Download URL py_lmobile_toolkit-3.0.0.tar.gz
Size 17.7 kB
Tags Source
SHA-256 checksum
How to use checksums
75605de15b7727f4b54c5e4b935cbf6f8f4f47a7f5b0e226eac893374e9d4299
BLAKE2b-256 checksum
How to use checksums
4fd6b29ff0d1ab6dec5560fa73bb176f9a947cd0d157ee1538bdb1904f6868bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.11

Release files / py_lmobile_toolkit-3.0.0-py3-none-any.whl

Download URL py_lmobile_toolkit-3.0.0-py3-none-any.whl
Size 16.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ff9b0e73b2ff81a632936f374b018598620a93d0055c4f5f033902015fe81ea4
BLAKE2b-256 checksum
How to use checksums
5cfc66d9e2abff6e76fcff422521e9d129d952ce8eae467f9cb5c4d7bc96f3ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.11

Security for py-lmobile-toolkit 3.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page