diff --git a/README.md b/README.md index 08cce7b..ceca05d 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Those familiar with Web of Things (WoT) terminology may note that these properti }, ``` If you are not familiar with Web of Things or the term "property affordance", consider the above JSON as a description of -what the property represents and how to interact with it from somewhere else. Such a JSON is both human-readable, yet consumable by any application that may use the property, say a client provider to create a client object to interact with the property or a GUI application to autogenerate a suitable input field for this property. +what the property represents and how to interact with it from somewhere else. Such a JSON is both human-readable, yet consumable by any application that may use the property - say, a client provider to create a client object to interact with the property or a GUI application to autogenerate a suitable input field for this property. For example, the Eclipse ThingWeb [node-wot](https://github.com/eclipse-thingweb/node-wot) supports this feature to produce a HTTP(s) client that can issue `readProperty("integration_time")` and `writeProperty("integration_time", 1000)` to read and write this property. The URL path segment `../spectrometer/..` in href field is taken from the `instance_name` which was specified in the `__init__`. @@ -314,20 +314,14 @@ See a list of currently supported possibilities while using this package [below] > You may use a script deployment/automation tool to remote stop and start servers, in an attempt to remotely control your hardware scripts. -### Looking for sponsorships - -Kindly read my message [in my GitHub profile](https://github.com/sponsors/VigneshVSV). - ### A little more about Usage -One may use the HTTP API according to one's beliefs (including letting the package auto-generate it), but it is mainly intended for web development and cross platform clients -like the interoperable [node-wot](https://github.com/eclipse-thingweb/node-wot) HTTP(s) client. If your plan is to develop a truly networked system, it is recommended to learn more and -se [Thing Descriptions](https://www.w3.org/TR/wot-thing-description11) to describe your hardware. A Thing Description will be automatically generated if absent as shown in JSON examples above or can be supplied manually. The default end point to -fetch thing descriptions are:
`http(s):////resources/wot-td`
+The HTTP API may be autogenerated or adjusted by the user. If your plan is to develop a truly networked system, it is recommended to learn more and +use [Thing Descriptions](https://www.w3.org/TR/wot-thing-description11) to describe your hardware (This is optional and one can still use a classic HTTP client). A Thing Description will be automatically generated if absent as shown in JSON examples above or can be supplied manually. The default end point to fetch thing descriptions are:
`http(s):////resources/wot-td`
If there are errors in generation of Thing Description (mostly due to JSON non-complaint types), one could use:
`http(s):////resources/wot-td?ignore_errors=true` -(client docs will be updated here next) +(client docs will be updated here next, also check official docs) ### Currently Supported diff --git a/hololinked/server/property.py b/hololinked/server/property.py index 31b70dd..a405d73 100644 --- a/hololinked/server/property.py +++ b/hololinked/server/property.py @@ -111,7 +111,7 @@ class Property(Parameter): """ - __slots__ = ['db_persist', 'db_init', 'db_commit', 'metadata', 'model', '_json_validator', '_remote_info', + __slots__ = ['db_persist', 'db_init', 'db_commit', 'metadata', 'model', 'validator', '_remote_info', '_observable', '_observable_event_descriptor', 'fcomparator', '_old_value_internal_name'] # RPC only init - no HTTP methods for those who dont like @@ -187,12 +187,14 @@ def __init__(self, default: typing.Any = None, *, isproperty=True ) self.model = None - self._json_validator = None + self.validator = None if model: - if isinstance(model, BaseModel): - self.model = wrap_plain_types_in_rootmodel(model) - elif issubclass(model, dict): - self._json_validator = JsonSchemaValidator(model) + if isinstance(model, dict): + self.model = model + self.validator = JsonSchemaValidator(model) + else: + self.model = wrap_plain_types_in_rootmodel(model) # type: BaseModel + self.validator = self.model.model_validate def __set_name__(self, owner: typing.Any, attrib_name: str) -> None: @@ -242,17 +244,17 @@ def _push_change_event_if_needed(self, obj, value : typing.Any) -> None: event_dispatcher.push(value) - def validate_and_adapt(self, value): + def validate_and_adapt(self, value) -> typing.Any: if value is None: if self.allow_None: return value else: raise ValueError(f"Property {self.name} does not allow None values") - elif self.model: - if isinstance(value, dict): - self._json_validator.validate(value) - else: - self.model(**value) # pydantic model validation, just try to create an instance + if self.model: + if isinstance(self.model, dict): + self.validator.validate(value) + elif issubklass(self.model, BaseModel): + self.validator(value) return super().validate_and_adapt(value)