Run Black on veilid-python
This commit is contained in:
parent
86a5accb1a
commit
d9d03885d9
@ -17,3 +17,9 @@ pytest-asyncio = "^0.21.0"
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 99
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
check_untyped_defs = true
|
@ -27,9 +27,7 @@ async def test_get_node_id(api_connection: veilid.VeilidAPI):
|
|||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_fail_connect():
|
async def test_fail_connect():
|
||||||
with pytest.raises(socket.gaierror) as exc:
|
with pytest.raises(socket.gaierror) as exc:
|
||||||
await veilid.json_api_connect(
|
await veilid.json_api_connect("fuahwelifuh32luhwafluehawea", 1, simple_update_callback)
|
||||||
"fuahwelifuh32luhwafluehawea", 1, simple_update_callback
|
|
||||||
)
|
|
||||||
|
|
||||||
assert exc.value.errno == socket.EAI_NONAME
|
assert exc.value.errno == socket.EAI_NONAME
|
||||||
|
|
||||||
|
@ -12,14 +12,13 @@ async def test_best_crypto_system(api_connection: veilid.VeilidAPI):
|
|||||||
async with cs:
|
async with cs:
|
||||||
assert await cs.default_salt_length() == 16
|
assert await cs.default_salt_length() == 16
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_get_crypto_system(api_connection: veilid.VeilidAPI):
|
async def test_get_crypto_system(api_connection: veilid.VeilidAPI):
|
||||||
cs: CryptoSystem = await api_connection.get_crypto_system(
|
cs: CryptoSystem = await api_connection.get_crypto_system(veilid.CryptoKind.CRYPTO_KIND_VLD0)
|
||||||
veilid.CryptoKind.CRYPTO_KIND_VLD0
|
|
||||||
)
|
|
||||||
async with cs:
|
async with cs:
|
||||||
assert await cs.default_salt_length() == 16
|
assert await cs.default_salt_length() == 16
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_get_crypto_system_invalid(api_connection: veilid.VeilidAPI):
|
async def test_get_crypto_system_invalid(api_connection: veilid.VeilidAPI):
|
||||||
@ -45,4 +44,3 @@ async def test_hash_and_verify_password(api_connection: veilid.VeilidAPI):
|
|||||||
# Password mismatch
|
# Password mismatch
|
||||||
phash2 = await cs.hash_password(b"abc1234", salt)
|
phash2 = await cs.hash_password(b"abc1234", salt)
|
||||||
assert not await cs.verify_password(b"abc12345", phash)
|
assert not await cs.verify_password(b"abc12345", phash)
|
||||||
|
|
||||||
|
@ -47,7 +47,9 @@ async def test_delete_dht_record_nonexistent(api_connection: veilid.VeilidAPI):
|
|||||||
async def test_create_delete_dht_record_simple(api_connection: veilid.VeilidAPI):
|
async def test_create_delete_dht_record_simple(api_connection: veilid.VeilidAPI):
|
||||||
rc = await api_connection.new_routing_context()
|
rc = await api_connection.new_routing_context()
|
||||||
async with rc:
|
async with rc:
|
||||||
rec = await rc.create_dht_record(veilid.DHTSchema.dflt(1), veilid.CryptoKind.CRYPTO_KIND_VLD0)
|
rec = await rc.create_dht_record(
|
||||||
|
veilid.DHTSchema.dflt(1), veilid.CryptoKind.CRYPTO_KIND_VLD0
|
||||||
|
)
|
||||||
await rc.close_dht_record(rec.key)
|
await rc.close_dht_record(rec.key)
|
||||||
await rc.delete_dht_record(rec.key)
|
await rc.delete_dht_record(rec.key)
|
||||||
|
|
||||||
|
@ -34,9 +34,7 @@ async def test_routing_contexts(api_connection: veilid.VeilidAPI):
|
|||||||
|
|
||||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(
|
rc = await (await api_connection.new_routing_context()).with_custom_privacy(
|
||||||
veilid.SafetySelection.safe(
|
veilid.SafetySelection.safe(
|
||||||
veilid.SafetySpec(
|
veilid.SafetySpec(None, 2, veilid.Stability.RELIABLE, veilid.Sequencing.ENSURE_ORDERED)
|
||||||
None, 2, veilid.Stability.RELIABLE, veilid.Sequencing.ENSURE_ORDERED
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await rc.release()
|
await rc.release()
|
||||||
@ -117,14 +115,10 @@ async def test_routing_context_app_call_loopback():
|
|||||||
|
|
||||||
# send an app message to our own private route
|
# send an app message to our own private route
|
||||||
request = b"abcd1234"
|
request = b"abcd1234"
|
||||||
app_call_task = asyncio.create_task(
|
app_call_task = asyncio.create_task(rc.app_call(prr, request), name="app call task")
|
||||||
rc.app_call(prr, request), name="app call task"
|
|
||||||
)
|
|
||||||
|
|
||||||
# we should get the same request back
|
# we should get the same request back
|
||||||
update: veilid.VeilidUpdate = await asyncio.wait_for(
|
update: veilid.VeilidUpdate = await asyncio.wait_for(app_call_queue.get(), timeout=10)
|
||||||
app_call_queue.get(), timeout=10
|
|
||||||
)
|
|
||||||
appcall = update.detail
|
appcall = update.detail
|
||||||
|
|
||||||
assert isinstance(appcall, veilid.VeilidAppCall)
|
assert isinstance(appcall, veilid.VeilidAppCall)
|
||||||
@ -164,9 +158,9 @@ async def test_routing_context_app_message_loopback_big_packets():
|
|||||||
await api.debug("purge routes")
|
await api.debug("purge routes")
|
||||||
|
|
||||||
# make a routing context that uses a safety route
|
# make a routing context that uses a safety route
|
||||||
rc = await (
|
rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(
|
||||||
await (await api.new_routing_context()).with_privacy()
|
veilid.Sequencing.ENSURE_ORDERED
|
||||||
).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
)
|
||||||
async with rc:
|
async with rc:
|
||||||
# make a new local private route
|
# make a new local private route
|
||||||
prl, blob = await api.new_private_route()
|
prl, blob = await api.new_private_route()
|
||||||
@ -223,14 +217,12 @@ async def test_routing_context_app_call_loopback_big_packets():
|
|||||||
# purge routes to ensure we start fresh
|
# purge routes to ensure we start fresh
|
||||||
await api.debug("purge routes")
|
await api.debug("purge routes")
|
||||||
|
|
||||||
app_call_task = asyncio.create_task(
|
app_call_task = asyncio.create_task(app_call_queue_task_handler(api), name="app call task")
|
||||||
app_call_queue_task_handler(api), name="app call task"
|
|
||||||
)
|
|
||||||
|
|
||||||
# make a routing context that uses a safety route
|
# make a routing context that uses a safety route
|
||||||
rc = await (
|
rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(
|
||||||
await (await api.new_routing_context()).with_privacy()
|
veilid.Sequencing.ENSURE_ORDERED
|
||||||
).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
)
|
||||||
async with rc:
|
async with rc:
|
||||||
# make a new local private route
|
# make a new local private route
|
||||||
prl, blob = await api.new_private_route()
|
prl, blob = await api.new_private_route()
|
||||||
@ -249,9 +241,7 @@ async def test_routing_context_app_call_loopback_big_packets():
|
|||||||
app_call_task.cancel()
|
app_call_task.cancel()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(os.getenv("NOSKIP") != "1", reason="unneeded test, only for performance check")
|
||||||
os.getenv("NOSKIP") != "1", reason="unneeded test, only for performance check"
|
|
||||||
)
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_routing_context_app_message_loopback_bandwidth():
|
async def test_routing_context_app_message_loopback_bandwidth():
|
||||||
app_message_queue: asyncio.Queue = asyncio.Queue()
|
app_message_queue: asyncio.Queue = asyncio.Queue()
|
||||||
|
@ -8,6 +8,7 @@ from veilid.api import CryptoSystem
|
|||||||
TEST_DB = "__pytest_db"
|
TEST_DB = "__pytest_db"
|
||||||
TEST_NONEXISTENT_DB = "__pytest_nonexistent_db"
|
TEST_NONEXISTENT_DB = "__pytest_nonexistent_db"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_delete_table_db_nonexistent(api_connection: veilid.VeilidAPI):
|
async def test_delete_table_db_nonexistent(api_connection: veilid.VeilidAPI):
|
||||||
deleted = await api_connection.delete_table_db(TEST_NONEXISTENT_DB)
|
deleted = await api_connection.delete_table_db(TEST_NONEXISTENT_DB)
|
||||||
@ -25,11 +26,12 @@ async def test_open_delete_table_db(api_connection: veilid.VeilidAPI):
|
|||||||
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
||||||
await api_connection.delete_table_db(TEST_DB)
|
await api_connection.delete_table_db(TEST_DB)
|
||||||
# drop the db
|
# drop the db
|
||||||
|
|
||||||
# now delete should succeed
|
# now delete should succeed
|
||||||
deleted = await api_connection.delete_table_db(TEST_DB)
|
deleted = await api_connection.delete_table_db(TEST_DB)
|
||||||
assert deleted
|
assert deleted
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_open_twice_table_db(api_connection: veilid.VeilidAPI):
|
async def test_open_twice_table_db(api_connection: veilid.VeilidAPI):
|
||||||
# delete test db if it exists
|
# delete test db if it exists
|
||||||
@ -37,12 +39,12 @@ async def test_open_twice_table_db(api_connection: veilid.VeilidAPI):
|
|||||||
|
|
||||||
tdb = await api_connection.open_table_db(TEST_DB, 1)
|
tdb = await api_connection.open_table_db(TEST_DB, 1)
|
||||||
tdb2 = await api_connection.open_table_db(TEST_DB, 1)
|
tdb2 = await api_connection.open_table_db(TEST_DB, 1)
|
||||||
|
|
||||||
# delete should fail because open
|
# delete should fail because open
|
||||||
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
||||||
await api_connection.delete_table_db(TEST_DB)
|
await api_connection.delete_table_db(TEST_DB)
|
||||||
await tdb.release()
|
await tdb.release()
|
||||||
|
|
||||||
# delete should fail because open
|
# delete should fail because open
|
||||||
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
||||||
await api_connection.delete_table_db(TEST_DB)
|
await api_connection.delete_table_db(TEST_DB)
|
||||||
@ -62,7 +64,7 @@ async def test_open_twice_table_db_store_load(api_connection: veilid.VeilidAPI):
|
|||||||
async with tdb:
|
async with tdb:
|
||||||
tdb2 = await api_connection.open_table_db(TEST_DB, 1)
|
tdb2 = await api_connection.open_table_db(TEST_DB, 1)
|
||||||
async with tdb2:
|
async with tdb2:
|
||||||
# store into first db copy
|
# store into first db copy
|
||||||
await tdb.store(b"asdf", b"1234")
|
await tdb.store(b"asdf", b"1234")
|
||||||
# load from second db copy
|
# load from second db copy
|
||||||
assert await tdb.load(b"asdf") == b"1234"
|
assert await tdb.load(b"asdf") == b"1234"
|
||||||
@ -71,6 +73,7 @@ async def test_open_twice_table_db_store_load(api_connection: veilid.VeilidAPI):
|
|||||||
deleted = await api_connection.delete_table_db(TEST_DB)
|
deleted = await api_connection.delete_table_db(TEST_DB)
|
||||||
assert deleted
|
assert deleted
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_open_twice_table_db_store_delete_load(api_connection: veilid.VeilidAPI):
|
async def test_open_twice_table_db_store_delete_load(api_connection: veilid.VeilidAPI):
|
||||||
# delete test db if it exists
|
# delete test db if it exists
|
||||||
@ -80,12 +83,11 @@ async def test_open_twice_table_db_store_delete_load(api_connection: veilid.Veil
|
|||||||
async with tdb:
|
async with tdb:
|
||||||
tdb2 = await api_connection.open_table_db(TEST_DB, 1)
|
tdb2 = await api_connection.open_table_db(TEST_DB, 1)
|
||||||
async with tdb2:
|
async with tdb2:
|
||||||
|
# store into first db copy
|
||||||
# store into first db copy
|
|
||||||
await tdb.store(b"asdf", b"1234")
|
await tdb.store(b"asdf", b"1234")
|
||||||
# delete from second db copy and clean up
|
# delete from second db copy and clean up
|
||||||
await tdb2.delete(b"asdf")
|
await tdb2.delete(b"asdf")
|
||||||
|
|
||||||
# load from first db copy
|
# load from first db copy
|
||||||
assert await tdb.load(b"asdf") == None
|
assert await tdb.load(b"asdf") == None
|
||||||
|
|
||||||
@ -104,24 +106,22 @@ async def test_resize_table_db(api_connection: veilid.VeilidAPI):
|
|||||||
# reopen the db with more columns should fail if it is already open
|
# reopen the db with more columns should fail if it is already open
|
||||||
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
||||||
await api_connection.open_table_db(TEST_DB, 2)
|
await api_connection.open_table_db(TEST_DB, 2)
|
||||||
|
|
||||||
tdb2 = await api_connection.open_table_db(TEST_DB, 2)
|
tdb2 = await api_connection.open_table_db(TEST_DB, 2)
|
||||||
async with tdb2:
|
async with tdb2:
|
||||||
# write something to second column
|
# write something to second column
|
||||||
await tdb2.store(b"qwer", b"5678", col = 1)
|
await tdb2.store(b"qwer", b"5678", col=1)
|
||||||
|
|
||||||
# reopen the db with fewer columns
|
# reopen the db with fewer columns
|
||||||
tdb = await api_connection.open_table_db(TEST_DB, 1)
|
tdb = await api_connection.open_table_db(TEST_DB, 1)
|
||||||
async with tdb:
|
async with tdb:
|
||||||
|
# Should fail access to second column
|
||||||
# Should fail access to second column
|
|
||||||
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
with pytest.raises(veilid.VeilidAPIErrorGeneric) as exc:
|
||||||
await tdb.load(b"qwer", col = 1)
|
await tdb.load(b"qwer", col=1)
|
||||||
|
|
||||||
# Should succeed with access to second column
|
# Should succeed with access to second column
|
||||||
assert await tdb2.load(b"qwer", col = 1) == b"5678"
|
assert await tdb2.load(b"qwer", col=1) == b"5678"
|
||||||
|
|
||||||
# now delete should succeed
|
# now delete should succeed
|
||||||
deleted = await api_connection.delete_table_db(TEST_DB)
|
deleted = await api_connection.delete_table_db(TEST_DB)
|
||||||
assert deleted
|
assert deleted
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ from .state import VeilidState
|
|||||||
|
|
||||||
|
|
||||||
class RoutingContext(ABC):
|
class RoutingContext(ABC):
|
||||||
|
|
||||||
async def __aenter__(self) -> Self:
|
async def __aenter__(self) -> Self:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -23,21 +22,21 @@ class RoutingContext(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def with_privacy(self, release = True) -> Self:
|
async def with_privacy(self, release=True) -> Self:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def with_custom_privacy(self, safety_selection: types.SafetySelection, release = True) -> Self:
|
async def with_custom_privacy(
|
||||||
|
self, safety_selection: types.SafetySelection, release=True
|
||||||
|
) -> Self:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def with_sequencing(self, sequencing: types.Sequencing, release = True) -> Self:
|
async def with_sequencing(self, sequencing: types.Sequencing, release=True) -> Self:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def app_call(
|
async def app_call(self, target: types.TypedKey | types.RouteId, request: bytes) -> bytes:
|
||||||
self, target: types.TypedKey | types.RouteId, request: bytes
|
|
||||||
) -> bytes:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -166,7 +165,6 @@ class TableDb(ABC):
|
|||||||
|
|
||||||
|
|
||||||
class CryptoSystem(ABC):
|
class CryptoSystem(ABC):
|
||||||
|
|
||||||
async def __aenter__(self) -> Self:
|
async def __aenter__(self) -> Self:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -183,9 +181,7 @@ class CryptoSystem(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def cached_dh(
|
async def cached_dh(self, key: types.PublicKey, secret: types.SecretKey) -> types.SharedSecret:
|
||||||
self, key: types.PublicKey, secret: types.SecretKey
|
|
||||||
) -> types.SharedSecret:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -211,9 +207,7 @@ class CryptoSystem(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def derive_shared_secret(
|
async def derive_shared_secret(self, password: bytes, salt: bytes) -> types.SharedSecret:
|
||||||
self, password: bytes, salt: bytes
|
|
||||||
) -> types.SharedSecret:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -233,9 +227,7 @@ class CryptoSystem(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def validate_key_pair(
|
async def validate_key_pair(self, key: types.PublicKey, secret: types.SecretKey) -> bool:
|
||||||
self, key: types.PublicKey, secret: types.SecretKey
|
|
||||||
) -> bool:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -255,9 +247,7 @@ class CryptoSystem(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def verify(
|
async def verify(self, key: types.PublicKey, data: bytes, signature: types.Signature):
|
||||||
self, key: types.PublicKey, data: bytes, signature: types.Signature
|
|
||||||
):
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -6,20 +6,45 @@ from typing import Awaitable, Callable, Optional, Self
|
|||||||
from jsonschema import exceptions, validators
|
from jsonschema import exceptions, validators
|
||||||
|
|
||||||
from . import schema
|
from . import schema
|
||||||
from .api import (CryptoSystem, RoutingContext, TableDb, TableDbTransaction,
|
from .api import CryptoSystem, RoutingContext, TableDb, TableDbTransaction, VeilidAPI
|
||||||
VeilidAPI)
|
|
||||||
from .error import raise_api_result
|
from .error import raise_api_result
|
||||||
from .operations import (CryptoSystemOperation, Operation,
|
from .operations import (
|
||||||
RoutingContextOperation, TableDbOperation,
|
CryptoSystemOperation,
|
||||||
TableDbTransactionOperation)
|
Operation,
|
||||||
|
RoutingContextOperation,
|
||||||
|
TableDbOperation,
|
||||||
|
TableDbTransactionOperation,
|
||||||
|
)
|
||||||
from .state import VeilidState, VeilidUpdate
|
from .state import VeilidState, VeilidUpdate
|
||||||
from .types import (CryptoKey, CryptoKeyDistance, CryptoKind,
|
from .types import (
|
||||||
DHTRecordDescriptor, DHTSchema, HashDigest, KeyPair,
|
CryptoKey,
|
||||||
NewPrivateRouteResult, Nonce, OperationId, PublicKey,
|
CryptoKeyDistance,
|
||||||
RouteId, SafetySelection, SecretKey, Sequencing, SharedSecret, Signature,
|
CryptoKind,
|
||||||
Stability, Timestamp, TypedKey, TypedKeyPair,
|
DHTRecordDescriptor,
|
||||||
TypedSignature, ValueData, ValueSubkey, VeilidJSONEncoder,
|
DHTSchema,
|
||||||
VeilidVersion, urlsafe_b64decode_no_pad)
|
HashDigest,
|
||||||
|
KeyPair,
|
||||||
|
NewPrivateRouteResult,
|
||||||
|
Nonce,
|
||||||
|
OperationId,
|
||||||
|
PublicKey,
|
||||||
|
RouteId,
|
||||||
|
SafetySelection,
|
||||||
|
SecretKey,
|
||||||
|
Sequencing,
|
||||||
|
SharedSecret,
|
||||||
|
Signature,
|
||||||
|
Stability,
|
||||||
|
Timestamp,
|
||||||
|
TypedKey,
|
||||||
|
TypedKeyPair,
|
||||||
|
TypedSignature,
|
||||||
|
ValueData,
|
||||||
|
ValueSubkey,
|
||||||
|
VeilidJSONEncoder,
|
||||||
|
VeilidVersion,
|
||||||
|
urlsafe_b64decode_no_pad,
|
||||||
|
)
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
|
|
||||||
@ -200,10 +225,7 @@ class _JsonVeilidAPI(VeilidAPI):
|
|||||||
self.writer.write(reqbytes)
|
self.writer.write(reqbytes)
|
||||||
|
|
||||||
async def send_ndjson_request(
|
async def send_ndjson_request(
|
||||||
self,
|
self, op: Operation, validate: Optional[Callable[[dict, dict], None]] = None, **kwargs
|
||||||
op: Operation,
|
|
||||||
validate: Optional[Callable[[dict, dict], None]] = None,
|
|
||||||
**kwargs
|
|
||||||
) -> dict:
|
) -> dict:
|
||||||
# Get next id
|
# Get next id
|
||||||
await self.lock.acquire()
|
await self.lock.acquire()
|
||||||
@ -249,9 +271,7 @@ class _JsonVeilidAPI(VeilidAPI):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
async def control(self, args: list[str]) -> str:
|
async def control(self, args: list[str]) -> str:
|
||||||
return raise_api_result(
|
return raise_api_result(await self.send_ndjson_request(Operation.CONTROL, args=args))
|
||||||
await self.send_ndjson_request(Operation.CONTROL, args=args)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def get_state(self) -> VeilidState:
|
async def get_state(self) -> VeilidState:
|
||||||
return VeilidState.from_json(
|
return VeilidState.from_json(
|
||||||
@ -266,9 +286,7 @@ class _JsonVeilidAPI(VeilidAPI):
|
|||||||
|
|
||||||
async def new_private_route(self) -> tuple[RouteId, bytes]:
|
async def new_private_route(self) -> tuple[RouteId, bytes]:
|
||||||
return NewPrivateRouteResult.from_json(
|
return NewPrivateRouteResult.from_json(
|
||||||
raise_api_result(
|
raise_api_result(await self.send_ndjson_request(Operation.NEW_PRIVATE_ROUTE))
|
||||||
await self.send_ndjson_request(Operation.NEW_PRIVATE_ROUTE)
|
|
||||||
)
|
|
||||||
).to_tuple()
|
).to_tuple()
|
||||||
|
|
||||||
async def new_custom_private_route(
|
async def new_custom_private_route(
|
||||||
@ -288,17 +306,13 @@ class _JsonVeilidAPI(VeilidAPI):
|
|||||||
async def import_remote_private_route(self, blob: bytes) -> RouteId:
|
async def import_remote_private_route(self, blob: bytes) -> RouteId:
|
||||||
return RouteId(
|
return RouteId(
|
||||||
raise_api_result(
|
raise_api_result(
|
||||||
await self.send_ndjson_request(
|
await self.send_ndjson_request(Operation.IMPORT_REMOTE_PRIVATE_ROUTE, blob=blob)
|
||||||
Operation.IMPORT_REMOTE_PRIVATE_ROUTE, blob=blob
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def release_private_route(self, route_id: RouteId):
|
async def release_private_route(self, route_id: RouteId):
|
||||||
raise_api_result(
|
raise_api_result(
|
||||||
await self.send_ndjson_request(
|
await self.send_ndjson_request(Operation.RELEASE_PRIVATE_ROUTE, route_id=route_id)
|
||||||
Operation.RELEASE_PRIVATE_ROUTE, route_id=route_id
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def app_call_reply(self, call_id: OperationId, message: bytes):
|
async def app_call_reply(self, call_id: OperationId, message: bytes):
|
||||||
@ -309,9 +323,7 @@ class _JsonVeilidAPI(VeilidAPI):
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def new_routing_context(self) -> RoutingContext:
|
async def new_routing_context(self) -> RoutingContext:
|
||||||
rc_id = raise_api_result(
|
rc_id = raise_api_result(await self.send_ndjson_request(Operation.NEW_ROUTING_CONTEXT))
|
||||||
await self.send_ndjson_request(Operation.NEW_ROUTING_CONTEXT)
|
|
||||||
)
|
|
||||||
return _JsonRoutingContext(self, rc_id)
|
return _JsonRoutingContext(self, rc_id)
|
||||||
|
|
||||||
async def open_table_db(self, name: str, column_count: int) -> TableDb:
|
async def open_table_db(self, name: str, column_count: int) -> TableDb:
|
||||||
@ -334,9 +346,7 @@ class _JsonVeilidAPI(VeilidAPI):
|
|||||||
return _JsonCryptoSystem(self, cs_id)
|
return _JsonCryptoSystem(self, cs_id)
|
||||||
|
|
||||||
async def best_crypto_system(self) -> CryptoSystem:
|
async def best_crypto_system(self) -> CryptoSystem:
|
||||||
cs_id = raise_api_result(
|
cs_id = raise_api_result(await self.send_ndjson_request(Operation.BEST_CRYPTO_SYSTEM))
|
||||||
await self.send_ndjson_request(Operation.BEST_CRYPTO_SYSTEM)
|
|
||||||
)
|
|
||||||
return _JsonCryptoSystem(self, cs_id)
|
return _JsonCryptoSystem(self, cs_id)
|
||||||
|
|
||||||
async def verify_signatures(
|
async def verify_signatures(
|
||||||
@ -375,27 +385,19 @@ class _JsonVeilidAPI(VeilidAPI):
|
|||||||
map(
|
map(
|
||||||
lambda x: TypedKeyPair(x),
|
lambda x: TypedKeyPair(x),
|
||||||
raise_api_result(
|
raise_api_result(
|
||||||
await self.send_ndjson_request(
|
await self.send_ndjson_request(Operation.GENERATE_KEY_PAIR, kind=kind)
|
||||||
Operation.GENERATE_KEY_PAIR, kind=kind
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def now(self) -> Timestamp:
|
async def now(self) -> Timestamp:
|
||||||
return Timestamp(
|
return Timestamp(raise_api_result(await self.send_ndjson_request(Operation.NOW)))
|
||||||
raise_api_result(await self.send_ndjson_request(Operation.NOW))
|
|
||||||
)
|
|
||||||
|
|
||||||
async def debug(self, command: str) -> str:
|
async def debug(self, command: str) -> str:
|
||||||
return raise_api_result(
|
return raise_api_result(await self.send_ndjson_request(Operation.DEBUG, command=command))
|
||||||
await self.send_ndjson_request(Operation.DEBUG, command=command)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def veilid_version_string(self) -> str:
|
async def veilid_version_string(self) -> str:
|
||||||
return raise_api_result(
|
return raise_api_result(await self.send_ndjson_request(Operation.VEILID_VERSION_STRING))
|
||||||
await self.send_ndjson_request(Operation.VEILID_VERSION_STRING)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def veilid_version(self) -> VeilidVersion:
|
async def veilid_version(self) -> VeilidVersion:
|
||||||
v = await self.send_ndjson_request(Operation.VEILID_VERSION)
|
v = await self.send_ndjson_request(Operation.VEILID_VERSION)
|
||||||
@ -424,11 +426,9 @@ class _JsonRoutingContext(RoutingContext):
|
|||||||
if not self.done:
|
if not self.done:
|
||||||
# attempt to clean up server-side anyway
|
# attempt to clean up server-side anyway
|
||||||
self.api.send_one_way_ndjson_request(
|
self.api.send_one_way_ndjson_request(
|
||||||
Operation.ROUTING_CONTEXT,
|
Operation.ROUTING_CONTEXT, rc_id=self.rc_id, rc_op=RoutingContextOperation.RELEASE
|
||||||
rc_id=self.rc_id,
|
|
||||||
rc_op=RoutingContextOperation.RELEASE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# complain
|
# complain
|
||||||
raise AssertionError("Should have released routing context before dropping object")
|
raise AssertionError("Should have released routing context before dropping object")
|
||||||
|
|
||||||
@ -442,11 +442,11 @@ class _JsonRoutingContext(RoutingContext):
|
|||||||
Operation.ROUTING_CONTEXT,
|
Operation.ROUTING_CONTEXT,
|
||||||
validate=validate_rc_op,
|
validate=validate_rc_op,
|
||||||
rc_id=self.rc_id,
|
rc_id=self.rc_id,
|
||||||
rc_op=RoutingContextOperation.RELEASE
|
rc_op=RoutingContextOperation.RELEASE,
|
||||||
)
|
)
|
||||||
self.done = True
|
self.done = True
|
||||||
|
|
||||||
async def with_privacy(self, release = True) -> Self:
|
async def with_privacy(self, release=True) -> Self:
|
||||||
new_rc_id = raise_api_result(
|
new_rc_id = raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
Operation.ROUTING_CONTEXT,
|
Operation.ROUTING_CONTEXT,
|
||||||
@ -459,7 +459,7 @@ class _JsonRoutingContext(RoutingContext):
|
|||||||
await self.release()
|
await self.release()
|
||||||
return self.__class__(self.api, new_rc_id)
|
return self.__class__(self.api, new_rc_id)
|
||||||
|
|
||||||
async def with_custom_privacy(self, safety_selection: SafetySelection, release = True) -> Self:
|
async def with_custom_privacy(self, safety_selection: SafetySelection, release=True) -> Self:
|
||||||
new_rc_id = raise_api_result(
|
new_rc_id = raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
Operation.ROUTING_CONTEXT,
|
Operation.ROUTING_CONTEXT,
|
||||||
@ -473,7 +473,7 @@ class _JsonRoutingContext(RoutingContext):
|
|||||||
await self.release()
|
await self.release()
|
||||||
return self.__class__(self.api, new_rc_id)
|
return self.__class__(self.api, new_rc_id)
|
||||||
|
|
||||||
async def with_sequencing(self, sequencing: Sequencing, release = True) -> Self:
|
async def with_sequencing(self, sequencing: Sequencing, release=True) -> Self:
|
||||||
new_rc_id = raise_api_result(
|
new_rc_id = raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
Operation.ROUTING_CONTEXT,
|
Operation.ROUTING_CONTEXT,
|
||||||
@ -664,7 +664,9 @@ class _JsonTableDbTransaction(TableDbTransaction):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# complain
|
# complain
|
||||||
raise AssertionError("Should have committed or rolled back transaction before dropping object")
|
raise AssertionError(
|
||||||
|
"Should have committed or rolled back transaction before dropping object"
|
||||||
|
)
|
||||||
|
|
||||||
def is_done(self) -> bool:
|
def is_done(self) -> bool:
|
||||||
return self.done
|
return self.done
|
||||||
@ -672,7 +674,7 @@ class _JsonTableDbTransaction(TableDbTransaction):
|
|||||||
async def commit(self):
|
async def commit(self):
|
||||||
if self.done:
|
if self.done:
|
||||||
raise AssertionError("Transaction is already done")
|
raise AssertionError("Transaction is already done")
|
||||||
|
|
||||||
raise_api_result(
|
raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
Operation.TABLE_DB_TRANSACTION,
|
Operation.TABLE_DB_TRANSACTION,
|
||||||
@ -736,12 +738,9 @@ class _JsonTableDb(TableDb):
|
|||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if not self.done:
|
if not self.done:
|
||||||
|
|
||||||
# attempt to clean up server-side anyway
|
# attempt to clean up server-side anyway
|
||||||
self.api.send_one_way_ndjson_request(
|
self.api.send_one_way_ndjson_request(
|
||||||
Operation.TABLE_DB,
|
Operation.TABLE_DB, db_id=self.db_id, db_op=TableDbOperation.RELEASE
|
||||||
db_id=self.db_id,
|
|
||||||
db_op=TableDbOperation.RELEASE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# complain
|
# complain
|
||||||
@ -757,11 +756,10 @@ class _JsonTableDb(TableDb):
|
|||||||
Operation.TABLE_DB,
|
Operation.TABLE_DB,
|
||||||
validate=validate_db_op,
|
validate=validate_db_op,
|
||||||
db_id=self.db_id,
|
db_id=self.db_id,
|
||||||
db_op=TableDbOperation.RELEASE
|
db_op=TableDbOperation.RELEASE,
|
||||||
)
|
)
|
||||||
self.done = True
|
self.done = True
|
||||||
|
|
||||||
|
|
||||||
async def get_column_count(self) -> int:
|
async def get_column_count(self) -> int:
|
||||||
return raise_api_result(
|
return raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
@ -859,12 +857,9 @@ class _JsonCryptoSystem(CryptoSystem):
|
|||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if not self.done:
|
if not self.done:
|
||||||
|
|
||||||
# attempt to clean up server-side anyway
|
# attempt to clean up server-side anyway
|
||||||
self.api.send_one_way_ndjson_request(
|
self.api.send_one_way_ndjson_request(
|
||||||
Operation.CRYPTO_SYSTEM,
|
Operation.CRYPTO_SYSTEM, cs_id=self.cs_id, cs_op=CryptoSystemOperation.RELEASE
|
||||||
cs_id=self.cs_id,
|
|
||||||
cs_op=CryptoSystemOperation.RELEASE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# complain
|
# complain
|
||||||
@ -872,7 +867,7 @@ class _JsonCryptoSystem(CryptoSystem):
|
|||||||
|
|
||||||
def is_done(self) -> bool:
|
def is_done(self) -> bool:
|
||||||
return self.done
|
return self.done
|
||||||
|
|
||||||
async def release(self):
|
async def release(self):
|
||||||
if self.done:
|
if self.done:
|
||||||
return
|
return
|
||||||
@ -880,7 +875,7 @@ class _JsonCryptoSystem(CryptoSystem):
|
|||||||
Operation.CRYPTO_SYSTEM,
|
Operation.CRYPTO_SYSTEM,
|
||||||
validate=validate_cs_op,
|
validate=validate_cs_op,
|
||||||
cs_id=self.cs_id,
|
cs_id=self.cs_id,
|
||||||
cs_op=CryptoSystemOperation.RELEASE
|
cs_op=CryptoSystemOperation.RELEASE,
|
||||||
)
|
)
|
||||||
self.done = True
|
self.done = True
|
||||||
|
|
||||||
@ -1142,9 +1137,7 @@ class _JsonCryptoSystem(CryptoSystem):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def crypt_no_auth(
|
async def crypt_no_auth(self, body: bytes, nonce: Nonce, shared_secret: SharedSecret) -> bytes:
|
||||||
self, body: bytes, nonce: Nonce, shared_secret: SharedSecret
|
|
||||||
) -> bytes:
|
|
||||||
return urlsafe_b64decode_no_pad(
|
return urlsafe_b64decode_no_pad(
|
||||||
raise_api_result(
|
raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
from typing import Self
|
from typing import Self
|
||||||
|
|
||||||
|
|
||||||
class Operation(StrEnum):
|
class Operation(StrEnum):
|
||||||
CONTROL = "Control"
|
CONTROL = "Control"
|
||||||
GET_STATE = "GetState"
|
GET_STATE = "GetState"
|
||||||
@ -28,6 +29,7 @@ class Operation(StrEnum):
|
|||||||
VEILID_VERSION_STRING = "VeilidVersionString"
|
VEILID_VERSION_STRING = "VeilidVersionString"
|
||||||
VEILID_VERSION = "VeilidVersion"
|
VEILID_VERSION = "VeilidVersion"
|
||||||
|
|
||||||
|
|
||||||
class RoutingContextOperation(StrEnum):
|
class RoutingContextOperation(StrEnum):
|
||||||
INVALID_ID = "InvalidId"
|
INVALID_ID = "InvalidId"
|
||||||
RELEASE = "Release"
|
RELEASE = "Release"
|
||||||
@ -45,6 +47,7 @@ class RoutingContextOperation(StrEnum):
|
|||||||
WATCH_DHT_VALUES = "WatchDhtValues"
|
WATCH_DHT_VALUES = "WatchDhtValues"
|
||||||
CANCEL_DHT_WATCH = "CancelDhtWatch"
|
CANCEL_DHT_WATCH = "CancelDhtWatch"
|
||||||
|
|
||||||
|
|
||||||
class TableDbOperation(StrEnum):
|
class TableDbOperation(StrEnum):
|
||||||
INVALID_ID = "InvalidId"
|
INVALID_ID = "InvalidId"
|
||||||
RELEASE = "Release"
|
RELEASE = "Release"
|
||||||
@ -55,6 +58,7 @@ class TableDbOperation(StrEnum):
|
|||||||
LOAD = "Load"
|
LOAD = "Load"
|
||||||
DELETE = "Delete"
|
DELETE = "Delete"
|
||||||
|
|
||||||
|
|
||||||
class TableDbTransactionOperation(StrEnum):
|
class TableDbTransactionOperation(StrEnum):
|
||||||
INVALID_ID = "InvalidId"
|
INVALID_ID = "InvalidId"
|
||||||
COMMIT = "Commit"
|
COMMIT = "Commit"
|
||||||
@ -62,6 +66,7 @@ class TableDbTransactionOperation(StrEnum):
|
|||||||
STORE = "Store"
|
STORE = "Store"
|
||||||
DELETE = "Delete"
|
DELETE = "Delete"
|
||||||
|
|
||||||
|
|
||||||
class CryptoSystemOperation(StrEnum):
|
class CryptoSystemOperation(StrEnum):
|
||||||
INVALID_ID = "InvalidId"
|
INVALID_ID = "InvalidId"
|
||||||
RELEASE = "Release"
|
RELEASE = "Release"
|
||||||
@ -85,7 +90,8 @@ class CryptoSystemOperation(StrEnum):
|
|||||||
DECRYPT_AEAD = "DecryptAead"
|
DECRYPT_AEAD = "DecryptAead"
|
||||||
ENCRYPT_AEAD = "EncryptAead"
|
ENCRYPT_AEAD = "EncryptAead"
|
||||||
CRYPT_NO_AUTH = "CryptNoAuth"
|
CRYPT_NO_AUTH = "CryptNoAuth"
|
||||||
|
|
||||||
|
|
||||||
class RecvMessageType(StrEnum):
|
class RecvMessageType(StrEnum):
|
||||||
RESPONSE = "Response"
|
RESPONSE = "Response"
|
||||||
UPDATE = "Update"
|
UPDATE = "Update"
|
||||||
|
@ -2,9 +2,18 @@ from enum import StrEnum
|
|||||||
from typing import Optional, Self
|
from typing import Optional, Self
|
||||||
|
|
||||||
from .config import VeilidConfig
|
from .config import VeilidConfig
|
||||||
from .types import (ByteCount, RouteId, Timestamp, TimestampDuration, TypedKey,
|
from .types import (
|
||||||
ValueData, ValueSubkey, VeilidLogLevel, OperationId,
|
ByteCount,
|
||||||
urlsafe_b64decode_no_pad)
|
RouteId,
|
||||||
|
Timestamp,
|
||||||
|
TimestampDuration,
|
||||||
|
TypedKey,
|
||||||
|
ValueData,
|
||||||
|
ValueSubkey,
|
||||||
|
VeilidLogLevel,
|
||||||
|
OperationId,
|
||||||
|
urlsafe_b64decode_no_pad,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AttachmentState(StrEnum):
|
class AttachmentState(StrEnum):
|
||||||
@ -200,9 +209,7 @@ class PeerTableData:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, j: dict) -> Self:
|
def from_json(cls, j: dict) -> Self:
|
||||||
"""JSON object hook"""
|
"""JSON object hook"""
|
||||||
return cls(
|
return cls(j["node_ids"], j["peer_address"], PeerStats.from_json(j["peer_stats"]))
|
||||||
j["node_ids"], j["peer_address"], PeerStats.from_json(j["peer_stats"])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class VeilidStateNetwork:
|
class VeilidStateNetwork:
|
||||||
@ -276,9 +283,7 @@ class VeilidLog:
|
|||||||
message: str
|
message: str
|
||||||
backtrace: Optional[str]
|
backtrace: Optional[str]
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, log_level: VeilidLogLevel, message: str, backtrace: Optional[str]):
|
||||||
self, log_level: VeilidLogLevel, message: str, backtrace: Optional[str]
|
|
||||||
):
|
|
||||||
self.log_level = log_level
|
self.log_level = log_level
|
||||||
self.message = message
|
self.message = message
|
||||||
self.backtrace = backtrace
|
self.backtrace = backtrace
|
||||||
@ -349,9 +354,7 @@ class VeilidValueChange:
|
|||||||
count: int
|
count: int
|
||||||
value: ValueData
|
value: ValueData
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, key: TypedKey, subkeys: list[ValueSubkey], count: int, value: ValueData):
|
||||||
self, key: TypedKey, subkeys: list[ValueSubkey], count: int, value: ValueData
|
|
||||||
):
|
|
||||||
self.key = key
|
self.key = key
|
||||||
self.subkeys = subkeys
|
self.subkeys = subkeys
|
||||||
self.count = count
|
self.count = count
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
from typing import Any, Optional, Self, Tuple
|
|
||||||
from functools import total_ordering
|
from functools import total_ordering
|
||||||
|
from typing import Any, Optional, Self, Tuple
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
|
|
||||||
@ -83,6 +83,7 @@ class SafetySelectionKind(StrEnum):
|
|||||||
UNSAFE = "Unsafe"
|
UNSAFE = "Unsafe"
|
||||||
SAFE = "Safe"
|
SAFE = "Safe"
|
||||||
|
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
|
|
||||||
|
|
||||||
@ -249,7 +250,12 @@ class VeilidVersion:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return isinstance(other, VeilidVersion) and self.data == other.data and self.seq == other.seq and self.writer == other.writer
|
return (
|
||||||
|
isinstance(other, VeilidVersion)
|
||||||
|
and self.data == other.data
|
||||||
|
and self.seq == other.seq
|
||||||
|
and self.writer == other.writer
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def major(self):
|
def major(self):
|
||||||
@ -319,8 +325,7 @@ class DHTSchema:
|
|||||||
if DHTSchemaKind(j["kind"]) == DHTSchemaKind.SMPL:
|
if DHTSchemaKind(j["kind"]) == DHTSchemaKind.SMPL:
|
||||||
return cls.smpl(
|
return cls.smpl(
|
||||||
j["o_cnt"],
|
j["o_cnt"],
|
||||||
[DHTSchemaSMPLMember.from_json(member)
|
[DHTSchemaSMPLMember.from_json(member) for member in j["members"]],
|
||||||
for member in j["members"]],
|
|
||||||
)
|
)
|
||||||
raise Exception("Unknown DHTSchema kind", j["kind"])
|
raise Exception("Unknown DHTSchema kind", j["kind"])
|
||||||
|
|
||||||
@ -351,8 +356,7 @@ class DHTRecordDescriptor:
|
|||||||
return cls(
|
return cls(
|
||||||
TypedKey(j["key"]),
|
TypedKey(j["key"]),
|
||||||
PublicKey(j["owner"]),
|
PublicKey(j["owner"]),
|
||||||
None if j["owner_secret"] is None else SecretKey(
|
None if j["owner_secret"] is None else SecretKey(j["owner_secret"]),
|
||||||
j["owner_secret"]),
|
|
||||||
DHTSchema.from_json(j["schema"]),
|
DHTSchema.from_json(j["schema"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -387,7 +391,12 @@ class ValueData:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return isinstance(other, ValueData) and self.data == other.data and self.seq == other.seq and self.writer == other.writer
|
return (
|
||||||
|
isinstance(other, ValueData)
|
||||||
|
and self.data == other.data
|
||||||
|
and self.seq == other.seq
|
||||||
|
and self.writer == other.writer
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, j: dict) -> Self:
|
def from_json(cls, j: dict) -> Self:
|
||||||
@ -403,13 +412,20 @@ class ValueData:
|
|||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
|
|
||||||
|
|
||||||
class SafetySpec:
|
class SafetySpec:
|
||||||
preferred_route: Optional[RouteId]
|
preferred_route: Optional[RouteId]
|
||||||
hop_count: int
|
hop_count: int
|
||||||
stability: Stability
|
stability: Stability
|
||||||
sequencing: Sequencing
|
sequencing: Sequencing
|
||||||
|
|
||||||
def __init__(self, preferred_route: Optional[RouteId], hop_count: int, stability: Stability, sequencing: Sequencing):
|
def __init__(
|
||||||
|
self,
|
||||||
|
preferred_route: Optional[RouteId],
|
||||||
|
hop_count: int,
|
||||||
|
stability: Stability,
|
||||||
|
sequencing: Sequencing,
|
||||||
|
):
|
||||||
self.preferred_route = preferred_route
|
self.preferred_route = preferred_route
|
||||||
self.hop_count = hop_count
|
self.hop_count = hop_count
|
||||||
self.stability = stability
|
self.stability = stability
|
||||||
@ -417,10 +433,12 @@ class SafetySpec:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, j: dict) -> Self:
|
def from_json(cls, j: dict) -> Self:
|
||||||
return cls(RouteId(j["preferred_route"]) if "preferred_route" in j else None,
|
return cls(
|
||||||
j["hop_count"],
|
RouteId(j["preferred_route"]) if "preferred_route" in j else None,
|
||||||
Stability(j["stability"]),
|
j["hop_count"],
|
||||||
Sequencing(j["sequencing"]))
|
Stability(j["stability"]),
|
||||||
|
Sequencing(j["sequencing"]),
|
||||||
|
)
|
||||||
|
|
||||||
def to_json(self) -> dict:
|
def to_json(self) -> dict:
|
||||||
return self.__dict__
|
return self.__dict__
|
||||||
|
Loading…
Reference in New Issue
Block a user