Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/write with blob #882

Merged
merged 12 commits into from
Mar 30, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions TM1py/Services/ApplicationService.py
Original file line number Diff line number Diff line change
@@ -229,7 +229,7 @@ def update(self, application: Union[Application, DocumentApplication], private:
else:
url = "/api/v1/Contents('Applications')" + mid + "/" + contents
response = self._rest.POST(url, application.body, **kwargs)

return response

def update_or_create_document_from_file(self, path: str, name: str,
@@ -245,10 +245,10 @@ def update_or_create_document_from_file(self, path: str, name: str,

if self.exists(path=path, application_type=ApplicationTypes.DOCUMENT, name=name, private=private):
response = self.update_document_from_file(path_to_file=path_to_file, application_path=path,
application_name=name, private=private)
application_name=name, private=private)
else:
response = self.create_document_from_file(path_to_file=path_to_file, application_path=path,
application_name=name, private=private)
application_name=name, private=private)

return response

@@ -290,7 +290,7 @@ def create_document_from_file(self, path_to_file: str, application_path: str, ap
"""
with open(path_to_file, 'rb') as file:
application = DocumentApplication(path=application_path, name=application_name, content=file.read())
return self.create(application=application, private=private, **kwargs)
return self.create(application=application, private=private, **kwargs)

def update_document_from_file(self, path_to_file: str, application_path: str, application_name: str,
private: bool = False, **kwargs) -> Response:
281 changes: 220 additions & 61 deletions TM1py/Services/CellService.py

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions TM1py/Services/FileService.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
import json

from TM1py.Services import RestService
from TM1py.Services.ObjectService import ObjectService
from TM1py.Utils import format_url


class FileService(ObjectService):

def __init__(self, tm1_rest: RestService):
"""

:param tm1_rest:
"""
super().__init__(tm1_rest)
self._rest = tm1_rest

def get(self, file_name: str, **kwargs) -> bytes:
url = format_url(
"/api/v1/Contents('Blobs')/Contents('{name}')/Content",
name=file_name)

return self._rest.GET(url, **kwargs).content

def create(self, file_name: str, file_content: bytes, **kwargs):
url = "/api/v1/Contents('Blobs')/Contents"
body = {
"@odata.type": "#ibm.tm1.api.v1.Document",
"ID": file_name,
"Name": file_name
}
self._rest.POST(url, json.dumps(body), **kwargs)

url = format_url(
"/api/v1/Contents('Blobs')/Contents('{name}')/Content",
name=file_name)

return self._rest.PUT(url, file_content, headers=self.BINARY_HTTP_HEADER, **kwargs)

def update(self, file_name: str, file_content: bytes, **kwargs):
url = format_url(
"/api/v1/Contents('Blobs')/Contents('{name}')/Content",
name=file_name)

return self._rest.PUT(url, file_content, headers=self.BINARY_HTTP_HEADER, **kwargs)

def update_or_create(self, file_name: str, file_content: bytes, **kwargs):
if self.exists(file_name, **kwargs):
return self.update(file_name, file_content, **kwargs)

return self.create(file_name, file_content, **kwargs)

def exists(self, file_name: str, **kwargs):
url = format_url(
"/api/v1/Contents('Blobs')/Contents('{name}')",
name=file_name)

return self._exists(url, **kwargs)

def delete(self, file_name: str, **kwargs):
url = format_url(
"/api/v1/Contents('Blobs')/Contents('{name}')",
name=file_name)

return self._rest.DELETE(url, **kwargs)
2 changes: 2 additions & 0 deletions TM1py/Services/TM1Service.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
from TM1py.Services import HierarchyService, SecurityService, ApplicationService, SubsetService, ServerService, \
MonitoringService, ProcessService, PowerBiService, AnnotationService, ViewService, RestService, CellService, \
ChoreService, DimensionService, CubeService, ElementService, SandboxService, GitService
from TM1py.Services.FileService import FileService


class TM1Service:
@@ -31,6 +32,7 @@ def __init__(self, **kwargs):
self.views = ViewService(self._tm1_rest)
self.sandboxes = SandboxService(self._tm1_rest)
self.git = GitService(self._tm1_rest)
self.files = FileService(self._tm1_rest)

def logout(self, **kwargs):
self._tm1_rest.logout(**kwargs)
235 changes: 209 additions & 26 deletions Tests/CellService_test.py

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions Tests/FileService_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import configparser
import unittest
from pathlib import Path

from TM1py import TM1Service
from .Utils import skip_if_insufficient_version


class TestApplicationService(unittest.TestCase):
tm1: TM1Service

FILE_NAME1 = "TM1py_unittest_file1"
FILE_NAME2 = "TM1py_unittest_file2"

@classmethod
def setUp(cls) -> None:
cls.config = configparser.ConfigParser()
cls.config.read(Path(__file__).parent.joinpath('config.ini'))
cls.tm1 = TM1Service(**cls.config['tm1srv01'])

with open(Path(__file__).parent.joinpath('resources', 'file.csv'), "rb") as file:
cls.tm1.files.update_or_create(cls.FILE_NAME1, file.read())

if cls.tm1.files.exists(cls.FILE_NAME2):
cls.tm1.files.delete(cls.FILE_NAME2)

@skip_if_insufficient_version(version="11.4")
def test_create_get(self):
with open(Path(__file__).parent.joinpath('resources', 'file.csv'), "rb") as original_file:
self.tm1.files.create(self.FILE_NAME2, original_file.read())

created_file = self.tm1.files.get(self.FILE_NAME1)

with open(Path(__file__).parent.joinpath('resources', 'file.csv'), "rb") as original_file:
self.assertEqual(original_file.read(), created_file)

@skip_if_insufficient_version(version="11.4")
def test_update_get(self):
with open(Path(__file__).parent.joinpath('resources', 'file.csv'), "rb") as original_file:
self.tm1.files.update(self.FILE_NAME1, original_file.read())

created_file = self.tm1.files.get(self.FILE_NAME1)

with open(Path(__file__).parent.joinpath('resources', 'file.csv'), "rb") as original_file:
self.assertEqual(original_file.read(), created_file)

@skip_if_insufficient_version(version="11.4")
def test_delete_exists(self):
self.assertTrue(self.tm1.files.exists(self.FILE_NAME1))

self.tm1.files.delete(self.FILE_NAME1)

self.assertFalse(self.tm1.files.exists(self.FILE_NAME1))

def tearDown(self) -> None:
if self.tm1.files.exists(self.FILE_NAME1):
self.tm1.files.delete(self.FILE_NAME1)
if self.tm1.files.exists(self.FILE_NAME2):
self.tm1.files.delete(self.FILE_NAME2)
self.tm1.logout()
2 changes: 2 additions & 0 deletions Tests/resources/file.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
d1,d2,value
e6,e2,888