Skip to content

Commit

Permalink
Merge branch 'main' into mhh-domain-node
Browse files Browse the repository at this point in the history
  • Loading branch information
MHHukiewitz authored Feb 1, 2024
2 parents b1ad1a5 + 4080042 commit 22e22dd
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 55 deletions.
1 change: 1 addition & 0 deletions examples/httpgateway.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" Server metrics upload.
"""

# -*- coding: utf-8 -*-

import click
Expand Down
1 change: 1 addition & 0 deletions examples/metrics.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" Server metrics upload.
"""

import asyncio
import os
import platform
Expand Down
1 change: 1 addition & 0 deletions examples/mqtt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" Server metrics upload.
"""

# -*- coding: utf-8 -*-

import asyncio
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ exclude =
dist
.eggs
docs/conf.py
ignore = E501 W291 W503 E203
ignore = E501 W291 W503 E203 E704

[isort]
profile = black
Expand Down
1 change: 1 addition & 0 deletions src/aleph/sdk/chains/nuls1.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" Barebone NULS address and message signing support.
"""

import hashlib
import logging
import struct
Expand Down
1 change: 1 addition & 0 deletions src/aleph/sdk/chains/remote.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Remote account, accessible via an API.
"""

import asyncio
from typing import Dict, Optional

Expand Down
28 changes: 15 additions & 13 deletions src/aleph/sdk/client/authenticated_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from ..conf import settings
from ..exceptions import BroadcastError, InsufficientFundsError, InvalidMessageError
from ..types import Account, StorageEnum
from ..utils import extended_json_encoder
from ..utils import extended_json_encoder, parse_volume
from .abstract import AuthenticatedAlephClient
from .http import AlephHttpClient

Expand Down Expand Up @@ -68,7 +68,7 @@ class AuthenticatedAlephHttpClient(AlephHttpClient, AuthenticatedAlephClient):
def __init__(
self,
account: Account,
api_server: Optional[str],
api_server: Optional[str] = None,
api_unix_socket: Optional[str] = None,
allow_unix_sockets: bool = True,
timeout: Optional[aiohttp.ClientTimeout] = None,
Expand Down Expand Up @@ -449,9 +449,7 @@ async def create_program(
# Trigger on HTTP calls.
triggers = {"http": True, "persistent": persistent}

volumes: List[MachineVolume] = [
MachineVolume.parse_obj(volume) for volume in volumes
]
volumes: List[MachineVolume] = [parse_volume(volume) for volume in volumes]

content = ProgramContent(
type="vm-function",
Expand All @@ -478,11 +476,13 @@ async def create_program(
runtime=FunctionRuntime(
ref=runtime,
use_latest=True,
comment="Official aleph.im runtime"
if runtime == settings.DEFAULT_RUNTIME_ID
else "",
comment=(
"Official aleph.im runtime"
if runtime == settings.DEFAULT_RUNTIME_ID
else ""
),
),
volumes=[MachineVolume.parse_obj(volume) for volume in volumes],
volumes=[parse_volume(volume) for volume in volumes],
time=time.time(),
metadata=metadata,
)
Expand Down Expand Up @@ -551,11 +551,13 @@ async def create_instance(
size_mib=rootfs_size,
persistence="host",
use_latest=True,
comment="Official Aleph Debian root filesystem"
if rootfs == settings.DEFAULT_RUNTIME_ID
else "",
comment=(
"Official Aleph Debian root filesystem"
if rootfs == settings.DEFAULT_RUNTIME_ID
else ""
),
),
volumes=[MachineVolume.parse_obj(volume) for volume in volumes],
volumes=[parse_volume(volume) for volume in volumes],
time=time.time(),
authorized_keys=ssh_keys,
metadata=metadata,
Expand Down
4 changes: 3 additions & 1 deletion src/aleph/sdk/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ class Settings(BaseSettings):
REMOTE_CRYPTO_UNIX_SOCKET: Optional[str] = None
ADDRESS_TO_USE: Optional[str] = None

DEFAULT_RUNTIME_ID: str = "f873715dc2feec3833074bd4b8745363a0e0093746b987b4c8191268883b2463" # Debian 12 official runtime
DEFAULT_RUNTIME_ID: str = (
"f873715dc2feec3833074bd4b8745363a0e0093746b987b4c8191268883b2463" # Debian 12 official runtime
)
DEFAULT_VM_MEMORY: int = 256
DEFAULT_VM_VCPUS: int = 1
DEFAULT_VM_TIMEOUT: float = 30.0
Expand Down
33 changes: 16 additions & 17 deletions src/aleph/sdk/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ async def check_domain(
Returns:
A dictionary containing the status of the domain configuration.
"""
status = {"cname": False, "owner_proof": False}
status = {}

dns_rules = self.get_required_dns_rules(hostname, target, owner)

resolver = await self.get_resolver_for(hostname)
for dns_rule in dns_rules:
status[dns_rule.name] = False

Expand All @@ -199,26 +199,25 @@ async def check_domain(
record_value = dns_rule.dns["value"]

try:
resolver = await self.get_resolver_for(hostname)
entries = await resolver.query(record_name, record_type.upper())
except aiodns.error.DNSError:
# Continue checks
entries = None

if entries and record_type == "txt":
for entry in entries:
if hasattr(entry, "text") and entry.text == record_value:
break
else:
return dns_rule.raise_error(status)
elif (
entries is None
or not hasattr(entries, record_type)
or getattr(entries, record_type) != record_value
):
return dns_rule.raise_error(status)

status[dns_rule.name] = True
if entries:
if record_type == "txt":
for entry in entries:
if hasattr(entry, "text") and entry.text == record_value:
status[dns_rule.name] = True
break
elif (
hasattr(entries, record_type)
and getattr(entries, record_type) == record_value
):
status[dns_rule.name] = True

if all(status.values()) is False:
dns_rule.raise_error(status)

return status

Expand Down
12 changes: 4 additions & 8 deletions src/aleph/sdk/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,19 @@ class Account(Protocol):
CURVE: str

@abstractmethod
async def sign_message(self, message: Dict) -> Dict:
...
async def sign_message(self, message: Dict) -> Dict: ...

@abstractmethod
def get_address(self) -> str:
...
def get_address(self) -> str: ...

@abstractmethod
def get_public_key(self) -> str:
...
def get_public_key(self) -> str: ...


class AccountFromPrivateKey(Account, Protocol):
"""Only accounts that are initialized from a private key string are supported."""

def __init__(self, private_key: bytes):
...
def __init__(self, private_key: bytes): ...


GenericMessage = TypeVar("GenericMessage", bound=AlephMessage)
36 changes: 31 additions & 5 deletions src/aleph/sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,23 @@
from enum import Enum
from pathlib import Path
from shutil import make_archive
from typing import Any, Iterable, Optional, Protocol, Tuple, Type, TypeVar, Union
from typing import (
Any,
Iterable,
Mapping,
Optional,
Protocol,
Tuple,
Type,
TypeVar,
Union,
get_args,
)
from zipfile import BadZipFile, ZipFile

from aleph_message.models import MessageType
from aleph_message.models.execution.program import Encoding
from aleph_message.models.execution.volume import MachineVolume
from pydantic.json import pydantic_encoder

from aleph.sdk.conf import settings
Expand Down Expand Up @@ -86,13 +98,11 @@ def check_unix_socket_valid(unix_socket_path: str) -> bool:


class AsyncReadable(Protocol[T]):
async def read(self, n: int = -1) -> T:
...
async def read(self, n: int = -1) -> T: ...


class Writable(Protocol[U]):
def write(self, buffer: U) -> int:
...
def write(self, buffer: U) -> int: ...


async def copy_async_readable_to_buffer(
Expand Down Expand Up @@ -150,3 +160,19 @@ def extended_json_encoder(obj: Any) -> Any:
return obj.hour * 3600 + obj.minute * 60 + obj.second + obj.microsecond / 1e6
else:
return pydantic_encoder(obj)


def parse_volume(volume_dict: Union[Mapping, MachineVolume]) -> MachineVolume:
# Python 3.9 does not support `isinstance(volume_dict, MachineVolume)`,
# so we need to iterate over all types.
if any(
isinstance(volume_dict, volume_type) for volume_type in get_args(MachineVolume)
):
return volume_dict
for volume_type in get_args(MachineVolume):
try:
return volume_type.parse_obj(volume_dict)
except ValueError:
continue
else:
raise ValueError(f"Could not parse volume: {volume_dict}")
15 changes: 6 additions & 9 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ def json_post() -> dict:
@pytest.fixture
def raw_messages_response(aleph_messages) -> Callable[[int], Dict[str, Any]]:
return lambda page: {
"messages": [message.dict() for message in aleph_messages]
if int(page) == 1
else [],
"messages": (
[message.dict() for message in aleph_messages] if int(page) == 1 else []
),
"pagination_item": "messages",
"pagination_page": int(page),
"pagination_per_page": max(len(aleph_messages), 20),
Expand All @@ -158,14 +158,11 @@ def __init__(self, sync: bool):
async def __aenter__(self):
return self

async def __aexit__(self, exc_type, exc_val, exc_tb):
...
async def __aexit__(self, exc_type, exc_val, exc_tb): ...

def raise_for_status(self):
...
def raise_for_status(self): ...

async def close(self):
...
async def close(self): ...

@property
def status(self):
Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_chain_nuls1_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This file tests that both implementations returns identical results.
"""

from pathlib import Path
from tempfile import NamedTemporaryFile

Expand Down
48 changes: 47 additions & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@
StoreMessage,
)
from aleph_message.models.execution.environment import MachineResources
from aleph_message.models.execution.volume import (
EphemeralVolume,
ImmutableVolume,
PersistentVolume,
)

from aleph.sdk.utils import enum_as_str, get_message_type_value
from aleph.sdk.utils import enum_as_str, get_message_type_value, parse_volume


def test_get_message_type_value():
Expand Down Expand Up @@ -128,3 +133,44 @@ async def test_prepare_aleph_message(
)

assert message.content.dict() == content


def test_parse_immutable_volume():
volume_dict = {
"ref": "QmX8K1c22WmQBAww5ShWQqwMiFif7XFrJD6iFBj7skQZXW",
"use_latest": True,
"comment": "Dummy hash",
}
volume = parse_volume(volume_dict)
volume = parse_volume(volume)
assert volume
assert isinstance(volume, ImmutableVolume)


def test_parse_ephemeral_volume():
volume_dict = {
"comment": "Dummy hash",
"ephemeral": True,
"size_mib": 1,
}
volume = parse_volume(volume_dict)
volume = parse_volume(volume)
assert volume
assert isinstance(volume, EphemeralVolume)


def test_parse_persistent_volume():
volume_dict = {
"parent": {
"ref": "QmX8K1c22WmQBAww5ShWQqwMiFif7XFrJD6iFBj7skQZXW",
"use_latest": True,
"comment": "Dummy hash",
},
"persistence": "host",
"name": "test",
"size_mib": 1,
}
volume = parse_volume(volume_dict)
volume = parse_volume(volume)
assert volume
assert isinstance(volume, PersistentVolume)

0 comments on commit 22e22dd

Please sign in to comment.