Skip to content

Commit

Permalink
Add proxies arg to TM1Service
Browse files Browse the repository at this point in the history
  • Loading branch information
MariusWirtz committed May 2, 2023
1 parent 0dfb8ee commit ea9e616
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 7 deletions.
35 changes: 28 additions & 7 deletions TM1py/Services/RestService.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# -*- coding: utf-8 -*-
import functools
import json
import re
import socket
import time
import warnings
from base64 import b64encode, b64decode
from http.client import HTTPResponse
from io import BytesIO
from json import JSONDecodeError
from typing import Union, Dict, Tuple, Optional

import requests
import urllib3
from requests import Timeout, Response, ConnectionError
from requests import Timeout, Response, ConnectionError, Session
from requests.adapters import HTTPAdapter

# SSO not supported for Linux
Expand Down Expand Up @@ -42,6 +44,7 @@ def wrapper(self, url: str, data: str = '', encoding='utf-8', async_requests_mod
url=url,
data=data,
encoding=encoding)

# execute request
try:
# determine async_requests_mode
Expand Down Expand Up @@ -149,16 +152,16 @@ def __init__(self, **kwargs):
:param cam_passport: String - the cam passport
:param session_id: String - TM1SessionId e.g. q7O6e1w49AixeuLVxJ1GZg
:param session_context: String - Name of the Application. Controls "Context" column in Arc / TM1top.
If None, use default: TM1py
If None, use default: TM1py
:param verify: path to .cer file or 'True' / True / 'False' / False (if no ssl verification is required)
:param logging: boolean - switch on/off verbose http logging into sys.stdout
:param timeout: Float - Number of seconds that the client will wait to receive the first byte.
:param cancel_at_timeout: Abort operation in TM1 when timeout is reached
:param async_requests_mode: changes internal REST execution mode to avoid 60s timeout on IBM cloud
:param tcp_keepalive: maintain the TCP connection all the time, users should choose either async_requests_mode or tcp_keepalive to run a long-run request
If both are True, use async_requests_mode by default
:param connection_pool_size - In a multithreaded environment, you should set this value to a
higher number, such as the number of threads
If both are True, use async_requests_mode by default
:param connection_pool_size - In a multi threaded environment, you should set this value to a
higher number, such as the number of threads
:param integrated_login: True for IntegratedSecurityMode3
:param integrated_login_domain: NT Domain name.
Default: '.' for local account.
Expand All @@ -170,6 +173,8 @@ def __init__(self, **kwargs):
Default: False
:param impersonate: Name of user to impersonate
:param re_connect_on_session_timeout: attempt to reconnect once if session is timed out
:param proxies: pass a dictionary with proxies e.g.
{'http': 'http://proxy.example.com:8080', 'https': 'http://secureproxy.example.com:8090'}
"""
# store kwargs for future use e.g. re_connect on 401 session timeout
self._kwargs = kwargs
Expand All @@ -182,9 +187,23 @@ def __init__(self, **kwargs):
self._cancel_at_timeout = kwargs.get('cancel_at_timeout', False)
self._async_requests_mode = self.translate_to_boolean(kwargs.get('async_requests_mode', False))
# Set tcp_keepalive to False explicitly to turn it off when async_requests_mode is enabled
self._tcp_keepalive = self.translate_to_boolean(kwargs.get('tcp_keepalive', False)) if self._async_requests_mode is not True else False
self._tcp_keepalive = self.translate_to_boolean(
kwargs.get('tcp_keepalive', False)) \
if self._async_requests_mode is not True \
else False
self._connection_pool_size = kwargs.get('connection_pool_size', None)
self._re_connect_on_session_timeout = kwargs.get('re_connect_on_session_timeout', True)

self._proxies = kwargs.get('proxies', None)
# handle invalid types and potential string argument
if not isinstance(self._proxies, (dict, str, type(None))):
raise ValueError("Argument of 'proxies' must be None, dictionary or JSON string")
elif isinstance(self._proxies, str):
try:
self._proxies = json.loads(self._proxies)
except JSONDecodeError:
raise ValueError("Invalid JSON passed for argument 'proxies': %s", self._proxies)

# populated on the fly
if kwargs.get('user'):
self._is_admin = True if case_and_space_insensitive_equals(kwargs.get('user'), 'ADMIN') else None
Expand Down Expand Up @@ -221,7 +240,9 @@ def __init__(self, **kwargs):

self.disable_http_warnings()

self._s = requests.session()
self._s = Session()
if self._proxies:
self._s.proxies = self._proxies

self.connect()

Expand Down
37 changes: 37 additions & 0 deletions TM1py/Services/TM1Service.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,43 @@ class TM1Service:
"""

def __init__(self, **kwargs):
""" Initiate the TM1Service
:param address: String - address of the TM1 instance
:param port: Int - HTTPPortNumber as specified in the tm1s.cfg
:param base_url - base url e.g. https://localhost:12354/api/v1
:param user: String - name of the user
:param password String - password of the user
:param decode_b64 - whether password argument is b64 encoded
:param namespace String - optional CAM namespace
:param ssl: boolean - as specified in the tm1s.cfg
:param cam_passport: String - the cam passport
:param session_id: String - TM1SessionId e.g. q7O6e1w49AixeuLVxJ1GZg
:param session_context: String - Name of the Application. Controls "Context" column in Arc / TM1top.
If None, use default: TM1py
:param verify: path to .cer file or 'True' / True / 'False' / False (if no ssl verification is required)
:param logging: boolean - switch on/off verbose http logging into sys.stdout
:param timeout: Float - Number of seconds that the client will wait to receive the first byte.
:param cancel_at_timeout: Abort operation in TM1 when timeout is reached
:param async_requests_mode: changes internal REST execution mode to avoid 60s timeout on IBM cloud
:param tcp_keepalive: maintain the TCP connection all the time, users should choose either async_requests_mode or tcp_keepalive to run a long-run request
If both are True, use async_requests_mode by default
:param connection_pool_size - In a multi threaded environment, you should set this value to a
higher number, such as the number of threads
:param integrated_login: True for IntegratedSecurityMode3
:param integrated_login_domain: NT Domain name.
Default: '.' for local account.
:param integrated_login_service: Kerberos Service type for remote Service Principal Name.
Default: 'HTTP'
:param integrated_login_host: Host name for Service Principal Name.
Default: Extracted from request URI
:param integrated_login_delegate: Indicates that the user's credentials are to be delegated to the server.
Default: False
:param impersonate: Name of user to impersonate
:param re_connect_on_session_timeout: attempt to reconnect once if session is timed out
:param proxies: pass a dictionary with proxies e.g.
{'http': 'http://proxy.example.com:8080', 'https': 'http://secureproxy.example.com:8090'}
"""
self._tm1_rest = RestService(**kwargs)
self.annotations = AnnotationService(self._tm1_rest)
self.cells = CellService(self._tm1_rest)
Expand Down

0 comments on commit ea9e616

Please sign in to comment.