diff --git a/notebooks/api/0.8/07-domain-register-control-flow.ipynb b/notebooks/api/0.8/07-domain-register-control-flow.ipynb index ff319fa8ea3..7f15791d463 100644 --- a/notebooks/api/0.8/07-domain-register-control-flow.ipynb +++ b/notebooks/api/0.8/07-domain-register-control-flow.ipynb @@ -266,7 +266,7 @@ "metadata": {}, "outputs": [], "source": [ - "assert root_client.metadata.signup_enabled == False\n", + "assert root_client.settings.get().signup_enabled == False\n", "assert isinstance(response_1, sy.SyftSuccess)\n", "assert isinstance(response_2, sy.SyftError)\n", "assert isinstance(response_3, sy.SyftError)" diff --git a/notebooks/tutorials/data-engineer/02-deployment-types.ipynb b/notebooks/tutorials/data-engineer/02-deployment-types.ipynb index ab5fc76428e..dad98683a70 100644 --- a/notebooks/tutorials/data-engineer/02-deployment-types.ipynb +++ b/notebooks/tutorials/data-engineer/02-deployment-types.ipynb @@ -73,6 +73,16 @@ ")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "86e66c8b-afa4-4236-a362-7ec9e07a7063", + "metadata": {}, + "outputs": [], + "source": [ + "assert memory_node is not None" + ] + }, { "cell_type": "markdown", "id": "4573b485", @@ -89,13 +99,23 @@ "outputs": [], "source": [ "webserver_node = sy.Orchestra.launch(\n", - " name=\"Arbitrary Dev Node\",\n", + " name=\"Arbitrary Webserver Dev Node\",\n", " dev_mode=True,\n", " reset=True,\n", - " port=80\n", + " port=8081\n", ")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "86ce3464-a51c-4870-a293-e479c08c66bc", + "metadata": {}, + "outputs": [], + "source": [ + "assert webserver_node is not None" + ] + }, { "cell_type": "markdown", "id": "dd74621a", @@ -353,7 +373,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.10.12" } }, "nbformat": 4, diff --git a/packages/syft/src/syft/client/client.py b/packages/syft/src/syft/client/client.py index 73bbcb558f7..8fad938c6ab 100644 --- a/packages/syft/src/syft/client/client.py +++ b/packages/syft/src/syft/client/client.py @@ -42,7 +42,7 @@ from ..serde.serialize import _serialize from ..service.context import NodeServiceContext from ..service.metadata.node_metadata import NodeMetadataJSON -from ..service.metadata.node_metadata import NodeMetadataV2 +from ..service.metadata.node_metadata import NodeMetadataV3 from ..service.response import SyftError from ..service.response import SyftSuccess from ..service.user.user import UserCreate @@ -597,7 +597,7 @@ def exchange_route(self, client: Self) -> Union[SyftSuccess, SyftError]: result = self.api.services.network.exchange_credentials_with( self_node_route=self_node_route, remote_node_route=remote_node_route, - remote_node_verify_key=client.metadata.to(NodeMetadataV2).verify_key, + remote_node_verify_key=client.metadata.to(NodeMetadataV3).verify_key, ) return result diff --git a/packages/syft/src/syft/node/node.py b/packages/syft/src/syft/node/node.py index 85bf0f5cc5f..30597a89d03 100644 --- a/packages/syft/src/syft/node/node.py +++ b/packages/syft/src/syft/node/node.py @@ -65,7 +65,7 @@ from ..service.dataset.dataset_service import DatasetService from ..service.enclave.enclave_service import EnclaveService from ..service.metadata.metadata_service import MetadataService -from ..service.metadata.node_metadata import NodeMetadataV2 +from ..service.metadata.node_metadata import NodeMetadataV3 from ..service.network.network_service import NetworkService from ..service.notification.notification_service import NotificationService from ..service.object_search.migration_state_service import MigrateStateService @@ -82,7 +82,7 @@ from ..service.service import AbstractService from ..service.service import ServiceConfigRegistry from ..service.service import UserServiceConfigRegistry -from ..service.settings.settings import NodeSettings +from ..service.settings.settings import NodeSettingsV2 from ..service.settings.settings_service import SettingsService from ..service.settings.settings_stash import SettingsStash from ..service.user.user import User @@ -741,43 +741,35 @@ def _get_service_method_from_path(self, path: str) -> Callable: return getattr(service_obj, method_name) @property - def metadata(self) -> NodeMetadataV2: + def settings(self) -> NodeSettingsV2: + settings_stash = SettingsStash(store=self.document_store) + settings = settings_stash.get_all(self.signing_key.verify_key) + if settings.is_ok() and len(settings.ok()) > 0: + settings_data = settings.ok()[0] + return settings_data + + @property + def metadata(self) -> NodeMetadataV3: name = "" - deployed_on = "" organization = "" - on_board = False description = "" - signup_enabled = False - admin_email = "" show_warnings = self.enable_warnings + settings_data = self.settings + name = settings_data.name + organization = settings_data.organization + description = settings_data.description + show_warnings = settings_data.show_warnings - settings_stash = SettingsStash(store=self.document_store) - settings = settings_stash.get_all(self.signing_key.verify_key) - if settings.is_ok() and len(settings.ok()) > 0: - settings_data = settings.ok()[0] - name = settings_data.name - deployed_on = settings_data.deployed_on - organization = settings_data.organization - on_board = settings_data.on_board - description = settings_data.description - signup_enabled = settings_data.signup_enabled - admin_email = settings_data.admin_email - show_warnings = settings_data.show_warnings - - return NodeMetadataV2( + return NodeMetadataV3( name=name, id=self.id, verify_key=self.verify_key, highest_version=SYFT_OBJECT_VERSION_1, lowest_version=SYFT_OBJECT_VERSION_1, syft_version=__version__, - deployed_on=deployed_on, description=description, organization=organization, - on_board=on_board, node_type=self.node_type.value, - signup_enabled=signup_enabled, - admin_email=admin_email, node_side_type=self.node_side_type.value, show_warnings=show_warnings, ) @@ -967,7 +959,7 @@ def get_unauthed_context( ) -> NodeServiceContext: return UnauthedServiceContext(node=self, login_credentials=login_credentials) - def create_initial_settings(self, admin_email: str) -> Optional[NodeSettings]: + def create_initial_settings(self, admin_email: str) -> Optional[NodeSettingsV2]: if self.name is None: self.name = random_name() try: @@ -981,8 +973,11 @@ def create_initial_settings(self, admin_email: str) -> Optional[NodeSettings]: # as enclaves do not have superusers if self.node_type == NodeType.ENCLAVE: flags.CAN_REGISTER = True - new_settings = NodeSettings( + new_settings = NodeSettingsV2( + id=self.id, name=self.name, + verify_key=self.verify_key, + node_type=self.node_type, deployed_on=datetime.now().date().strftime("%m/%d/%Y"), signup_enabled=flags.CAN_REGISTER, admin_email=admin_email, diff --git a/packages/syft/src/syft/protocol/protocol_version.json b/packages/syft/src/syft/protocol/protocol_version.json index 41761d9890d..f28c32c12da 100644 --- a/packages/syft/src/syft/protocol/protocol_version.json +++ b/packages/syft/src/syft/protocol/protocol_version.json @@ -749,5 +749,23 @@ } } } + }, + "dev": { + "object_versions": { + "NodeMetadata": { + "3": { + "version": 3, + "hash": "3cc67abf394a805066a88aef0bea15bde609b9ecbe7ec15172eac5e7a0b7ef7c", + "action": "add" + } + }, + "NodeSettings": { + "2": { + "version": 2, + "hash": "29a82afcb006a044b6ae04c6ea8a067d145d28b4210bb038ea9fa86ebde108c8", + "action": "add" + } + } + } } } diff --git a/packages/syft/src/syft/service/metadata/migrations.py b/packages/syft/src/syft/service/metadata/migrations.py index 58d09021eb2..91cabf0357d 100644 --- a/packages/syft/src/syft/service/metadata/migrations.py +++ b/packages/syft/src/syft/service/metadata/migrations.py @@ -1,8 +1,14 @@ +# stdlib +from typing import Callable + # relative from ...types.syft_migration import migrate +from ...types.transforms import TransformContext +from ...types.transforms import drop from ...types.transforms import rename from .node_metadata import NodeMetadata from .node_metadata import NodeMetadataV2 +from .node_metadata import NodeMetadataV3 @migrate(NodeMetadata, NodeMetadataV2) @@ -19,3 +25,31 @@ def downgrade_metadata_v2_to_v1(): rename("highest_version", "highest_object_version"), rename("lowest_version", "lowest_object_version"), ] + + +@migrate(NodeMetadataV2, NodeMetadataV3) +def upgrade_metadata_v2_to_v3(): + return [drop(["deployed_on", "on_board", "signup_enabled", "admin_email"])] + + +def _downgrade_metadata_v3_to_v2() -> Callable: + def set_defaults_from_settings(context: TransformContext) -> TransformContext: + # Extract from settings if node is attached to context + if context.node is not None: + context.output["deployed_on"] = context.node.settings.deployed_on + context.output["on_board"] = context.node.settings.on_board + context.output["signup_enabled"] = context.node.settings.signup_enabled + context.output["admin_email"] = context.node.settings.admin_email + else: + # Else set default value + context.output["signup_enabled"] = False + context.output["admin_email"] = "" + + return context + + return set_defaults_from_settings + + +@migrate(NodeMetadataV3, NodeMetadataV2) +def downgrade_metadata_v3_to_v2(): + return [_downgrade_metadata_v3_to_v2()] diff --git a/packages/syft/src/syft/service/metadata/node_metadata.py b/packages/syft/src/syft/service/metadata/node_metadata.py index 05f61ba59e7..07cab49c421 100644 --- a/packages/syft/src/syft/service/metadata/node_metadata.py +++ b/packages/syft/src/syft/service/metadata/node_metadata.py @@ -18,6 +18,7 @@ from ...serde.serializable import serializable from ...types.syft_object import SYFT_OBJECT_VERSION_1 from ...types.syft_object import SYFT_OBJECT_VERSION_2 +from ...types.syft_object import SYFT_OBJECT_VERSION_3 from ...types.syft_object import StorableObjectType from ...types.syft_object import SyftObject from ...types.transforms import convert_types @@ -120,6 +121,31 @@ def check_version(self, client_version: str) -> bool: ) +@serializable() +class NodeMetadataV3(SyftObject): + __canonical_name__ = "NodeMetadata" + __version__ = SYFT_OBJECT_VERSION_3 + + name: str + id: UID + verify_key: SyftVerifyKey + highest_version: int + lowest_version: int + syft_version: str + node_type: NodeType = NodeType.DOMAIN + organization: str = "OpenMined" + description: str = "Text" + node_side_type: str + show_warnings: bool + + def check_version(self, client_version: str) -> bool: + return check_version( + client_version=client_version, + server_version=self.syft_version, + server_name=self.name, + ) + + @serializable() class NodeMetadataJSON(BaseModel, StorableObjectType): metadata_version: int @@ -130,12 +156,8 @@ class NodeMetadataJSON(BaseModel, StorableObjectType): lowest_object_version: Optional[int] syft_version: str node_type: str = NodeType.DOMAIN.value - deployed_on: str = "Date" organization: str = "OpenMined" - on_board: bool = False description: str = "My cool domain" - signup_enabled: bool - admin_email: str node_side_type: str show_warnings: bool supported_protocols: List = [] @@ -155,7 +177,7 @@ def check_version(self, client_version: str) -> bool: ) -@transform(NodeMetadataV2, NodeMetadataJSON) +@transform(NodeMetadataV3, NodeMetadataJSON) def metadata_to_json() -> List[Callable]: return [ drop(["__canonical_name__"]), @@ -166,7 +188,7 @@ def metadata_to_json() -> List[Callable]: ] -@transform(NodeMetadataJSON, NodeMetadataV2) +@transform(NodeMetadataJSON, NodeMetadataV3) def json_to_metadata() -> List[Callable]: return [ drop(["metadata_version", "supported_protocols"]), diff --git a/packages/syft/src/syft/service/network/network_service.py b/packages/syft/src/syft/service/network/network_service.py index 66ef7dee5d6..6511d259b44 100644 --- a/packages/syft/src/syft/service/network/network_service.py +++ b/packages/syft/src/syft/service/network/network_service.py @@ -17,6 +17,7 @@ from ...node.credentials import SyftVerifyKey from ...node.worker_settings import WorkerSettings from ...serde.serializable import serializable +from ...service.settings.settings import NodeSettingsV2 from ...store.document_store import BaseUIDStoreStash from ...store.document_store import DocumentStore from ...store.document_store import PartitionKey @@ -30,7 +31,7 @@ from ...util.telemetry import instrument from ..context import AuthedServiceContext from ..data_subject.data_subject import NamePartitionKey -from ..metadata.node_metadata import NodeMetadataV2 +from ..metadata.node_metadata import NodeMetadataV3 from ..response import SyftError from ..response import SyftSuccess from ..service import AbstractService @@ -401,8 +402,15 @@ def node_route_to_http_connection( return HTTPConnection(url=url, proxy_target_uid=obj.proxy_target_uid) -@transform(NodeMetadataV2, NodePeer) +@transform(NodeMetadataV3, NodePeer) def metadata_to_peer() -> List[Callable]: return [ keep(["id", "name", "verify_key", "node_type", "admin_email"]), ] + + +@transform(NodeSettingsV2, NodePeer) +def settings_to_peer() -> List[Callable]: + return [ + keep(["id", "name", "verify_key", "node_type", "admin_email"]), + ] diff --git a/packages/syft/src/syft/service/network/node_peer.py b/packages/syft/src/syft/service/network/node_peer.py index bb9532f27e0..07342adc818 100644 --- a/packages/syft/src/syft/service/network/node_peer.py +++ b/packages/syft/src/syft/service/network/node_peer.py @@ -17,7 +17,7 @@ from ...types.syft_object import SyftObject from ...types.uid import UID from ..context import NodeServiceContext -from ..metadata.node_metadata import NodeMetadataV2 +from ..metadata.node_metadata import NodeMetadataV3 from .routes import HTTPNodeRoute from .routes import NodeRoute from .routes import NodeRouteType @@ -108,9 +108,9 @@ def existed_route(self, route: NodeRoute) -> Tuple[bool, Optional[int]]: @staticmethod def from_client(client: SyftClient) -> Self: if not client.metadata: - raise Exception("Client has have metadata first") + raise Exception("Client has to have metadata first") - peer = client.metadata.to(NodeMetadataV2).to(NodePeer) + peer = client.metadata.to(NodeMetadataV3).to(NodePeer) route = connection_to_route(client.connection) peer.node_routes.append(route) return peer diff --git a/packages/syft/src/syft/service/network/routes.py b/packages/syft/src/syft/service/network/routes.py index e77e62d005f..d8b29316b9e 100644 --- a/packages/syft/src/syft/service/network/routes.py +++ b/packages/syft/src/syft/service/network/routes.py @@ -64,7 +64,7 @@ def validate_with_context(self, context: AuthedServiceContext) -> NodePeer: return SyftError(message="Signature Verification Failed in ping") # Step 2: Create a Node Peer with the given route - self_node_peer = context.node.metadata.to(NodePeer) + self_node_peer = context.node.settings.to(NodePeer) self_node_peer.node_routes.append(self) return self_node_peer diff --git a/packages/syft/src/syft/service/project/project.py b/packages/syft/src/syft/service/project/project.py index 5ad6cbdf2ae..2a170af94e0 100644 --- a/packages/syft/src/syft/service/project/project.py +++ b/packages/syft/src/syft/service/project/project.py @@ -31,7 +31,7 @@ from ...node.credentials import SyftVerifyKey from ...serde.serializable import serializable from ...serde.serialize import _serialize -from ...service.metadata.node_metadata import NodeMetadataV2 +from ...service.metadata.node_metadata import NodeMetadataV3 from ...store.linked_obj import LinkedObject from ...types.datetime import DateTime from ...types.identity import Identity @@ -64,7 +64,7 @@ class EventAlreadyAddedException(SyftException): pass -@transform(NodeMetadataV2, NodeIdentity) +@transform(NodeMetadataV3, NodeIdentity) def metadata_to_node_identity() -> List[Callable]: return [rename("id", "node_id"), rename("name", "node_name")] @@ -1232,7 +1232,7 @@ def to_node_identity(val: Union[SyftClient, NodeIdentity]): if isinstance(val, NodeIdentity): return val elif isinstance(val, SyftClient): - metadata = val.metadata.to(NodeMetadataV2) + metadata = val.metadata.to(NodeMetadataV3) return metadata.to(NodeIdentity) else: raise SyftException( diff --git a/packages/syft/src/syft/service/request/request.py b/packages/syft/src/syft/service/request/request.py index 22a7a03f71e..f25aae49849 100644 --- a/packages/syft/src/syft/service/request/request.py +++ b/packages/syft/src/syft/service/request/request.py @@ -241,7 +241,6 @@ def _repr_html_(self) -> Any: ) metadata = api.services.metadata.get_metadata() - admin_email = metadata.admin_email node_name = api.node_name.capitalize() if api.node_name is not None else "" email_str = ( @@ -266,7 +265,7 @@ def _repr_html_(self) -> Any:
Changes: {str_changes}
Status: {self.status}
Requested on: {node_name} of type \ - {metadata.node_type.value.capitalize()} owned by {admin_email}
+ {metadata.node_type.value.capitalize()}Requested by: {self.requesting_user_name} {email_str} {institution_str}
diff --git a/packages/syft/src/syft/service/settings/__init__.py b/packages/syft/src/syft/service/settings/__init__.py new file mode 100644 index 00000000000..80eb6c422b0 --- /dev/null +++ b/packages/syft/src/syft/service/settings/__init__.py @@ -0,0 +1,2 @@ +# relative +from .migrations import * # noqa: F403 diff --git a/packages/syft/src/syft/service/settings/migrations.py b/packages/syft/src/syft/service/settings/migrations.py new file mode 100644 index 00000000000..49dcaf67b02 --- /dev/null +++ b/packages/syft/src/syft/service/settings/migrations.py @@ -0,0 +1,32 @@ +# stdlib +from typing import Callable + +# relative +from ...types.syft_migration import migrate +from ...types.transforms import TransformContext +from ...types.transforms import drop +from .settings import NodeSettings +from .settings import NodeSettingsV2 + + +def set_from_node_to_key(node_attr: str, key: str) -> Callable: + def extract_from_node(context: TransformContext) -> TransformContext: + context.output[key] = getattr(context.node, node_attr) + return context + + return extract_from_node + + +@migrate(NodeSettings, NodeSettingsV2) +def upgrade_metadata_v1_to_v2(): + return [ + set_from_node_to_key("verify_key", "verify_key"), + set_from_node_to_key("node_type", "node_type"), + ] + + +@migrate(NodeSettingsV2, NodeSettings) +def downgrade_metadata_v2_to_v1(): + return [ + drop(["verify_key", "node_type"]), + ] diff --git a/packages/syft/src/syft/service/settings/settings.py b/packages/syft/src/syft/service/settings/settings.py index 1cdda879227..fc16195c0aa 100644 --- a/packages/syft/src/syft/service/settings/settings.py +++ b/packages/syft/src/syft/service/settings/settings.py @@ -2,9 +2,12 @@ # relative from ...abstract_node import NodeSideType +from ...abstract_node import NodeType +from ...node.credentials import SyftVerifyKey from ...serde.serializable import serializable from ...types.syft_object import PartialSyftObject from ...types.syft_object import SYFT_OBJECT_VERSION_1 +from ...types.syft_object import SYFT_OBJECT_VERSION_2 from ...types.syft_object import SyftObject from ...types.uid import UID @@ -44,3 +47,29 @@ class NodeSettings(SyftObject): admin_email: str node_side_type: NodeSideType = NodeSideType.HIGH_SIDE show_warnings: bool + + +@serializable() +class NodeSettingsV2(SyftObject): + __canonical_name__ = "NodeSettings" + __version__ = SYFT_OBJECT_VERSION_2 + __repr_attrs__ = [ + "name", + "organization", + "deployed_on", + "signup_enabled", + "admin_email", + ] + + id: UID + name: str = "Node" + deployed_on: str + organization: str = "OpenMined" + verify_key: SyftVerifyKey + on_board: bool = True + description: str = "Text" + node_type: NodeType = NodeType.DOMAIN + signup_enabled: bool + admin_email: str + node_side_type: NodeSideType = NodeSideType.HIGH_SIDE + show_warnings: bool diff --git a/packages/syft/src/syft/service/settings/settings_service.py b/packages/syft/src/syft/service/settings/settings_service.py index 601003f1ae0..d0e8a92dcef 100644 --- a/packages/syft/src/syft/service/settings/settings_service.py +++ b/packages/syft/src/syft/service/settings/settings_service.py @@ -19,8 +19,8 @@ from ..service import AbstractService from ..service import service_method from ..warnings import HighSideCRUDWarning -from .settings import NodeSettings from .settings import NodeSettingsUpdate +from .settings import NodeSettingsV2 from .settings_stash import SettingsStash @@ -49,7 +49,7 @@ def get(self, context: UnauthedServiceContext) -> Result[Ok, Err]: @service_method(path="settings.set", name="set") def set( - self, context: AuthedServiceContext, settings: NodeSettings + self, context: AuthedServiceContext, settings: NodeSettingsV2 ) -> Result[Ok, Err]: """Set a new the Node Settings""" print("Here!") diff --git a/packages/syft/src/syft/service/settings/settings_stash.py b/packages/syft/src/syft/service/settings/settings_stash.py index 924e2915d93..35aa58486e8 100644 --- a/packages/syft/src/syft/service/settings/settings_stash.py +++ b/packages/syft/src/syft/service/settings/settings_stash.py @@ -13,7 +13,7 @@ from ...store.document_store import PartitionSettings from ...types.uid import UID from ...util.telemetry import instrument -from .settings import NodeSettings +from .settings import NodeSettingsV2 NamePartitionKey = PartitionKey(key="name", type_=str) ActionIDsPartitionKey = PartitionKey(key="action_ids", type_=List[UID]) @@ -22,17 +22,17 @@ @instrument @serializable() class SettingsStash(BaseUIDStoreStash): - object_type = NodeSettings + object_type = NodeSettingsV2 settings: PartitionSettings = PartitionSettings( - name=NodeSettings.__canonical_name__, object_type=NodeSettings + name=NodeSettingsV2.__canonical_name__, object_type=NodeSettingsV2 ) def __init__(self, store: DocumentStore) -> None: super().__init__(store=store) def set( - self, credentials: SyftVerifyKey, settings: NodeSettings - ) -> Result[NodeSettings, str]: + self, credentials: SyftVerifyKey, settings: NodeSettingsV2 + ) -> Result[NodeSettingsV2, str]: res = self.check_type(settings, self.object_type) # we dont use and_then logic here as it is hard because of the order of the arguments if res.is_err(): @@ -40,8 +40,8 @@ def set( return super().set(credentials=credentials, obj=res.ok()) def update( - self, credentials: SyftVerifyKey, settings: NodeSettings - ) -> Result[NodeSettings, str]: + self, credentials: SyftVerifyKey, settings: NodeSettingsV2 + ) -> Result[NodeSettingsV2, str]: res = self.check_type(settings, self.object_type) # we dont use and_then logic here as it is hard because of the order of the arguments if res.is_err(): diff --git a/packages/syft/src/syft/service/user/user_service.py b/packages/syft/src/syft/service/user/user_service.py index aa0dda1b451..0cca4a98529 100644 --- a/packages/syft/src/syft/service/user/user_service.py +++ b/packages/syft/src/syft/service/user/user_service.py @@ -410,7 +410,7 @@ def register( else self.get_role_for_credentials(new_user.created_by) ) can_user_register = ( - context.node.metadata.signup_enabled + context.node.settings.signup_enabled or request_user_role in DATA_OWNER_ROLE_LEVEL ) diff --git a/packages/syft/src/syft/types/syft_object.py b/packages/syft/src/syft/types/syft_object.py index ff61fc58b74..42c8110536e 100644 --- a/packages/syft/src/syft/types/syft_object.py +++ b/packages/syft/src/syft/types/syft_object.py @@ -52,6 +52,16 @@ SYFT_OBJECT_VERSION_1 = 1 SYFT_OBJECT_VERSION_2 = 2 +SYFT_OBJECT_VERSION_3 = 3 + +supported_object_versions = [ + SYFT_OBJECT_VERSION_1, + SYFT_OBJECT_VERSION_2, + SYFT_OBJECT_VERSION_3, +] + +HIGHEST_SYFT_OBJECT_VERSION = max(supported_object_versions) +LOWEST_SYFT_OBJECT_VERSION = min(supported_object_versions) # These attributes are dynamically added based on node/client diff --git a/packages/syft/tests/syft/settings/fixtures.py b/packages/syft/tests/syft/settings/fixtures.py index 3d3c3abee8b..5d66447d71f 100644 --- a/packages/syft/tests/syft/settings/fixtures.py +++ b/packages/syft/tests/syft/settings/fixtures.py @@ -8,12 +8,15 @@ from syft.__init__ import __version__ from syft.abstract_node import NodeSideType from syft.abstract_node import NodeType +from syft.node.credentials import SyftSigningKey from syft.service.metadata.node_metadata import NodeMetadataJSON -from syft.service.settings.settings import NodeSettings from syft.service.settings.settings import NodeSettingsUpdate +from syft.service.settings.settings import NodeSettingsV2 from syft.service.settings.settings_service import SettingsService from syft.service.settings.settings_stash import SettingsStash -from syft.types.syft_object import SYFT_OBJECT_VERSION_1 +from syft.types.syft_object import HIGHEST_SYFT_OBJECT_VERSION +from syft.types.syft_object import LOWEST_SYFT_OBJECT_VERSION +from syft.types.uid import UID @pytest.fixture @@ -22,8 +25,9 @@ def settings_stash(document_store) -> SettingsStash: @pytest.fixture -def settings(worker, faker) -> NodeSettings: - return NodeSettings( +def settings(worker, faker) -> NodeSettingsV2: + return NodeSettingsV2( + id=UID(), name=worker.name, organization=faker.text(), on_board=faker.boolean(), @@ -33,6 +37,8 @@ def settings(worker, faker) -> NodeSettings: admin_email="info@openmined.org", node_side_type=NodeSideType.LOW_SIDE, show_warnings=False, + verify_key=SyftSigningKey.generate().verify_key, + node_type=NodeType.DOMAIN, ) @@ -52,11 +58,9 @@ def metadata_json(faker) -> NodeMetadataJSON: name=faker.name(), id=faker.text(), verify_key=faker.text(), - highest_version=SYFT_OBJECT_VERSION_1, - lowest_version=SYFT_OBJECT_VERSION_1, + highest_object_version=HIGHEST_SYFT_OBJECT_VERSION, + lowest_object_version=LOWEST_SYFT_OBJECT_VERSION, syft_version=__version__, - signup_enabled=False, - admin_email="info@openmined.org", node_side_type=NodeSideType.LOW_SIDE.value, show_warnings=False, node_type=NodeType.DOMAIN.value, diff --git a/packages/syft/tests/syft/settings/settings_service_test.py b/packages/syft/tests/syft/settings/settings_service_test.py index ad318b82b04..d0a6def902d 100644 --- a/packages/syft/tests/syft/settings/settings_service_test.py +++ b/packages/syft/tests/syft/settings/settings_service_test.py @@ -1,5 +1,6 @@ # stdlib from copy import deepcopy +from datetime import datetime from unittest import mock # third party @@ -14,11 +15,10 @@ from syft.node.credentials import SyftSigningKey from syft.node.credentials import SyftVerifyKey from syft.service.context import AuthedServiceContext -from syft.service.metadata.node_metadata import NodeMetadataV2 from syft.service.response import SyftError from syft.service.response import SyftSuccess -from syft.service.settings.settings import NodeSettings from syft.service.settings.settings import NodeSettingsUpdate +from syft.service.settings.settings import NodeSettingsV2 from syft.service.settings.settings_service import SettingsService from syft.service.settings.settings_stash import SettingsStash from syft.service.user.user import UserCreate @@ -28,7 +28,7 @@ def test_settingsservice_get_success( monkeypatch: MonkeyPatch, settings_service: SettingsService, - settings: NodeSettings, + settings: NodeSettingsV2, authed_context: AuthedServiceContext, ) -> None: mock_stash_get_all_output = [settings, settings] @@ -41,7 +41,7 @@ def mock_stash_get_all(credentials) -> Ok: response = settings_service.get(context=authed_context) - assert isinstance(response.ok(), NodeSettings) + assert isinstance(response.ok(), NodeSettingsV2) assert response == expected_output @@ -75,20 +75,20 @@ def mock_stash_get_all_error(credentials) -> Err: def test_settingsservice_set_success( settings_service: SettingsService, - settings: NodeSettings, + settings: NodeSettingsV2, authed_context: AuthedServiceContext, ) -> None: response = settings_service.set(authed_context, settings) assert response.is_ok() is True - assert isinstance(response.ok(), NodeSettings) + assert isinstance(response.ok(), NodeSettingsV2) assert response.ok() == settings def test_settingsservice_set_fail( monkeypatch: MonkeyPatch, settings_service: SettingsService, - settings: NodeSettings, + settings: NodeSettingsV2, authed_context: AuthedServiceContext, ) -> None: mock_error_message = "database failure" @@ -107,8 +107,8 @@ def mock_stash_set_error(credentials, a) -> Err: def add_mock_settings( root_verify_key: SyftVerifyKey, settings_stash: SettingsStash, - settings: NodeSettings, -) -> NodeSettings: + settings: NodeSettingsV2, +) -> NodeSettingsV2: # create a mock settings in the stash so that we can update it result = settings_stash.partition.set(root_verify_key, settings) assert result.is_ok() @@ -124,7 +124,7 @@ def test_settingsservice_update_success( monkeypatch: MonkeyPatch, settings_stash: SettingsStash, settings_service: SettingsService, - settings: NodeSettings, + settings: NodeSettingsV2, update_settings: NodeSettingsUpdate, authed_context: AuthedServiceContext, ) -> None: @@ -194,7 +194,7 @@ def test_settingsservice_update_stash_empty( def test_settingsservice_update_fail( monkeypatch: MonkeyPatch, - settings: NodeSettings, + settings: NodeSettingsV2, settings_service: SettingsService, update_settings: NodeSettingsUpdate, authed_context: AuthedServiceContext, @@ -210,7 +210,7 @@ def mock_stash_get_all(credentials) -> Ok: mock_update_error_message = "Failed to update obj NodeMetadata" - def mock_stash_update_error(credentials, update_settings: NodeSettings) -> Err: + def mock_stash_update_error(credentials, update_settings: NodeSettingsV2) -> Err: return Err(mock_update_error_message) monkeypatch.setattr(settings_service.stash, "update", mock_stash_update_error) @@ -227,7 +227,7 @@ def test_settings_allow_guest_registration( # Create a new worker verify_key = SyftSigningKey.generate().verify_key - mock_node_metadata = NodeMetadataV2( + mock_node_settings = NodeSettingsV2( name=faker.name(), verify_key=verify_key, highest_version=1, @@ -237,12 +237,13 @@ def test_settings_allow_guest_registration( admin_email="info@openmined.org", node_side_type=NodeSideType.LOW_SIDE, show_warnings=False, + deployed_on=datetime.now().date().strftime("%m/%d/%Y"), ) with mock.patch( - "syft.Worker.metadata", + "syft.Worker.settings", new_callable=mock.PropertyMock, - return_value=mock_node_metadata, + return_value=mock_node_settings, ): worker = syft.Worker.named(name=faker.name(), reset=True) guest_domain_client = worker.guest_client @@ -268,11 +269,11 @@ def test_settings_allow_guest_registration( assert any(user.email == email1 for user in root_domain_client.users) # only after the root client enable other users to signup, they can - mock_node_metadata.signup_enabled = True + mock_node_settings.signup_enabled = True with mock.patch( - "syft.Worker.metadata", + "syft.Worker.settings", new_callable=mock.PropertyMock, - return_value=mock_node_metadata, + return_value=mock_node_settings, ): worker = syft.Worker.named(name=faker.name(), reset=True) guest_domain_client = worker.guest_client @@ -310,7 +311,7 @@ def get_mock_client(faker, root_client, role): ) verify_key = SyftSigningKey.generate().verify_key - mock_node_metadata = NodeMetadataV2( + mock_node_settings = NodeSettingsV2( name=faker.name(), verify_key=verify_key, highest_version=1, @@ -320,12 +321,13 @@ def get_mock_client(faker, root_client, role): admin_email="info@openmined.org", node_side_type=NodeSideType.LOW_SIDE, show_warnings=False, + deployed_on=datetime.now().date().strftime("%m/%d/%Y"), ) with mock.patch( - "syft.Worker.metadata", + "syft.Worker.settings", new_callable=mock.PropertyMock, - return_value=mock_node_metadata, + return_value=mock_node_settings, ): worker = syft.Worker.named(name=faker.name(), reset=True) root_client = worker.root_client diff --git a/packages/syft/tests/syft/settings/settings_stash_test.py b/packages/syft/tests/syft/settings/settings_stash_test.py index 68d9ea73f42..f1abc406a68 100644 --- a/packages/syft/tests/syft/settings/settings_stash_test.py +++ b/packages/syft/tests/syft/settings/settings_stash_test.py @@ -1,14 +1,14 @@ # third party # syft absolute -from syft.service.settings.settings import NodeSettings from syft.service.settings.settings import NodeSettingsUpdate +from syft.service.settings.settings import NodeSettingsV2 from syft.service.settings.settings_stash import SettingsStash def add_mock_settings( - root_verify_key, settings_stash: SettingsStash, settings: NodeSettings -) -> NodeSettings: + root_verify_key, settings_stash: SettingsStash, settings: NodeSettingsV2 +) -> NodeSettingsV2: # prepare: add mock settings result = settings_stash.partition.set(root_verify_key, settings) assert result.is_ok() @@ -20,13 +20,13 @@ def add_mock_settings( def test_settingsstash_set( - root_verify_key, settings_stash: SettingsStash, settings: NodeSettings + root_verify_key, settings_stash: SettingsStash, settings: NodeSettingsV2 ) -> None: result = settings_stash.set(root_verify_key, settings) assert result.is_ok() created_settings = result.ok() - assert isinstance(created_settings, NodeSettings) + assert isinstance(created_settings, NodeSettingsV2) assert created_settings == settings assert settings.id in settings_stash.partition.data @@ -34,7 +34,7 @@ def test_settingsstash_set( def test_settingsstash_update( root_verify_key, settings_stash: SettingsStash, - settings: NodeSettings, + settings: NodeSettingsV2, update_settings: NodeSettingsUpdate, ) -> None: # prepare: add a mock settings @@ -50,5 +50,5 @@ def test_settingsstash_update( assert result.is_ok() updated_settings = result.ok() - assert isinstance(updated_settings, NodeSettings) + assert isinstance(updated_settings, NodeSettingsV2) assert mock_settings == updated_settings diff --git a/packages/syft/tests/syft/users/user_service_test.py b/packages/syft/tests/syft/users/user_service_test.py index c17d6517ee7..94e3d7a5deb 100644 --- a/packages/syft/tests/syft/users/user_service_test.py +++ b/packages/syft/tests/syft/users/user_service_test.py @@ -29,11 +29,11 @@ from syft.types.uid import UID -def metadata_with_signup_enabled(worker) -> Type: - mock_metadata = worker.metadata - mock_metadata.signup_enabled = True +def settings_with_signup_enabled(worker) -> Type: + mock_settings = worker.settings + mock_settings.signup_enabled = True - return mock_metadata + return mock_settings def test_userservice_create_when_user_exists( @@ -476,11 +476,11 @@ def mock_get_by_email(credentials: SyftVerifyKey, email): monkeypatch.setattr(user_service.stash, "get_by_email", mock_get_by_email) expected_error_msg = f"User already exists with email: {guest_create_user.email}" - # Patch Worker Metadata to enable signup + # Patch Worker settings to enable signup with mock.patch( - "syft.Worker.metadata", + "syft.Worker.settings", new_callable=mock.PropertyMock, - return_value=metadata_with_signup_enabled(worker), + return_value=settings_with_signup_enabled(worker), ): mock_worker = Worker.named(name="mock-node") node_context = NodeServiceContext(node=mock_worker) @@ -503,11 +503,11 @@ def mock_get_by_email(credentials: SyftVerifyKey, email): monkeypatch.setattr(user_service.stash, "get_by_email", mock_get_by_email) - # Patch Worker Metadata to enable signup + # Patch Worker settings to enable signup with mock.patch( - "syft.Worker.metadata", + "syft.Worker.settings", new_callable=mock.PropertyMock, - return_value=metadata_with_signup_enabled(worker), + return_value=settings_with_signup_enabled(worker), ): mock_worker = Worker.named(name="mock-node") node_context = NodeServiceContext(node=mock_worker) @@ -530,12 +530,12 @@ def mock_get_by_email(credentials: SyftVerifyKey, email: str) -> Ok: def mock_set(*args, **kwargs) -> Ok: return Ok(guest_user) - # Patch Worker Metadata to enable signup + # Patch Worker settings to enable signup with mock.patch( - "syft.Worker.metadata", + "syft.Worker.settings", new_callable=mock.PropertyMock, - return_value=metadata_with_signup_enabled(worker), + return_value=settings_with_signup_enabled(worker), ): mock_worker = Worker.named(name="mock-node") node_context = NodeServiceContext(node=mock_worker) @@ -577,9 +577,9 @@ def mock_set( return Err(expected_error_msg) with mock.patch( - "syft.Worker.metadata", + "syft.Worker.settings", new_callable=mock.PropertyMock, - return_value=metadata_with_signup_enabled(worker), + return_value=settings_with_signup_enabled(worker), ): mock_worker = Worker.named(name="mock-node") node_context = NodeServiceContext(node=mock_worker)