DataDot (DD) 🔍
中文文档 | English
DataDot (DD) is a Python library designed to simplify data access. It provides a chain-style calling method to safely access nested data structures without cumbersome null checks.
Key Features
- 🔗 Chain-style API
- 🛡️ Safe attribute and index access
- 🔒 Null-safe handling (using
._modifier) - 🔄 Data structure expansion operations
- 📝 Friendly error messages
Examples
# Assume we have the following nested data structure
data = {
"users": [
{"name": "Zhang San", "details": {"age": 30, "email": "zhangsan@example.com"}},
{"name": "Li Si", "details": {"age": 25, "email": "lisi@example.com"}}
]
}
# Using DD to access data ✨
from dd import dd
# Get the email of the first user 📧
email = dd(data).users[0].details.email()
print(email) # Output: zhangsan@example.com
# Null-safe handling 🛡️
missing = dd(data)._.users[3].details.email()
print(missing) # Output: None instead of raising an exception
# Expansion operation to get all user names 👥
names = dd(data).users[...].name()
print(names) # Output: ['Zhang San', 'Li Si']
✨ Features
- 🔗 Chainable API: Easy navigation through nested data with dot notation
- 🛡️ Error Handling: Beautiful error messages with path information
- 🔒 Null Safety: Optional null-safe operations with
._(applies to all subsequent operations) - 🔄 List/Dict Expansion: Process all items in a collection with
[...] - ⏳ Lazy Evaluation: Operations are recorded and only executed when the final value is needed
📦 Installation
pip install datadot
🚀 Quick Start
🔰 Basic Usage
from dd import dd
# Simple data access
data = {"users": [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]}
alice_age = dd(data).users[0].age() # Returns 30
# With conversion function
is_adult = dd(data).users[0].age(lambda x: x >= 18) # Returns True
🛡️ Null Safety
# Traditional way - will raise AttributeError 💥
data = {"users": None}
try:
users = data["users"][0].name
except AttributeError:
print("Error accessing attribute")
# With dd - safe navigation ✅
# Once ._ is used, all subsequent operations become null-safe automatically
result = dd(data)._.users[0].name() # Returns None without error
🔄 List/Dict Expansion
# Get all user names
data = {"users": [{"name": "Alice"}, {"name": "Bob"}, {"name": "Charlie"}]}
names = dd(data).users[...].name() # Returns ["Alice", "Bob", "Charlie"]
# Get all values from a dictionary
config = {"server": {"ports": {"http": 80, "https": 443}}}
ports = dd(config).server.ports[...]() # Returns [80, 443]
🔀 Combining Features
# Safely get all user ages from potentially null data
data = {"groups": [{"users": None}, {"users": [{"name": "Alice", "age": 30}]}]}
# No need to repeat ._ as it applies to all subsequent operations
ages = dd(data).groups[...]._.users[...].age() # Returns [[], [30, 15]]
# Filter adult users
adult_names = dd(data).groups[...]._.users[...](
lambda users_groups: [
[user["name"] for user in (users or []) if user.get("age", 0) >= 18]
for users in users_groups
]
) # Returns [[], ["Alice"]]
⚠️ Error Handling
# Accessing a non-existent key with descriptive error
data = {"users": [{"name": "Alice"}]}
try:
dd(data).users[0].email()
except Exception as e:
print(e) # Prints: "Failed to get attribute 'email': 'dict' object has no attribute 'email'
# at path: dd.users[0].email, value: {'name': 'Alice'}"
🧙♂️ Advanced Usage
🧮 Custom Transformations
# Apply transformations to extracted data
data = {"items": [{"price": 10}, {"price": 20}, {"price": 30}]}
total = dd(data).items[...].price(lambda prices: sum(prices)) # Returns 60
# Format all names to uppercase
data = {"users": [{"name": "alice"}, {"name": "bob"}]}
upper_names = dd(data).users[...].name(lambda names: [n.upper() for n in names])
# Returns ["ALICE", "BOB"]
🌐 Working with APIs
import requests
from dd import dd
# Safely navigate through API response with a single ._ for the entire chain
response = requests.get("https://api.example.com/data").json()
first_tag = dd(response)._.data.items[0].tags[0]() # Safely get the first tag, even if any part is None
# Process all items safely
all_prices = dd(response)._.data.items[...].price() # Get all prices, handling nulls
📄 License
MIT
Release files for datadot 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| datadot-1.0.0.tar.gz | 13.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| datadot-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.8 kB
Release files / datadot-1.0.0.tar.gz
| Download URL | datadot-1.0.0.tar.gz |
|---|---|
| Size | 13.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
10d44a4277813d1f8ce7fd49dacf05c61bfc61ea8f50066279bfe2977ff0b208
|
|
BLAKE2b-256 checksum How to use checksums |
405db3c7ae20b9095004ec8e5a5ac1c85f2483189950c4554d9e7f136777bb19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 8, 2025.
Transparency logRelease files / datadot-1.0.0-py3-none-any.whl
| Download URL | datadot-1.0.0-py3-none-any.whl |
|---|---|
| Size | 5.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
65cda58f57d2b9c4172d193f6c9e7952bfea033b0fb0237985133496a08c980f
|
|
BLAKE2b-256 checksum How to use checksums |
7e8707617b02d3a989977ebf6bbcf0bc81b1b4196ac68af53e5db5aa99ae6c4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 8, 2025.
Transparency log