Skip to content

Set and delete cookies with all of Starlette's options through ViewSetResult (0.14.1) - #73

Merged
velis74 merged 3 commits into
mainfrom
viewset-result-cookie-options
Oct 27, 2026
Merged

velis74 merged 3 commits into
mainfrom
viewset-result-cookie-options

Conversation

@velis74

@velis74 velis74 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Summary

ViewSetResult sets and deletes cookies with every option of Starlette's Response.set_cookie() /
Response.delete_cookie(), so an action or a command middleware sets an HttpOnly, Secure, SameSite session
cookie with a Max-Age, and deletes it, without putting it into the body and without modifies_response_shape.

@__router.post("login")
async def login(self, credentials: Credentials) -> ViewSetResult[Account]:
    result = ViewSetResult(body=Account(username=credentials.username))
    result.set_cookie("sessionid", session_key, max_age=1209600, secure=True, httponly=True, samesite="lax")
    return result

@__router.post("logout")
async def logout(self) -> ViewSetResult[None]:
    result = ViewSetResult(body=None)
    result.delete_cookie("sessionid", secure=True, httponly=True, samesite="lax")
    return result

Changes

  • Cookie(value, max_age, expires, path, domain, secure, httponly, samesite, partitioned) and
    DeleteCookie(path, domain, secure, httponly, samesite) in fastapi_viewsets.middleware: dataclasses with
    Starlette's parameters and defaults, SerializableObjects.
  • ViewSetResult.set_cookie() / ViewSetResult.delete_cookie() with the signatures of the Starlette methods; they
    store a Cookie / DeleteCookie in ViewSetResult.cookies. Any other value in cookies is set as
    str(value) with Starlette's defaults, as before.
  • apply_cookies(response, cookies) applies them with Starlette's own set_cookie() / delete_cookie(); the
    lifecycle runner uses it. partitioned is passed on only when True.
  • ViewSetResult.__serialize__ / __deserialize__ and the celery_viewset result transport carry Cookie /
    DeleteCookie with all options (expires as datetime, number or string keeps its type).
  • Docs: the command middleware guide documents cookies values, the two methods, a login/logout session-cookie
    example, and that status_code/headers/cookies do not change the response shape; how route_viewset decides
    to drop the response_model (global list, read at decoration, every route of the class; instances injected by
    @action_configuration not consulted). The muxws guide states that reply headers hold the last value of a repeated
    header. Docstrings updated accordingly.
  • Version 0.14.1 (Python and npm), changelog entry.

Tests

  • HTTP: set with every option, delete, plain/option/deletion mix in one result, middleware-set cookies, typed
    OpenAPI schema kept; headers compared with what Starlette's own Response produces for the same arguments.
  • muxws: set-cookie in the reply headers for a set and a deletion.
  • Celery: codec round trip, in-process worker over HTTP and muxws, real-worker e2e (worker_e2e_test.py).
  • Serialization round trip through JSON for every expires type.

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

✅ Incremental coverage — 100%

████████████████████ 58 / 58 changed lines covered · threshold 70% · main → viewset-result-cookie-options

File Coverage Covered Uncovered lines
✅ fastapi_viewsets/__init__.py 100% 1 / 1 —
✅ fastapi_viewsets/decorators/celery_viewset/transport.py 100% 0 / 0 no executable lines changed
✅ fastapi_viewsets/decorators/lifecycle_runner.py 100% 2 / 2 —
✅ fastapi_viewsets/decorators/route_viewset.py 100% 0 / 0 no executable lines changed
✅ fastapi_viewsets/middleware/__init__.py 100% 6 / 6 —
✅ fastapi_viewsets/middleware/cookies.py 100% 49 / 49 —
Total 100% 58 / 58
11 files not graded (4 ignored by pattern, 7 not source files)
File Reason
changelog.md not a source file
docs/api/route-viewset.md not a source file
docs/guide/command-middleware.md not a source file
docs/guide/muxws.md not a source file
docs/guide/routers.md not a source file
fastapi_viewsets/decorators/celery_viewset/transport_test.py ignored by *_test.py
fastapi_viewsets/decorators/celery_viewset/worker_e2e_test.py ignored by *_test.py
fastapi_viewsets/middleware/__init___test.py ignored by *_test.py
fastapi_viewsets/middleware/cookies_test.py ignored by *_test.py
package-lock.json not a source file
package.json not a source file

Coverage reports: coverage.json (coverage.py, 69 files) · coverage/clover.xml (clover, 13 files) — incremental-coverage-check v3.0.0

@velis74
velis74 merged commit 7bf8f61 into main Oct 27, 2026
6 checks passed
@velis74
velis74 deleted the viewset-result-cookie-options branch October 27, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant