Skip to main content

A functional data navigation tool for Python

Project description

DataDot (DD) 🔍

WIP

中文文档 | 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

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

datadot-1.0.0.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

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

datadot-1.0.0-py3-none-any.whl (5.0 kB view details)

Uploaded Python 3

File details

Details for the file datadot-1.0.0.tar.gz.

File metadata

  • Download URL: datadot-1.0.0.tar.gz
  • Upload date:
  • Size: 13.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for datadot-1.0.0.tar.gz
Algorithm Hash digest
SHA256 10d44a4277813d1f8ce7fd49dacf05c61bfc61ea8f50066279bfe2977ff0b208
MD5 44e2cc49c61222259372adc3c462fc84
BLAKE2b-256 405db3c7ae20b9095004ec8e5a5ac1c85f2483189950c4554d9e7f136777bb19

See more details on using hashes here.

Provenance

The following attestation bundles were made for datadot-1.0.0.tar.gz:

Publisher: workflow.yml on zqqqqz2000/datadot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file datadot-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: datadot-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 5.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for datadot-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 65cda58f57d2b9c4172d193f6c9e7952bfea033b0fb0237985133496a08c980f
MD5 ab65c823ea5c641dd67cfef5162f1fa1
BLAKE2b-256 7e8707617b02d3a989977ebf6bbcf0bc81b1b4196ac68af53e5db5aa99ae6c4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for datadot-1.0.0-py3-none-any.whl:

Publisher: workflow.yml on zqqqqz2000/datadot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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