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

Feature request: function (view) overloading? #378

Open
Talkless opened this issue Mar 16, 2023 · 6 comments
Open

Feature request: function (view) overloading? #378

Talkless opened this issue Mar 16, 2023 · 6 comments
Assignees

Comments

@Talkless
Copy link
Contributor

Not sure if this would be doable in Flask at all, but instead of having view with compex signatures using Unions / Optionals / Variants:

 #if first parameter is integer, second parameter is ignored
 time_from_or_days_ago: Union[str, int], time_to: Optional[str]

...we could have something like this, by introducing "aliases" (or some other term) to group overloads:

@foo.method("foo.bar_dates", alias="foo.bar")
def foo_bar_dates(time_from: str, time_to: str) -> str
    # ...
    
@foo.method("foo.bar_days", alias="foo.bar")
def foo_bar_days(days_ago: int) -> str
    # ...

image

@nycholas nycholas self-assigned this Mar 20, 2023
@nycholas
Copy link
Member

It seems good to me, even the presentation of the overloadings, 👍

@Talkless
Copy link
Contributor Author

Not sure about "alias" keyword though, maybe it there will be "needed" for other feature in the future, but not sure what else to suggest.

overload_set="foo.bar" might be correctly specific, but maybe too cryptic?

group="foo.bar" could be another alternative, though not sure why it's better than alias.

@nycholas
Copy link
Member

I was thought in some think like that:

from __future__ import annotations

from collections.abc import Sequence
from typing import overload

from flask import Flask

from flask_jsonrpc import JSONRPC

app = Flask('application')
jsonrpc = JSONRPC(app, '/api', enable_web_browsable_api=True)

@overload
def double(input_: int) -> int:
    ...

@overload
def double(input_: Sequence[int]) -> list[int]:
    ...

@jsonrpc.method('App.double')
def double(input_: int | Sequence[int]) -> int | list[int]:
    if isinstance(input_, Sequence):
        return [i * 2 for i in input_]
    return input_ * 2

@Talkless
Copy link
Contributor Author

The idea of overloading was to avoid having if isinstance... logic inside function.

Maybe I do not follow this example. What will be in the bodies of these two @overload'ed functions if I see all code in @jsonrpc.method('App.double') then?

@nycholas
Copy link
Member

Maybe I do not follow this example. What will be in the bodies of these two @overload'ed functions if I see all code in @jsonrpc.method('App.double') then?

No, did you see it right, I didn't see that were two completely different functions, and I thought about the typing.overload support that can be used with typing.TypeGuard[1] together.

In that case, I have a bad feeling regarding it, Flask doesn't allow mapping two functions to one URL, the opposite is true. Besides that, to do that, we will need to analyze the input (payload) and choice the right function to trigger, and further more, changing the way of register of functions in Flask-JSONRPC, from Dict[str, Callable] to Dict[str, List[Callable]].

[1] - https://peps.python.org/pep-0647/

@Talkless
Copy link
Contributor Author

Flask doesn't allow mapping two functions to one URL

OK, could then some sort of jsonrpc.register_overload_set('foo.bar') (not an decorator) be used to register "generated" single method with single URL to make Flask happy?

Then, inside that "generated" method implementation, it would select best match from @jsonrpc.overloaded_method('foo.bar')'s for given argument set.

Not sure how would @jwt_required() would for these "not-really-a-flask-views"?

nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 25, 2023
The expected behavior is that when using the modular way, the API
Browser merges in one, instead of having one API Browser for each.

Now, the server is aware of the `SERVER_NAME` Flask configuration,
it is being used by API Browser to request the correct server,
besides that, the API Browser is able to call servers in different
domains. For that configuration, the `JSONRPCSite` generates the
`path` and `base_url` variables from `SERVER_NAME`, `APPLICATION_ROOT`,
and `PREFERRED_URL_SCHEME`.

It is the first step to providing a Browse Schema to improve
documentation and examples from API (JSON-RPC methods).

Resolves: #388
See: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 27, 2023
It's very important to provide a safe way to change
the Web Browsable API in the next tasks.

See also: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 27, 2023
It's very important to provide a safe way to change
the Web Browsable API in the next tasks.

See also: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 27, 2023
It's very important to provide a safe way to change
the Web Browsable API in the next tasks.

See also: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 27, 2023
It's very important to provide a safe way to change
the Web Browsable API in the next tasks.

See also: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 29, 2023
It's very important to provide a safe way to change
the Web Browsable API in the next tasks.

See also: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 29, 2023
It's very important to provide a safe way to change
the Web Browsable API in the next tasks.

See also: #378, #377, #376, #374, #373, and #370
nycholas added a commit that referenced this issue Mar 29, 2023
It's very important to provide a safe way to change
the Web Browsable API in the next tasks.

See also: #378, #377, #376, #374, #373, and #370
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants