Skip to main content

Using a service account to call IMS APIs

In order to integrate IMS with your backend server, you may need to call IMS APIs. You can use a service account to authenticate with APIs.

danger

Do not use a service account to call IMS APIs from within your Game Client, this will expose you to potential attacks from malicious players. You should not call IMS APIs from your Game Client, with the exception of specific Matchmaker and Session Manager APIs that are designed for Game Clients and use player auth.

import os
from dotenv import load_dotenv
from rauth import OAuth2Service, OAuth2Session
from typing import Dict
import time

# This class is used to authenticate with IMS APIs and handle token refreshing
class IMSClient:
_oauth: OAuth2Service
_oauth_params: Dict[str, str]
_tokenExpiry = 0
_token = ""
_session: OAuth2Session

def __init__(self, client_id: str, client_secret: str, refresh_token: str):
self._oauth = OAuth2Service(
client_id=client_id,
client_secret=client_secret,
name='ims',
authorize_url='https://platform-auth.improbable.io/auth/v1/authorize',
access_token_url='https://platform-auth.improbable.io/auth/v1/token'
)

self._oauth_params = {
"grant_type": "refresh_token",
"refresh_token": refresh_token
}


def _refresh_session(self):
print("refeshing token")
raw_access_token = self._oauth.get_raw_access_token(data=self._oauth_params).json()
self._token = raw_access_token["access_token"]
print(raw_access_token["expires_in"])
self._tokenExpiry = time.time() + raw_access_token["expires_in"] - 60 # 60 seconds padding to ensure token doesn't expire between session creation and request
self._session = self._oauth.get_session(token=self._token)

def _token_valid(self):
return self._tokenExpiry > time.time()


def session(self) -> OAuth2Session:
if not self._token_valid():
self._refresh_session()

return self._session


load_dotenv()


# Create client

ims = IMSClient(
client_id=os.environ["OAUTH_CLIENT_ID"],
client_secret=os.environ["OAUTH_CLIENT_SECRET"],
refresh_token=os.environ["OAUTH_REFRESH_TOKEN"]
)

# Call API to view allocations (hint: replace :project-id with your project id)
# ensure that ims.session() is called for each api call otherwise you may run into issues where the token isn't refreshed
response = ims.session().get("https://production.orchestration.improbable.io/api/v0/projects/:project-id/allocations")
print(response.json())