Kahibaro
Discord Login Register

Very basic APIs

What Is an API (In Practice)?

In this chapter you’ll build very simple APIs with Python and Flask.

You’ve already seen how to create a basic web server and use routes and templates. An API (Application Programming Interface) in web development is just:

A way for programs to talk to your server and get data, usually in a structured format like JSON, instead of a full HTML page.

Key ideas for this chapter:

HTML vs JSON Responses

Until now, your Flask routes probably returned HTML strings or templates:

from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home():
    return render_template("index.html")

An API route usually returns JSON:

from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/api/hello")
def api_hello():
    data = {"message": "Hello from the API!"}
    return jsonify(data)

If you open /api/hello in your browser, you’ll see something like:

{"message": "Hello from the API!"}

Returning JSON with `jsonify`

Flask has a helper called jsonify that:

You pass it standard Python data structures:

Example:

from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/api/user")
def get_user():
    user = {
        "id": 1,
        "name": "Alice",
        "is_active": True
    }
    return jsonify(user)

You can also return a list:

@app.route("/api/users")
def get_users():
    users = [
        {"id": 1, "name": "Alice"},
        {"id": 2, "name": "Bob"}
    ]
    return jsonify(users)

A Minimal API-Only Flask App

Here is a tiny app that exposes only APIs (no HTML pages):

from flask import Flask, jsonify
app = Flask(__name__)
# Simple "status" endpoint
@app.route("/api/status")
def status():
    return jsonify({"status": "ok"})
# Some dummy data
BOOKS = [
    {"id": 1, "title": "Python Basics"},
    {"id": 2, "title": "Flask for Beginners"},
]
@app.route("/api/books")
def get_books():
    return jsonify(BOOKS)
if __name__ == "__main__":
    app.run(debug=True)

Start this app and visit in your browser (or with curl):

You’ll see JSON responses.

Using Path Parameters

APIs often include values inside the URL, like /api/books/2.

Flask lets you capture parts of the URL as parameters:

from flask import Flask, jsonify
app = Flask(__name__)
BOOKS = [
    {"id": 1, "title": "Python Basics"},
    {"id": 2, "title": "Flask for Beginners"},
]
@app.route("/api/books/<int:book_id>")
def get_book(book_id):
    for book in BOOKS:
        if book["id"] == book_id:
            return jsonify(book)
    # Book not found
    return jsonify({"error": "Book not found"}), 404

Notes:

Try:

Using Query Parameters (`?key=value`)

Another way to pass data to an API is via query parameters, e.g.:

You read them with request.args:

from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route("/api/echo")
def echo():
    # Get the 'text' query parameter: /api/echo?text=hello
    text = request.args.get("text", "")  # default to empty string
    return jsonify({"you_sent": text})

Visit:

You’ll see the value you sent in the URL.

Basic HTTP Methods: GET vs POST

So far, all routes used the default GET method (usually to get data).

APIs also commonly use POST to send data to the server (e.g. creating something).

In Flask, you specify allowed methods:

from flask import Flask, jsonify, request
app = Flask(__name__)
messages = []
@app.route("/api/messages", methods=["GET"])
def list_messages():
    return jsonify(messages)
@app.route("/api/messages", methods=["POST"])
def create_message():
    text = request.form.get("text", "")
    if not text:
        return jsonify({"error": "Missing 'text'"}), 400
    message = {"id": len(messages) + 1, "text": text}
    messages.append(message)
    return jsonify(message), 201

For now, you can test POSTs using tools like:

Example with curl (optional):

curl -X POST -F "text=Hello API" http://127.0.0.1:5000/api/messages

Sending and Receiving JSON in POST

Instead of sending form data, many APIs send JSON in the request body.

In Flask, you can access JSON data with request.get_json():

from flask import Flask, jsonify, request
app = Flask(__name__)
todos = []
@app.route("/api/todos", methods=["GET"])
def get_todos():
    return jsonify(todos)
@app.route("/api/todos", methods=["POST"])
def add_todo():
    data = request.get_json()
    if not data or "title" not in data:
        return jsonify({"error": "JSON with 'title' required"}), 400
    todo = {
        "id": len(todos) + 1,
        "title": data["title"],
        "done": False
    }
    todos.append(todo)
    return jsonify(todo), 201

Example JSON you might send:

{"title": "Learn basic APIs"}

Basic Status Codes

An API response has:

  1. Body (JSON we return)
  2. Status code (numeric HTTP code)

Common ones you’ll use:

In Flask, you set the status code by returning a tuple:

return jsonify({"error": "Item not found"}), 404

Keep it simple for now: use 200 or 201 on success, 400 or 404 on basic errors.

A Tiny “Todo API” Example

Here’s a small but complete example combining everything:

from flask import Flask, jsonify, request
app = Flask(__name__)
todos = [
    {"id": 1, "title": "Learn Flask", "done": False},
]
@app.route("/api/todos", methods=["GET"])
def list_todos():
    return jsonify(todos)
@app.route("/api/todos/<int:todo_id>", methods=["GET"])
def get_todo(todo_id):
    for todo in todos:
        if todo["id"] == todo_id:
            return jsonify(todo)
    return jsonify({"error": "Todo not found"}), 404
@app.route("/api/todos", methods=["POST"])
def create_todo():
    data = request.get_json()
    if not data or "title" not in data:
        return jsonify({"error": "JSON with 'title' required"}), 400
    new_id = max([t["id"] for t in todos], default=0) + 1
    todo = {"id": new_id, "title": data["title"], "done": False}
    todos.append(todo)
    return jsonify(todo), 201
if __name__ == "__main__":
    app.run(debug=True)

This is not production-ready, but:

How Another Program Could Use Your API

Imagine a Python script using your API (instead of calling functions directly). It might use the requests library like this:

import requests
response = requests.get("http://127.0.0.1:5000/api/status")
data = response.json()
print(data["status"])

You don’t need to build this script now, but it shows what APIs are for:

Your Flask app becomes a service that other programs can call.

Practice Ideas

Try adding and testing these simple API features:

  1. Add /api/time that returns the current time as JSON.
  2. Extend the books API:
    • /api/books/search?title=python – return only matching books.
  3. Add a field update route for todos:
    • e.g. /api/todos/<id>/complete that marks a todo as done (you can use POST for now).

Keep things small: a few routes, clear JSON, simple code. The goal here is to feel comfortable with:

Views: 15

Comments

Please login to add a comment.

Don't have an account? Register now!