1 of 38

API

1

LEVEL -9

2 of 38

2

API Basics

An API, or Application Programming Interface, is a server that you can use to retrieve and send data to using code. APIs are most commonly used to retrieve data

 

 

When we want to receive data from an API, we need to make a request. Requests are used all over the web. For instance, when you visited this blog post, your web browser made a request to the Dataquest web server, which responded with the content of this web page.

3 of 38

Making API Requests in Python

In order to work with APIs in Python, we need tools that will make those requests. In Python, the most common library for making requests and working with APIs is the requests library. The requests library isn’t part of the standard Python library, so you’ll need to install it to get started.

pip install requests

Once you’ve installed the library, you’ll need to import it. Let’s start with that important step:

import requests

4 of 38

Making Our First API Request

There are many different types of requests. The most commonly used one, a GET request, is used to retrieve data.

When we make a request, the response from the API comes with a response code which tells us whether our request was successful. Response codes are important because they immediately tell us if something went wrong.

To make a ‘GET’ request, we’ll use the requests.get(url) function

We’ll start by making a request to an API endpoint that doesn’t exist, so we can see what that response code looks like.

import requests

response = requests.get("https://randomuser.me/api/")

print(response)

>>> <Response [200]>

In this small example, you import the requests library and then fetch (or get) data from the URL for the Random User Generator API. But you don’t actually see any of the data returned. What you get instead is a Response [200], which in API terms means everything went OK.

5 of 38

Now change the url api to api1. now ap1 is not available in url.

response = requests.get("https://randomuser.me/api1/")

>>> <Response [404]>

The ‘404’ status code might be familiar to you — it’s the status code that a server returns if it can’t find the file we requested

Before you move forward, one thing you need to know about endpoints is the difference between http:// and https://. In a nutshell, HTTPS is the encrypted version of HTTP, making all traffic between the client and the server much safer. When consuming public APIs, you should definitely stay away from sending any private or sensitive information to http:// endpoints and use only those APIs that provide a secure https:// base URL.

6 of 38

Request and Response

As you very briefly read above, all interactions between a client—in this case your Python console—and an API are split into a request and a response:

Requests contain relevant data regarding your API request call, such as the base URL, the endpoint, the method used, the headers, and so on.

Responses contain relevant data returned by the server, including the data or content, the status code, and the headers.

import requests

response = requests.get("https://api.thedogapi.com/v1/breeds")

print(response)#<Response [200]>

print(response.text) #'[{"weight":{"imperial":"6 - 13","metric":"3 - 6"},"height": {"imperial":"9 - 11.5","metric":"23 29"},"id":1,"name":“ Affenpinscher", ...}]'

print(response.status_code)#200

print(response.headers) #{'Cache-Control': 'post-check=0, pre-check=0', 'Content-Encoding': 'gzip',

#'Content-Type': 'application/json; charset=utf-8','Date': 'Sat, 25 Jul 2020 17:23:53 GMT'...}

print(response.reason)

request = response.request

print(request)#<PreparedRequest [GET]>

print(request.url)#'https://api.thedogapi.com/v1/breeds'

print(request.path_url)#'/v1/breeds'

print(request.method)#'GET'

print(request.headers) #{'User-Agent': 'python-requests/2.24.0', 'Accept-Encoding': 'gzip, deflate','Accept': '*/*', 'Connection': 'keep-alive'}

7 of 38

Status Codes

Status codes are one of the most important pieces of information to look for in any API response. They tell you if your request was successful, if it’s missing data, if it’s missing credentials, and so on.

With time, you’ll recognize the different status codes without help. But for now, here’s a list with some of the most common status codes you’ll find:

Status code

Description

200 OK

Your request was successful!

201 Created

Your request was accepted and the resource was created.

400 Bad Request

Your request is either wrong or missing some information.

401 Unauthorized

Your request requires some additional permissions.

404 Not Found

The requested resource does not exist.

405 Method Not Allowed

The endpoint does not allow for that specific HTTP method.

500 Internal Server Error

Your request wasn’t expected and probably broke something on the server side.

8 of 38

Response Content

As you just learned, the type of content you find in the API response will vary according to the Content-Type header. To properly read the response contents according to the different Content-Type headers, the requests package comes with a couple of different Response attributes you can use to manipulate the response data:

