Skip to content

Commit

Permalink
Update and modify files for the project
Browse files Browse the repository at this point in the history
- Updated files:
  - src/bee_py/bee.py
  - src/bee_py/chunk/serialize.py
  - src/bee_py/modules/bytes.py
  - src/bee_py/types/type.py
  - src/bee_py/utils/http.py
  - src/bee_py/utils/type.py
  - tests/conftest.py
  - tests/unit/chunk/test_soc.py
  - tests/unit/test_bee.py
  • Loading branch information
Aviksaikat committed Dec 11, 2023
1 parent c41d6ac commit d38a55e
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 119 deletions.
9 changes: 7 additions & 2 deletions src/bee_py/bee.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class Bee:
# Ky instance that defines connection to Bee node
request_options: BeeRequestOptions

def __init__(self, url: str, options: Optional[BeeOptions] = None):
def __init__(self, url: str, options: Optional[Union[BeeOptions, dict]] = None):
"""
Constructs a new Bee instance.
Expand All @@ -115,6 +115,11 @@ def __init__(self, url: str, options: Optional[BeeOptions] = None):
# which could lead to double slash in URL to which Bee responds with
# unnecessary redirects.
self.url = strip_last_slash(url)
if options:
if not isinstance(options, BeeOptions):
if not isinstance(options, dict):
msg = f"Expected: Options must be of type dict or BeeOptions. Got: {type(options)}"
raise TypeError(msg)

if options and "signer" in options:
self.signer = sign(options["signer"])
Expand All @@ -124,7 +129,7 @@ def __init__(self, url: str, options: Optional[BeeOptions] = None):
"baseURL": self.url,
**(
{
"timeout": int(options.get("timeout", 300)),
"timeout": options.get("timeout", 300),
"headers": options.get("headers", {}),
"onRequest": options.get("onRequest", True),
}
Expand Down
11 changes: 5 additions & 6 deletions src/bee_py/chunk/serialize.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from collections.abc import ByteString, Sequence
from itertools import chain
# from collections.abc import ByteString, Sequence
# from itertools import chain


def serialize_bytes(*arrays: Sequence[ByteString]) -> ByteString:
def serialize_bytes(*arrays: bytes) -> bytes:
"""
Serializes a sequence of byte arrays into a single byte array.
Args:
*arrays (Sequence[ByteString]): The sequence of byte arrays to serialize.
*arrays (bytes): The sequence of byte arrays to serialize.
Returns:
ByteString: The serialized byte array.
"""
flattened_bytes = chain.from_iterable(arrays)
return bytes(flattened_bytes)
return b"".join(arrays)
3 changes: 2 additions & 1 deletion src/bee_py/modules/bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from bee_py.utils.headers import extract_upload_headers
from bee_py.utils.http import http
from bee_py.utils.logging import logger
from bee_py.utils.type import make_tag_uid
from bee_py.utils.type import assert_request_options, make_tag_uid

BYTES_ENDPOINT = "bytes"

Expand All @@ -29,6 +29,7 @@ def upload(
Returns:
UploadResult: The result of the upload operation.
"""
assert_request_options(request_options)

