X

Best Practices from Oracle Development's A‑Team

Using Oracle Documents Cloud REST API with Python Requests

Mark Foster
Director

Python Requests is a library that simplifies consuming RESTful resources from the client side. The Oracle Documents Cloud Service (DOCS) REST API fits well with Python Requests, allowing a service call to get a folder or file to be done in few lines of code. Since Python is naturally friendly to JSON responses, parsing the Response object can be done using standard syntax.

The Requests library must be installed to Python using the pip utility (or easy-install on Windows). The example below also uses the "getpass" module to handle user entry of a password.

Python Requests link: http://docs.python-requests.org/en/latest/

Python getpass module link: https://docs.python.org/2/library/getpass.html

 

A first look at using Requests with DOCS REST services is to get a user's Personal Workspace. Notice that importing the Requests library allows calling a HTTP GET on a REST URL. All of the HTTP work is done in Python Requests and the client code need only pass in a URL, username, and password.

import requests import getpass docsurl='https://mydocsinstance/documents/api/1.1/folders/items' username='peter.flies@oracle.com' # Get password from user entry. This is using a module called "getpass" pw = getpass.getpass("Enter password:") response = requests.get(docsurl, auth=(username, pw)) # View the status code - should be 200. Error handling can be done with the status code. print (response.status_code) # Header data is available from the Response object, which is part of Python Requests print (response.headers['content-type']) # Get the JSON data j = response.json() # Navigate the JSON data using standard Python print('count=' + j['count']) print('errorCode=' + j['errorCode']) print('totalResults=' + j['totalResults']) print('Items:') for item in j['items']:  print ('type=' + item['type'] + ' name=' + item['name'] + ' owner=' + item['ownedBy']['displayName'])

 

An upload example requires a multipart HTTP POST request to send the file payload and a JSON payload. This example also shows the use of a Session in Python Requests. The Session can have the Authorization header set once and be re-used for all subsequent REST calls to Oracle Documents Cloud service. The example below uploads all files in a directory to a user's DOCS account. A folder GUID is needed for the upload to add the new files into the target folder. Some additional lines of code are added here for printing out the amount of milliseconds that each upload takes. The upload request differs from the previous example in that the POST request needs multipart payload to succeed. Notice that a data part called "jsonInputParameters" and a file part called "primaryFile" are both added to the request. Python's os module can handle opening the file and placing it into the multipart. A loop can grab each file from the directory and submit an upload request.

import os import getpass import time import requests docsurl='https://mydocsinstance/documents/api/1.1' path = 'C:/TEMP/upload' username = 'peter.flies@oracle.com' uploadfolderid = 'F26415F66B0BE6EE53314461T0000DEFAULT00000000' # Get user input to set the password. Set the REST client authorization header by directly passing in the username and password pw = getpass.getpass("Enter password:") files = (file for file in os.listdir(path)  if os.path.isfile(os.path.join(path, file))) # Requests has a reusable Session object. Init it with the Authorization header s = requests.Session() s.auth = (username, pw) print('Uploading files from path ' + path + ' to Documents Cloud Service ' + docsurl + '.\n') for file in files:  startMillis = int(round(time.time() * 1000))  print('Uploading ' + file + '...')  print(path + '/' + file)  resourcePath = 'files/data'  fullpath = path + '/' + file  files = {   'primaryFile': open(fullpath, 'rb')  }  jsondata='{\"parentID\": \"' + uploadfolderid + '\" }'  data = {   'jsonInputParameters': jsondata  }  response = s.post(docsurl + '/' + resourcePath, files=files, data=data)  endMillis = int(round(time.time() * 1000))  if(response.status_code == 200 or response.status_code == 201):   j = response.json()   print('Upload successful. ' + str(endMillis - startMillis) + ' ms. File id: ' + j['id'] + ', version number: ' + j['version'] + '\n')  else:   print('ERROR: Upload unsuccessful for file: ' + file)   print(str(response.status_code) + ' ' + response.reason )   if(response.json()):    j = response.json()    print('Error details: ' + j['errorCode'] + ' ' + j['errorMessage'])   else:    print('Dump of response text:')    print(response.text + '\n') 

A file download is a HTTP GET but requires saving the file to a location on disk. Again, Python has utilities to simplify the downloading and saving of Oracle Documents Cloud files.

