Add OpenAPI description of the extension API
fcollonval opened this issue · 3 comments
Or better #16 (comment)
- Describe Python object with Pydantic
- Generate json-schema from it
- Generate TS from schema
As I may have mentioned over there: having one of the implementations be the source of truth is convenient... for the source of truth. In particular, pydantic
has some oddments around optional fields, e.g. not set != _ set by 'null
_ that has bitten me a few times. Further, it's another (non-trivial) dependency, while jsonschema
, for all its warts, is already guaranteed to be around... nothing much else in the Jupyter python stack (above tornado
) is typed yet, so some of the benefits around static typing are hard to realize at present.
In general, I've encountered fewer surprises when a project:
- maintains a single JSON/YAML/TOML spec that gets updated
- generates the required typings/stubs on either side of the exchange
- checks in the generated types
- as they become very useful in history
- they shouldn't change much over time, but when they do, it's important and worthy of review
This also prevents some chicken-and-egg scenarios, letting frontend and backend be tested independently of one another (though the tooling itself has to live somewhere). If it is tolerable to have to do a JS build first, the output of labextension build
will copy the schema
folder, unchanged, I'm pretty sure, making it a good place to live.
- generates the required typings/stubs on either side of the exchange
@bollwyvl Any recs for a good openapi -> python and/or openapi -> typescript stub generator?
The biggest player is OpenAPITools/openapi-generator. This generates entire opinionated servers/clients. We... don't want those opinions, yet, e.g. Flask. Nor do i want to sling enough Java to make one for tornado.
A related approach is connexion, which forces an app to use the OpenAPI spec to wire up the application, and doesn't turn on if the team forgets to implement a route (in Flask, tornado, or aiohttp). It kinda takes over everything, as one can imagine.
I prefer a lighter touch, of just the data model, and not get wrapped up in a specific application, as none of these things would know what the heck traitlets
is babbling on about, anyway. For this, quicktype/quicktype has usually met my needs for python, while i don't even bother and go straight to the node-based stuff in the linked comment.
Except: if I already have a JSON schema validator around in sys.modules
or... whatever webpack does... and am working in a language that doesn't really have runtime typechecking (my kingdom for deno/mypyc) ... I just validate the instances at runtime against the JSON schema. For get
/post
/patch
/put
, it's just part of the input/output... there's probably some nice decorator patterns possible.
For manager-kinda-things, that have mutable state with traitlets, making a Schema
trait, which can be used anywhere I'd use an Any
. Could be subclassed to be a SchemaList
or a SchemaDict
, etc.