Python SDK how to set a proxy

Hi All,

On a Windows host, when attempting to authenticate to ISC with the sail sdk init python generated boilerplate sdk.py script, I get a timeout because the proxy is not set.

I am looking for an example showing how to set the proxy.

I can see that the Configuration object has a property for proxy. I have set it like so after creating the configuration object:

configuration.proxy =  "http://username:[email protected]:9443\"

I still get the same error after updating the proxy property.

The boilerplate script is as follows, the only thing I have added is the above line:

import sailpoint
import sailpoint.v3
import sailpoint.beta
from sailpoint.configuration import Configuration
from sailpoint.paginator import Paginator
from sailpoint.v3.models.search import Search
from pprint import pprint

configuration = Configuration()
configuration.proxy =  "http://username:[email protected]:9443\"

# Enter a context with an instance of the API client
with sailpoint.v3.ApiClient(configuration) as api_client:
    # Create an instance of the API class
    api_instance = sailpoint.v3.TransformsApi(api_client)

    # List transforms
    try:
        # List transforms
        api_response = api_instance.list_transforms()
        print("The response of TransformsApi->list_transforms:\n")
        for transform in api_response:
            pprint(transform.name)
    except Exception as e:
        print("Exception when calling TransformsApi->list_transforms: %s\n" % e)

    # List Access Profiles
    api_instance = sailpoint.v3.AccessProfilesApi(api_client)

    try:
        api_response = api_instance.list_access_profiles()
        print("The response of AccessProfilesApi->list_access_profiles:\n")
        for access_profile in api_response:
            pprint(access_profile.name)
    except Exception as e:
        print(
            "Exception when calling AccessProfilesApi->list_access_profiles: %s\n" % e
        )

    # Use the paginator with search

    search = Search()
    search.indices = ['identities']
    search.query = { 'query': '*' }
    search.sort = ['-name']

    identities = Paginator.paginate_search(sailpoint.v3.SearchApi(api_client),search, 250, 1000)
    for identity in identities:
        print(identity['name'])



    # Use the paginator to paginate 1000 accounts 100 at a time
    accounts = Paginator.paginate(sailpoint.v3.AccountsApi(api_client).list_accounts, 1000, limit=100)
    print(len(accounts))
    for account in accounts:
        print(account.name)


with sailpoint.beta.ApiClient(configuration) as api_client:

    workgroups = sailpoint.beta.GovernanceGroupsApi(api_client).list_workgroups()
    for workgroup in workgroups:
        print(workgroup.name)

I thought also that there may be an environment variable that I could set but cannot find any references. Any help would be appreciated.

Thanks,
SC

You could try setting the environment variables for username and password. Then update the proxy string to be an f string and pass in the environment variables. Proxy setting are going to be unique to your endearment. The @proxy.acme.com:9443 is an example of how you would configure the proxy information. If you do not have a proxy then I would just comment this out and try running it again. You will also need to define the proxy headers. Hope this helps.

Fstring Example

configuration.proxy =  f"http://{username}:{password}@proxy.acme.com:9443"

Proxy config using urllib3

configuration.proxy = "https://proxy.acme.com:9443/"
configuration.proxy_headers = make_headers(proxy_basic_auth=f"{username}:{mypassword}")
1 Like

Thank you @mpotti for the good examples. Unfortunately with the configuration suggested the connection still does not seem to be going to the proxy.

What I find strange is that my normal Python script using the requests module works fine. It does not need any configuration around the proxy. I assume it is getting the proxy information from the system but I am not sure how that works. This is the working script without the SailPoint provided Python SDK:

# Credit for class and ssl: https://stackoverflow.com/questions/42982143/python-requests-how-to-use-system-ca-certificates-debian-ubuntu
# Credit for SailPoint API part: https://developer.sailpoint.com/discuss/t/python-authentication-example-with-jwt/16070/5
 
import ssl
import requests
from requests.adapters import HTTPAdapter
import os


class LocalSSLContext(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = ssl.create_default_context()
        context.load_default_certs()
        kwargs['ssl_context'] = context
        return super(LocalSSLContext, self).init_poolmanager(*args, **kwargs)

# Set the necessary variables
tenant_id = os.environ.get("tenant_id")
client_id = os.environ.get("client_id")
client_secret = os.environ.get("client_secret")
base_url = f"https://{tenant_id}.api.identitynow.com"

# Get an access token
auth_url = f"{base_url}/oauth/token"
auth_data = {
    "grant_type": "client_credentials",
    "client_id": client_id,
    "client_secret": client_secret,
}

session = requests.Session()
sslContext = LocalSSLContext()
session.mount(base_url, sslContext)
response = session.post(url=auth_url, data=auth_data)
print(session.proxies)
print(response.status_code)

#Extract the access token from the response
access_token = response.json()["access_token"]

# API Call to get Sources
url = f"{base_url}/v3/sources"
headers = {
    'Authorization': f'Bearer {access_token}',
    'cache-control': 'no-cache',
	'Content-Type': 'application/json'
}

#response = requests.request("GET",url, headers=headers, verify=False)
response = session.get(url=url, headers=headers)

if response.status_code == 200:
    data = response.json()
  
else:
    print(f"Request for sources failed with status code: {response.status_code}")

session.close

@colin_mckibben @tyler_mairose any pointers on setting up a proxy for the python sdk?

@mpotti @smc-sp,

We will need to make some changes to the python SDK to get it to work with proxies. The base calls will work today but I need to use the proxy configuration provided in the get token request as well.

I will respond back here once I make the changes, you can also track it here:

1 Like