{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "QuickSight Data APIs to build data sources and datasets\n", "\n", "Author: Ying Wang (Sr.Data Visualization Engineer in ProServe GSP)\n", "Date: April 16 2020\n", "\n", "Author: Vamsi Bhadriraju (Data Architect in ProServe) \n", "Revision Date : March 23 2021\n", "Revision Date : May 27 2021\n", "\n", "Author: Ian Liao (Data Visualization Engineer in ProServe GSP)\n", "Date: Dec 3 2021\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import boto3\n", "import botocore\n", "import json\n", "import time\n", "import os\n", "from IPython.display import JSON\n", "from IPython.display import IFrame\n", "def display_json(doc, root='root'):\n", " return JSON(doc)\n", "#qs = boto3.client('quicksight')\n", "import logging\n", "from typing import Any, Dict, List, Optional\n", "\n", "def default_botocore_config() -> botocore.config.Config:\n", " \"\"\"Botocore configuration.\"\"\"\n", " retries_config: Dict[str, Union[str, int]] = {\n", " \"max_attempts\": int(os.getenv(\"AWS_MAX_ATTEMPTS\", \"5\")),\n", " }\n", " mode: Optional[str] = os.getenv(\"AWS_RETRY_MODE\")\n", " if mode:\n", " retries_config[\"mode\"] = mode\n", " return botocore.config.Config(\n", " retries=retries_config,\n", " connect_timeout=10,\n", " max_pool_connections=10,\n", " user_agent_extra=f\"qs_sdk_BIOps\",\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "construct target information " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def _assume_role(aws_account_number, role_name, aws_region):\n", " sts_client = boto3.client('sts', config=default_botocore_config())\n", " response = sts_client.assume_role(\n", " RoleArn='arn:aws:iam::' + aws_account_number + ':role/' + role_name,\n", " RoleSessionName='quicksight'\n", " )\n", " # Storing STS credentials\n", " session = boto3.Session(\n", " aws_access_key_id=response['Credentials']['AccessKeyId'],\n", " aws_secret_access_key=response['Credentials']['SecretAccessKey'],\n", " aws_session_token=response['Credentials']['SessionToken'],\n", " region_name=aws_region\n", " )\n", "\n", " #logger.info(\"Assumed session for \" + aws_account_number + \" in region \" + aws_region + \".\")\n", "\n", " return session\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_user_arn (session, username, region='us-east-1', namespace='default'): \n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " if username=='root':\n", " arn='arn:aws:iam::'+account_id+':'+username\n", " else:\n", " arn=\"arn:aws:quicksight:\"+region+\":\"+account_id+\":user/\"+namespace+\"/\"+username\n", " \n", " return arn" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_target(targetsession, rds,redshift,s3Bucket,s3Key,vpc,tag,targetadmin,rdscredential,redshiftcredential,region='us-east-1', namespace='default',version='1'): \n", " sts_client = targetsession.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " target: Dict[str, Any] = {\n", " \"rds\": {\"rdsinstanceid\": ''},\n", "\"s3\":{\"manifestBucket\": '',\n", "\"manifestkey\": ''},\n", "\"vpc\": '',\n", "\"tag\": '',\n", " \"credential\": {\"rdscredential\": rdscredential,\n", " \"redshiftcredential\": redshiftcredential},\n", " \"datasourcepermission\": [\n", " {'Principal': targetadmin,\n", " 'Actions': [\"quicksight:DescribeDataSource\",\n", " \"quicksight:DescribeDataSourcePermissions\",\n", " \"quicksight:PassDataSource\",\n", " \"quicksight:UpdateDataSource\",\n", " \"quicksight:DeleteDataSource\",\n", " \"quicksight:UpdateDataSourcePermissions\"]\n", " }\n", " ],\n", " \"datasetpermission\": [{'Principal': targetadmin,\n", " 'Actions': ['quicksight:UpdateDataSetPermissions',\n", " 'quicksight:DescribeDataSet',\n", " 'quicksight:DescribeDataSetPermissions',\n", " 'quicksight:PassDataSet',\n", " 'quicksight:DescribeIngestion',\n", " 'quicksight:ListIngestions',\n", " 'quicksight:UpdateDataSet',\n", " 'quicksight:DeleteDataSet',\n", " 'quicksight:CreateIngestion',\n", " 'quicksight:CancelIngestion']}],\n", " \"version\": '1', \n", " }\n", " \n", " if rds:\n", " target[\"rds\"][\"rdsinstanceid\"] = rds\n", " \n", " if redshift:\n", " target[\"redshift\"] = redshift\n", " \n", " if s3Bucket:\n", " target[\"s3\"][\"manifestBucket\"] = s3Bucket\n", " target[\"s3\"][\"manifestkey\"]=s3Key\n", " \n", " if vpc:\n", " target[\"vpc\"] = \"arn:aws:quicksight:\"+region+\":\"+account_id+\":vpcConnection/\"+vpc\n", " \n", " if tag:\n", " target[\"tag\"]=tag\n", " \n", " if rdscredential:\n", " target[\"credential\"][\"rdscredential\"]=rdscredential\n", " \n", " if redshiftcredential:\n", " target[\"credential\"][\"redshiftcredential\"]=redshiftcredential\n", " \n", " return target\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#get datasets of dashboards in deployment list\n", "def data_sets_ls_of_dashboard(dashboard, sourcesession):\n", " dashboardid=get_dashboard_ids(dashboard, sourcesession)\n", " print(dashboardid)\n", " sourcedashboard=describe_dashboard(sourcesession, dashboardid[0])\n", " DataSetArns=sourcedashboard['Dashboard']['Version']['DataSetArns']\n", " sourcedsref = []\n", " for i in DataSetArns:\n", " missing=False\n", " did = i.split(\"/\")[1]\n", " #print(did)\n", " try:\n", " dname=get_dataset_name(did, sourcesession)\n", " except Exception as e:\n", " faillist.append({\"Error Type\": \"Dataset: \"+did+\" is missing!\",\"DashboardId\": dashboardid[0], \"Name\": dashboard, \"Error\": str(e)})\n", " missing=True\n", " break\n", " \n", " sourcedsref.append(dname)\n", " return sourcedsref" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#get datasets of analysis in deployment list\n", "def data_sets_ls_of_analysis(analysis, sourcesession):\n", " analysisid=get_analysis_ids(analysis, sourcesession)\n", " sourceanalysis=describe_analysis(sourcesession, analysisid[0])\n", " DataSetArns=sourceanalysis['Analysis']['DataSetArns']\n", " sourcedsref = []\n", " for i in DataSetArns:\n", " missing=False\n", " did = i.split(\"/\")[1]\n", " #print(did)\n", " try:\n", " dname=get_dataset_name(did, sourcesession)\n", " except Exception as e:\n", " faillist.append({\"Error Type\": \"Dataset: \"+did+\" is missing!\",\"AnalysisId\": analysisid[0], \"Name\": analysis, \"Error\": str(e)})\n", " missing=True\n", " break\n", " \n", " sourcedsref.append(dname)\n", " return sourcedsref" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#get data sources of dashboards in deployment list\n", "def data_sources_ls_of_dashboard(dashboard, sourcesession):\n", " datasets=data_sets_ls_of_dashboard(dashboard, sourcesession)\n", " sourcedsref = []\n", " for dataset in datasets:\n", " ids = get_dataset_ids(dataset, sourcesession)\n", " res=describe_dataset(sourcesession, ids[0])\n", "\n", " PT=res['DataSet']['PhysicalTableMap']\n", " for key, value in PT.items():\n", " for i,j in value.items():\n", " dsid = j['DataSourceArn'].split(\"/\")[1]\n", " dsname=get_datasource_name(dsid, sourcesession)\n", " if dsname not in sourcedsref:\n", " sourcedsref.append(dsname)\n", " return sourcedsref" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#get data sources of analysis in deployment list\n", "def data_sources_ls_of_analysis(analysis, sourcesession):\n", " datasets=data_sets_ls_of_analysis(analysis, sourcesession)\n", " sourcedsref = []\n", " for dataset in datasets:\n", " ids = get_dataset_ids(dataset, sourcesession)\n", " res=describe_dataset(sourcesession, ids[0])\n", "\n", " PT=res['DataSet']['PhysicalTableMap']\n", " for key, value in PT.items():\n", " for i,j in value.items():\n", " dsid = j['DataSourceArn'].split(\"/\")[1]\n", " dsname=get_datasource_name(dsid, sourcesession)\n", " if dsname not in sourcedsref:\n", " sourcedsref.append(dsname)\n", " return sourcedsref" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_data_source_deployment_list(sourcesession,source_deployment_list):\n", " datasources=data_sources(sourcesession) #get data source details with listdatasource API\n", " \n", " deployment_list=[]\n", " for newsource in source_deployment_list:\n", " ids = get_datasource_ids(newsource, sourcesession) #Get id of data sources deployment list\n", " for datasource in datasources:\n", " if ids[0] == datasource[\"DataSourceId\"]:\n", " deployment_list.append(datasource) #deployment_list is an array containing data source connection information and etc\n", "\n", " return deployment_list\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "get object ids from name, or get object name from id " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# \n", "def get_dashboard_ids(name: str, session) -> List[str]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " \n", " ids: List[str] = []\n", " for dashboard in dashboards(session):\n", " if dashboard[\"Name\"] == name:\n", " ids.append(dashboard[\"DashboardId\"])\n", " return ids\n", "\n", "def get_analysis_ids(name: str, session) -> List[str]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " \n", " ids: List[str] = []\n", " for analysis_list in analysis(session):\n", " if analysis_list[\"Name\"] == name:\n", " ids.append(analysis_list[\"AnalysisId\"])\n", " return ids\n", "\n", "def get_dashboard_name(did: str, session) -> List[str]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " \n", " name: str\n", " for dashboard in dashboards(session):\n", " if dashboard[\"DashboardId\"] == did:\n", " name=dashboard[\"Name\"]\n", " return name\n", "\n", "\n", "\n", "def get_dataset_name(did: str, session) -> List[str]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " \n", " name: str\n", " for dataset in data_sets(session):\n", " if dataset[\"DataSetId\"] == did:\n", " name=dataset[\"Name\"]\n", " return name\n", "\n", "def get_dataset_ids(name: str, session) -> List[str]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " \n", " ids: List[str] = []\n", " for dataset in data_sets(session):\n", " if dataset[\"Name\"] == name:\n", " ids.append(dataset[\"DataSetId\"])\n", " return ids\n", "\n", "def get_datasource_name(did: str, session) -> List[str]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " \n", " name: str\n", " for datasource in data_sources(session):\n", " if datasource[\"DataSourceId\"] == did:\n", " name=datasource[\"Name\"]\n", " return name\n", "\n", "def get_datasource_ids(name: str, session) -> List[str]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " \n", " ids: List[str] = []\n", " for datasource in data_sources(session):\n", " if datasource[\"Name\"] == name:\n", " ids.append(datasource[\"DataSourceId\"])\n", " return ids" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "List current Data sources/datasets" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#\n", "def data_sources (session):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " datasources = []\n", " response = qs.list_data_sources(AwsAccountId=account_id)\n", " next_token: str = response.get(\"NextToken\", None)\n", " datasources += response[\"DataSources\"]\n", " while next_token is not None:\n", " response = qs.list_data_sources(AwsAccountId=account_id, NextToken=next_token)\n", " next_token = response.get(\"NextToken\", None)\n", " datasources += response[\"DataSources\"]\n", " return datasources\n", " \n", "def data_sets (session):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " datasets = []\n", " response = qs.list_data_sets(AwsAccountId=account_id)\n", " next_token: str = response.get(\"NextToken\", None)\n", " datasets += response[\"DataSetSummaries\"]\n", " while next_token is not None:\n", " response = qs.list_data_sets(AwsAccountId=account_id, NextToken=next_token)\n", " next_token = response.get(\"NextToken\", None)\n", " datasets += response[\"DataSetSummaries\"]\n", " return datasets\n", "\n", "def templates (session):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " token=None\n", " \n", " args: Dict[str, Any] = {\n", " \"AwsAccountId\": account_id,\n", " \"MaxResults\": 100,\n", " }\n", " \n", " tlist=qs.list_templates(**args)\n", "\n", " templates=tlist['TemplateSummaryList']\n", " \n", " if 'NextToken' in tlist:\n", " token=tlist['NextToken']\n", " while token is not None:\n", " args[\"NextToken\"] = token\n", " tlist=qs.list_templates(**args)\n", " templates.append(tlist['TemplateSummaryList'])\n", " token = tlist.get(\"NextToken\", None) \n", " else: pass\n", " #print('token is none. No further action.')\n", "\n", " return templates\n", "\n", "def dashboards(session)-> List[Dict[str, Any]]:\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " dashboards = []\n", " response = qs.list_dashboards(AwsAccountId=account_id)\n", " next_token: str = response.get(\"NextToken\", None)\n", " dashboards += response[\"DashboardSummaryList\"]\n", " while next_token is not None:\n", " response = qs.list_dashboards(AwsAccountId=account_id, NextToken=next_token)\n", " next_token = response.get(\"NextToken\", None)\n", " dashboards += response[\"DashboardSummaryList\"]\n", " return dashboards\n", "\n", "def analysis (session):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " analysis = []\n", " response = qs.list_analyses(AwsAccountId=account_id)\n", " next_token: str = response.get(\"NextToken\", None)\n", " analysis += response[\"AnalysisSummaryList\"]\n", " while next_token is not None:\n", " response = qs.list_analyses(AwsAccountId=account_id, NextToken=next_token)\n", " next_token = response.get(\"NextToken\", None)\n", " analysis += response[\"AnalysisSummaryList\"]\n", " return analysis\n", "\n", "def themes (session):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " themes = []\n", " response = qs.list_themes(AwsAccountId=account_id)\n", " next_token: str = response.get(\"NextToken\", None)\n", " themes += response[\"ThemeSummaryList\"]\n", " while next_token is not None:\n", " response = qs.list_themes(AwsAccountId=account_id, NextToken=next_token)\n", " next_token = response.get(\"NextToken\", None)\n", " themes += response[\"ThemeSummaryList\"]\n", " return themes\n", "\n", "def folder_members (session, folderid):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " members = []\n", " response = qs.list_folder_members(AwsAccountId=account_id, FolderId = folderid)\n", " next_token: str = response.get(\"NextToken\", None)\n", " members += response[\"FolderMemberList\"]\n", " while next_token is not None:\n", " response = qs.list_folder_members(AwsAccountId=account_id, FolderId = folderid, NextToken=next_token)\n", " next_token = response.get(\"NextToken\", None)\n", " members += response[\"FolderMemberList\"]\n", " return members" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Describe a Data source/dataset" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#\n", "def describe_source (session, DSID):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.describe_data_source(\n", " AwsAccountId=AccountId,\n", " DataSourceId=DSID)\n", " return response\n", "\n", "\n", "#Describe a Dataset\n", "def describe_dataset (session, DSID):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.describe_data_set(\n", " AwsAccountId=AccountId,\n", " DataSetId=DSID)\n", " return response\n", "\n", "def describe_dashboard(session, dashboard):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " try:\n", " response = qs.describe_dashboard(\n", " AwsAccountId=account_id,\n", " DashboardId=dashboard)\n", " except Exception as e:\n", " return ('Faild to describe dashboard: '+str(e))\n", " else: return response\n", "\n", "def describe_template(session,tid):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.describe_template(\n", " AwsAccountId=account_id,\n", " TemplateId=tid)\n", " return response\n", "\n", "def describe_analysis(session, analysis):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " try:\n", " response = qs.describe_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis)\n", " except Exception as e:\n", " return ('Faild to describe analysis: '+str(e))\n", " else: return response\n", " \n", "def describe_theme (session, THEMEID):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.describe_theme(\n", " AwsAccountId=AccountId,\n", " ThemeId=THEMEID)\n", " return response" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "delete object " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def delete_source (session, DataSourceId):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " delsource = qs.delete_data_source(\n", " AwsAccountId=AccountId,\n", " DataSourceId=DataSourceId)\n", " return delsource\n", "\n", "def delete_dataset (session, DataSetId):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.delete_data_set(\n", " AwsAccountId=AccountId,\n", " DataSetId=DataSetId)\n", " return response\n", "\n", "def delete_template (session, tid, version=None):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " args: Dict[str, Any] = {\n", " \"AwsAccountId\": AccountId,\n", " \"TemplateId\": tid,\n", " }\n", " if version:\n", " args[\"VersionNumber\"] = version\n", " \n", " response = qs.delete_template(**args)\n", " return response\n", "\n", "def delete_dashboard(session, did):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.delete_dashboard(\n", " AwsAccountId=account_id,\n", " DashboardId=did)\n", " return response\n", "\n", "def delete_analysis(session, did):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.delete_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=did)\n", " return response\n", "\n", "def delete_theme (session, THEMEID):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.delete_theme(\n", " AwsAccountId=AccountId,\n", " ThemeId=THEMEID)\n", " return response" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " Create Objects " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def create_data_source(source, session, target):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " credential=None\n", "\n", " # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/quicksight.html#QuickSight.Client.create_data_source\n", " conn_dict = {\n", " \"aurora\": \"AuroraParameters\",\n", " \"aurora_postgresql\": \"AuroraPostgreSqlParameters\",\n", " \"mariadb\": \"MariaDbParameters\",\n", " \"mysql\": \"MySqlParameters\",\n", " \"postgresql\": \"PostgreSqlParameters\",\n", " \"sqlserver\": \"SqlServerParameters\"\n", " }\n", "\n", " #rds\n", " if source['Type'].lower() in [\n", " 'aurora', 'aurora_postgresql', 'mariadb', 'mysql', 'postgresql',\n", " 'sqlserver'] and 'RdsParameters' in source['DataSourceParameters']:\n", " #Update data source instance name\n", " instance_id = source['DataSourceParameters']['RdsParameters']\n", " instance_id['InstanceId'] = target['rds']['rdsinstanceid']\n", " credential = target['credential']['rdscredential']\n", " elif source['Type'].lower() in [\n", " 'aurora', 'aurora_postgresql', 'mariadb', 'mysql', 'postgresql',\n", " 'sqlserver'] and conn_dict.get(source['Type'].lower()) in source['DataSourceParameters']:\n", " #Update data source parameters\n", " conn_name = conn_dict.get(source['Type'].lower())\n", " conn_params = source['DataSourceParameters'][conn_name]\n", " conn_params['Host'] = target['rds']['rdsinstanceid']\n", " credential = target['credential']['rdscredential']\n", " \n", " \n", " #redshift\n", " if source['Type']==\"REDSHIFT\":\n", " \n", " #Update data source instance name\n", " Cluster=source['DataSourceParameters']['RedshiftParameters']\n", " if 'ClusterId' in Cluster:\n", " Cluster['ClusterId'] = target['redshift']['ClusterId']\n", " Cluster['Host'] = target['redshift']['Host']\n", " if target['redshift']['Database'] is not None and 'Database' in Cluster:\n", " Cluster['Database'] = target['redshift']['Database']\n", " credential=target['credential']['redshiftcredential']\n", " \n", " if 'VpcConnectionProperties' in source and target['vpc'] is not None:\n", " source['VpcConnectionProperties']['VpcConnectionArn'] = target['vpc']\n", " elif 'VpcConnectionProperties' in source and target['vpc'] is None:\n", " raise Exception(\"Sorry, you need the targetvpc information\")\n", "\n", " args: Dict[str, Any] = {\n", " \"AwsAccountId\": account_id,\n", " \"DataSourceId\": source['DataSourceId'],\n", " \"Name\": source['Name'],\n", " \"Type\": source['Type'],\n", " }\n", " \n", " if \"SslProperties\" in source: \n", " args[\"SslProperties\"] = source['SslProperties']\n", " \n", " if 'DataSourceParameters' in source:\n", " args[\"DataSourceParameters\"] = source['DataSourceParameters']\n", " \n", " if target['tag'] is not None:\n", " args[\"Tags\"] = target['tag']\n", " \n", " if credential is not None:\n", " args[\"Credentials\"] = credential\n", " \n", " if 'VpcConnectionProperties' in source:\n", " args[\"VpcConnectionProperties\"] = source['VpcConnectionProperties']\n", " \n", " args[\"Permissions\"] = target['datasourcepermission']\n", " \n", " try:\n", " NewSource = qs.create_data_source(**args)\n", " return NewSource\n", " except Exception as e:\n", " error={\"DataSource\": args, \"Error\": str(e)}\n", " return error" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def loaddsinput (file, part):\n", " import json\n", " with open(file) as f:\n", " data = json.load(f)\n", " \n", " res=data['DataSet'][part]\n", " \n", " return res\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#AccountId string; DataSetId string; Name string; Physical: json; Logical: json; Mode: string;\n", "#ColumnGroups: json array; Permissions: json array; RLS: json; Tags: json array\n", "def create_dataset (session, DataSetId, Name, Physical, Logical, Mode, Permissions, ColumnGroups=None, RowLevelPermissionDataSet=None):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " args: Dict[str, Any] = {\n", " \"AwsAccountId\": AccountId,\n", " \"DataSetId\": DataSetId,\n", " \"Name\": Name,\n", " \"PhysicalTableMap\": Physical,\n", " \"LogicalTableMap\": Logical,\n", " \"ImportMode\": Mode,\n", " \"Permissions\": Permissions,\n", " }\n", " if ColumnGroups:\n", " args[\"ColumnGroups\"] = ColumnGroups\n", " if RowLevelPermissionDataSet:\n", " args[\"RowLevelPermissionDataSet\"] = RowLevelPermissionDataSet\n", " \n", " response = qs.create_data_set(**args)\n", " return response" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def create_template(session, TemplateId, tname, dsref, sourceanalysis, version):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " try:\n", " delete_template(session, TemplateId)\n", " except Exception:\n", " print(traceback.format_exc())\n", " #assert isinstance(TemplateId, int), ''\n", " finally:\n", " response = qs.create_template(\n", " AwsAccountId=account_id, \n", " TemplateId=TemplateId,\n", " Name=tname,\n", " SourceEntity={\n", " 'SourceAnalysis': {\n", " 'Arn': sourceanalysis,\n", " 'DataSetReferences': dsref\n", " }\n", " },\n", " VersionDescription=version\n", " )\n", " return response\n", "\n", "#res=update_template_permission('810061268089', 'covid19dashboard', 'arn:aws:iam::889399602426:root')\n", " \n", "def copy_template(session, TemplateId, tname, SourceTemplatearn):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " try:\n", " delete_template(session, TemplateId)\n", " except Exception:\n", " print(traceback.format_exc())\n", " #assert isinstance(TemplateId, int), ''\n", " finally:\n", " response = qs.create_template(\n", " AwsAccountId=account_id, \n", " TemplateId=TemplateId,\n", " Name=tname,\n", " SourceEntity={\n", " 'SourceTemplate': {\n", " 'Arn': SourceTemplatearn\n", " }\n", " },\n", " VersionDescription='1'\n", " )\n", " return response\n", "\n", "def create_dashboard(session, dashboard, name,principal, SourceEntity, version,themearn, filter='ENABLED',csv='ENABLED', sheetcontrol='EXPANDED'):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " if themearn=='':\n", " response = qs.create_dashboard(\n", " AwsAccountId=account_id,\n", " DashboardId=dashboard,\n", " Name=name,\n", " Permissions=[\n", " {\n", " 'Principal': principal,\n", " 'Actions': [\n", " 'quicksight:DescribeDashboard',\n", " 'quicksight:ListDashboardVersions',\n", " 'quicksight:UpdateDashboardPermissions',\n", " 'quicksight:QueryDashboard',\n", " 'quicksight:UpdateDashboard',\n", " 'quicksight:DeleteDashboard',\n", " 'quicksight:DescribeDashboardPermissions',\n", " 'quicksight:UpdateDashboardPublishedVersion' \n", " ]\n", " },\n", " ],\n", " SourceEntity=SourceEntity,\n", " VersionDescription=version,\n", " DashboardPublishOptions={\n", " 'AdHocFilteringOption': {\n", " 'AvailabilityStatus': filter\n", " },\n", " 'ExportToCSVOption': {\n", " 'AvailabilityStatus': csv\n", " },\n", " 'SheetControlsOption': {\n", " 'VisibilityState': sheetcontrol\n", " }\n", " }\n", " )\n", " else:\n", " response = qs.create_dashboard(\n", " AwsAccountId=account_id,\n", " DashboardId=dashboard,\n", " Name=name,\n", " Permissions=[\n", " {\n", " 'Principal': principal,\n", " 'Actions': [\n", " 'quicksight:DescribeDashboard',\n", " 'quicksight:ListDashboardVersions',\n", " 'quicksight:UpdateDashboardPermissions',\n", " 'quicksight:QueryDashboard',\n", " 'quicksight:UpdateDashboard',\n", " 'quicksight:DeleteDashboard',\n", " 'quicksight:DescribeDashboardPermissions',\n", " 'quicksight:UpdateDashboardPublishedVersion' \n", " ]\n", " },\n", " ],\n", " SourceEntity=SourceEntity,\n", " VersionDescription=version,\n", " DashboardPublishOptions={\n", " 'AdHocFilteringOption': {\n", " 'AvailabilityStatus': filter\n", " },\n", " 'ExportToCSVOption': {\n", " 'AvailabilityStatus': csv\n", " },\n", " 'SheetControlsOption': {\n", " 'VisibilityState': sheetcontrol\n", " }\n", " },\n", " ThemeArn=themearn\n", " )\n", " \n", " return response\n", "\n", "\n", "def create_analysis(session, analysis, name,principal, SourceEntity,ThemeArn):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " if ThemeArn != '':\n", " response = qs.create_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis,\n", " Name=name,\n", " Permissions=[\n", " {\n", " 'Principal': principal,\n", " 'Actions': [\n", " 'quicksight:RestoreAnalysis',\n", " 'quicksight:UpdateAnalysisPermissions',\n", " 'quicksight:DeleteAnalysis',\n", " 'quicksight:QueryAnalysis',\n", " 'quicksight:DescribeAnalysisPermissions',\n", " 'quicksight:DescribeAnalysis',\n", " 'quicksight:UpdateAnalysis'\n", " \n", " ]\n", " }\n", " ],\n", " SourceEntity=SourceEntity,\n", " ThemeArn=ThemeArn\n", " )\n", " else:\n", " response = qs.create_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis,\n", " Name=name,\n", " Permissions=[\n", " {\n", " 'Principal': principal,\n", " 'Actions': [\n", " 'quicksight:RestoreAnalysis',\n", " 'quicksight:UpdateAnalysisPermissions',\n", " 'quicksight:DeleteAnalysis',\n", " 'quicksight:QueryAnalysis',\n", " 'quicksight:DescribeAnalysisPermissions',\n", " 'quicksight:DescribeAnalysis',\n", " 'quicksight:UpdateAnalysis'\n", " \n", " ]\n", " }\n", " ],\n", " SourceEntity=SourceEntity\n", " )\n", "\n", " return response\n", "\n", "def create_theme (session,THEMEID, Name,BaseThemeId,Configuration):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.create_theme(\n", " AwsAccountId=AccountId,\n", " ThemeId=THEMEID,\n", " Name=Name,\n", " BaseThemeId=BaseThemeId,\n", " Configuration=Configuration\n", " )\n", " return response" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "def create_folder_membership(session, folderid, objectid, objecttype):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.create_folder_membership(\n", " AwsAccountId = AccountId,\n", " FolderId=folderid,\n", " MemberId=objectid,\n", " MemberType=objecttype\n", " )\n", " return response" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ " Update Objects " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "#AccountId string; DataSetId string; Name string; Physical: json; Logical: json; Mode: string;\n", "#ColumnGroups: json array; Permissions: json array; RLS: json; Tags: json array\n", "def update_dataset (session, DataSetId, Name, Physical, Logical, Mode, ColumnGroups=None, RowLevelPermissionDataSet=None):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " AccountId = sts_client.get_caller_identity()[\"Account\"]\n", " args: Dict[str, Any] = {\n", " \"AwsAccountId\": AccountId,\n", " \"DataSetId\": DataSetId,\n", " \"Name\": Name,\n", " \"PhysicalTableMap\": Physical,\n", " \"LogicalTableMap\": Logical,\n", " \"ImportMode\": Mode,\n", " }\n", " if ColumnGroups:\n", " args[\"ColumnGroups\"] = ColumnGroups\n", " if RowLevelPermissionDataSet:\n", " args[\"RowLevelPermissionDataSet\"] = RowLevelPermissionDataSet\n", " \n", " response = qs.update_data_set(**args)\n", " return response" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def update_template_permission(session, TemplateId, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_template_permissions(\n", " AwsAccountId=account_id,\n", " TemplateId=TemplateId,\n", " GrantPermissions=[\n", " {\n", " 'Principal': Principal,\n", " 'Actions': [\n", " 'quicksight:DescribeTemplate',\n", " ]\n", " }\n", " ]\n", " )\n", " return response\n", "\n", "def update_dashboard(session, dashboard, name, SourceEntity, version, filter='ENABLED',csv='ENABLED', sheetcontrol='EXPANDED'):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " response = qs.update_dashboard(\n", " AwsAccountId=account_id,\n", " DashboardId=dashboard,\n", " Name=name,\n", " SourceEntity=SourceEntity,\n", " VersionDescription=version,\n", " DashboardPublishOptions={\n", " 'AdHocFilteringOption': {\n", " 'AvailabilityStatus': filter\n", " },\n", " 'ExportToCSVOption': {\n", " 'AvailabilityStatus': csv\n", " },\n", " 'SheetControlsOption': {\n", " 'VisibilityState': sheetcontrol\n", " }\n", " })\n", " \n", " return response\n", "\n", "def update_data_source_permissions(session, datasourceid, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_data_source_permissions(\n", " AwsAccountId=account_id,\n", " DataSourceId=datasourceid,\n", " GrantPermissions=[\n", " {\n", " 'Principal': Principal,\n", " 'Actions':[\"quicksight:DescribeDataSource\",\n", " \"quicksight:DescribeDataSourcePermissions\",\n", " \"quicksight:PassDataSource\",\n", " \"quicksight:UpdateDataSource\",\n", " \"quicksight:DeleteDataSource\",\n", " \"quicksight:UpdateDataSourcePermissions\"]\n", " },\n", " ]\n", " )\n", " return response\n", "\n", "def update_data_set_permissions(session, datasetid, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_data_set_permissions(\n", " AwsAccountId=account_id,\n", " DataSetId=datasetid,\n", " GrantPermissions=[\n", " {\n", " 'Principal': Principal,\n", " 'Actions':['quicksight:UpdateDataSetPermissions',\n", " 'quicksight:DescribeDataSet',\n", " 'quicksight:DescribeDataSetPermissions',\n", " 'quicksight:PassDataSet',\n", " 'quicksight:DescribeIngestion',\n", " 'quicksight:ListIngestions',\n", " 'quicksight:UpdateDataSet',\n", " 'quicksight:DeleteDataSet',\n", " 'quicksight:CreateIngestion',\n", " 'quicksight:CancelIngestion']\n", " },\n", " ]\n", " )\n", " return response\n", "\n", "\n", "def update_analysis(session, analysis, name, SourceEntity,themearn):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " if themearn == '':\n", " response = qs.update_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis,\n", " Name=name,\n", " SourceEntity=SourceEntity\n", " )\n", " else:\n", " response = qs.update_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis,\n", " Name=name,\n", " SourceEntity=SourceEntity,\n", " ThemeArn=themearn\n", " ) \n", " return response\n", "\n", "\n", "def describe_analysis_permissions(session, analysis):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " try:\n", " response = qs.describe_analysis_permissions(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis)\n", " except Exception as e:\n", " return ('Faild to describe analysis: '+str(e))\n", " else: return response\n", " \n", "def update_theme(session, THEMEID, name,BaseThemeId):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " response = qs.update_theme(\n", " AwsAccountId=account_id,\n", " ThemeId=THEMEID,\n", " Name=name,\n", " BaseThemeId=BaseThemeId\n", " )\n", " return response\n", "\n", "def describe_theme_permissions(session, THEMEID):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " response = qs.describe_theme_permissions(\n", " AwsAccountId=account_id,\n", " ThemeId=THEMEID\n", " )\n", " return response\n", "\n", "def update_theme_permissions(session, THEMEID, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_theme_permissions(\n", " AwsAccountId=account_id,\n", " ThemeId=THEMEID,\n", " GrantPermissions=[\n", " {\n", " 'Principal':Principal,\n", " 'Actions':['quicksight:ListThemeVersions',\n", " 'quicksight:UpdateThemeAlias',\n", " 'quicksight:UpdateThemePermissions',\n", " 'quicksight:DescribeThemeAlias',\n", " 'quicksight:DeleteThemeAlias',\n", " 'quicksight:DeleteTheme',\n", " 'quicksight:ListThemeAliases',\n", " 'quicksight:DescribeTheme',\n", " 'quicksight:CreateThemeAlias',\n", " 'quicksight:UpdateTheme',\n", " 'quicksight:DescribeThemePermissions']\n", " }\n", " ]\n", " )\n", " return response" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def update_template_permission(session, TemplateId, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_template_permissions(\n", " AwsAccountId=account_id,\n", " TemplateId=TemplateId,\n", " GrantPermissions=[\n", " {\n", " 'Principal': Principal,\n", " 'Actions': [\n", " 'quicksight:DescribeTemplate',\n", " ]\n", " }\n", " ]\n", " )\n", " return response\n", "\n", "def update_dashboard(session, dashboard, name, SourceEntity, version, filter='ENABLED',csv='ENABLED', sheetcontrol='EXPANDED'):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " response = qs.update_dashboard(\n", " AwsAccountId=account_id,\n", " DashboardId=dashboard,\n", " Name=name,\n", " SourceEntity=SourceEntity,\n", " VersionDescription=version,\n", " DashboardPublishOptions={\n", " 'AdHocFilteringOption': {\n", " 'AvailabilityStatus': filter\n", " },\n", " 'ExportToCSVOption': {\n", " 'AvailabilityStatus': csv\n", " },\n", " 'SheetControlsOption': {\n", " 'VisibilityState': sheetcontrol\n", " }\n", " })\n", " \n", " return response\n", "\n", "def update_data_source_permissions(session, datasourceid, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_data_source_permissions(\n", " AwsAccountId=account_id,\n", " DataSourceId=datasourceid,\n", " GrantPermissions=[\n", " {\n", " 'Principal': Principal,\n", " 'Actions':[\"quicksight:DescribeDataSource\",\n", " \"quicksight:DescribeDataSourcePermissions\",\n", " \"quicksight:PassDataSource\",\n", " \"quicksight:UpdateDataSource\",\n", " \"quicksight:DeleteDataSource\",\n", " \"quicksight:UpdateDataSourcePermissions\"]\n", " },\n", " ]\n", " )\n", " return response\n", "\n", "def update_data_set_permissions(session, datasetid, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_data_set_permissions(\n", " AwsAccountId=account_id,\n", " DataSetId=datasetid,\n", " GrantPermissions=[\n", " {\n", " 'Principal': Principal,\n", " 'Actions':['quicksight:UpdateDataSetPermissions',\n", " 'quicksight:DescribeDataSet',\n", " 'quicksight:DescribeDataSetPermissions',\n", " 'quicksight:PassDataSet',\n", " 'quicksight:DescribeIngestion',\n", " 'quicksight:ListIngestions',\n", " 'quicksight:UpdateDataSet',\n", " 'quicksight:DeleteDataSet',\n", " 'quicksight:CreateIngestion',\n", " 'quicksight:CancelIngestion']\n", " },\n", " ]\n", " )\n", " return response\n", "\n", "\n", "def update_analysis(session, analysis, name, SourceEntity,themearn):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " if themearn == '':\n", " response = qs.update_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis,\n", " Name=name,\n", " SourceEntity=SourceEntity\n", " )\n", " else:\n", " response = qs.update_analysis(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis,\n", " Name=name,\n", " SourceEntity=SourceEntity,\n", " ThemeArn=themearn\n", " ) \n", " return response\n", "\n", "\n", "def describe_analysis_permissions(session, analysis):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " try:\n", " response = qs.describe_analysis_permissions(\n", " AwsAccountId=account_id,\n", " AnalysisId=analysis)\n", " except Exception as e:\n", " return ('Faild to describe analysis: '+str(e))\n", " else: return response\n", " \n", "def update_theme(session, THEMEID, name,BaseThemeId):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " response = qs.update_theme(\n", " AwsAccountId=account_id,\n", " ThemeId=THEMEID,\n", " Name=name,\n", " BaseThemeId=BaseThemeId\n", " )\n", " return response\n", "\n", "def describe_theme_permissions(session, THEMEID):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", "\n", " response = qs.describe_theme_permissions(\n", " AwsAccountId=account_id,\n", " ThemeId=THEMEID\n", " )\n", " return response\n", "\n", "def update_theme_permissions(session, THEMEID, Principal):\n", " qs = session.client('quicksight')\n", " sts_client = session.client(\"sts\")\n", " account_id = sts_client.get_caller_identity()[\"Account\"]\n", " response = qs.update_theme_permissions(\n", " AwsAccountId=account_id,\n", " ThemeId=THEMEID,\n", " GrantPermissions=[\n", " {\n", " 'Principal':Principal,\n", " 'Actions':['quicksight:ListThemeVersions',\n", " 'quicksight:UpdateThemeAlias',\n", " 'quicksight:UpdateThemePermissions',\n", " 'quicksight:DescribeThemeAlias',\n", " 'quicksight:DeleteThemeAlias',\n", " 'quicksight:DeleteTheme',\n", " 'quicksight:ListThemeAliases',\n", " 'quicksight:DescribeTheme',\n", " 'quicksight:CreateThemeAlias',\n", " 'quicksight:UpdateTheme',\n", " 'quicksight:DescribeThemePermissions']\n", " }\n", " ]\n", " )\n", " return response" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('done')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "conda_python3", "language": "python", "name": "conda_python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.13" }, "toc-showmarkdowntxt": true }, "nbformat": 4, "nbformat_minor": 4 }