Skip to main content

A universal proxy class for Python that provides chainable, dot-notation access to nested data structures.

Project description

dotquery - A Universal Proxy Class for Python

dotquery provides a versatile Proxy class that wraps Python objects (dictionaries, lists, strings, and more) to allow for unified, chainable, dot-notation access to their elements.

It is particularly useful for navigating complex, nested data structures, such as those found in API responses or configuration files, without verbose key/index lookups.

Features

  • Unified Dot-Notation Access: Access dictionary keys, list indices, and object attributes with the same . syntax (e.g., proxy.key, getattr(proxy, '0'), proxy.attribute).
  • Automatic String Parsing: When a string is proxied, dotquery automatically tries to parse it in the following order:
    1. JSON: Deserializes a JSON string into a navigable object.
    2. URL: Parses an absolute or relative URL string into its components (scheme, path, query, fragment, etc.).
    3. URL Query String: Parses a query string (e.g., key=value&a=b) into a dictionary.
  • Recursive & Chainable: Every element accessed from a Proxy object is wrapped in another Proxy instance, allowing for deep, uninterrupted chaining (e.g., proxy.data.user.name).
  • Handles Complex Objects: Seamlessly works with objects like requests.PreparedRequest, allowing you to inspect the URL, headers, and body with the same dot-notation syntax.
  • Underlying Object Access: You can retrieve the original, unwrapped object at any point in the chain using the ._ property (e.g., proxy.data.user.id._).

Installation

This is a single-file utility. Simply place dotquery.py in your project. It has one external dependency, requests.

pip install requests

Usage

Basic Example: Dictionary and List

from dotquery import Proxy

data = {"user": {"name": "Alex", "tags": ["dev", "test"]}, "status": "active"}
p_data = Proxy(data)

# Access nested dictionary keys
print(p_data.user.name)  # Output: Proxy('Alex')

# Access the raw value
print(p_data.user.name._) # Output: Alex

# Access list elements (using getattr for numeric keys)
tag = getattr(p_data.user.tags, '1')
print(tag._) # Output: 'test'

# Accessing a non-existent key returns a Proxy of None
print(p_data.user.address._) # Output: None

String Parsing Examples

Proxy automatically detects and parses strings.

JSON String

json_str = '{"success": true, "data": {"id": 123}}'
p_json = Proxy(json_str)

print(p_json.data.id._) # Output: 123

URL and Nested Fragment Parsing

Proxy can parse a URL and recursively parse its components, like the fragment.

# The fragment itself is a URL-like string
url_str = "https://example.com/api?key=value#/profile?user=test"
p_url = Proxy(url_str)

print(p_url.scheme._)         # Output: 'https'
print(p_url.path._)           # Output: '/api'
print(p_url.query.key._)      # Output: 'value'

# The fragment is parsed recursively
print(p_url.fragment.path._)         # Output: '/profile'
print(p_url.fragment.query.user._)   # Output: 'test'

Advanced Example: requests.Request

dotquery makes inspecting requests objects incredibly simple.

import requests
from dotquery import Proxy, assert_eq

# 1. Create a request
url = "https://example.com/api#/profile?user=test"
req = requests.Request(
    method='POST',
    url=url,
    json={"user": {"name": "Alex"}},
    headers={"Content-Type": "application/json"}
)
prepared_req = req.prepare()

# 2. Wrap it in a Proxy
p_req = Proxy(prepared_req)

# 3. Access everything with dot notation
assert p_req.url.scheme == "https"
assert p_req.url.fragment.path == "/profile"
assert p_req.url.fragment.query.user == "test"
assert p_req.body.user.name == "Alex"
assert p_req.headers['Content-Type'] == "application/json"

Limitations

Numeric Property Access

Due to Python's syntax rules, you cannot access numeric indices directly with dot notation (e.g., proxy.0 is a SyntaxError). You must use the built-in getattr() function for this purpose, which dotquery fully supports.

p_list = Proxy(["apple", "banana"])

# Correct way
second_item = getattr(p_list, '1')
print(second_item._) # Output: 'banana'

# Incorrect way
# p_list.1 # This will raise a SyntaxError

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

dotquery-0.1.0.tar.gz (5.6 kB view details)

Uploaded Source

Built Distribution

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

dotquery-0.1.0-py3-none-any.whl (5.8 kB view details)

Uploaded Python 3

File details

Details for the file dotquery-0.1.0.tar.gz.

File metadata

  • Download URL: dotquery-0.1.0.tar.gz
  • Upload date:
  • Size: 5.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for dotquery-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3dfdeff49efce440bc3747104c2c6b32339fd89b74a30d6273f66618ee3f88d5
MD5 9323f240caa80d7c516230d8892f04a3
BLAKE2b-256 435b3168f57550863988e7d4465f2431fb0018cea025ff16701ed171d8da5002

See more details on using hashes here.

File details

Details for the file dotquery-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dotquery-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for dotquery-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 482717070203a80fb889f659e4822777713b7e9090fe363afa64e1c7ff968583
MD5 44e2be9d74885d20bf76525e2f44cf9e
BLAKE2b-256 47678a7cf30acc4f9d7dd75734fb7f44d557f28478d5e0e9597b1ccb1a307f53

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