I am new come to the python, but I need to invoke Power BI REST API with python to publish my pbix file in my repo to the workspace.
Based on this document, I could successfully authenticated and get the workspace:
import json, requests, pandas as pd
try:
from azure.identity import ClientSecretCredential
except Exception:
!pip install azure.identity
from azure.identity import ClientSecretCredential
# --------------------------------------------------------------------------------------#
# String variables: Replace with your own
tenant = 'Your-Tenant-ID'
client = 'Your-App-Client-ID'
client_secret = 'Your-Client-Secret-Value' # See Note 2: Better to use key vault
api = 'https://analysis.windows.net/powerbi/api/.default'
# --------------------------------------------------------------------------------------#
# Generates the access token for the Service Principal
auth = ClientSecretCredential(authority = 'https://login.microsoftonline.com/',
tenant_id = tenant,
client_id = client,
client_secret = client_secret)
access_token = auth.get_token(api)
access_token = access_token.token
print('\nSuccessfully authenticated.')
But I do not know how to publish my pbix to one of my workspace and with parameter overwrite by using REST API with python. And if the pbix already existed in the workspace, provide the parameter to overwrite it.
Any advice would be greatly appreciated and a sample will be greate.
Is there any Python code sample available to get Google ads campaign data using Python via service account.
The information available on https://developers.google.com/google-ads/api/docs/oauth/service-accounts
is not sufficient enough to start. I have created service code and trying to use following code, but I am not even sure of this is depreciated on or the new one
from google.oauth2.service_account import Credentials
from google.ads.googleads.client import GoogleAdsClient
SCOPES = ['https://www.googleapis.com/auth/adwords']
PATH_TO_SERVICE_ACCOUNT_JSON = ''
CUSTOMER_ID = ''
DEVELOPER_TOKEN = ''
QUERY = ''
credentials = Credentials.from_service_account_file(PATH_TO_SERVICE_ACCOUNT_JSON, scopes=SCOPES, subject="<AN ACTUAL USER'S EMAIL HERE>")
googleads_client = GoogleAdsClient(credentials=credentials, developer_token=DEVELOPER_TOKEN, version="v7")
ga_service = googleads_client.get_service("GoogleAdsService")
response = ga_service.search(customer_id=CUSTOMER_ID, query=QUERY)
I am getting this error when I try to list down all my vms on Azure through python
Code: AuthorizationFailed
Message: The client "XXXX" with object id "XXXX" does not have authorization to perform action 'Microsoft.Compute/virtualMachines/read' over scope '/subscriptions/XXXXX or the scope is invalid. If access was recently granted, please refresh your credentials.
my code is below:
from azure.mgmt.compute import ComputeManagementClient
from azure.identity import ClientSecretCredential
Subscription_Id = "XXXX"
Tenant_Id = "XXXXX"
Client_Id = "XXXXX"
Secret = "XXXXX"
credential = ClientSecretCredential(
client_id=Client_Id,
client_secret=Secret,
tenant_id=Tenant_Id
)
compute_client = ComputeManagementClient(credential, Subscription_Id)
vm_list = compute_client.virtual_machines.list_all()
pageobject1 = vm_list.by_page(continuation_token=None)
for page in pageobject1:
for j in page:
print(j)
Instead of passing your app registration applicationId/objectId you need to pass the service principal/appregistration name when you are trying to assign a particular role like virtualmachinecontributor to your Service principal as show in below.
Post providing the required access to the service principal/appregistration you will be able to pull the list of virtual machines in your subscription. we have checked the above python in our local environment which is also working fine.
Here is sample output screenshot for reference:
Updated Answer To pull list of VM's using Resource Management Client:
from azure.mgmt.resource import ResourceManagementClient
from azure.identity import ClientSecretCredential
Subscription_Id = "<subId>"
Tenant_Id = "<tenantid>"
Client_Id = "<appId>"
Secret = "<clientSecret>"
credential = ClientSecretCredential(
client_id=Client_Id,
client_secret=Secret,
tenant_id=Tenant_Id
)
resource_client=ResourceManagementClient(credential=credential,subscription_id=Subscription_Id)
resource_list=resource_client.resources.list()
for item in resource_list:
if(item.type == 'Microsoft.Compute/virtualMachines'):
print(item)
I am trying to fetch the calendar events from my personal premium outlook account. It is not a work account.
I have a office 365 subscription. Using the same, I have setup Azure actuve directory where I have added my python web application, granted all the required permissions to the app. While accessing the API via web app I am able to fetch profile details, users and all, but unable to get data related to events, calendar etc.
I am getting this error - "message": "The tenant for tenant guid \u00*******b5d-*9-4b-b1-c5c***2ec8\u0027 does not exist."
I looked at many solutions on msdn and also on stackoverflow, but everyone told to get a premium account which I did but still the issue is not resolved.
Please help resolving the same. Thankyou in advance :)
I am attaching the copy of my app.config file for your reference.
import os
CLIENT_SECRET = "client secret key"
AUTHORITY = "https://login.microsoftonline.com/tenant id"
CLIENT_ID = "client id"
REDIRECT_PATH = "/getAToken"
ENDPOINT =ENDPOINT = 'https://graph.microsoft.com/v1.0/users/{my id}/events
# I also tried 'ENDPOINT = ' 'https://graph.microsoft.com/v1.0/users/{my id}/calendar/events''
SCOPE = ["User.ReadBasic.All"]
SESSION_TYPE = "filesystem" # So token cache will be stored in server-side session
use 'Oauth' class of python to pass all your token and ADD details like client id, client secret etc.
Something like this -
(Note config files contains all my details mentioned above.)
OAUTH = OAuth(APP)
MSGRAPH = OAUTH.remote_app(
'microsoft',
consumer_key=config.CLIENT_ID,
consumer_secret=config.CLIENT_SECRET,
request_token_params={'scope': config.SCOPES},
base_url=config.RESOURCE + config.API_VERSION + '/',
request_token_url=None,
access_token_method='POST',
access_token_url=config.AUTHORITY_URL + config.TOKEN_ENDPOINT,
authorize_url=config.AUTHORITY_URL + config.AUTH_ENDPOINT)
my config file :
CLIENT_ID = 'put here'
CLIENT_SECRET = 'put here'
REDIRECT_URI = 'http://localhost:5000/login/authorized'
AUTHORITY_URL = 'https://login.microsoftonline.com/common'
AUTH_ENDPOINT = '/oauth2/v2.0/authorize'
TOKEN_ENDPOINT = '/oauth2/v2.0/token'
RESOURCE = 'https://graph.microsoft.com/'
API_VERSION = 'v1.0'
SCOPES = ['User.Read', 'Mail.Send', 'Files.ReadWrite','Calendars.Read', 'Calendars.ReadWrite']
now you can call the get events like this :
eventResponse = MSGRAPH.get('me/events',headers=request_headers()) #request_headers() return all the requeried headers
print(eventResponce.data)
I'm trying to send a simple test email using the Gmail API but I keep getting the same error for every code sample I find.
My code at the moment is this:
def validationService():
SCOPES = ['https://mail.google.com/']
SERVICE_ACCOUNT_FILE = 'creds.json'
creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
service = build('gmail', 'v1', credentials=creds)
return service
def SendMessage(service, user_id, message):
try:
message = (service.users().messages().send(userId=user_id, body=message).execute())
print('Message Id:',message['id'])
return message
except errors.HttpError as error:
print('An error occurred:', error)
def CreateMessage(sender, to, subject, message_text):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()}
service = validationService()
email = CreateMessage("sendermail#gmail.com", "receiverrmail#gmail.com", "Test", "This is a test")
sent = SendMessage(service, "sendermail#gmail.com", email)
Returns
>>> An error occurred: <HttpError 400 when requesting https://www.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Bad Request">
I also don't understand the difference between the "sender" parameter at CreateMessage and userId at SendMessage.
If serves a purpose, I'm using a Service Account credential
-
Thanks!
When using a service account with the Gmail API. You need to set domain-wide delegation, which allows the service account to impersonate any user in your G Suite domain. Therefore, you must have a G Suite Account to be able to use domain wide-delegation as the docs say:
If you have a G Suite domain—if you use G Suite, for example—an
administrator of the G Suite domain can authorize an application to
access user data on behalf of users in the G Suite domain.
So now, why do you need to impersonate a user(a real person)? it's due to the fact a service account is a bot(not a real person) that is used to server-to-server interactions making possible your app calls Google APIs and although the service account has a parameter called client_email, which has a structure like name#project-randomnumber.iam.gserviceaccount.com it's not a real email that belongs to a real person (kind of confusing I know).
Having said that, I made some changes to your code. First, I modified your validationService function in order to build the service using domain-wide delegation.
def validationService():
# Set the crendentials
credentials = service_account.Credentials.\
from_service_account_file(SERVICE_ACCOUNT_FILE, scopes= SCOPES)
# Delegate the credentials to the user you want to impersonate
delegated_credentials = credentials.with_subject(USER_EMAIL)
service = discovery.build('gmail', 'v1', credentials=delegated_credentials)
return service
In your SendMessage function is not necessarily to pass the user who is going to send the email. Using me is enough as the Users.messages: send Parameters state:
userId string The user's email address. The special value me can be
used to indicate the authenticated user.
def SendMessage(service, message):
message = service.users().messages().send(userId="me", body=message).execute()
return message
Your whole code at the end could look like this one:
from googleapiclient import discovery, errors
from oauth2client import file, client, tools
from google.oauth2 import service_account
from email.mime.text import MIMEText
import base64
SERVICE_ACCOUNT_FILE = 'service_account.json'
SCOPES = [' https://mail.google.com/']
# The user we want to "impersonate"
USER_EMAIL = "user#domain"
def validationService():
# Set the crendentials
credentials = service_account.Credentials.\
from_service_account_file(SERVICE_ACCOUNT_FILE, scopes= SCOPES)
# Delegate the credentials to the user you want to impersonate
delegated_credentials = credentials.with_subject(USER_EMAIL)
service = discovery.build('gmail', 'v1', credentials=delegated_credentials)
return service
def SendMessage(service, message):
message = service.users().messages().send(userId="me", body=message).execute()
return message
def CreateMessage(sender, to, subject, message_text):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()}
def main():
try:
service = validationService()
email = CreateMessage(USER_EMAIL, "receiverrmail#domain", "Test", "This is a test")
email_sent = SendMessage(service, email)
print('Message Id:', email_sent['id'])
except errors.HttpError as err:
print('\n---------------You have the following error-------------')
print(err)
print('---------------You have the following error-------------\n')
if __name__ == '__main__':
main()
Notice
You also need to allow your service account to access Google's API when using domain-wide delegation by setting the Managing API client access on your G Suite account.
You don't break your head... Just use email and smtplib libraries. Very simple and fun sending email through Python, if you ask me. I have given my coding below and you should develop your own code based on this. If it works, just let me know - I will be happy. here it is....
import email, smtplib, os, time, fnmatch
from datetime import date, timedelta
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
def sendMailTo(recepient_id, today):
login_id = 'myemailID#gmail.com'
login_pwd = "mypassword"
fro_ = login_id
s_name = 'smtp.gmail.com'
s_port = 587
fileList = []
fi_type = '*.pdf'
file_path = "C:\\Myfolder\\Subfolder"
srvr = smtplib.SMTP(s_name, s_port)
srvr.ehlo()
srvr.starttls()
srvr.ehlo()
srvr.login(login_id, login_pwd)
sub = "Your subject here"
# loading MIMEMultipart obj onto outer var
outer = MIMEMultipart('alternative')
outer["From"] = 'Your company/Personal Name'
outer["To"] = recepient_id
outer['Subject'] = sub
# storing only pdf files
fileList = fnmatch.filter(os.listdir(file_path), fi_type)
for fi in fileList:
fi_name = os.path.join(file_path, fi)
fp = open(fi_name, 'rb')
img = MIMEImage(fp.read(), _subtype='jpg')
fp.close()
img.add_header('Content-disposition', "attachment", filename = fi)
outer.attach(img)
#start sending email with attachment with original file name
srvr.sendmail(fro_, recepient_id, outer.as_string())
part = None
outer = None
srvr.quit()