0
# Querystring Parser
1
2
A Python library that parses query strings into nested dictionaries, handling complex bracket notation that Django's standard QueryDict treats as literal strings. Converts form data like `section[0]['words'][2]=value` into proper nested Python dictionaries for easier data manipulation.
3
4
## Package Information
5
6
- **Package Name**: querystring_parser
7
- **Language**: Python (2.7 and 3.x compatible)
8
- **Installation**: `pip install querystring_parser`
9
- **Dependencies**: `six` (Python 2/3 compatibility)
10
11
## Core Imports
12
13
```python
14
from querystring_parser import parser
15
from querystring_parser import builder
16
```
17
18
Individual function imports:
19
20
```python
21
from querystring_parser.parser import parse, MalformedQueryStringError
22
from querystring_parser.builder import build
23
```
24
25
## Basic Usage
26
27
```python
28
from querystring_parser import parser
29
30
# Parse a query string with nested parameters
31
query_string = "section[1]['words'][2]=a§ion[0]['words'][2]=a§ion[0]['words'][2]=b"
32
result = parser.parse(query_string)
33
34
# Output: {u'section': {0: {u'words': {2: [u'a', u'b']}}, 1: {u'words': {2: u'a'}}}}
35
print(result)
36
37
# Convert back to query string
38
from querystring_parser import builder
39
rebuilt_query = builder.build(result)
40
print(rebuilt_query)
41
```
42
43
## Capabilities
44
45
### Query String Parsing
46
47
Converts query strings with bracket notation into nested Python dictionaries, properly handling arrays and nested structures.
48
49
```python { .api }
50
def parse(query_string, unquote=True, normalized=False, encoding=DEFAULT_ENCODING):
51
"""
52
Parse query string into nested dictionary structure.
53
54
Parameters:
55
- query_string (str|bytes): Query string to parse
56
- unquote (bool): Whether to URL-decode the query string (default: True)
57
- normalized (bool): Convert numeric dict keys to proper lists (default: False)
58
- encoding (str|None): Encoding for decoding keys/values (default: DEFAULT_ENCODING)
59
60
Returns:
61
dict: Nested dictionary representing parsed query string
62
63
Raises:
64
MalformedQueryStringError: When query string is malformed
65
"""
66
```
67
68
**Usage Examples:**
69
70
```python
71
from querystring_parser.parser import parse
72
73
# Basic parsing
74
result = parse("name=John&age=30")
75
# Returns: {'name': 'John', 'age': '30'}
76
77
# Nested structures
78
result = parse("user[name]=John&user[details][age]=30")
79
# Returns: {'user': {'name': 'John', 'details': {'age': '30'}}}
80
81
# Array handling
82
result = parse("items[0]=apple&items[1]=banana")
83
# Returns: {'items': {0: 'apple', 1: 'banana'}}
84
85
# Normalized output (converts numeric keys to lists)
86
result = parse("items[0]=apple&items[1]=banana", normalized=True)
87
# Returns: {'items': ['apple', 'banana']}
88
89
# Custom encoding
90
result = parse("name=%D8%B9%D9%84%DB%8C", encoding='utf-8')
91
# Returns: {'name': 'علی'}
92
93
# Handle bytes input
94
result = parse(b"name=John&age=30")
95
# Returns: {'name': 'John', 'age': '30'}
96
```
97
98
### Query String Building
99
100
Converts nested Python dictionaries and lists back into query string format with proper bracket notation.
101
102
```python { .api }
103
def build(item, encoding=None):
104
"""
105
Convert nested dictionary/list structure to query string format.
106
107
Parameters:
108
- item (dict|list): Dictionary or list to convert to query string
109
- encoding (str|None): Optional encoding for URL encoding (default: None)
110
111
Returns:
112
str: Query string representation of the input structure
113
"""
114
```
115
116
**Usage Examples:**
117
118
```python
119
from querystring_parser.builder import build
120
121
# Basic dictionary
122
data = {'name': 'John', 'age': '30'}
123
result = build(data)
124
# Returns: "name=John&age=30"
125
126
# Nested structures
127
data = {'user': {'name': 'John', 'details': {'age': '30'}}}
128
result = build(data)
129
# Returns: "user[name]=John&user[details][age]=30"
130
131
# Lists and arrays
132
data = {'items': ['apple', 'banana']}
133
result = build(data)
134
# Returns: "items=apple&items=banana"
135
136
# Mixed nested structures
137
data = {
138
'section': {
139
0: {'words': {2: ['a', 'b']}},
140
1: {'words': {2: 'c'}}
141
}
142
}
143
result = build(data)
144
# Returns: "section[0][words][2]=a§ion[0][words][2]=b§ion[1][words][2]=c"
145
146
# Custom encoding
147
data = {'name': 'علی'}
148
result = build(data, encoding='utf-8')
149
# Returns: "name=%D8%B9%D9%84%DB%8C"
150
```
151
152
### Error Handling
153
154
Handles malformed query strings with specific exception for debugging and error recovery.
155
156
```python { .api }
157
class MalformedQueryStringError(Exception):
158
"""
159
Raised when query string cannot be parsed due to malformed syntax.
160
161
Common causes:
162
- Missing equals sign in key-value pairs
163
- Unclosed bracket notation
164
- Invalid bracket syntax
165
"""
166
```
167
168
**Usage Examples:**
169
170
```python
171
from querystring_parser.parser import parse, MalformedQueryStringError
172
173
try:
174
# This will raise an exception due to missing equals sign
175
result = parse("name&age=30", unquote=False)
176
except MalformedQueryStringError as e:
177
print(f"Failed to parse query string: {e}")
178
179
try:
180
# This will raise an exception due to unclosed bracket
181
result = parse("section[0[words]=value", unquote=False)
182
except MalformedQueryStringError as e:
183
print(f"Failed to parse query string: {e}")
184
```
185
186
## Types
187
188
```python { .api }
189
# Module constants
190
DEFAULT_ENCODING = 'utf-8' # On Python 2, None on Python 3
191
192
# Helper functions (internal but potentially useful)
193
def has_variable_name(s):
194
"""Check if string has variable name before bracket notation."""
195
196
def more_than_one_index(s, brackets=2):
197
"""Search for multiple sets of bracket pairs."""
198
199
def get_key(s):
200
"""Extract key from between brackets, removing quotes."""
201
202
def is_number(s):
203
"""Check if string represents a number (for array indices)."""
204
205
def parser_helper(key, val):
206
"""Recursive helper for main parse function."""
207
```
208
209
## Key Features
210
211
- **Nested Structure Support**: Handles complex bracket notation like `section[0]['words'][2]`
212
- **Python 2/3 Compatibility**: Works with both Python 2.7 and 3.x
213
- **Flexible Input**: Accepts both string and bytes input
214
- **URL Encoding/Decoding**: Automatic URL decoding with custom encoding support
215
- **List Normalization**: Optional conversion of numeric dictionary keys to proper Python lists
216
- **Round-trip Compatibility**: Parse and build functions work together seamlessly
217
- **Error Handling**: Clear exceptions for malformed input with specific error types
218
- **Performance**: Comparable speed to Django's QueryDict for simple cases