Accessing Google Adsense API from a server with Python? - python

Is there any way to use Python to access the Google Adsense API from a server without any user interaction?
This is typically done by setting up a "service account", but Google's docs say that "AdSense doesn't support Service Accounts".
They say to use the web or installed application flows, but these require the user to manually confirm access for every access. My application needs to run on a headless server, without user interaction, so it can pull data every hour, so this won't work. This similar question suggests going through the user consent screen once and then caching the token on the server, but this isn't feasible in my case since my process needs to be 100% automated, and the token will eventually expire and require user interaction.
Unfortunately, Google's docs are quiet unhelpful, and even worse their Python coding examples haven't been updated in 7 years, and don't even seem to have worked back then, as many of them don't even run Python 2.7, much less 3.

It's true that the AdSense Management API doesn't support service accounts. While there is setup required at first with the Web Flow, the same is true for service accounts which also have to be granted permissions on the account being accessed.
Regarding the tokens expiring, the Web Flow will yield a refresh token, which you can use to generate new access tokens (known as offline access, which doesn't require user involvement after the initial setup).

Related

Daemon application authentication for OneDrive files

I have a OneDrive for Business user account within a large organization. I'd like to have a daemon service running (Python) that automatically uploads files to this user's OneDrive.
This service will be running in a headless VM, so browser-based authentication (especially if it needs to be done more than once) is very difficult.
What are my options for authenticating this app to allow it to write to the user's OneDrive? I've registered an app and created a client secret for it. I was experimenting with the authorization flow described here, but that SDK is deprecated and no longer supported, so I'd prefer to use Graph if possible.
What are my options for authentication with Python in this scenario, and is any sample code / example available?
Both delegated and application permissions are supported on MS Graph API: https://learn.microsoft.com/en-us/graph/api/drive-list?view=graph-rest-1.0&tabs=http. Application permissions might not be acceptable for your use case since they would allow access to all users' OneDrives?
Application permissions would definitely be the easiest choice.
But you can also implement this scenario using delegated permissions
You would need the user to initialize the process by authenticating interactively once.
When they do that, store the refresh token in a secret store accessible by the server application.
Then it can use the refresh token to get a new refresh token + access token when needed.
This approach has some more complexity but does allow you to only give access to this one user's OneDrive for the app.
Also, keep in mind that refresh tokens can expire.
The user would need to re-authenticate if that happens.
If this process is critical, application permissions can be a really good idea despite the downsides.

Google Drive API: Avoiding Manual Authentication

I want to write a python script that can connect to Google Drive API without having to manually authenticate on every device the script is run on.
I am writing some python code for a research study that is going to be run at various study locations. For data privacy reasons, we cannot store data locally and need to write it to the cloud (ideally Google Drive). A member of our team will not present at all locations the software is being run, and thus any sort of initial manual authentication (entering username and password at the different sites for OAuth) is really off of the table for us.
I've looked into the Google Drive API (Python), and am wondering if there is a way for a device running my script to get a Refresh token (and subsequent Access tokens) to modify a Google Sheet without needling to manually authenticate on each device.
Is there any way to make this possible with the Google Drive API (by having some sort of 'secret' that the code could store)? If not, are there any other cloud services that may be able to accommodate this?
Additionally, the python script is being run as part of an executable (produced from Vizard, probably irrelevant but mentioning it just in case)
Yes it can be done - see How do I authorise an app (web or installed) without user intervention?
However, it's probably a bad idea for two reasons. if you distribute code with embedded secrets (technically the secret is a Refresh Token), they tend not to stay secret for long. Secondly, there is the chance that the Refresh Token will expire and your users will be dead in the water.
I would suggest that you consider:-
A Service Account
Writing an OAuth proxy, which you can host for free on Google AppEngine, which puts all of the secret stuff on a server and from which your app can fetch Access Tokens as they are needed.

create a web application using google analytics api and its client google-api-python-client?

I was going through googles's api python-client-library and google analytics api . I was able to do all steps mentioned in official docs but then I got some doubts. Since I've never done this kind of thing before, so I need your valuable suggestions/tips.
My Goal:
Want to design a web application in Python(using django/flask) and google-api-python-client. I have few matrices(coming from my web ecommerce product that is using GA.) and I'm not sure if google analytics dashboard by default support at that deep level. so I will use Google's analytic api to customize data according to my need and show in my analytic web app(which can be accessed by any one).
Doubts/Queries:
1) first of all which reporting api I would be needing for this mentioned here. core api or metadata api?
2) while I was setting up the project and client key, I chose 2nd option(OAuth 2.0 client ID)
is that ok or should I chose service account? once I selected 2nd options there were couple of radio buttons(web, android, ios, other, etc.) I chose other or should I chose web?
3) once i chose other option from radio button list, I executed my script and it prompt a browser to ask for permission, I allowed. here my question is if I put my application on production would there not be any browser, what would happen in that case?
I would really appreciate if you can help me in these queries, sorry for long question, this is my first question.
PS: Bottom line is how one should structure and develop there analytic web application in general.
The key thing to understand is that Google Analytics is an authenticated API. It is designed make it easy to allow the end user to access their own data. It is designed to be hard to allow the end user to access data they do not own.
If you are building a web application to allow your users to access their own private data It is recommended that you use a client side authentication method, such as in this example or this example.
If you are trying to build a web application that shares your private data with your users there are a few ways to go about it:
You could collect the data server side in python using a service account (note you will have to add the service account the GA account you wish it to have access).
You can take a hybrid approach and have a service account generate an access token and use the embed api to actually make the query.
In the end I would encourage you to spend some time to read Using OAuth 2.0 to Access Google APIs, and understand senarios descussed and ask yourself which of these senerios will work best for my application.

How to make 'access_type=offline' / server-only OAuth2 operations on GAE/Python?

This post is a followup to How to do OAuth-requiring operations in a GAE cron job?, where I realized I'm mis-using the #oauth_required decorator from OAuth2DecoratorFromClientSecrets.
As described by the OAuth 2.0 explained presentation, Oauth 2.0 solves the problem of:
Building a service...
... accessed by a user...
... and accessing the user's data from a third party.
That's what #oauth_required abstracts, and it does it well (currently my app "works": if I trigger the refresh page, I'm being asked to authorize access to my youtube data to my app, and the rest follows). But that's not what I want! My app does something simpler, which is creating a youtube playlist every day with my credentials and without any user input. So to compare to the above 3-tier negociation, I want:
A service
... accessed by users
... but only accessing "server-owned" YouTube playlist data. I don't want any access to the user's YouTube data, I just want to modify a playlist I (i.e. me / a userid persisted by the server) own.
But I still need help to do that; here is my current state:
After a few searches I learned that what I want to do is called Offline Access (emphasis mine, which is almost exactly my use case):
"In some cases, your application may need to access a Google API when the user is not present. Examples of this include backup services and applications that make blogger posts exactly at 8am on Monday morning. This style of access is called offline, and web server applications may request offline access from a user. The normal and default style of access is called online."...
→ So I should keep doing what I'm doing right now, keep requesting access to my YouTube account, but do it using the type_access=offline flag to get a token, and persist/use it for subsequent requests.
The Offline Access and Using a Refresh Token sections make total sense, but stay at a general HTTP level. Being still a newbie, I don't see how to integrate those principles into my Python code, and I didn't find any sample Python code around....
→ Could anyone help me with one Python example illustrating how and where to use this flag?
... and in particular, after studying oauth2client.appengine.OAuth2Decorator.oauth_required, I'm still not sure if I can bend it to my case, or if I should do my own thing.
→ What do you think?
Thanks for your time; if needed I'm also hanging out on irc://irc.freenode.net/#appengine as ronj.
Offline access is the default when retrieving tokens; you may have noticed this in the OAuth dialog that comes up:
Perform these operations when I'm not using the application
When your user accepts the OAuth dialog in a method decorated with decorator.oauth_required the credentials for that user will be stored in the datastore, including the refresh token.
Once you have one of these credentials objects, you can use it so authorize an HTTP object for calling APIS:
import httplib2
http = credentials.authorize(httplib2.Http())
and once authorized, it will do all the work for you. So if the access_token is expired, the first API response will be a 401 and so the credentials object will use the refresh_token to get a new access_token and make the request again.
If you know the user ID, you can retrieve the credentials from the datastore as described in How to do OAuth-requiring operations in a GAE Task Queue?:
from oauth2client.appengine import CredentialsModel
from oauth2client.appengine import StorageByKeyName
credentials = StorageByKeyName(
CredentialsModel, user_id, 'credentials').get()
Note/Gotcha:
If a user has already authorized your client ID, the subsequent times you perform OAuth for these users they will not see the OAuth dialog and you won't be given a refresh token. A refresh token can only be given if they go through the OAuth dialog, but since the user had already authorized your client ID, the spec assumes you would already have a refresh token around.
This often comes up when developers are testing OAuth, since they will go through the flow multiple times with a test account and after accepting the 2nd, 3rd, 4th, ... times, they never see the refresh token. A simple way around this is to use approval_prompt=force as an argument to the OAuth2Decorator constructor. This will force the OAuth dialog to appear every time you perform OAuth for a user.
However, this will not cause the dialog to show up every time a request is served for a given user; this would be a TERRIBLE user experience. Instead, the SACSID cookie from the request can be used (by the client library and some App Engine libraries) to determine who the current user is. Once the the library knows that current user, it can get your existing stored token/credentials for that user from the datastore and no jarring dialog will be needed.

Deploying an app to users' appspot

I am working on a Python App, which runs on App Engine. Is there a way I can publish the app on each customers' appSpot account, so that the App uses the users' cloud storage? Instead of running the App on my AppSpot account and all the users storing the data on my Cloud space?
Yes, absolutely.
You just need to have each client create an App Engine account with an application to which you have administrator access. You can adjust the settings on the application to forbid downloads of your code by the other administrators if that's appropriate for your agreement with the client. This also allows the clients to be billed directly for their instances' usage, and makes it completely impossible for data to leak between different clients' instances.
Using multiple applications for multiple clients who are licensing your application almost certainly does not violate part 4.4 of the TOS, although don't take this as legal advice.
No, you cannot do that. The app is hosted and run in the administrator's account which would be you. What you can do is, release the source code and point your users do install it in their appspot account, just like creating a new application.
I suppose it's not exactly what you need. But it can give you an idea where to go. Please check DryDrop project. There is small Python application you can ask each user to install on their account, then they can configure it to fetch your site files from your GitHub repo through webhooks functionality. I didn't try it, but, theoretically, you update your site, commit it to your repo, and all users get your updated application automatically. You can share your thoughts if that works for you.
Maybe. If it's an open source app that you're giving away, you can publish the source and instruct users to upload it to their own accounts.
If you're selling the app, displaying ads or otherwise trying to monetize the service, you probably want to stick with one instance. Using multiple instances to avoid paying for quota usage is direct violation of the App Engine TOS:
4.4. You may not develop multiple Applications to simulate or act as a
single Application or otherwise access
the Service in a manner intended to
avoid incurring fees.
No. Writing an application that deploys other applications is in violation of the terms of service.
Note we don't have any 'hard' limits - those limits that aren't billing enabled can be increased on application to us if you provide a reasonable use-case.

Categories

Resources