
Python
Now that you understand how to consume APIs, let's create your own! Building APIs allows you to expose your application's functionality to other developers. REST APIs using Flask are an excellent way to get started with API development.
An API server is a program that listens for requests and responds with data. It follows the same REST principles you learned about earlier, but now you're on the server side, not the client side.
# This is what you'll be building
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/hello')
def hello():
return jsonify({'message': 'Hello from my API!'})
# Client requests this:
# GET http://localhost:5000/api/hello
# Client receives: {"message": "Hello from my API!"}Flask is a lightweight web framework perfect for building APIs:
# Installation
pip install flaskfrom flask import Flask
# Create Flask application
app = Flask(__name__)
# Define an endpoint
@app.route('/api/hello', methods=['GET'])
def hello():
return {'message': 'Hello World'}
# Run the server
if __name__ == '__main__':
app.run(debug=True, port=5000)
# Visit http://localhost:5000/api/hello in browser or curl:
# curl http://localhost:5000/api/hello
# Response: {"message":"Hello World"}Endpoints are URLs that clients can request. Each endpoint represents a resource or action.
from flask import Flask, jsonify
app = Flask(__name__)
# Sample data
users = [
{'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},
{'id': 2, 'name': 'Bob', 'email': 'bob@example.com'},
{'id': 3, 'name': 'Carol', 'email': 'carol@example.com'}
]
# Get all users
@app.route('/api/users', methods=['GET'])
def get_all_users():
return jsonify(users)
# Get single user
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
user = next((u for u in users if u['id'] == user_id), None)
if not user:
return jsonify({'error': 'User not found'}), 404
return jsonify(user)
# Get user by email
@app.route('/api/users/search/<email>', methods=['GET'])
def search_user(email):
user = next((u for u in users if u['email'] == email), None)
if not user:
return jsonify({'error': 'User not found'}), 404
return jsonify(user)
if __name__ == '__main__':
app.run(debug=True)
# Test with:
# curl http://localhost:5000/api/users
# curl http://localhost:5000/api/users/1
# curl http://localhost:5000/api/users/search/alice@example.comfrom flask import Flask, jsonify, request
app = Flask(__name__)
users = [
{'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},
]
next_id = 2
# Create new user
@app.route('/api/users', methods=['POST'])
def create_user():
global next_id
# Get JSON data from request
data = request.get_json()
# Validate required fields
if not data or 'name' not in data or 'email' not in data:
return jsonify({'error': 'Missing required fields'}), 400
# Create new user
new_user = {
'id': next_id,
'name': data['name'],
'email': data['email']
}
users.append(new_user)
next_id += 1
# Return created user with 201 status
return jsonify(new_user), 201
if __name__ == '__main__':
app.run(debug=True)
# Test with curl:
# curl -X POST http://localhost:5000/api/users \
# -H "Content-Type: application/json" \
# -d '{"name": "Dave", "email": "dave@example.com"}'from flask import Flask, jsonify, request
app = Flask(__name__)
users = [
{'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},
{'id': 2, 'name': 'Bob', 'email': 'bob@example.com'},
]
# Update entire user
@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
user = next((u for u in users if u['id'] == user_id), None)
if not user:
return jsonify({'error': 'User not found'}), 404
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
# Update fields
user['name'] = data.get('name', user['name'])
user['email'] = data.get('email', user['email'])
return jsonify(user)
if __name__ == '__main__':
app.run(debug=True)
# Test with:
# curl -X PUT http://localhost:5000/api/users/1 \
# -H "Content-Type: application/json" \
# -d '{"name": "Alice Smith", "email": "alice.smith@example.com"}'from flask import Flask, jsonify
app = Flask(__name__)
users = [
{'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},
{'id': 2, 'name': 'Bob', 'email': 'bob@example.com'},
]
# Delete user
@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
global users
user = next((u for u in users if u['id'] == user_id), None)
if not user:
return jsonify({'error': 'User not found'}), 404
users = [u for u in users if u['id'] != user_id]
return jsonify({'message': 'User deleted'}), 204
if __name__ == '__main__':
app.run(debug=True)
# Test with:
# curl -X DELETE http://localhost:5000/api/users/1from flask import Flask, jsonify, request
from typing import List, Dict, Optional
app = Flask(__name__)
# In-memory data store
users: List[Dict] = [
{'id': 1, 'name': 'Alice', 'email': 'alice@example.com', 'role': 'admin'},
{'id': 2, 'name': 'Bob', 'email': 'bob@example.com', 'role': 'user'},
]
next_id = 3
# Helper functions
def get_user_by_id(user_id: int) -> Optional[Dict]:
"""Find user by ID"""
return next((u for u in users if u['id'] == user_id), None)
def validate_user_data(data: Dict) -> tuple[bool, str]:
"""Validate user data"""
if not data:
return False, 'No data provided'
if 'name' not in data or not data['name']:
return False, 'Name is required'
if 'email' not in data or not data['email']:
return False, 'Email is required'
return True, 'Valid'
# Routes
@app.route('/api/users', methods=['GET'])
def list_users():
"""Get all users"""
return jsonify(users), 200
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
"""Get single user by ID"""
user = get_user_by_id(user_id)
if not user:
return jsonify({'error': 'User not found'}), 404
return jsonify(user), 200
@app.route('/api/users', methods=['POST'])
def create_user():
"""Create new user"""
global next_id
data = request.get_json()
valid, message = validate_user_data(data)
if not valid:
return jsonify({'error': message}), 400
new_user = {
'id': next_id,
'name': data['name'],
'email': data['email'],
'role': data.get('role', 'user')
}
users.append(new_user)
next_id += 1
return jsonify(new_user), 201
@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
"""Update user"""
user = get_user_by_id(user_id)
if not user:
return jsonify({'error': 'User not found'}), 404
data = request.get_json()
valid, message = validate_user_data(data)
if not valid:
return jsonify({'error': message}), 400
user['name'] = data.get('name', user['name'])
user['email'] = data.get('email', user['email'])
user['role'] = data.get('role', user['role'])
return jsonify(user), 200
@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
"""Delete user"""
global users
user = get_user_by_id(user_id)
if not user:
return jsonify({'error': 'User not found'}), 404
users = [u for u in users if u['id'] != user_id]
return '', 204
# Error handling
@app.errorhandler(404)
def not_found(error):
return jsonify({'error': 'Endpoint not found'}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({'error': 'Internal server error'}), 500
if __name__ == '__main__':
app.run(debug=True, port=5000)Handle filtering and pagination with query parameters:
from flask import Flask, jsonify, request
app = Flask(__name__)
users = [
{'id': 1, 'name': 'Alice', 'role': 'admin'},
{'id': 2, 'name': 'Bob', 'role': 'user'},
{'id': 3, 'name': 'Carol', 'role': 'user'},
{'id': 4, 'name': 'Dave', 'role': 'admin'},
]
@app.route('/api/users', methods=['GET'])
def list_users():
"""Get users with filtering and pagination"""
# Get query parameters
role = request.args.get('role') # ?role=admin
page = request.args.get('page', 1, type=int) # ?page=1
limit = request.args.get('limit', 10, type=int) # ?limit=10
# Filter by role
filtered_users = users
if role:
filtered_users = [u for u in filtered_users if u['role'] == role]
# Pagination
start = (page - 1) * limit
end = start + limit
paginated_users = filtered_users[start:end]
return jsonify({
'data': paginated_users,
'total': len(filtered_users),
'page': page,
'limit': limit
})
if __name__ == '__main__':
app.run(debug=True)
# Test:
# curl http://localhost:5000/api/users
# curl http://localhost:5000/api/users?role=admin
# curl http://localhost:5000/api/users?page=2&limit=2from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/docs', methods=['GET'])
def get_docs():
"""API documentation"""
return jsonify({
'title': 'My API',
'version': '1.0',
'endpoints': [
{
'method': 'GET',
'path': '/api/users',
'description': 'Get all users',
'response': '[{"id": 1, "name": "Alice", ...}]'
},
{
'method': 'GET',
'path': '/api/users/<id>',
'description': 'Get user by ID',
'response': '{"id": 1, "name": "Alice", ...}'
},
{
'method': 'POST',
'path': '/api/users',
'description': 'Create new user',
'request_body': '{"name": "Alice", "email": "alice@example.com"}',
'response': '{"id": 1, "name": "Alice", ...}',
'status': 201
}
]
})
if __name__ == '__main__':
app.run(debug=True)| Concept | Remember |
|---|---|
| Flask | Lightweight Python web framework for APIs |
| @app.route() | Decorator that maps URLs to functions |
| methods | List HTTP methods: GET, POST, PUT, DELETE |
| request.get_json() | Get JSON data from request body |
| jsonify() | Convert Python dict to JSON response |
| Status Codes | Return appropriate codes: 200, 201, 400, 404, 500 |
| URL Parameters | Use `<int:id>` to capture from URL |
| Query Parameters | Use `request.args.get()` for ?param=value |
| Error Handling | Return error dicts with appropriate status codes |
Learn the fundamentals of web scraping to extract data from websites.
Ready to practice? Try challenges or explore resources
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward