zeh
zeh

Reputation: 1317

How to Short an URL using Google API and REQUESTS?

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?

Upvotes: 1

Views: 6017

Answers (3)

Tanaike
Tanaike

Reputation: 201388

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.

Upvotes: 1

zeh
zeh

Reputation: 1317

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)

Upvotes: 0

zeh
zeh

Reputation: 1317

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).

Upvotes: 0

Related Questions