Skip to content

Commit

Permalink
Router default options, addresses #1267 (#1268)
Browse files Browse the repository at this point in the history
* add pyenv-virtualenv .python-version to ignore

* added Router operation options default dict

* moved statements to a new test and added override checks

* remove typeddict

* optional = None, default False in Operation__init__

* added more testing

* revert tests added to existing file
  • Loading branch information
Ksauder committed Aug 20, 2024
1 parent b1ecd36 commit b655532
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 64 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ docs/site

.DS_Store
.idea
.python-version
48 changes: 24 additions & 24 deletions ninja/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ def get(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -174,10 +174,10 @@ def post(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -217,10 +217,10 @@ def delete(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -260,10 +260,10 @@ def patch(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -303,10 +303,10 @@ def put(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -347,10 +347,10 @@ def api_operation(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down
24 changes: 12 additions & 12 deletions ninja/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ def __init__(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
include_in_schema: bool = True,
url_name: Optional[str] = None,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -99,10 +99,10 @@ def __init__(
self.openapi_extra = openapi_extra

# Exporting models params
self.by_alias = by_alias
self.exclude_unset = exclude_unset
self.exclude_defaults = exclude_defaults
self.exclude_none = exclude_none
self.by_alias = by_alias or False
self.exclude_unset = exclude_unset or False
self.exclude_defaults = exclude_defaults or False
self.exclude_none = exclude_none or False

if hasattr(view_func, "_ninja_contribute_to_operation"):
# Allow 3rd party code to contribute to the operation behavior
Expand Down Expand Up @@ -407,10 +407,10 @@ def add_operation(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down
73 changes: 45 additions & 28 deletions ninja/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,20 @@ def __init__(
auth: Any = NOT_SET,
throttle: Union[BaseThrottle, List[BaseThrottle], NOT_SET_TYPE] = NOT_SET,
tags: Optional[List[str]] = None,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
) -> None:
self.api: Optional[NinjaAPI] = None
self.auth = auth
self.throttle = throttle
self.tags = tags
self.by_alias = by_alias
self.exclude_unset = exclude_unset
self.exclude_defaults = exclude_defaults
self.exclude_none = exclude_none

self.path_operations: Dict[str, PathView] = {}
self._routers: List[Tuple[str, Router]] = []

Expand All @@ -55,10 +64,10 @@ def get(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -95,10 +104,10 @@ def post(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -135,10 +144,10 @@ def delete(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -175,10 +184,10 @@ def patch(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -215,10 +224,10 @@ def put(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -256,10 +265,10 @@ def api_operation(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand Down Expand Up @@ -303,10 +312,10 @@ def add_api_operation(
description: Optional[str] = None,
tags: Optional[List[str]] = None,
deprecated: Optional[bool] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
by_alias: Optional[bool] = None,
exclude_unset: Optional[bool] = None,
exclude_defaults: Optional[bool] = None,
exclude_none: Optional[bool] = None,
url_name: Optional[str] = None,
include_in_schema: bool = True,
openapi_extra: Optional[Dict[str, Any]] = None,
Expand All @@ -316,6 +325,14 @@ def add_api_operation(
self.path_operations[path] = path_view
else:
path_view = self.path_operations[path]

by_alias = by_alias is None and self.by_alias or by_alias
exclude_unset = exclude_unset is None and self.exclude_unset or exclude_unset
exclude_defaults = (
exclude_defaults is None and self.exclude_defaults or exclude_defaults
)
exclude_none = exclude_none is None and self.exclude_none or exclude_none

path_view.add_operation(
path=path,
methods=methods,
Expand Down
62 changes: 62 additions & 0 deletions tests/test_router_defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from typing import Optional

import pytest
from pydantic import Field

from ninja import NinjaAPI, Router, Schema
from ninja.testing import TestClient


class SomeResponse(Schema):
field1: Optional[int] = 1
field2: Optional[str] = "default value"
field3: Optional[int] = Field(None, alias="aliased")


@pytest.mark.parametrize(
"oparg,retdict,assertone,asserttwo",
[
(
"exclude_defaults",
{"field1": 3},
{"field1": 3},
{"field1": 3, "field2": "default value", "field3": None},
),
(
"exclude_unset",
{"field2": "test"},
{"field2": "test"},
{"field1": 1, "field2": "test", "field3": None},
),
(
"exclude_none",
{"field1": None, "field2": None, "aliased": 10},
{"field3": 10},
{"field1": None, "field2": None, "field3": 10},
),
(
"by_alias",
{"aliased": 10},
{"field1": 1, "field2": "default value", "aliased": 10},
{"field1": 1, "field2": "default value", "field3": 10},
),
],
)
def test_router_defaults(oparg, retdict, assertone, asserttwo):
"""Test that the router level settings work and can be overriden at the op level"""
api = NinjaAPI()
router = Router(**{oparg: True})
api.add_router("/", router)

func1 = router.get("/test1", response=SomeResponse)(lambda request: retdict)
func2 = router.get("/test2", response=SomeResponse, **{oparg: False})(
lambda request: retdict
)

client = TestClient(api)

assert getattr(func1._ninja_operation, oparg) is True
assert getattr(func2._ninja_operation, oparg) is False

assert client.get("/test1").json() == assertone
assert client.get("/test2").json() == asserttwo

0 comments on commit b655532

Please sign in to comment.