.text returns the response contents in Unicode format.

.content returns the response contents in bytes.

You already used the .text attribute above. But for some specific types of data, like images and other nontextual data, using .content is typically a better approach, even if it returns a very similar result to .text:

response = requests.get("https://api.thedogapi.com/v1/breeds/1")

print(response.headers.get("Content-Type"))

#'application/json; charset=utf-8'

print(response.content)

#b'{"weight":{"imperial":"6 - 13","metric":"3 - 6"}...'

print(response.json())

#{'weight': {'imperial': '6 - 13', 'metric': '3 - 6'},'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'}...}

print(response.json()["name"])

9 of 38

response = requests.get("http://placegoat.com/200/200")

print(response.headers.get("Content-Type"))

print(response.content)

file = open(r"C:\Users\Kokila\Desktop\practice\goat.jpeg", "wb")

file.write(response.content)

file.close()

10 of 38

HTTP Method

Description

Requests method

POST

Create a new resource.

requests.post()

GET

Read an existing resource.

requests.get()

PUT

Update an existing resource.

requests.put()

DELETE

Delete an existing resource.

requests.delete()

HTTP Methods

When calling an API, there are a few different methods, also called verbs, that you can use to specify what action you want to execute. For example, if you wanted to fetch some data, you’d use the method GET, and if you wanted to create some data, then you’d use the method POST.

When purely consuming data using APIs, you’ll typically stick to GET requests,

but here’s a list of the most common methods and their typical use case:

These four methods are typically referred to as CRUD operations as they allow you to create, read, update and delete resources.

11 of 38

Query Parameters

Sometimes when you call an API, you get a ton of data that you don’t need or want. For example, when calling TheDogAPI’s /breeds endpoint, you get a lot of information about a given breed. But in some cases, you might want to extract only certain information about a given breed. That’s where query parameters come in!

print(requests.get("https://randomuser.me/api/").json())

print(requests.get("https://randomuser.me/api/?gender=female").json())

print(requests.get("https://randomuser.me/api/?gender=female&nat=de").json())

query_params = {"gender": "female", "nat": "de"}

print(requests.get("https://randomuser.me/api/", params=query_params).json())

12 of 38

      • https://realpython.com/python-api/

References

13 of 38

Api Creation

14 of 38

CDSID: lvishwan

14

�How to create an API in Python

There are different ways to create an API in Python, the most used being FastAPI and Flask. So, I will explain how both work, so that you can use the way to create APIs in Python that you like the most. Let’s start with FastAPI.

How to create an API in Python with FastAPI

Requirements to use FastAPI

FastAPI is a way of creating APIs in Python that came out at the end of 2018. It is very fast, although it can only be used with Python 3.6+ (in my opinion this should not be a problem, but it is important).

To use it, you must install two libraries: fastapi and uvicorn 

15 of 38

Your first Python API with FastAPI

Now that we have installed the packages, we simply have to create a file in Python where we will define our API. In this file, we must create an app, where we will include the APIs, with their endpoints, parameters, etc.

Once we have the app, that’s where we define the information that the API requires: endpoint, HTTP method, input arguments and what the API will do behind it.

from fastapi import FastAPI

app = FastAPI()

@app.get("/my-first-api")

def hello():

return {"Hello world!"}

16 of 38

Check the operation of a FastAPI API

As I said at the beginning of this section, to create an API in FastAPI we must include our code in a Python file, preferably main.py. Also, we must have uvicorn installed. Taking this into account, we can run our API in a very simple way, with the following code:

uvicorn main:app - -reload

This will run our application and we will be able to access our API, both at the browser level and by making calls from our computer. The API has not been uploaded anywhere yet, so it will be accessible from localhost. You can access the localhost both in http://127.0.0.1/ and in http://localhost/, although you will have to do it in the same port that is running the API. To find out, in my opinion, the easiest thing is to use the link that uvicorn will give you when executing the API:

17 of 38

With this we would already have a very simple API created, which simply returns “Hello world!”. As you will see, in a few lines we have defined: the method (get), the endpoint (“/”) and the function that this API should run.

We could even pass arguments to our API, for it to use in its function. Whenever we pass an argument to our function we must indicate the type of data that it must be (number, text, etc.).

Important : FastAPI performs a check that the type of data that we pass to it in the call is what we have indicated it should be. This is essential to ensure that our API works properly, and it is something that other API creation frameworks (like Flask) do not include.

@app.get("/my-second-api")

def hello(name: str):

return {'Hello ' + name + '!'}

Simple API

>>> http://127.0.0.1:8000/my-second-api >>>

{"detail":[{"loc":["query","name"],"msg":"field required","type":"value_error.missing"}]}

Api with arguments

@app.get("/my-second-api")

def hello(name: str):

return {'Hello ' + name + '!'}

http://127.0.0.1:8000/my-second-api?name=Ander >>>

["Hello Ander!"]

18 of 38

Return other data types:

@app.get("/get-iris")

def get_iris():

import pandas as pd

url ='https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/ 0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv'

iris = pd.read_csv(url)

return iris

19 of 38

Streaming response

from fastapi.responses import FileResponse

@app.get("/plot-iris")

def plot_iris():

import pandas as pd

import matplotlib.pyplot as plt

url ='https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv'

iris = pd.read_csv(url)

plt.scatter(iris['sepal_length'], iris['sepal_width'])

plt.savefig('iris.png')

return FileResponse('iris.png')

20 of 38

Get data from API

import requests

from PIL import Image

import io

resp = requests.get('http://127.0.0.1:8000/plot-iris')

print(resp.content)

file = io.BytesIO(resp.content)

im = Image.open(file)

im.show()

import requests

resp = requests.get('http://127.0.0.1:8000/my-second-api?name=Viswa')

print(resp.text)

21 of 38

http://127.0.0.1:8000/docs

http://127.0.0.1:8000/redoc

You will see the automatic interactive API documentation

You will see the alternative automatic documentation

22 of 38

Cross-Origin Resource Sharing (CORS)

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.

23 of 38

Overcome CORS issue in Flask

from flask import Flask,render_template,request

app = Flask(__name__)

import smtplib

import random

@app.after_request

def after_request(response):

response.headers.add('Access-Control-Allow-Origin', '*')

response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')

response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')

return response

24 of 38

from fastapi import FastAPI

from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [

"http://localhost.tiangolo.com",

"https://localhost.tiangolo.com",

"http://localhost",

"http://localhost:8080",

]

app.add_middleware(

CORSMiddleware,

allow_origins=origins,

allow_credentials=True,

allow_methods=["*"],

allow_headers=["*"],

)

@app.get("/")

async def main():

return {"message": "Hello World"}

Overcome CORS issue in Fast-Api

25 of 38

26 of 38

google API: google sheet as database

import gspread

gc=gspread.service_account(filename='creds.json')

sh=gc.open('database').sheet1

sh.update('A1','test')

pre request:

  • goto google developer
  • create new project
  • goto google drive api & enable
  • goto sheets api & enable
  • goto credential→ create credential → service account → account name → create→ done
  • Edit →add key→ json → save file in py current directory
  • add sheet and share to created account
  • Run python file

27 of 38

Workbook

  • sh = gc.create('A new spreadsheet')
  • sh.share('otto@example.com', perm_type='user', role='writer')
  • sh = gc.open("Example spreadsheet")

work sheet

  • worksheet = sh.get_worksheet(0)
  • worksheet_list = sh.worksheets()
  • worksheet = sh.add_worksheet(title="A worksheet", rows="100", cols="20")
  • sh.del_worksheet(worksheet)

Rows

  • sh.resize(1) Delete all rows above
  • LR=len(sh.get_all_values())
  • values_list = worksheet.row_values(1)
  • sh.append_row(['a','b'])

columns

  • values_list = worksheet.col_values(1)

cell

  • val = worksheet.cell(1, 2).value
  • worksheet.update_cell(1, 2, 'Bingo!')
  • cell form= worksheet.cell(1, 2, value_render_option='FORMULA').value

cells

  • list_of_lists = worksheet.get_all_values()
  • list_of_dicts = worksheet.get_all_records()

28 of 38

  • cell = worksheet.find("Dough")
  • print("Found something at R%sC%s" % (cell.row, cell.col))
  • cell_list = worksheet.findall("Rug store")
  • worksheet.batch_clear(["A1:B1", "C2:E2", "my_named_range"])
  • worksheet.clear()

