Office365-REST-Python-Client icon indicating copy to clipboard operation
Office365-REST-Python-Client copied to clipboard

Error Uploading File - Extra data in JSON ???

Open UNIcodeX opened this issue 1 year ago • 0 comments

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)

UNIcodeX avatar May 02 '24 14:05 UNIcodeX