Artificial Intelligence Corporate Risk
  • Welcome
  • Getting Started
    • Inviting Users
    • Adding New Large Language Models
      • Azure OpenAI Service
      • OpenAI
      • Mistral
      • Google AI
      • LLaMA AI
      • AWS Bedrock
  • Chat
    • Initiating a Chat
    • Viewing Chat History
  • Dashboards
    • Creating Dashboards
    • Dashboard Elements
      • Top N
      • Charts and Graphs
      • Totals
      • Maps
  • Monitoring
    • Adding a User to the Monitor Role
    • Setting up alerts and issues
    • Editing Issues
  • Compliance
    • Adding a User to the Compliance Role
    • Creating a Search
    • Consuming the Results
  • Admin
    • AI Agents
      • Adding a New Agent
        • General Settings
        • Agent Engine Properties
          • Azure OpenAI
          • OpenAI
          • Mistral
          • Google AI
          • LLaMA AI
          • AWS Bedrock
        • Advanced Settings
          • Usage
            • Max Messages
            • LLM Temperature
          • Scanners
            • AI Scanners
            • General Scanners
          • API Keys
          • Files
      • Editing an Agent
      • Deleting an Agent
      • Adding from a Template
    • Company
      • General Information
      • External Agent Provider Settings
    • Custom APIs
      • OAuth2 API
      • Adding a New API
        • API Information
        • API Headers
        • API Endpoint Parameters
        • API Query Parameters
        • Body Parameters
      • Editing a Custom API
      • Deleting a Custom API
    • Custom Database
    • Users
      • Inviting a New User
      • Deleting a User
      • Roles
        • Accessing User Roles
      • Assigning an Agent
      • Setting a Default Agent
    • Groups
      • Adding a New Group
      • Deleting a Group
      • Assigning a User
      • Removing a User
      • Adding an Agent
      • Removing an Agent
    • Agent Scanner Defaults
      • Toxicity
      • Personal Information
      • Topic Scanner
      • Prompt Injection Detection
      • Regex Scanner
      • Geographic Gating
      • Language Detection
      • Allowed File Types
    • Logs
      • Interpreting Logs
  • Server Admin
    • Upgrade
    • Default Agents
      • Adding a New Agent
    • Data Archive
    • API Access
      • Chat
        • List Agents
        • Create Conversation
        • List of Conversations
        • Get Conversations
        • Ask Agent
        • Chat with Agent
        • Add File to Conversation
        • Add Files to Agent
        • Deleting a File
      • OAuth2
        • OAuth2
        • OAuth2 Token
      • Users
        • List Users
        • Create User
        • Add User to Group
        • Set User Token
        • Delete User
      • How to Launch Our API Example
        • How the Code Works
    • Configure OAuth2
    • Custom Secrets
  • API Overview
    • Authentication
    • Calling the Scanner
    • Consuming the Results
    • 📃Pagination
      • Understanding API Parameters
      • Pagination Helper
      • Example Page
      • Recap
    • AIRisk API OAuth2 Authentication
      • Authorization
      • Authorization Endpoint
        • Example Authorization URL
        • Error Responses
      • Tokens
        • Error Handling
        • Generic vs. User-Specific Tokens
          • Example Usage Flow / Reasons
        • Usage of the Access Token
      • Token Endpoint
        • Example Token Request
        • Error Responses
      • Summary of OAuth2 Authorization Flow
  • Managing Your Account
    • Personal Data
  • Support
    • Onboarding Check List
  • Internal Deployment
    • Outlook Plugin
    • Firewall Rules
    • Infrastructure
    • Graph Connection Requirements
    • Zoom Transcripts
  • Example Python Application
  • Release Notes
    • V4.28
    • V4.12
    • V4.0
    • V3.71
    • V3.0 Beta
    • V2.23
    • V2.22
    • V2.120 HotFix
    • V2.103 June 1
Powered by GitBook
On this page
  • Understanding the project structure
  • NOTES:
  • Installation
  • Commands & Usage
  • The UI
  • NOTES:
  • Components
  • Before Running
  • How it Works

Example Python Application

Provides and explains how to build your own chat application utilizing our (your own deployment of our) API within a flask application.

PreviousZoom TranscriptsNextV4.28

Last updated 26 days ago

Understanding the project structure

Poetry used for package management

  • Non-src-based layout

    • I.e., the main package is adjacent to the pyproject.toml file (since the source code is important, when usually one would use poetry to build the package and send a wheel of it)

  • Why Poetry?

    • Automatically and cleanly handles cross-package dependencies, installing valid versions for cross-compatibility if possible

    • Virtual Environment Management

Resources

  1. Swagger Page: https://demo.aicrisk.com/Swagger/index.html

    1. NOTE: Outside of the demo server, replace https://demo.aicrisk.com with your deployed endpoint

NOTES:

  1. Setup: Rename example.env to .env (Or if there is already a .env file, edit that) and fill in CLIENT_ID and CLIENT_SECRET and any other configuration

    1. For Example, set USER_ID if wanting the app to automatically select you (and even sign you in automatically if AUTO_LOG_ME_IN is True) as the user to authenticate

    2. Ensure proper url to deployment in API_BASE_URL

Installation

  1. cd into directory containing pyproject.toml

  2. poetry install

Commands & Usage

CD into airisk_python_demo/airisk_python_demo

  • Run Dev: poetry run flask run --port 7221 --cert=adhoc

  • Run with debugger: poetry run flask run --port 7221 --cert=adhoc --debugger --debug

The UI

  1. When Signed in as User, Impersonate User button allows impersonation of another user without losing initial user token

  2. Exit Impersonation button when impersonating someone will remove active impersonation and will sign in as initial user.

  3. Data Endpoints Section

    • View the literal JSON response data from corresponding remote endpoints

  4. UI Endpoints

    • Examples of using remote data in ones own UI

  5. Select Navigator section

    • View remote data on things relative to other things

      • Ex. Given current authenticated users available agents, go to conversation data for one agent (the one selected in the dropdown)

  6. Endpoint with Form Link

    • Example of integrating ones own form and flask view to handle the data input, and to communicate with the remote API with some sore of creation action. Ex. Creating a conversation.

  7. Forms

    • Ask Form Page (Deprecated, replaced with "Option Name" section)

      • Rough example of chat-less interface for using the remote /api/Chat/Ask endpoint

    • Single Object Navigator Util

      • List Conversations JSON Button

        • JSON data view for all authenticated conversations

      • Option Name ... section

        • Navigate to a custom chat page with which communicates with the remote server, providing a ChatGPT-like interface for an entire conversation.

          • Note, since this example app isn't utilizing streaming, one could either adapt this app to do so, or could create an illusion of streaming.

