Skip to main content

A collection of powerful Python decorators for enhanced functionality

Project description

PyWraps 🎁

A collection of powerful Python decorators for enhanced functionality

PyPI version Python Support License: Apache 2.0 Code Quality

🚀 Features

PyWraps provides a comprehensive suite of decorators that enhance your Python functions with powerful capabilities:

  • 🔄 Retry: Automatically retry failed function calls with customizable attempts and delays
  • ⏱️ Timeout: Set execution time limits for both synchronous and asynchronous functions
  • 🎯 Debounce: Prevent rapid successive function calls, executing only the last one
  • 🧵 Background: Execute functions in separate threads without blocking the main thread

📦 Installation

pip install pywraps

🎯 Quick Start

from pywraps import retry, timeout, debounce, background
import time
import random

@retry(tries=3, delay=1.0)
def unreliable_function():
    if random.random() < 0.7:
        raise Exception("Random failure!")
    return "Success!"

@timeout(seconds=5.0)
def slow_function():
    time.sleep(3)
    return "Completed within timeout"

@debounce(wait=2.0)
def search_function(query):
    print(f"Searching for: {query}")

@background
def heavy_computation():
    time.sleep(10)
    print("Background task completed!")

📚 Detailed Documentation

🔄 Retry Decorator

The @retry decorator automatically retries function execution when exceptions occur.

Parameters:

  • tries (int): Number of retry attempts (default: 3)
  • delay (float): Delay between retries in seconds (default: 1.0)
  • exceptions (Exception or tuple): Exception types to catch (default: Exception)

Examples:

from pywraps import retry
import requests
import random

@retry(tries=5, delay=2.0)
def fetch_data_from_api():
    response = requests.get("https://api.example.com/data")
    if response.status_code != 200:
        raise requests.RequestException("API request failed")
    return response.json()

@retry(tries=3, delay=0.5, exceptions=(ValueError, TypeError))
def parse_user_input(user_input):
    if not user_input.strip():
        raise ValueError("Empty input")
    return int(user_input)

@retry(tries=10, delay=1.0)
def database_operation():
    if random.random() < 0.8:
        raise ConnectionError("Database connection failed")
    return "Data saved successfully"

try:
    result = fetch_data_from_api()
    print("API data:", result)
except requests.RequestException as e:
    print(f"Failed after retries: {e}")

⏱️ Timeout Decorator

The @timeout decorator sets execution time limits for functions, supporting both synchronous and asynchronous operations.

Parameters:

  • seconds (float): Maximum execution time in seconds

Examples:

from pywraps import timeout
import time
import asyncio
import aiohttp

@timeout(seconds=3.0)
def cpu_intensive_task():
    total = 0
    for i in range(10000000):
        total += i * i
    return total

@timeout(seconds=5.0)
async def fetch_multiple_urls():
    urls = [
        "https://httpbin.org/delay/1",
        "https://httpbin.org/delay/2",
        "https://httpbin.org/delay/1"
    ]
    
    async with aiohttp.ClientSession() as session:
        tasks = []
        for url in urls:
            tasks.append(session.get(url))
        
        responses = await asyncio.gather(*tasks)
        return [resp.status for resp in responses]

@timeout(seconds=2.0)
def file_processing():
    with open("large_file.txt", "r") as f:
        lines = f.readlines()
    return len(lines)

try:
    result = cpu_intensive_task()
    print("Task completed:", result)
except TimeoutError as e:
    print(f"Operation timed out: {e}")

async def main():
    try:
        statuses = await fetch_multiple_urls()
        print("HTTP statuses:", statuses)
    except TimeoutError as e:
        print(f"Async operation timed out: {e}")

asyncio.run(main())

🎯 Debounce Decorator

The @debounce decorator prevents rapid successive function calls, executing only the last call after a specified delay.

Parameters:

  • wait (float): Delay time in seconds before execution

Examples:

from pywraps import debounce
import time

@debounce(wait=1.0)
def save_user_preferences(user_id, preferences):
    print(f"Saving preferences for user {user_id}: {preferences}")
    

@debounce(wait=0.5)
def search_suggestions(query):
    print(f"Fetching suggestions for: '{query}'")
    return [f"{query}_suggestion_{i}" for i in range(3)]

@debounce(wait=2.0)
def auto_save_document(document_id, content):
    print(f"Auto-saving document {document_id}")
    with open(f"doc_{document_id}.txt", "w") as f:
        f.write(content)

user_prefs = {"theme": "dark", "language": "en"}
save_user_preferences(123, user_prefs)
save_user_preferences(123, {**user_prefs, "theme": "light"})
save_user_preferences(123, {**user_prefs, "notifications": True})

