File: examples.rst

package info (click to toggle)
dotty-dict 1.3.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 352 kB
  • sloc: python: 1,166; makefile: 192; sh: 5
file content (188 lines) | stat: -rw-r--r-- 4,768 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
========
Examples
========

Yes, I know it's dangerous to follow code examples.
Usually examples aren't in sync with real source code.

But I found a solution ... I hope!

.. note:: | All examples are derived from real code hooked to Pytest.
          | Every change in source code enforce change in examples.
          | **Outdated examples == failed build**.
          |
          | You can check at https://github.com/pawelzny/dotty_dict/blob/master/tests/test_examples.py

.. seealso:: Look at :ref:`Public API` for more details.


******
Basics
******

The easiest way to use Dotty dict is with function factory.
Factory takes only one, optional dictionary as argument.

If leaved empty, factory function will create new, empty dictionary.


Wrap existing dict
==================

.. literalinclude:: ../example/basics.py
   :language: python
   :dedent: 4
   :start-after: wrap_existing_dict
   :end-before: # end of wrap_existing_dict


Create new dotty
================

.. literalinclude:: ../example/basics.py
   :language: python
   :dedent: 4
   :start-after: create_new_dotty
   :end-before: # end of create_new_dotty


Builtin methods
===============

Dotty exposes all native to dict, builtin methods.
Only change is made to method which uses key as input to accept dot notation.

.. literalinclude:: ../example/basics.py
   :language: python
   :dedent: 4
   :start-after: builtin_methods
   :end-before: # end of builtin_methods


********
Advanced
********

Lets simulate more real scenario. API requests and responses are often very complex
with many deeply nested keys. And when you need to check one of them it may
looks like: ``res.get('data', {}).get('service', {}).get('status', {}).get('current', False)``.

**It's awful!** All this empty dictionary fallback to dig in for current status!


Make API request
================

In this scenario we will send post request to create new user with superuser privileges.
Below there is example response as dictionary, and then the way to check granted privileges.

.. literalinclude:: ../example/advanced.py
   :language: python
   :dedent: 4
   :start-after: api_request
   :end-before: # end of api_request
   :emphasize-lines: 45


Access dict with embedded lists
===============================

This scenario shows how to access subfield in a list.

.. literalinclude:: ../example/advanced.py
   :language: python
   :dedent: 4
   :start-after: list_embedded
   :end-before: # end of list_embedded
   :emphasize-lines: 4


Access multiple fields with list slices
=======================================

This scenario shows how to access multiple subfields in a list of dicts.

.. literalinclude:: ../example/advanced.py
   :language: python
   :dedent: 4
   :start-after: list_slices
   :end-before: # end of list_slices
   :emphasize-lines: 4


Access numeric fields as dict keys
==================================

This scenario shows how to access numeric keys which should not be treated as list indices.

.. literalinclude:: ../example/advanced.py
   :language: python
   :dedent: 4
   :start-after: no_list_flag
   :end-before: # end of no_list_flag
   :emphasize-lines: 4


Escape character
================

In some cases we want to preserve dot in key name and do not treat it
as keys separator. It can by done with escape character.

.. literalinclude:: ../example/advanced.py
   :language: python
   :dedent: 4
   :start-after: escape_character
   :end-before: # end of escape_character


Escape the escape character
===========================

What if escape character should be preserved as integral key name,
but it happens to be placed right before separator character?

The answer is: Escape the escape character.

.. warning:: Be careful because backslashes in Python require special treatment.

.. literalinclude:: ../example/advanced.py
   :language: python
   :dedent: 4
   :start-after: escape_the_escape_character
   :end-before: # end of escape_the_escape_character


*************
Customization
*************

By default Dotty uses dot as keys separator and backslash as escape character.
In special occasions you may want to use different set of chars.

Customization require using Dotty class directly instead of factory function.


Custom separator
================

In fact any valid string can be used as separator.

.. literalinclude:: ../example/customization.py
   :language: python
   :dedent: 4
   :start-after: custom_separator
   :end-before: # end of custom_separator


Custom escape char
==================

As separator, escape character can be any valid string
not only single character.

.. literalinclude:: ../example/customization.py
   :language: python
   :dedent: 4
   :start-after: custom_escape_char
   :end-before: # end of custom_escape_char