1. import functools
  2. import inspect
  3. def validate_url_params(func):
  4. """
  5. Decorator to validate URL parameters and wrap errors for diagnostics.
  6. """
  7. @functools.wraps(func)
  8. def wrapper(*args, **kwargs):
  9. """Wrapper function to validate URL parameters."""
  10. sig = inspect.signature(func)
  11. params = sig.parameters
  12. # Extract URL parameters from kwargs
  13. url_params = {
  14. p.name: kwargs.get(p.name)
  15. for p in params.values()
  16. if p.name in kwargs
  17. }
  18. # Validate parameters based on function signature
  19. for name, param in params.items():
  20. if param.default is inspect.Parameter.empty and name in url_params:
  21. try:
  22. # Perform validation logic here. Example: convert to int
  23. if param.annotation == int:
  24. int(url_params[name])
  25. # Add other validation logic based on param.annotation
  26. # ...
  27. except ValueError:
  28. raise ValueError(f"Invalid value for URL parameter '{name}'. Expected {param.annotation}, got '{url_params[name]}'")
  29. except TypeError:
  30. raise TypeError(f"Invalid type for URL parameter '{name}'. Expected {param.annotation}, got {type(url_params[name])}")
  31. # Call the original function if validation passes
  32. return func(*args, **kwargs)
  33. return wrapper
  34. if __name__ == '__main__':
  35. @validate_url_params
  36. def my_function(id: int, name: str = "default"):
  37. """
  38. Example function that accepts URL parameters.
  39. """
  40. print(f"ID: {id}, Name: {name}")
  41. # Test cases
  42. try:
  43. my_function(123, name="Alice") # Valid
  44. my_function(123) # Valid, uses default for name
  45. my_function("abc", name="Bob") # Raises ValueError
  46. except (ValueError, TypeError) as e:
  47. print(f"Error: {e}")

Add your comment