|
26 | 26 | MATRIX_V2_API_PATH = "/_matrix/client/r0" |
27 | 27 |
|
28 | 28 |
|
29 | | -class MatrixHttpApi(object): |
30 | | - """Contains all raw Matrix HTTP Client-Server API calls. |
| 29 | +class MatrixApi(object): |
| 30 | + """Contains transport-agnostic Matrix Client-Server API calls. |
31 | 31 |
|
32 | | - Usage: |
33 | | - matrix = MatrixHttpApi("https://matrix.org", token="foobar") |
34 | | - response = matrix.sync() |
35 | | - response = matrix.send_message("!roomid:matrix.org", "Hello!") |
36 | | -
|
37 | | - For room and sync handling, consider using MatrixClient. |
| 32 | + For usage, MatrixApi must be subclassed with a valid _send method. |
38 | 33 | """ |
39 | 34 |
|
40 | 35 | def __init__(self, base_url, token=None, identity=None): |
41 | | - """Construct and configure the HTTP API. |
| 36 | + """Construct and configure the API. |
42 | 37 |
|
43 | 38 | Args: |
44 | 39 | base_url(str): The home server URL e.g. 'http://localhost:8008' |
@@ -524,45 +519,8 @@ def create_filter(self, user_id, filter_params): |
524 | 519 | filter_params, |
525 | 520 | api_path=MATRIX_V2_API_PATH) |
526 | 521 |
|
527 | | - def _send(self, method, path, content=None, query_params={}, headers={}, |
528 | | - api_path="/_matrix/client/api/v1"): |
529 | | - method = method.upper() |
530 | | - if method not in ["GET", "PUT", "DELETE", "POST"]: |
531 | | - raise MatrixError("Unsupported HTTP method: %s" % method) |
532 | | - |
533 | | - if "Content-Type" not in headers: |
534 | | - headers["Content-Type"] = "application/json" |
535 | | - |
536 | | - query_params["access_token"] = self.token |
537 | | - if self.identity: |
538 | | - query_params["user_id"] = self.identity |
539 | | - |
540 | | - endpoint = self.base_url + api_path + path |
541 | | - |
542 | | - if headers["Content-Type"] == "application/json" and content is not None: |
543 | | - content = json.dumps(content) |
544 | | - |
545 | | - response = None |
546 | | - while True: |
547 | | - response = requests.request( |
548 | | - method, endpoint, |
549 | | - params=query_params, |
550 | | - data=content, |
551 | | - headers=headers, |
552 | | - verify=self.validate_cert |
553 | | - ) |
554 | | - |
555 | | - if response.status_code == 429: |
556 | | - sleep(response.json()['retry_after_ms'] / 1000) |
557 | | - else: |
558 | | - break |
559 | | - |
560 | | - if response.status_code < 200 or response.status_code >= 300: |
561 | | - raise MatrixRequestError( |
562 | | - code=response.status_code, content=response.text |
563 | | - ) |
564 | | - |
565 | | - return response.json() |
| 522 | + def _send(self, *args, **kwargs): |
| 523 | + raise NotImplementedError("MatrixApi must be subclassed by a transport class.") |
566 | 524 |
|
567 | 525 | def media_upload(self, content, content_type): |
568 | 526 | return self._send( |
@@ -641,3 +599,55 @@ def get_room_members(self, room_id): |
641 | 599 | """ |
642 | 600 | return self._send("GET", "/rooms/{}/members".format(quote(room_id)), |
643 | 601 | api_path=MATRIX_V2_API_PATH) |
| 602 | + |
| 603 | + |
| 604 | +class MatrixHttpApi(MatrixApi): |
| 605 | + """Contains all Matrix Client-Server API calls with Http transport. |
| 606 | +
|
| 607 | + Usage: |
| 608 | + matrix = MatrixHttpApi("https://matrix.org", token="foobar") |
| 609 | + response = matrix.sync() |
| 610 | + response = matrix.send_message("!roomid:matrix.org", "Hello!") |
| 611 | +
|
| 612 | + For room and sync handling, consider using MatrixClient. |
| 613 | + """ |
| 614 | + |
| 615 | + def _send(self, method, path, content=None, query_params={}, headers={}, |
| 616 | + api_path="/_matrix/client/api/v1"): |
| 617 | + method = method.upper() |
| 618 | + if method not in ["GET", "PUT", "DELETE", "POST"]: |
| 619 | + raise MatrixError("Unsupported HTTP method: %s" % method) |
| 620 | + |
| 621 | + if "Content-Type" not in headers: |
| 622 | + headers["Content-Type"] = "application/json" |
| 623 | + |
| 624 | + query_params["access_token"] = self.token |
| 625 | + if self.identity: |
| 626 | + query_params["user_id"] = self.identity |
| 627 | + |
| 628 | + endpoint = self.base_url + api_path + path |
| 629 | + |
| 630 | + if headers["Content-Type"] == "application/json" and content is not None: |
| 631 | + content = json.dumps(content) |
| 632 | + |
| 633 | + response = None |
| 634 | + while True: |
| 635 | + response = requests.request( |
| 636 | + method, endpoint, |
| 637 | + params=query_params, |
| 638 | + data=content, |
| 639 | + headers=headers, |
| 640 | + verify=self.validate_cert |
| 641 | + ) |
| 642 | + |
| 643 | + if response.status_code == 429: |
| 644 | + sleep(response.json()['retry_after_ms'] / 1000) |
| 645 | + else: |
| 646 | + break |
| 647 | + |
| 648 | + if response.status_code < 200 or response.status_code >= 300: |
| 649 | + raise MatrixRequestError( |
| 650 | + code=response.status_code, content=response.text |
| 651 | + ) |
| 652 | + |
| 653 | + return response.json() |
0 commit comments