Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

177 upgrade pydantic version #179

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ dynamic = [ "version" ]
dependencies = [
"aiohttp>=3.8.3",
"aioresponses>=0.7.6",
"aleph-message>=0.5",
"aleph-message @ git+https://github.com/aleph-im/aleph-message@108-upgrade-pydantic-version#egg=aleph-message",
"aleph-superfluid>=0.2.1",
"base58==2.1.1", # Needed now as default with _load_account changement
"base58==2.1.1", # Needed now as default with _load_account changement
"coincurve; python_version<'3.11'",
"coincurve>=19; python_version>='3.11'",
"eth-abi>=4; python_version>='3.11'",
"eth-typing==4.3.1",
"jwcrypto==1.5.6",
"pynacl==1.5", # Needed now as default with _load_account changement
"pydantic-settings>=2",
philogicae marked this conversation as resolved.
Show resolved Hide resolved
"pynacl==1.5", # Needed now as default with _load_account changement
"python-magic",
"typing-extensions",
"web3==6.3",
Expand Down Expand Up @@ -154,6 +155,7 @@ dependencies = [
"ruff==0.4.8",
"isort==5.13.2",
"pyproject-fmt==2.2.1",
"pydantic-settings>=2",
]
[tool.hatch.envs.linting.scripts]
typing = "mypy --config-file=pyproject.toml {args:} ./src/ ./tests/ ./examples/"
Expand Down
2 changes: 1 addition & 1 deletion src/aleph/sdk/chains/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async def sign_message(self, message: Dict) -> Dict:
"""
message = self._setup_sender(message)
signature = await self.sign_raw(get_verification_buffer(message))
message["signature"] = signature.hex()
message["signature"] = "0x" + signature.hex()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this added here ?

Copy link
Member Author

@Antonyjin Antonyjin Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my mistake. Normally, .hex() should not remove the 0x at the beginning of the signature, but after the changes made for the Pydantic upgrade, it remove it.
I was just missing this, so I added it temporarily to check if everything would pass and completely forgot to correct it.

I'll debug to see why the hex remove the 0x

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found out that with python3>=3.5 .hex() should remove the 0x prefix from the string.
My branch does it so it causes some errors in the tests but on the main branch it seems that the prefix is not removed even though the python version is 3.11.5

return message

@abstractmethod
Expand Down
4 changes: 2 additions & 2 deletions src/aleph/sdk/chains/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async def from_crypto_host(
session = aiohttp.ClientSession(connector=connector)

async with session.get(f"{host}/properties") as response:
response.raise_for_status()
await response.raise_for_status()
philogicae marked this conversation as resolved.
Show resolved Hide resolved
data = await response.json()
properties = AccountProperties(**data)

Expand All @@ -75,7 +75,7 @@ def private_key(self):
async def sign_message(self, message: Dict) -> Dict:
"""Sign a message inplace."""
async with self._session.post(f"{self._host}/sign", json=message) as response:
response.raise_for_status()
await response.raise_for_status()
philogicae marked this conversation as resolved.
Show resolved Hide resolved
return await response.json()

async def sign_raw(self, buffer: bytes) -> bytes:
Expand Down
20 changes: 10 additions & 10 deletions src/aleph/sdk/client/authenticated_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ async def _broadcast(
url = "/api/v0/messages"
logger.debug(f"Posting message on {url}")

message_dict = message.dict(include=self.BROADCAST_MESSAGE_FIELDS)
message_dict = message.model_dump(include=self.BROADCAST_MESSAGE_FIELDS)
async with self.http_session.post(
url,
json={
Expand Down Expand Up @@ -301,7 +301,7 @@ async def create_post(
)

message, status, _ = await self.submit(
content=content.dict(exclude_none=True),
content=content.model_dump(exclude_none=True),
message_type=MessageType.post,
channel=channel,
allow_inlining=inline,
Expand Down Expand Up @@ -329,7 +329,7 @@ async def create_aggregate(
)

message, status, _ = await self.submit(
content=content_.dict(exclude_none=True),
content=content_.model_dump(exclude_none=True),
message_type=MessageType.aggregate,
channel=channel,
allow_inlining=inline,
Expand Down Expand Up @@ -403,7 +403,7 @@ async def create_store(
content = StoreContent(**values)

message, status, _ = await self.submit(
content=content.dict(exclude_none=True),
content=content.model_dump(exclude_none=True),
message_type=MessageType.store,
channel=channel,
allow_inlining=True,
Expand Down Expand Up @@ -496,7 +496,7 @@ async def create_program(
assert content.on.persistent == persistent

message, status, _ = await self.submit(
content=content.dict(exclude_none=True),
content=content.model_dump(exclude_none=True),
message_type=MessageType.program,
channel=channel,
storage_engine=storage_engine,
Expand Down Expand Up @@ -572,7 +572,7 @@ async def create_instance(
payment=payment,
)
message, status, response = await self.submit(
content=content.dict(exclude_none=True),
content=content.model_dump(exclude_none=True),
message_type=MessageType.instance,
channel=channel,
storage_engine=storage_engine,
Expand Down Expand Up @@ -618,7 +618,7 @@ async def forget(
)

message, status, _ = await self.submit(
content=content.dict(exclude_none=True),
content=content.model_dump(exclude_none=True),
message_type=MessageType.forget,
channel=channel,
storage_engine=storage_engine,
Expand Down Expand Up @@ -662,11 +662,11 @@ async def _storage_push_file_with_message(
# Prepare the STORE message
message = await self.generate_signed_message(
message_type=MessageType.store,
content=store_content.dict(exclude_none=True),
content=store_content.model_dump(exclude_none=True),
channel=channel,
)
metadata = {
"message": message.dict(exclude_none=True),
"message": message.model_dump(exclude_none=True),
"sync": sync,
}
data.add_field(
Expand Down Expand Up @@ -710,7 +710,7 @@ async def _upload_file_native(
item_hash=file_hash,
mime_type=mime_type,
time=time.time(),
**extra_fields,
**(extra_fields or {}),
)
message, _ = await self._storage_push_file_with_message(
file_content=file_content,
Expand Down
2 changes: 1 addition & 1 deletion src/aleph/sdk/client/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ async def get_posts(
posts: List[Post] = []
for post_raw in posts_raw:
try:
posts.append(Post.parse_obj(post_raw))
posts.append(Post.model_validate(post_raw))
except ValidationError as e:
if not ignore_invalid_messages:
raise e
Expand Down
2 changes: 1 addition & 1 deletion src/aleph/sdk/client/vm_confidential_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ async def measurement(self, vm_id: ItemHash) -> SEVMeasurement:
status, text = await self.perform_operation(
vm_id, "confidential/measurement", method="GET"
)
sev_measurement = SEVMeasurement.parse_raw(text)
sev_measurement = SEVMeasurement.model_validate_json(text)
return sev_measurement

async def validate_measure(
Expand Down
39 changes: 19 additions & 20 deletions src/aleph/sdk/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import os
from pathlib import Path
from shutil import which
from typing import Dict, Optional, Union
from typing import ClassVar, Dict, List, Optional, Union

from aleph_message.models import Chain
from aleph_message.models.execution.environment import HypervisorType
from pydantic import BaseModel, BaseSettings, Field
from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings, SettingsConfigDict

from aleph.sdk.types import ChainInfo

Expand Down Expand Up @@ -41,7 +42,7 @@ class Settings(BaseSettings):
REMOTE_CRYPTO_HOST: Optional[str] = None
REMOTE_CRYPTO_UNIX_SOCKET: Optional[str] = None
ADDRESS_TO_USE: Optional[str] = None
HTTP_REQUEST_TIMEOUT = 15.0
HTTP_REQUEST_TIMEOUT: float = 15.0

DEFAULT_CHANNEL: str = "ALEPH-CLOUDSOLUTIONS"
DEFAULT_RUNTIME_ID: str = (
Expand Down Expand Up @@ -83,12 +84,12 @@ class Settings(BaseSettings):

CODE_USES_SQUASHFS: bool = which("mksquashfs") is not None # True if command exists

VM_URL_PATH = "https://aleph.sh/vm/{hash}"
VM_URL_HOST = "https://{hash_base32}.aleph.sh"
VM_URL_PATH: ClassVar[str] = "https://aleph.sh/vm/{hash}"
VM_URL_HOST: ClassVar[str] = "https://{hash_base32}.aleph.sh"

# Web3Provider settings
TOKEN_DECIMALS = 18
TX_TIMEOUT = 60 * 3
TOKEN_DECIMALS: ClassVar[int] = 18
TX_TIMEOUT: ClassVar[int] = 60 * 3
CHAINS: Dict[Union[Chain, str], ChainInfo] = {
# TESTNETS
"SEPOLIA": ChainInfo(
Expand Down Expand Up @@ -217,16 +218,15 @@ class Settings(BaseSettings):
DEFAULT_CHAIN: Chain = Chain.ETH

# Dns resolver
DNS_IPFS_DOMAIN = "ipfs.public.aleph.sh"
DNS_PROGRAM_DOMAIN = "program.public.aleph.sh"
DNS_INSTANCE_DOMAIN = "instance.public.aleph.sh"
DNS_STATIC_DOMAIN = "static.public.aleph.sh"
DNS_RESOLVERS = ["9.9.9.9", "1.1.1.1"]

class Config:
env_prefix = "ALEPH_"
case_sensitive = False
env_file = ".env"
DNS_IPFS_DOMAIN: ClassVar[str] = "ipfs.public.aleph.sh"
DNS_PROGRAM_DOMAIN: ClassVar[str] = "program.public.aleph.sh"
DNS_INSTANCE_DOMAIN: ClassVar[str] = "instance.public.aleph.sh"
DNS_STATIC_DOMAIN: ClassVar[str] = "static.public.aleph.sh"
DNS_RESOLVERS: ClassVar[List[str]] = ["9.9.9.9", "1.1.1.1"]

model_config = SettingsConfigDict(
env_prefix="ALEPH_", case_sensitive=False, env_file=".env"
)


class MainConfiguration(BaseModel):
Expand All @@ -237,8 +237,7 @@ class MainConfiguration(BaseModel):
path: Path
chain: Chain

class Config:
use_enum_values = True
model_config = SettingsConfigDict(use_enum_values=True)


# Settings singleton
Expand Down Expand Up @@ -294,7 +293,7 @@ def save_main_configuration(file_path: Path, data: MainConfiguration):
Synchronously save a single ChainAccount object as JSON to a file.
"""
with file_path.open("w") as file:
data_serializable = data.dict()
data_serializable = data.model_dump()
data_serializable["path"] = str(data_serializable["path"])
json.dump(data_serializable, file, indent=4)

Expand Down
4 changes: 2 additions & 2 deletions src/aleph/sdk/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ def raise_error(self, status: Dict[str, bool]):
def hostname_from_url(url: Union[HttpUrl, str]) -> Hostname:
"""Extract FQDN from url"""

parsed = urlparse(url)
parsed = urlparse(str(url))
if all([parsed.scheme, parsed.netloc]) is True:
url = parsed.netloc

return Hostname(url)
return Hostname(str(url))


async def get_target_type(fqdn: Hostname) -> Optional[TargetType]:
Expand Down
10 changes: 5 additions & 5 deletions src/aleph/sdk/query/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
ItemType,
MessageConfirmation,
)
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field


class Post(BaseModel):
Expand Down Expand Up @@ -48,9 +48,9 @@ class Post(BaseModel):
ref: Optional[Union[str, Any]] = Field(
description="Other message referenced by this one"
)
address: Optional[str] = Field(description="Address of the sender")

class Config:
allow_extra = False
model_config = ConfigDict(extra="forbid")


class PaginationResponse(BaseModel):
Expand All @@ -64,14 +64,14 @@ class PostsResponse(PaginationResponse):
"""Response from an aleph.im node API on the path /api/v0/posts.json"""

posts: List[Post]
pagination_item = "posts"
pagination_item: str = "posts"


class MessagesResponse(PaginationResponse):
"""Response from an aleph.im node API on the path /api/v0/messages.json"""

messages: List[AlephMessage]
pagination_item = "messages"
pagination_item: str = "messages"


class PriceResponse(BaseModel):
Expand Down
10 changes: 3 additions & 7 deletions src/aleph/sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
from uuid import UUID
from zipfile import BadZipFile, ZipFile

import pydantic_core
from aleph_message.models import ItemHash, MessageType
from aleph_message.models.execution.program import Encoding
from aleph_message.models.execution.volume import MachineVolume
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from jwcrypto.jwa import JWA
from pydantic.json import pydantic_encoder

from aleph.sdk.conf import settings
from aleph.sdk.types import GenericMessage, SEVInfo, SEVMeasurement
Expand Down Expand Up @@ -173,19 +173,15 @@ def extended_json_encoder(obj: Any) -> Any:
elif isinstance(obj, time):
return obj.hour * 3600 + obj.minute * 60 + obj.second + obj.microsecond / 1e6
else:
return pydantic_encoder(obj)
return pydantic_core.to_jsonable_python(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)
return volume_type.model_validate(volume_dict)
except ValueError:
continue
else:
Expand Down
2 changes: 1 addition & 1 deletion src/aleph/sdk/vm/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def __init__(
)

self.cache = {}
self.api_host = connector_url if connector_url else settings.API_HOST
self.api_host = str(connector_url) if connector_url else settings.API_HOST

async def get(self, key: str) -> Optional[bytes]:
sanitized_key = sanitize_cache_key(key)
Expand Down
Loading
Loading