Skip to content

Commit 80fb21f

Browse files
MadLittleModsMic92
authored andcommitted
Reorganize Pydantic models and types used in handlers (element-hq#17279)
Spawning from element-hq#17187 (comment) around wanting to put `SlidingSyncBody` (parse the request in the rest layer), `SlidingSyncConfig` (from the rest layer, pass to the handler), `SlidingSyncResponse` (pass the response from the handler back to the rest layer to respond) somewhere that doesn't contaminate the imports and cause circular import issues. - Moved Pydantic parsing models to `synapse/types/rest` - Moved handler types to `synapse/types/handlers`
1 parent 388e573 commit 80fb21f

File tree

15 files changed

+269
-244
lines changed

15 files changed

+269
-244
lines changed

changelog.d/17279.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Re-organize Pydantic models and types used in handlers.

synapse/events/validator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@
4747
validate_canonicaljson,
4848
)
4949
from synapse.http.servlet import validate_json_object
50-
from synapse.rest.models import RequestBodyModel
5150
from synapse.storage.controllers.state import server_acl_evaluator_from_event
5251
from synapse.types import EventID, JsonDict, RoomID, StrCollection, UserID
52+
from synapse.types.rest import RequestBodyModel
5353

5454

5555
class EventValidator:

synapse/handlers/pagination.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@
3737
JsonMapping,
3838
Requester,
3939
ScheduledTask,
40-
ShutdownRoomParams,
41-
ShutdownRoomResponse,
4240
StreamKeyType,
4341
TaskStatus,
4442
)
43+
from synapse.types.handlers import ShutdownRoomParams, ShutdownRoomResponse
4544
from synapse.types.state import StateFilter
4645
from synapse.util.async_helpers import ReadWriteLock
4746
from synapse.visibility import filter_events_for_client

synapse/handlers/room.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,14 @@
8080
RoomAlias,
8181
RoomID,
8282
RoomStreamToken,
83-
ShutdownRoomParams,
84-
ShutdownRoomResponse,
8583
StateMap,
8684
StrCollection,
8785
StreamKeyType,
8886
StreamToken,
8987
UserID,
9088
create_requester,
9189
)
90+
from synapse.types.handlers import ShutdownRoomParams, ShutdownRoomResponse
9291
from synapse.types.state import StateFilter
9392
from synapse.util import stringutils
9493
from synapse.util.caches.response_cache import ResponseCache

synapse/handlers/sliding_sync.py

Lines changed: 3 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,14 @@
1818
#
1919
#
2020
import logging
21-
from enum import Enum
22-
from typing import TYPE_CHECKING, AbstractSet, Dict, Final, List, Optional, Tuple
21+
from typing import TYPE_CHECKING, AbstractSet, Dict, List, Optional
2322

24-
import attr
2523
from immutabledict import immutabledict
2624

27-
from synapse._pydantic_compat import HAS_PYDANTIC_V2
28-
29-
if TYPE_CHECKING or HAS_PYDANTIC_V2:
30-
from pydantic.v1 import Extra
31-
else:
32-
from pydantic import Extra
33-
3425
from synapse.api.constants import Membership
3526
from synapse.events import EventBase
36-
from synapse.rest.client.models import SlidingSyncBody
37-
from synapse.types import JsonMapping, Requester, RoomStreamToken, StreamToken, UserID
27+
from synapse.types import Requester, RoomStreamToken, StreamToken, UserID
28+
from synapse.types.handlers import OperationType, SlidingSyncConfig, SlidingSyncResult
3829

3930
if TYPE_CHECKING:
4031
from synapse.server import HomeServer
@@ -62,166 +53,6 @@ def filter_membership_for_sync(*, membership: str, user_id: str, sender: str) ->
6253
return membership != Membership.LEAVE or sender != user_id
6354

6455

65-
class SlidingSyncConfig(SlidingSyncBody):
66-
"""
67-
Inherit from `SlidingSyncBody` since we need all of the same fields and add a few
68-
extra fields that we need in the handler
69-
"""
70-
71-
user: UserID
72-
device_id: Optional[str]
73-
74-
# Pydantic config
75-
class Config:
76-
# By default, ignore fields that we don't recognise.
77-
extra = Extra.ignore
78-
# By default, don't allow fields to be reassigned after parsing.
79-
allow_mutation = False
80-
# Allow custom types like `UserID` to be used in the model
81-
arbitrary_types_allowed = True
82-
83-
84-
class OperationType(Enum):
85-
"""
86-
Represents the operation types in a Sliding Sync window.
87-
88-
Attributes:
89-
SYNC: Sets a range of entries. Clients SHOULD discard what they previous knew about
90-
entries in this range.
91-
INSERT: Sets a single entry. If the position is not empty then clients MUST move
92-
entries to the left or the right depending on where the closest empty space is.
93-
DELETE: Remove a single entry. Often comes before an INSERT to allow entries to move
94-
places.
95-
INVALIDATE: Remove a range of entries. Clients MAY persist the invalidated range for
96-
offline support, but they should be treated as empty when additional operations
97-
which concern indexes in the range arrive from the server.
98-
"""
99-
100-
SYNC: Final = "SYNC"
101-
INSERT: Final = "INSERT"
102-
DELETE: Final = "DELETE"
103-
INVALIDATE: Final = "INVALIDATE"
104-
105-
106-
@attr.s(slots=True, frozen=True, auto_attribs=True)
107-
class SlidingSyncResult:
108-
"""
109-
The Sliding Sync result to be serialized to JSON for a response.
110-
111-
Attributes:
112-
next_pos: The next position token in the sliding window to request (next_batch).
113-
lists: Sliding window API. A map of list key to list results.
114-
rooms: Room subscription API. A map of room ID to room subscription to room results.
115-
extensions: Extensions API. A map of extension key to extension results.
116-
"""
117-
118-
@attr.s(slots=True, frozen=True, auto_attribs=True)
119-
class RoomResult:
120-
"""
121-
Attributes:
122-
name: Room name or calculated room name.
123-
avatar: Room avatar
124-
heroes: List of stripped membership events (containing `user_id` and optionally
125-
`avatar_url` and `displayname`) for the users used to calculate the room name.
126-
initial: Flag which is set when this is the first time the server is sending this
127-
data on this connection. Clients can use this flag to replace or update
128-
their local state. When there is an update, servers MUST omit this flag
129-
entirely and NOT send "initial":false as this is wasteful on bandwidth. The
130-
absence of this flag means 'false'.
131-
required_state: The current state of the room
132-
timeline: Latest events in the room. The last event is the most recent
133-
is_dm: Flag to specify whether the room is a direct-message room (most likely
134-
between two people).
135-
invite_state: Stripped state events. Same as `rooms.invite.$room_id.invite_state`
136-
in sync v2, absent on joined/left rooms
137-
prev_batch: A token that can be passed as a start parameter to the
138-
`/rooms/<room_id>/messages` API to retrieve earlier messages.
139-
limited: True if their are more events than fit between the given position and now.
140-
Sync again to get more.
141-
joined_count: The number of users with membership of join, including the client's
142-
own user ID. (same as sync `v2 m.joined_member_count`)
143-
invited_count: The number of users with membership of invite. (same as sync v2
144-
`m.invited_member_count`)
145-
notification_count: The total number of unread notifications for this room. (same
146-
as sync v2)
147-
highlight_count: The number of unread notifications for this room with the highlight
148-
flag set. (same as sync v2)
149-
num_live: The number of timeline events which have just occurred and are not historical.
150-
The last N events are 'live' and should be treated as such. This is mostly
151-
useful to determine whether a given @mention event should make a noise or not.
152-
Clients cannot rely solely on the absence of `initial: true` to determine live
153-
events because if a room not in the sliding window bumps into the window because
154-
of an @mention it will have `initial: true` yet contain a single live event
155-
(with potentially other old events in the timeline).
156-
"""
157-
158-
name: str
159-
avatar: Optional[str]
160-
heroes: Optional[List[EventBase]]
161-
initial: bool
162-
required_state: List[EventBase]
163-
timeline: List[EventBase]
164-
is_dm: bool
165-
invite_state: List[EventBase]
166-
prev_batch: StreamToken
167-
limited: bool
168-
joined_count: int
169-
invited_count: int
170-
notification_count: int
171-
highlight_count: int
172-
num_live: int
173-
174-
@attr.s(slots=True, frozen=True, auto_attribs=True)
175-
class SlidingWindowList:
176-
"""
177-
Attributes:
178-
count: The total number of entries in the list. Always present if this list
179-
is.
180-
ops: The sliding list operations to perform.
181-
"""
182-
183-
@attr.s(slots=True, frozen=True, auto_attribs=True)
184-
class Operation:
185-
"""
186-
Attributes:
187-
op: The operation type to perform.
188-
range: Which index positions are affected by this operation. These are
189-
both inclusive.
190-
room_ids: Which room IDs are affected by this operation. These IDs match
191-
up to the positions in the `range`, so the last room ID in this list
192-
matches the 9th index. The room data is held in a separate object.
193-
"""
194-
195-
op: OperationType
196-
range: Tuple[int, int]
197-
room_ids: List[str]
198-
199-
count: int
200-
ops: List[Operation]
201-
202-
next_pos: StreamToken
203-
lists: Dict[str, SlidingWindowList]
204-
rooms: Dict[str, RoomResult]
205-
extensions: JsonMapping
206-
207-
def __bool__(self) -> bool:
208-
"""Make the result appear empty if there are no updates. This is used
209-
to tell if the notifier needs to wait for more events when polling for
210-
events.
211-
"""
212-
return bool(self.lists or self.rooms or self.extensions)
213-
214-
@staticmethod
215-
def empty(next_pos: StreamToken) -> "SlidingSyncResult":
216-
"Return a new empty result"
217-
return SlidingSyncResult(
218-
next_pos=next_pos,
219-
lists={},
220-
rooms={},
221-
extensions={},
222-
)
223-
224-
22556
class SlidingSyncHandler:
22657
def __init__(self, hs: "HomeServer"):
22758
self.clock = hs.get_clock()