for query in ["py", "pyt", "pyth", "pytho", "python"]:
    search_suggestions(query)
    time.sleep(0.1)

time.sleep(3)

🧵 Background Decorator

The @background decorator executes functions in separate threads, preventing blocking of the main thread.

Examples:

from pywraps import background
import time
import logging

logging.basicConfig(level=logging.INFO)

@background
def send_email_notification(recipient, subject, body):
    print(f"Sending email to {recipient}...")
    time.sleep(2)
    print(f"Email sent to {recipient}: {subject}")

@background
def generate_report(report_type, data):
    print(f"Generating {report_type} report...")
    time.sleep(5)
    print(f"Report '{report_type}' generated with {len(data)} records")

@background
def cleanup_temp_files():
    print("Starting cleanup process...")
    time.sleep(3)
    print("Temporary files cleaned up")

@background
def log_user_activity(user_id, action, timestamp):
    logging.info(f"User {user_id} performed {action} at {timestamp}")
    time.sleep(0.5)
    logging.info(f"Activity logged for user {user_id}")

send_email_notification("user@example.com", "Welcome!", "Thank you for joining!")
generate_report("monthly_sales", list(range(1000)))
cleanup_temp_files()

for i in range(5):
    log_user_activity(f"user_{i}", "login", time.time())

print("All background tasks started!")
time.sleep(6)
print("Main thread continues...")

🔧 Advanced Usage

Combining Decorators

You can combine multiple decorators for enhanced functionality:

from pywraps import retry, timeout, background
import requests
import time

@background
@retry(tries=3, delay=1.0)
@timeout(seconds=10.0)
def robust_api_call(url):
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

@retry(tries=5, delay=0.5)
@timeout(seconds=30.0)
def critical_database_operation():
    time.sleep(2)
    return "Operation completed successfully"

robust_api_call("https://api.github.com/users/octocat")
result = critical_database_operation()
print(result)

Error Handling Best Practices

from pywraps import retry, timeout
import logging

logging.basicConfig(level=logging.INFO)

@retry(tries=3, delay=1.0, exceptions=(ConnectionError, TimeoutError))
@timeout(seconds=5.0)
def resilient_operation():
    import random
    if random.random() < 0.6:
        raise ConnectionError("Network issue")
    return "Success"

try:
    result = resilient_operation()
    logging.info(f"Operation successful: {result}")
except Exception as e:
    logging.error(f"Operation failed after all retries: {e}")

🎨 Use Cases

Web Development

  • API Rate Limiting: Use @debounce for search endpoints
  • Timeout Protection: Apply @timeout to external API calls
  • Background Processing: Use @background for email sending, file uploads
  • Retry Logic: Implement @retry for database operations

Data Processing

  • Batch Operations: @background for large dataset processing
  • Network Resilience: @retry for data fetching from unreliable sources
  • Resource Management: @timeout to prevent memory leaks in long operations

User Interface

  • Search Optimization: @debounce for real-time search suggestions
  • Form Validation: @debounce for input validation
  • Progress Tracking: @background for long-running tasks with progress updates

🤝 Contributing

We welcome contributions! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Make your changes and add tests
  4. Commit your changes: git commit -am 'Add new feature'
  5. Push to the branch: git push origin feature-name
  6. Submit a pull request

📄 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

  • Inspired by the need for simple, powerful decorators in Python
  • Built with love for the Python community
  • Special thanks to all contributors and users

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pywraps-1.0.1.tar.gz (49.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pywraps-1.0.1-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file pywraps-1.0.1.tar.gz.

File metadata

  • Download URL: pywraps-1.0.1.tar.gz
  • Upload date:
  • Size: 49.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for pywraps-1.0.1.tar.gz
Algorithm Hash digest
SHA256 77f21a5dc48ebed59c5996cee840cc35eace12aeb4cfe0c64be918bedef73e1d
MD5 76e354b8c669b8e2b1a2b222fc62fa65
BLAKE2b-256 eeaa7a28b7e943bf0b2bdab734872fa4818cd1663643189058a7c23187213e75

See more details on using hashes here.

File details

Details for the file pywraps-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pywraps-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for pywraps-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 52c8f3555646b1b4978fdcf0dd003af2675d062f9eeac8bf6ece2c093f4eb7ae
MD5 46c232a2ec388f76266fd1a06808f242
BLAKE2b-256 0488e2e1841f9a6d8c8f4ab8e0d335b4ff236655232e5a9292937d8e78414941

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page