Office365-REST-Python-Client
Office365-REST-Python-Client copied to clipboard
Error Uploading File - Extra data in JSON ???
Getting the error talked about here (https://github.com/vgrem/Office365-REST-Python-Client/issues/547). Discussion on this seems to be dead.
import os
from office365.sharepoint.client_context import ClientContext
from office365.onedrive.driveitems.driveItem import DriveItem
class SharepointClient():
def __init__(self, client_id="", tenant_id="", cert_thumbprint="", cert_path="", site="", channel=""):
if client_id:
self.client_id = client_id
else:
raise Exception(self.return_certifcate_generation_information("client_id parameter is required."))
if tenant_id:
self.tenant_id = tenant_id
else:
raise Exception(self.return_certifcate_generation_information("tenant_id parameter is required."))
if cert_thumbprint:
self.cert_thumbprint = cert_thumbprint
else:
raise Exception(self.return_certifcate_generation_information("cert_thumbprint parameter is required."))
self.msal_authority = f'https://login.microsoftonline.com/{self.tenant_id}'
if not site:
raise Exception(self.return_certifcate_generation_information("site parameter is required."))
else:
self.site = site
self.site_url = f"https://prefix.sharepoint.com/sites/{site}"
self.relative_prefix = f"/sites/{self.site}"
if channel:
self.site_url += f"-{channel}"
self.relative_prefix += f"-{channel}"
if cert_path:
self.current_script_path = os.path.abspath(cert_path)
else:
self.current_script_path = os.path.abspath(__file__)
self.current_script_path = os.path.abspath(os.path.dirname(self.current_script_path))
self.cert = {
"private_key": self.load_private_key(),
"thumbprint": self.cert_thumbprint
}
self.ctx = ClientContext(self.site_url).with_client_certificate(
self.tenant_id,
self.client_id,
self.cert_thumbprint,
os.path.join(self.current_script_path, "key.pem")
)
def load_private_key(self):
private_key = open(os.path.join(self.current_script_path, "key.pem"), "rb").read()
self.load_private_key = private_key
if private_key:
return private_key
else:
raise Exception("Key could not be loaded.")
def write(self, sub_directories=[], file_name="", file_contents=""):
base_folder = self.ctx.web.lists.get_by_title("Documents").root_folder
target_folder = base_folder
for directory in sub_directories:
# hacky way to change directory since it will grab the object if it already exists
target_folder = target_folder.add(directory)
print(f"Created directory structure: {os.path.split(self.site_url)[-1]} / Shared Documents / {' / '.join(sub_directories)}")
target_folder.execute_query()
if file_name and file_contents:
target_file = target_folder.upload_file(file_name, file_contents).execute_query()
print(f"File uploaded to {target_file.serverRelativeUrl}")
def return_certifcate_generation_information(self, s):
return f"""
{s}
If you do not have a certificate, one can be created using the following command in powershell:
openssl req -newkey rsa:2048 -new -nodes -x509 -days 999999 -keyout key.pem -out cert.pem
Upload the resultant .pem file on Azure AD manager under your App Registration's "Certificates & secrets", and then the "Certificates" tab.
"""
def get_folders_by_relative_path(self, relative_path):
root = self.ctx.web.get_folder_by_server_relative_url(relative_path).expand(["Files", 'Folders']).get().execute_query()
for folder in root.folders:
yield folder
if __name__ == "__main__":
sp_client = SharepointClient(
client_id="###############################",
tenant_id="###############################",
cert_thumbprint="###############################",
cert_path="{path to cert}",
site="team name",
channel="channel name"
)
sp_client.write(sub_directories=["Some Folder", "Some Sub Folder", "Target Folder"], file_name="test.txt", file_contents="this is a test".encode())
Traceback:
Traceback (most recent call last):
File "C:\Program Files\Python310\lib\site-packages\requests\models.py", line 971, in json
return complexjson.loads(self.text, **kwargs)
File "C:\Program Files\Python310\lib\site-packages\simplejson\__init__.py", line 525, in loads
return _default_decoder.decode(s)
File "C:\Program Files\Python310\lib\site-packages\simplejson\decoder.py", line 375, in decode
raise JSONDecodeError("Extra data", s, end, len(s))
simplejson.errors.JSONDecodeError: Extra data: line 1 column 5 - line 1 column 19 (char 4 - 18)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\inetpub\wwwroot\docup\test.py", line 25, in <module>
sp_client.write(sub_directories=["Some Folder", "Some Sub Folder", "Target Folder"], file_name="test.txt", file_contents="this is a test".encode())
File "C:\inetpub\wwwroot\includes\python\sharepoint_client.py", line 86, in write
target_folder.execute_query()
File "C:\Program Files\Python310\lib\site-packages\office365\runtime\client_object.py", line 44, in execute_query
self.context.execute_query()
File "C:\Program Files\Python310\lib\site-packages\office365\runtime\client_runtime_context.py", line 161, in execute_query
self.pending_request().execute_query(qry)
File "C:\Program Files\Python310\lib\site-packages\office365\runtime\client_request.py", line 57, in execute_query
response = self.execute_request_direct(request)
File "C:\Program Files\Python310\lib\site-packages\office365\runtime\client_request.py", line 69, in execute_request_direct
self.beforeExecute.notify(request)
File "C:\Program Files\Python310\lib\site-packages\office365\runtime\types\event_handler.py", line 21, in notify
listener(*args, **kwargs)
File "C:\Program Files\Python310\lib\site-packages\office365\sharepoint\client_context.py", line 221, in _build_modification_query
self._ensure_form_digest(request)
File "C:\Program Files\Python310\lib\site-packages\office365\sharepoint\client_context.py", line 157, in _ensure_form_digest
self._ctx_web_info = self._get_context_web_information()
File "C:\Program Files\Python310\lib\site-packages\office365\sharepoint\client_context.py", line 170, in _get_context_web_information
client.map_json(response.json(), return_value, json_format)
File "C:\Program Files\Python310\lib\site-packages\requests\models.py", line 975, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Extra data: line 1 column 5 (char 4)