feat: Add Client for Systems State Service APIs#89
Conversation
| @pytest.fixture | ||
| def default_work_space() -> str: | ||
| """Fixture that returns the default workspace id""" | ||
| return "846e294a-a007-47ac-9fc2-fac07eab240e" |
There was a problem hiding this comment.
Tests should be agnostic of the SLE instance and equipped to work with a fresh deployment by taking care of creating/deleting any necessary entities or mock them in the requests response.
| return "846e294a-a007-47ac-9fc2-fac07eab240e" | |
| return "" |
|
I'm yet to update the changes that I made for resolving the previous comments. Awaiting your reply on the privilege issue (test tier for my role) for creating or updating states, to test the modified client code. However, I have few doubts. |
|
In the functions involving If I make use of the decorator, the response is not inferring the expected type properly. Also, the function signature in the documentation is displayed as |
|
In the swagger docs for updating a state, But can we explicitly define a proper model in our client package, for updating a state? |
|
|
Please refer to multi-part with Uplink.
|
| ... | ||
|
|
||
| @post("export-state", args=[Body]) | ||
| def export_state(self, query: models.ExportStateRequest) -> str: |
There was a problem hiding this comment.
Your type hint for the response is a string, but this will return a file download. This should instead be an IteratorFileLike and you should decorate the function with @response_handler(file_like_response_handler).
The same applies for export_state_from_system
|
|
||
| @patch("states/{stateId}", args=[Path("stateId"), Body]) | ||
| def update_state( | ||
| self, id: str, patch_updates: Dict[str, Any] |
There was a problem hiding this comment.
We'd really prefer a proper class to this patch_updates dictionary. Its cases like this that pushed us to hand create these clients rather than just generating them from the OpenAPI yaml.
The actual strings and values we expect to allow in this dictionary are known and we can build a proper update object that maps to the dictionary the API takes. See the ModelConverter class and the StateConstants.Update* fields for the keys. The update model should be a fully optional version of the StateUpdate class
| Part(name="File", type=str), | ||
| ], | ||
| ) | ||
| def replace_state_content( |
There was a problem hiding this comment.
Use BinaryIO instead of io.BytesIO. Its basically just a more flexible alias.
| architecture: str, | ||
| properties: str, | ||
| workspace: str, | ||
| file: BytesIO, |
There was a problem hiding this comment.
Similarly here use BinaryIO from typing instead of BytesIO
| description: str, | ||
| distribution: models.Distribution, | ||
| architecture: models.Architecture, | ||
| properties: str, |
There was a problem hiding this comment.
properties should be a string-string dictionary. The API expects serialized JSON, so I expect you'll need to convert it to json yourself. I bet there is a way to get uplink to convert the dictionary to a json string for you, if you want to dig into it.
| """Basic State entities that can be extended further""" | ||
|
|
||
| name: Optional[str] = None | ||
| """Gets or sets the name of the state.""" |
There was a problem hiding this comment.
These "gets or sets" doc strings are not great. I get this is copied from the swagger, but really these should just be what comes after, "The name of the state" in this case.
| ) | ||
|
|
||
|
|
||
| class StateDescriptionListResponse(JsonModel): |
There was a problem hiding this comment.
This is what the type is called in the swagger but I'm not a fan. How about StateMetadataList instead
| class StateResponse(StateMetaData, AdditionalStateInformation): | ||
| """Model for system state object.""" | ||
|
|
||
| error: Optional[ApiError] = None |
There was a problem hiding this comment.
We can remove this error object. The routes that will return StateResponse will return either the error or the proper State object, not both. When the error is the response it will always be with a 4xx error code, which is automatically raised as a ApiException in the base client, which then provides access to the error body. This means we should be able to fully replace this StateResponse with State as the returned type from the client functions.
The same applies to StateDescriptionListResponse
| """ | ||
|
|
||
|
|
||
| class StateMetaData(State): |
There was a problem hiding this comment.
It should be StateMetadata (no capital D) and it would make more sense to invert this relationship. State is the complete object and it should inherit from StateMetadata, the incomplete object. State should additionally get feeds, packages, systemImage, and containsExtraOperations
|
|
||
| Create, query, update, and delete states | ||
|
|
||
| .. literalinclude:: ../examples/systemsstate/systemsstate.py |
There was a problem hiding this comment.
This file doesn't exist, did you forget to commit it?
What does this Pull Request accomplish?
This PR adds API Client Module for
Statesmicroservice in theSystems State Service.Why should this Pull Request be merged?
The
SystemsStateClientmakes it easier for users to interact with the endpoints ofSystems State Serviceby just creating an instance of it.What testing has been done?
Automated integration tests are included.
API Link: Swagger Link