headers = {
"Content-Type": "application/octet-stream",
Expand Down
48 changes: 5 additions & 43 deletions src/bee_py/types/type.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import json

# from abc import abstractmethod
from enum import Enum
from typing import Annotated, Any, Callable, Generic, NewType, Optional, TypeVar, Union

from ape.managers.accounts import AccountAPI
from ape.types import AddressType

# from eth_pydantic_types import HexBytes
# from eth_pydantic_types import HexBytes as BaseHexBytes
from pydantic import BaseModel, Field, validator
from swarm_cid.swarm_cid import CIDv1

# from requests import PreparedRequest, Response
from typing_extensions import TypeAlias

Expand Down Expand Up @@ -67,20 +64,6 @@
AddressPrefix: TypeAlias = str


# class HexBytes(BaseHexBytes):
# """
# A class representing bytes as a hex-str.
# """

# @classmethod
# def __get_validators__(cls):
# yield cls._validate

# @classmethod
# def _validate(cls, v):
# return HexBytes(v)


class BeeRequest(BaseModel):
"""
Bee request model.
Expand Down Expand Up @@ -344,25 +327,11 @@ def is_object(value: Any) -> bool:
return value is not None and isinstance(value, dict)


class UploadOptions:
"""Represents the options for uploading a file to Bee."""

pin: Optional[bool]
encrypt: Optional[bool]
tag: Optional[int]
deferred: Optional[bool]

def __init__(
self,
pin: Optional[bool] = None,
encrypt: Optional[bool] = None,
tag: Optional[int] = None,
deferred: Optional[bool] = True, # noqa: FBT002
):
self.pin = pin
self.encrypt = encrypt
self.tag = tag
self.deferred = deferred
class UploadOptions(BaseModel):
pin: Optional[bool] = False
encrypt: Optional[bool] = False
tag: Optional[int] = None
deferred: Optional[bool] = True


class FileHeaders(BaseModel):
Expand Down Expand Up @@ -864,13 +833,6 @@ class UploadResultWithCid(UploadResult):
cid: Callable[[], CIDv1]


class UploadOptions(BaseModel):
pin: Optional[bool] = False
encrypt: Optional[bool] = False
tag: Optional[int] = None
deferred: Optional[bool] = True


class FileUploadOptions(UploadOptions):
size: Optional[int] = None
content_type: Optional[str] = None
Expand Down
3 changes: 3 additions & 0 deletions src/bee_py/utils/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def http(options: Union[BeeRequestOptions, dict], config: dict) -> requests.Resp
**options,
}
request_config = maybe_run_on_request_hook(options, request_config)
if "http" not in request_config:
msg = f"Invalid URL: {request_config['url']}"
raise TypeError(msg)
response = requests.request(**request_config)
return response
except Exception as e:
Expand Down
57 changes: 41 additions & 16 deletions src/bee_py/utils/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
PUBKEY_HEX_LENGTH,
REFERENCE_HEX_LENGTH,
AllTagsOptions,
BeeRequestOptions,
FeedType,
ReferenceOrENS,
Tag,
UploadOptions,
UploadResult,
UploadResultWithCid,
)
from bee_py.utils.error import BeeError
from bee_py.utils.error import BeeArgumentError, BeeError
from bee_py.utils.hex import assert_hex_string, is_hex_string, is_prefixed_hex_string


Expand Down Expand Up @@ -160,15 +162,31 @@ def assert_request_options(options: Any, name: str = "RequestOptions") -> None:
if options is None:
return

if options.retry:
if not isinstance(options.retry, int) or options.retry < 0:
if not isinstance(options, BeeRequestOptions):
if not isinstance(options, dict):
msg = f"Options must be an instance of BeeRequestOptions or dictionary. Got: {type(options)}"
raise TypeError(msg)

if isinstance(options, BeeRequestOptions):
options = options.model_dump()

if options.get("retry", None):
if (
not isinstance(
options.get(
"retry",
),
int,
)
or options.get("retry", None) < 0
):
msg = f"{name}.retry has to be a non-negative integer!"
raise ValueError(msg)
raise BeeArgumentError(msg, options.get("retry"))

if options.timeout:
if not isinstance(options.timeout, int) or options.timeout < 0:
if options.get("timeout", None):
if not isinstance(options.get("timeout"), int) or options.get("timeout", None) < 0:
msg = f"{name}.timeout has to be a non-negative integer!"
raise ValueError(msg)
raise BeeArgumentError(msg, options.get("timeout"))


def assert_upload_options(value: Any, name: str = "UploadOptions") -> None:
Expand All @@ -185,19 +203,26 @@ def assert_upload_options(value: Any, name: str = "UploadOptions") -> None:
"""
assert_request_options(value, name)

if not isinstance(value, UploadOptions):
value = UploadOptions.model_validate(value)

options = value

if options.pin and not isinstance(options.pin, bool):
msg = f"options.pin property in {name} has to be boolean or undefined!"
msg = f"options.pin property in {name} has to be boolean or None!"
raise TypeError(msg)

if options.encrypt and not isinstance(options.encrypt, bool):
msg = f"options.encrypt property in {name} has to be boolean or undefined!"
msg = f"options.encrypt property in {name} has to be boolean or None!"
raise TypeError(msg)

if options.tag and (not isinstance(options.tag, int) and options.tag >= 0):
msg = f"options.tag property in {name} has to be number or undefined!"
raise TypeError(msg)
if options.tag:
if not isinstance(options.tag, int):
msg = f"options.tag property in {name} has to be number or None!"
raise TypeError(msg)
if options.tag <= 0:
msg = f"options.tag property in {name} has to be non-negative"
raise BeeArgumentError(msg, options.tag)


def assert_file_upload_options(value: Any, name: str = "FileUploadOptions") -> None:
Expand All @@ -218,15 +243,15 @@ def assert_file_upload_options(value: Any, name: str = "FileUploadOptions") -> N
options = value

if options.size and not isinstance(options.size, int):
msg = "size property in FileUploadOptions has to be number or undefined!"
msg = "size property in FileUploadOptions has to be number or None!"
raise TypeError(msg)

if options.size and options.size < 0:
msg = "size property in FileUploadOptions has to be a non-negative integer"
raise ValueError(msg)

if options.content_type and not isinstance(options.content_type, str):
msg = "contentType property in FileUploadOptions has to be string or undefined!"
msg = "contentType property in FileUploadOptions has to be string or None!"
raise TypeError(msg)


Expand All @@ -249,12 +274,12 @@ def assert_collection_upload_options(value: Any, name: str = "CollectionUploadOp

if options.index_document:
if not isinstance(options.index_document, str):
msg = "indexDocument property in CollectionUploadOptions has to be string or undefined!"
msg = "indexDocument property in CollectionUploadOptions has to be string or None!"
raise TypeError(msg)

if options.error_document:
if not isinstance(options.error_document, str):
msg = "errorDocument property in CollectionUploadOptions has to be string or undefined!"
msg = "errorDocument property in CollectionUploadOptions has to be string or None!"
raise TypeError(msg)


Expand Down
29 changes: 3 additions & 26 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,29 +329,6 @@ def test_chunk_encrypted_reference_cid() -> str:
return "bah5acgzazjrvpieogf6rl3cwb7xtjzgel6hrt4a4g4vkody5u4v7u7y2im4muy2xuchdc7iv5rla73zu4tcf7dyz6aodokvhb4o2ok72p4negoa" # noqa: E501


def batch_id_assertion(executor):
with pytest.raises(TypeError):
executor(1)

with pytest.raises(TypeError):
executor(True)

with pytest.raises(TypeError):
executor({})

with pytest.raises(TypeError):
executor(None)

with pytest.raises(TypeError):
executor([])

with pytest.raises(TypeError):
executor("")

# Not a valid hexstring (ZZZ)
with pytest.raises(TypeError):
executor("ZZZfb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd")

# Prefixed hexstring is not accepted
with pytest.raises(TypeError):
executor("0x634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd")
@pytest.fixture
def test_batch_id() -> str:
return "ca6357a08e317d15ec560fef34e4c45f8f19f01c372aa70f1da72bfa7f1a4338"
3 changes: 1 addition & 2 deletions tests/unit/chunk/test_soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,5 @@ def test_single_owner_chunk_creation():
soc_address = bytes_to_hex(soc.address)
owner = soc.owner

# * Remove the 0x
assert soc_address[2:] == soc_hash
assert soc_address == soc_hash
assert owner == signer.address
Loading

0 comments on commit d38a55e

Please sign in to comment.