# Python FunASR-Client
[](https://github.com/atomiechen/FunASR-Client)
[](https://pypi.org/project/funasr-client/)
Really easy-to-use Python client for [FunASR][1] runtime server.
To deploy your own FunASR server, follow the [FunASR runtime guide][2], or use the improved startup scripts [here][3].
## Features
- ☯️ Both synchronous and asynchronous (`async`) support everywhere
- 💻 Both Command Line Interface (CLI) and Python API
- 🔤 Auto decoding of messages with real timestamps (`FunASRMessageDecoded`)
- 🎙️ Real-time audio recognition from a microphone (`mic_asr`)
- 🎵 File-based audio recognition (`file_asr`)
## Installation
Install directly from PyPI:
```bash
pip install funasr-client
```
If you want to use the microphone (`pyaudio`) for real-time recognition, install with:
```bash
pip install "funasr-client[mic]"
```
Install from github for the latest updates:
```bash
pip install "git+https://github.com/atomiechen/FunASR-Client.git"
```
## CLI
The CLI `funasr-client` or `python -m funasr_client` supports either real-time microphone input or file input for ASR, and outputs the recognized results in JSON (file) or JSON Lines (mic) format.
<details>
<summary>View all CLI options by specifying <code>-h</code>.</summary>
```
usage: funasr-client [-h] [-v] [--mode MODE] [--chunk_size P C F] [--chunk_interval CHUNK_INTERVAL] [--audio_fs AUDIO_FS]
[--hotwords WORD:WEIGHT [WORD:WEIGHT ...]] [--no-itn] [--svs_lang SVS_LANG] [--no-svs_itn] [--async]
URI [FILE_PATH]
FunASR Client CLI v0.1.0. Use microphone for real-time recognition (needs pyaudio), or specify input audio file.
positional arguments:
URI WebSocket URI to connect to the FunASR server.
FILE_PATH Optional input audio file path (suppress microphone). (default: None)
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
--mode MODE offline, online, 2pass (default: 2pass)
--chunk_size P C F Chunk size: past, current, future. (default: [5, 10, 5])
--chunk_interval CHUNK_INTERVAL
Chunk interval. (default: 10)
--audio_fs AUDIO_FS Audio sampling frequency. (default: 16000)
--hotwords WORD:WEIGHT [WORD:WEIGHT ...]
Hotwords with weights, e.g., 'hello:10 world:5'. (default: [])
--no-itn Disable ITN (default: True)
--svs_lang SVS_LANG SVS language. (default: auto)
--no-svs_itn Disable SVS ITN (default: True)
--async Use asynchronous client. (default: False)
```
</details>
### Microphone Real-time ASR
Requires `pyaudio` for microphone support (install it using `pip install "funasr-client[mic]"`).
```sh
funasr-client ws://localhost:10096
```
### File ASR
```sh
funasr-client ws://localhost:10096 path/to/audio.wav
```
## Python API
Sync API (`funasr_client`):
```python
from funasr_client import funasr_client
with funasr_client("ws://localhost:10096") as client:
@client.on_message
def callback(msg):
print("Received:", msg)
```
Async API (`async_funasr_client`):
```python
from funasr_client import async_funasr_client
async def main():
async with async_funasr_client("ws://localhost:10096") as client:
# NOTE: sync callback is also supported
@client.on_message
async def callback(msg):
print("Received:", msg)
```
See scripts in the [examples directory](examples/) for real-world usage.
### Registering Callbacks in non-blocking mode
By default, the client runs in non-blocking mode, which allows you to continue using your program while waiting for ASR results.
It starts a background loop in a thread (sync) or an async task (async) to handle incoming messages.
Two ways to register message callbacks (**both** sync and async are supported):
1. Using `@client.on_message` decorator (like shown above).
2. Passing `callback` handler to the constructor.
```python
funasr_client(
...
callback=lambda msg: print(msg)
)
```
> [!NOTE]
> Sync callback in async client will be run in a thread pool executor.
### Blocking Mode
To run in blocking mode (disable background loop), pass `blocking=True` to the client constructor.
It is your responsibility to call `client.stream()` or `client.recv()` to receive messages.
Use `client.stream()` (async) generator to receive messages in a loop:
```python
from funasr_client import funasr_client
with funasr_client("ws://localhost:10096", blocking=True) as client:
for msg in client.stream():
print("Received:", msg)
```
Or, use the low-level `client.recv()` method to receive messages one by one:
```python
from funasr_client import funasr_client
with funasr_client("ws://localhost:10096", blocking=True) as client:
while True:
msg = client.recv()
if msg is None:
break
print("Received:", msg)
```
### Decoding Messages
By default, the client decodes response messages into `FunASRMessageDecoded` dicts, which parses `timestamps` JSON string into a list.
If `start_time` (int in ms) is provided to the client, `real_timestamp` and `real_stamp_sents` will be calculated and added to the decoded message.
To disable decoding, pass `decode=False` to the constructor to get original dict object.
### Microphone Real-time ASR
Open a microphone stream and get the stream of **decoded** messages (`mic_asr` / `async_mic_asr`):
```python
from funasr_client import mic_asr
with mic_asr("ws://localhost:10096") as msg_gen:
for msg in msg_gen:
print("Received:", msg)
```
### File ASR
Get the final result as a **merged decoded** message (`file_asr` / `async_file_asr`):
```python
from funasr_client import file_asr
result = file_asr("path/to/audio.wav", "ws://localhost:10096")
print(result)
```
Or, get the stream of **decoded or original** (depends on `decode` option) messages (`file_asr_stream` / `async_file_asr_stream`):
```python
from funasr_client import file_asr_stream
with file_asr_stream("path/to/audio.wav", "ws://localhost:10096") as msg_gen:
for msg in msg_gen:
print("Received:", msg)
```
[1]: https://github.com/modelscope/FunASR
[2]: https://github.com/modelscope/FunASR/blob/main/runtime/readme.md
[3]: https://gist.github.com/atomiechen/2deaf80dba21b4434ab21d6bf656fbca
Raw data
{
"_id": null,
"home_page": null,
"name": "funasr-client",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "asr, asynchronous, asyncio, funasr, funasr-client, websocket, websockets",
"author": null,
"author_email": "Atomie CHEN <atomic_cwh@163.com>",
"download_url": "https://files.pythonhosted.org/packages/44/7c/7fc9fb323701c5be1c67965446f91b2260b0432efb376f072af19b81ad75/funasr_client-0.1.2.tar.gz",
"platform": null,
"description": "# Python FunASR-Client\n\n[](https://github.com/atomiechen/FunASR-Client)\n[](https://pypi.org/project/funasr-client/)\n\n\nReally easy-to-use Python client for [FunASR][1] runtime server.\n\nTo deploy your own FunASR server, follow the [FunASR runtime guide][2], or use the improved startup scripts [here][3].\n\n## Features\n\n- \u262f\ufe0f Both synchronous and asynchronous (`async`) support everywhere\n- \ud83d\udcbb Both Command Line Interface (CLI) and Python API\n- \ud83d\udd24 Auto decoding of messages with real timestamps (`FunASRMessageDecoded`)\n- \ud83c\udf99\ufe0f Real-time audio recognition from a microphone (`mic_asr`)\n- \ud83c\udfb5 File-based audio recognition (`file_asr`)\n\n\n## Installation\n\nInstall directly from PyPI:\n\n```bash\npip install funasr-client\n```\n\nIf you want to use the microphone (`pyaudio`) for real-time recognition, install with:\n\n```bash\npip install \"funasr-client[mic]\"\n```\n\nInstall from github for the latest updates:\n\n```bash\npip install \"git+https://github.com/atomiechen/FunASR-Client.git\"\n```\n\n## CLI\n\nThe CLI `funasr-client` or `python -m funasr_client` supports either real-time microphone input or file input for ASR, and outputs the recognized results in JSON (file) or JSON Lines (mic) format.\n\n\n<details>\n<summary>View all CLI options by specifying <code>-h</code>.</summary>\n\n```\nusage: funasr-client [-h] [-v] [--mode MODE] [--chunk_size P C F] [--chunk_interval CHUNK_INTERVAL] [--audio_fs AUDIO_FS]\n [--hotwords WORD:WEIGHT [WORD:WEIGHT ...]] [--no-itn] [--svs_lang SVS_LANG] [--no-svs_itn] [--async]\n URI [FILE_PATH]\n\nFunASR Client CLI v0.1.0. Use microphone for real-time recognition (needs pyaudio), or specify input audio file.\n\npositional arguments:\n URI WebSocket URI to connect to the FunASR server.\n FILE_PATH Optional input audio file path (suppress microphone). (default: None)\n\noptional arguments:\n -h, --help show this help message and exit\n -v, --version show program's version number and exit\n --mode MODE offline, online, 2pass (default: 2pass)\n --chunk_size P C F Chunk size: past, current, future. (default: [5, 10, 5])\n --chunk_interval CHUNK_INTERVAL\n Chunk interval. (default: 10)\n --audio_fs AUDIO_FS Audio sampling frequency. (default: 16000)\n --hotwords WORD:WEIGHT [WORD:WEIGHT ...]\n Hotwords with weights, e.g., 'hello:10 world:5'. (default: [])\n --no-itn Disable ITN (default: True)\n --svs_lang SVS_LANG SVS language. (default: auto)\n --no-svs_itn Disable SVS ITN (default: True)\n --async Use asynchronous client. (default: False)\n```\n\n</details>\n\n### Microphone Real-time ASR\n\nRequires `pyaudio` for microphone support (install it using `pip install \"funasr-client[mic]\"`).\n\n```sh\nfunasr-client ws://localhost:10096\n```\n\n### File ASR\n\n```sh\nfunasr-client ws://localhost:10096 path/to/audio.wav\n```\n\n\n## Python API\n\nSync API (`funasr_client`):\n```python\nfrom funasr_client import funasr_client\n\nwith funasr_client(\"ws://localhost:10096\") as client:\n @client.on_message\n def callback(msg):\n print(\"Received:\", msg)\n```\n\nAsync API (`async_funasr_client`):\n```python\nfrom funasr_client import async_funasr_client\n\nasync def main():\n async with async_funasr_client(\"ws://localhost:10096\") as client:\n # NOTE: sync callback is also supported\n @client.on_message\n async def callback(msg):\n print(\"Received:\", msg)\n```\n\nSee scripts in the [examples directory](examples/) for real-world usage.\n\n### Registering Callbacks in non-blocking mode\n\nBy default, the client runs in non-blocking mode, which allows you to continue using your program while waiting for ASR results. \nIt starts a background loop in a thread (sync) or an async task (async) to handle incoming messages.\n\nTwo ways to register message callbacks (**both** sync and async are supported):\n1. Using `@client.on_message` decorator (like shown above).\n2. Passing `callback` handler to the constructor.\n ```python\n funasr_client(\n ...\n callback=lambda msg: print(msg)\n )\n ```\n\n> [!NOTE] \n> Sync callback in async client will be run in a thread pool executor.\n\n\n### Blocking Mode\n\nTo run in blocking mode (disable background loop), pass `blocking=True` to the client constructor.\nIt is your responsibility to call `client.stream()` or `client.recv()` to receive messages.\n\nUse `client.stream()` (async) generator to receive messages in a loop:\n\n```python\nfrom funasr_client import funasr_client\nwith funasr_client(\"ws://localhost:10096\", blocking=True) as client:\n for msg in client.stream():\n print(\"Received:\", msg)\n```\n\nOr, use the low-level `client.recv()` method to receive messages one by one:\n\n```python\nfrom funasr_client import funasr_client\nwith funasr_client(\"ws://localhost:10096\", blocking=True) as client:\n while True:\n msg = client.recv()\n if msg is None:\n break\n print(\"Received:\", msg)\n```\n\n\n### Decoding Messages\n\nBy default, the client decodes response messages into `FunASRMessageDecoded` dicts, which parses `timestamps` JSON string into a list.\nIf `start_time` (int in ms) is provided to the client, `real_timestamp` and `real_stamp_sents` will be calculated and added to the decoded message.\n\nTo disable decoding, pass `decode=False` to the constructor to get original dict object.\n\n\n### Microphone Real-time ASR\n\nOpen a microphone stream and get the stream of **decoded** messages (`mic_asr` / `async_mic_asr`):\n\n```python\nfrom funasr_client import mic_asr\nwith mic_asr(\"ws://localhost:10096\") as msg_gen:\n for msg in msg_gen:\n print(\"Received:\", msg)\n```\n\n### File ASR\n\nGet the final result as a **merged decoded** message (`file_asr` / `async_file_asr`):\n\n```python\nfrom funasr_client import file_asr\n\nresult = file_asr(\"path/to/audio.wav\", \"ws://localhost:10096\")\nprint(result)\n```\n\nOr, get the stream of **decoded or original** (depends on `decode` option) messages (`file_asr_stream` / `async_file_asr_stream`):\n\n```python\nfrom funasr_client import file_asr_stream\n\nwith file_asr_stream(\"path/to/audio.wav\", \"ws://localhost:10096\") as msg_gen:\n for msg in msg_gen:\n print(\"Received:\", msg)\n```\n\n\n[1]: https://github.com/modelscope/FunASR\n[2]: https://github.com/modelscope/FunASR/blob/main/runtime/readme.md\n[3]: https://gist.github.com/atomiechen/2deaf80dba21b4434ab21d6bf656fbca\n",
"bugtrack_url": null,
"license": null,
"summary": "Easy-to-use client for FunASR runtime server.",
"version": "0.1.2",
"project_urls": {
"changelog": "https://github.com/atomiechen/FunASR-Client/blob/main/CHANGELOG.md",
"homepage": "https://github.com/atomiechen/FunASR-Client",
"issues": "https://github.com/atomiechen/FunASR-Client/issues"
},
"split_keywords": [
"asr",
" asynchronous",
" asyncio",
" funasr",
" funasr-client",
" websocket",
" websockets"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "016156fb21e6ee6d04fde312095f0754d35fc3e04ce35a704d65672bbb39c653",
"md5": "dc5eed851691078ed52779063750cd61",
"sha256": "ca5be3e0ff76f477f2430482cd26c9e3bf610009dd4b770ff5b7871068c04798"
},
"downloads": -1,
"filename": "funasr_client-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "dc5eed851691078ed52779063750cd61",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 19426,
"upload_time": "2025-08-05T04:08:30",
"upload_time_iso_8601": "2025-08-05T04:08:30.822147Z",
"url": "https://files.pythonhosted.org/packages/01/61/56fb21e6ee6d04fde312095f0754d35fc3e04ce35a704d65672bbb39c653/funasr_client-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "447c7fc9fb323701c5be1c67965446f91b2260b0432efb376f072af19b81ad75",
"md5": "7423d3adff0143dc8c8710a3d0673968",
"sha256": "8325904480e9b78a5b75f6fe91c4b2de06b8b7e75408627c0ded35b732bc8277"
},
"downloads": -1,
"filename": "funasr_client-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "7423d3adff0143dc8c8710a3d0673968",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 44490,
"upload_time": "2025-08-05T04:08:32",
"upload_time_iso_8601": "2025-08-05T04:08:32.022257Z",
"url": "https://files.pythonhosted.org/packages/44/7c/7fc9fb323701c5be1c67965446f91b2260b0432efb376f072af19b81ad75/funasr_client-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-05 04:08:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "atomiechen",
"github_project": "FunASR-Client",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "funasr-client"
}