-
-
Notifications
You must be signed in to change notification settings - Fork 210
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
Add object-oriented client option #224
Comments
With the current approach, for every API call, the user has to import a a module from a tag package and call the `asyncio` or `sync` method with the "client=client" argument. This patch adds a wrapper around tag packages and two wrapper `Client` objects to spare the need for that boilerplate code. Check this issue for more information: openapi-generators#224
Thanks for the suggestions @fyhertz. I think the best way to go forward with a more object oriented style is to have a separate set of templates for OO, rather than complicating existing generated clients. I do like the idea of the wrapper, I just don't see a world in which users would want both styles present rather than tuning for one or the other. #231 has already started work toward alternate template support, I think we'd get that finished first then folks can either use their own custom templates (which I think a lot of users are itching to do) or select one of the included template sets. |
With the current approach, for every API call, the user has to import a a module from a tag package and call the `asyncio` or `sync` method with the "client=client" argument. This patch adds a wrapper around tag packages and two wrapper `Client` objects to spare the need for that boilerplate code. Check this issue for more information: openapi-generators#224 `base_url` can be omitted during client initialization if `SPEC_TITLE_BASE_URL` is set. Object-oriented clients have also been renamed to include the spec title.
With the current approach, for every API call, the user has to import a a module from a tag package and call the `asyncio` or `sync` method with the "client=client" argument. This patch adds a wrapper around tag packages and two wrapper `Client` objects to spare the need for that boilerplate code. Check this issue for more information: openapi-generators#224 `base_url` can be omitted during client initialization if `SPEC_TITLE_BASE_URL` is set. Object-oriented clients have also been renamed to include the spec title.
With the current approach, for every API call, the user has to import a a module from a tag package and call the `asyncio` or `sync` method with the "client=client" argument. This patch adds a wrapper around tag packages and two wrapper `Client` objects to spare the need for that boilerplate code. Check this issue for more information: openapi-generators#224 `base_url` can be omitted during client initialization if `SPEC_TITLE_BASE_URL` is set. Object-oriented clients have also been renamed to include the spec title.
@dbanty I've followed some of your comments in various issues/PRs about what it would take to support very flexible templating. I don't know jinja too well so it sounds like it would be pretty tough. Could a compromise be to create a handler base class and then split off the hard-coded logic for the current template setup into a out-of-the-box handler for the default template setup? This client generator could then provide the equipment for building a library but not need to get into all the specifics of how a particular user may do it. I ask because I forked the project and while a few of my modifications could be decent candidates for PRs, one isn't because it's specific to us: I patched in some methods that operate similar to the |
@alexifm that's probable the way we'll have to go long term, yes. Without there being a Python-side implementation to drive things (what the The hard part will be deciding where to draw lines between shared core logic and useful, reusable components. Like do we leave all the type conversion / generation stuff in the core lib? Or pull that into the templates somewhere? Is generating models for endpoint inputs/outputs useful enough to include? If so how do we do that in a way that is useful to those building their own generators without getting in the way? I don't have answers to any of the questions around a stable, extensible API. I do know we'll have to be careful when moving the project in that direction though. Part of the reason for this project existing was to make more opinionated, more Pythonic clients from a codebase which is easier to reason about for Python developers. I fear if we move too far in the flexibility direction, we'll end up being effectively the same as the Java tool except written in Python and supporting less of the OpenAPI spec 😅. Having a stable way for people to build their own generators from this project is very far down the roadmap. Right now most of my focus is around making this tool more compliant with the spec and more accessible for the majority of users. That being said, having the ability to generate mkdocs for a generated client doesn't seem like a horrible option. If we were to add more documentation, that would probably the road we'd go down. |
For whatever my opinion is worth, I think you're right to favor being opinionated since you're making it conform to popular modern Python standards, as opposed to that official tool which looks like Python crafted by Java devs. That's why I gravitated to this library.
Sounds good. I just wanted to chime in based on our experience. Perhaps a refactoring that keeps the core functionality but opens up a hidden ability to adapt a handler base class that more in depth users could experiment with, kind of similar to the custom template path. We'd like to not use our fork. But maybe the changes can be brought in and more template customization won't be necessary.
I'll start a PR with a sketch of how it could be done. It's pretty basic templating. The other two things I added:
|
With the current approach, for every API call, the user has to import a a module from a tag package and call the `asyncio` or `sync` method with the "client=client" argument. This patch adds a wrapper around tag packages and two wrapper `Client` objects to spare the need for that boilerplate code. Check this issue for more information: openapi-generators#224 `base_url` can be omitted during client initialization if `SPEC_TITLE_BASE_URL` is set. Object-oriented clients have also been renamed to include the spec title.
With the current approach, for every API call, the user has to import a a module from a tag package and call the `asyncio` or `sync` method with the "client=client" argument. This patch adds a wrapper around tag packages and two wrapper `Client` objects to spare the need for that boilerplate code. Check this issue for more information: openapi-generators#224 `base_url` can be omitted during client initialization if `SPEC_TITLE_BASE_URL` is set. Object-oriented clients have also been renamed to include the spec title.
With the current approach, for every API call, the user has to import a a module from a tag package and call the `asyncio` or `sync` method with the "client=client" argument. This patch adds a wrapper around tag packages and two wrapper `Client` objects to spare the need for that boilerplate code. Check this issue for more information: openapi-generators#224 `base_url` can be omitted during client initialization if `SPEC_TITLE_BASE_URL` is set. Object-oriented clients have also been renamed to include the spec title.
If this can be of any interest to anyone, I've implemented something extremely similar to what OP described, even before reading this issue: https://github.com/ramnes/sftpgo-client/blob/0.2.3/sftpgo_client/__init__.py It does a quite bit of Python magic, which I do not particularly like, and add a few things related to SFTPGo. The good part is that it just relies on the existence of |
First of all, thank you for this great project, the code is very nice and I think it really has a lot of potential.
Is your feature request related to a problem? Please describe.
As mentioned in #171, the current approach arguably needs a little too much boilerplate that could be avoided by adding a more object oriented
Client
.Describe the solution you'd like
SyncClient
andAsyncClient
that would wrap the currently generated tag packages in objects, and expose them as properties.With that approach, a developer could call an endpoint with as little code as:
One issue is that we loose the ability to statically tell the user that some endpoint requires an
AuthenticatedClient
or not... Some thinking required here I guess.Additionally, a default
base_url
could be provided through an environment variable named after the spec title, for instance:SWAGGER_PETSTORE_BASE_URL
. It could be nice to prevent microservices from using different naming conventions.For reference, my crude attempt at implementing those interfaces is available here: https://github.com/upciti/openapi-python-client/tree/feature/0-boilerplate-clients.
The text was updated successfully, but these errors were encountered: