Metadata-Version: 2.4
Name: lovensepy
Version: 1.1.4
Summary: Python Lovense API client
Author-email: LovensePy contributors <git@koval-dev.org>
License: Apache-2.0
Project-URL: Homepage, https://github.com/koval01/lovensepy
Project-URL: Repository, https://github.com/koval01/lovensepy
Project-URL: Issues, https://github.com/koval01/lovensepy/issues
Project-URL: Documentation, https://lovensepy.koval-dev.org/
Keywords: lovense,api,iot,teledildonics,asyncio,sdk,mqtt,home-assistant,ble
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp>=3.13.3
Requires-Dist: pydantic>=2.12.5
Provides-Extra: mqtt
Requires-Dist: paho-mqtt>=2.1.0; extra == "mqtt"
Provides-Extra: ble
Requires-Dist: bleak>=0.22.0; extra == "ble"
Requires-Dist: pick>=2.6.0; extra == "ble"
Provides-Extra: service
Requires-Dist: fastapi>=0.115.0; extra == "service"
Requires-Dist: uvicorn[standard]>=0.42.0; extra == "service"
Provides-Extra: dev
Requires-Dist: pytest>=9.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=1.3.0; extra == "dev"
Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
Requires-Dist: ruff>=0.15.0; extra == "dev"
Requires-Dist: pylint>=4.0.0; extra == "dev"
Requires-Dist: bandit>=1.9.0; extra == "dev"
Requires-Dist: pip-audit<2.10,>=2.7.0; extra == "dev"
Requires-Dist: build>=1.4.0; extra == "dev"
Requires-Dist: paho-mqtt>=2.1.0; extra == "dev"
Requires-Dist: bleak>=0.22.0; extra == "dev"
Requires-Dist: pick>=2.6.0; extra == "dev"
Requires-Dist: semgrep>=1.100.0; extra == "dev"
Requires-Dist: fastapi>=0.115.0; extra == "dev"
Requires-Dist: uvicorn[standard]>=0.42.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.6.1; extra == "docs"
Requires-Dist: mkdocs-material>=9.7.0; extra == "docs"
Requires-Dist: mkdocs-static-i18n>=1.3.1; extra == "docs"
Requires-Dist: pymdown-extensions>=10.21.0; extra == "docs"
Dynamic: license-file

# LovensePy

[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

**LovensePy** is a Python client for the [Lovense developer APIs](https://developer.lovense.com): Standard API over LAN (Game Mode) and cloud, Socket API (WebSocket, optional LAN command path), and Toy Events. Optional pieces include a Home Assistant MQTT bridge and direct BLE control.

**Who it is for:** developers building scripts, bots, dashboards, Home Assistant integrations, or experiments. Lovense’s official docs remain the source of truth for protocol behavior; this library wraps those flows in typed, tested Python.

## Install

```bash
pip install lovensepy
```

Optional extras:

```bash
pip install 'lovensepy[mqtt]'   # Home Assistant MQTT bridge service + paho-mqtt; run: lovensepy-mqtt
pip install 'lovensepy[ble]'    # Direct BLE (bleak, pick for examples)
```

## Docker Compose: Mosquitto + Home Assistant

The root `docker-compose.yml` starts **Mosquitto** and **Home Assistant** only. The LovensePy MQTT bridge runs **on the host** (BLE needs Bluetooth; LAN is simpler that way too). See [compose/README.md](compose/README.md) and [Home Assistant MQTT](docs/tutorials/home-assistant-mqtt.en.md#home-assistant-with-ble-full-setup).

## Minimal example (Game Mode)

```python
from lovensepy import LANClient, Actions

client = LANClient("MyApp", "192.168.1.100", port=20011)
client.function_request({Actions.VIBRATE: 10}, time=3)
```

Enable Game Mode in Lovense Remote, use the app host’s IP, and pick the right port (e.g. **20011** for Remote, **34567** for Connect). Full setup, tutorials, and API tables are on **[GitHub Pages](https://lovensepy.koval-dev.org/)** (or browse the [docs](docs/index.en.md) folder in the repository).

For **`async`/`await`** code, **`AsyncLANClient`**, **`AsyncServerClient`**, **`BleDirectHub`**, and **`BleDirectClient`** all subclass **`LovenseAsyncControlClient`**: same control methods so you can switch transport by changing only construction. See [Connection methods](docs/connection-methods.en.md#same-control-code-different-transport) and the [API reference](docs/api-reference.en.md#lovenseasynccontrolclient).

## How clients reach the toy

```mermaid
flowchart TB
    subgraph yourCode [Your app]
        LANClient
        AsyncLANClient
        ServerClient
        AsyncServerClient
        SocketAPIClient
        ToyEventsClient
        BleDirect[BleDirectClient / BleDirectHub]
        HAMqttBridge
    end

    subgraph localNet [Local network]
        RemoteApp[Lovense app]
        Toy[Lovense toy]
        MQTTBroker[MQTT broker]
    end

    subgraph cloudLayer [Lovense cloud]
        LovenseServer[Lovense server]
    end

    LANClient -->|"HTTP/HTTPS"| RemoteApp
    AsyncLANClient -->|"HTTP/HTTPS"| RemoteApp
    RemoteApp --> Toy

    ServerClient -->|"HTTPS"| LovenseServer
    AsyncServerClient -->|"HTTPS"| LovenseServer
    LovenseServer --> RemoteApp

    SocketAPIClient -->|"WebSocket"| LovenseServer
    SocketAPIClient -->|"HTTPS when use_local_commands"| RemoteApp

    ToyEventsClient -->|"WebSocket"| RemoteApp

    HAMqttBridge -->|"LAN: HTTP + Toy Events WS"| RemoteApp
    HAMqttBridge -.->|"BLE mode: direct"| Toy
    HAMqttBridge <-->|"MQTT"| MQTTBroker

    BleDirect -.->|"BLE"| Toy
```

## Documentation and official APIs

- **Project docs (site):** [lovensepy.koval-dev.org](https://lovensepy.koval-dev.org/) — **source:** [docs/index.en.md](docs/index.en.md) (Russian: [index.ru.md](docs/index.ru.md))
- [Lovense Standard API](https://developer.lovense.com/docs/standard-solutions/standard-api.html)
- [Lovense Socket API](https://developer.lovense.com/docs/standard-solutions/socket-api.html)
- [Toy Events API](https://developer.lovense.com/docs/standard-solutions/toy-events-api.html)

## Changelog

See [CHANGELOG.md](CHANGELOG.md).

## License

**Apache License 2.0** — see [LICENSE](LICENSE) for full text.
