Open beniroquai opened 3 years ago
This is definitely something we should look into. I believe that one of our engineers had some success with a Javascript client generator.
Have you tried alternative client generators? FastAPI generates an OpenAPI JSON file. OpenAPI used to be known as Swagger.
https://swagger.io/tools/swagger-codegen/ (i've had success with this one in the past) https://openapi-generator.tech/
I did successfully create a client using https://swagger.io/tools/swagger-codegen/ . Hopefully that works for you.
Thanks for the quick reply!
I tried this one:
but unfortunately, it didn't work and give s the following error:
USER:Downloads bene$ openapi-python-client generate --path openapi.yaml
Error(s) encountered while generating, client was not created
Failed to parse OpenAPI document
30 validation errors for OpenAPI
components -> schemas -> ComparisonStatus -> $ref
field required (type=value_error.missing)
components -> schemas -> ComparisonStatus -> properties -> differenceVector -> $ref
field required (type=value_error.missing)
components -> schemas -> ComparisonStatus -> properties -> differenceVector -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> ComparisonStatus -> properties -> differenceVector -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> ComparisonStatus -> properties -> thresholdVector -> $ref
field required (type=value_error.missing)
components -> schemas -> ComparisonStatus -> properties -> thresholdVector -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> ComparisonStatus -> properties -> thresholdVector -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> InstrumentOffset -> $ref
field required (type=value_error.missing)
components -> schemas -> InstrumentOffset -> properties -> single -> $ref
field required (type=value_error.missing)
components -> schemas -> InstrumentOffset -> properties -> single -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> InstrumentOffset -> properties -> single -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> InstrumentOffset -> properties -> multi -> $ref
field required (type=value_error.missing)
components -> schemas -> InstrumentOffset -> properties -> multi -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> InstrumentOffset -> properties -> multi -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> JogPosition -> $ref
field required (type=value_error.missing)
components -> schemas -> JogPosition -> properties -> vector -> $ref
field required (type=value_error.missing)
components -> schemas -> JogPosition -> properties -> vector -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> JogPosition -> properties -> vector -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> LoadLabwareResult -> $ref
field required (type=value_error.missing)
components -> schemas -> LoadLabwareResult -> properties -> calibration -> $ref
field required (type=value_error.missing)
components -> schemas -> LoadLabwareResult -> properties -> calibration -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> LoadLabwareResult -> properties -> calibration -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> OffsetData -> $ref
field required (type=value_error.missing)
components -> schemas -> OffsetData -> properties -> value -> $ref
field required (type=value_error.missing)
components -> schemas -> OffsetData -> properties -> value -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> OffsetData -> properties -> value -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> WellLocation -> $ref
field required (type=value_error.missing)
components -> schemas -> WellLocation -> properties -> offset -> $ref
field required (type=value_error.missing)
components -> schemas -> WellLocation -> properties -> offset -> items
value is not a valid dict (type=type_error.dict)
components -> schemas -> WellLocation -> properties -> offset -> items
value is not a valid dict (type=type_error.dict)
If you believe this was a mistake or this tool is missing a feature you need, please open an issue at https://github.com/triaxtec/openapi-python-client/issues/new/choose
Would be cool to play with it a bit!
I'll have a look into the links you sent. Thanks!
@amitlissack thanks for pointing me to the swagger-apigenerator. I tested it using the following line to generate the client from the openapi.json
file:
swagger-codegen generate -i ~/Downloads/openapi.json -l python -o ~/Downloads/opentrons_python_api/
and it failed.
I know this is a bit off-topic, but can you roughly remember the steps to reproduce it? (I'm not a programming expert, sorry ;).
What I did is: Downloading the openapi.json
file from the opentrons and executed the line above, does this make any sense at all?
In case it's of interest, the output of the terminal is the following: dump.txt
I'm really not an expert, but the error which says "filename too long" is probably coming from the nested/recurseive definition of the schema, or?
Is the API (I'm using the latest) up to date? Are you planning to integrate more functionalities or is it possible to "unlock" more of the fastAPI functions from the swagger ?
@beniroquai The API you're using is probably up to date. We are always adding more API.
I used the web site at https://swagger.io/tools/swagger-codegen/ . While it did successfully complete the generation, the resulting code is not that helpful.
We will have to spend time on this.
In the meantime, can I offer an alternative to code generation? The OpenAPI spec is generated from python classes in our robot-server
directory. You can import the robot_server
project into your client and use request
and our pydantic
classes.
Here is an example using our /health
endpoint.
import requests
from robot_server.health import models
r = requests.get("http://localhost:31950/health", headers={"Opentrons-Version": "2"})
model = models.Health(**r.json())
print(model.name, model.fw_version, model.board_revision)
Great! I'll have a look at it! :-)
May I have a follow-up question?
The above example works, so I could make use of the API which is defined in openapi.json
using the classes and get nice looking code instead of hacking around with customized python classes..right?
That's already nice! Thanks!
That is correct. It's not ideal, but you can be confident that the models you're using are accurate since they are being used by the server.
Each route handler lives in some python file in the robot-server
repo. In case you're not familiar with FastAPI, the argument(s) to the handler are the data in the request. The response model defined by the decorator is the response model.
Please feel free to reach out for more questions.
We'll need a more comprehensive and dev-friendly solution.
Brilliant! Thanks! I'll have a look.
I think the coolest "thing" to have would be a python client which mirrors the OT2 API on the opentrons to a remote computer with all states and protocol functions ;-)
Overview
We were wondering if there exists a way to automatically generate a Python client for the opentrons fastAPI using tools such as this toolbox
Implementation details
We tried using the fast_api_client generator without success (so far).
Design
Control basic functions of the robot remotely with an automated way of creating the client.
Acceptance criteria
Having the ability to control the opentrons robot through the fastAPI from a remote python console.