Python Falcon - Resource Class
Last Updated :
18 Dec, 2023
Python Falcon is a simple web framework that helps developers efficiently manage RESTful APIs. One of its main strengths is how it organizes code using Resource Classes. These classes play a crucial role in Falcon applications, making it easier to handle endpoint logic and improving the clarity and maintainability of the code. As developers explore Falcon, using Resource Classes becomes important. They provide a structured way to create APIs that are both scalable and high-performing.
Python Falcon - Resource Class
In the Falcon world, a Resource class serves as a Python entity that defines how a particular API endpoint behaves. It acts as a guide for handling incoming HTTP requests, going through them, managing the details, and creating the appropriate response. These classes wrap up the complex handling of different HTTP methods (GET, POST, PUT, DELETE, etc.) associated with a specific resource. These classes make sure everything runs smoothly when someone interacts with that part of the system
Features of Python Falcon - Resource Class
- Routing Mechanism: Falcon utilizes Resource classes to establish connections between HTTP methods and their corresponding resource endpoints. This is achieved by automatically directing incoming requests to the appropriate Resource class, determined by evaluating the requested URI and HTTP method.
- Method Definitions: In Falcon, Resource classes conventionally define methods corresponding to various HTTP methods, such as on_get, on_post, on_put, and more. These methods are responsible for processing incoming requests and generating appropriate responses.
- Request and Response Handling: Falcon provides Request and Response objects as inputs to the methods within the Resource class. These objects encapsulate the details of the incoming request and the intended response, facilitating streamlined handling of data within the framework.
- Statelessness Principle: Falcon follows a stateless approach, advocating the development of APIs that operate independently for each request. Resource classes are expected to align with this principle, ensuring that each request is managed autonomously without relying on shared states between different requests. This design philosophy enhances scalability and simplifies the maintenance of Falcon-based applications.
Create Python Falcon - Resource Class
Let's navigate through the journey of shaping a straightforward Falcon Resource class
Step 1: Basic Falcon Class
In this example, we've created a basic Falcon Resource class named HelloWorldResource with an on_get method. This method will be invoked when a GET request is made to the corresponding endpoint.
Python3
import falcon
class HelloWorldResource:
def on_get(self, req, resp):
resp.status = falcon.HTTP_200
resp.body = "Hello, World!"
Step 2: Routing Requests to Resource Classes
Routing requests to Resource classes is a fundamental aspect of Falcon. This is achieved through the add_route method of the Falcon API instance. Here's an example:
Here, we've created a Falcon app instance and added a route that maps the '/hello' URI to our HelloWorldResource class. Now, when a GET request is made to '/hello', the on_get method of HelloWorldResource will be executed.
Python3
import falcon
app = falcon.App()
hello_world_resource = HelloWorldResource()
app.add_route('/hello', hello_world_resource)
CRUD Operation in Python Falcon - Resource Class
Here ,the code defines a Falcon API with a resource class named `TaskResource` to manage tasks. The resource supports GET, POST, PUT, and DELETE methods. The `on_get` method retrieves the list of tasks, the `on_post` method adds a new task, the `on_put` method updates a task, and the `on_delete` method deletes a task based on the specified criteria. Additionally, the code includes an HTML UI for interacting with the task management system. The UI allows users to add, update, and delete tasks through a web interface. The Falcon app is configured to serve this HTML UI through a separate `HTMLResource` class, and the entire application is run on a local server at http://127.0.0.1:8000. Users can access the web interface to manage tasks through the provided HTML UI.
Python3
import falcon
import json
class TaskResource:
def __init__(self):
self.tasks = []
self.next_id = 1
# Get Method in Falcon
def on_get(self, req, resp):
resp.status = falcon.HTTP_200
resp.media = {"tasks": self.tasks}
# Post Method in Falcon
def on_post(self, req, resp):
data = json.loads(req.bounded_stream.read().decode("utf-8"))
if "title" not in data:
resp.status = falcon.HTTP_400
resp.media = {"error": "Title is required"}
return
new_task = {"id": self.next_id, "title": data["title"]}
self.tasks.append(new_task)
self.next_id += 1
resp.status = falcon.HTTP_201
resp.media = new_task
# Put Method in Falcon
def on_put(self, req, resp):
data = json.loads(req.bounded_stream.read().decode("utf-8"))
if "current_title" not in data or "new_title" not in data:
resp.status = falcon.HTTP_400
resp.media = {"error": "Both current_title and new_title are required"}
return
for task in self.tasks:
if task["title"] == data["current_title"]:
task["title"] = data["new_title"]
resp.status = falcon.HTTP_200
resp.media = task
return
resp.status = falcon.HTTP_404
resp.media = {"error": "Task not found"}
# Delete Method in Falcon
def on_delete(self, req, resp):
data = json.loads(req.bounded_stream.read().decode("utf-8"))
if "title" not in data:
resp.status = falcon.HTTP_400
resp.media = {"error": "Title is required"}
return
for task in self.tasks:
if task["title"] == data["title"]:
self.tasks.remove(task)
resp.status = falcon.HTTP_200
resp.media = {"message": "Task deleted"}
return
resp.status = falcon.HTTP_404
resp.media = {"error": "Task not found"}
# Create a Falcon app
app = falcon.App()
# Create an instance of TaskResource
task_resource = TaskResource()
# Add routes to the app
app.add_route("/tasks", task_resource)
# HTML UI (cleaned up)
html_ui = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Task Manager</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f9f9f9;
margin: 0;
padding: 0;
}
header {
background-color: #333;
color: #fff;
text-align: center;
padding: 1rem;
}
main {
max-width: 800px;
margin: 20px auto;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
form {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
label {
font-weight: bold;
color: #333;
}
input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 3px;
width: 70%;
font-size: 14px;
}
button {
padding: 8px 15px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background-color: #0056b3;
}
h1 {
color: white;
font-size: 1.5rem;
margin-bottom: 10px;
}
h2 {
color: #28a745;
font-size: 3rem;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin: 10px 0;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
}
li:hover {
background-color: #f0f0f0;
}
button.update,
button.delete {
padding: 5px 10px;
font-size: 0.9rem;
}
button.update {
background-color: green;
color: #fff;
border: none;
margin-right: 5px;
}
button.delete {
background-color: red;
color: #fff;
border: none;
}
</style>
</head>
<body>
<header>
<h2>GeeksforGeeks</h2>
<h1>Task Manager</h1>
</header>
<main>
<form id="taskForm">
<label for="taskTitle">Task Title:</label>
<input type="text" id="taskTitle" required>
<button type="submit">Add Task</button>
</form>
<h3>Task List</h3>
<ul id="taskList"></ul>
</main>
<script>
function fetchTasks() {
fetch('/tasks')
.then(response => response.json())
.then(data => {
const taskList = document.getElementById('taskList');
taskList.innerHTML = '';
data.tasks.forEach(task => {
const listItem = document.createElement('li');
listItem.textContent = task.title;
const updateButton = document.createElement('button');
updateButton.textContent = 'Update';
updateButton.onclick = () => handleUpdate(task.title);
listItem.appendChild(updateButton);
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.onclick = () => handleDelete(task.title);
listItem.appendChild(deleteButton);
taskList.appendChild(listItem);
});
});
}
function handleFormSubmission(event) {
event.preventDefault();
const taskTitle = document.getElementById('taskTitle').value;
fetch('/tasks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: taskTitle }),
})
.then(response => response.json())
.then(data => {
console.log('Task added:', data);
fetchTasks();
});
document.getElementById('taskTitle').value = '';
}
function handleUpdate(currentTitle) {
const newTitle = prompt('Enter new title:');
if (newTitle !== null) {
fetch('/tasks', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ current_title: currentTitle, new_title: newTitle }),
})
.then(response => response.json())
.then(data => {
console.log('Task updated:', data);
fetchTasks();
});
}
}
function handleDelete(title) {
const confirmDelete = confirm(`Are you sure you want to delete the task "${title}"?`);
if (confirmDelete) {
fetch('/tasks', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: title }),
})
.then(response => response.json())
.then(data => {
console.log('Task deleted:', data);
fetchTasks();
});
}
}
document.getElementById('taskForm').addEventListener('submit', handleFormSubmission);
fetchTasks();
</script>
</body>
</html>
"""
# Falcon route to serve the HTML UI
class HTMLResource:
def on_get(self, req, resp):
resp.content_type = "text/html"
resp.text = html_ui
app.add_route("/", HTMLResource())
# Run the app
if __name__ == "__main__":
from wsgiref import simple_server
httpd = simple_server.make_server("127.0.0.1", 8000, app)
print("Serving on http://127.0.0.1:8000")
httpd.serve_forever()
Run the Server
python script_name.py
Output
Conclusion
The Falcon Resource class is a powerful tool for building RESTful APIs with Python. By encapsulating endpoint-specific logic in Resource classes, Falcon promotes clean, modular, and maintainable API code. Understanding how to create and use Resource classes is essential for anyone developing APIs with Falcon, and it forms the backbone of efficient and scalable API applications. As you explore Falcon further, you'll discover additional features and capabilities that make it a versatile and lightweight framework for API development in Python.
Similar Reads
Python Tutorial | Learn Python Programming Language
Python Tutorial â Python is one of the most popular programming languages. Itâs simple to use, packed with features and supported by a wide range of libraries and frameworks. Its clean syntax makes it beginner-friendly.Python is:A high-level language, used in web development, data science, automatio
10 min read
Python Interview Questions and Answers
Python is the most used language in top companies such as Intel, IBM, NASA, Pixar, Netflix, Facebook, JP Morgan Chase, Spotify and many more because of its simplicity and powerful libraries. To crack their Online Assessment and Interview Rounds as a Python developer, we need to master important Pyth
15+ min read
Non-linear Components
In electrical circuits, Non-linear Components are electronic devices that need an external power source to operate actively. Non-Linear Components are those that are changed with respect to the voltage and current. Elements that do not follow ohm's law are called Non-linear Components. Non-linear Co
11 min read
Python OOPs Concepts
Object Oriented Programming is a fundamental concept in Python, empowering developers to build modular, maintainable, and scalable applications. By understanding the core OOP principles (classes, objects, inheritance, encapsulation, polymorphism, and abstraction), programmers can leverage the full p
11 min read
Python Projects - Beginner to Advanced
Python is one of the most popular programming languages due to its simplicity, versatility, and supportive community. Whether youâre a beginner eager to learn the basics or an experienced programmer looking to challenge your skills, there are countless Python projects to help you grow.Hereâs a list
10 min read
Python Exercise with Practice Questions and Solutions
Python Exercise for Beginner: Practice makes perfect in everything, and this is especially true when learning Python. If you're a beginner, regularly practicing Python exercises will build your confidence and sharpen your skills. To help you improve, try these Python exercises with solutions to test
9 min read
Class Diagram | Unified Modeling Language (UML)
A UML class diagram is a visual tool that represents the structure of a system by showing its classes, attributes, methods, and the relationships between them. It helps everyone involved in a projectâlike developers and designersâunderstand how the system is organized and how its components interact
12 min read
Python Programs
Practice with Python program examples is always a good choice to scale up your logical understanding and programming skills and this article will provide you with the best sets of Python code examples.The below Python section contains a wide collection of Python programming examples. These Python co
11 min read
Spring Boot Tutorial
Spring Boot is a Java framework that makes it easier to create and run Java applications. It simplifies the configuration and setup process, allowing developers to focus more on writing code for their applications. This Spring Boot Tutorial is a comprehensive guide that covers both basic and advance
10 min read
Python Data Types
Python Data types are the classification or categorization of data items. It represents the kind of value that tells what operations can be performed on a particular data. Since everything is an object in Python programming, Python data types are classes and variables are instances (objects) of thes
9 min read