Skip to main content

Standardizes function return values across Python applications to enhance code consistency, readability, and maintainability.

Project description

BasicReturns 🐍

PyPI Version PyPI - Python Version PyPI - License PyPI Downloads

Standardizes function return values across Python applications to enhance code consistency, readability, and maintainability.

📦 Installation

pip install BasicReturns

🚀 Quick Start

from BasicReturns import BasicReturn, DataAndMsgReturn

def divide_numbers(a: float, b: float) -> DataAndMsgReturn:
    """Safely divide two numbers with unified return structure."""
    response = DataAndMsgReturn()

    try:
        if b == 0:
            raise ZeroDivisionError("Cannot divide by zero")
        response.data = a / b
        response.msg = "Division completed successfully"
    except Exception as e:
        response.ok = False
        response.error = e
        response.msg = "Division failed"

    return response

# Usage example
result = divide_numbers(10, 2)

if result.ok:
    print(f"{result.msg}: {result.data}")  # Division completed successfully: 5.0
else:
    print(f"{result.msg}: {result.error}")  # Division failed: Cannot divide by zero

🛠️ Practical Examples

File Operations Utility

Here's how to implement a file utility class using unified returns:

from io import TextIOWrapper
from pathlib import Path
import json
from typing import Any
from BasicReturns import BaseReturn, DataAndMsgReturn

class FilesUtils:
    @staticmethod
    def file_exists(filename: str) -> bool:
        return Path(filename).is_file()

    @staticmethod
    def read_file(filename: str) -> DataAndMsgReturn:
        """Read file content with unified return structure."""
        response = DataAndMsgReturn()

        try:
            if not FilesUtils.file_exists(filename):
                response.ok = False
                response.error = FileNotFoundError(f"File '{filename}' not found")
                response.msg = "File does not exist"
                return response

            with open(filename, 'r', encoding='utf-8') as file:
                response.data = file.read()
                response.msg = f"Successfully read file: {filename}"
        except Exception as e:
            response.ok = False
            response.error = e
            response.msg = f"Error reading file: {filename}"

        return response

    @staticmethod
    def read_json(filename: str) -> DataAndMsgReturn:
        """Read and parse JSON file with unified error handling."""
        response = DataAndMsgReturn()
        file_result = FilesUtils.read_file(filename)

        if not file_result.ok:
            # Propagate the error from read_file
            response.ok = file_result.ok
            response.error = file_result.error
            response.msg = file_result.msg
            return response

        try:
            response.data = json.loads(file_result.data)
            response.msg = f"Successfully parsed JSON from: {filename}"
        except json.JSONDecodeError as e:
            response.ok = False
            response.error = e
            response.msg = f"Invalid JSON format in file: {filename}"

        return response

    @staticmethod
    def write_json(filename: str, data: dict) -> BaseReturn:
        """Write dictionary to JSON file with atomic operation handling."""
        response = BaseReturn()

        try:
            with open(filename, 'w', encoding='utf-8') as file:
                json.dump(data, file, indent=2, sort_keys=True, ensure_ascii=False)
            response.msg = f"Successfully wrote JSON to: {filename}"
        except Exception as e:
            response.ok = False
            response.error = e
            response.msg = f"Failed to write JSON file: {filename}"

        return response

Usage in Application

# Read configuration file
config_result = FilesUtils.read_json("config.json")

if config_result.ok:
    config = config_result.data
    print("Configuration loaded:", config)
else:
    print("Error loading config:", config_result.error)
    # Fallback to default configuration
    config = {"default": "settings"}

# Save user data
user_data = {"name": "John Doe", "email": "john@example.com"}
save_result = FilesUtils.write_json("users/john.json", user_data)

if save_result.ok:
    print("User data saved successfully")
else:
    print("Failed to save user data:", save_result.error)
    # Handle the error appropriately

🌟 Best Practices

1. Consistent Error Handling

def process_data(data: Any) -> DataAndMsgReturn:
    response = DataAndMsgReturn()

    if not data:
        response.ok = False
        response.error = ValueError("Empty data provided")
        response.msg = "Validation failed"
        return response

    # Process data...
    response.data = processed_data
    response.msg = "Data processed successfully"
    return response

2. Chaining Operations

def load_and_validate_config() -> DataAndMsgReturn:
    config_result = FilesUtils.read_json("config.json")

    if not config_result.ok:
        return config_result  # Return the error immediately

    validation_result = validate_config(config_result.data)

    if not validation_result.ok:
        return DataAndMsgReturn(
            ok=False,
            error=validation_result.error,
            msg=f"Configuration validation failed: {validation_result.msg}"
        )

    return DataAndMsgReturn(
        data=config_result.data,
        msg="Configuration loaded and validated successfully"
    )

3. API Integration

import requests
from BasicReturns import DataAndMsgReturn

def fetch_api_data(url: str) -> DataAndMsgReturn:
    response = DataAndMsgReturn()

    try:
        api_response = requests.get(url, timeout=10)
        api_response.raise_for_status()

        response.data = api_response.json()
        response.msg = f"Successfully fetched data from {url}"
    except requests.exceptions.RequestException as e:
        response.ok = False
        response.error = e
        response.msg = f"API request failed: {url}"

    return response

📊 Benefits

Consistent Error Handling - No more guessing return types or error formats
Improved Readability - Clear success/failure states with contextual messages
Better Debugging - Structured error information with stack traces when needed
Type Safety - Full MyPy compatibility with proper type annotations
Seamless Integration - Works with any Python framework or application
Serialization Ready - Built-in to_dict() method for JSON/API responses

🤝 Contributing

Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.

  1. Fork the repository
  2. Create your feature branch (git switch -c feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a pull request

📄 License

Distributed under the MIT License. See LICENSE for more information.


Made with ❤️ for Python developers who value clean, consistent code

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

basicreturns-0.1.2.tar.gz (6.4 kB view details)

Uploaded Source

Built Distribution

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

basicreturns-0.1.2-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file basicreturns-0.1.2.tar.gz.

File metadata

  • Download URL: basicreturns-0.1.2.tar.gz
  • Upload date:
  • Size: 6.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.6

File hashes

Hashes for basicreturns-0.1.2.tar.gz
Algorithm Hash digest
SHA256 2e4f42e7338f1d7d9e079d2df8d5cceaaf6cb2696e70b20cbd365aeac5f98525
MD5 f58b5fa9e68e865ac05fdafb6628cf41
BLAKE2b-256 c720ece5d405674e6a571ffdf23346beeadc8357ca547efc704365b79d8522c8

See more details on using hashes here.

File details

Details for the file basicreturns-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: basicreturns-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 6.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.6

File hashes

Hashes for basicreturns-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6269c0a6c3a55edc80b3e1cc859a1b0c1735a47d7953d1ca9c54365dd4503145
MD5 32996b955f80b1810c663c05ae43b79c
BLAKE2b-256 f4551664572017893b2b0372d64dc5ee16dde14f3caaeb371611e9a636ef34b1

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