@@ -41,10 +41,10 @@ <h1 class="title">Module <code>supertokens_python.framework.fastapi.fastapi_resp
4141# under the License.
4242import json
4343from math import ceil
44- from time import time
4544from typing import Any, Dict, Optional
4645
4746from supertokens_python.framework.response import BaseResponse
47+ from supertokens_python.utils import get_timestamp_ms
4848
4949
5050class FastApiResponse(BaseResponse):
@@ -77,31 +77,22 @@ <h1 class="title">Module <code>supertokens_python.framework.fastapi.fastapi_resp
7777 httponly: bool = False,
7878 samesite: str = "lax",
7979 ):
80- if domain is None:
81- # we do ceil because if we do floor, we tests may fail where the access
82- # token lifetime is set to 1 second
83- self.response.set_cookie(
84- key=key,
85- value=value,
86- expires=ceil((expires - int(time() * 1000)) / 1000),
87- path=path,
88- secure=secure,
89- httponly=httponly,
90- samesite=samesite,
91- )
92- else:
93- # we do ceil because if we do floor, we tests may fail where the access
94- # token lifetime is set to 1 second
95- self.response.set_cookie(
96- key=key,
97- value=value,
98- expires=ceil((expires - int(time() * 1000)) / 1000),
99- path=path,
100- domain=domain,
101- secure=secure,
102- httponly=httponly,
103- samesite=samesite,
104- )
80+ # Note: For FastAPI response object, the expires value
81+ # doesn't mean the absolute time in ms, but the duration in seconds
82+ # So we need to convert our absolute expiry time (ms) to a duration (seconds)
83+
84+ # we do ceil because if we do floor, we tests may fail where the access
85+ # token lifetime is set to 1 second
86+ self.response.set_cookie(
87+ key=key,
88+ value=value, # Note: Unlike other frameworks, FastAPI wraps the value in quotes in Set-Cookie header
89+ expires=ceil((expires - get_timestamp_ms()) / 1000),
90+ path=path,
91+ domain=domain, # type: ignore # starlette didn't set domain as optional type but their default value is None anyways
92+ secure=secure,
93+ httponly=httponly,
94+ samesite=samesite,
95+ )
10596
10697 def set_header(self, key: str, value: str):
10798 self.response.headers[key] = value
@@ -183,31 +174,22 @@ <h2 class="section-title" id="header-classes">Classes</h2>
183174 httponly: bool = False,
184175 samesite: str = "lax",
185176 ):
186- if domain is None:
187- # we do ceil because if we do floor, we tests may fail where the access
188- # token lifetime is set to 1 second
189- self.response.set_cookie(
190- key=key,
191- value=value,
192- expires=ceil((expires - int(time() * 1000)) / 1000),
193- path=path,
194- secure=secure,
195- httponly=httponly,
196- samesite=samesite,
197- )
198- else:
199- # we do ceil because if we do floor, we tests may fail where the access
200- # token lifetime is set to 1 second
201- self.response.set_cookie(
202- key=key,
203- value=value,
204- expires=ceil((expires - int(time() * 1000)) / 1000),
205- path=path,
206- domain=domain,
207- secure=secure,
208- httponly=httponly,
209- samesite=samesite,
210- )
177+ # Note: For FastAPI response object, the expires value
178+ # doesn't mean the absolute time in ms, but the duration in seconds
179+ # So we need to convert our absolute expiry time (ms) to a duration (seconds)
180+
181+ # we do ceil because if we do floor, we tests may fail where the access
182+ # token lifetime is set to 1 second
183+ self.response.set_cookie(
184+ key=key,
185+ value=value, # Note: Unlike other frameworks, FastAPI wraps the value in quotes in Set-Cookie header
186+ expires=ceil((expires - get_timestamp_ms()) / 1000),
187+ path=path,
188+ domain=domain, # type: ignore # starlette didn't set domain as optional type but their default value is None anyways
189+ secure=secure,
190+ httponly=httponly,
191+ samesite=samesite,
192+ )
211193
212194 def set_header(self, key: str, value: str):
213195 self.response.headers[key] = value
@@ -298,31 +280,22 @@ <h3>Methods</h3>
298280 httponly: bool = False,
299281 samesite: str = "lax",
300282):
301- if domain is None:
302- # we do ceil because if we do floor, we tests may fail where the access
303- # token lifetime is set to 1 second
304- self.response.set_cookie(
305- key=key,
306- value=value,
307- expires=ceil((expires - int(time() * 1000)) / 1000),
308- path=path,
309- secure=secure,
310- httponly=httponly,
311- samesite=samesite,
312- )
313- else:
314- # we do ceil because if we do floor, we tests may fail where the access
315- # token lifetime is set to 1 second
316- self.response.set_cookie(
317- key=key,
318- value=value,
319- expires=ceil((expires - int(time() * 1000)) / 1000),
320- path=path,
321- domain=domain,
322- secure=secure,
323- httponly=httponly,
324- samesite=samesite,
325- )</ code > </ pre >
283+ # Note: For FastAPI response object, the expires value
284+ # doesn't mean the absolute time in ms, but the duration in seconds
285+ # So we need to convert our absolute expiry time (ms) to a duration (seconds)
286+
287+ # we do ceil because if we do floor, we tests may fail where the access
288+ # token lifetime is set to 1 second
289+ self.response.set_cookie(
290+ key=key,
291+ value=value, # Note: Unlike other frameworks, FastAPI wraps the value in quotes in Set-Cookie header
292+ expires=ceil((expires - get_timestamp_ms()) / 1000),
293+ path=path,
294+ domain=domain, # type: ignore # starlette didn't set domain as optional type but their default value is None anyways
295+ secure=secure,
296+ httponly=httponly,
297+ samesite=samesite,
298+ )</ code > </ pre >
326299</ details >
327300</ dd >
328301< dt id ="supertokens_python.framework.fastapi.fastapi_response.FastApiResponse.set_header "> < code class ="name flex ">
0 commit comments