Skip to main content

A lightweight type-safe Python utility for safely accessing deeply nested dictionary values

Project description

Nougat 🍫

PyPI version License: MIT Python Versions Test and Build

PyPI - Wheel GitHub Release GitHub repo size

logo
A lightweight type-safe Python utility for safely accessing deeply nested dictionary values.

Overview

Nougat solves the common problem of accessing nested dictionary values without raising KeyError exceptions. It provides high-performance nested dictionary access with a clean, type-safe interface for traversing nested dictionaries, returning a default value when any key in the path doesn't exist. Stop worrying about KeyError exceptions and messy null checks!

Problem

Working with nested dictionaries in Python often leads to verbose, error-prone code:

# Deeply nested access without Nougat
data = {...}
user_city = None
if 'user' in data and data['user'] and 'profile' in data['user'] \
        and data['user']['profile'] and 'address' in data['user']['profile']:
    if 'city' in data['user']['profile']['address']:
        user_city = data['user']['profile']['address']['city']

Or risky code that might raise exceptions:

# Error-prone approach
data = {...}
try:
    user_city = data['user']['profile']['address']['city']
except (KeyError, TypeError):
    user_city = None

Solution

Nougat provides a clean, performant way to safely access nested values:

# With Nougat
from src import nougat

data = {...}
user_city = nougat(data, "user", "profile", "address", "city", default="Unknown")

Installation

via pip:

pip install pynougat

via git+pip:

# Clone the repository
git clone https://github.com/sphireinc/pynougat.git

# Install directly with pip
pip install git+https://github.com/sphireinc/pynougat.git

Usage

Basic Usage

from src.pynougat import nougat

# Sample nested data
data = {
    "user": {
        "profile": {
            "name": "Alice",
            "address": {
                "city": "Seattle",
                "zip": "98101"
            }
        },
        "preferences": {
            "theme": "dark"
        },
        "scores": [85, 92, 78]
    }
}

# Simple path traversal
name = nougat(data, "user", "profile", "name")  # "Alice"

# Default values for missing paths
country = nougat(data, "user", "profile", "address", "country", default="USA")  # "USA"

# Access list items
second_score = nougat(data, "user", "scores", 1)  # 92

# Path doesn't exist? No problem!
missing = nougat(data, "user", "profile", "age", default=0)  # 0

Advanced Features

Dot Notation

from src.pynougat import nougat

# Use dot strings for cleaner access
theme = nougat(data, "user.preferences.theme", separator=".")  # "dark"

Alternative Keys

from src.pynougat import nougat

# Try multiple keys at each level and use first match
theme = nougat(data, ("users", "user"), "preferences", ("appearance", "theme"))

Value Transformation

from src.pynougat import nougat

# Transform the returned value
scores_sum = nougat(data, "user", "scores", transform=sum)  # 255 (85+92+78)

Path Caching for High Performance

from src.pynougat import nougat_cached

# Create a reusable, cached accessor function for a specific path
data1 = {}
data2 = {}
get_user_city = nougat_cached(["user", "profile", "address", "city"])

# Use it repeatedly for high performance
city1 = get_user_city(data1)
city2 = get_user_city(data2)

Strict Type Checking

from src.pynougat import nougat

# Enable strict type checking for better error identification
nougat(data, "user", "profile", "address", strict_types=True)

Features

  • Zero dependencies - just pure Python
  • Highly optimized for performance
  • 🛡️ Type-safe with full mypy support
  • 🧠 Smart traversal of dicts, lists, tuples, and custom objects
  • 🔄 Alternative paths to try multiple access routes
  • 🔍 Dot notation support for concise access patterns
  • 🚀 Path caching for repeated high-performance lookups
  • 🪄 Value transformation to process retrieved values
  • 🔒 Never raises exceptions for a clean, predictable API
  • Customizable default values
  • Handles any depth of nesting
  • Lightweight and fast

When to Use Nougat

  • Accessing configuration values that might not exist
  • Processing API responses with varying structures
  • Handling user input or preferences with optional fields
  • Any situation where you need to safely navigate nested dictionaries

Performance

Nougat is optimized for high performance:

  • Fast paths for common data types
  • Minimal overhead for common operations
  • Path caching for repeated access
  • Exception-free operation

License

MIT License - See LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b 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

Made with ❤️ for all Python developers tired of KeyError exceptions and messy data.get('obj', {}).get('key', None) chains

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

pynougat-0.0.2.tar.gz (5.5 kB view details)

Uploaded Source

Built Distribution

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

pynougat-0.0.2-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

File details

Details for the file pynougat-0.0.2.tar.gz.

File metadata

  • Download URL: pynougat-0.0.2.tar.gz
  • Upload date:
  • Size: 5.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pynougat-0.0.2.tar.gz
Algorithm Hash digest
SHA256 fe1beffca55e92544da91beb310d4ab8286e14bb2e5942e81e8b72812109f636
MD5 a7bf5d96851f632f76df224388560d6b
BLAKE2b-256 afd51d3c137b9ace6974be21e5d38ebb251f989f63198a5be9dfe97681f5740d

See more details on using hashes here.

File details

Details for the file pynougat-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: pynougat-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 6.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pynougat-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f1e21ee973c3dc9c72ba20e65624bed91fd8f39352b1dec4917472247f96c3b0
MD5 52945f602140e066d77b2f8849a0f673
BLAKE2b-256 d07fe24ee00409ec7e13c0d34ac335c8c1b7dc936ac97db9809d76bb4fd7060b

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