Hug Overview
Hug is a Python web framework designed to make developing APIs fast and easy.
It aims to be simple, reliable, and high-performance, allowing developers to quickly build robust web services.
In this tutorial, we will explore the history, features, and examples of using Hug web framework.
History
Hug was created by Timothée Peignier in 2014 as a response to the complexity and verbosity of existing web frameworks. The goal was to provide a simple and intuitive way to build APIs with Python.
Since its release, Hug has gained popularity among developers due to its ease of use and focus on performance. It has become a go-to choice for building RESTful services and microservices in Python.
Features of Hug
Hug offers several features that make it a powerful framework for building APIs:
1. Easy to Use
Hug provides a straightforward and intuitive API for defining routes and handling requests. Developers can quickly get started without needing to learn complex concepts or boilerplate code.
Here's an example of a simple Hug API endpoint:
import hug
@hug.get('/hello')
def hello():
return {'message': 'Hello, world!'}
In this example, we define a GET route /hello that returns a JSON response with the message "Hello, world!".
2. Automatic Documentation
Hug automatically generates documentation for your API based on the code you write. This makes it easy to keep your API documentation up to date and accessible to other developers.
You can access the automatically generated documentation by visiting the /doc endpoint of your Hug API.
3. Input and Output Validation
Hug provides built-in support for input and output validation, ensuring that data passed to and returned from your API endpoints is of the expected format.
Here's an example of using input validation in Hug:
import hug
@hug.get('/greet')
def greet(name: hug.types.text):
return f"Hello, {name}!"
In this example, the name parameter is defined as a text type, ensuring that only text values are accepted. If a non-text value is provided, Hug will automatically return a validation error.
4. Content Negotiation
Hug allows you to easily handle different content types, such as JSON, XML, or plain text, based on the client's request. This enables you to build flexible APIs that can respond with the appropriate content type based on the client's needs.
Here's an example of content negotiation in Hug:
import hug
@hug.get('/data')
def get_data():
data = {'message': 'Hello, world!'}
return hug.output_format(data, 'application/json')
In this example, we define a route that returns data as JSON by using the hug.output_format function. However, if the client requests a different content type, Hug will automatically convert the data accordingly.
5. Middleware Support
Hug supports middleware, allowing you to easily extend and modify the behavior of your API. Middleware functions can be used to perform actions before and after processing requests, such as authentication, logging, or error handling.
Here's an example of using middleware in Hug:
import hug
def log_request_middleware(request, response):
print(f'Request: {request.method} {request.url}')
app = hug.API(__name__)
app.http.add_middleware(log_request_middleware)
@hug.get('/hello')
def hello():
return {'message': 'Hello, world!'}
In this example, we define a middleware function log_request_middleware that logs each incoming request. We then add this middleware to our Hug API using the add_middleware method.
Examples of Hug Web Framework
Now let's explore some practical examples of using Hug to build APIs.
Example 1: Todo API
Let's create a simple todo API using Hug. This API will allow users to create, read, update, and delete todos.
import hug
todos = []
@hug.get('/todos')
def get_todos():
return {'todos': todos}
@hug.post('/todos')
def create_todo(todo: hug.types.text):
todos.append(todo)
return {'message': 'Todo created successfully.'}
@hug.put('/todos/{id}')
def update_todo(id: hug.types.number, todo: hug.types.text):
if id < len(todos):
todos[id] = todo
return {'message': 'Todo updated successfully.'}
else:
return {'message': 'Todo not found.'}
@hug.delete('/todos/{id}')
def delete_todo(id: hug.types.number):
if id < len(todos):
del todos[id]
return {'message': 'Todo deleted successfully.'}
else:
return {'message': 'Todo not found.'}
In this example, we define endpoints for getting all todos, creating a new todo, updating an existing todo, and deleting a todo. The todos are stored in a list in memory.
Example 2: Weather API
Let's create an API that fetches the weather forecast for a given location using the OpenWeatherMap API.
import hug
import requests
@hug.get('/weather')
def get_weather(location: hug.types.text):
url = f'http://api.openweathermap.org/data/2.5/weather?q={location}&appid=YOUR_API_KEY'
response = requests.get(url)
data = response.json()
return data['weather'][0]['description']
In this example, we define an endpoint that takes a location parameter and fetches the weather forecast for that location using the OpenWeatherMap API. The API key needs to be replaced with your own key.
To learn more about Hug and its capabilities, you can visit the official website.