HTTP Methods API¶
The methods module defines constants and helper functions for handling HTTP methods in Plinx applications. This module provides a clean way to work with HTTP methods throughout your application.
HTTP Method Constants¶
plinx.methods.HTTPMethods
¶
Bases: Enum
Enumeration of HTTP methods supported by the Plinx framework.
This enum defines the standard HTTP methods as defined in RFC 7231 and RFC 5789, categorized by their safety and idempotency properties.
Safe methods (should not modify resources): - GET: Retrieve a representation of a resource - HEAD: Same as GET but returns only headers, no body
Idempotent methods (multiple identical requests have same effect as single request): - PUT: Replace a resource with the request payload - DELETE: Remove the specified resource - OPTIONS: Describe the communication options for the target resource
Non-idempotent methods (multiple identical requests may have different effects): - POST: Submit data to be processed, typically creating a new resource - PATCH: Apply partial modifications to a resource
Usage
from plinx.methods import HTTPMethods
# Check if a method is GET
if method == HTTPMethods.GET:
# handle GET request
# Get the string value of a method
method_str = HTTPMethods.POST.value # "POST"
Source code in plinx/methods.py
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
Method Handling Functions¶
plinx.methods.is_valid_method(method)
¶
Check if the given method is a valid HTTP method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str
|
The HTTP method to check |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the method is valid, False otherwise |
Source code in plinx/methods.py
51 52 53 54 55 56 57 58 59 60 61 | |
plinx.methods.get_handler_name_for_method(method)
¶
Get the handler name for a given HTTP method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str
|
The HTTP method to get the handler name for |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The handler name corresponding to the HTTP method |
Source code in plinx/methods.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 | |
Examples¶
Checking for Valid HTTP Methods¶
from plinx.methods import is_valid_method
# Check if a method is supported
if is_valid_method("GET"):
print("GET is a valid HTTP method")
if not is_valid_method("CUSTOM"):
print("CUSTOM is not a valid HTTP method")
Working with HTTP Method Constants¶
from plinx import Plinx
from plinx.methods import HTTPMethods
app = Plinx()
@app.route("/example")
def handler(request, response):
if request.method == HTTPMethods.GET:
response.text = "This is a GET request"
elif request.method == HTTPMethods.POST:
response.text = "This is a POST request"
else:
response.text = f"This is a {request.method} request"
Finding Handler Method Names¶
from plinx.methods import get_handler_name_for_method
# For class-based views, this function maps HTTP methods to method names
handler_name = get_handler_name_for_method("GET") # Returns "get"
handler_name = get_handler_name_for_method("POST") # Returns "post"
Method Handling in Class-Based Views¶
In class-based views, HTTP methods are automatically mapped to methods with lowercase names:
from plinx import Plinx
app = Plinx()
@app.route("/resource")
class ResourceHandler:
def get(self, request, response):
response.text = "Handling GET request"
def post(self, request, response):
response.text = "Handling POST request"
def put(self, request, response):
response.text = "Handling PUT request"
def delete(self, request, response):
response.text = "Handling DELETE request"
def patch(self, request, response):
response.text = "Handling PATCH request"
def head(self, request, response):
# HEAD requests don't return a body
pass
def options(self, request, response):
response.headers["Allow"] = "GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS"
When a request comes in, Plinx will call the appropriate method based on the HTTP method of the request.
Custom Method Handlers¶
You can implement custom method handling by overriding the default behavior:
from plinx import Plinx
from plinx.methods import get_handler_name_for_method
# Custom function to map HTTP methods to handler names
def custom_method_mapper(method):
method_map = {
"GET": "handle_get",
"POST": "handle_post",
"PUT": "handle_put",
"DELETE": "handle_delete"
}
return method_map.get(method, "handle_default")
app = Plinx()
@app.route("/custom")
class CustomMethodHandler:
def handle_get(self, request, response):
response.text = "Custom GET handler"
def handle_post(self, request, response):
response.text = "Custom POST handler"
def handle_put(self, request, response):
response.text = "Custom PUT handler"
def handle_delete(self, request, response):
response.text = "Custom DELETE handler"
def handle_default(self, request, response):
response.text = f"Default handler for {request.method}"
# Override the default method handling
def __getattr__(self, name):
if name == get_handler_name_for_method(request.method):
# Use our custom mapper instead
handler_name = custom_method_mapper(request.method)
return getattr(self, handler_name)
raise AttributeError(f"{self.__class__.__name__} has no attribute {name}")
Method Not Allowed Handling¶
Plinx automatically handles requests with methods not supported by your handler:
from plinx import Plinx
app = Plinx()
@app.route("/limited")
class LimitedHandler:
def get(self, request, response):
response.text = "GET is allowed"
# No other methods defined
# POST, PUT, etc. will receive a 405 Method Not Allowed response
# For function handlers, the default behavior allows all methods
@app.route("/allow-all")
def all_methods_handler(request, response):
response.text = f"Handling {request.method} request"
Method Override¶
Sometimes it's useful to override the HTTP method, especially when working with HTML forms that only support GET and POST:
from plinx import Plinx
from plinx.middleware import Middleware
class MethodOverrideMiddleware(Middleware):
def process_request(self, request):
# Check for X-HTTP-Method-Override header
override = request.headers.get("X-HTTP-Method-Override")
# Check for _method form field (common in HTML forms)
if not override and request.method == "POST":
override = request.POST.get("_method")
# Override the method if specified
if override and override.upper() in ["PUT", "DELETE", "PATCH"]:
request.method = override.upper()
app = Plinx()
app.add_middleware(MethodOverrideMiddleware)
This allows HTML forms to simulate PUT, DELETE, and PATCH requests by including a form field named _method or by setting the X-HTTP-Method-Override header.
Best Practices¶
- Use HTTP methods semantically: Follow RESTful conventions (GET for retrieval, POST for creation, etc.)
- Handle OPTIONS requests: Especially important for CORS support
- Return appropriate status codes: 405 Method Not Allowed for unsupported methods
- Support idempotent methods: GET, PUT, and DELETE should be idempotent
- Consider method overrides: If supporting HTML forms that can only use GET and POST
- Document supported methods: Make it clear which methods are supported by each endpoint