Nougat 🍫
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.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Made with ❤️ for all Python developers tired of KeyError exceptions and messy data.get('obj', {}).get('key', None) chains
Metadata
Release files for pynougat 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pynougat-0.0.2.tar.gz | 5.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pynougat-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.5 kB
Release files / pynougat-0.0.2.tar.gz
| Download URL | pynougat-0.0.2.tar.gz |
|---|---|
| Size | 5.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fe1beffca55e92544da91beb310d4ab8286e14bb2e5942e81e8b72812109f636
|
|
BLAKE2b-256 checksum How to use checksums |
afd51d3c137b9ace6974be21e5d38ebb251f989f63198a5be9dfe97681f5740d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Release files / pynougat-0.0.2-py3-none-any.whl
| Download URL | pynougat-0.0.2-py3-none-any.whl |
|---|---|
| Size | 6.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1e21ee973c3dc9c72ba20e65624bed91fd8f39352b1dec4917472247f96c3b0
|
|
BLAKE2b-256 checksum How to use checksums |
d07fe24ee00409ec7e13c0d34ac335c8c1b7dc936ac97db9809d76bb4fd7060b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Security for pynougat 0.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.