cubewise-code / tm1py

TM1py is a Python package that wraps the TM1 REST API in a simple to use library.
http://tm1py.readthedocs.io/en/latest/
MIT License
188 stars 107 forks source link

TM1py to TM1 server connection #661

Closed marmar1020 closed 2 years ago

marmar1020 commented 2 years ago

Hello All,

I am using TM1py to connect to a TM1 Server. I am unable to establish a connection, please see the code and error produced below.

Code: import TM1py from TM1py import TM1Service

A1="XX.XX.X.X" A2=XXXXX A3="CompanyAD/My Name" A4="Password" A5=True Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

Error upon execution:

TM1pyRestException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_33024/2693994863.py in 4 A4="PASSWORD" 5 A5=True ----> 6 Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\TM1Service.py in init(self, kwargs) 13 14 def init(self, kwargs): ---> 15 self._tm1_rest = RestService(**kwargs) 16 self.annotations = AnnotationService(self._tm1_rest) 17 self.cells = CellService(self._tm1_rest)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in init(self, **kwargs) 198 self._s.cookies.set("TM1SessionId", kwargs["session_id"]) 199 else: --> 200 self._start_session( 201 user=kwargs.get("user", None), 202 password=kwargs.get("password", None),

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _start_session(self, user, password, decode_b64, namespace, gateway, cam_passport, integrated_login, integrated_login_domain, integrated_login_service, integrated_login_host, integrated_login_delegate, impersonate) 365 additional_headers["TM1-Impersonate"] = impersonate 366 --> 367 response = self.GET(url=url, headers=additional_headers) 368 self._version = response.text 369 finally:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in wrapper(self, url, data, encoding, async_requests_mode, **kwargs) 78 79 # verify ---> 80 self.verify_response(response=response) 81 82 # response encoding

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in verify_response(response) 452 """ 453 if not response.ok: --> 454 raise TM1pyRestException(response.text, 455 status_code=response.status_code, 456 reason=response.reason,

TM1pyRestException: Text: '' - Status Code: 401 - Reason: 'Unauthorized' - Headers: {'Content-Type': 'text/plain', 'Content-Length': '0', 'Connection': 'keep-alive', 'Set-Cookie': 'TM1SessionId=sWgZpMRGJHNr3Vsr0p1S7w; Path=/api/; HttpOnly; Secure', 'WWW-Authenticate': 'CAMPassport http:xxxxxxxxxxxxxxxxxx, CAMNamespace'}

Version

rclapp commented 2 years ago

TM1 does not expect user names to be prefaced with the domain, you can remove the CompanyAD from the user name. Instead that needs to be passed as the namespace.

From: marmar1020 @.> Reply-To: cubewise-code/tm1py @.> Date: Thursday, January 6, 2022 at 12:09 PM To: cubewise-code/tm1py @.> Cc: Subscribed @.> Subject: [cubewise-code/tm1py] TM1py to TM1 server connection (Issue #661)

Hello All,

I am using TM1py to connect to a TM1 Server. I am unable to establish a connection, please see the code and error produced below.

Code: import TM1py from TM1py import TM1Service

A1="XX.XX.X.X" A2=XXXXX A3="CompanyAD/My Name" A4="Password" A5=True Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

Error upon execution:

TM1pyRestException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_33024/2693994863.py in 4 A4="PASSWORD" 5 A5=True ----> 6 Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\TM1Service.py in init(self, kwargs) 13 14 def init(self, kwargs): ---> 15 self._tm1_rest = RestService(**kwargs) 16 self.annotations = AnnotationService(self._tm1_rest) 17 self.cells = CellService(self._tm1_rest)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in init(self, **kwargs) 198 self._s.cookies.set("TM1SessionId", kwargs["session_id"]) 199 else: --> 200 self._start_session( 201 user=kwargs.get("user", None), 202 password=kwargs.get("password", None),

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _start_session(self, user, password, decode_b64, namespace, gateway, cam_passport, integrated_login, integrated_login_domain, integrated_login_service, integrated_login_host, integrated_login_delegate, impersonate) 365 additional_headers["TM1-Impersonate"] = impersonate 366 --> 367 response = self.GET(url=url, headers=additional_headers) 368 self._version = response.text 369 finally:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in wrapper(self, url, data, encoding, async_requests_mode, **kwargs) 78 79 # verify ---> 80 self.verify_response(response=response) 81 82 # response encoding

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in verify_response(response) 452 """ 453 if not response.ok: --> 454 raise TM1pyRestException(response.text, 455 status_code=response.status_code, 456 reason=response.reason,

TM1pyRestException: Text: '' - Status Code: 401 - Reason: 'Unauthorized' - Headers: {'Content-Type': 'text/plain', 'Content-Length': '0', 'Connection': 'keep-alive', 'Set-Cookie': 'TM1SessionId=sWgZpMRGJHNr3Vsr0p1S7w; Path=/api/; HttpOnly; Secure', 'WWW-Authenticate': 'CAMPassport http:xxxxxxxxxxxxxxxxxx, CAMNamespace'}

Version

— Reply to this email directly, view it on GitHubhttps://github.com/cubewise-code/tm1py/issues/661, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEK7GZT3U4N3KJP3AMAL2OLUUXZEBANCNFSM5LND3X7A. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you are subscribed to this thread.Message ID: @.***>

marmar1020 commented 2 years ago

Hi rclapp,

I updated by removing the CompanyAD from the user name, but no luck (see below). Question, where would the namespace parameter go? Upon researching, all I've come across are the 5 parameters needed to connect i.e. setting Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5).

import TM1py from TM1py import TM1Service

A1="XX.XX.X.X" A2=XXXXX A3="FirstName LastName" A4="Windows Password" A5=True Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

Error upon execution:

TM1pyRestException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_33024/398189723.py in 4 A4="MY PASSWORD" 5 A5=True ----> 6 Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\TM1Service.py in init(self, kwargs) 13 14 def init(self, kwargs): ---> 15 self._tm1_rest = RestService(**kwargs) 16 self.annotations = AnnotationService(self._tm1_rest) 17 self.cells = CellService(self._tm1_rest)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in init(self, **kwargs) 198 self._s.cookies.set("TM1SessionId", kwargs["session_id"]) 199 else: --> 200 self._start_session( 201 user=kwargs.get("user", None), 202 password=kwargs.get("password", None),

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _start_session(self, user, password, decode_b64, namespace, gateway, cam_passport, integrated_login, integrated_login_domain, integrated_login_service, integrated_login_host, integrated_login_delegate, impersonate) 365 additional_headers["TM1-Impersonate"] = impersonate 366 --> 367 response = self.GET(url=url, headers=additional_headers) 368 self._version = response.text 369 finally:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in wrapper(self, url, data, encoding, async_requests_mode, **kwargs) 78 79 # verify ---> 80 self.verify_response(response=response) 81 82 # response encoding

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in verify_response(response) 452 """ 453 if not response.ok: --> 454 raise TM1pyRestException(response.text, 455 status_code=response.status_code, 456 reason=response.reason,

TM1pyRestException: Text: '' - Status Code: 401 - Reason: 'Unauthorized' - Headers: {'Content-Type': 'text/plain', 'Content-Length': '0', 'Connection': 'keep-alive', 'Set-Cookie': 'TM1SessionId=Ox9lnp0UitKtiONpwwix0A; Path=/api/; HttpOnly; Secure', 'WWW-Authenticate': 'CAMPassport company url xxxxxxxxxxxxxxxxxxxxxxxx, CAMNamespace'}

rclapp commented 2 years ago

There is another named parameter in the TM1 service

TM1Service(address=my_address, port=my_port, user=my_user, password=my_password, namespace=my_namespace, ssl=my_ssl)

From: marmar1020 @.> Reply-To: cubewise-code/tm1py @.> Date: Thursday, January 6, 2022 at 12:42 PM To: cubewise-code/tm1py @.> Cc: "Clapp, Ryan" @.>, Comment @.***> Subject: Re: [cubewise-code/tm1py] TM1py to TM1 server connection (Issue #661)

Hi rclapp,

I updated by removing the CompanyAD from the user name, but no luck (see below). Question, where would the namespace parameter go? Upon researching, all I've come across are the 5 parameters needed to connect i.e. setting Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5).

import TM1py from TM1py import TM1Service

A1="XX.XX.X.X" A2=XXXXX A3="FirstName LastName" A4="Windows Password" A5=True Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

Error upon execution:

TM1pyRestException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_33024/398189723.py in 4 A4="MY PASSWORD" 5 A5=True ----> 6 Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, ssl=A5)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\TM1Service.py in init(self, kwargs) 13 14 def init(self, kwargs): ---> 15 self._tm1_rest = RestService(**kwargs) 16 self.annotations = AnnotationService(self._tm1_rest) 17 self.cells = CellService(self._tm1_rest)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in init(self, **kwargs) 198 self._s.cookies.set("TM1SessionId", kwargs["session_id"]) 199 else: --> 200 self._start_session( 201 user=kwargs.get("user", None), 202 password=kwargs.get("password", None),

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _start_session(self, user, password, decode_b64, namespace, gateway, cam_passport, integrated_login, integrated_login_domain, integrated_login_service, integrated_login_host, integrated_login_delegate, impersonate) 365 additional_headers["TM1-Impersonate"] = impersonate 366 --> 367 response = self.GET(url=url, headers=additional_headers) 368 self._version = response.text 369 finally:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in wrapper(self, url, data, encoding, async_requests_mode, **kwargs) 78 79 # verify ---> 80 self.verify_response(response=response) 81 82 # response encoding

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in verify_response(response) 452 """ 453 if not response.ok: --> 454 raise TM1pyRestException(response.text, 455 status_code=response.status_code, 456 reason=response.reason,

TM1pyRestException: Text: '' - Status Code: 401 - Reason: 'Unauthorized' - Headers: {'Content-Type': 'text/plain', 'Content-Length': '0', 'Connection': 'keep-alive', 'Set-Cookie': 'TM1SessionId=Ox9lnp0UitKtiONpwwix0A; Path=/api/; HttpOnly; Secure', 'WWW-Authenticate': 'CAMPassport company url xxxxxxxxxxxxxxxxxxxxxxxx, CAMNamespace'}

— Reply to this email directly, view it on GitHubhttps://github.com/cubewise-code/tm1py/issues/661#issuecomment-1006919952, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEK7GZRF3KQ5PH5XGVI4OY3UUX467ANCNFSM5LND3X7A. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you commented.Message ID: @.***>

marmar1020 commented 2 years ago

Thanks for the info.

Updated my connection as shows but still no luck.

import TM1py from TM1py import TM1Service

A1="XX.XX.X.X" A2=XXXXX A3="FirstName LastName" A4="Password" A5="CompanyAD/FirstName LastName" A6=True Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, namepace=A5, ssl=A6)

Results

TM1pyRestException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_33024/3129807742.py in 5 A5="CompanyAD/FirstName LastName" 6 A6=True ----> 7 Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, namepace=A5, ssl=A6)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\TM1Service.py in init(self, kwargs) 13 14 def init(self, kwargs): ---> 15 self._tm1_rest = RestService(**kwargs) 16 self.annotations = AnnotationService(self._tm1_rest) 17 self.cells = CellService(self._tm1_rest)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in init(self, **kwargs) 198 self._s.cookies.set("TM1SessionId", kwargs["session_id"]) 199 else: --> 200 self._start_session( 201 user=kwargs.get("user", None), 202 password=kwargs.get("password", None),

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _start_session(self, user, password, decode_b64, namespace, gateway, cam_passport, integrated_login, integrated_login_domain, integrated_login_service, integrated_login_host, integrated_login_delegate, impersonate) 365 additional_headers["TM1-Impersonate"] = impersonate 366 --> 367 response = self.GET(url=url, headers=additional_headers) 368 self._version = response.text 369 finally:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in wrapper(self, url, data, encoding, async_requests_mode, **kwargs) 78 79 # verify ---> 80 self.verify_response(response=response) 81 82 # response encoding

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in verify_response(response) 452 """ 453 if not response.ok: --> 454 raise TM1pyRestException(response.text, 455 status_code=response.status_code, 456 reason=response.reason,

TM1pyRestException: Text: '' - Status Code: 401 - Reason: 'Unauthorized' - Headers: {'Content-Type': 'text/plain', 'Content-Length': '0', 'Connection': 'keep-alive', 'Set-Cookie': 'TM1SessionId=O3RsiV0NP1WLA7qq0X1nYw; Path=/api/; HttpOnly; Secure', 'WWW-Authenticate': 'CAMPassport http: company url xxxxxxxxxxxxxxxxx, CAMNamespace'}

rclapp commented 2 years ago

Your values are not correct. It should be the same way you login to any other TM1 Interface

Namespace should come from Cognos, so something like “Cognos” or “MyCompanyDomainName”.

User should be just that your user name, look at the clients dimension (it should be the display value not the CAM ID)

From: marmar1020 @.> Reply-To: cubewise-code/tm1py @.> Date: Thursday, January 6, 2022 at 1:48 PM To: cubewise-code/tm1py @.> Cc: "Clapp, Ryan" @.>, Comment @.***> Subject: Re: [cubewise-code/tm1py] TM1py to TM1 server connection (Issue #661)

Thanks for the info.

Updated my connection as shows but still no luck.

import TM1py from TM1py import TM1Service

A1="XX.XX.X.X" A2=XXXXX A3="FirstName LastName" A4="Password" A5="CompanyAD/FirstName LastName" A6=True Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, namepace=A5, ssl=A6)

Results

TM1pyRestException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_33024/3129807742.py in 5 A5="CompanyAD/FirstName LastName" 6 A6=True ----> 7 Tm1= TM1Service(address=A1, port=A2, user=A3, password=A4, namepace=A5, ssl=A6)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\TM1Service.py in init(self, kwargs) 13 14 def init(self, kwargs): ---> 15 self._tm1_rest = RestService(**kwargs) 16 self.annotations = AnnotationService(self._tm1_rest) 17 self.cells = CellService(self._tm1_rest)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in init(self, **kwargs) 198 self._s.cookies.set("TM1SessionId", kwargs["session_id"]) 199 else: --> 200 self._start_session( 201 user=kwargs.get("user", None), 202 password=kwargs.get("password", None),

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _start_session(self, user, password, decode_b64, namespace, gateway, cam_passport, integrated_login, integrated_login_domain, integrated_login_service, integrated_login_host, integrated_login_delegate, impersonate) 365 additional_headers["TM1-Impersonate"] = impersonate 366 --> 367 response = self.GET(url=url, headers=additional_headers) 368 self._version = response.text 369 finally:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in wrapper(self, url, data, encoding, async_requests_mode, **kwargs) 78 79 # verify ---> 80 self.verify_response(response=response) 81 82 # response encoding

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in verify_response(response) 452 """ 453 if not response.ok: --> 454 raise TM1pyRestException(response.text, 455 status_code=response.status_code, 456 reason=response.reason,

TM1pyRestException: Text: '' - Status Code: 401 - Reason: 'Unauthorized' - Headers: {'Content-Type': 'text/plain', 'Content-Length': '0', 'Connection': 'keep-alive', 'Set-Cookie': 'TM1SessionId=O3RsiV0NP1WLA7qq0X1nYw; Path=/api/; HttpOnly; Secure', 'WWW-Authenticate': 'CAMPassport http: company url xxxxxxxxxxxxxxxxx, CAMNamespace'}

— Reply to this email directly, view it on GitHubhttps://github.com/cubewise-code/tm1py/issues/661#issuecomment-1006958410, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEK7GZU7CG3C7QUUREMUKW3UUYEXXANCNFSM5LND3X7A. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you commented.Message ID: @.***>

marmar1020 commented 2 years ago

Rclapp,

Ok, updated to the correct connection, CAM with SSO (IntegratedSecurityMode 5).

Ran my credentials via the test script and got:

TM1 User (leave empty if SSO): Password (leave empty if SSO): ········ CAM Namespace (leave empty if no CAM Security): XXX Address (leave empty if localhost): XX.XX.X.X ClientCAMURI (leave empty if no SSO): http://xxxx.xxxx.net:80/xxxx/xx/xx/disp HTTP Port (Default 5000): XXXX SSL (Default T or F): T

**ERROR: Failed to authenticate through CAM. HTTP response does not contain 'cam_passport' cookie**

Error upon executing code: RuntimeError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_30536/298617961.py in ----> 1 with TM1Service(address="XX.XX.X.X", port=XXXX, ssl=True, namespace="XXX", gateway="http://xxxx.xxxx.net:80/xxxx/xx/xx/disp") as tm1: 2 print(tm1.server.get_product_version())

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\TM1Service.py in init(self, kwargs) 13 14 def init(self, kwargs): ---> 15 self._tm1_rest = RestService(**kwargs) 16 self.annotations = AnnotationService(self._tm1_rest) 17 self.cells = CellService(self._tm1_rest)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in init(self, **kwargs) 198 self._s.cookies.set("TM1SessionId", kwargs["session_id"]) 199 else: --> 200 self._start_session( 201 user=kwargs.get("user", None), 202 password=kwargs.get("password", None),

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _start_session(self, user, password, decode_b64, namespace, gateway, cam_passport, integrated_login, integrated_login_domain, integrated_login_service, integrated_login_host, integrated_login_delegate, impersonate) 350 # Authorization [Basic, CAM] through Headers 351 else: --> 352 token = self._build_authorization_token( 353 user, 354 self.b64_decode_password(password) if decode_b64 else password,

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _build_authorization_token(user, password, namespace, gateway, cam_passport, verify) 465 return 'CAMPassport ' + cam_passport 466 elif namespace: --> 467 return RestService._build_authorization_token_cam(user, password, namespace, gateway, verify) 468 else: 469 return RestService._build_authorization_token_basic(user, password)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\TM1py\Services\RestService.py in _build_authorization_token_cam(user, password, namespace, gateway, verify) 486 + str(response.status_code)) 487 elif 'cam_passport' not in response.cookies: --> 488 raise RuntimeError( 489 "Failed to authenticate through CAM. HTTP response does not contain 'cam_passport' cookie") 490 else:

RuntimeError: Failed to authenticate through CAM. HTTP response does not contain 'cam_passport' cookie

Any thoughts?

marmar1020 commented 2 years ago

First off, thank you for your support rclapp.

Just wanted to update. I was able to successfully connect. What solved my issue, "RuntimeError: Failed to authenticate through CAM. HTTP response does not contain 'cam_passport' cookie", was getting the correct namespace from the server admin.

Connecting via CAM with SSO (IntegratedSecurityMode 5) was successful.