> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lumos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List Inactive AppStore Approver or Admins

> Use this recipe to print out a list of users who are inactive but are approvers or admins in AppStore apps.

<RequestExample>
  ```python Python theme={null}
  """
  This script prints out a list of Lumos users who are not active and who are approver or admins
  on AppStore applications.

  This script does not consider two scenarios:
      - When an inactive user is an approver in a permission
      - When an inactive user is the only active user in an approver or admin group.

  The output will look like this, for each user that is not active:

      ==============================================
      user (<user_id>):
          email: <user email>
          first: <user first name>
          last: <user last name>

          Approver on these AppStore Apps:
              - <app name> (<AppStore app URL>)
              ...

          Admin on these AppStore Apps:
              - <app name> (<AppStore app URL>)
              ...
  """

  import typing
  from dataclasses import dataclass

  import requests

  headers = {
      "accept": "application/json",
      "authorization": "Bearer <API TOKEN>",
  }


  # Initialize types and constants
  @dataclass
  class UserInfo:
      email: str
      first_name: str
      last_name: str


  @dataclass
  class AppInfo:
      id: str
      name: str


  @dataclass
  class NonActiveUserEntry:
      user: UserInfo
      approver_apps: typing.List[AppInfo]
      admin_apps: typing.List[AppInfo]


  UserID = str

  results: typing.Dict[UserID, NonActiveUserEntry] = {}

  GET_APPSTORE_APPS_URL = "https://api.lumos.com/appstore/apps"
  GET_APPSTORE_APPS_SETTINGS_URL = "https://api.lumos.com/appstore/apps/{app_id}/settings"
  APP_URL = "https://app.lumosidentity.com/apps/{app_id}?tab=users"


  # Define a helper function for recordkeeping.
  def init_nonactive_user_entry(user: typing.Dict):
      results[user["id"]] = NonActiveUserEntry(
          user=UserInfo(
              email=user["email"],
              first_name=user["given_name"],
              last_name=user["family_name"],
          ),
          approver_apps=[],
          admin_apps=[],
      )


  # Iterate through all AppStore Apps.
  response = requests.get(GET_APPSTORE_APPS_URL, headers=headers)
  response_page = response.json()

  while len(response_page["items"]):
      for app in response_page["items"]:

          app_id = app["id"]
          app_name = app["user_friendly_label"]

          # Fetch AppStore app permissions, and extract out approvers or admins who are inactive.
          response = requests.get(
              GET_APPSTORE_APPS_SETTINGS_URL.format(app_id=app_id),
              headers=headers,
          )
          response_json = response.json()
          approver_users = response_json["request_flow"]["approvers"]["users"]
          approver_stage_2_users = response_json["request_flow"]["approvers_stage_2"]["users"]

          for user in approver_users + approver_stage_2_users:
              if user["status"] == "ACTIVE":
                  continue

              if user["id"] not in results:
                  init_nonactive_user_entry(user)
              results[user["id"]].approver_apps.append(AppInfo(id=app_id, name=app_name))

          admin_users = response_json["request_flow"]["admins"]["users"]
          for user in admin_users:
              if user["status"] == "ACTIVE":
                  continue

              if user["id"] not in results:
                  init_nonactive_user_entry(user)
              results[user["id"]].admin_apps.append(AppInfo(id=app_id, name=app_name))

      response = requests.get(
          GET_APPSTORE_APPS_URL,
          headers=headers,
          params={"size": 50, "page": response_page["page"] + 1},
      )
      response_page = response.json()

  # Iterate, and print the dictionary.
  for user_id in results:
      user = results[user_id].user
      approver_apps = results[user_id].approver_apps
      admin_apps = results[user_id].admin_apps

      print("==============================================")
      print(f"user (id: {user_id}): ")
      print(f"\temail: {user.email}")
      print(f"\tfirst: {user.first_name}")
      print(f"\tlast: {user.last_name}")
      print("")

      print("\t\t Approver on these AppStore Apps:")
      for approver_app in approver_apps:
          app_url = APP_URL.format(app_id=approver_app.id)
          print(f"\t\t\t- {approver_app.name} ({app_url})")

      print("\t\t Admin on these AppStore Apps:")
      for admin_app in admin_apps:
          app_url = APP_URL.format(app_id=admin_app.id)
          print(f"\t\t\t- {admin_app.name} ({app_url})")

  ```
</RequestExample>

<Steps>
  <Step title="Initialize types, variables, and helpers">
    This script iterates through all AppStore apps, fetches approvers and admins, and keeps a record of inactive users together with the application that they are an approver or admin of.

    To do that, create helper types to parse the information. Then define a helper function that populates the dictionary used to track inactive users.

    Paste your own API token in line 33.

    This script uses Python3 and uses the "requests" Python library, which you will need to install with `pip install requests` if you don't already have it installed.
  </Step>

  <Step title="Iterate through AppStore apps and count">
    Use the get AppStore apps endpoint to iterate through each of the AppStore apps.

    For each of those apps, call the GET AppStore app settings endpoint to get further information about the AppStore settings for that app.

    Then, update the dictionary for record keeping.
  </Step>

  <Step title="Print results">
    Iterate through each of the inactive users you found, and print the AppStore apps they are approvers or admins for.
  </Step>
</Steps>
