Skip to content
11 changes: 11 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,17 @@ repos:
- id: prettier
exclude: ^(packages/grid/helm|packages/grid/frontend/pnpm-lock.yaml|packages/syft/tests/mongomock|.vscode)

- repo: https://github.com/jsh9/pydoclint
rev: 0.5.6
hooks:
- id: pydoclint
args: [
# --config=packages/syft/pyproject.toml,
--quiet,
--style=google,
--allow-init-docstring=true,
]

# - repo: meta
# hooks:
# - id: identity
Expand Down
1 change: 1 addition & 0 deletions packages/syft/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ dev =
ruff==0.4.7
safety>=2.4.0b2
aiosmtpd==1.4.6
pydoclint==0.5.6

telemetry =
opentelemetry-api==1.27.0
Expand Down
75 changes: 57 additions & 18 deletions packages/syft/src/syft/custom_worker/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class CustomWorkerBuilder:

@cached_property
def builder(self) -> BuilderBase:
"""Returns the appropriate builder instance based on the environment.

Returns:
BuilderBase: An instance of either KubernetesBuilder or DockerBuilder.
"""
if IN_KUBERNETES:
return KubernetesBuilder()
else:
Expand All @@ -39,16 +44,22 @@ def builder(self) -> BuilderBase:
def build_image(
self,
config: WorkerConfig,
tag: str | None = None,
tag: str | None,
**kwargs: Any,
) -> ImageBuildResult:
"""
Builds a Docker image from the given configuration.
"""Builds a Docker image from the given configuration.

Args:
config (WorkerConfig): The configuration for building the Docker image.
tag (str): The tag to use for the image.
"""
tag (str | None): The tag to use for the image. Defaults to None.
**kwargs (Any): Additional keyword arguments for the build process.

Returns:
ImageBuildResult: The result of the image build process.

Raises:
TypeError: If the config type is not recognized.
"""
if isinstance(config, DockerWorkerConfig):
return self._build_dockerfile(config, tag, **kwargs)
elif isinstance(config, CustomWorkerConfig):
Expand All @@ -64,13 +75,18 @@ def push_image(
password: str,
**kwargs: Any,
) -> ImagePushResult:
"""
Pushes a Docker image to the given repo.
"""Pushes a Docker image to the given registry.

Args:
repo (str): The repo to push the image to.
tag (str): The tag to use for the image.
"""
tag (str): The tag of the image to push.
registry_url (str): The URL of the registry.
username (str): The username for registry authentication.
password (str): The password for registry authentication.
**kwargs (Any): Additional keyword arguments for the push process.

Returns:
ImagePushResult: The result of the image push process.
"""
return self.builder.push_image(
tag=tag,
username=username,
Expand All @@ -84,6 +100,16 @@ def _build_dockerfile(
tag: str,
**kwargs: Any,
) -> ImageBuildResult:
"""Builds a Docker image using a Dockerfile.

Args:
config (DockerWorkerConfig): The configuration containing the Dockerfile.
tag (str): The tag to use for the image.
**kwargs (Any): Additional keyword arguments for the build process.

Returns:
ImageBuildResult: The result of the image build process.
"""
return self.builder.build_image(
dockerfile=config.dockerfile,
tag=tag,
Expand All @@ -95,8 +121,18 @@ def _build_template(
config: CustomWorkerConfig,
**kwargs: Any,
) -> ImageBuildResult:
# Builds a Docker pre-made CPU/GPU image template using a CustomWorkerConfig
# remove once GPU is supported
"""Builds a Docker image using a pre-made template.

Args:
config (CustomWorkerConfig): The configuration containing template settings.
**kwargs (Any): Additional keyword arguments for the build process.

Returns:
ImageBuildResult: The result of the image build process.

Raises:
Exception: If GPU support is requested but not supported.
"""
if config.build.gpu:
raise Exception("GPU custom worker is not supported yet")

Expand All @@ -120,16 +156,19 @@ def _build_template(
)

def find_worker_image(self, type: str) -> Path:
"""
Find the Worker Dockerfile and it's context path
- PROD will be in `$APPDIR/grid/`
- DEV will be in `packages/grid/backend/grid/images`
- In both the cases context dir does not matter (unless we're calling COPY)
"""Finds the Worker Dockerfile and its context path.

The production Dockerfile will be located at `$APPDIR/grid/`.
The development Dockerfile will be located in `packages/grid/backend/grid/images`.

Args:
type (str): The type of worker.
type (str): The type of worker (e.g., 'cpu' or 'gpu').

Returns:
Path: The path to the Dockerfile.

Raises:
FileNotFoundError: If the Dockerfile is not found in any of the expected locations.
"""
filename = f"worker_{type}.dockerfile"
lookup_paths = [
Expand Down
9 changes: 0 additions & 9 deletions packages/syft/src/syft/dev/prof.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@

@contextlib.contextmanager
def pyspy() -> None: # type: ignore
"""Profile a block of code using py-spy. Intended for development purposes only.

Example:
```
with pyspy():
# do some work
a = [i for i in range(1000000)]
```
"""
fd, fname = tempfile.mkstemp(".svg")
os.close(fd)

Expand Down
6 changes: 3 additions & 3 deletions packages/syft/src/syft/serde/arrow.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ def numpyutf8toarray(input_index: np.ndarray) -> np.ndarray:


def arraytonumpyutf8(string_list: str | np.ndarray) -> bytes:
"""Encodes string Numpyarray to utf-8 encoded numpy array.
"""Encodes string Numpyarray to utf-8 encoded numpy array.

Args:
string_list (np.ndarray): NumpyArray to be encoded
string_list (str | np.ndarray): NumpyArray or string to be encoded.

Returns:
bytes: serialized utf-8 encoded int Numpy array
bytes: serialized utf-8 encoded int Numpy array.
"""
array_shape = np.array(string_list).shape
string_list = np.array(string_list).flatten()
Expand Down
11 changes: 6 additions & 5 deletions packages/syft/src/syft/serde/lib_service_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,16 @@ def init_child(
child_obj: type | object,
absolute_path: str,
) -> Self | None:
"""Get the child of parent as a CMPBase object
"""Get the child of parent as a CMPBase object.

Args:
parent_obj (_type_): parent object
child_path (_type_): _description_
child_obj (_type_): _description_
parent_obj (type | object): The parent object.
child_path (str): The path of the child object.
child_obj (type | object): The child object.
absolute_path (str): The absolute path of the child object.

Returns:
_type_: _description_
Self | None: The initialized CMPBase object or None if not applicable.
"""
parent_is_parent_module = CMPBase.parent_is_parent_module(parent_obj, child_obj)
if CMPBase.isfunction(child_obj) and parent_is_parent_module:
Expand Down
34 changes: 18 additions & 16 deletions packages/syft/src/syft/serde/serializable.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

module_type = type(syft)


T = TypeVar("T", bound=type)


Expand All @@ -26,25 +25,28 @@ def serializable(
Recursively serialize attributes of the class.

Args:
`attrs` : List of attributes to serialize
`without` : List of attributes to exclude from serialization
`inherit` : Whether to inherit serializable attribute list from base class
`inheritable` : Whether the serializable attribute list can be inherited by derived class

For non-pydantic classes,
- `inheritable=True` => Derived classes will include base class `attrs`
- `inheritable=False` => Derived classes will not include base class `attrs`
- `inherit=True` => Base class `attrs` + `attrs` - `without`
- `inherit=False` => `attrs` - `without`

For pydantic classes,
attrs (list[str] | None): List of attributes to serialize. Defaults to None.
without (list[str] | None): List of attributes to exclude from serialization. Defaults to None.
inherit (bool | None): Whether to inherit the serializable attribute list from the base class. Defaults to True.
inheritable (bool | None): Whether the serializable attribute list can be inherited by derived
classes. Defaults to True.
canonical_name (str | None): The canonical name for the serialization. Defaults to None.
version (int | None): The version number for the serialization. Defaults to None.

For non-pydantic classes:
- `inheritable=True` => Derived classes will include base class `attrs`.
- `inheritable=False` => Derived classes will not include base class `attrs`.
- `inherit=True` => Base class `attrs` + `attrs` - `without`.
- `inherit=False` => `attrs` - `without`.

For pydantic classes:
- No need to provide `attrs`. They will be automatically inferred.
- Providing `attrs` will override the inferred attributes.
- `without` will work only on attributes of `Optional` type
- `inherit`, `inheritable` will not work as pydantic inherits by default
- `without` will work only on attributes of `Optional` type.
- `inherit`, `inheritable` will not work as pydantic inherits by default.

Returns:
Decorated class
Callable[[T], T]: The decorated class.
"""

def rs_decorator(cls: T) -> T:
Expand Down
Loading