feat: add meshnet python sdk
This commit is contained in:
143
tests/test_meshnet_sdk.py
Normal file
143
tests/test_meshnet_sdk.py
Normal file
@@ -0,0 +1,143 @@
|
||||
"""US-010 integration tests: typed meshnet SDK over local gateway/tracker/nodes."""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
|
||||
from meshnet import Client
|
||||
from meshnet_contracts import LocalSolanaContracts
|
||||
from meshnet_gateway.server import GatewayServer, _payment_address_for_api_key
|
||||
from meshnet_node.server import StubNodeServer
|
||||
from meshnet_tracker.server import TrackerServer, _NodeEntry, _coverage_percentage
|
||||
|
||||
|
||||
def test_sdk_support_helpers_are_deterministic_without_network():
|
||||
"""Non-socket coverage for SDK-facing gateway/tracker helper behavior."""
|
||||
address = _payment_address_for_api_key("sdk-key")
|
||||
nodes = [
|
||||
_NodeEntry("a", "http://node-a", 0, 15, "stub-model", None, {}, None, 1.0),
|
||||
_NodeEntry("b", "http://node-b", 16, 31, "stub-model", None, {}, None, 1.0),
|
||||
]
|
||||
|
||||
assert 32 <= len(address) <= 44
|
||||
assert _coverage_percentage(nodes, 0, 31) == 100.0
|
||||
|
||||
|
||||
def _post_json(url: str, payload: dict) -> dict:
|
||||
data = json.dumps(payload).encode()
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
data=data,
|
||||
headers={"Content-Type": "application/json"},
|
||||
method="POST",
|
||||
)
|
||||
with urllib.request.urlopen(req) as r:
|
||||
return json.loads(r.read())
|
||||
|
||||
|
||||
def _register_node(
|
||||
tracker_url: str,
|
||||
endpoint: str,
|
||||
shard_start: int,
|
||||
shard_end: int,
|
||||
*,
|
||||
wallet_address: str,
|
||||
) -> None:
|
||||
_post_json(
|
||||
f"{tracker_url}/v1/nodes/register",
|
||||
{
|
||||
"endpoint": endpoint,
|
||||
"shard_start": shard_start,
|
||||
"shard_end": shard_end,
|
||||
"hardware_profile": {},
|
||||
"wallet_address": wallet_address,
|
||||
"score": 1.0,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_meshnet_sdk_methods_against_local_network():
|
||||
"""SDK covers OpenAI chat passthrough plus meshnet wallet/model/cost/request APIs."""
|
||||
contracts = LocalSolanaContracts(starting_credit_lamports=0)
|
||||
contracts.payment.fund_api_key("sdk-key", lamports=2_000_000_000, usdc_micro=123_000_000)
|
||||
|
||||
tracker = TrackerServer(contracts=contracts)
|
||||
tracker_port = tracker.start()
|
||||
tracker_url = f"http://127.0.0.1:{tracker_port}"
|
||||
|
||||
nodes = [
|
||||
StubNodeServer(shard_start=0, shard_end=15, is_last_shard=False),
|
||||
StubNodeServer(shard_start=16, shard_end=31, is_last_shard=True),
|
||||
StubNodeServer(shard_start=0, shard_end=15, is_last_shard=False),
|
||||
StubNodeServer(shard_start=16, shard_end=31, is_last_shard=True),
|
||||
]
|
||||
node_ports = [node.start() for node in nodes]
|
||||
|
||||
for index, (port, shard_start, shard_end) in enumerate(
|
||||
[
|
||||
(node_ports[0], 0, 15),
|
||||
(node_ports[1], 16, 31),
|
||||
(node_ports[2], 0, 15),
|
||||
(node_ports[3], 16, 31),
|
||||
],
|
||||
start=1,
|
||||
):
|
||||
_register_node(
|
||||
tracker_url,
|
||||
f"http://127.0.0.1:{port}",
|
||||
shard_start,
|
||||
shard_end,
|
||||
wallet_address=f"wallet-{index}",
|
||||
)
|
||||
|
||||
gateway = GatewayServer(tracker_url=tracker_url, contracts=contracts)
|
||||
gateway_port = gateway.start()
|
||||
gateway_url = f"http://127.0.0.1:{gateway_port}"
|
||||
|
||||
try:
|
||||
client = Client(api_key="sdk-key", base_url=gateway_url)
|
||||
|
||||
chat_response = client.chat.completions.create(
|
||||
model="stub-model",
|
||||
messages=[{"role": "user", "content": "hello sdk"}],
|
||||
)
|
||||
assert chat_response.choices[0].message.content == "stub response to: hello sdk"
|
||||
|
||||
balance = client.wallet.balance()
|
||||
assert balance.sol == 2.0
|
||||
assert balance.usdc == 123.0
|
||||
|
||||
top_up = client.wallet.top_up(amount_sol=1.0)
|
||||
assert top_up.amount_sol == 1.0
|
||||
assert 32 <= len(top_up.payment_address) <= 44
|
||||
assert top_up.qr.startswith("solana:")
|
||||
|
||||
available_models = client.models.available()
|
||||
assert available_models == [
|
||||
{
|
||||
"id": "stub-model",
|
||||
"shard_coverage_percentage": 100.0,
|
||||
}
|
||||
]
|
||||
|
||||
estimate = client.estimate_cost(model="stub-model", tokens=1_000)
|
||||
assert estimate.model == "stub-model"
|
||||
assert estimate.tokens == 1_000
|
||||
assert estimate.sol == 0.000032
|
||||
|
||||
redundant = client.request(
|
||||
model="stub-model",
|
||||
messages=[{"role": "user", "content": "redundant"}],
|
||||
redundancy=2,
|
||||
)
|
||||
assert redundant.redundancy == 2
|
||||
assert redundant.majority_response.choices[0].message.content == (
|
||||
"stub response to: redundant"
|
||||
)
|
||||
assert len(redundant.responses) == 2
|
||||
assert nodes[1].received_activations
|
||||
assert nodes[3].received_activations
|
||||
finally:
|
||||
gateway.stop()
|
||||
for node in nodes:
|
||||
node.stop()
|
||||
tracker.stop()
|
||||
Reference in New Issue
Block a user