brynq-sdk-sharepoint 3.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ from .sharepoint import Sharepoint
@@ -0,0 +1,258 @@
1
+ from brynq_sdk_brynq import BrynQ
2
+ import os
3
+ from typing import List, Union, Literal, Optional
4
+ import requests
5
+ import json
6
+ from io import BytesIO
7
+ import typing
8
+
9
+
10
+ class Sharepoint(BrynQ):
11
+ def __init__(self, system_type: Optional[Literal['source', 'target']] = None, site: str = None, site_id: str = None, json_subset: int = None, site_name: str = None, debug: bool = False, deviating_data_interface_id: int = None):
12
+ """
13
+ :param label: label of the sharepoint system in BrynQ
14
+ :param site: base url of the sharepoint site
15
+ :param site_id: site id of the sharepoint site
16
+ :param json_subset: fill in the part of the json that needs to be accessed to get the wanted drive id, accompanying the drive you are looking for
17
+ :param debug: set to True to enable debug logging
18
+ :param deviating_data_interface_id: Sometimes you need to get credentials from another data interface. This is the data interface id of the data interface you want to get the credentials from.
19
+ """
20
+ super().__init__()
21
+ self.system_type = system_type
22
+ self.data_interface_id = deviating_data_interface_id if deviating_data_interface_id is not None else self.data_interface_id
23
+ credentials = self.interfaces.credentials.get(system="sharepoint", system_type=system_type)
24
+ credentials = credentials.get('data')
25
+ self.debug = debug
26
+ self.timeout = 3600
27
+ if self.debug:
28
+ print(f"credentials: {credentials}")
29
+ self.access_token = credentials['access_token']
30
+ if site_name is not None:
31
+ self.json_subset = 0 if json_subset is None else json_subset
32
+ self.site_id = self.get_site_id(site_name=site_name)
33
+ elif site_id is not None:
34
+ self.site_id = f"{site},{site_id}"
35
+ self.json_subset = json_subset
36
+ else:
37
+ raise KeyError('Either site_name or site_id, site and json_subset must be provided')
38
+ if self.debug:
39
+ print(f"site_id: {self.site_id}, json_subset: {self.json_subset}, credentials: {credentials}")
40
+
41
+ def _refresh_credentials(self):
42
+ credentials = self.interfaces.credentials.get(system="sharepoint", system_type=self.system_type)
43
+ credentials = credentials.get('data')
44
+ self.access_token = credentials['access_token']
45
+
46
+ def _get_sharepoint_headers(self):
47
+ self._refresh_credentials()
48
+ headers = {'Authorization': f'Bearer {self.access_token}'}
49
+ if self.debug:
50
+ print(headers)
51
+
52
+ return headers
53
+
54
+ def get_site_id(self, site_name: str) -> str:
55
+ """
56
+ Get the site id of a site
57
+ :param site_name: name of the site
58
+ :return: site id
59
+ """
60
+ url = f'https://graph.microsoft.com/v1.0/sites?search={site_name}'
61
+ if self.debug:
62
+ print(f"url: {url}")
63
+ response = requests.get(url=url, headers=self._get_sharepoint_headers(), timeout=self.timeout)
64
+ response.raise_for_status()
65
+ site_id = response.json()['value'][0]['id']
66
+ if self.debug:
67
+ print(f"site_id: {site_id}")
68
+
69
+ return site_id
70
+
71
+ def get_driveid(self):
72
+ """
73
+ This method is used to derive the driveid to which the files have to be uploaded. Needed in the upload url for file upload.
74
+ :return: returns the needed driveid
75
+ """
76
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives'
77
+ if self.debug:
78
+ print(f"url: {url}")
79
+ response = requests.get(url, headers=self._get_sharepoint_headers(), timeout=self.timeout)
80
+ response.raise_for_status()
81
+ drive_id = response.json()['value'][self.json_subset]['id']
82
+ if self.debug:
83
+ print(f"drive_id: {drive_id}")
84
+
85
+ return drive_id
86
+
87
+ def upload_file(self, local_file_path: str, remote_file_path: str):
88
+ """
89
+ This method performs the actual file upload to the formerly derived site + drive.
90
+ local_file_path: local path of the file you want to upload
91
+ remote_file_path: remote path of the folder and filename where you want to place the file
92
+ """
93
+ drive_id = self.get_driveid()
94
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{drive_id}/root:/{remote_file_path}:/createUploadSession'
95
+ if self.debug:
96
+ print(f"url: {url}")
97
+ headers = self._get_sharepoint_headers()
98
+ response = requests.post(url, headers=headers, timeout=self.timeout)
99
+ response.raise_for_status()
100
+ upload_url = response.json()['uploadUrl']
101
+ if self.debug:
102
+ print(f"upload_url: {upload_url}")
103
+ with open(f'{local_file_path}', 'rb') as file_input:
104
+ file_bytes = os.path.getsize(f'{local_file_path}')
105
+ headers_upload = {'Content-Type': 'application/json',
106
+ 'Content-Length': f'{file_bytes}',
107
+ 'Content-Range': f'bytes 0-{file_bytes - 1}/{file_bytes}'}
108
+ response_upload = requests.put(url=upload_url, headers=headers_upload, data=file_input, timeout=self.timeout)
109
+ response_upload.raise_for_status()
110
+
111
+ return response_upload
112
+
113
+ def open_file(self, remote_file_path: str) -> bytes:
114
+ """
115
+ Get a file from sharepoint as a bytesstream
116
+ remote_file_path: filepath on sharepoint
117
+ :return: bytes of file object
118
+ """
119
+ drive_id = self.get_driveid()
120
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{drive_id}/root:/{remote_file_path}'
121
+ if self.debug:
122
+ print(f"url: {url}")
123
+ headers = self._get_sharepoint_headers()
124
+ response = requests.get(url=url, headers=headers, timeout=self.timeout)
125
+ response.raise_for_status()
126
+ download_url = response.json()['@microsoft.graph.downloadUrl']
127
+ if self.debug:
128
+ print(f"download_url: {download_url}")
129
+ response_download = requests.get(url=download_url, headers=headers, timeout=self.timeout)
130
+ response_download.raise_for_status()
131
+
132
+ return response_download.content
133
+
134
+ def download_file(self, local_file_path: str, remote_file_path: str):
135
+ """
136
+ This method downloads a file from sharepoint to the local machine.
137
+ local_file_path: local folder where the file will be downloaded to
138
+ remote_file_path: remote path of the file on sharepoint
139
+ """
140
+ driveid = self.get_driveid()
141
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{driveid}/root:/{remote_file_path}'
142
+ headers = self._get_sharepoint_headers()
143
+ response = requests.get(url=url, headers=headers, timeout=self.timeout)
144
+ response.raise_for_status()
145
+ download_url = response.json()['@microsoft.graph.downloadUrl']
146
+ response_download = requests.get(url=download_url, headers=headers, timeout=self.timeout)
147
+ response_download.raise_for_status()
148
+ with open(file=f'{local_file_path}', mode='wb') as f:
149
+ f.write(BytesIO(response_download.content).read())
150
+
151
+ return response_download
152
+
153
+ def download_files(self, local_folder_path: str, remote_folder_path: str):
154
+ """
155
+ This method downloads a file from sharepoint to the local machine.
156
+ local_folder_path: local folder where the files will be downloaded to
157
+ remote_folder_path: remote path of the folder you want to get on sharepoint
158
+ """
159
+ driveid = self.get_driveid()
160
+ folder_content = self.list_dir(remote_folder_path=remote_folder_path)
161
+ # remove subdirectories, can not be downloaded
162
+ folder_content = [item for item in folder_content if 'file' in item]
163
+ if self.debug:
164
+ print(f"folder_content: {folder_content}")
165
+ filecount = 0
166
+
167
+ responses = []
168
+ for file in folder_content:
169
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{driveid}/root:/{remote_folder_path}{file["name"]}'
170
+ if self.debug:
171
+ print(f"url: {url}")
172
+ headers = self._get_sharepoint_headers()
173
+ response = requests.get(url=url, headers=headers, timeout=self.timeout)
174
+ response.raise_for_status()
175
+ download_url = response.json()['@microsoft.graph.downloadUrl']
176
+ response_download = requests.get(url=download_url, headers=headers, timeout=self.timeout)
177
+ with open(file=f'{local_folder_path}{file["name"]}', mode='wb') as f:
178
+ f.write(BytesIO(response_download.content).read())
179
+ filecount += 1
180
+ responses.append(response_download)
181
+ print(f'{filecount} files downloaded')
182
+
183
+ return responses
184
+
185
+ def list_dir(self, remote_folder_path: str, get_files_from_nested_folders: bool = False) -> [json, typing.Generator]:
186
+ """
187
+ Fetch the contents of the API and return the "children"
188
+ which has the information of all the items under that folder
189
+ remote_folder_path: folder path you want to list
190
+ :return: all the contents of the folder items
191
+ """
192
+ if get_files_from_nested_folders:
193
+ return list(self._get_all_files_in_folder(folder_path=remote_folder_path))
194
+
195
+ drive_id = self.get_driveid()
196
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{drive_id}/root:/{remote_folder_path}?expand=children'
197
+ if self.debug:
198
+ print(f"url: {url}")
199
+ response = requests.get(url, headers=self._get_sharepoint_headers(), timeout=120)
200
+ response.raise_for_status()
201
+
202
+ return response.json()['children']
203
+
204
+ # helpers function to get all files in a nested directory
205
+ def _get_all_files_in_folder(self, folder_path) -> typing.Generator:
206
+ children = self.list_dir(remote_folder_path=folder_path)
207
+ for child in children:
208
+ if 'file' in child:
209
+ yield {"folder": folder_path, "file": child['name'], "id": child['id']}
210
+ else:
211
+ yield from self._get_all_files_in_folder(folder_path=f"{folder_path}/{child['name']}")
212
+
213
+ def remove_file(self, remote_file_path: str):
214
+ """
215
+ Remove a file from Sharepoint
216
+ remote_file_path: complete path including filename
217
+ :return: response from Sharepoint
218
+ """
219
+ drive_id = self.get_driveid()
220
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{drive_id}/root:/{remote_file_path}'
221
+ if self.debug:
222
+ print(f"url: {url}")
223
+ response = requests.delete(url=url, headers=self._get_sharepoint_headers(), timeout=self.timeout)
224
+ response.raise_for_status()
225
+
226
+ return response
227
+
228
+ def remove_files(self, remote_folder_path: str):
229
+ """
230
+ Remove a file from Sharepoint
231
+ remote_folder_path: folder path that you want to empty
232
+ """
233
+ drive_id = self.get_driveid()
234
+ folder_content = self.list_dir(remote_folder_path=remote_folder_path)
235
+ responses = []
236
+ for file in folder_content:
237
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{drive_id}/root:/{remote_folder_path}{file["name"]}'
238
+ if self.debug:
239
+ print(f"url: {url}")
240
+ response = requests.delete(url=url, headers=self._get_sharepoint_headers(), timeout=self.timeout)
241
+ response.raise_for_status()
242
+ responses.append(response)
243
+
244
+ return responses
245
+
246
+ def remove_folder(self, folder_id: str):
247
+ """
248
+ Remove a folder from Sharepoint
249
+ folder: folder id that you want to delete
250
+ """
251
+ drive_id = self.get_driveid()
252
+ url = f'https://graph.microsoft.com/v1.0/sites/{self.site_id}/drives/{drive_id}/items/{folder_id}'
253
+ if self.debug:
254
+ print(f"url: {url}")
255
+ response = requests.delete(url=url, headers=self._get_sharepoint_headers(), timeout=self.timeout)
256
+ response.raise_for_status()
257
+
258
+ return response
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: brynq_sdk_sharepoint
3
+ Version: 3.1.0
4
+ Summary: Sharepoint wrapper from BrynQ
5
+ Author: BrynQ
6
+ Author-email: support@brynq.com
7
+ License: BrynQ License
8
+ Requires-Dist: brynq-sdk-brynq<5,>=4
9
+ Requires-Dist: requests<=3,>=2
10
+ Dynamic: author
11
+ Dynamic: author-email
12
+ Dynamic: description
13
+ Dynamic: license
14
+ Dynamic: requires-dist
15
+ Dynamic: summary
16
+
17
+ Sharepoint wrapper from BrynQ
@@ -0,0 +1,6 @@
1
+ brynq_sdk_sharepoint/__init__.py,sha256=_a97AIYUyo6XHTL3tX3z0SYIBcqvxC9HTwEzjCzjEDY,34
2
+ brynq_sdk_sharepoint/sharepoint.py,sha256=AfeaA5rjwr8wh2NIihBRalhN61YmPIYARhCB_ND0AcQ,11996
3
+ brynq_sdk_sharepoint-3.1.0.dist-info/METADATA,sha256=YqCSkjPyx4GKvbzP6WS7NmyrlhrEYQx8XH6QcuXAs08,387
4
+ brynq_sdk_sharepoint-3.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
5
+ brynq_sdk_sharepoint-3.1.0.dist-info/top_level.txt,sha256=rQPErn1un8EwO_9Lt5jnuQJ9IiELAoSFIizKKkzhzFY,21
6
+ brynq_sdk_sharepoint-3.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ brynq_sdk_sharepoint