API Development Guide
Building and integrating APIs with Flask, Ngrok, Pusher, and more
API Basics
APIs (Application Programming Interfaces) allow different software applications to communicate with each other. Here's what you need to know about building and consuming APIs:
Key Concepts:
- Endpoints: URLs that accept requests and return responses
- HTTP Methods: GET, POST, PUT, DELETE, etc.
- Status Codes: 200 OK, 404 Not Found, 500 Server Error, etc.
- Request/Response Headers: Metadata about the communication
- Request Body: Data sent to the API
- Response Body: Data returned by the API
REST API Design
Best practices for designing RESTful APIs:
- Use nouns for resources (/users instead of /getUsers)
- Use HTTP methods appropriately (GET for fetching, POST for creating, etc.)
- Include versioning (/api/v1/users)
- Use proper status codes
- Keep endpoints consistent and intuitive
Example Endpoints:
GET /api/v1/users # List all users
POST /api/v1/users # Create a new user
GET /api/v1/users/{id} # Get a specific user
PUT /api/v1/users/{id} # Update a user
DELETE /api/v1/users/{id} # Delete a user
Flask API Development
Flask is a lightweight Python web framework perfect for building APIs:
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # Enable CORS for all routes
@app.route('/api/v1/users', methods=['GET'])
def get_users():
# Example user data
users = [
{'id': 1, 'name': 'John'},
{'id': 2, 'name': 'Jane'}
]
return jsonify(users)
@app.route('/api/v1/users', methods=['POST'])
def create_user():
data = request.json
# Process the data...
return jsonify({'message': 'User created'}), 201
if __name__ == '__main__':
app.run(debug=True)
Key Flask Features:
- Simple routing with decorators
- Request handling and parsing
- JSON response helpers
- Error handling
- Middleware support
Ngrok - Tunnel to Local Server
Ngrok creates secure tunnels to expose your local server to the internet:
# Start ngrok tunnel
ngrok http 5000 # Expose local port 5000
Benefits:
- Expose local development server to the internet
- Secure HTTPS URLs
- Request inspection and replay
- Custom subdomains (with paid plan)
Pusher - Real-time Communication
Pusher enables real-time bi-directional communication between servers and clients:
Server-side (Python):
import pusher
pusher_client = pusher.Pusher(
app_id='your_app_id',
key='your_key',
secret='your_secret',
cluster='your_cluster'
)
def send_notification(event, data):
pusher_client.trigger('my-channel', event, data)
Client-side (JavaScript):
const pusher = new Pusher('your_key', {
cluster: 'your_cluster'
});
const channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data) {
console.log('Received:', data);
});
API Authentication
Common authentication methods:
- API Keys
- JWT (JSON Web Tokens)
- OAuth 2.0
- Basic Authentication
Example JWT Implementation in Flask:
from flask_jwt_extended import JWTManager, create_access_token, jwt_required
app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'your-secret-key'
jwt = JWTManager(app)
@app.route('/login', methods=['POST'])
def login():
# Verify credentials...
access_token = create_access_token(identity=user_id)
return jsonify({'token': access_token})
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected_route():
return jsonify({'message': 'Access granted'})
Error Handling
Proper error handling in Flask APIs:
from flask import jsonify
class APIError(Exception):
def __init__(self, message, status_code=400):
self.message = message
self.status_code = status_code
@app.errorhandler(APIError)
def handle_api_error(error):
response = jsonify({'error': error.message})
response.status_code = error.status_code
return response
@app.route('/api/v1/resource')
def get_resource():
if not resource_exists:
raise APIError('Resource not found', 404)
return jsonify(resource)
Testing APIs
Tools and methods for API testing:
- Postman for manual testing
- pytest for automated testing
- curl for command-line testing
- Integration tests with real databases
Example pytest Test:
def test_get_users(client):
response = client.get('/api/v1/users')
assert response.status_code == 200
assert len(response.json) > 0
def test_create_user(client):
response = client.post('/api/v1/users',
json={'name': 'Test User'})
assert response.status_code == 201
API Documentation
Tools and formats for documenting APIs:
- OpenAPI (Swagger) Specification
- API Blueprint
- Flask-RESTX for automatic documentation
- Markdown documentation
Example OpenAPI Spec:
openapi: 3.0.0
info:
title: Sample API
version: 1.0.0
paths:
/users:
get:
summary: List all users
responses:
'200':
description: List of users
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'