-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🌿 Fern Regeneration -- support OAuth 2.0 Authentication (#3)
* SDK regeneration * update README * fix --------- Co-authored-by: fern-api <115122769+fern-api[bot]@users.noreply.github.com> Co-authored-by: dsinghvi <[email protected]>
- Loading branch information
1 parent
1f65393
commit 97b5ba0
Showing
8 changed files
with
306 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,6 @@ | |
|
||
README.md | ||
assets/ | ||
|
||
src/webflow/client.py | ||
src/webflow/oauth.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
|
||
import typing | ||
import httpx | ||
import urllib.parse | ||
from json.decoder import JSONDecodeError | ||
|
||
from .core.api_error import ApiError | ||
from .core.jsonable_encoder import jsonable_encoder | ||
from .environment import WebflowEnvironment | ||
from .types import OauthScope | ||
|
||
try: | ||
import pydantic.v1 as pydantic # type: ignore | ||
except ImportError: | ||
import pydantic # type: ignore | ||
|
||
# this is used as the default value for optional parameters | ||
OMIT = typing.cast(typing.Any, ...) | ||
|
||
|
||
def authorize_url( | ||
*, | ||
client_id: str, | ||
state: typing.Optional[str] = OMIT, | ||
redirect_uri: typing.Optional[str] = OMIT, | ||
scope: typing.Optional[typing.Union[OauthScope, typing.List[OauthScope]]] = OMIT, | ||
) -> str: | ||
""" | ||
Get the URL to authorize a user | ||
Parameters: | ||
- client_id: str. The OAuth client ID | ||
- state: typing.Optional[str]. The state. | ||
- redirect_uri: typing.Optional[str]. The redirect URI. | ||
- scope: typing.Optional[typing.Union[OauthScope, typing.List[OauthScope]]]. | ||
OAuth Scopes. | ||
--- | ||
from webflow.oauth import authorize_url | ||
from webflow import OauthScope | ||
url = authorize_url( | ||
client_id = "<YOUR_CLIENT_ID>", | ||
redirect_uri = "https://my.server.com/oauth/callback", | ||
scopes = [OauthScope.ReadSites, OauthScope.WriteItems", OauthScope.ReadUsers], | ||
) | ||
""" | ||
params: typing.Dict[str, typing.Any] = { | ||
"client_id": client_id, | ||
"response_type": "code", | ||
} | ||
if state is not OMIT: | ||
params["state"] = state | ||
if redirect_uri is not OMIT: | ||
params["redirect_uri"] = redirect_uri | ||
if scope is not OMIT and isinstance(scope, str): | ||
params["scope"] = scope.value | ||
elif scope is not OMIT: | ||
params["scope"] = ", ".join([s.value for s in scope]) # type: ignore | ||
return f"https://webflow.com/oauth/authorize?{urllib.parse.urlencode(params)}" | ||
|
||
|
||
def get_access_token( | ||
*, | ||
client_id: str, | ||
client_secret: str, | ||
code: str, | ||
redirect_uri: typing.Optional[str] = OMIT, | ||
) -> str: | ||
""" | ||
Get the URL to authorize a user | ||
Parameters: | ||
- client_id: str. The OAuth client ID | ||
- client_secret: str. The OAuth client secret | ||
- code: str. The OAuth code | ||
- redirect_uri: typing.Optional[str]. The redirect URI. | ||
--- | ||
from webflow.oauth import get_access_token | ||
token = get_access_token( | ||
client_id = "<YOUR_CLIENT_ID>", | ||
client_secret = "<YOUR_CLIENT_ID>", | ||
code= "<YOUR_CODE>" | ||
redirect_uri = "https://my.server.com/oauth/callback", | ||
) | ||
""" | ||
request: typing.Dict[str, typing.Any] = { | ||
"client_id": client_id, | ||
"client_secret": client_secret, | ||
"code": code, | ||
"grant_type": "authorization_code", | ||
} | ||
if redirect_uri is not OMIT: | ||
request["redirect_uri"] = redirect_uri | ||
response = httpx.request( | ||
"POST", | ||
"https://api.webflow.com/oauth/access_token", | ||
json=jsonable_encoder(request), | ||
timeout=60, | ||
) | ||
if 200 <= response.status_code < 300: | ||
_response_json = response.json() | ||
return _response_json["access_token"] | ||
try: | ||
raise ApiError(status_code=response.status_code, body=response.json()) | ||
except JSONDecodeError: | ||
raise ApiError(status_code=response.status_code, body=response.text) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# This file was auto-generated by Fern from our API Definition. | ||
|
||
import enum | ||
import typing | ||
|
||
T_Result = typing.TypeVar("T_Result") | ||
|
||
|
||
class OauthScope(str, enum.Enum): | ||
AUTHORIZED_USER_READ = "authorized_user:read" | ||
""" | ||
read details about the authorized user | ||
""" | ||
|
||
READ_PAGES = "read:pages" | ||
""" | ||
read pages on the site | ||
""" | ||
|
||
SITES_READ = "sites:read" | ||
""" | ||
read sites on the site | ||
""" | ||
|
||
SITES_WRITE = "sites:write" | ||
""" | ||
modify pages on the site | ||
""" | ||
|
||
CUSTOM_CODE_READ = "custom_code:read" | ||
""" | ||
read custom code on the site | ||
""" | ||
|
||
CUSTOM_CODE_WRITE = "custom_code:write" | ||
""" | ||
modify custom code on the site | ||
""" | ||
|
||
CUSTOM_CODE_DELETE = "custom_code:delete" | ||
""" | ||
delete custom code on the site | ||
""" | ||
|
||
USERS_READ = "users:read" | ||
""" | ||
read users on the site | ||
""" | ||
|
||
USERS_WRITE = "users:write" | ||
""" | ||
modify users on the site | ||
""" | ||
|
||
ECOMMERCE_READ = "ecommerce:read" | ||
""" | ||
read ecommerce data | ||
""" | ||
|
||
ECOMMERCE_WRITE = "ecommerce:write" | ||
""" | ||
edit ecommerce data | ||
""" | ||
|
||
def visit( | ||
self, | ||
authorized_user_read: typing.Callable[[], T_Result], | ||
read_pages: typing.Callable[[], T_Result], | ||
sites_read: typing.Callable[[], T_Result], | ||
sites_write: typing.Callable[[], T_Result], | ||
custom_code_read: typing.Callable[[], T_Result], | ||
custom_code_write: typing.Callable[[], T_Result], | ||
custom_code_delete: typing.Callable[[], T_Result], | ||
users_read: typing.Callable[[], T_Result], | ||
users_write: typing.Callable[[], T_Result], | ||
ecommerce_read: typing.Callable[[], T_Result], | ||
ecommerce_write: typing.Callable[[], T_Result], | ||
) -> T_Result: | ||
if self is OauthScope.AUTHORIZED_USER_READ: | ||
return authorized_user_read() | ||
if self is OauthScope.READ_PAGES: | ||
return read_pages() | ||
if self is OauthScope.SITES_READ: | ||
return sites_read() | ||
if self is OauthScope.SITES_WRITE: | ||
return sites_write() | ||
if self is OauthScope.CUSTOM_CODE_READ: | ||
return custom_code_read() | ||
if self is OauthScope.CUSTOM_CODE_WRITE: | ||
return custom_code_write() | ||
if self is OauthScope.CUSTOM_CODE_DELETE: | ||
return custom_code_delete() | ||
if self is OauthScope.USERS_READ: | ||
return users_read() | ||
if self is OauthScope.USERS_WRITE: | ||
return users_write() | ||
if self is OauthScope.ECOMMERCE_READ: | ||
return ecommerce_read() | ||
if self is OauthScope.ECOMMERCE_WRITE: | ||
return ecommerce_write() |
Oops, something went wrong.