|
1 | 1 | # This file was auto-generated by Fern from our API Definition. |
2 | 2 |
|
3 | | -from backports.cached_property import cached_property |
| 3 | +import typing |
| 4 | +import urllib.parse |
| 5 | +from json.decoder import JSONDecodeError |
4 | 6 |
|
| 7 | +import httpx |
| 8 | +import pydantic |
| 9 | + |
| 10 | +from .core.api_error import ApiError |
| 11 | +from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper |
| 12 | +from .core.jsonable_encoder import jsonable_encoder |
5 | 13 | from .environment import CodeCombatEnvironment |
6 | 14 | from .resources.auth.client import AsyncAuthClient, AuthClient |
7 | 15 | from .resources.clans.client import AsyncClansClient, ClansClient |
8 | 16 | from .resources.classrooms.client import AsyncClassroomsClient, ClassroomsClient |
9 | 17 | from .resources.stats.client import AsyncStatsClient, StatsClient |
10 | 18 | from .resources.users.client import AsyncUsersClient, UsersClient |
| 19 | +from .types.user_response import UserResponse |
| 20 | + |
| 21 | +# this is used as the default value for optional parameters |
| 22 | +OMIT = typing.cast(typing.Any, ...) |
11 | 23 |
|
12 | 24 |
|
13 | 25 | class CodeCombat: |
14 | 26 | def __init__( |
15 | | - self, *, environment: CodeCombatEnvironment = CodeCombatEnvironment.PRODUCTION, username: str, password: str |
| 27 | + self, |
| 28 | + *, |
| 29 | + base_url: typing.Optional[str] = None, |
| 30 | + environment: CodeCombatEnvironment = CodeCombatEnvironment.DEFAULT, |
| 31 | + username: typing.Union[str, typing.Callable[[], str]], |
| 32 | + password: typing.Union[str, typing.Callable[[], str]], |
| 33 | + timeout: typing.Optional[float] = 60, |
16 | 34 | ): |
17 | | - self._environment = environment |
18 | | - self._username = username |
19 | | - self._password = password |
20 | | - |
21 | | - @cached_property |
22 | | - def auth(self) -> AuthClient: |
23 | | - return AuthClient(environment=self._environment, username=self._username, password=self._password) |
24 | | - |
25 | | - @cached_property |
26 | | - def clans(self) -> ClansClient: |
27 | | - return ClansClient(environment=self._environment, username=self._username, password=self._password) |
28 | | - |
29 | | - @cached_property |
30 | | - def classrooms(self) -> ClassroomsClient: |
31 | | - return ClassroomsClient(environment=self._environment, username=self._username, password=self._password) |
32 | | - |
33 | | - @cached_property |
34 | | - def stats(self) -> StatsClient: |
35 | | - return StatsClient(environment=self._environment, username=self._username, password=self._password) |
36 | | - |
37 | | - @cached_property |
38 | | - def users(self) -> UsersClient: |
39 | | - return UsersClient(environment=self._environment, username=self._username, password=self._password) |
| 35 | + self._client_wrapper = SyncClientWrapper( |
| 36 | + base_url=_get_base_url(base_url=base_url, environment=environment), |
| 37 | + username=username, |
| 38 | + password=password, |
| 39 | + httpx_client=httpx.Client(timeout=timeout), |
| 40 | + ) |
| 41 | + self.auth = AuthClient(client_wrapper=self._client_wrapper) |
| 42 | + self.clans = ClansClient(client_wrapper=self._client_wrapper) |
| 43 | + self.classrooms = ClassroomsClient(client_wrapper=self._client_wrapper) |
| 44 | + self.stats = StatsClient(client_wrapper=self._client_wrapper) |
| 45 | + self.users = UsersClient(client_wrapper=self._client_wrapper) |
| 46 | + |
| 47 | + def post_users_handle_o_auth_identities( |
| 48 | + self, |
| 49 | + handle: str, |
| 50 | + *, |
| 51 | + provider: str, |
| 52 | + access_token: typing.Optional[str] = OMIT, |
| 53 | + code: typing.Optional[str] = OMIT, |
| 54 | + ) -> UserResponse: |
| 55 | + """ |
| 56 | + Adds an OAuth2 identity to the user, so that they can be logged in with that identity. You need to send the OAuth code or the access token to this endpoint. 1. If no access token is provided, it will use your OAuth2 token URL to exchange the given code for an access token. 2. Then it will use the access token (given by you, or received from step 1) to look up the user on your service using the lookup URL, and expects a JSON object in response with an `id` property. 3. It will then save that user `id` to the user in our db as a new OAuthIdentity. In this example, we call your lookup URL (let's say, `https://oauth.provider/user?t=<%= accessToken %>`) with the access token (`1234`). The lookup URL returns `{ id: 'abcd' }` in this case, which we save to the user in our db. |
| 57 | +
|
| 58 | + Parameters: |
| 59 | + - handle: str. The document's `_id` or `slug`. |
| 60 | +
|
| 61 | + - provider: str. Your OAuth Provider ID. |
| 62 | +
|
| 63 | + - access_token: typing.Optional[str]. Will be passed through your lookup URL to get the user ID. Required if no `code`. |
| 64 | +
|
| 65 | + - code: typing.Optional[str]. Will be passed to the OAuth token endpoint to get a token. Required if no `accessToken`. |
| 66 | + """ |
| 67 | + _request: typing.Dict[str, typing.Any] = {"provider": provider} |
| 68 | + if access_token is not OMIT: |
| 69 | + _request["accessToken"] = access_token |
| 70 | + if code is not OMIT: |
| 71 | + _request["code"] = code |
| 72 | + _response = self._client_wrapper.httpx_client.request( |
| 73 | + "POST", |
| 74 | + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"users/{handle}/o-auth-identities"), |
| 75 | + json=jsonable_encoder(_request), |
| 76 | + headers=self._client_wrapper.get_headers(), |
| 77 | + timeout=60, |
| 78 | + ) |
| 79 | + if 200 <= _response.status_code < 300: |
| 80 | + return pydantic.parse_obj_as(UserResponse, _response.json()) # type: ignore |
| 81 | + try: |
| 82 | + _response_json = _response.json() |
| 83 | + except JSONDecodeError: |
| 84 | + raise ApiError(status_code=_response.status_code, body=_response.text) |
| 85 | + raise ApiError(status_code=_response.status_code, body=_response_json) |
40 | 86 |
|
41 | 87 |
|
42 | 88 | class AsyncCodeCombat: |
43 | 89 | def __init__( |
44 | | - self, *, environment: CodeCombatEnvironment = CodeCombatEnvironment.PRODUCTION, username: str, password: str |
| 90 | + self, |
| 91 | + *, |
| 92 | + base_url: typing.Optional[str] = None, |
| 93 | + environment: CodeCombatEnvironment = CodeCombatEnvironment.DEFAULT, |
| 94 | + username: typing.Union[str, typing.Callable[[], str]], |
| 95 | + password: typing.Union[str, typing.Callable[[], str]], |
| 96 | + timeout: typing.Optional[float] = 60, |
45 | 97 | ): |
46 | | - self._environment = environment |
47 | | - self._username = username |
48 | | - self._password = password |
49 | | - |
50 | | - @cached_property |
51 | | - def auth(self) -> AsyncAuthClient: |
52 | | - return AsyncAuthClient(environment=self._environment, username=self._username, password=self._password) |
53 | | - |
54 | | - @cached_property |
55 | | - def clans(self) -> AsyncClansClient: |
56 | | - return AsyncClansClient(environment=self._environment, username=self._username, password=self._password) |
57 | | - |
58 | | - @cached_property |
59 | | - def classrooms(self) -> AsyncClassroomsClient: |
60 | | - return AsyncClassroomsClient(environment=self._environment, username=self._username, password=self._password) |
61 | | - |
62 | | - @cached_property |
63 | | - def stats(self) -> AsyncStatsClient: |
64 | | - return AsyncStatsClient(environment=self._environment, username=self._username, password=self._password) |
65 | | - |
66 | | - @cached_property |
67 | | - def users(self) -> AsyncUsersClient: |
68 | | - return AsyncUsersClient(environment=self._environment, username=self._username, password=self._password) |
| 98 | + self._client_wrapper = AsyncClientWrapper( |
| 99 | + base_url=_get_base_url(base_url=base_url, environment=environment), |
| 100 | + username=username, |
| 101 | + password=password, |
| 102 | + httpx_client=httpx.AsyncClient(timeout=timeout), |
| 103 | + ) |
| 104 | + self.auth = AsyncAuthClient(client_wrapper=self._client_wrapper) |
| 105 | + self.clans = AsyncClansClient(client_wrapper=self._client_wrapper) |
| 106 | + self.classrooms = AsyncClassroomsClient(client_wrapper=self._client_wrapper) |
| 107 | + self.stats = AsyncStatsClient(client_wrapper=self._client_wrapper) |
| 108 | + self.users = AsyncUsersClient(client_wrapper=self._client_wrapper) |
| 109 | + |
| 110 | + async def post_users_handle_o_auth_identities( |
| 111 | + self, |
| 112 | + handle: str, |
| 113 | + *, |
| 114 | + provider: str, |
| 115 | + access_token: typing.Optional[str] = OMIT, |
| 116 | + code: typing.Optional[str] = OMIT, |
| 117 | + ) -> UserResponse: |
| 118 | + """ |
| 119 | + Adds an OAuth2 identity to the user, so that they can be logged in with that identity. You need to send the OAuth code or the access token to this endpoint. 1. If no access token is provided, it will use your OAuth2 token URL to exchange the given code for an access token. 2. Then it will use the access token (given by you, or received from step 1) to look up the user on your service using the lookup URL, and expects a JSON object in response with an `id` property. 3. It will then save that user `id` to the user in our db as a new OAuthIdentity. In this example, we call your lookup URL (let's say, `https://oauth.provider/user?t=<%= accessToken %>`) with the access token (`1234`). The lookup URL returns `{ id: 'abcd' }` in this case, which we save to the user in our db. |
| 120 | +
|
| 121 | + Parameters: |
| 122 | + - handle: str. The document's `_id` or `slug`. |
| 123 | +
|
| 124 | + - provider: str. Your OAuth Provider ID. |
| 125 | +
|
| 126 | + - access_token: typing.Optional[str]. Will be passed through your lookup URL to get the user ID. Required if no `code`. |
| 127 | +
|
| 128 | + - code: typing.Optional[str]. Will be passed to the OAuth token endpoint to get a token. Required if no `accessToken`. |
| 129 | + """ |
| 130 | + _request: typing.Dict[str, typing.Any] = {"provider": provider} |
| 131 | + if access_token is not OMIT: |
| 132 | + _request["accessToken"] = access_token |
| 133 | + if code is not OMIT: |
| 134 | + _request["code"] = code |
| 135 | + _response = await self._client_wrapper.httpx_client.request( |
| 136 | + "POST", |
| 137 | + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"users/{handle}/o-auth-identities"), |
| 138 | + json=jsonable_encoder(_request), |
| 139 | + headers=self._client_wrapper.get_headers(), |
| 140 | + timeout=60, |
| 141 | + ) |
| 142 | + if 200 <= _response.status_code < 300: |
| 143 | + return pydantic.parse_obj_as(UserResponse, _response.json()) # type: ignore |
| 144 | + try: |
| 145 | + _response_json = _response.json() |
| 146 | + except JSONDecodeError: |
| 147 | + raise ApiError(status_code=_response.status_code, body=_response.text) |
| 148 | + raise ApiError(status_code=_response.status_code, body=_response_json) |
| 149 | + |
| 150 | + |
| 151 | +def _get_base_url(*, base_url: typing.Optional[str] = None, environment: CodeCombatEnvironment) -> str: |
| 152 | + if base_url is not None: |
| 153 | + return base_url |
| 154 | + elif environment is not None: |
| 155 | + return environment.value |
| 156 | + else: |
| 157 | + raise Exception("Please pass in either base_url or environment to construct the client") |
0 commit comments