Utils:

  • rowcol_to_a1(1, 1)
  • a1_to_rowcol('A1')
  • a1_range_to_grid_range('A1:A1')
  • a1_range_to_grid_range('A:B')
  • a1_range_to_grid_range('A5:B')
  • a1_range_to_grid_range('1')
  • a1_range_to_grid_range('A1', sheet_id=0)
  • is_scalar(42)

29 of 38

cell format:

worksheet.format("A2:B2", { "backgroundColor": { "red": 0.0, "green": 0.0, "blue": 0.0 }, "horizontalAlignment": "CENTER", "textFormat": { "foregroundColor": { "red": 1.0, "green": 1.0, "blue": 1.0 }, "fontSize": 12, "bold": True } })

Pandas:

import pandas as pd

dataframe = pd.DataFrame(worksheet.get_all_records())

worksheet.update([dataframe.columns.values.tolist()] + dataframe.values.tolist())

array:

array = np.array(worksheet.get_all_values())

array = np.array([[1, 2, 3], [4, 5, 6]])

worksheet.update('A2', array.tolist())

30 of 38

Example code:

creds={

"type": "service_account",

"project_id": "logical-veld-278011",

"private_key_id": "d3bb3c92ce1fda6f048f740ca57f120aa63c7016",

"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0iyWUEkkA2uJw\n9+Y1pyAFlKsN5PAz5DYLExM8mBabYou0i2fKm7FIYzmXMuEKqAvrdlKKqiDBF3V/\nOAB0vr/vUsuc20QL8FVIXmz3yAqbujDYPoKU53enezaQRknyZNQPVK4lhXJXDORh\nyOpXrsy4AF1AN8ZQZtgnKGd3pFTc2ccmi1JWNyx0ZWsDo2rZwWOTwieBkqb2yf4n\nvFFDyeEqAHy1YHgjxKFX37h+6c7aQp6eomjie4nHX8qHUqNLolKbKnIpkASBmsLk\nlbIblKpsQy50oJrkcFRBykaQMoTrPqlWRrou5HejLg57reEHI5zw2hH4/TEpc0ve\n15gW2FA7AgMBAAECggEAUVZ9BBQm0p1KNhXhH5vfF9SOKdDSDLbMSDn8SSjFypRf\nl2PUy1lQSen2GLHB5DCoShkA/9q8rfFZLIr43Z/QTcxR0iWQpwZMDbIIyqrTaKw9\n9DZZUydi50/h2abpCqy1QwDmAh54UFKNE6bWONGWBnGXkWZvUGq9CAsybhrZZrNu\nqSCttUVW2wika9eQfuzgHiAKZ7hoD8xF9GlgjzMb0jGq5blP/DDX6Ma8q+gB2q2A\nZhSXEMZr7v88yZKdSRQXDesCl2PQMNlHhUTtzgigpuzmC48aAcdgPXRprK8xIRau\nzKqv5qpI+pLHnhFEHMHdQibwE2coNHt9XESlbmcv6QKBgQDews5bcEBhyI0aZCFZ\nkKyS6PvUL92pTrMEE7ty0/8q7MoSJL4vgRruRa3Et4sjpHA0CQJBI6w/wSF83A5k\nHHhncLdykFQG6evItpndRFG2DBFo7IBSFJhjOi1XI2wHmFkVd0aeqnpLFZYXV3aY\nlzN+jUWHZzMHFaLjrXD9a/de+QKBgQDPe6/4BYURlXU1Hte96iZBYP3xIwbdGOKl\n/Gh9bSwB5APjaAGxGOLhYQe1ziuUgmRiEKWNJc5t0Rm/CGEvjLk6M5DOs8r2LYf7\nosaAxtGOZKniR3BUY1RJ9tfPm5agNhutkT1KQtNKDAP4yBEzYGEGg8NpcOVw08W1\ngV05rvqR0wKBgQDUO/Yv2Dr+7vzA8DV2CAjjz2ZfO1uNO5YDhGlLdf/e/ctojelF\niVQHQAvXKKhARSNB8HNdbIdoFrG5LE/pwdZVd2bQmAH2tFgY2yCtV7IiKE1OEkYP\n7d9iasNYCj+a3OPDN+josrPhZaeihYpQx34gTKi54PEVBuAy28STLpJ4wQKBgHUJ\naDGXq4BHtl3IkBnowruOYrBq+awuJWtL/gUCWBiY7jiQqqOjThekDB1ZtuuGwekv\nSrNb6B26HbPMnkWcM7/I5p4yfQJwnIwtPZvWis6vqcSiV5LClQFD5GiPc1/cJbC6\nhMAnAdh6/qKO+GTqsNBj8w6/SC1kx9mip1uqgF1RAoGAKUUE8uyLLlV9KmgxvD2P\nuNPC4pwY9kaMG5WUyceDY64pvuALefbX95qPaK0mX1YBVKEiNrtj2MkTFeOImEOr\npWP+OWX+L9rtKpglwrZwdfKeevpWv5pMqHn9mFWsoq0Th1cgEcFnvz7BSdwQhSO0\nGnLyEuiHI8lPzr6BccqXu2Q=\n-----END PRIVATE KEY-----\n",

"client_email": "gspreadscraper@logical-veld-278011.iam.gserviceaccount.com",

"client_id": "112845638206064996927",

"auth_uri": "https://accounts.google.com/o/oauth2/auth",

"token_uri": "https://oauth2.googleapis.com/token",

"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",

"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspreadscraper%40logical-veld-278011.iam.gserviceaccount.com"

}