NOTES:

  1. Since in demo.aicrisk.com, the callback URLs allowed are HTTPS and not HTTP (e.g. https://localhost:7221/callback), therefore it is necessary to make flask run with https

    • needed pyopenssl and to append --cert=adhoc to flask cli (or equiv to app.run)

  2. Like #1, the callback URLs specify a port 7221.

    • Need to run flask with --port 7221 or change the setting

  3. Using Jinja2 as a template language for rendering the front-end HTML based UI using data coming from python

Components

  1. .env

    • Contains config variables for a more dynamic approach

  2. const.py

    • loads from .env into env variables also defining defaults.

    • Also defines TokenInput class for persistence of tokens with support for auto-saving, auto-loading, expiration-aware auth, etc.

  3. decorators.py

    • @login_required

      • Custom decorator to redirect client to / url (where auth is invoked) for any views accessing the remote api and therefore needing authentication.

        • If running server in debug mode, making a change & saving and then refreshing the page on a non-root URL, the page will fail since it would be obnoxious to implement authentication logic in every view and since these views require a token.

  4. authentication/

    • Module containing the flask Blueprint encapsulating the app logic (to show how to separate concerns.)

      • Could have set custom url prefix for this as well but didn't since didn't want to change aicrisk callback urls

      • contains view functions and data retrieval utilities along with some state management therein

  5. templates/

    • Directory containing the jinja2 templates used across the project

    • base.html is the root template (all others 'extend' it)

      • i.e. when extending a template, you inherit everything by default, including blocks. If defining an extisting block in the child, the whole block from the parent is overridden (unless doing super call therein)

      • Added CDN for tailwind css for easier style prototyping

Before Running

  • Make sure to set variables in .env properly. Noteably the CLIENT_ID and CLIENT_SECRET. Also the REDIRECT_URI if on a non-demo instance of AICRisk

  • Ensure callback urls are set in the remote server admin

    • If running locally, https://localhost:{PORT} (+/callback, ...)

    • Otherwise, set the exact IP or domain in which the local server will be run on

  • If wanting to automatically sign in as oneself (assuming USER_ID is set), also set AUTO_LOG_ME_IN=True

How it Works

  1. On start, the variables in .env are loaded into environment variables with fallbacks in const.py

  2. flask runs app.py (using configured variables) which in turn uses the app factory pattern to register the auth_bp blueprint and its routes to the app

  3. User opens browser to page

    • If the page is the auth_index page

      • If AUTO_RESTORE_SESSION is True and if the file at the path of TOKEN_INFO_FILE exists and contains a valid, not-expired token, then that token is read, validated, and set within the session as "access_token"

      • Otherwise

        • If AUTO_RESTORE_SESSION is False but the token file exists and contains a valid, non-expired token

          • The page is rendered with links to

            1. Go through the auth process from scratch, invoked by redirecting to auth view

            2. Read & load token from the file (see TokenInfo.load)

        • Otherwise (token non-existent or expired)

          • The page is rendered with a link to go through the authentication process

    • Otherwise (any other page that also isn't the authentication view (auth))

      • The client is redirected to auth_index page and is provided same means of authenticating as above accordingly

  4. Once auth is invoked

    • Starts by passing client_id (from env) and redirect_uri (https://{HOST|localhost}:{PORT|7221}/callback) to the remote authorize endpoint via a GET request (/api/oauth2) with encoded params placed in the url directly

    • The remote server then does its thing internally and redirects the client browser to the passed redirect_url (url for oauth_callback view) with a code parameter passed along therefrom

    • The redirect urls corresponding view function (oauth_callback) then issues a POST request to the remote token endpoint (/api/oauth2/Token) with parameters for the client_id, client_secret, grant_type="authorization_code", redirect_uri, and code with the value of code being that value received from the remote authorize endpoint

    • If successful and yielding a valid response from that POST request, a variable is then pulled from the returned json for access_token and is set in the state and saved. This is the JWT/Bearer Token we needed for the rest of the apps views to work

    • Custom UI components are rendered to simplify navigation and to illustrate how to somewhat dynamically set up linking to the other pages

      • For the list views, a given remote endpoint (ex user list) has

        1. a corresponding local url for retrieving the data.

        2. (Optionally) Some also have a corresponding "*_ui" view which renders the data in a nice user-centric fashion

      • Also illustrate how one may set up form field choices based on the existing remote data fetched. Ex. selecting conversations only for a particular agent

possible states when in app (non-linear)

  • Not Authenticated - [client_id, client_secret]

  • Authenticated as Generic

    • has token

  • Authenticated as Generic then User

  • User Authenticated directly without generic

  • User Authenticated somehow, and impersonating another user

Install Poetry
Activate your poetry environment
Article on running flask with HTTPS
428KB
airisk_python_demo - updated - 4-25-25.7z
Now with Leave-Feedback Functionality!
Page cover image