Skip to content

Commit e40d840

Browse files
authored
Merge pull request #67 from JarbasHiveMind/release-0.4.2a1
Release 0.4.2a1
2 parents 89f4b2c + a8b418e commit e40d840

19 files changed

+223
-642
lines changed

.github/workflows/publish_stable.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: Setup Python
2727
uses: actions/setup-python@v1
2828
with:
29-
python-version: 3.8
29+
python-version: "3.11"
3030
- name: Install Build Tools
3131
run: |
3232
python -m pip install build wheel

.github/workflows/unit_tests.yml

Lines changed: 0 additions & 58 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,36 @@
11
# Changelog
22

3-
## [0.4.0a1](https://github.com/JarbasHiveMind/hivemind-websocket-client/tree/0.4.0a1) (2025-01-08)
3+
## [0.4.2a1](https://github.com/JarbasHiveMind/hivemind-websocket-client/tree/0.4.2a1) (2025-01-08)
44

5-
[Full Changelog](https://github.com/JarbasHiveMind/hivemind-websocket-client/compare/0.3.0a2...0.4.0a1)
5+
[Full Changelog](https://github.com/JarbasHiveMind/hivemind-websocket-client/compare/0.4.1a2...0.4.2a1)
6+
7+
**Closed issues:**
8+
9+
- Execution example in the readme raises an error [\#22](https://github.com/JarbasHiveMind/hivemind-websocket-client/issues/22)
610

711
**Merged pull requests:**
812

9-
- feat:http client [\#60](https://github.com/JarbasHiveMind/hivemind-websocket-client/pull/60) ([JarbasAl](https://github.com/JarbasAl))
13+
- fix: no auto connect [\#66](https://github.com/JarbasHiveMind/hivemind-websocket-client/pull/66) ([JarbasAl](https://github.com/JarbasAl))
1014

11-
## [0.3.0a2](https://github.com/JarbasHiveMind/hivemind-websocket-client/tree/0.3.0a2) (2025-01-03)
15+
## [0.4.1a2](https://github.com/JarbasHiveMind/hivemind-websocket-client/tree/0.4.1a2) (2025-01-08)
1216

13-
[Full Changelog](https://github.com/JarbasHiveMind/hivemind-websocket-client/compare/0.3.0a1...0.3.0a2)
17+
[Full Changelog](https://github.com/JarbasHiveMind/hivemind-websocket-client/compare/0.4.1a1...0.4.1a2)
1418

1519
**Merged pull requests:**
1620

17-
- chore:benchmark [\#57](https://github.com/JarbasHiveMind/hivemind-websocket-client/pull/57) ([JarbasAl](https://github.com/JarbasAl))
21+
- bring http client closes to websocket client [\#64](https://github.com/JarbasHiveMind/hivemind-websocket-client/pull/64) ([JarbasAl](https://github.com/JarbasAl))
22+
23+
## [0.4.1a1](https://github.com/JarbasHiveMind/hivemind-websocket-client/tree/0.4.1a1) (2025-01-08)
24+
25+
[Full Changelog](https://github.com/JarbasHiveMind/hivemind-websocket-client/compare/0.4.0...0.4.1a1)
1826

19-
## [0.3.0a1](https://github.com/JarbasHiveMind/hivemind-websocket-client/tree/0.3.0a1) (2025-01-03)
27+
**Closed issues:**
2028

21-
[Full Changelog](https://github.com/JarbasHiveMind/hivemind-websocket-client/compare/0.2.1...0.3.0a1)
29+
- Faster encodings [\#59](https://github.com/JarbasHiveMind/hivemind-websocket-client/issues/59)
2230

2331
**Merged pull requests:**
2432

25-
- feat:more encodings [\#55](https://github.com/JarbasHiveMind/hivemind-websocket-client/pull/55) ([JarbasAl](https://github.com/JarbasAl))
33+
- refactor: move to z85base91 package [\#62](https://github.com/JarbasHiveMind/hivemind-websocket-client/pull/62) ([JarbasAl](https://github.com/JarbasAl))
2634

2735

2836

README.md

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Hivemind Websocket Client
1+
# Hivemind Bus Client
22

3-
![logo](./logo.png)
3+
Python client library for [hivemind-core](https://github.com/JarbasHiveMind/HiveMind-core)
44

55
## Install
66

@@ -10,36 +10,88 @@ pip install hivemind_bus_client
1010

1111
## Usage
1212

13+
via [hivemind-http-protocol](https://github.com/JarbasHiveMind/hivemind-http-protocol)
14+
1315
```python
14-
from time import sleep
15-
from ovos_bus_client import Message
16-
from hivemind_bus_client import HiveMessageBusClient
17-
from hivemind_bus_client.decorators import on_escalate, \
18-
on_shared_bus, on_ping, on_broadcast, on_propagate, on_mycroft_message, \
19-
on_registry_opcode, on_third_party, on_cascade, on_handshake, on_hello, \
20-
on_rendezvous, on_hive_message, on_third_party, on_payload
16+
from hivemind_bus_client.http_client import HiveMindHTTPClient
2117

22-
key = "super_secret_access_key"
23-
crypto_key = "ivf1NQSkQNogWYyr"
18+
# not passing key etc so it uses identity file
19+
client = HiveMindHTTPClient(host="http://localhost", port=5679)
20+
client.connect() # establish a secure end-to-end encrypted connection
21+
```
2422

25-
bus = HiveMessageBusClient(key, crypto_key=crypto_key, ssl=False)
23+
via [hivemind-websocket-protocol](https://github.com/JarbasHiveMind/hivemind-websocket-protocol)
24+
```python
25+
from hivemind_bus_client.client import HiveMessageBusClient
2626

27-
bus.run_in_thread()
27+
# not passing key etc so it uses identity file
28+
client = HiveMessageBusClient(host="ws://localhost", port=5678)
29+
client.connect() # establish a secure end-to-end encrypted connection
30+
```
31+
32+
### Example: Simple Chat
33+
34+
```python
35+
import threading
36+
from ovos_bus_client.message import Message
37+
from hivemind_bus_client.message import HiveMessage, HiveMessageType
38+
from hivemind_bus_client.http_client import HiveMindHTTPClient
2839

40+
# not passing key etc so it uses identity file
41+
client = HiveMindHTTPClient(host="http://localhost", port=5679)
2942

30-
@on_mycroft_message(payload_type="speak", bus=bus)
31-
def on_speak(msg):
32-
print(msg.data["utterance"])
43+
# to handle agent responses, use client.on_mycroft("event", handler)
44+
answered = threading.Event()
3345

46+
def handle_speak(message: Message):
47+
print(message.data['utterance'])
3448

35-
mycroft_msg = Message("recognizer_loop:utterance",
36-
{"utterances": ["tell me a joke"]})
37-
bus.emit_mycroft(mycroft_msg)
49+
def utt_handled(message: Message):
50+
answered.set()
3851

52+
client.on_mycroft("speak", handle_speak)
53+
client.on_mycroft("ovos.utterance.handled", utt_handled)
3954

40-
sleep(50)
4155

42-
bus.close()
56+
while True:
57+
utt = input("> ")
58+
answered.clear()
59+
client.emit(HiveMessage(HiveMessageType.BUS,
60+
Message("recognizer_loop:utterance", {"utterances": [utt]})))
61+
answered.wait()
62+
```
63+
64+
### Example: Remote TTS
65+
66+
if server is running [hivemind-audio-binary-protocol](https://github.com/JarbasHiveMind/hivemind-audio-binary-protocol)
67+
68+
```python
69+
from ovos_bus_client.message import Message
70+
from hivemind_bus_client.client import BinaryDataCallbacks
71+
from hivemind_bus_client.message import HiveMessage, HiveMessageType
72+
from hivemind_bus_client.http_client import HiveMindHTTPClient
73+
74+
# To handle binary data subclass BinaryDataCallbacks
75+
class BinaryDataHandler(BinaryDataCallbacks):
76+
def handle_receive_tts(self, bin_data: bytes,
77+
utterance: str,
78+
lang: str,
79+
file_name: str):
80+
# we can play it or save to file or whatever
81+
print(f"got {len(bin_data)} bytes of TTS audio")
82+
print(f"utterance: {utterance}", f"lang: {lang}", f"file_name: {file_name}")
83+
# got 33836 bytes of TTS audio
84+
# utterance: hello world lang: en-US file_name: 5eb63bbbe01eeed093cb22bb8f5acdc3.wav
85+
86+
87+
# not passing key etc so it uses identity file
88+
client = HiveMindHTTPClient(host="http://localhost", port=5679,
89+
bin_callbacks=BinaryDataHandler())
90+
91+
# send HiveMessages as usual
92+
client.emit(HiveMessage(HiveMessageType.BUS,
93+
Message("speak:synth", {"utterance": "hello world"})))
94+
4395
```
4496

4597
## Cli Usage
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1-
from hivemind_bus_client.encodings.z85b import Z85B
2-
from hivemind_bus_client.encodings.z85p import Z85P
3-
from hivemind_bus_client.encodings.b91 import B91
1+
from z85base91 import Z85B, Z85P, B91
2+
import warnings
3+
4+
# Deprecation warning
5+
warnings.warn(
6+
"Importing from hivemind_bus_client.encodings is deprecated and will be removed in a future release. "
7+
"Please update your code to use the new package 'z85base91'",
8+
DeprecationWarning,
9+
stacklevel=2,
10+
)

hivemind_bus_client/encodings/b91.py

Lines changed: 10 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,10 @@
1-
from typing import Union
2-
3-
4-
class B91:
5-
ALPHABET = [
6-
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
7-
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
8-
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
9-
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
10-
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '#', '$',
11-
'%', '&', '(', ')', '*', '+', ',', '.', '/', ':', ';', '<', '=',
12-
'>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '"'
13-
]
14-
15-
DECODE_TABLE = {char: idx for idx, char in enumerate(ALPHABET)}
16-
17-
@classmethod
18-
def decode(cls, encoded_data: Union[str, bytes], encoding: str = "utf-8") -> bytes:
19-
"""
20-
Decodes a Base91-encoded string into its original binary form.
21-
22-
Args:
23-
encoded_data (Union[str, bytes]): Base91-encoded input data. If `bytes`, it is decoded as UTF-8.
24-
encoding (str): The encoding to use if `encoded_data` is provided as a string. Default is 'utf-8'.
25-
26-
Returns:
27-
bytes: The decoded binary data.
28-
29-
Raises:
30-
ValueError: If the input contains invalid Base91 characters.
31-
"""
32-
if isinstance(encoded_data, bytes):
33-
encoded_data = encoded_data.decode(encoding)
34-
35-
v = -1
36-
b = 0
37-
n = 0
38-
out = bytearray()
39-
40-
for char in encoded_data:
41-
if char not in cls.DECODE_TABLE:
42-
raise ValueError(f"Invalid Base91 character: {char}")
43-
c = cls.DECODE_TABLE[char]
44-
if v < 0:
45-
v = c
46-
else:
47-
v += c * 91
48-
b |= v << n
49-
n += 13 if (v & 8191) > 88 else 14
50-
while n >= 8:
51-
out.append(b & 255)
52-
b >>= 8
53-
n -= 8
54-
v = -1
55-
56-
if v >= 0:
57-
out.append((b | v << n) & 255)
58-
59-
return bytes(out)
60-
61-
@classmethod
62-
def encode(cls, data: Union[bytes, str], encoding: str = "utf-8") -> bytes:
63-
"""
64-
Encodes binary data into a Base91-encoded string.
65-
66-
Args:
67-
data (Union[bytes, str]): Input binary data to encode. If `str`, it is encoded as UTF-8.
68-
encoding (str): The encoding to use if `data` is provided as a string. Default is 'utf-8'.
69-
70-
Returns:
71-
str: The Base91-encoded string.
72-
"""
73-
if isinstance(data, str):
74-
data = data.encode(encoding)
75-
76-
b = 0
77-
n = 0
78-
out = []
79-
80-
for byte in data:
81-
b |= byte << n
82-
n += 8
83-
if n > 13:
84-
v = b & 8191
85-
if v > 88:
86-
b >>= 13
87-
n -= 13
88-
else:
89-
v = b & 16383
90-
b >>= 14
91-
n -= 14
92-
out.append(cls.ALPHABET[v % 91])
93-
out.append(cls.ALPHABET[v // 91])
94-
95-
if n:
96-
out.append(cls.ALPHABET[b % 91])
97-
if n > 7 or b > 90:
98-
out.append(cls.ALPHABET[b // 91])
99-
100-
return ''.join(out).encode(encoding)
1+
from z85base91 import B91
2+
import warnings
3+
4+
# Deprecation warning
5+
warnings.warn(
6+
"Importing from hivemind_bus_client.encodings is deprecated and will be removed in a future release. "
7+
"Please update your code to use the new package 'z85base91'",
8+
DeprecationWarning,
9+
stacklevel=2,
10+
)

hivemind_bus_client/encodings/benchmark.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import click
1111
import pybase64
1212

13-
from hivemind_bus_client.encodings import Z85B, B91, Z85P
13+
from z85base91 import Z85B, B91, Z85P
1414
from hivemind_bus_client.exceptions import InvalidEncoding
1515

1616
performance_weight = 0.5

0 commit comments

Comments
 (0)