Code generation for ThingClient subclasses #89
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently,
ThingClientsubclasses are generated on-the-fly from a Thing Description. This "gets the job done" and means it's always possible to have a client that's up to date with the server. However, it would be nice to support static analysis, e.g. type checking, autocompletion, etc. with importable client classes for specific instruments.Functionality
This PR implements client code generation, specifically:
ThingClientand named as per thetitleof the Thing Description.get_property,set_propertyas provided byThingClientDataSchemaobjects don't distinguish whether extra properties are allowed or not.invoke_action....is used to distinguish between explicitly setNonevalues, and unspecified values (i.e. not included in the JSON). This allows for values or defaults that areNoneto be handled differently from properties that are optional but don't have a default.Schema conversion
Conversion from
DataSchemato Python types is implemented partially. Types are converted recursively, with support for:integer->intnumber->floatboolean->boolstring->stranyOf->Unionarray->List(if an item type is specified, it's converted recursively)object->dict[str, Any]AnyThe major limitation here is that
objectgets converted to adictso we don't get hints for each property. We'd need to use atypeddictordataclassor similar to get that functionality, and for now I'm going to consider it out of scope. However, there's one exception, which is the input schema of an Action. That is currently required to be anobject, and we map each of its properties to an argument, which is then typed as per the list above.Still to do
Before this is useful, we need to add a few things:
from_urlwill overwrite the methods with generic ones.get_propertyand friends and implementations of that roughly equivalent toDirectThingClientandThingCilent, and then providing a base client class with class methodsfrom_urlandfrom_thingthat create a subclass that mixes in eitherDirectThingClientorHTTPThingClientas appropriate.