import getpass import requests import logging docsurl='https://documents.us.oracle.com/documents/api/1.1' savePath = 'C:/TEMP/download' username = 'peter.flies@oracle.com' fileid = 'DCA4BBA0908AE2F497832BC2T0000DEFAULT00000000' resourcePath = 'files/{fileid}/data' resourcePath = resourcePath.replace('{fileid}', fileid) # Get user input to set the password. Set the REST client authorization header by directly passing in the username and password pw = getpass.getpass("Enter password:") # Requests has a reusable Session object. Init it with the Authorization header s = requests.Session() s.auth = (username, pw) with open(savePath, 'wb') as fhandle:  response = s.get(docsurl + '/' + resourcePath, stream=True)  if not response.ok:   print("Error!") #What do you want to do in case of error?  for filePiece in response.iter_content(1024):   if not filePiece:    break  fhandle.write(filePiece) #no JSON in response, but check it for status code, headers, etc. print(response.status_code)

 

For services that you may want to call frequently, a Python class can be created that wraps the Requests library. The commonly used service calls and associated parameters can have a method signature that sets the default parameters, but can also be overridden as needed. In the example class file below, the "DOCSClient" class has a constructor that initializes the Session. Once a handle to a DOCSClient is created, a method called "itemPersonalWorkspace" can be called with parameters to set the sort order, limit, and offset. This sample class has methods for only a few of the Documents Cloud Service REST calls, but the example can be applied to any DOCS REST API.

 

import requests import logging class DOCSClient:  def __init__(self, docsurl, username, password):   self.docsurl = docsurl   self.version = '1.1'   self.restBaseUrl = docsurl + '/api/' + self.version + '/'   self.s = requests.Session()   self.s.auth = (username, password)   self.appLinkRoles = ('viewer', 'downloader', 'contributor')   self.roles = ('viewer', 'downloader', 'contributor', 'manager')  # Sample Item Resource REST method  def itemPersonalWorkspace(self, orderby='name:asc', limit=50, offset=0):   resourcePath = 'folders/items' + '?orderby=' + orderby + '&limit=' + str(limit) + '&offset=' + str(offset)   return self.s.get(self.restBaseUrl + resourcePath)  # Sample Folder Resource REST methods  def folderQuery(self, folderid):   resourcePath = 'folders/{folderid}'   resourcePath = resourcePath.replace('{folderid}', folderid)   return self.s.get(self.restBaseUrl + resourcePath)  def folderCreate(self, folderid, name, description=''):   resourcePath = 'folders/{folderid}'   resourcePath = resourcePath.replace('{folderid}', folderid)   resourcePath = resourcePath + '?name=' + name + '&description=' + description   return self.s.post(self.restBaseUrl + resourcePath)  # Sample Upload Resource REST method  def fileUpload(self, parentID, filepath):   resourcePath = 'files/data'   files = {    'primaryFile': open(filepath, 'rb')   }   jsondata='{\"parentID\": \"' + parentID + '\" }'   data = {    'jsonInputParameters'  : jsondata   }   response = self.s.post(self.restBaseUrl + resourcePath, files=files, data=data)   return response

 

 

Lastly, using the newly created class can be done using an import statement. The class in this case was stored in a file called "oracledocsrequests.py". That file must be in the PYTHON_PATH to be found when the code is run, and once in the path the import statement is a single line to make the script aware of the DOCSClient class. Once a client object is created, with the URL, username, and password being passed in, any of the methods can be called in a single line. A folder creation example is shown below using one of the class methods.  Note that the parameters in the DOCSClient class define description parameter as being empty by default, but the example overrides the empty string with "created from Python" as the folder description.

import getpass from oracledocsrequests import DOCSClient docsurl='https://documents.us.oracle.com/documents' username='peter.flies@oracle.com' folderid = 'F26415F66B0BE6EE53314461T0000DEFAULT00000000' # Get user input to set the password. Set the REST client authorization header by directly passing in the username and password pw = getpass.getpass("Enter password:") client = DOCSClient(docsurl, username, pw) print('\n******* folderCreate *******') response = client.folderCreate(folderid, 'My python folder', 'created from Python') j = response.json() print(response.status_code) print('name=' + j['name'])

 

The Python Requests library slogan is "HTTP for Humans". The powerful Requests library makes using the Oracle Documents Cloud Service REST API simple enough to write your own utilities to interact with a DOCS workspace.

 

 

 

 

 

 

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha