Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 290 lines (224 sloc) 12.312 kB
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
1 # redis-py
ec9d72c @andymccurdy readme sample usage
authored
2
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
3 The Python interface to the Redis key-value store.
bfe1ca5 @andymccurdy added support for setuptools, finally. props to Paul Hubbard for aut…
authored
4
331949d badge up the README
andy authored
5 [![Build Status](https://secure.travis-ci.org/andymccurdy/redis-py.png?branch=master)](http://travis-ci.org/andymccurdy/redis-py)
6
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
7 ## Installation
ec9d72c @andymccurdy readme sample usage
authored
8
9fea093 @andymccurdy typo in easy_install docs. fixes #79.
authored
9 $ sudo pip install redis
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
10
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
11 or alternatively (you really should be using pip though):
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
12
9fea093 @andymccurdy typo in easy_install docs. fixes #79.
authored
13 $ sudo easy_install redis
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
14
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
15 From source:
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
16
2abb7c1 @gnrfan Yet some more adjustments to the README
gnrfan authored
17 $ sudo python setup.py install
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
18
19
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
20 ## Getting Started
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
21
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
22 >>> import redis
7095c03 Renamed the base client class to StrictRedis, replacing ZADD and LREM…
andy authored
23 >>> r = redis.StrictRedis(host='localhost', port=6379, db=0)
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
24 >>> r.set('foo', 'bar')
25 True
26 >>> r.get('foo')
27 'bar'
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
28
7095c03 Renamed the base client class to StrictRedis, replacing ZADD and LREM…
andy authored
29 ## API Reference
30
31 The official Redis documentation does a great job of explaining each command in
32 detail (http://redis.io/commands). redis-py exposes two client classes that
33 implement these commands. The StrictRedis class attempts to adhere to the
34 official official command syntax. There are a few exceptions:
35
36 * SELECT: Not implemented. See the explanation in the Thread Safety section
37 below.
38 * DEL: 'del' is a reserved keyword in the Python syntax. Therefore redis-py
39 uses 'delete' instead.
40 * CONFIG GET|SET: These are implemented separately as config_get or config_set.
41 * MULTI/EXEC: These are implemented as part of the Pipeline class. Calling
42 the pipeline method and specifying use_transaction=True will cause the
43 pipeline to be wrapped with the MULTI and EXEC statements when it is executed.
44 See more about Pipelines below.
45 * SUBSCRIBE/LISTEN: Similar to pipelines, PubSub is implemented as a separate
46 class as it places the underlying connection in a state where it can't
47 execute non-pubsub commands. Calling the pubsub method from the Redis client
48 will return a PubSub instance where you can subscribe to channels and listen
49 for messages. You can call PUBLISH from both classes.
50
51 In addition to the changes above, the Redis class, a subclass of StrictRedis,
52 overrides several other commands to provide backwards compatibility with older
53 versions of redis-py:
54
55 * LREM: Order of 'num' and 'value' arguments reversed such that 'num' can
56 provide a default value of zero.
57 * ZADD: Redis specifies the 'score' argument before 'value'. These were swapped
58 accidentally when being implemented and not discovered until after people
59 were already using it. The Redis class expects *args in the form of:
60 name1, score1, name2, score2, ...
d5fdb5f @andymccurdy added a note about SETEX in the Redis class
authored
61 * SETEX: Order of 'time' and 'value' arguments reversed.
7095c03 Renamed the base client class to StrictRedis, replacing ZADD and LREM…
andy authored
62
63
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
64 ## More Detail
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
65
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
66 ### Connection Pools
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
67
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
68 Behind the scenes, redis-py uses a connection pool to manage connections to
69 a Redis server. By default, each Redis instance you create will in turn create
70 its own connection pool. You can override this behavior and use an existing
71 connection pool by passing an already created connection pool instance to the
72 connection_pool argument of the Redis class. You may choose to do this in order
73 to implement client side sharding or have finer grain control of how connections
74 are managed.
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
75
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
76 >>> pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
77 >>> r = redis.Redis(connection_pool=pool)
78
7315f9f @WoLpH Fixed "Connetion" typo
WoLpH authored
79 ### Connections
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
80
81 ConnectionPools manage a set of Connection instances. redis-py ships with two
82 types of Connections. The default, Connection, is a normal TCP socket based
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
83 connection. The UnixDomainSocketConnection allows for clients running on the
84 same device as the server to connect via a unix domain socket. To use a
88a3a3c @andymccurdy get the argument name correct
authored
85 UnixDomainSocketConnection connection, simply pass the unix_socket_path
86 argument, which is a string to the unix domain socket file. Additionally, make
87 sure the unixsocket parameter is defined in your redis.conf file. It's
88 commented out by default.
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
89
88a3a3c @andymccurdy get the argument name correct
authored
90 >>> r = redis.Redis(unix_socket_path='/tmp/redis.sock')
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
91
fc41ca2 @andymccurdy documentation fix for #138
authored
92 You can create your own Connection subclasses as well. This may be useful if
93 you want to control the socket behavior within an async framework. To
94 instantiate a client class using your own connection, you need to create
95 a connection pool, passing your class to the connection_class argument.
96 Other keyword parameters your pass to the pool will be passed to the class
97 specified during initialization.
98
99 >>> pool = redis.ConnectionPool(connection_class=YourConnectionClass,
100 your_arg='...', ...)
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
101
102 ### Parsers
103
104 Parser classes provide a way to control how responses from the Redis server
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
105 are parsed. redis-py ships with two parser classes, the PythonParser and the
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
106 HiredisParser. By default, redis-py will attempt to use the HiredisParser if
107 you have the hiredis module installed and will fallback to the PythonParser
108 otherwise.
109
110 Hiredis is a C library maintained by the core Redis team. Pieter Noordhuis was
111 kind enough to create Python bindings. Using Hiredis can provide up to a
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
112 10x speed improvement in parsing responses from the Redis server. The
113 performance increase is most noticeable when retrieving many pieces of data,
114 such as from LRANGE or SMEMBERS operations.
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
115
116 Hiredis is available on Pypi, and can be installed via pip or easy_install
117 just like redis-py.
118
119 $ pip install hiredis
120
121 or
122
123 $ easy_install hiredis
124
125 ### Response Callbacks
126
127 The client class uses a set of callbacks to cast Redis responses to the
128 appropriate Python type. There are a number of these callbacks defined on
129 the Redis client class in a dictionary called RESPONSE_CALLBACKS.
130
131 Custom callbacks can be added on a per-instance basis using the
132 set_response_callback method. This method accepts two arguments: a command
133 name and the callback. Callbacks added in this manner are only valid on the
134 instance the callback is added to. If you want to define or override a callback
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
135 globally, you should make a subclass of the Redis client and add your callback
136 to its REDIS_CALLBACKS class dictionary.
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
137
138 Response callbacks take at least one parameter: the response from the Redis
139 server. Keyword arguments may also be accepted in order to further control
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
140 how to interpret the response. These keyword arguments are specified during the
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
141 command's call to execute_command. The ZRANGE implementation demonstrates the
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
142 use of response callback keyword arguments with its "withscores" argument.
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
143
144 ## Thread Safety
145
146 Redis client instances can safely be shared between threads. Internally,
147 connection instances are only retrieved from the connection pool during
148 command execution, and returned to the pool directly after. Command execution
149 never modifies state on the client instance.
150
151 However, there is one caveat: the Redis SELECT command. The SELECT command
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
152 allows you to switch the database currently in use by the connection. That
153 database remains selected until another is selected or until the connection is
154 closed. This creates an issue in that connections could be returned to the pool
155 that are connected to a different database.
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
156
157 As a result, redis-py does not implement the SELECT command on client instances.
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
158 If you use multiple Redis databases within the same application, you should
159 create a separate client instance (and possibly a separate connection pool) for
160 each database.
47a4a7e @andymccurdy added ability for per-instance response callbacks. also, holy shit, d…
authored
161
ecc303c @andymccurdy Note about thread safety and piplines regarding #198
authored
162 It is not safe to pass PubSub or Pipeline objects between threads.
a834869 @andymccurdy notes about LREM order of args and PubSub objects not being threadsafe.
authored
163
9a182c7 documentation about pipelines
andy authored
164 ## Pipelines
165
166 Pipelines are a subclass of the base Redis class that provide support for
167 buffering multiple commands to the server in a single request. They can be used
168 to dramatically increase the performance of groups of commands by reducing the
169 number of back-and-forth TCP packets between the client and server.
170
171 Pipelines are quite simple to use:
172
173 >>> r = redis.Redis(...)
174 >>> r.set('bing', 'baz')
175 >>> # Use the pipeline() method to create a pipeline instance
628d65d @nicholasknight The pipeline object comes off of the existing Redis instance, not the…
nicholasknight authored
176 >>> pipe = r.pipeline()
9a182c7 documentation about pipelines
andy authored
177 >>> # The following SET commands are buffered
178 >>> pipe.set('foo', 'bar')
179 >>> pipe.get('bing')
180 >>> # the EXECUTE call sends all buffered commands to the server, returning
181 >>> # a list of responses, one for each command.
182 >>> pipe.execute()
183 [True, 'baz']
184
185 For ease of use, all commands being buffered into the pipeline return the
186 pipeline object itself. Therefore calls can be chained like:
187
188 >>> pipe.set('foo', 'bar').sadd('faz', 'baz').incr('auto_number').execute()
189 [True, True, 6]
190
191 In addition, pipelines can also ensure the buffered commands are executed
192 atomically as a group. This happens by default. If you want to disable the
193 atomic nature of a pipeline but still want to buffer commands, you can turn
194 off transactions.
195
196 >>> pipe = r.pipeline(transaction=False)
197
198 A common issue occurs when requiring atomic transactions but needing to
199 retrieve values in Redis prior for use within the transaction. For instance,
200 let's assume that the INCR command didn't exist and we need to build an atomic
201 version of INCR in Python.
202
203 The completely naive implementation could GET the value, increment it in
204 Python, and SET the new value back. However, this is not atomic because
205 multiple clients could be doing this at the same time, each getting the same
206 value from GET.
207
208 Enter the WATCH command. WATCH provides the ability to monitor one or more keys
209 prior to starting a transaction. If any of those keys change prior the
dc79eb8 @zakj Correct typos in README.md
zakj authored
210 execution of that transaction, the entire transaction will be canceled and a
9a182c7 documentation about pipelines
andy authored
211 WatchError will be raised. To implement our own client-side INCR command, we
212 could do something like this:
213
36ba087 @wolever Docs for proposed Pipeline context manager.
wolever authored
214 >>> with r.pipeline() as pipe:
215 ... while 1:
216 ... try:
217 ... # put a WATCH on the key that holds our sequence value
218 ... pipe.watch('OUR-SEQUENCE-KEY')
219 ... # after WATCHing, the pipeline is put into immediate execution
220 ... # mode until we tell it to start buffering commands again.
221 ... # this allows us to get the current value of our sequence
222 ... current_value = pipe.get('OUR-SEQUENCE-KEY')
223 ... next_value = int(current_value) + 1
224 ... # now we can put the pipeline back into buffered mode with MULTI
225 ... pipe.multi()
226 ... pipe.set('OUR-SEQUENCE-KEY', next_value)
227 ... # and finally, execute the pipeline (the set command)
228 ... pipe.execute()
229 ... # if a WatchError wasn't raised during execution, everything
230 ... # we just did happened atomically.
231 ... break
232 ... except WatchError:
233 ... # another client must have changed 'OUR-SEQUENCE-KEY' between
234 ... # the time we started WATCHing it and the pipeline's execution.
235 ... # our best bet is to just retry.
236 ... continue
237
2e18568 Pipelines can now be used as Context Managers. Thanks David Wolever. …
andy authored
238 Note that, because the Pipeline must bind to a single connection for the
dc79eb8 @zakj Correct typos in README.md
zakj authored
239 duration of a WATCH, care must be taken to ensure that the connection is
2e18568 Pipelines can now be used as Context Managers. Thanks David Wolever. …
andy authored
240 returned to the connection pool by calling the reset() method. If the
241 Pipeline is used as a context manager (as in the example above) reset()
dc79eb8 @zakj Correct typos in README.md
zakj authored
242 will be called automatically. Of course you can do this the manual way by
2e18568 Pipelines can now be used as Context Managers. Thanks David Wolever. …
andy authored
243 explicity calling reset():
36ba087 @wolever Docs for proposed Pipeline context manager.
wolever authored
244
9a182c7 documentation about pipelines
andy authored
245 >>> pipe = r.pipeline()
246 >>> while 1:
1292ca9 @wolever Fixing example to include `finally: pipe.reset()`
wolever authored
247 ... try:
248 ... pipe.watch('OUR-SEQUENCE-KEY')
36ba087 @wolever Docs for proposed Pipeline context manager.
wolever authored
249 ... ...
1292ca9 @wolever Fixing example to include `finally: pipe.reset()`
wolever authored
250 ... pipe.execute()
deffb95 @wolever Whoops, forgot `break`.
wolever authored
251 ... break
36ba087 @wolever Docs for proposed Pipeline context manager.
wolever authored
252 ... except WatchError:
1292ca9 @wolever Fixing example to include `finally: pipe.reset()`
wolever authored
253 ... continue
36ba087 @wolever Docs for proposed Pipeline context manager.
wolever authored
254 ... finally:
1292ca9 @wolever Fixing example to include `finally: pipe.reset()`
wolever authored
255 ... pipe.reset()
9a182c7 documentation about pipelines
andy authored
256
4c750ee Added a `transaction` convenience method that eliminates boilerplate …
andy authored
257 A convenience method named "transaction" exists for handling all the
258 boilerplate of handling and retrying watch errors. It takes a callable that
259 should expect a single parameter, a pipeline object, and any number of keys to
25888c8 docs
andy authored
260 be WATCHed. Our client-side INCR command above can be written like this,
4c750ee Added a `transaction` convenience method that eliminates boilerplate …
andy authored
261 which is much easier to read:
262
263 >>> def client_side_incr(pipe):
264 ... current_value = pipe.get('OUR-SEQUENCE-KEY')
265 ... next_value = int(current_value) + 1
266 ... pipe.multi()
267 ... pipe.set('OUR-SEQUENCE-KEY', next_value)
268 >>>
269 >>> r.transaction(client_side_incr, 'OUR-SEQUENCE-KEY')
270 [True]
271
2c4b66d @andymccurdy pipelines need the response_callback love, too. grammar fixes in docs
authored
272 ## Versioning scheme
273
274 redis-py is versioned after Redis. For example, redis-py 2.0.0 should
275 support all the commands available in Redis 2.0.0.
8379f18 @gnrfan Adding command reference and some other sections to the README
gnrfan authored
276
ec9d72c @andymccurdy readme sample usage
authored
277 Author
c148ede @andymccurdy * fix for #21, make only the "db" argument of select() required. If …
authored
278 ------
ec9d72c @andymccurdy readme sample usage
authored
279
12570a3 @andymccurdy Changelog updated, version incremented
authored
280 redis-py is developed and maintained by Andy McCurdy (sedrik@gmail.com).
281 It can be found here: http://github.com/andymccurdy/redis-py
bfe1ca5 @andymccurdy added support for setuptools, finally. props to Paul Hubbard for aut…
authored
282
12570a3 @andymccurdy Changelog updated, version incremented
authored
283 Special thanks to:
bfe1ca5 @andymccurdy added support for setuptools, finally. props to Paul Hubbard for aut…
authored
284
12570a3 @andymccurdy Changelog updated, version incremented
authored
285 * Ludovico Magnocavallo, author of the original Python Redis client, from
286 which some of the socket code is still used.
287 * Alexander Solovyov for ideas on the generic response callback system.
288 * Paul Hubbard for initial packaging support.
bfe1ca5 @andymccurdy added support for setuptools, finally. props to Paul Hubbard for aut…
authored
289
Something went wrong with that request. Please try again.