synapse/rest/client/account.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@
5656
from synapse.http.site import SynapseRequest
5757
from synapse.metrics import threepid_send_requests
5858
from synapse.push.mailer import Mailer
59-
from synapse.rest.client.models import (
59+
from synapse.types import JsonDict
60+
from synapse.types.rest import RequestBodyModel
61+
from synapse.types.rest.client import (
6062
AuthenticationData,
6163
ClientSecretStr,
6264
EmailRequestTokenBody,
6365
MsisdnRequestTokenBody,
6466
)
65-
from synapse.rest.models import RequestBodyModel
66-
from synapse.types import JsonDict
6767
from synapse.util.msisdn import phone_number_to_msisdn
6868
from synapse.util.stringutils import assert_valid_client_secret, random_string
6969
from synapse.util.threepids import check_3pid_allowed, validate_email

synapse/rest/client/devices.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
)
4343
from synapse.http.site import SynapseRequest
4444
from synapse.rest.client._base import client_patterns, interactive_auth_handler
45-
from synapse.rest.client.models import AuthenticationData
46-
from synapse.rest.models import RequestBodyModel
4745
from synapse.types import JsonDict
46+
from synapse.types.rest import RequestBodyModel
47+
from synapse.types.rest.client import AuthenticationData
4848

4949
if TYPE_CHECKING:
5050
from synapse.server import HomeServer

synapse/rest/client/directory.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
)
4242
from synapse.http.site import SynapseRequest
4343
from synapse.rest.client._base import client_patterns
44-
from synapse.rest.models import RequestBodyModel
4544
from synapse.types import JsonDict, RoomAlias
45+
from synapse.types.rest import RequestBodyModel
4646

4747
if TYPE_CHECKING:
4848
from synapse.server import HomeServer

synapse/rest/client/sync.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
)
5454
from synapse.http.site import SynapseRequest
5555
from synapse.logging.opentracing import trace_with_opname
56-
from synapse.rest.client.models import SlidingSyncBody
5756
from synapse.types import JsonDict, Requester, StreamToken
57+
from synapse.types.rest.client import SlidingSyncBody
5858
from synapse.util import json_decoder
5959
from synapse.util.caches.lrucache import LruCache
6060

synapse/rest/key/v2/remote_key_resource.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
parse_and_validate_json_object_from_request,
4242
parse_integer,
4343
)
44-
from synapse.rest.models import RequestBodyModel
4544
from synapse.storage.keys import FetchKeyResultForRemote
4645
from synapse.types import JsonDict
46+
from synapse.types.rest import RequestBodyModel
4747
from synapse.util import json_decoder
4848
from synapse.util.async_helpers import yieldable_gather_results
4949

synapse/types/__init__.py

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,60 +1279,3 @@ class ScheduledTask:
12791279
result: Optional[JsonMapping]
12801280
# Optional error that should be assigned a value when the status is FAILED
12811281
error: Optional[str]
1282-
1283-
1284-
class ShutdownRoomParams(TypedDict):
1285-
"""
1286-
Attributes:
1287-
requester_user_id:
1288-
User who requested the action. Will be recorded as putting the room on the
1289-
blocking list.
1290-
new_room_user_id:
1291-
If set, a new room will be created with this user ID
1292-
as the creator and admin, and all users in the old room will be
1293-
moved into that room. If not set, no new room will be created
1294-
and the users will just be removed from the old room.
1295-
new_room_name:
1296-
A string representing the name of the room that new users will
1297-
be invited to. Defaults to `Content Violation Notification`
1298-
message:
1299-
A string containing the first message that will be sent as
1300-
`new_room_user_id` in the new room. Ideally this will clearly
1301-
convey why the original room was shut down.
1302-
Defaults to `Sharing illegal content on this server is not
1303-
permitted and rooms in violation will be blocked.`
1304-
block:
1305-
If set to `true`, this room will be added to a blocking list,
1306-
preventing future attempts to join the room. Defaults to `false`.
1307-
purge:
1308-
If set to `true`, purge the given room from the database.
1309-
force_purge:
1310-
If set to `true`, the room will be purged from database
1311-
even if there are still users joined to the room.
1312-
"""
1313-
1314-
requester_user_id: Optional[str]
1315-
new_room_user_id: Optional[str]
1316-
new_room_name: Optional[str]
1317-
message: Optional[str]
1318-
block: bool
1319-
purge: bool
1320-
force_purge: bool
1321-
1322-
1323-
class ShutdownRoomResponse(TypedDict):
1324-
"""
1325-
Attributes:
1326-
kicked_users: An array of users (`user_id`) that were kicked.
1327-
failed_to_kick_users:
1328-
An array of users (`user_id`) that that were not kicked.
1329-
local_aliases:
1330-
An array of strings representing the local aliases that were
1331-
migrated from the old room to the new.
1332-
new_room_id: A string representing the room ID of the new room.
1333-
"""
1334-
1335-
kicked_users: List[str]
1336-
failed_to_kick_users: List[str]
1337-
local_aliases: List[str]
1338-
new_room_id: Optional[str]

0 commit comments

Comments
 (0)