Source code for sasctl._services.files

#!/usr/bin/env python
# encoding: utf-8
#
# Copyright © 2019, SAS Institute Inc., Cary, NC, USA.  All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

import os
from pathlib import Path

from sasctl.utils.cli import sasctl_command

from .folders import Folders
from .service import Service


[docs] class Files(Service): """The Files API provides persistence and retrieval of files, such as documents, attachments, and reports. The file can be associated with the URI of another identifiable object (for example, a parentUri). Every file must have an assigned content type and name. Files can be retrieved individually by using the file's identifier or as a list of files by using a parentUri. Each file has its content stream associated with it. After creation, the metadata that is associated with the file or the actual content can be updated. A single file can be deleted by using a specific ID. Multiple files can be deleted by specifying a parentUri. A file can be uploaded via raw request or multipart form request. """ _SERVICE_ROOT = "/files" list_files, get_file, update_file, delete_file = Service._crud_funcs( "/files", "file" )
[docs] @classmethod @sasctl_command("files", "create") def create_file(cls, file, folder=None, filename=None, expiration=None): """Create a new file on the server by uploading a local file. Parameters ---------- file : str, pathlib.Path, or typing.BinaryIO Path to the file to upload or a file-like object. folder : str or dict, optional Name or folder information as returned by :meth:`.get_folder`. filename : str, optional Name to assign to the uploaded file. Defaults to the filename if `file` is a path, otherwise required. expiration : datetime.datetime, optional A timestamp that indicates when to expire the file. Defaults to no expiration. Returns ------- RestObj A dictionary containing the file attributes. """ if isinstance(file, (str, Path)): filename = filename or Path(file).name with open(file, "rb") as f: file = f.read() else: if filename is None: raise ValueError( "`filename` must be specified if `file` is not a path." ) file = file.read() params = {} if folder is not None: _folder = Folders().get_folder(folder) if _folder is None: raise ValueError("Folder '%s' could not be found." % folder) params["parentFolderUri"] = cls.get_link(_folder, "self")["href"] if expiration is not None: pass # TODO: add 'expirationTimeStamp' to params. Need to determine correct format return cls.post("/files#multipartUpload", files={filename: file}, params=params)
[docs] @classmethod @sasctl_command("files", "content") def get_file_content(cls, file): """Download the contents of a file. Parameters ---------- file : str or dict, optional Name or file information as returned by :func:`get_file`. Returns ------- str content """ file = cls.get_file(file) r = cls.request_link(file, "content", format="response") content_type = r.headers.get("Content-Type", "") if "text/plain" in content_type: return r.text if "application/json" in content_type: return r.json() if "application/octet-stream" in content_type: return r.content return r.text