Power BI REST API with python to publish the pbix files - python

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.

Related

I am authenticating to azure through python to list down all my virtual machines and I am getting this error

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)

Use of token code when accessing OneDrive using Python

I am writing some code to move files over to OneDrive (enterprise account). My app is authenticated in Azure AD and should have the correct accesses (Files.ReadWrite.All in MS Graph, Sites.ReadWrite.All in Office365 SPO and User.Read in Azure AD).
The code to receive the app token works fine:
import msal
client_id = 'dc185bb*************6bcda94'
authority_host_uri = 'https://login.microsoftonline.com'
discovery_uri = 'https://api.office.com/discovery/'
client_secret = 'VsY7vV**************ToiA0='
tenant = '4a6*********************65079'
authority_uri = authority_host_uri + '/' + tenant
scopes=['https://graph.microsoft.com/.default']
app = msal.ConfidentialClientApplication(
client_id=client_id, authority=authority_uri,
client_credential=client_secret)
result = app.acquire_token_for_client(scopes=scopes)
print(result)
However, when I try to use this token with the OneDrive SDK library it seems like I am not able pass it through:
def __init__(self, http_provider, client_id=None, scopes=None, access_token=None, session_type=None, loop=None,
auth_server_url=None, auth_token_url=None):
"""Initialize the authentication provider for authenticating
requests sent to OneDrive
Args:
http_provider (:class:`HttpProviderBase<onedrivesdk.http_provider_base>`):
The HTTP provider to use for all auth requests
client_id (str): Defaults to None, the client id for your
application
scopes (list of str): Defaults to None, the scopes
that are required for your application
access_token (str): Defaults to None. Not used in this implementation.
The above is from the auth_provider.py part of the onedrivesdk, and clearly states the access_token is not used in the implementation.
Is there another way around this? Or other libraries to use?
You could try to use this Authentication of OneDrive for Business.
import onedrivesdk
from onedrivesdk.helpers import GetAuthCodeServer
from onedrivesdk.helpers.resource_discovery import ResourceDiscoveryRequest
redirect_uri = 'http://localhost:8080'
client_id = your_client_id
client_secret = your_client_secret
discovery_uri = 'https://api.office.com/discovery/'
auth_server_url='https://login.microsoftonline.com/common/oauth2/authorize'
auth_token_url='https://login.microsoftonline.com/common/oauth2/token'
http = onedrivesdk.HttpProvider()
auth = onedrivesdk.AuthProvider(http,
client_id,
auth_server_url=auth_server_url,
auth_token_url=auth_token_url)
auth_url = auth.get_auth_url(redirect_uri)
code = GetAuthCodeServer.get_auth_code(auth_url, redirect_uri)
auth.authenticate(code, redirect_uri, client_secret, resource=discovery_uri)
# If you have access to more than one service, you'll need to decide
# which ServiceInfo to use instead of just using the first one, as below.
service_info = ResourceDiscoveryRequest().get_service_info(auth.access_token)[0]
auth.redeem_refresh_token(service_info.service_resource_id)
client = onedrivesdk.OneDriveClient(service_info.service_resource_id + '/_api/v2.0/', auth, http)
Upload an Item:
returned_item = client.item(drive='me', id='root').children['newfile.txt'].upload('./path_to_file.txt')
For more examples, you can refer to this link.

googleapi.discovery iam create service account

Hi I want to use the google api service to create service accounts.
Here is my current code:
base_url = f"https://iam.googleapis.com/v1/projects/{project}/serviceAccounts"
auth = f"?access_token={access_token}"
data = {"accountId": name,
"serviceAccount": {
"displayName": name
}}
Create a service Account
r = requests.post(base_url + auth, json=data)
try:
r.raise_for_status()
except requests.HTTPError:
if r.status_code != 409:
raise
This works, but it uses the requests package.
I want to use googleapiclient
from googleapiclient.discovery import build
credentials = GoogleCredentials.get_application_default()
api = build(service, version, credentials=credentials)
Then, where do I find information on how to use this api object?
I've tried:
api.projects().serviceAccounts.create(name=name).execute()
But this does not work, and I don't know how to find what arguments are expected or required.
You can find the GCP IAM API documentation here.
The arguments required and values are documented there.
For anyone else who is struggling.
Check out api explorer to get the format of the request.
For example, If the endpoint is iam.projects.serviceAccounts.get
and you need to provide name = "projects/project/serviceAccounts/sa#gsc.googleserviceaccounts.com"
Then your call will look like:
from googleapiclient.discovery import build
credentials = GoogleCredentials.get_application_default()
api = build(service, version, credentials=credentials)
sa = api.projects().serviceAccounts().get(name="projects/project/serviceAccounts/sa#gsc.googleserviceaccounts.com")
Hope this helps someone.

People API returns no connections when authenticating via Service Account [duplicate]

I'm trying to programmatically access the list of contacts on my own personal Google Account using the Python Client Library
This is a script that will run on a server without user input, so I have it set up to use credentials from a Service Account I set up. My Google API console setup looks like this.
I'm using the following basic script, pulled from the examples provided in the API docs -
import json
from httplib2 import Http
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build
# Only need read-only access
scopes = ['https://www.googleapis.com/auth/contacts.readonly']
# JSON file downloaded from Google API Console when creating the service account
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'keep-in-touch-5d3ebc885d4c.json', scopes)
# Build the API Service
service = build('people', 'v1', credentials=credentials)
# Query for the results
results = service.people().connections().list(resourceName='people/me').execute()
# The result set is a dictionary and should contain the key 'connections'
connections = results.get('connections', [])
print connections #=> [] - empty!
When I hit the API it returns a result set without any 'connections' key. Specifically it returns -
>>> results
{u'nextSyncToken': u'CNP66PXjKhIBMRj-EioECAAQAQ'}
Is there something pertaining to my setup or code that's incorrect? Is there a way to see the response HTTP status code or get any further detail about what it's trying to do?
Thanks!
Side note: When I try it using the "Try it!" feature in the API docs, it correctly returns my contacts. Although I doubt that uses the client library and instead relies on user authorization via OAuth
The personFields mask is required. Specify one or more valid paths. Valid paths are documented at https://developers.google.com/people/api/rest/v1/people.connections/list/.
Additionally, use fields mask to specify which fields are included in a partial response.
Instead of:
results = service.people().connections().list(resourceName='people/me').execute()
... try:
results = service.people().connections().list(resourceName='people/me',personFields='names,emailAddresses',fields='connections,totalItems,nextSyncToken').execute()
Here is a working demo. I just tested it right now. Python 3.5.2
google-api-python-client==1.6.4
httplib2==0.10.3
oauth2client==4.1.2
You can save it to demo.py and then just run it. I left the create_contact function in case you might want to use it and have one more example on the API usage.
CLIENT_ID and CLIENT_SECRET are environment variables so I don't accidentally share that in code.
"""Google API stuff."""
import httplib2
import json
import os
from apiclient.discovery import build
from oauth2client.file import Storage
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run_flow
CLIENT_ID = os.environ['CLIENT_ID']
CLIENT_SECRET = os.environ['CLIENT_SECRET']
SCOPE = 'https://www.googleapis.com/auth/contacts'
USER_AGENT = 'JugDemoStackOverflow/v0.1'
def make_flow():
"""Make flow."""
flow = OAuth2WebServerFlow(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
scope=SCOPE,
user_agent=USER_AGENT,
)
return flow
def get_people():
"""Return a people_service."""
flow = make_flow()
storage = Storage('info.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = run_flow(flow, storage)
http = httplib2.Http()
http = credentials.authorize(http)
people_service = build(serviceName='people', version='v1', http=http)
return people_service
def create_contact(people, user):
"""Create a Google Contact."""
request = people.createContact(
body={
'names': [{'givenName': user.name}],
'phoneNumbers': [
{'canonicalForm': user.phone, 'value': user.phone}],
}
)
return request.execute()
def demo():
"""Demonstrate getting contacts from Google People."""
people_service = get_people()
people = people_service.people()
connections = people.connections().list(
resourceName='people/me',
personFields='names,emailAddresses,phoneNumbers',
pageSize=2000,
)
result = connections.execute()
s = json.dumps(result)
# with open('contacts.json', 'w') as f:
# f.write(s)
return s
if __name__ == '__main__':
print(demo())
With service account, in DwD - G Suite Domain-wide Delegation, is necessary impersonate or delegate user in this way
delegate = credentials.create_delegated('user#xxxx.xxx')
For fellow googlers: I have the same problem using the JS API.
I succeded on my personal gmail address, but not on my work one (g-suite) neither on my secondary gmail address.
Can't see the pattern. It's possible that the work one has contact listing deactivated.

How to create Google API OAuth Credentials object from alternate source

I am working with this simple Google API example:
import httplib2
from apiclient.discovery import build
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run
# Path to the client_secret.json file downloaded from the Developer Console
CLIENT_SECRET_FILE = 'client_secret.json'
# Check https://developers.google.com/gmail/api/auth/scopes for all available scopes
OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.readonly'
# Location of the credentials storage file
STORAGE = Storage('gmail.storage')
# Start the OAuth flow to retrieve credentials
flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE)
http = httplib2.Http()
# Try to retrieve credentials from storage or run the flow to generate them
credentials = STORAGE.get()
if credentials is None or credentials.invalid:
credentials = run(flow, STORAGE, http=http)
# Authorize the httplib2.Http object with our credentials
http = credentials.authorize(http)
# Build the Gmail service from discovery
gmail_service = build('gmail', 'v1', http=http)
And seeing as I have already gone through the OAuth flow previously (in a different non-Python app) and have my refresh tokens, etc. I would like to skip the first portion of this example and either manually create the expected storage file gmail.storage or create the credentials object some other way.
The problem is I can't find any documentation about the expected format of this storage file, or what should be in it, or how to instantiate the credentials object in any other way. Sorry that I cannot show any work here, but I'm at a loss. Any point in the right direction would be greatly appreciated.
Very simple, apparently this works:
from oauth2client.client import GoogleCredentials
from oauth2client import GOOGLE_TOKEN_URI
access_token = None
token_expiry = None
token_uri = GOOGLE_TOKEN_URI
user_agent = 'Python client library'
revoke_uri = None
gCreds = GoogleCredentials(
access_token,
client_id,
client_secret,
refresh_token,
token_expiry,
token_uri,
user_agent,
revoke_uri=revoke_uri
)
As explained here: in Google Cloud Platform's github
you can also use a string to setup this. Specially a json string
import json
import os
from google.oauth2 import service_account
from google.cloud import translate
info = json.loads(os.environ['GOOGLE_APPLICATION_CREDENTIALS_JSON_STRING'])
creds = service_account.Credentials.from_service_account_info(info)
# Instantiates a client
translate_client = translate.Client(credentials=creds)
Please note that I used Google Translate's API for this example but it's the same logic.
There is a bit more explanation in this git issue too: https://github.com/GoogleCloudPlatform/google-cloud-python/issues/4477
The oauth2client.file.Storage lib might be of interest to you:
from oauth2client.file import Storage
storage = Storage('gmail.storage')
credentials = storage.get()
storage.put(credentials)

Categories