gc=gspread.service_account_from_dict(creds)

31 of 38

from flask import Flask,render_template,request

app = Flask(__name__)

import smtplib

import random

import gspread

gc=gspread.service_account(filename='creds.json')

@app.route('/signup',methods = ["GET","POST"])

def signup():

sh=gc.open('database').sheet1

df={sh.cell(i, 1).value:sh.cell(i, 1).value for i in range(1, sh.row_count + 1)}

if request.form['user'] not in df:

sh.append_row([request.form['user'],request.form['password']])

return 'sucessfully registerd'

else: return 'user name already taken'

32 of 38

Email API

def sendotp(to):

try:

otp=str(random.randint(1000,9999))

smtp = smtplib.SMTP('smtp.gmail.com', 587)

smtp.starttls()

smtp.login('visandreams@gmail.com','rturkuqbgicwaqaw')

message = 'Subject: {}'.format("your otp is:"+otp)

smtp.sendmail('visandreams@gmail.com', to,message)

smtp.quit()

return otp

except Exception as e:

return e

@app.route('/send_otp',methods = ["GET","POST"])

def send_otp():

data = request.args

otp=sendotp(data['to'])

return otp

33 of 38

def get_list_files():

from google.oauth2 import service_account

from getfilelistpy import getfilelist

SCOPES = ['https://www.googleapis.com/auth/drive']

SERVICE_ACCOUNT_FILE = 'creds.json'

credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)

topFolderId ='13SVxB_BMYPPjno9-GbOAkjjZ8BMbFKRv'

resource = {"service_account": credentials,"id": topFolderId,"fields": "files(name,id)",}

res = getfilelist.GetFileList(resource)

print(dict(res)['totalNumberOfFiles'])

Pre requirements:

  • generate credential json file
  • share folder
  • get folder id

Google drive API

get file list in folder

34 of 38

Upload files:

import json

import requests

def upload(file):

token='ya29.a0ARrdaM9vMfvCVe4_a6QRSWYs2QUlGA1o8BO-HgYc5m-zxAAZ7iSSG9GfeRvW1UoqVrkpZHNIVqLKrc2xgGt-X6f1t5ZM2VTYlzszUETBOKJBdwdnDzSHzbiVWeSq0_D5Kwy4RUJCNAfpqgryX4qindcqLIrP'

headers = {"Authorization": "Bearer "+token}

para = {"name": "samplefile.png","parents":["13SVxB_BMYPPjno9-GbOAkjjZ8BMbFKRv"]}

files = {'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),'file': open(file, "rb")}

r = requests.post("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",headers=headers,files=files)

print (r.text)

upload(file="D:/3d.png")

prerequisite: enable Google API & get authorization key- oAuth2.0 playground

<ref:https://www.youtube.com/watch?v=JwGzHitUVcU>

35 of 38

36 of 38

Google map Api

37 of 38

Whats app Api

38 of 38

Sms Api