Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Move the BaseModel subclass to synapse.rest
Browse files Browse the repository at this point in the history
and give it a rename to be a bit more specific
  • Loading branch information
David Robertson committed Aug 10, 2022
1 parent f8f6037 commit c404f8f
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 26 deletions.
24 changes: 24 additions & 0 deletions synapse/rest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# limitations under the License.
from typing import TYPE_CHECKING, Callable

from pydantic import BaseModel, Extra

from synapse.http.server import HttpServer, JsonResource
from synapse.rest import admin
from synapse.rest.client import (
Expand Down Expand Up @@ -130,3 +132,25 @@ def register_servlets(client_resource: HttpServer, hs: "HomeServer") -> None:

# unstable
mutual_rooms.register_servlets(hs, client_resource)


class RequestBodyModel(BaseModel):
"""A custom version of Pydantic's BaseModel which
- ignores unknown fields and
- does not allow fields to be overwritten after construction,
but otherwise uses Pydantic's default behaviour.
Ignoring unknown fields is a useful default. It means that clients can provide
unstable field not known to the server without the request being refused outright.
Subclassing in this way is recommended by
https://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally
"""

class Config:
# By default, ignore fields that we don't recognise.
extra = Extra.ignore
# By default, don't allow fields to be reassigned after parsing.
allow_mutation = False
7 changes: 4 additions & 3 deletions synapse/rest/client/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@
from synapse.http.site import SynapseRequest
from synapse.metrics import threepid_send_requests
from synapse.push.mailer import Mailer
from synapse.rest import RequestBodyModel
from synapse.rest.client.models import AuthenticationData, EmailRequestTokenBody
from synapse.types import JsonDict, SynapseBaseModel
from synapse.types import JsonDict
from synapse.util.msisdn import phone_number_to_msisdn
from synapse.util.stringutils import assert_valid_client_secret, random_string
from synapse.util.threepids import check_3pid_allowed, validate_email
Expand Down Expand Up @@ -159,7 +160,7 @@ def __init__(self, hs: "HomeServer"):
self.password_policy_handler = hs.get_password_policy_handler()
self._set_password_handler = hs.get_set_password_handler()

class PostBody(SynapseBaseModel):
class PostBody(RequestBodyModel):
auth: Optional[AuthenticationData] = None
logout_devices: StrictBool = True
if TYPE_CHECKING:
Expand Down Expand Up @@ -293,7 +294,7 @@ def __init__(self, hs: "HomeServer"):
self.auth_handler = hs.get_auth_handler()
self._deactivate_account_handler = hs.get_deactivate_account_handler()

class PostBody(SynapseBaseModel):
class PostBody(RequestBodyModel):
auth: Optional[AuthenticationData] = None
id_server: Optional[StrictStr] = None
# Not specced, see https://github.com/matrix-org/matrix-spec/issues/297
Expand Down
15 changes: 12 additions & 3 deletions synapse/rest/client/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,28 @@

from pydantic import Extra, StrictInt, StrictStr, constr, validator

from synapse.types import SynapseBaseModel
from synapse.rest import RequestBodyModel
from synapse.util.threepids import validate_email


class AuthenticationData(SynapseBaseModel):
class AuthenticationData(RequestBodyModel):
"""
Data used during user-interactive authentication.
(The name "Authentication Data" is taken directly from the spec.)
Additional keys will be present, depending on the `type` field. Use `.dict()` to
access them.
"""

class Config:
extra = Extra.allow

session: Optional[StrictStr] = None
type: Optional[StrictStr] = None


class EmailRequestTokenBody(SynapseBaseModel):
class EmailRequestTokenBody(RequestBodyModel):
if TYPE_CHECKING:
client_secret: StrictStr
else:
Expand Down
20 changes: 0 additions & 20 deletions synapse/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

import attr
from frozendict import frozendict
from pydantic import BaseModel, Extra
from signedjson.key import decode_verify_key_bytes
from signedjson.types import VerifyKey
from typing_extensions import Final, TypedDict
Expand Down Expand Up @@ -921,22 +920,3 @@ class UserProfile(TypedDict):
class RetentionPolicy:
min_lifetime: Optional[int] = None
max_lifetime: Optional[int] = None


class SynapseBaseModel(BaseModel):
"""A custom version of Pydantic's BaseModel.
This
- ignores unknown fields and
- does not allow fields to be overwritten after construction,
but otherwise uses Pydantic's default behaviour.
Subclassing in this way is recommended by
https://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally
"""

class Config:
# By default, ignore fields that we don't recognise.
extra = Extra.ignore
# By default, don't allow fields to be reassigned after parsing.
allow_mutation = False

0 comments on commit c404f8f

Please sign in to comment.