|
1 | | -""" |
2 | | -Graph Session |
3 | | -""" |
| 1 | +from typing import Optional |
| 2 | + |
4 | 3 | from requests import Session |
5 | 4 |
|
6 | | -from msgraphcore.constants import BASE_URL, SDK_VERSION |
| 5 | +from msgraphcore.client_factory import HTTPClientFactory |
7 | 6 | from msgraphcore.middleware.abc_token_credential import TokenCredential |
8 | | -from msgraphcore.middleware.authorization import AuthorizationHandler |
9 | | -from msgraphcore.middleware.middleware import BaseMiddleware, MiddlewarePipeline |
| 7 | +from msgraphcore.middleware.middleware import BaseMiddleware |
10 | 8 | from msgraphcore.middleware.options.middleware_control import middleware_control |
11 | 9 |
|
12 | 10 |
|
13 | | -class GraphSession(Session): |
14 | | - """Extends Session with Graph functionality |
15 | | -
|
16 | | - Extends Session by adding support for middleware options and middleware pipeline |
17 | | - """ |
| 11 | +class GraphClient: |
| 12 | + """Constructs a custom HTTPClient to be used for requests against Microsoft Graph""" |
18 | 13 | def __init__( |
19 | | - self, |
20 | | - credential: TokenCredential, |
21 | | - scopes: [str] = ['.default'], |
22 | | - middleware: list = [], |
23 | | - api_version: str = 'v1.0' |
| 14 | + self, credential: Optional[TokenCredential], session: Optional[Session], |
| 15 | + middleware: Optional[[BaseMiddleware]], **kwargs |
24 | 16 | ): |
25 | | - super().__init__() |
26 | | - self._append_sdk_version() |
27 | | - self._base_url = BASE_URL + '/' + api_version |
28 | | - |
29 | | - auth_handler = AuthorizationHandler(credential, scopes) |
30 | | - |
31 | | - # The authorization handler should be the first middleware in the pipeline. |
32 | | - middleware.insert(0, auth_handler) |
33 | | - self._register(middleware) |
| 17 | + """ |
| 18 | + Class constructor that accepts a session object and kwargs to |
| 19 | + be passed to the HTTPClientFactory |
| 20 | + """ |
| 21 | + self.graph_session = get_graph_session(credential, session, middleware, **kwargs) |
34 | 22 |
|
35 | 23 | @middleware_control.get_middleware_options |
36 | 24 | def get(self, url: str, **kwargs): |
37 | 25 | r"""Sends a GET request. Returns :class:`Response` object. |
38 | | -
|
39 | 26 | :param url: URL for the new :class:`Request` object. |
40 | 27 | :param \*\*kwargs: Optional arguments that ``request`` takes. |
41 | 28 | :rtype: requests.Response |
42 | 29 | """ |
43 | | - return super().get(self._graph_url(url), **kwargs) |
| 30 | + return self.graph_session.get(self._graph_url(url), **kwargs) |
44 | 31 |
|
45 | 32 | @middleware_control.get_middleware_options |
46 | 33 | def post(self, url, data=None, json=None, **kwargs): |
47 | 34 | r"""Sends a POST request. Returns :class:`Response` object. |
48 | | -
|
49 | 35 | :param url: URL for the new :class:`Request` object. |
50 | 36 | :param data: (optional) Dictionary, list of tuples, bytes, or file-like |
51 | 37 | object to send in the body of the :class:`Request`. |
52 | 38 | :param json: (optional) json to send in the body of the :class:`Request`. |
53 | 39 | :param \*\*kwargs: Optional arguments that ``request`` takes. |
54 | 40 | :rtype: requests.Response |
55 | 41 | """ |
56 | | - return super().post(self._graph_url(url), data, json, **kwargs) |
| 42 | + return self.graph_session.post(self._graph_url(url), data, json, **kwargs) |
57 | 43 |
|
58 | 44 | @middleware_control.get_middleware_options |
59 | 45 | def put(self, url, data=None, **kwargs): |
60 | 46 | r"""Sends a PUT request. Returns :class:`Response` object. |
61 | | -
|
62 | 47 | :param url: URL for the new :class:`Request` object. |
63 | 48 | :param data: (optional) Dictionary, list of tuples, bytes, or file-like |
64 | 49 | object to send in the body of the :class:`Request`. |
65 | 50 | :param \*\*kwargs: Optional arguments that ``request`` takes. |
66 | 51 | :rtype: requests.Response |
67 | 52 | """ |
68 | | - return super().put(self._graph_url(url), data, **kwargs) |
| 53 | + return self.graph_session.put(self._graph_url(url), data, **kwargs) |
69 | 54 |
|
70 | 55 | @middleware_control.get_middleware_options |
71 | 56 | def patch(self, url, data=None, **kwargs): |
72 | 57 | r"""Sends a PATCH request. Returns :class:`Response` object. |
73 | | -
|
74 | 58 | :param url: URL for the new :class:`Request` object. |
75 | 59 | :param data: (optional) Dictionary, list of tuples, bytes, or file-like |
76 | 60 | object to send in the body of the :class:`Request`. |
77 | 61 | :param \*\*kwargs: Optional arguments that ``request`` takes. |
78 | 62 | :rtype: requests.Response |
79 | 63 | """ |
80 | | - return super().patch(self._graph_url(url), data, **kwargs) |
| 64 | + return self.graph_session.patch(self._graph_url(url), data, **kwargs) |
81 | 65 |
|
82 | 66 | @middleware_control.get_middleware_options |
83 | 67 | def delete(self, url, **kwargs): |
84 | 68 | r"""Sends a DELETE request. Returns :class:`Response` object. |
85 | | -
|
86 | 69 | :param url: URL for the new :class:`Request` object. |
87 | 70 | :param \*\*kwargs: Optional arguments that ``request`` takes. |
88 | 71 | :rtype: requests.Response |
89 | 72 | """ |
90 | | - return super().delete(self._graph_url(url), **kwargs) |
| 73 | + return self.graph_session.delete(self._graph_url(url), **kwargs) |
91 | 74 |
|
92 | 75 | def _graph_url(self, url: str) -> str: |
93 | 76 | """Appends BASE_URL to user provided path |
94 | | -
|
95 | 77 | :param url: user provided path |
96 | 78 | :return: graph_url |
97 | 79 | """ |
98 | | - return self._base_url + url if (url[0] == '/') else url |
99 | | - |
100 | | - def _register(self, middleware: [BaseMiddleware]) -> None: |
101 | | - """Adds middleware to middleware_pipeline |
102 | | -
|
103 | | - :param middleware: list of middleware |
104 | | - """ |
105 | | - if middleware: |
106 | | - middleware_pipeline = MiddlewarePipeline() |
107 | | - |
108 | | - for ware in middleware: |
109 | | - middleware_pipeline.add_middleware(ware) |
110 | | - |
111 | | - self.mount('https://', middleware_pipeline) |
112 | | - |
113 | | - def _append_sdk_version(self) -> None: |
114 | | - """Updates sdkVersion in headers with comma-separated new values |
115 | | - """ |
116 | | - if 'sdkVersion' in self.headers: |
117 | | - self.headers.update( |
118 | | - { |
119 | | - 'sdkVersion': |
120 | | - 'graph-python-' + SDK_VERSION + ', ' + self.headers.get('sdkVersion') |
121 | | - } |
122 | | - ) |
123 | | - else: |
124 | | - self.headers.update({'sdkVersion': 'graph-python-' + SDK_VERSION}) |
| 80 | + return self.graph_session.base_url + url if (url[0] == '/') else url |
| 81 | + |
| 82 | + |
| 83 | +_INSTANCE = None |
| 84 | + |
| 85 | + |
| 86 | +def get_graph_session( |
| 87 | + credential: Optional[TokenCredential], session: Optional[Session], |
| 88 | + middleware: Optional[[BaseMiddleware]], **kwargs |
| 89 | +): |
| 90 | + """Method to always return a single instance of a HTTP Client""" |
| 91 | + global _INSTANCE |
| 92 | + |
| 93 | + if credential and middleware: |
| 94 | + raise Exception("Invalid parameters! Both TokenCredential and middleware cannot be passed") |
| 95 | + if not credential and not middleware: |
| 96 | + raise ValueError("Invalid parameters!. Missing TokenCredential or middleware") |
| 97 | + if _INSTANCE is None: |
| 98 | + if credential: |
| 99 | + _INSTANCE = HTTPClientFactory(session, |
| 100 | + **kwargs).create_with_default_middleware(credential) |
| 101 | + elif middleware: |
| 102 | + _INSTANCE = HTTPClientFactory(session, |
| 103 | + **kwargs).create_with_custom_middleware(middleware) |
| 104 | + return _INSTANCE |
0 commit comments