def test_grafana_api(self, mock_get): mock_get.return_value = Mock() mock_get.return_value.return_value = """{ "email": "*****@*****.**", "name": "admin", "login": "******", "theme": "light", "orgId": 1, "isGrafanaAdmin": true }""" cli = GrafanaFace(('admin', 'admin'), host='localhost', url_path_prefix='', protocol='https') cli.find_user('*****@*****.**')
def test_grafana_api_no_verify(self): cli = GrafanaFace(('admin', 'admin'), host='localhost', url_path_prefix='', protocol='https', verify=False) cli.api.s.get = Mock(name='get') cli.api.s.get.return_value = MockResponse( { "email": "*****@*****.**", "name": "admin", "login": "******", "theme": "light", "orgId": 1, "isGrafanaAdmin": True }, 200) basicAuth = requests.auth.HTTPBasicAuth('admin', 'admin') cli.users.find_user('*****@*****.**') cli.api.s.get.assert_called_once_with( 'https://localhost/api/users/[email protected]', auth=basicAuth, headers=None, json=None, verify=False)
def __init__( self, auth, host="localhost", port=None, url_path_prefix="", protocol="https", verify=False, ): """ Init auth :param auth: API Token (https://grafana.com/docs/http_api/auth/#create-api-token) :param host: Host of the API server Ex. 127.0.0.1 :param port: Ex. 3000 (default port) :param protocol: http or https .. code-block:: python grafana = GenerateSnapshot(auth='', host='xx', port=3000, protocol="https") """ self.api = GrafanaFace( auth, host=host, port=port, url_path_prefix=url_path_prefix, protocol=protocol, verify=verify, ) self.snapshots = Snapshots(self.api, host, protocol)
def create_or_update_grafana_dashboard(dashboard_json, legend_config, dashboard_id=None): auth = legend_config["grafana_api_key"] host = legend_config["grafana_host"] protocol = legend_config["grafana_protocol"] grafana_url = "%s://%s" % (protocol, host) grafana_api = GrafanaFace(auth=auth, host=host, protocol=protocol, timeout=30.0) # Create dashboard based on the folder, if a new dashboard # Check if the folder exists id = get_grafana_folder_id(dashboard_id, auth, grafana_url) if id is None: # Create folder if doesn't exist id = create_grafana_folder(dashboard_id, auth, grafana_url) dashboard_dict = {} dashboard_dict.update(dashboard=dashboard_json) dashboard_dict.update(folderId=int(id)) dashboard_dict.update(overwrite=True) resp = grafana_api.dashboard.update_dashboard(dashboard_dict) return resp
def test_grafana_api_no_verify(self): cli = GrafanaFace( ("admin", "admin"), host="localhost", url_path_prefix="", protocol="https", verify=False, ) cli.api.s.get = Mock(name="get") cli.api.s.get.return_value = MockResponse( { "email": "*****@*****.**", "name": "admin", "login": "******", "theme": "light", "orgId": 1, "isGrafanaAdmin": True, }, 200, ) basic_auth = requests.auth.HTTPBasicAuth("admin", "admin") cli.users.find_user("*****@*****.**") cli.api.s.get.assert_called_once_with( "https://localhost/api/users/[email protected]", auth=basic_auth, headers=None, json=None, verify=False, timeout=5.0, )
def setup(self): url = urlparse(self.grafana_url) # Grafana API Key auth if self.grafana_token: auth = self.grafana_token # HTTP basic auth else: username = url.username or 'admin' password = url.password or 'admin' auth = (username, password) self.grafana = GrafanaFace(auth, protocol=url.scheme, host=url.hostname, port=url.port, url_path_prefix=url.path.lstrip('/')) # Configure a larger HTTP request pool. # Todo: Review the pool settings and eventually adjust according to concurrency level or other parameters. # https://urllib3.readthedocs.io/en/latest/advanced-usage.html#customizing-pool-behavior # https://laike9m.com/blog/requests-secret-pool_connections-and-pool_maxsize,89/ adapter = requests.adapters.HTTPAdapter(pool_connections=100, pool_maxsize=100, max_retries=5, pool_block=True) self.grafana.api.s.mount('http://', adapter) self.grafana.api.s.mount('https://', adapter) return self
def __init__(self, host=None, user="******", password="******", port=3000): """""" # Create the GrafanaFace object to interface with the API self.grafana_api = GrafanaFace(host=host, auth=(user, password), port=port)
def setup_grafana(config_dict): global grafana_api, configuration configuration = config_dict grafana_api = GrafanaFace( auth=configuration.GRAFANA_AUTH, host=configuration.GRAFANA_URL, protocol=configuration.GRAFANA_PROTOCOL )
def test_grafana_api_token_auth(self): cli = GrafanaFace( "alongtoken012345etc", host="localhost", url_path_prefix="", protocol="https", ) self.assertTrue(isinstance(cli.api.auth, TokenAuth))
def test_grafana_api_timeout(self): cli = GrafanaFace( ("admin", "admin"), host="play.grafana.org", url_path_prefix="", protocol="https", verify=False, timeout=0.0001 ) with self.assertRaises(requests.exceptions.Timeout): cli.folder.get_all_folders()
def test_grafana_api(self, mock_get): mock_get.return_value = Mock() mock_get.return_value.return_value = """{ "email": "*****@*****.**", "name": "admin", "login": "******", "theme": "light", "orgId": 1, "isGrafanaAdmin": true }""" cli = GrafanaFace( ("admin", "admin"), host="localhost", url_path_prefix="", protocol="https" ) cli.users.find_user("*****@*****.**")
def create_dashboards(): grafana_api = GrafanaFace(auth=(settings.GF_SECURITY_ADMIN_USER, settings.GF_SECURITY_ADMIN_PASSWORD), host='grafana:3000') create_source_in_grafana(grafana_api) dashboards = [] for db in source_dbs: monitored_tables = MonitoredTable.get_monitored_tables(db.name) for table in monitored_tables: dash_data = create_dashboard_for_table(grafana_api, db, table) dashboards.append(dash_data) create_home_dashboard(grafana_api, dashboards)
def delete_dashboard(legend_config, uid): auth = legend_config["grafana_api_key"] host = legend_config["grafana_host"] protocol = legend_config["grafana_protocol"] grafana_api = GrafanaFace(auth=auth, host=host, protocol=protocol, timeout=30.0) try: grafana_api.dashboard.delete_dashboard(dashboard_uid=uid) return "Dashboard deleted" except GrafanaClientError as e: if e.message == "Client Error 404: Dashboard not found": return "Client Error 404: Dashboard not found" else: raise (e)
def create_dashboards(): grafana_api = GrafanaFace( auth=(settings.GF_SECURITY_ADMIN_USER, settings.GF_SECURITY_ADMIN_PASSWORD), host=f'{settings.GRAFANA_WEB_HOST}:{settings.GRAFANA_WEB_PORT}' ) create_source_in_grafana(grafana_api) dashboards = [] for db in source_dbs: monitored_tables = MonitoredTable.get_monitored_tables(db.name) for table in monitored_tables: dash_data = create_dashboard_for_table(grafana_api, db, table) dashboards.append(dash_data) home_response = create_home_dashboard(grafana_api, dashboards) star_home_dashboard(grafana_api, home_response)
def add_dashboard_to_grafana(dashboard): api = GrafanaFace( auth= "eyJrIjoiVTRUNlVNY0dHS1F3aU9JZnc1a2hWaFFpQUdVWFVhUWYiLCJuIjoiZ3JhZmFuYS1kZW1vLWRldmljZSIsImlkIjoxfQ==", host="192.168.0.16", port=3000, protocol="http" ) # Documentation can be found on the grafana-api github... Https can be used along with the verify keyword in the event of you not properly setting up the trust print("Trying to add dashboard to Grafana") dashboard = api.dashboard.update_dashboard( { "dashboard": dashboard, "overwrite": True } ) # We overwrite any dashboards with the current dashboard title. Dashboards need unique names in the same folder (you can also specify a folderId if required... return dashboard
def create_dashboards(): grafana_api = GrafanaFace( auth=(settings.GF_SECURITY_ADMIN_USER, settings.GF_SECURITY_ADMIN_PASSWORD), host=f'{settings.GRAFANA_WEB_HOST}:{settings.GRAFANA_WEB_PORT}') create_source_in_grafana(grafana_api) create_notifcation_channels(grafana_api) dashboards = [] for db in DataSource.source_dbs(): monitored_tables = MonitoredTable.get_monitored_tables(db.name) for table in monitored_tables: dash_data = create_dashboard_for_table(grafana_api, db, table) table.grafana_url = dash_data['dashboard']['url'] dashboards.append(dash_data) metrics_session.commit() home_response = create_home_dashboard(grafana_api, dashboards) star_home_dashboard(grafana_api, home_response)
dir_path = os.getcwd() #os.path.dirname(os.path.realpath(__file__)) print(dir_path) import time from datetime import datetime import pandas as pd from dateutil.relativedelta import relativedelta from datetime import date, time, timedelta import json from grafana_api.grafana_face import GrafanaFace grafana_api = GrafanaFace( auth= 'eyJrIjoibDZvZGdzN3RFUDlOc0JQdnNSN0RmTWtnU3hWaWdJM1giLCJuIjoicHl0aG9uIiwiaWQiOjF9', host='138.246.233.65:3000') current_time = datetime.now() # - relativedelta(days=1, hours=4) url = "https://ivscc.gsfc.nasa.gov/sessions/" + str(date.today().year) + "/" def add_datetime(x): return datetime.combine(x["start_date"], x["start_time"]) def calc_end_schedule(x): hours, minutes = map(int, x["Dur"].split(':')) duration = timedelta(hours=hours, minutes=minutes) return x["start_schedule"] + duration
from grafana_api.grafana_face import GrafanaFace import json import requests #login to the grafana api through the library grafana_api = GrafanaFace(auth=('admin', 'admin'), port=3001) # ORGANIZATIONS def _organization_check( organization): #checks if org exists or not in order to create it orgs = grafana_api.organizations.list_organization() for i in range(len(orgs)): if str(organization) in orgs[i]['name']: print("organization already created") return 1 return 0 def _create_organization(organization): url = 'http://*****:*****@localhost:3001/api/orgs' data = { "name": organization, } headers = {"Content-Type": 'application/json'} response = requests.post(url, json=data, headers=headers) print(response.text) def _get_current_organization(): url = 'http://*****:*****@localhost:3001api/org/' response = requests.get(url)
import os from grafana_api.grafana_api import GrafanaException from grafana_api.grafana_face import GrafanaFace MAIN_ORG_ID = 1 GRAFANA_MULTI_TENANT_OPERATOR_HOST = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_HOST") GRAFANA_MULTI_TENANT_OPERATOR_PORT = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_PORT") GRAFANA_MULTI_TENANT_OPERATOR_PROTOCOL = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_PROTOCOL", "http") GRAFANA_MULTI_TENANT_OPERATOR_VERIFY = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_VERIFY", True) in (True, 'true') GRAFANA_MULTI_TENANT_OPERATOR_TIMEOUT = float( os.getenv("GRAFANA_MULTI_TENANT_OPERATOR_TIMEOUT", "5.0")) GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_USERNAME = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_USERNAME", "admin") GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_PASSWORD = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_PASSWORD") api = GrafanaFace(auth=(GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_USERNAME, GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_PASSWORD), host=GRAFANA_MULTI_TENANT_OPERATOR_HOST, port=GRAFANA_MULTI_TENANT_OPERATOR_PORT, protocol=GRAFANA_MULTI_TENANT_OPERATOR_PROTOCOL, verify=GRAFANA_MULTI_TENANT_OPERATOR_VERIFY, timeout=GRAFANA_MULTI_TENANT_OPERATOR_TIMEOUT)
def setUp(self): self.cli = GrafanaFace(("admin", "admin"), host="localhost", url_path_prefix="", protocol="http")
config.read(config_file) grafana_host = config['grafana']['host'] grafana_user = config['grafana']['user'] grafana_password = config['grafana']['password'] grafana_port = config['grafana']['port'] grafana_protocol = config['grafana']['protocol'] #grafana_api_key = config['grafana']['api_key'] # Read json file with open(json_file, 'r') as file: json_dashboard = json.loads(file.read().replace('\n', '')) # Configure grafana conneciton grafana_api = GrafanaFace( # auth=grafana_api_key, host=grafana_host (grafana_user, grafana_password), host=grafana_host, port=grafana_port, protocol=grafana_protocol) # Push dashboard grafana_api.dashboard.update_dashboard(dashboard={ 'dashboard': json_dashboard, 'folderId': 0, 'overwrite': True }) # # Delete a dashboard by UID # grafana_api.dashboard.delete_dashboard(dashboard_uid='abcdefgh')
metavar='editor', type=str, help='the e-mail address of the user who should be added as editor') # Execute the parse_args() method args = parser.parse_args() #input_path = args.App logging.info('App: %s' % args.App) logging.info('Editor: %s' % args.Editor) logging.info(os.environ['GRAFANA_HOST']) try: grafana_api = GrafanaFace(auth=(os.environ['GRAFANA_USER'], os.environ['GRAFANA_PWD']), protocol='https', host=os.environ['GRAFANA_HOST']) # 1. Create team if it does not exist # 2. Add user to team if he is not already member try: user = grafana_api.users.find_user(args.Editor) user_id = user["id"] print(user) except: logging.critical('User does not exist. Aborting!') exit(1) name = 'Team %s' % args.App logging.info('Searching for team %s' % name) team = grafana_api.teams.get_team_by_name(name)
def main(): base_path = '.' # base_path = os.path.dirname(os.path.abspath(__file__)) if args.base_path is not None: base_path = inArgs.base_path config_file = base_path + '/' + JSON_CONFIG_NAME if args.config_file is not None: config_file = inArgs.config_file confObj = jsonConfig(config_file) if confObj is None: print('init config failure !') sys.exit(2) config = confObj.load() if config is None: print(confObj.err_msg) sys.exit(2) if args.verbose is None: if 'debug' in config['general']: args.verbose = config['general']['debug'] else: args.verbose = False #print( json.dumps(config, sort_keys=True, indent=4) ) datasources = {} context = {'vars': {}} if args.dashboard_name is None: args.dashboard_name = 'Oracle Overview' # collect info from configuration file context_name = args.dashboard_name if args.context_name is not None: context_name = args.context_name if 'contexts' in config and context_name in config['contexts']: cur_cont = config['contexts'][context_name] if 'vars' in cur_cont: context['vars'].update(cur_cont['vars']) if 'time_from' in cur_cont and args.time_from is None: args.time_from = cur_cont['time_from'] if 'time_to' in cur_cont and args.time_to is None: args.time_to = cur_cont['time_to'] if args.time_from is None: args.time_from = 'now-5m' if args.time_to is None: args.time_to = 'now' grafana_api = GrafanaFace(auth=config['grafana']['token'], host=config['grafana']['host'], protocol=config['grafana']['protocol'], port=config['grafana']['port'], verify=config['grafana']['verify_ssl']) try: res = grafana_api.health.check() if res['database'] != 'ok': print("grafana health_check is not KO.") sys.exit(2) elif args.verbose: print("grafana health_check is OK.") except e: print("error: {} - message: {}".format(status_code, e.message)) sys.exit(2) if args.action == 'generate' or args.action == 'export': dashboard = get_dashboard_content(config, grafana_api, args.dashboard_name) if dashboard is None: print("dashboard not found !") sys.exit(0) try: dtsrcs = grafana_api.datasource.list_datasources() except e: print("error: {} - message: {}".format(status_code, e.message)) sys.exit(2) for dtsrc in dtsrcs: datasources[dtsrc['name']] = dtsrc['id'] if 'isDefault' in dtsrc and dtsrc['isDefault']: datasources['default'] = dtsrc['id'] if args.verbose: print('datasources OK.') context['url'] = dashboard['meta']['url'] params = { 'api': grafana_api, 'dashboard': dashboard['dashboard'], 'datasources': datasources, 'time_to': args.time_to, 'time_from': args.time_from, 'context': context, 'debug': args.verbose } #********************************************************************************** #*** collect the data from datasources to populate the snapshot data_api = GrafanaData(params) res = data_api.get_dashboard_data() if res is None or not res: print("can't obtain dashboard data... snapshot canceled!") sys.exit(2) #********************************************************************************** #*** build the dashboard name dashboard_name = args.dashboard_name if 'snapshot_suffix' in config['general'] and config['general'][ 'snapshot_suffix']: dashboard_name += datetime.datetime.today().strftime( config['general']['snapshot_suffix']) #********************************************************************************** # init element for new snapshot time_from = data_api.context['time_from'] if time_from is None: #** 'now-5m' time_from = datetime.datetime.now().timestamp() time_from = datetime.datetime.fromtimestamp(time_from - 300).isoformat() else: time_from = datetime.datetime.fromtimestamp(time_from).isoformat() time_to = data_api.context['time_to'] if time_to is None: #** 'now' time_to = datetime.datetime.now().isoformat() else: time_to = datetime.datetime.fromtimestamp(time_to).isoformat() if args.verbose: print('time_from = {0} - time_to = {1}'.format(time_from, time_to)) raw = dashboard['dashboard']['time'] dashboard['dashboard']['time'] = { 'from': time_from, 'to': time_to, 'raw': raw } params = {'dashboard': dashboard['dashboard'], 'name': dashboard_name} if args.action == 'generate': #********************************************************************************** #*** check if snapshot name is already present in list res = [] try: res = grafana_api.snapshots.get_dashboard_snapshots() except: print("can't list existing snapshot") snapshots = res old_snap = False del_snap = False for snap in snapshots: #print(snap) if dashboard_name == snap['name']: old_snap = True try: res = grafana_api.snapshots.delete_snapshot_by_key( snap['key']) del_snap = True except: print("can't remove existing snapshot") # print( resp) break if args.verbose: if old_snap and del_snap: print("old snapshot was found and removed.") elif old_snap: print("old snapshot was found but not removed.") else: print("old snapshot was not found.") #********************************************************************************** # create new snapshot try: res = grafana_api.snapshots.create_new_snapshot(**params) print("OK: new snapshot '{}' created.".format(dashboard_name)) except Exception as e: print("error: {}".format(traceback.format_exc())) print("can't create new snapshot !") else: # action is export output_file = base_path + '/' if 'output_path' in config['general']: output_file += config['general']['output_path'] + '/' file_name = remove_accents_and_space(dashboard_name) output_file += file_name + '.json' try: output = open(output_file, 'w') except OSError as e: print('File {0} error: {1}.'.format(output_file, e.strerror)) sys.exit(2) content = None if args.pretty: content = json.dumps(params, sort_keys=True, indent=2) else: content = json.dumps(params) output.write(content) output.close() print( "OK: snapshot exported to '{}' exported.".format(output_file)) # end if action == export # end if action == generate|export elif args.action == 'import': if args.import_file is None: print('no file to import provided!') sys.exit(2) import_file = args.import_file if not re.search(r'^/', args.import_file): import_path = base_path + '/' if 'output_path' in config['general']: import_path += config['general']['output_path'] + '/' import_path += import_file try: input = open(import_path, 'r') except OSError as e: print('File {0} error: {1}.'.format(import_path, e.strerror)) sys.exit(2) data = input.read() input.close() try: params = json.loads(data) except json.JSONDecodeError as e: print("error reading '{}': {}".format(import_path, e)) sys.exit(2) #* format for exported snapshots is: # params = { # 'dashboard': dashboard['dashboard'], # 'name': dashboard_name # } if 'dashboard' in params and 'name' in params: dashboard_name = params['name'] data_api = GrafanaData({ 'api': grafana_api, }) res = data_api.insert_snapshot(**params) if res: print("OK: snapshot '{}' imported.".format(dashboard_name)) else: print("can't create new snapshot !") # end if action == import elif args.action == 'extract': #********************************************************************************** #*** check if snapshot name is already present in list res = [] try: res = grafana_api.snapshots.get_dashboard_snapshots() except: print("can't find existing snapshot") snapshots = res extracted_snap = None for snap in snapshots: #print(snap) if args.snapshot_name == snap['name']: try: extracted_snap = grafana_api.snapshots.get_snapshot_by_key( snap['key']) except Exception as e: print("error: {}".format(traceback.format_exc())) print("can't remove existing snapshot") break if extracted_snap is None: print("can't find {} in existing snapshots".format( args.snapshot_name)) sys.exit(2) save_snapshot(config, args, base_path, args.snapshot_name, extracted_snap, 'extracted')
def test_grafana_api_token_auth(self): cli = GrafanaFace('alongtoken012345etc', host='localhost', url_path_prefix='', protocol='https') self.assertTrue(isinstance(cli.api.auth, TokenAuth))
import os from grafana_api.grafana_face import GrafanaFace MAIN_ORG_ID = 1 GRAFANA_MULTI_TENANT_OPERATOR_HOST = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_HOST") GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_USERNAME = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_USERNAME", "admin") GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_PASSWORD = os.getenv( "GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_PASSWORD") api = GrafanaFace(auth=(GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_USERNAME, GRAFANA_MULTI_TENANT_OPERATOR_ADMIN_PASSWORD), host=GRAFANA_MULTI_TENANT_OPERATOR_HOST)
def test_grafana_api_basic_auth(self): cli = GrafanaFace(('admin', 'admin'), host='localhost', url_path_prefix='', protocol='https') self.assertTrue(isinstance(cli.api.auth, requests.auth.HTTPBasicAuth))
"""Grafana interaction functions.""" import requests from grafana_api.grafana_face import GrafanaFace import os # Login to the grafana api through the library grafana_port = os.environ["MF_USER_CONTROL_GRAFANA_PORT"] #3001 grafana_admin_name = os.environ["MF_USER_CONTROL_GRAFANA_ADMIN_NAME"] #admin grafana_admin_pass = os.environ["MF_USER_CONTROL_GRAFANA_ADMIN_PASS"] #admin #grafana_port = 3001 #grafana_admin_name = "admin" #grafana_admin_pass = "******" grafana_api = GrafanaFace(auth=(grafana_admin_name, grafana_admin_pass), host='mainflux-grafana', port=grafana_port) host = 'http://' + grafana_admin_name + ':' + grafana_admin_pass + '@mainflux-grafana:' + str( grafana_port) def _generic_get(url_): url = host + url_ headers = {"Content-Type": 'application/json'} response = requests.get(url, headers=headers) print(response.text) return response.json # ORGANIZATIONS def _organization_check( organization): # checks if org exists or not in order to create it
# This work is based on original code developed and copyrighted by TNO 2020. # Subsequent contributions are licensed to you by the developers of such code and are # made available to the Project under one or several contributor license agreements. # # This work is licensed to you under the Apache License, Version 2.0. # You may obtain a copy of the license at # # http://www.apache.org/licenses/LICENSE-2.0 # # Contributors: # TNO - Initial implementation # Manager: # TNO # import os from grafana_api.grafana_face import GrafanaFace INTERNAL_GRAFANA_HOST = os.getenv("INTERNAL_GRAFANA_HOST") INTERNAL_GRAFANA_PORT = os.getenv("INTERNAL_GRAFANA_PORT") EXTERNAL_GRAFANA_URL = os.getenv("EXTERNAL_GRAFANA_URL") GRAFANA_KEY = os.getenv("GRAFANA_API_KEY") """The Grafana API key. To be able to manage all resources, the role needs to be Admin.""" GRAFANA_API = GrafanaFace( auth=GRAFANA_KEY, host=INTERNAL_GRAFANA_HOST, port=INTERNAL_GRAFANA_PORT )
def __init__(self, layer, key, host="perfboard.dev.mozaws.net", port=3000): self.client = GrafanaFace(host=host, port=port, auth=key) self.layer = layer
import csv import os from grafana_api.grafana_face import GrafanaFace from grafana_api.grafana_api import GrafanaServerError gf_host = os.environ['GF_HOST'] gf_username = os.environ['GF_USERNAME'] gf_password = os.environ['GF_PASSWORD'] grafana_api = GrafanaFace(auth=(gf_username, gf_password), host=gf_host) # open csv file with open('users.csv') as csv_file: csv_reader = csv.reader(csv_file, delimiter=',') for row in csv_reader: if len(row) < 2: print('Invalid row format') continue name = row[0] email = row[1] username = email.replace('@gmail.com', '') user = { "name": name, "email": email, "login": username, "password": "******", "OrgId": 1 } try: result = grafana_api.admin.create_user(user) print(result)