Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clients: add API client to this SDK #197

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

imrehg
Copy link
Member

@imrehg imrehg commented Dec 22, 2021

This PR is a WIP, opening it for early feedback, will update description when closer to completion.

Comment on lines 322 to 327
if default_server_size is None:
default_server_size = {
"instanceSizeType": "custom",
"instanceSize": {"milliCpus": 1000, "memoryMb": 4096},
}
payload["defaultServerSize"] = default_server_size
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be some common schemas with the ServerClient might be worth considering reusing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there are some stuff here and there, there's _InstanceSizeSchema from JobClient for example, but will see to mix and match further. It would be great to avoid duplication, there are some subtle differences as much as I can tell, but still digging into the actual platform api schema.

faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
faculty/clients/api.py Outdated Show resolved Hide resolved
ERROR = "error"


@define
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than attrs new interface, I'd actually advocate for using dataclasses now that we're only supporting 3.6+ (dataclasses are 3.7+, but there is a 3.6 backport that you can install on Python 3.6 only). The syntax is basically the same but this has the obvious advantage of being in the standard library and better integrated with other Python tools.

I'd suggest we use dataclasses here and gradually migrate other clients to use dataclasses in future. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this is a good call. Don't have strong reason to go with attr, not given how do we use things.
The plan sounds very sensible, will do the changes here, and once merged, will create an issue to track the whole migration as you outline.

working_directory: str
module: str
wsgi_object: str
last_updated_at: Optional[datetime] = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From looking at the aperture code, I don't think this is Optional (see ControllerReads line 92 and PersistentDetails line 43).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is optional, because this class is used not just for replies from aperture, but also request for creating APIs, and then the user would need to supply a last_updated_at value.

ie. with the current Optional setting, we can do

api_definition = WSGIDefinition(working_directory="/project/testapi", module="app", wsgi_object="app")
# [...snip...]
x = client.create(project_id=PROJECT_ID, command_definition=api_definition, subdomain=subdomain, name=name, default_server_size=server)

and without it the request will fail, obviously, unless a value is set, even if the create endpoint doesn't require that value (see the Command Definitions in the README).

Thus the tricky place is that for requests it's definitely optional, for replies it will always be included, and thus the reason why I did it like this.

Given all the above, how would you prefer to resolve it?

  • keeping it Optional due to the dual use?
  • making it non-optional but having a default value? (of datetime.now() or something?) (this feels dirty)
  • making it non-optional and make people pass in some value? (feels dirty like above)
  • something completely different?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, the "right" thing to do here would be to have different models, since the schema for the create body is different than the schema for the get response. But that will cause a fair bit of duplication, which is obviously undesirable. I'll have a think and get back to you.

I'd say a definite no to the second and third bullets in your comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @acroz, I've pushed some changes to see if they resolve this conundrum, breaking classes up into "Something" (for requests) and "SomethingResponse" (with inheritance derived from Something, for responses). This feels like having the right amount of duplication (ie. "SomethingResponse" only needs the additional or changed fields). I've tested it very briefly so far and seems to work, also the way we are creating the json payload, that's helpful that we don't need to convert Something <-> SomethingResponse at any point, and still can use them. (that conversion would be a bit verbose and hacky, as much as I've researched).

It's not fully fledged yet (ie. there might be mistakes in the rewrite), but wanted to get your opinion with code.

class PlumberDefinition:
working_directory: str
script_name: str
last_updated_at: Optional[datetime] = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

class ScriptDefinition:
working_directory: str
script_name: str
last_updated_at: Optional[datetime] = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

@imrehg imrehg mentioned this pull request May 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants