Compare commits

...

6 Commits

Author SHA1 Message Date
Olivier Wilkinson (reivilibre)
8b2aad8aed Newsfile
Signed-off-by: Olivier Wilkinson (reivilibre) <oliverw@matrix.org>
2021-10-01 14:47:36 +01:00
Olivier Wilkinson (reivilibre)
b9047eab07 v1 APIs return a List of code and then the dict, so check and convert to tuple 2021-10-01 14:46:47 +01:00
Olivier Wilkinson (reivilibre)
67241232c5 Fix annotations of types that feed into get_json and friends. 2021-10-01 10:22:45 +01:00
Olivier Wilkinson (reivilibre)
a41c909188 Await post_json as well as asserting the result is a dict (functional) 2021-10-01 10:10:18 +01:00
Olivier Wilkinson (reivilibre)
e824369788 Where needed, assert that return type is dict not list (mechanical) 2021-10-01 10:07:58 +01:00
Olivier Wilkinson (reivilibre)
3e668fcbc4 Add the desired type annotation 2021-09-29 17:22:47 +01:00
3 changed files with 170 additions and 56 deletions

1
changelog.d/10965.misc Normal file
View File

@@ -0,0 +1 @@
Add type annotations for `client` on `TransportLayerClient`.

View File

@@ -227,7 +227,7 @@ class FederationClient(FederationBase):
)
async def backfill(
self, dest: str, room_id: str, limit: int, extremities: Iterable[str]
self, dest: str, room_id: str, limit: int, extremities: List[str]
) -> Optional[List[EventBase]]:
"""Requests some more historic PDUs for the given room from the
given destination server.

View File

@@ -15,7 +15,7 @@
import logging
import urllib
from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Tuple, Union
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
import attr
import ijson
@@ -30,7 +30,11 @@ from synapse.api.urls import (
)
from synapse.events import EventBase, make_event_from_dict
from synapse.federation.units import Transaction
from synapse.http.matrixfederationclient import ByteParser
from synapse.http.matrixfederationclient import (
ByteParser,
MatrixFederationHttpClient,
QueryArgs,
)
from synapse.logging.utils import log_function
from synapse.types import JsonDict
@@ -47,7 +51,7 @@ class TransportLayerClient:
def __init__(self, hs):
self.server_name = hs.hostname
self.client = hs.get_federation_http_client()
self.client: MatrixFederationHttpClient = hs.get_federation_http_client()
@log_function
async def get_room_state_ids(
@@ -68,12 +72,14 @@ class TransportLayerClient:
logger.debug("get_room_state_ids dest=%s, room=%s", destination, room_id)
path = _create_v1_path("/state_ids/%s", room_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination,
path=path,
args={"event_id": event_id},
try_trailing_slash_on_400=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_event(
@@ -94,13 +100,15 @@ class TransportLayerClient:
logger.debug("get_pdu dest=%s, event_id=%s", destination, event_id)
path = _create_v1_path("/event/%s", event_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination, path=path, timeout=timeout, try_trailing_slash_on_400=True
)
assert isinstance(resp, dict)
return resp
@log_function
async def backfill(
self, destination: str, room_id: str, event_tuples: Iterable[str], limit: int
self, destination: str, room_id: str, event_tuples: List[str], limit: int
) -> Optional[JsonDict]:
"""Requests `limit` previous PDUs in a given context before list of
PDUs.
@@ -128,11 +136,17 @@ class TransportLayerClient:
path = _create_v1_path("/backfill/%s", room_id)
args = {"v": event_tuples, "limit": [str(limit)]}
# wide type annotation needed because Dict's value type parameter is invariant
args: Dict[str, Union[str, List[str]]] = {
"v": event_tuples,
"limit": [str(limit)],
}
return await self.client.get_json(
resp = await self.client.get_json(
destination, path=path, args=args, try_trailing_slash_on_400=True
)
assert isinstance(resp, dict)
return resp
@log_function
async def send_transaction(
@@ -207,7 +221,7 @@ class TransportLayerClient:
room_id: str,
user_id: str,
membership: str,
params: Optional[Mapping[str, Union[str, Iterable[str]]]],
params: Optional[QueryArgs],
) -> JsonDict:
"""Asks a remote server to build and sign us a membership event
@@ -254,7 +268,7 @@ class TransportLayerClient:
ignore_backoff = True
retry_on_dns_fail = True
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args=params,
@@ -262,6 +276,8 @@ class TransportLayerClient:
timeout=20000,
ignore_backoff=ignore_backoff,
)
assert isinstance(resp, dict)
return resp
@log_function
async def send_join_v1(
@@ -307,7 +323,7 @@ class TransportLayerClient:
) -> Tuple[int, JsonDict]:
path = _create_v1_path("/send_leave/%s/%s", room_id, event_id)
return await self.client.put_json(
resp = await self.client.put_json(
destination=destination,
path=path,
data=content,
@@ -317,6 +333,12 @@ class TransportLayerClient:
# sync.
ignore_backoff=True,
)
assert isinstance(resp, list)
assert len(resp) == 2
code, body = resp
assert isinstance(code, int)
assert isinstance(body, dict)
return code, body
@log_function
async def send_leave_v2(
@@ -324,7 +346,7 @@ class TransportLayerClient:
) -> JsonDict:
path = _create_v2_path("/send_leave/%s/%s", room_id, event_id)
return await self.client.put_json(
resp = await self.client.put_json(
destination=destination,
path=path,
data=content,
@@ -334,6 +356,8 @@ class TransportLayerClient:
# sync.
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def send_knock_v1(
@@ -365,9 +389,11 @@ class TransportLayerClient:
"""
path = _create_v1_path("/send_knock/%s/%s", room_id, event_id)
return await self.client.put_json(
resp = await self.client.put_json(
destination=destination, path=path, data=content
)
assert isinstance(resp, dict)
return resp
@log_function
async def send_invite_v1(
@@ -375,9 +401,15 @@ class TransportLayerClient:
) -> Tuple[int, JsonDict]:
path = _create_v1_path("/invite/%s/%s", room_id, event_id)
return await self.client.put_json(
resp = await self.client.put_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, list)
assert len(resp) == 2
code, body = resp
assert isinstance(code, int)
assert isinstance(body, dict)
return code, body
@log_function
async def send_invite_v2(
@@ -385,9 +417,11 @@ class TransportLayerClient:
) -> JsonDict:
path = _create_v2_path("/invite/%s/%s", room_id, event_id)
return await self.client.put_json(
resp = await self.client.put_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_public_rooms(
@@ -460,6 +494,7 @@ class TransportLayerClient:
)
raise
assert isinstance(response, dict)
return response
@log_function
@@ -468,9 +503,11 @@ class TransportLayerClient:
) -> JsonDict:
path = _create_v1_path("/exchange_third_party_invite/%s", room_id)
return await self.client.put_json(
resp = await self.client.put_json(
destination=destination, path=path, data=event_dict
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_event_auth(
@@ -478,7 +515,9 @@ class TransportLayerClient:
) -> JsonDict:
path = _create_v1_path("/event_auth/%s/%s", room_id, event_id)
return await self.client.get_json(destination=destination, path=path)
resp = await self.client.get_json(destination=destination, path=path)
assert isinstance(resp, dict)
return resp
@log_function
async def query_client_keys(
@@ -518,9 +557,11 @@ class TransportLayerClient:
"""
path = _create_v1_path("/user/keys/query")
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=query_content, timeout=timeout
)
assert isinstance(resp, dict)
return resp
@log_function
async def query_user_devices(
@@ -558,9 +599,11 @@ class TransportLayerClient:
"""
path = _create_v1_path("/user/devices/%s", user_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination, path=path, timeout=timeout
)
assert isinstance(resp, dict)
return resp
@log_function
async def claim_client_keys(
@@ -597,9 +640,11 @@ class TransportLayerClient:
path = _create_v1_path("/user/keys/claim")
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=query_content, timeout=timeout
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_missing_events(
@@ -614,7 +659,7 @@ class TransportLayerClient:
) -> JsonDict:
path = _create_v1_path("/get_missing_events/%s", room_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
data={
@@ -625,6 +670,8 @@ class TransportLayerClient:
},
timeout=timeout,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_group_profile(
@@ -633,12 +680,14 @@ class TransportLayerClient:
"""Get a group profile"""
path = _create_v1_path("/groups/%s/profile", group_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def update_group_profile(
@@ -654,13 +703,15 @@ class TransportLayerClient:
"""
path = _create_v1_path("/groups/%s/profile", group_id)
return self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_group_summary(
@@ -669,12 +720,14 @@ class TransportLayerClient:
"""Get a group summary"""
path = _create_v1_path("/groups/%s/summary", group_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_rooms_in_group(
@@ -683,12 +736,14 @@ class TransportLayerClient:
"""Get all rooms in a group"""
path = _create_v1_path("/groups/%s/rooms", group_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
async def add_room_to_group(
self,
@@ -701,13 +756,15 @@ class TransportLayerClient:
"""Add a room to a group"""
path = _create_v1_path("/groups/%s/room/%s", group_id, room_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
async def update_room_in_group(
self,
@@ -723,13 +780,15 @@ class TransportLayerClient:
"/groups/%s/room/%s/config/%s", group_id, room_id, config_key
)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
async def remove_room_from_group(
self, destination: str, group_id: str, requester_user_id: str, room_id: str
@@ -737,12 +796,14 @@ class TransportLayerClient:
"""Remove a room from a group"""
path = _create_v1_path("/groups/%s/room/%s", group_id, room_id)
return await self.client.delete_json(
resp = await self.client.delete_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_users_in_group(
@@ -751,12 +812,14 @@ class TransportLayerClient:
"""Get users in a group"""
path = _create_v1_path("/groups/%s/users", group_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_invited_users_in_group(
@@ -765,12 +828,14 @@ class TransportLayerClient:
"""Get users that have been invited to a group"""
path = _create_v1_path("/groups/%s/invited_users", group_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def accept_group_invite(
@@ -779,20 +844,24 @@ class TransportLayerClient:
"""Accept a group invite"""
path = _create_v1_path("/groups/%s/users/%s/accept_invite", group_id, user_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, dict)
return resp
@log_function
def join_group(
async def join_group(
self, destination: str, group_id: str, user_id: str, content: JsonDict
) -> JsonDict:
"""Attempts to join a group"""
path = _create_v1_path("/groups/%s/users/%s/join", group_id, user_id)
return self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, dict)
return resp
@log_function
async def invite_to_group(
@@ -806,13 +875,15 @@ class TransportLayerClient:
"""Invite a user to a group"""
path = _create_v1_path("/groups/%s/users/%s/invite", group_id, user_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def invite_to_group_notification(
@@ -824,9 +895,11 @@ class TransportLayerClient:
path = _create_v1_path("/groups/local/%s/users/%s/invite", group_id, user_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, dict)
return resp
@log_function
async def remove_user_from_group(
@@ -840,13 +913,15 @@ class TransportLayerClient:
"""Remove a user from a group"""
path = _create_v1_path("/groups/%s/users/%s/remove", group_id, user_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def remove_user_from_group_notification(
@@ -858,9 +933,11 @@ class TransportLayerClient:
path = _create_v1_path("/groups/local/%s/users/%s/remove", group_id, user_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, dict)
return resp
@log_function
async def renew_group_attestation(
@@ -872,9 +949,11 @@ class TransportLayerClient:
path = _create_v1_path("/groups/%s/renew_attestation/%s", group_id, user_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, dict)
return resp
@log_function
async def update_group_summary_room(
@@ -897,13 +976,15 @@ class TransportLayerClient:
else:
path = _create_v1_path("/groups/%s/summary/rooms/%s", group_id, room_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def delete_group_summary_room(
@@ -925,12 +1006,14 @@ class TransportLayerClient:
else:
path = _create_v1_path("/groups/%s/summary/rooms/%s", group_id, room_id)
return await self.client.delete_json(
resp = await self.client.delete_json(
destination=destination,
path=path,
args={"requester_user_id": user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_group_categories(
@@ -939,12 +1022,14 @@ class TransportLayerClient:
"""Get all categories in a group"""
path = _create_v1_path("/groups/%s/categories", group_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_group_category(
@@ -953,12 +1038,14 @@ class TransportLayerClient:
"""Get category info in a group"""
path = _create_v1_path("/groups/%s/categories/%s", group_id, category_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def update_group_category(
@@ -972,13 +1059,15 @@ class TransportLayerClient:
"""Update a category in a group"""
path = _create_v1_path("/groups/%s/categories/%s", group_id, category_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def delete_group_category(
@@ -987,12 +1076,14 @@ class TransportLayerClient:
"""Delete a category in a group"""
path = _create_v1_path("/groups/%s/categories/%s", group_id, category_id)
return await self.client.delete_json(
resp = await self.client.delete_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_group_roles(
@@ -1001,12 +1092,14 @@ class TransportLayerClient:
"""Get all roles in a group"""
path = _create_v1_path("/groups/%s/roles", group_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def get_group_role(
@@ -1015,12 +1108,14 @@ class TransportLayerClient:
"""Get a roles info"""
path = _create_v1_path("/groups/%s/roles/%s", group_id, role_id)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def update_group_role(
@@ -1034,13 +1129,15 @@ class TransportLayerClient:
"""Update a role in a group"""
path = _create_v1_path("/groups/%s/roles/%s", group_id, role_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def delete_group_role(
@@ -1049,12 +1146,14 @@ class TransportLayerClient:
"""Delete a role in a group"""
path = _create_v1_path("/groups/%s/roles/%s", group_id, role_id)
return await self.client.delete_json(
resp = await self.client.delete_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def update_group_summary_user(
@@ -1074,13 +1173,15 @@ class TransportLayerClient:
else:
path = _create_v1_path("/groups/%s/summary/users/%s", group_id, user_id)
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def set_group_join_policy(
@@ -1089,13 +1190,15 @@ class TransportLayerClient:
"""Sets the join policy for a group"""
path = _create_v1_path("/groups/%s/settings/m.join_policy", group_id)
return await self.client.put_json(
resp = await self.client.put_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
data=content,
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
@log_function
async def delete_group_summary_user(
@@ -1114,12 +1217,14 @@ class TransportLayerClient:
else:
path = _create_v1_path("/groups/%s/summary/users/%s", group_id, user_id)
return await self.client.delete_json(
resp = await self.client.delete_json(
destination=destination,
path=path,
args={"requester_user_id": requester_user_id},
ignore_backoff=True,
)
assert isinstance(resp, dict)
return resp
async def bulk_get_publicised_groups(
self, destination: str, user_ids: Iterable[str]
@@ -1130,9 +1235,11 @@ class TransportLayerClient:
content = {"user_ids": user_ids}
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=content, ignore_backoff=True
)
assert isinstance(resp, dict)
return resp
async def get_room_complexity(self, destination: str, room_id: str) -> JsonDict:
"""
@@ -1142,7 +1249,9 @@ class TransportLayerClient:
"""
path = _create_path(FEDERATION_UNSTABLE_PREFIX, "/rooms/%s/complexity", room_id)
return await self.client.get_json(destination=destination, path=path)
resp = await self.client.get_json(destination=destination, path=path)
assert isinstance(resp, dict)
return resp
async def get_space_summary(
self,
@@ -1173,9 +1282,11 @@ class TransportLayerClient:
if max_rooms_per_space is not None:
params["max_rooms_per_space"] = max_rooms_per_space
return await self.client.post_json(
resp = await self.client.post_json(
destination=destination, path=path, data=params
)
assert isinstance(resp, dict)
return resp
async def get_room_hierarchy(
self,
@@ -1193,11 +1304,13 @@ class TransportLayerClient:
FEDERATION_UNSTABLE_PREFIX, "/org.matrix.msc2946/hierarchy/%s", room_id
)
return await self.client.get_json(
resp = await self.client.get_json(
destination=destination,
path=path,
args={"suggested_only": "true" if suggested_only else "false"},
)
assert isinstance(resp, dict)
return resp
def _create_path(federation_prefix: str, path: str, *args: str) -> str: