1

I am trying to short an URL using Google API but using only the requests module.

The code looks like this:

import requests

Key = "" # found in https://developers.google.com/url-shortener/v1/getting_started#APIKey

api = "https://www.googleapis.com/urlshortener/v1/url"

target = "http://www.google.com/"

def goo_shorten_url(url=target):
  payload = {'longUrl': url, "key":Key}
  r = requests.post(api, params=payload)

print(r.text)

When I run goo_shorten_url it returns:

 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Required",
    "locationType": "parameter",
    "location": "resource.longUrl"
   }

  ],
  "code": 400,
  "message": "Required"
 }

But the longUrl parameter is there!

What am I doing wrong?

zeh
  • 1,197
  • 2
  • 14
  • 29

3 Answers3

1

At first, please confirm that "urlshortener api v1" is enabled at Google API Console.

Content-Type is required as a header. And please use data as a request parameter. The modified sample is as follows.

Modified sample :

import json
import requests

Key = "" # found in https://developers.google.com/url-shortener/v1/getting_started#APIKey

api = "https://www.googleapis.com/urlshortener/v1/url"

target = "http://www.google.com/"

def goo_shorten_url(url=target):
  headers = {"Content-Type": "application/json"}
  payload = {'longUrl': url, "key":Key}
  r = requests.post(api, headers=headers, data=json.dumps(payload))

print(r.text)

If above script doesn't work, please use an access token. The scope is https://www.googleapis.com/auth/urlshortener. In the case of use of access token, the sample script is as follows.

Sample script :

import json
import requests

headers = {
    "Authorization": "Bearer " + "access token",
    "Content-Type": "application/json"
}
payload = {"longUrl": "http://www.google.com/"}
r = requests.post(
    "https://www.googleapis.com/urlshortener/v1/url",
    headers=headers,
    data=json.dumps(payload)
)
print(r.text)

Result :

{
 "kind": "urlshortener#url",
 "id": "https://goo.gl/#####",
 "longUrl": "http://www.google.com/"
}

Added 1 :

In the case of use tinyurl.com

import requests

URL = "http://www.google.com/"
r = requests.get("http://tinyurl.com/" + "api-create.php?url=" + URL)
print(r.text)

Added 2 :

How to use Python Quickstart

You can use Python Quickstart. If you don't have "google-api-python-client", please install it. After installed it, please copy paste a sample script from "Step 3: Set up the sample", and create it as a python script. Modification points are following 2 parts.

1. Scope

Before :

SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'

After :

SCOPES = 'https://www.googleapis.com/auth/urlshortener'

2. Script

Before :

def main():
    """Shows basic usage of the Google Drive API.

    Creates a Google Drive API service object and outputs the names and IDs
    for up to 10 files.
    """
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('drive', 'v3', http=http)

    results = service.files().list(
        pageSize=10,fields="nextPageToken, files(id, name)").execute()
    items = results.get('files', [])
    if not items:
        print('No files found.')
    else:
        print('Files:')
        for item in items:
            print('{0} ({1})'.format(item['name'], item['id']))

After :

def main():
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('urlshortener', 'v1', http=http)
    resp = service.url().insert(body={'longUrl': 'http://www.google.com/'}).execute()
    print(resp)

After done the above modifications, please execute the sample script. You can get the short URL.

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Where do I get an access token? Is the api key? The json version also was not working. I just posted the simpler version of the problem – zeh Apr 14 '17 at 12:16
  • I'm sorry for my poor answer. I have posted how to get access token before. Please check it. That is used python. http://stackoverflow.com/questions/42815450/refresh-google-drive-access-token/42822060#42822060 – Tanaike Apr 14 '17 at 23:39
  • Thank you for the link. I'll try to put an working example from that. Any idea how to use the Service Account instead of OAuth? – zeh Apr 15 '17 at 02:07
  • In order to use API, API key and OAuth are required for the most cases. For example, if you use quick start (https://developers.google.com/drive/v3/web/quickstart/python) of Google for python, I think taht the OAuth process will be simple. If you will use this, I can prepare a sample script. Please tell me. – Tanaike Apr 15 '17 at 02:48
  • @zeh Now I found this. Using ``tinyurl.com``, it seems that an URL can be easily shorten. I tried this. It works fine. I edited above my answer. Please check it. – Tanaike Apr 15 '17 at 03:23
  • Oh, thank you. I tried to edit your answer to make it complete but stackoverflow said that I changed too much. I posted another answer which is basically your answer with my comments. Not sure how to proceed. In any case, could you add this other way using QuickStart? (Maybe putting everything in again new answer so I can accept). Thank you. – zeh Apr 15 '17 at 07:34
  • @zeh No problem. I updated my answer just now. I added about How to use Python Quickstart as "added 2". Please confirm it. – Tanaike Apr 15 '17 at 07:53
  • Btw, I think we agree that it is not possible to use the API ONLY with requests. Right? – zeh Apr 15 '17 at 08:11
0

I am convinced that one CANNOT use ONLY requests to use google api for shorten an url.

Below I wrote the solution I ended up with,

It works, but it uses google api, which is ok, but I cannot find much documentation or examples about it (Not as much as I wanted).

To run the code remember to install google api for python first with pip install google-api-python-client, then:

import json

from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build

scopes = ['https://www.googleapis.com/auth/urlshortener']

path_to_json = "PATH_TO_JSON" 
#Get the JSON file from Google Api [Website]
(https://console.developers.google.com/apis/credentials), then:
# 1. Click on Create Credentials. 
# 2. Select "SERVICE ACCOUNT KEY". 
# 3. Create or select a Service Account and 
# 4. save the JSON file.   

credentials = ServiceAccountCredentials.from_json_keyfile_name(path_to_json, scopes)

short = build("urlshortener", "v1",credentials=credentials)

request = short.url().insert(body={"longUrl":"www.google.com"})
print(request.execute())

I adapted this from Google's Manual Page.

The reason it has to be so complicated (more than I expected at first at least) is to avoid the OAuth2 authentication that requires the user (Me in this case) to press a button (to confirm that I can use my information).

zeh
  • 1,197
  • 2
  • 14
  • 29
0

As the question is not very clear this answer is divided in 4 parts.

Shortening URL Using:

1. API Key.

2. Access Token

3. Service Account

4. Simpler solution with TinyUrl.


API Key

At first, please confirm that "urlshortener api v1" is enabled at Google API Console.

Content-Type is required as a header. And please use data as a request parameter. The modified sample is as follows.

(Seems not to be working despite what the API manual says).

Modified sample :

import json
import requests

Key = "" # found in https://developers.google.com/url-shortener/v1/getting_started#APIKey

api = "https://www.googleapis.com/urlshortener/v1/url"

target = "http://www.google.com/"

def goo_shorten_url(url=target):
  headers = {"Content-Type": "application/json"}
  payload = {'longUrl': url, "key":Key}
  r = requests.post(api, headers=headers, data=json.dumps(payload))

print(r.text)

Access Token:

If above script doesn't work, please use an access token. The scope is https://www.googleapis.com/auth/urlshortener. In the case of use of access token, the sample script is as follows.

This answer in Stackoverflow shows how to get an Access Token: Link.

Sample script :

import json
import requests

headers = {
    "Authorization": "Bearer " + "access token",
    "Content-Type": "application/json"
}
payload = {"longUrl": "http://www.google.com/"}
r = requests.post(
    "https://www.googleapis.com/urlshortener/v1/url",
    headers=headers,
    data=json.dumps(payload)
)
print(r.text)

Result :

{
 "kind": "urlshortener#url",
 "id": "https://goo.gl/#####",
 "longUrl": "http://www.google.com/"
}

Using Service Account

To avoid the user need to accept the OAuth authentication (with a pop up screen and all that) there is a solution that uses authentication from machine to machine using a Service Account (As mentioned in another proposed answer).

To run this part of the code remember to install google api for python first with pip install google-api-python-client, then:

import json

from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build

scopes = ['https://www.googleapis.com/auth/urlshortener']

path_to_json = "PATH_TO_JSON" 
#Get the JSON file from Google Api [Website]
(https://console.developers.google.com/apis/credentials), then:
# 1. Click on Create Credentials. 
# 2. Select "SERVICE ACCOUNT KEY". 
# 3. Create or select a Service Account and 
# 4. save the JSON file.   

credentials = ServiceAccountCredentials.from_json_keyfile_name(path_to_json, scopes)

short = build("urlshortener", "v1",credentials=credentials)

request = short.url().insert(body={"longUrl":"www.google.com"})
print(request.execute())

Adapted from Google's Manual Page.

Even simpler:

In the case of use tinyurl.com

import requests

URL = "http://www.google.com/"
r = requests.get("http://tinyurl.com/" + "api-create.php?url=" + URL)
print(r.text)
Community
  • 1
  • 1
zeh
  • 1,197
  • 2
  • 14
  • 29