Remove vendor/vendor-local dependencies.

This commit is contained in:
Safwan Rahman 2015-10-17 18:21:04 +06:00 коммит произвёл John Giannelos
Родитель 276639f814
Коммит 3e9431ecf4
1962 изменённых файлов: 371 добавлений и 285673 удалений

52
.gitmodules поставляемый
Просмотреть файл

@ -1,52 +0,0 @@
[submodule "vendor-local/src/django-statsd"]
path = vendor-local/src/django-statsd
url = https://github.com/andymckay/django-statsd/
[submodule "vendor-local/src/django-autocomplete-light"]
path = vendor-local/src/django-autocomplete-light
url = git://github.com/yourlabs/django-autocomplete-light
[submodule "vendor"]
ignore = dirty
path = vendor
url = git://github.com/mozilla/playdoh-lib
[submodule "vendor-local/src/elasticutils"]
path = vendor-local/src/elasticutils
url = git://github.com/mozilla/elasticutils
[submodule "vendor-local/src/django-tastypie"]
path = vendor-local/src/django-tastypie
url = git://github.com/toastdriven/django-tastypie
[submodule "vendor-local/src/pystatsd"]
path = vendor-local/src/pystatsd
url = git://github.com/jsocol/pystatsd
[submodule "vendor-local/src/django-csp"]
path = vendor-local/src/django-csp
url = git://github.com/mozilla/django-csp
[submodule "vendor-local/src/happyforms"]
path = vendor-local/src/happyforms
url = https://github.com/mozilla/happyforms.git
[submodule "vendor-local/src/basket-client-submodule"]
path = vendor-local/src/basket-client-submodule
url = git://github.com/mozilla/basket-client.git
[submodule "mozillians/static/mozillians/css/less-prefixer"]
path = mozillians/static/mozillians/css/less-prefixer
url = https://github.com/JoelSutherland/LESS-Prefixer.git
[submodule "vendor-local/src/sorl-thumbnail"]
path = vendor-local/src/sorl-thumbnail
url = git://github.com/mariocesar/sorl-thumbnail
[submodule "vendor-local/src/django-waffle"]
path = vendor-local/src/django-waffle
url = git://github.com/jsocol/django-waffle.git
[submodule "vendor-local/src/django-browserid"]
path = vendor-local/src/django-browserid
url = git://github.com/mozilla/django-browserid/
[submodule "vendor-local/src/elasticsearch-py"]
path = vendor-local/src/elasticsearch-py
url = git://github.com/elasticsearch/elasticsearch-py.git
[submodule "vendor-local/src/urllib3"]
path = vendor-local/src/urllib3
url = git://github.com/shazow/urllib3.git
[submodule "vendor-local/src/django"]
path = vendor-local/src/django
url = git://github.com/django/django.git
[submodule "vendor-local/src/jingo"]
path = vendor-local/src/jingo
url = git://github.com/jbalogh/jingo.git

@ -1 +0,0 @@
Subproject commit f441f348096a89811ebd7a29b5089ca3bde036c1

Просмотреть файл

@ -30,7 +30,7 @@
@import "sandstone/sandstone.less";
@import "sandstone/sandstone-resp.less";
@import "mosaic.less";
@import "less-prefixer/prefixer.less";
@import "prefixer.less";
/* Fonts
==================== */

Просмотреть файл

@ -0,0 +1,370 @@
//---------------------------------------------------
// LESS Prefixer
//---------------------------------------------------
//
// All of the CSS3 fun, none of the prefixes!
//
// As a rule, you can use the CSS properties you
// would expect just by adding a '.':
//
// box-shadow => .box-shadow(@args)
//
// Also, when shorthand is available, arguments are
// not parameterized. Learn CSS, not LESS Prefixer.
//
// -------------------------------------------------
// TABLE OF CONTENTS
// (*) denotes a syntax-sugar helper
// -------------------------------------------------
//
// .animation(@args)
// .animation-delay(@delay)
// .animation-direction(@direction)
// .animation-duration(@duration)
// .animation-fill-mode(@mode)
// .animation-iteration-count(@count)
// .animation-name(@name)
// .animation-play-state(@state)
// .animation-timing-function(@function)
// .background-size(@args)
// .border-radius(@args)
// .box-shadow(@args)
// .inner-shadow(@args) *
// .box-sizing(@args)
// .border-box() *
// .content-box() *
// .columns(@args)
// .column-count(@count)
// .column-gap(@gap)
// .column-rule(@args)
// .column-width(@width)
// .gradient(@default,@start,@stop) *
// .linear-gradient-top(@default,@color1,@stop1,@color2,@stop2,[@color3,@stop3,@color4,@stop4])*
// .linear-gradient-left(@default,@color1,@stop1,@color2,@stop2,[@color3,@stop3,@color4,@stop4])*
// .opacity(@factor)
// .transform(@args)
// .transform-origin(@args)
// .transform-style(@style)
// .rotate(@deg)
// .scale(@factor)
// .translate(@x,@y)
// .translate3d(@x,@y,@z)
// .translateHardware(@x,@y) *
// .text-shadow(@args)
// .transition(@args)
// .transition-delay(@delay)
// .transition-duration(@duration)
// .transition-property(@property)
// .transition-timing-function(@function)
//
//
//
// Credit to LESS Elements for the motivation and
// to CSS3Please.com for implementation.
//
// Copyright (c) 2012 Joel Sutherland
// MIT Licensed:
// http://www.opensource.org/licenses/mit-license.php
//
//---------------------------------------------------
// Animation
.animation(@args) {
-webkit-animation: @args;
-moz-animation: @args;
-ms-animation: @args;
-o-animation: @args;
animation: @args;
}
.animation-delay(@delay) {
-webkit-animation-delay: @delay;
-moz-animation-delay: @delay;
-ms-animation-delay: @delay;
-o-animation-delay: @delay;
animation-delay: @delay;
}
.animation-direction(@direction) {
-webkit-animation-direction: @direction;
-moz-animation-direction: @direction;
-ms-animation-direction: @direction;
-o-animation-direction: @direction;
}
.animation-duration(@duration) {
-webkit-animation-duration: @duration;
-moz-animation-duration: @duration;
-ms-animation-duration: @duration;
-o-animation-duration: @duration;
}
.animation-fill-mode(@mode) {
-webkit-animation-fill-mode: @mode;
-moz-animation-fill-mode: @mode;
-ms-animation-fill-mode: @mode;
-o-animation-fill-mode: @mode;
animation-fill-mode: @mode;
}
.animation-iteration-count(@count) {
-webkit-animation-iteration-count: @count;
-moz-animation-iteration-count: @count;
-ms-animation-iteration-count: @count;
-o-animation-iteration-count: @count;
animation-iteration-count: @count;
}
.animation-name(@name) {
-webkit-animation-name: @name;
-moz-animation-name: @name;
-ms-animation-name: @name;
-o-animation-name: @name;
animation-name: @name;
}
.animation-play-state(@state) {
-webkit-animation-play-state: @state;
-moz-animation-play-state: @state;
-ms-animation-play-state: @state;
-o-animation-play-state: @state;
animation-play-state: @state;
}
.animation-timing-function(@function) {
-webkit-animation-timing-function: @function;
-moz-animation-timing-function: @function;
-ms-animation-timing-function: @function;
-o-animation-timing-function: @function;
animation-timing-function: @function;
}
// Background Size
.background-size(@args) {
-webkit-background-size: @args;
background-size: @args;
}
// Border Radius
.border-radius(@args) {
-webkit-border-radius: @args;
border-radius: @args;
background-clip: padding-box;
}
// Box Shadows
.box-shadow(@args) {
-webkit-box-shadow: @args;
box-shadow: @args;
}
.inner-shadow(@args) {
.box-shadow(inset @args);
}
// Box Sizing
.box-sizing(@args) {
-webkit-box-sizing: @args;
-moz-box-sizing: @args;
box-sizing: @args;
}
.border-box(){
.box-sizing(border-box);
}
.content-box(){
.box-sizing(content-box);
}
// Columns
.columns(@args) {
-webkit-columns: @args;
-moz-columns: @args;
columns: @args;
}
.column-count(@count) {
-webkit-column-count: @count;
-moz-column-count: @count;
column-count: @count;
}
.column-gap(@gap) {
-webkit-column-gap: @gap;
-moz-column-gap: @gap;
column-gap: @gap;
}
.column-width(@width) {
-webkit-column-width: @width;
-moz-column-width: @width;
column-width: @width;
}
.column-rule(@args) {
-webkit-column-rule: @args;
-moz-column-rule: @args;
column-rule: @args;
}
// Gradients
.gradient(@default: #F5F5F5, @start: #EEE, @stop: #FFF) {
.linear-gradient-top(@default,@start,0%,@stop,100%);
}
.linear-gradient-top(@default,@color1,@stop1,@color2,@stop2) {
background-color: @default;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(@stop1, @color1), color-stop(@stop2 @color2));
background-image: -webkit-linear-gradient(top, @color1 @stop1, @color2 @stop2);
background-image: -moz-linear-gradient(top, @color1 @stop1, @color2 @stop2);
background-image: -ms-linear-gradient(top, @color1 @stop1, @color2 @stop2);
background-image: -o-linear-gradient(top, @color1 @stop1, @color2 @stop2);
background-image: linear-gradient(top, @color1 @stop1, @color2 @stop2);
}
.linear-gradient-top(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3) {
background-color: @default;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3));
background-image: -webkit-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: -moz-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: -ms-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: -o-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
}
.linear-gradient-top(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3,@color4,@stop4) {
background-color: @default;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3), color-stop(@stop4 @color4));
background-image: -webkit-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: -moz-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: -ms-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: -o-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
}
.linear-gradient-left(@default,@color1,@stop1,@color2,@stop2) {
background-color: @default;
background-image: -webkit-gradient(linear, left top, left top, color-stop(@stop1, @color1), color-stop(@stop2 @color2));
background-image: -webkit-linear-gradient(left, @color1 @stop1, @color2 @stop2);
background-image: -moz-linear-gradient(left, @color1 @stop1, @color2 @stop2);
background-image: -ms-linear-gradient(left, @color1 @stop1, @color2 @stop2);
background-image: -o-linear-gradient(left, @color1 @stop1, @color2 @stop2);
background-image: linear-gradient(left, @color1 @stop1, @color2 @stop2);
}
.linear-gradient-left(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3) {
background-color: @default;
background-image: -webkit-gradient(linear, left top, left top, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3));
background-image: -webkit-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: -moz-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: -ms-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: -o-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
background-image: linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
}
.linear-gradient-left(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3,@color4,@stop4) {
background-color: @default;
background-image: -webkit-gradient(linear, left top, left top, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3), color-stop(@stop4 @color4));
background-image: -webkit-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: -moz-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: -ms-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: -o-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
background-image: linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
}
// Opacity
.opacity(@factor) {
@iefactor: @factor*100;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=@{iefactor})";
filter: ~"alpha(opacity=(@{iefactor}))";
opacity: @factor;
}
// Text Shadow
.text-shadow(@args) {
text-shadow: @args;
}
// Transforms
.transform(@args) {
-webkit-transform: @args;
-moz-transform: @args;
-ms-transform: @args;
-o-transform: @args;
transform: @args;
}
.transform-origin(@args) {
-webkit-transform-origin: @args;
-moz-transform-origin: @args;
-ms-transform-origin: @args;
-o-transform-origin: @args;
transform-origin: @args;
}
.transform-style(@style) {
-webkit-transform-style: @style;
-moz-transform-style: @style;
-ms-transform-style: @style;
-o-transform-style: @style;
transform-style: @style;
}
.rotate(@deg:45deg){
.transform(rotate(@deg));
}
.scale(@factor:.5){
.transform(scale(@factor));
}
.translate(@x,@y){
.transform(translate(@x,@y));
}
.translate3d(@x,@y,@z) {
.transform(translate3d(@x,@y,@z));
}
.translateHardware(@x,@y) {
.translate(@x,@y);
-webkit-transform: translate3d(@x,@y,0);
-moz-transform: translate3d(@x,@y,0);
-o-transform: translate3d(@x,@y,0);
-ms-transform: translate3d(@x,@y,0);
transform: translate3d(@x,@y,0);
}
// Transitions
.transition(@args:200ms) {
-webkit-transition: @args;
-moz-transition: @args;
-o-transition: @args;
-ms-transition: @args;
transition: @args;
}
.transition-delay(@delay:0) {
-webkit-transition-delay: @delay;
-moz-transition-delay: @delay;
-o-transition-delay: @delay;
-ms-transition-delay: @delay;
transition-delay: @delay;
}
.transition-duration(@duration:200ms) {
-webkit-transition-duration: @duration;
-moz-transition-duration: @duration;
-o-transition-duration: @duration;
-ms-transition-duration: @duration;
transition-duration: @duration;
}
.transition-property(@property:all) {
-webkit-transition-property: @property;
-moz-transition-property: @property;
-o-transition-property: @property;
-ms-transition-property: @property;
transition-property: @property;
}
.transition-timing-function(@function:ease) {
-webkit-transition-timing-function: @function;
-moz-transition-timing-function: @function;
-o-transition-timing-function: @function;
-ms-transition-timing-function: @function;
transition-timing-function: @function;
}

1
vendor

@ -1 +0,0 @@
Subproject commit c494144f80ead4398bdce27dcbb0e60b9edc065f

Просмотреть файл

@ -1,10 +0,0 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'celery==2.5.5','console_scripts','camqadm'
__requires__ = 'celery==2.5.5'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('celery==2.5.5', 'console_scripts', 'camqadm')()
)

Просмотреть файл

@ -1,10 +0,0 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'celery==2.5.5','console_scripts','celerybeat'
__requires__ = 'celery==2.5.5'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('celery==2.5.5', 'console_scripts', 'celerybeat')()
)

Просмотреть файл

@ -1,10 +0,0 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'celery==2.5.5','console_scripts','celeryctl'
__requires__ = 'celery==2.5.5'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('celery==2.5.5', 'console_scripts', 'celeryctl')()
)

Просмотреть файл

@ -1,10 +0,0 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'celery==2.5.5','console_scripts','celeryd'
__requires__ = 'celery==2.5.5'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('celery==2.5.5', 'console_scripts', 'celeryd')()
)

Просмотреть файл

@ -1,10 +0,0 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'celery==2.5.5','console_scripts','celeryd-multi'
__requires__ = 'celery==2.5.5'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('celery==2.5.5', 'console_scripts', 'celeryd-multi')()
)

Просмотреть файл

@ -1,10 +0,0 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'celery==2.5.5','console_scripts','celeryev'
__requires__ = 'celery==2.5.5'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('celery==2.5.5', 'console_scripts', 'celeryev')()
)

Просмотреть файл

@ -1,10 +0,0 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'django-celery==2.5.5','console_scripts','djcelerymon'
__requires__ = 'django-celery==2.5.5'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('django-celery==2.5.5', 'console_scripts', 'djcelerymon')()
)

Просмотреть файл

@ -1,34 +0,0 @@
#!/usr/bin/env python
"""
Python Markdown, the Command Line Script
========================================
This is the command line script for Python Markdown.
Basic use from the command line:
markdown source.txt > destination.html
Run "markdown --help" to see more options.
See markdown/__init__.py for information on using Python Markdown as a module.
## Authors and License
Started by [Manfred Stienstra](http://www.dwerg.net/). Continued and
maintained by [Yuri Takhteyev](http://www.freewisdom.org), [Waylan
Limberg](http://achinghead.com/) and [Artem Yunusov](http://blog.splyer.com).
Contact: markdown@freewisdom.org
Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
Copyright 200? Django Software Foundation (OrderedDict implementation)
Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
Copyright 2004 Manfred Stienstra (the original version)
License: BSD (see docs/LICENSE for details).
"""
if __name__ == '__main__':
from markdown.__main__ import run
run()

Просмотреть файл

@ -1,47 +0,0 @@
Metadata-Version: 1.1
Name: Markdown
Version: 2.3.1
Summary: Python implementation of Markdown.
Home-page: http://packages.python.org/Markdown/
Author: Waylan Limberg
Author-email: waylan [at] gmail.com
License: BSD License
Download-URL: http://pypi.python.org/packages/source/M/Markdown/Markdown-2.3.1.tar.gz
Description: This is a Python implementation of John Gruber's Markdown_.
It is almost completely compliant with the reference implementation,
though there are a few known issues. See Features_ for information
on what exactly is supported and what is not. Additional features are
supported by the `Available Extensions`_.
.. _Markdown: http://daringfireball.net/projects/markdown/
.. _Features: http://packages.python.org/Markdown/index.html#Features
.. _`Available Extensions`: http://packages.python.org/Markdown/extensions/index.html
Support
=======
You may ask for help and discuss various other issues on the
`mailing list`_ and report bugs on the `bug tracker`_.
.. _`mailing list`: http://lists.sourceforge.net/lists/listinfo/python-markdown-discuss
.. _`bug tracker`: http://github.com/waylan/Python-Markdown/issues
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Topic :: Communications :: Email :: Filters
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Filters
Classifier: Topic :: Text Processing :: Markup :: HTML

Просмотреть файл

@ -1,35 +0,0 @@
setup.cfg
Markdown.egg-info/PKG-INFO
Markdown.egg-info/SOURCES.txt
Markdown.egg-info/dependency_links.txt
Markdown.egg-info/top_level.txt
bin/markdown_py
markdown/__init__.py
markdown/__main__.py
markdown/__version__.py
markdown/blockparser.py
markdown/blockprocessors.py
markdown/inlinepatterns.py
markdown/odict.py
markdown/postprocessors.py
markdown/preprocessors.py
markdown/serializers.py
markdown/treeprocessors.py
markdown/util.py
markdown/extensions/__init__.py
markdown/extensions/abbr.py
markdown/extensions/admonition.py
markdown/extensions/attr_list.py
markdown/extensions/codehilite.py
markdown/extensions/def_list.py
markdown/extensions/extra.py
markdown/extensions/fenced_code.py
markdown/extensions/footnotes.py
markdown/extensions/headerid.py
markdown/extensions/meta.py
markdown/extensions/nl2br.py
markdown/extensions/sane_lists.py
markdown/extensions/smart_strong.py
markdown/extensions/tables.py
markdown/extensions/toc.py
markdown/extensions/wikilinks.py

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,64 +0,0 @@
../markdown/blockprocessors.py
../markdown/__init__.py
../markdown/blockparser.py
../markdown/serializers.py
../markdown/inlinepatterns.py
../markdown/odict.py
../markdown/postprocessors.py
../markdown/__main__.py
../markdown/preprocessors.py
../markdown/__version__.py
../markdown/util.py
../markdown/treeprocessors.py
../markdown/extensions/abbr.py
../markdown/extensions/extra.py
../markdown/extensions/__init__.py
../markdown/extensions/wikilinks.py
../markdown/extensions/footnotes.py
../markdown/extensions/tables.py
../markdown/extensions/toc.py
../markdown/extensions/attr_list.py
../markdown/extensions/codehilite.py
../markdown/extensions/smart_strong.py
../markdown/extensions/fenced_code.py
../markdown/extensions/sane_lists.py
../markdown/extensions/headerid.py
../markdown/extensions/meta.py
../markdown/extensions/nl2br.py
../markdown/extensions/def_list.py
../markdown/extensions/admonition.py
../markdown/blockprocessors.pyc
../markdown/__init__.pyc
../markdown/blockparser.pyc
../markdown/serializers.pyc
../markdown/inlinepatterns.pyc
../markdown/odict.pyc
../markdown/postprocessors.pyc
../markdown/__main__.pyc
../markdown/preprocessors.pyc
../markdown/__version__.pyc
../markdown/util.pyc
../markdown/treeprocessors.pyc
../markdown/extensions/abbr.pyc
../markdown/extensions/extra.pyc
../markdown/extensions/__init__.pyc
../markdown/extensions/wikilinks.pyc
../markdown/extensions/footnotes.pyc
../markdown/extensions/tables.pyc
../markdown/extensions/toc.pyc
../markdown/extensions/attr_list.pyc
../markdown/extensions/codehilite.pyc
../markdown/extensions/smart_strong.pyc
../markdown/extensions/fenced_code.pyc
../markdown/extensions/sane_lists.pyc
../markdown/extensions/headerid.pyc
../markdown/extensions/meta.pyc
../markdown/extensions/nl2br.pyc
../markdown/extensions/def_list.pyc
../markdown/extensions/admonition.pyc
./
PKG-INFO
SOURCES.txt
top_level.txt
dependency_links.txt
../../../bin/markdown_py

Просмотреть файл

@ -1 +0,0 @@
markdown

Просмотреть файл

@ -1,47 +0,0 @@
Metadata-Version: 1.1
Name: Markdown
Version: 2.4
Summary: Python implementation of Markdown.
Home-page: http://packages.python.org/Markdown/
Author: Waylan Limberg
Author-email: waylan [at] gmail.com
License: BSD License
Download-URL: http://pypi.python.org/packages/source/M/Markdown/Markdown-2.4.tar.gz
Description: This is a Python implementation of John Gruber's Markdown_.
It is almost completely compliant with the reference implementation,
though there are a few known issues. See Features_ for information
on what exactly is supported and what is not. Additional features are
supported by the `Available Extensions`_.
.. _Markdown: http://daringfireball.net/projects/markdown/
.. _Features: http://packages.python.org/Markdown/index.html#Features
.. _`Available Extensions`: http://packages.python.org/Markdown/extensions/index.html
Support
=======
You may ask for help and discuss various other issues on the
`mailing list`_ and report bugs on the `bug tracker`_.
.. _`mailing list`: http://lists.sourceforge.net/lists/listinfo/python-markdown-discuss
.. _`bug tracker`: http://github.com/waylan/Python-Markdown/issues
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Topic :: Communications :: Email :: Filters
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Filters
Classifier: Topic :: Text Processing :: Markup :: HTML

Просмотреть файл

@ -1,36 +0,0 @@
setup.cfg
Markdown.egg-info/PKG-INFO
Markdown.egg-info/SOURCES.txt
Markdown.egg-info/dependency_links.txt
Markdown.egg-info/top_level.txt
bin/markdown_py
markdown/__init__.py
markdown/__main__.py
markdown/__version__.py
markdown/blockparser.py
markdown/blockprocessors.py
markdown/inlinepatterns.py
markdown/odict.py
markdown/postprocessors.py
markdown/preprocessors.py
markdown/serializers.py
markdown/treeprocessors.py
markdown/util.py
markdown/extensions/__init__.py
markdown/extensions/abbr.py
markdown/extensions/admonition.py
markdown/extensions/attr_list.py
markdown/extensions/codehilite.py
markdown/extensions/def_list.py
markdown/extensions/extra.py
markdown/extensions/fenced_code.py
markdown/extensions/footnotes.py
markdown/extensions/headerid.py
markdown/extensions/meta.py
markdown/extensions/nl2br.py
markdown/extensions/sane_lists.py
markdown/extensions/smart_strong.py
markdown/extensions/smarty.py
markdown/extensions/tables.py
markdown/extensions/toc.py
markdown/extensions/wikilinks.py

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,66 +0,0 @@
../markdown/__version__.py
../markdown/preprocessors.py
../markdown/blockprocessors.py
../markdown/blockparser.py
../markdown/serializers.py
../markdown/odict.py
../markdown/__main__.py
../markdown/util.py
../markdown/inlinepatterns.py
../markdown/treeprocessors.py
../markdown/__init__.py
../markdown/postprocessors.py
../markdown/extensions/footnotes.py
../markdown/extensions/sane_lists.py
../markdown/extensions/meta.py
../markdown/extensions/admonition.py
../markdown/extensions/toc.py
../markdown/extensions/codehilite.py
../markdown/extensions/attr_list.py
../markdown/extensions/extra.py
../markdown/extensions/smarty.py
../markdown/extensions/wikilinks.py
../markdown/extensions/headerid.py
../markdown/extensions/__init__.py
../markdown/extensions/smart_strong.py
../markdown/extensions/tables.py
../markdown/extensions/nl2br.py
../markdown/extensions/abbr.py
../markdown/extensions/fenced_code.py
../markdown/extensions/def_list.py
../markdown/__version__.pyc
../markdown/preprocessors.pyc
../markdown/blockprocessors.pyc
../markdown/blockparser.pyc
../markdown/serializers.pyc
../markdown/odict.pyc
../markdown/__main__.pyc
../markdown/util.pyc
../markdown/inlinepatterns.pyc
../markdown/treeprocessors.pyc
../markdown/__init__.pyc
../markdown/postprocessors.pyc
../markdown/extensions/footnotes.pyc
../markdown/extensions/sane_lists.pyc
../markdown/extensions/meta.pyc
../markdown/extensions/admonition.pyc
../markdown/extensions/toc.pyc
../markdown/extensions/codehilite.pyc
../markdown/extensions/attr_list.pyc
../markdown/extensions/extra.pyc
../markdown/extensions/smarty.pyc
../markdown/extensions/wikilinks.pyc
../markdown/extensions/headerid.pyc
../markdown/extensions/__init__.pyc
../markdown/extensions/smart_strong.pyc
../markdown/extensions/tables.pyc
../markdown/extensions/nl2br.pyc
../markdown/extensions/abbr.pyc
../markdown/extensions/fenced_code.pyc
../markdown/extensions/def_list.pyc
./
SOURCES.txt
dependency_links.txt
top_level.txt
PKG-INFO
../../../bin/markdown_py

Просмотреть файл

@ -1 +0,0 @@
markdown

Просмотреть файл

@ -1,22 +0,0 @@
Metadata-Version: 1.1
Name: South
Version: 1.0.2
Summary: South: Migrations for Django
Home-page: http://south.aeracode.org/
Author: Andrew Godwin & Andy McCurdy
Author-email: south@aeracode.org
License: UNKNOWN
Download-URL: http://south.aeracode.org/wiki/Download
Description: South is an intelligent database migrations library for the Django web framework. It is database-independent and DVCS-friendly, as well as a whole host of other features.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7

Просмотреть файл

@ -1,123 +0,0 @@
README
setup.cfg
South.egg-info/PKG-INFO
South.egg-info/SOURCES.txt
South.egg-info/dependency_links.txt
South.egg-info/top_level.txt
south/__init__.py
south/exceptions.py
south/logger.py
south/models.py
south/modelsinspector.py
south/orm.py
south/signals.py
south/test_shim.py
south/v2.py
south/creator/__init__.py
south/creator/actions.py
south/creator/changes.py
south/creator/freezer.py
south/db/__init__.py
south/db/firebird.py
south/db/generic.py
south/db/mysql.py
south/db/oracle.py
south/db/postgresql_psycopg2.py
south/db/sqlite3.py
south/db/sql_server/__init__.py
south/db/sql_server/pyodbc.py
south/hacks/__init__.py
south/hacks/django_1_0.py
south/introspection_plugins/__init__.py
south/introspection_plugins/annoying_autoonetoone.py
south/introspection_plugins/django_audit_log.py
south/introspection_plugins/django_objectpermissions.py
south/introspection_plugins/django_tagging.py
south/introspection_plugins/django_taggit.py
south/introspection_plugins/django_timezones.py
south/introspection_plugins/geodjango.py
south/management/__init__.py
south/management/commands/__init__.py
south/management/commands/convert_to_south.py
south/management/commands/datamigration.py
south/management/commands/graphmigrations.py
south/management/commands/migrate.py
south/management/commands/migrationcheck.py
south/management/commands/schemamigration.py
south/management/commands/startmigration.py
south/management/commands/syncdb.py
south/management/commands/test.py
south/management/commands/testserver.py
south/migration/__init__.py
south/migration/base.py
south/migration/migrators.py
south/migration/utils.py
south/tests/__init__.py
south/tests/autodetection.py
south/tests/db.py
south/tests/db_firebird.py
south/tests/db_mysql.py
south/tests/freezer.py
south/tests/inspector.py
south/tests/logger.py
south/tests/logic.py
south/tests/brokenapp/__init__.py
south/tests/brokenapp/models.py
south/tests/brokenapp/migrations/0001_depends_on_unmigrated.py
south/tests/brokenapp/migrations/0002_depends_on_unknown.py
south/tests/brokenapp/migrations/0003_depends_on_higher.py
south/tests/brokenapp/migrations/0004_higher.py
south/tests/brokenapp/migrations/__init__.py
south/tests/circular_a/__init__.py
south/tests/circular_a/models.py
south/tests/circular_a/migrations/0001_first.py
south/tests/circular_a/migrations/__init__.py
south/tests/circular_b/__init__.py
south/tests/circular_b/models.py
south/tests/circular_b/migrations/0001_first.py
south/tests/circular_b/migrations/__init__.py
south/tests/deps_a/__init__.py
south/tests/deps_a/models.py
south/tests/deps_a/migrations/0001_a.py
south/tests/deps_a/migrations/0002_a.py
south/tests/deps_a/migrations/0003_a.py
south/tests/deps_a/migrations/0004_a.py
south/tests/deps_a/migrations/0005_a.py
south/tests/deps_a/migrations/__init__.py
south/tests/deps_b/__init__.py
south/tests/deps_b/models.py
south/tests/deps_b/migrations/0001_b.py
south/tests/deps_b/migrations/0002_b.py
south/tests/deps_b/migrations/0003_b.py
south/tests/deps_b/migrations/0004_b.py
south/tests/deps_b/migrations/0005_b.py
south/tests/deps_b/migrations/__init__.py
south/tests/deps_c/__init__.py
south/tests/deps_c/models.py
south/tests/deps_c/migrations/0001_c.py
south/tests/deps_c/migrations/0002_c.py
south/tests/deps_c/migrations/0003_c.py
south/tests/deps_c/migrations/0004_c.py
south/tests/deps_c/migrations/0005_c.py
south/tests/deps_c/migrations/__init__.py
south/tests/emptyapp/__init__.py
south/tests/emptyapp/models.py
south/tests/emptyapp/migrations/__init__.py
south/tests/fakeapp/__init__.py
south/tests/fakeapp/models.py
south/tests/fakeapp/migrations/0001_spam.py
south/tests/fakeapp/migrations/0002_eggs.py
south/tests/fakeapp/migrations/0003_alter_spam.py
south/tests/fakeapp/migrations/__init__.py
south/tests/non_managed/__init__.py
south/tests/non_managed/models.py
south/tests/non_managed/migrations/__init__.py
south/tests/otherfakeapp/__init__.py
south/tests/otherfakeapp/models.py
south/tests/otherfakeapp/migrations/0001_first.py
south/tests/otherfakeapp/migrations/0002_second.py
south/tests/otherfakeapp/migrations/0003_third.py
south/tests/otherfakeapp/migrations/__init__.py
south/utils/__init__.py
south/utils/datetime_utils.py
south/utils/py3.py

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,239 +0,0 @@
../south/orm.py
../south/exceptions.py
../south/__init__.py
../south/signals.py
../south/test_shim.py
../south/models.py
../south/logger.py
../south/v2.py
../south/modelsinspector.py
../south/creator/__init__.py
../south/creator/changes.py
../south/creator/actions.py
../south/creator/freezer.py
../south/db/mysql.py
../south/db/postgresql_psycopg2.py
../south/db/__init__.py
../south/db/sqlite3.py
../south/db/oracle.py
../south/db/generic.py
../south/db/firebird.py
../south/management/__init__.py
../south/introspection_plugins/django_taggit.py
../south/introspection_plugins/__init__.py
../south/introspection_plugins/django_timezones.py
../south/introspection_plugins/django_audit_log.py
../south/introspection_plugins/annoying_autoonetoone.py
../south/introspection_plugins/django_tagging.py
../south/introspection_plugins/geodjango.py
../south/introspection_plugins/django_objectpermissions.py
../south/hacks/__init__.py
../south/hacks/django_1_0.py
../south/migration/base.py
../south/migration/__init__.py
../south/migration/utils.py
../south/migration/migrators.py
../south/tests/__init__.py
../south/tests/db_mysql.py
../south/tests/autodetection.py
../south/tests/logger.py
../south/tests/freezer.py
../south/tests/db.py
../south/tests/logic.py
../south/tests/inspector.py
../south/tests/db_firebird.py
../south/db/sql_server/__init__.py
../south/db/sql_server/pyodbc.py
../south/management/commands/startmigration.py
../south/management/commands/convert_to_south.py
../south/management/commands/migrate.py
../south/management/commands/__init__.py
../south/management/commands/testserver.py
../south/management/commands/syncdb.py
../south/management/commands/schemamigration.py
../south/management/commands/test.py
../south/management/commands/migrationcheck.py
../south/management/commands/datamigration.py
../south/management/commands/graphmigrations.py
../south/tests/circular_a/__init__.py
../south/tests/circular_a/models.py
../south/tests/emptyapp/__init__.py
../south/tests/emptyapp/models.py
../south/tests/deps_a/__init__.py
../south/tests/deps_a/models.py
../south/tests/fakeapp/__init__.py
../south/tests/fakeapp/models.py
../south/tests/brokenapp/__init__.py
../south/tests/brokenapp/models.py
../south/tests/circular_b/__init__.py
../south/tests/circular_b/models.py
../south/tests/otherfakeapp/__init__.py
../south/tests/otherfakeapp/models.py
../south/tests/deps_c/__init__.py
../south/tests/deps_c/models.py
../south/tests/deps_b/__init__.py
../south/tests/deps_b/models.py
../south/tests/non_managed/__init__.py
../south/tests/non_managed/models.py
../south/tests/circular_a/migrations/__init__.py
../south/tests/circular_a/migrations/0001_first.py
../south/tests/emptyapp/migrations/__init__.py
../south/tests/deps_a/migrations/__init__.py
../south/tests/deps_a/migrations/0004_a.py
../south/tests/deps_a/migrations/0003_a.py
../south/tests/deps_a/migrations/0001_a.py
../south/tests/deps_a/migrations/0005_a.py
../south/tests/deps_a/migrations/0002_a.py
../south/tests/fakeapp/migrations/0002_eggs.py
../south/tests/fakeapp/migrations/__init__.py
../south/tests/fakeapp/migrations/0001_spam.py
../south/tests/fakeapp/migrations/0003_alter_spam.py
../south/tests/brokenapp/migrations/0001_depends_on_unmigrated.py
../south/tests/brokenapp/migrations/__init__.py
../south/tests/brokenapp/migrations/0003_depends_on_higher.py
../south/tests/brokenapp/migrations/0002_depends_on_unknown.py
../south/tests/brokenapp/migrations/0004_higher.py
../south/tests/circular_b/migrations/__init__.py
../south/tests/circular_b/migrations/0001_first.py
../south/tests/otherfakeapp/migrations/__init__.py
../south/tests/otherfakeapp/migrations/0002_second.py
../south/tests/otherfakeapp/migrations/0003_third.py
../south/tests/otherfakeapp/migrations/0001_first.py
../south/tests/deps_c/migrations/0005_c.py
../south/tests/deps_c/migrations/0001_c.py
../south/tests/deps_c/migrations/__init__.py
../south/tests/deps_c/migrations/0004_c.py
../south/tests/deps_c/migrations/0002_c.py
../south/tests/deps_c/migrations/0003_c.py
../south/tests/deps_b/migrations/0003_b.py
../south/tests/deps_b/migrations/0005_b.py
../south/tests/deps_b/migrations/__init__.py
../south/tests/deps_b/migrations/0004_b.py
../south/tests/deps_b/migrations/0002_b.py
../south/tests/deps_b/migrations/0001_b.py
../south/tests/non_managed/migrations/__init__.py
../south/utils/__init__.py
../south/utils/py3.py
../south/utils/datetime_utils.py
../south/orm.pyc
../south/exceptions.pyc
../south/__init__.pyc
../south/signals.pyc
../south/test_shim.pyc
../south/models.pyc
../south/logger.pyc
../south/v2.pyc
../south/modelsinspector.pyc
../south/creator/__init__.pyc
../south/creator/changes.pyc
../south/creator/actions.pyc
../south/creator/freezer.pyc
../south/db/mysql.pyc
../south/db/postgresql_psycopg2.pyc
../south/db/__init__.pyc
../south/db/sqlite3.pyc
../south/db/oracle.pyc
../south/db/generic.pyc
../south/db/firebird.pyc
../south/management/__init__.pyc
../south/introspection_plugins/django_taggit.pyc
../south/introspection_plugins/__init__.pyc
../south/introspection_plugins/django_timezones.pyc
../south/introspection_plugins/django_audit_log.pyc
../south/introspection_plugins/annoying_autoonetoone.pyc
../south/introspection_plugins/django_tagging.pyc
../south/introspection_plugins/geodjango.pyc
../south/introspection_plugins/django_objectpermissions.pyc
../south/hacks/__init__.pyc
../south/hacks/django_1_0.pyc
../south/migration/base.pyc
../south/migration/__init__.pyc
../south/migration/utils.pyc
../south/migration/migrators.pyc
../south/tests/__init__.pyc
../south/tests/db_mysql.pyc
../south/tests/autodetection.pyc
../south/tests/logger.pyc
../south/tests/freezer.pyc
../south/tests/db.pyc
../south/tests/logic.pyc
../south/tests/inspector.pyc
../south/tests/db_firebird.pyc
../south/db/sql_server/__init__.pyc
../south/db/sql_server/pyodbc.pyc
../south/management/commands/startmigration.pyc
../south/management/commands/convert_to_south.pyc
../south/management/commands/migrate.pyc
../south/management/commands/__init__.pyc
../south/management/commands/testserver.pyc
../south/management/commands/syncdb.pyc
../south/management/commands/schemamigration.pyc
../south/management/commands/test.pyc
../south/management/commands/migrationcheck.pyc
../south/management/commands/datamigration.pyc
../south/management/commands/graphmigrations.pyc
../south/tests/circular_a/__init__.pyc
../south/tests/circular_a/models.pyc
../south/tests/emptyapp/__init__.pyc
../south/tests/emptyapp/models.pyc
../south/tests/deps_a/__init__.pyc
../south/tests/deps_a/models.pyc
../south/tests/fakeapp/__init__.pyc
../south/tests/fakeapp/models.pyc
../south/tests/brokenapp/__init__.pyc
../south/tests/brokenapp/models.pyc
../south/tests/circular_b/__init__.pyc
../south/tests/circular_b/models.pyc
../south/tests/otherfakeapp/__init__.pyc
../south/tests/otherfakeapp/models.pyc
../south/tests/deps_c/__init__.pyc
../south/tests/deps_c/models.pyc
../south/tests/deps_b/__init__.pyc
../south/tests/deps_b/models.pyc
../south/tests/non_managed/__init__.pyc
../south/tests/non_managed/models.pyc
../south/tests/circular_a/migrations/__init__.pyc
../south/tests/circular_a/migrations/0001_first.pyc
../south/tests/emptyapp/migrations/__init__.pyc
../south/tests/deps_a/migrations/__init__.pyc
../south/tests/deps_a/migrations/0004_a.pyc
../south/tests/deps_a/migrations/0003_a.pyc
../south/tests/deps_a/migrations/0001_a.pyc
../south/tests/deps_a/migrations/0005_a.pyc
../south/tests/deps_a/migrations/0002_a.pyc
../south/tests/fakeapp/migrations/0002_eggs.pyc
../south/tests/fakeapp/migrations/__init__.pyc
../south/tests/fakeapp/migrations/0001_spam.pyc
../south/tests/fakeapp/migrations/0003_alter_spam.pyc
../south/tests/brokenapp/migrations/0001_depends_on_unmigrated.pyc
../south/tests/brokenapp/migrations/__init__.pyc
../south/tests/brokenapp/migrations/0003_depends_on_higher.pyc
../south/tests/brokenapp/migrations/0002_depends_on_unknown.pyc
../south/tests/brokenapp/migrations/0004_higher.pyc
../south/tests/circular_b/migrations/__init__.pyc
../south/tests/circular_b/migrations/0001_first.pyc
../south/tests/otherfakeapp/migrations/__init__.pyc
../south/tests/otherfakeapp/migrations/0002_second.pyc
../south/tests/otherfakeapp/migrations/0003_third.pyc
../south/tests/otherfakeapp/migrations/0001_first.pyc
../south/tests/deps_c/migrations/0005_c.pyc
../south/tests/deps_c/migrations/0001_c.pyc
../south/tests/deps_c/migrations/__init__.pyc
../south/tests/deps_c/migrations/0004_c.pyc
../south/tests/deps_c/migrations/0002_c.pyc
../south/tests/deps_c/migrations/0003_c.pyc
../south/tests/deps_b/migrations/0003_b.pyc
../south/tests/deps_b/migrations/0005_b.pyc
../south/tests/deps_b/migrations/__init__.pyc
../south/tests/deps_b/migrations/0004_b.pyc
../south/tests/deps_b/migrations/0002_b.pyc
../south/tests/deps_b/migrations/0001_b.pyc
../south/tests/non_managed/migrations/__init__.pyc
../south/utils/__init__.pyc
../south/utils/py3.pyc
../south/utils/datetime_utils.pyc
./
top_level.txt
PKG-INFO
SOURCES.txt
dependency_links.txt

Просмотреть файл

@ -1 +0,0 @@
south

Просмотреть файл

@ -1,126 +0,0 @@
Metadata-Version: 1.0
Name: amqp
Version: 1.0.6
Summary: Low-level AMQP client for Python (fork of amqplib)
Home-page: http://github.com/celery/py-amqp
Author: Ask Solem
Author-email: pyamqp@celeryproject.org
License: LGPL
Description: =====================================================================
Python AMQP 0.9.1 client library
=====================================================================
:Version: 1.0.6
:Web: http://amqp.readthedocs.org/
:Download: http://pypi.python.org/pypi/amqp/
:Source: http://github.com/celery/py-amqp/
:Keywords: amqp, rabbitmq
About
=====
This is a fork of amqplib_ which was originally written by Barry Pederson.
It is maintained by the Celery_ project, and used by `kombu`_ as a pure python
alternative when `librabbitmq`_ is not available.
This library should be API compatible with `librabbitmq`_.
.. _amqplib: http://pypi.python.org/pypi/amqplib
.. _Celery: http://celeryproject.org/
.. _kombu: http://kombu.readthedocs.org/
.. _librabbitmq: http://pypi.python.org/pypi/librabbitmq
Differences from `amqplib`_
===========================
- Supports draining events from multiple channels (``Connection.drain_events``)
- Support for timeouts
- Channels are restored after channel error, instead of having to close the
connection.
- Support for heartbeats
- ``Connection.heartbeat_tick(rate=2)`` must called at regular intervals
(half of the heartbeat value if rate is 2).
- Or some other scheme by using ``Connection.send_heartbeat``.
- Supports RabbitMQ extensions:
- Consumer Cancel Notifications
- by default a cancel results in ``ChannelError`` being raised
- but not if a ``on_cancel`` callback is passed to ``basic_consume``.
- Publisher confirms
- ``Channel.confirm_select()`` enables publisher confirms.
- ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
to be called when a message is confirmed. This callback is then
called with the signature ``(delivery_tag, multiple)``.
- Exchange-to-exchange bindings: ``exchange_bind`` / ``exchange_unbind``.
- ``Channel.confirm_select()`` enables publisher confirms.
- ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
to be called when a message is confirmed. This callback is then
called with the signature ``(delivery_tag, multiple)``.
- Support for ``basic_return``
- Uses AMQP 0-9-1 instead of 0-8.
- ``Channel.access_request`` and ``ticket`` arguments to methods
**removed**.
- Supports the ``arguments`` argument to ``basic_consume``.
- ``internal`` argument to ``exchange_declare`` removed.
- ``auto_delete`` argument to ``exchange_declare`` deprecated
- ``insist`` argument to ``Connection`` removed.
- ``Channel.alerts`` has been removed.
- Support for ``Channel.basic_recover_async``.
- ``Channel.basic_recover`` deprecated.
- Exceptions renamed to have idiomatic names:
- ``AMQPException`` -> ``AMQPError``
- ``AMQPConnectionException`` -> ConnectionError``
- ``AMQPChannelException`` -> ChannelError``
- ``Connection.known_hosts`` removed.
- ``Connection`` no longer supports redirects.
- ``exchange`` argument to ``queue_bind`` can now be empty
to use the "default exchange".
- Adds ``Connection.is_alive`` that tries to detect
whether the connection can still be used.
- Adds ``Connection.connection_errors`` and ``.channel_errors``,
a list of recoverable errors.
- Exposes the underlying socket as ``Connection.sock``.
- Adds ``Channel.no_ack_consumers`` to keep track of consumer tags
that set the no_ack flag.
- Slightly better at error recovery
Further
=======
- Differences between AMQP 0.8 and 0.9.1
http://www.rabbitmq.com/amqp-0-8-to-0-9-1.html
- AMQP 0.9.1 Quick Reference
http://www.rabbitmq.com/amqp-0-9-1-quickref.html
- RabbitMQ Extensions
http://www.rabbitmq.com/extensions.html
- For more information about AMQP, visit
http://www.amqp.org
- For other Python client libraries see:
http://www.rabbitmq.com/devtools.html#python-dev
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent

Просмотреть файл

@ -1,62 +0,0 @@
Changelog
LICENSE
MANIFEST.in
README.rst
setup.cfg
setup.py
amqp/__init__.py
amqp/abstract_channel.py
amqp/basic_message.py
amqp/channel.py
amqp/connection.py
amqp/exceptions.py
amqp/method_framing.py
amqp/serialization.py
amqp/transport.py
amqp.egg-info/PKG-INFO
amqp.egg-info/SOURCES.txt
amqp.egg-info/dependency_links.txt
amqp.egg-info/not-zip-safe
amqp.egg-info/top_level.txt
demo/amqp_clock.py
demo/demo_receive.py
demo/demo_send.py
docs/Makefile
docs/changelog.rst
docs/conf.py
docs/index.rst
docs/.static/.keep
docs/.templates/page.html
docs/.templates/sidebarintro.html
docs/.templates/sidebarlogo.html
docs/_ext/applyxrefs.py
docs/_ext/literals_to_xrefs.py
docs/_theme/celery/theme.conf
docs/_theme/celery/static/celery.css_t
docs/includes/intro.txt
docs/reference/amqp.abstract_channel.rst
docs/reference/amqp.basic_message.rst
docs/reference/amqp.channel.rst
docs/reference/amqp.connection.rst
docs/reference/amqp.exceptions.rst
docs/reference/amqp.method_framing.rst
docs/reference/amqp.serialization.rst
docs/reference/amqp.transport.rst
docs/reference/index.rst
docs/templates/readme.txt
extra/README
extra/generate_skeleton_0_8.py
extra/update_comments_from_spec.py
extra/release/bump_version.py
extra/release/sphinx-to-rst.py
funtests/run_all.py
funtests/settings.py
funtests/test_basic_message.py
funtests/test_channel.py
funtests/test_connection.py
funtests/test_exceptions.py
funtests/test_serialization.py
funtests/test_with.py
requirements/docs.txt
requirements/pkgutils.txt
requirements/test.txt

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,24 +0,0 @@
../amqp/transport.py
../amqp/abstract_channel.py
../amqp/exceptions.py
../amqp/basic_message.py
../amqp/connection.py
../amqp/__init__.py
../amqp/method_framing.py
../amqp/serialization.py
../amqp/channel.py
../amqp/transport.pyc
../amqp/abstract_channel.pyc
../amqp/exceptions.pyc
../amqp/basic_message.pyc
../amqp/connection.pyc
../amqp/__init__.pyc
../amqp/method_framing.pyc
../amqp/serialization.pyc
../amqp/channel.pyc
./
top_level.txt
SOURCES.txt
not-zip-safe
PKG-INFO
dependency_links.txt

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1 +0,0 @@
amqp

Просмотреть файл

@ -1,50 +0,0 @@
"""Low-level AMQP client for Python (fork of amqplib)"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
VERSION = (1, 0, 6)
__version__ = '.'.join(map(str, VERSION[0:3])) + ''.join(VERSION[3:])
__author__ = 'Barry Pederson'
__maintainer__ = 'Ask Solem'
__contact__ = 'pyamqp@celeryproject.org'
__homepage__ = 'http://github.com/celery/py-amqp'
__docformat__ = 'restructuredtext'
# -eof meta-
#
# Pull in the public items from the various sub-modules
#
from .basic_message import Message
from .channel import Channel
from .connection import Connection
from .exceptions import (
AMQPError,
ConnectionError,
ChannelError,
ConsumerCancel,
)
__all__ = [
'Connection',
'Channel',
'Message',
'AMQPError',
'ConnectionError',
'ChannelError',
'ConsumerCancel',
]

Просмотреть файл

@ -1,93 +0,0 @@
"""Code common to Connection and Channel objects."""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
from .exceptions import AMQPError
from .serialization import AMQPWriter
try:
bytes
except NameError:
# Python 2.5 and lower
bytes = str
__all__ = ['AbstractChannel']
class AbstractChannel(object):
"""Superclass for both the Connection, which is treated
as channel 0, and other user-created Channel objects.
The subclasses must have a _METHOD_MAP class property, mapping
between AMQP method signatures and Python methods.
"""
def __init__(self, connection, channel_id):
self.connection = connection
self.channel_id = channel_id
connection.channels[channel_id] = self
self.method_queue = [] # Higher level queue for methods
self.auto_decode = False
def __enter__(self):
return self
def __exit__(self, *exc_info):
self.close()
def _send_method(self, method_sig, args=bytes(), content=None):
"""Send a method for our channel."""
if isinstance(args, AMQPWriter):
args = args.getvalue()
self.connection.method_writer.write_method(
self.channel_id, method_sig, args, content)
def close(self):
"""Close this Channel or Connection"""
raise NotImplementedError('Must be overriden in subclass')
def wait(self, allowed_methods=None):
"""Wait for a method that matches our allowed_methods parameter (the
default value of None means match any method), and dispatch to it."""
method_sig, args, content = self.connection._wait_method(
self.channel_id, allowed_methods)
return self.dispatch_method(method_sig, args, content)
def dispatch_method(self, method_sig, args, content):
if content and \
self.auto_decode and \
hasattr(content, 'content_encoding'):
try:
content.body = content.body.decode(content.content_encoding)
except Exception:
pass
try:
amqp_method = self._METHOD_MAP[method_sig]
except KeyError:
raise AMQPError('Unknown AMQP method %r' % method_sig)
if content is None:
return amqp_method(self, args)
else:
return amqp_method(self, args, content)
#: Placeholder, the concrete implementations will have to
#: supply their own versions of _METHOD_MAP
_METHOD_MAP = {}

Просмотреть файл

@ -1,123 +0,0 @@
"""Messages for AMQP"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
from .serialization import GenericContent
__all__ = ['Message']
class Message(GenericContent):
"""A Message for use with the Channnel.basic_* methods."""
#: Instances of this class have these attributes, which
#: are passed back and forth as message properties between
#: client and server
PROPERTIES = [
('content_type', 'shortstr'),
('content_encoding', 'shortstr'),
('application_headers', 'table'),
('delivery_mode', 'octet'),
('priority', 'octet'),
('correlation_id', 'shortstr'),
('reply_to', 'shortstr'),
('expiration', 'shortstr'),
('message_id', 'shortstr'),
('timestamp', 'timestamp'),
('type', 'shortstr'),
('user_id', 'shortstr'),
('app_id', 'shortstr'),
('cluster_id', 'shortstr')
]
def __init__(self, body='', children=None, **properties):
"""Expected arg types
body: string
children: (not supported)
Keyword properties may include:
content_type: shortstr
MIME content type
content_encoding: shortstr
MIME content encoding
application_headers: table
Message header field table, a dict with string keys,
and string | int | Decimal | datetime | dict values.
delivery_mode: octet
Non-persistent (1) or persistent (2)
priority: octet
The message priority, 0 to 9
correlation_id: shortstr
The application correlation identifier
reply_to: shortstr
The destination to reply to
expiration: shortstr
Message expiration specification
message_id: shortstr
The application message identifier
timestamp: datetime.datetime
The message timestamp
type: shortstr
The message type name
user_id: shortstr
The creating user id
app_id: shortstr
The creating application id
cluster_id: shortstr
Intra-cluster routing identifier
Unicode bodies are encoded according to the 'content_encoding'
argument. If that's None, it's set to 'UTF-8' automatically.
example::
msg = Message('hello world',
content_type='text/plain',
application_headers={'foo': 7})
"""
super(Message, self).__init__(**properties)
self.body = body
def __eq__(self, other):
"""Check if the properties and bodies of this Message and another
Message are the same.
Received messages may contain a 'delivery_info' attribute,
which isn't compared.
"""
try:
return (super(Message, self).__eq__(other) and
self.body == other.body)
except AttributeError:
return NotImplemented

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,923 +0,0 @@
"""AMQP Connections"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
import logging
import socket
from array import array
try:
from ssl import SSLError
except ImportError:
class SSLError(Exception): # noqa
pass
from . import __version__
from .abstract_channel import AbstractChannel
from .channel import Channel
from .exceptions import ChannelError, ConnectionError
from .method_framing import MethodReader, MethodWriter
from .serialization import AMQPWriter
from .transport import create_transport
HAS_MSG_PEEK = hasattr(socket, 'MSG_PEEK')
START_DEBUG_FMT = """
Start from server, version: %d.%d, properties: %s, mechanisms: %s, locales: %s
""".strip()
__all__ = ['Connection']
#
# Client property info that gets sent to the server on connection startup
#
LIBRARY_PROPERTIES = {
'product': 'py-amqp',
'product_version': __version__,
'capabilities': {},
}
AMQP_LOGGER = logging.getLogger('amqp')
class Connection(AbstractChannel):
"""The connection class provides methods for a client to establish a
network connection to a server, and for both peers to operate the
connection thereafter.
GRAMMAR::
connection = open-connection *use-connection close-connection
open-connection = C:protocol-header
S:START C:START-OK
*challenge
S:TUNE C:TUNE-OK
C:OPEN S:OPEN-OK
challenge = S:SECURE C:SECURE-OK
use-connection = *channel
close-connection = C:CLOSE S:CLOSE-OK
/ S:CLOSE C:CLOSE-OK
"""
Channel = Channel
prev_sent = None
prev_recv = None
missed_heartbeats = 0
def __init__(self,
host='localhost',
userid='guest',
password='guest',
login_method='AMQPLAIN',
login_response=None,
virtual_host='/',
locale='en_US',
client_properties=None,
ssl=False,
connect_timeout=None,
channel_max=None,
frame_max=None,
heartbeat=0,
**kwargs):
"""Create a connection to the specified host, which should be
a 'host[:port]', such as 'localhost', or '1.2.3.4:5672'
(defaults to 'localhost', if a port is not specified then
5672 is used)
If login_response is not specified, one is built up for you from
userid and password if they are present.
The 'ssl' parameter may be simply True/False, or for Python >= 2.6
a dictionary of options to pass to ssl.wrap_socket() such as
requiring certain certificates.
"""
channel_max = channel_max or 65535
frame_max = frame_max or 131072
if (login_response is None) \
and (userid is not None) \
and (password is not None):
login_response = AMQPWriter()
login_response.write_table({'LOGIN': userid, 'PASSWORD': password})
login_response = login_response.getvalue()[4:] # Skip the length
# at the beginning
d = dict(LIBRARY_PROPERTIES, **client_properties or {})
self._method_override = {(60, 50): self._dispatch_basic_return}
self.channels = {}
# The connection object itself is treated as channel 0
super(Connection, self).__init__(self, 0)
self.transport = None
# Properties set in the Tune method
self.channel_max = channel_max
self.frame_max = frame_max
self.heartbeat = heartbeat
self._avail_channel_ids = array('H', range(self.channel_max, 0, -1))
# Properties set in the Start method
self.version_major = 0
self.version_minor = 0
self.server_properties = {}
self.mechanisms = []
self.locales = []
# Let the transport.py module setup the actual
# socket connection to the broker.
#
self.transport = create_transport(host, connect_timeout, ssl)
self.method_reader = MethodReader(self.transport)
self.method_writer = MethodWriter(self.transport, self.frame_max)
self.wait(allowed_methods=[
(10, 10), # start
])
self._x_start_ok(d, login_method, login_response, locale)
self._wait_tune_ok = True
while self._wait_tune_ok:
self.wait(allowed_methods=[
(10, 20), # secure
(10, 30), # tune
])
return self._x_open(virtual_host)
def _do_close(self):
try:
self.transport.close()
temp_list = [x for x in self.channels.values() if x is not self]
for ch in temp_list:
ch._do_close()
except socket.error:
pass # connection already closed on the other end
finally:
self.transport = self.connection = self.channels = None
def _get_free_channel_id(self):
try:
return self._avail_channel_ids.pop()
except IndexError:
raise ConnectionError(
'No free channel ids, current=%d, channel_max=%d' % (
len(self.channels), self.channel_max), (20, 10))
def _wait_method(self, channel_id, allowed_methods):
"""Wait for a method from the server destined for
a particular channel."""
#
# Check the channel's deferred methods
#
method_queue = self.channels[channel_id].method_queue
for queued_method in method_queue:
method_sig = queued_method[0]
if (allowed_methods is None) \
or (method_sig in allowed_methods) \
or (method_sig == (20, 40)):
method_queue.remove(queued_method)
return queued_method
#
# Nothing queued, need to wait for a method from the peer
#
while 1:
channel, method_sig, args, content = \
self.method_reader.read_method()
if (channel == channel_id) \
and ((allowed_methods is None) \
or (method_sig in allowed_methods) \
or (method_sig == (20, 40))):
return method_sig, args, content
#
# Certain methods like basic_return should be dispatched
# immediately rather than being queued, even if they're not
# one of the 'allowed_methods' we're looking for.
#
if channel and method_sig in self.Channel._IMMEDIATE_METHODS:
self.channels[channel].dispatch_method(
method_sig, args, content)
continue
#
# Not the channel and/or method we were looking for. Queue
# this method for later
#
self.channels[channel].method_queue.append(
(method_sig, args, content)
)
#
# If we just queued up a method for channel 0 (the Connection
# itself) it's probably a close method in reaction to some
# error, so deal with it right away.
#
if not channel:
self.wait()
def channel(self, channel_id=None):
"""Fetch a Channel object identified by the numeric channel_id, or
create that object if it doesn't already exist."""
try:
return self.channels[channel_id]
except KeyError:
return self.Channel(self, channel_id)
def is_alive(self):
if HAS_MSG_PEEK:
sock = self.sock
prev = sock.gettimeout()
sock.settimeout(0.0001)
try:
sock.recv(1, socket.MSG_PEEK)
except socket.timeout:
pass
except socket.error:
return False
finally:
sock.settimeout(prev)
return True
def drain_events(self, timeout=None):
"""Wait for an event on a channel."""
chanmap = self.channels
chanid, method_sig, args, content = self._wait_multiple(
chanmap, None, timeout=timeout)
channel = chanmap[chanid]
if content \
and channel.auto_decode \
and hasattr(content, 'content_encoding'):
try:
content.body = content.body.decode(content.content_encoding)
except Exception:
pass
amqp_method = self._method_override.get(method_sig) or \
channel._METHOD_MAP.get(method_sig, None)
if amqp_method is None:
raise Exception('Unknown AMQP method (%d, %d)' % method_sig)
if content is None:
return amqp_method(channel, args)
else:
return amqp_method(channel, args, content)
def read_timeout(self, timeout=None):
if timeout is None:
return self.method_reader.read_method()
sock = self.sock
prev = sock.gettimeout()
if prev != timeout:
sock.settimeout(timeout)
try:
try:
return self.method_reader.read_method()
except SSLError, exc:
# http://bugs.python.org/issue10272
if 'timed out' in str(exc):
raise socket.timeout()
# Non-blocking SSL sockets can throw SSLError
if 'The operation did not complete' in str(exc):
raise socket.timeout()
raise
finally:
if prev != timeout:
sock.settimeout(prev)
def _wait_multiple(self, channels, allowed_methods, timeout=None):
for channel_id, channel in channels.iteritems():
method_queue = channel.method_queue
for queued_method in method_queue:
method_sig = queued_method[0]
if (allowed_methods is None) \
or (method_sig in allowed_methods) \
or (method_sig == (20, 40)):
method_queue.remove(queued_method)
method_sig, args, content = queued_method
return channel_id, method_sig, args, content
# Nothing queued, need to wait for a method from the peer
read_timeout = self.read_timeout
wait = self.wait
while 1:
channel, method_sig, args, content = read_timeout(timeout)
if channel in channels and \
(allowed_methods is None or \
method_sig in allowed_methods or \
method_sig == (20, 40)):
return channel, method_sig, args, content
# Not the channel and/or method we were looking for. Queue
# this method for later
channels[channel].method_queue.append((method_sig, args, content))
#
# If we just queued up a method for channel 0 (the Connection
# itself) it's probably a close method in reaction to some
# error, so deal with it right away.
#
if channel == 0:
wait()
def _dispatch_basic_return(self, channel, args, msg):
reply_code = args.read_short()
reply_text = args.read_shortstr()
exchange = args.read_shortstr()
routing_key = args.read_shortstr()
exc = ChannelError('basic.return', reply_code, reply_text, (50, 60))
handlers = channel.events.get('basic_return')
if not handlers:
raise exc
for callback in handlers:
callback(exc, exchange, routing_key, msg)
def close(self, reply_code=0, reply_text='', method_sig=(0, 0)):
"""Request a connection close
This method indicates that the sender wants to close the
connection. This may be due to internal conditions (e.g. a
forced shut-down) or due to an error handling a specific
method, i.e. an exception. When a close is due to an
exception, the sender provides the class and method id of the
method which caused the exception.
RULE:
After sending this method any received method except the
Close-OK method MUST be discarded.
RULE:
The peer sending this method MAY use a counter or timeout
to detect failure of the other peer to respond correctly
with the Close-OK method.
RULE:
When a server receives the Close method from a client it
MUST delete all server-side resources associated with the
client's context. A client CANNOT reconnect to a context
after sending or receiving a Close method.
PARAMETERS:
reply_code: short
The reply code. The AMQ reply codes are defined in AMQ
RFC 011.
reply_text: shortstr
The localised reply text. This text can be logged as an
aid to resolving issues.
class_id: short
failing method class
When the close is provoked by a method exception, this
is the class of the method.
method_id: short
failing method ID
When the close is provoked by a method exception, this
is the ID of the method.
"""
if self.transport is None:
# already closed
return
args = AMQPWriter()
args.write_short(reply_code)
args.write_shortstr(reply_text)
args.write_short(method_sig[0]) # class_id
args.write_short(method_sig[1]) # method_id
self._send_method((10, 50), args)
return self.wait(allowed_methods=[
(10, 50), # Connection.close
(10, 51), # Connection.close_ok
])
def _close(self, args):
"""Request a connection close
This method indicates that the sender wants to close the
connection. This may be due to internal conditions (e.g. a
forced shut-down) or due to an error handling a specific
method, i.e. an exception. When a close is due to an
exception, the sender provides the class and method id of the
method which caused the exception.
RULE:
After sending this method any received method except the
Close-OK method MUST be discarded.
RULE:
The peer sending this method MAY use a counter or timeout
to detect failure of the other peer to respond correctly
with the Close-OK method.
RULE:
When a server receives the Close method from a client it
MUST delete all server-side resources associated with the
client's context. A client CANNOT reconnect to a context
after sending or receiving a Close method.
PARAMETERS:
reply_code: short
The reply code. The AMQ reply codes are defined in AMQ
RFC 011.
reply_text: shortstr
The localised reply text. This text can be logged as an
aid to resolving issues.
class_id: short
failing method class
When the close is provoked by a method exception, this
is the class of the method.
method_id: short
failing method ID
When the close is provoked by a method exception, this
is the ID of the method.
"""
reply_code = args.read_short()
reply_text = args.read_shortstr()
class_id = args.read_short()
method_id = args.read_short()
self._x_close_ok()
raise ConnectionError(reply_code, reply_text, (class_id, method_id))
def _x_close_ok(self):
"""Confirm a connection close
This method confirms a Connection.Close method and tells the
recipient that it is safe to release resources for the
connection and close the socket.
RULE:
A peer that detects a socket closure without having
received a Close-Ok handshake method SHOULD log the error.
"""
self._send_method((10, 51))
self._do_close()
def _close_ok(self, args):
"""Confirm a connection close
This method confirms a Connection.Close method and tells the
recipient that it is safe to release resources for the
connection and close the socket.
RULE:
A peer that detects a socket closure without having
received a Close-Ok handshake method SHOULD log the error.
"""
self._do_close()
def _x_open(self, virtual_host, capabilities=''):
"""Open connection to virtual host
This method opens a connection to a virtual host, which is a
collection of resources, and acts to separate multiple
application domains within a server.
RULE:
The client MUST open the context before doing any work on
the connection.
PARAMETERS:
virtual_host: shortstr
virtual host name
The name of the virtual host to work with.
RULE:
If the server supports multiple virtual hosts, it
MUST enforce a full separation of exchanges,
queues, and all associated entities per virtual
host. An application, connected to a specific
virtual host, MUST NOT be able to access resources
of another virtual host.
RULE:
The server SHOULD verify that the client has
permission to access the specified virtual host.
RULE:
The server MAY configure arbitrary limits per
virtual host, such as the number of each type of
entity that may be used, per connection and/or in
total.
capabilities: shortstr
required capabilities
The client may specify a number of capability names,
delimited by spaces. The server can use this string
to how to process the client's connection request.
"""
args = AMQPWriter()
args.write_shortstr(virtual_host)
args.write_shortstr(capabilities)
args.write_bit(False)
self._send_method((10, 40), args)
return self.wait(allowed_methods=[
(10, 41), # Connection.open_ok
])
def _open_ok(self, args):
"""Signal that the connection is ready
This method signals to the client that the connection is ready
for use.
PARAMETERS:
known_hosts: shortstr (deprecated)
"""
AMQP_LOGGER.debug('Open OK!')
def _secure(self, args):
"""Security mechanism challenge
The SASL protocol works by exchanging challenges and responses
until both peers have received sufficient information to
authenticate each other. This method challenges the client to
provide more information.
PARAMETERS:
challenge: longstr
security challenge data
Challenge information, a block of opaque binary data
passed to the security mechanism.
"""
challenge = args.read_longstr() # noqa
def _x_secure_ok(self, response):
"""Security mechanism response
This method attempts to authenticate, passing a block of SASL
data for the security mechanism at the server side.
PARAMETERS:
response: longstr
security response data
A block of opaque data passed to the security
mechanism. The contents of this data are defined by
the SASL security mechanism.
"""
args = AMQPWriter()
args.write_longstr(response)
self._send_method((10, 21), args)
def _start(self, args):
"""Start connection negotiation
This method starts the connection negotiation process by
telling the client the protocol version that the server
proposes, along with a list of security mechanisms which the
client can use for authentication.
RULE:
If the client cannot handle the protocol version suggested
by the server it MUST close the socket connection.
RULE:
The server MUST provide a protocol version that is lower
than or equal to that requested by the client in the
protocol header. If the server cannot support the
specified protocol it MUST NOT send this method, but MUST
close the socket connection.
PARAMETERS:
version_major: octet
protocol major version
The protocol major version that the server agrees to
use, which cannot be higher than the client's major
version.
version_minor: octet
protocol major version
The protocol minor version that the server agrees to
use, which cannot be higher than the client's minor
version.
server_properties: table
server properties
mechanisms: longstr
available security mechanisms
A list of the security mechanisms that the server
supports, delimited by spaces. Currently ASL supports
these mechanisms: PLAIN.
locales: longstr
available message locales
A list of the message locales that the server
supports, delimited by spaces. The locale defines the
language in which the server will send reply texts.
RULE:
All servers MUST support at least the en_US
locale.
"""
self.version_major = args.read_octet()
self.version_minor = args.read_octet()
self.server_properties = args.read_table()
self.mechanisms = args.read_longstr().split(' ')
self.locales = args.read_longstr().split(' ')
AMQP_LOGGER.debug(START_DEBUG_FMT,
self.version_major, self.version_minor,
self.server_properties, self.mechanisms, self.locales)
def _x_start_ok(self, client_properties, mechanism, response, locale):
"""Select security mechanism and locale
This method selects a SASL security mechanism. ASL uses SASL
(RFC2222) to negotiate authentication and encryption.
PARAMETERS:
client_properties: table
client properties
mechanism: shortstr
selected security mechanism
A single security mechanisms selected by the client,
which must be one of those specified by the server.
RULE:
The client SHOULD authenticate using the highest-
level security profile it can handle from the list
provided by the server.
RULE:
The mechanism field MUST contain one of the
security mechanisms proposed by the server in the
Start method. If it doesn't, the server MUST close
the socket.
response: longstr
security response data
A block of opaque data passed to the security
mechanism. The contents of this data are defined by
the SASL security mechanism. For the PLAIN security
mechanism this is defined as a field table holding two
fields, LOGIN and PASSWORD.
locale: shortstr
selected message locale
A single message local selected by the client, which
must be one of those specified by the server.
"""
if self.server_capabilities.get('consumer_cancel_notify'):
if 'capabilities' not in client_properties:
client_properties['capabilities'] = {}
client_properties['capabilities']['consumer_cancel_notify'] = True
args = AMQPWriter()
args.write_table(client_properties)
args.write_shortstr(mechanism)
args.write_longstr(response)
args.write_shortstr(locale)
self._send_method((10, 11), args)
def _tune(self, args):
"""Propose connection tuning parameters
This method proposes a set of connection configuration values
to the client. The client can accept and/or adjust these.
PARAMETERS:
channel_max: short
proposed maximum channels
The maximum total number of channels that the server
allows per connection. Zero means that the server does
not impose a fixed limit, but the number of allowed
channels may be limited by available server resources.
frame_max: long
proposed maximum frame size
The largest frame size that the server proposes for
the connection. The client can negotiate a lower
value. Zero means that the server does not impose any
specific limit but may reject very large frames if it
cannot allocate resources for them.
RULE:
Until the frame-max has been negotiated, both
peers MUST accept frames of up to 4096 octets
large. The minimum non-zero value for the frame-
max field is 4096.
heartbeat: short
desired heartbeat delay
The delay, in seconds, of the connection heartbeat
that the server wants. Zero means the server does not
want a heartbeat.
"""
self.channel_max = args.read_short() or self.channel_max
self.frame_max = args.read_long() or self.frame_max
self.method_writer.frame_max = self.frame_max
heartbeat = args.read_short() # noqa
self._x_tune_ok(self.channel_max, self.frame_max, self.heartbeat)
def send_heartbeat(self):
self.transport.write_frame(8, 0, bytes())
def heartbeat_tick(self, rate=2):
"""Verify that hartbeats are sent and received.
:keyword rate: Rate is how often the tick is called
compared to the actual heartbeat value. E.g. if
the heartbeat is set to 3 seconds, and the tick
is called every 3 / 2 seconds, then the rate is 2.
"""
sent_now = self.method_writer.bytes_sent
recv_now = self.method_reader.bytes_recv
if self.prev_sent is not None and self.prev_sent == sent_now:
self.send_heartbeat()
if self.prev_recv is not None and self.prev_recv == recv_now:
self.missed_heartbeats += 1
else:
self.missed_heartbeats = 0
self.prev_sent, self.prev_recv = sent_now, recv_now
if self.missed_heartbeats >= rate:
raise ConnectionError('Too many heartbeats missed')
def _x_tune_ok(self, channel_max, frame_max, heartbeat):
"""Negotiate connection tuning parameters
This method sends the client's connection tuning parameters to
the server. Certain fields are negotiated, others provide
capability information.
PARAMETERS:
channel_max: short
negotiated maximum channels
The maximum total number of channels that the client
will use per connection. May not be higher than the
value specified by the server.
RULE:
The server MAY ignore the channel-max value or MAY
use it for tuning its resource allocation.
frame_max: long
negotiated maximum frame size
The largest frame size that the client and server will
use for the connection. Zero means that the client
does not impose any specific limit but may reject very
large frames if it cannot allocate resources for them.
Note that the frame-max limit applies principally to
content frames, where large contents can be broken
into frames of arbitrary size.
RULE:
Until the frame-max has been negotiated, both
peers must accept frames of up to 4096 octets
large. The minimum non-zero value for the frame-
max field is 4096.
heartbeat: short
desired heartbeat delay
The delay, in seconds, of the connection heartbeat
that the client wants. Zero means the client does not
want a heartbeat.
"""
args = AMQPWriter()
args.write_short(channel_max)
args.write_long(frame_max)
args.write_short(heartbeat or 0)
self._send_method((10, 31), args)
self._wait_tune_ok = False
@property
def sock(self):
return self.transport.sock
@property
def server_capabilities(self):
return self.server_properties.get('capabilities') or {}
_METHOD_MAP = {
(10, 10): _start,
(10, 20): _secure,
(10, 30): _tune,
(10, 41): _open_ok,
(10, 50): _close,
(10, 51): _close_ok,
}
_IMMEDIATE_METHODS = []
connection_errors = (ConnectionError,
socket.error,
IOError,
OSError)
channel_errors = (ChannelError, )

Просмотреть файл

@ -1,125 +0,0 @@
"""Exceptions used by amqp"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
from struct import pack, unpack
__all__ = ['AMQPError', 'ConnectionError', 'ChannelError']
class AMQPError(Exception):
def __init__(self, msg, reply_code=None, reply_text=None, method_sig=None,
method_name=None):
self.message = msg
self.amqp_reply_code = reply_code
self.amqp_reply_text = reply_text
self.amqp_method_sig = method_sig
self.method_name = method_name or ''
if method_sig and not self.method_name:
self.method_name = METHOD_NAME_MAP.get(method_sig, '')
Exception.__init__(self, msg, reply_code,
reply_text, method_sig, self.method_name)
def __str__(self):
if self.amqp_reply_code:
return '%s: (%s, %s, %s)' % (
self.message, self.amqp_reply_code, self.amqp_reply_text,
self.amqp_method_sig)
return self.message
class ConnectionError(AMQPError):
pass
class ChannelError(AMQPError):
pass
class ConsumerCancel(ChannelError):
pass
METHOD_NAME_MAP = {
(10, 10): 'Connection.start',
(10, 11): 'Connection.start_ok',
(10, 20): 'Connection.secure',
(10, 21): 'Connection.secure_ok',
(10, 30): 'Connection.tune',
(10, 31): 'Connection.tune_ok',
(10, 40): 'Connection.open',
(10, 41): 'Connection.open_ok',
(10, 50): 'Connection.close',
(10, 51): 'Connection.close_ok',
(20, 10): 'Channel.open',
(20, 11): 'Channel.open_ok',
(20, 20): 'Channel.flow',
(20, 21): 'Channel.flow_ok',
(20, 40): 'Channel.close',
(20, 41): 'Channel.close_ok',
(30, 10): 'Access.request',
(30, 11): 'Access.request_ok',
(40, 10): 'Exchange.declare',
(40, 11): 'Exchange.declare_ok',
(40, 20): 'Exchange.delete',
(40, 21): 'Exchange.delete_ok',
(40, 30): 'Exchange.bind',
(40, 31): 'Exchange.bind_ok',
(40, 40): 'Exchange.unbind',
(40, 41): 'Exchange.unbind_ok',
(50, 10): 'Queue.declare',
(50, 11): 'Queue.declare_ok',
(50, 20): 'Queue.bind',
(50, 21): 'Queue.bind_ok',
(50, 30): 'Queue.purge',
(50, 31): 'Queue.purge_ok',
(50, 40): 'Queue.delete',
(50, 41): 'Queue.delete_ok',
(50, 50): 'Queue.unbind',
(50, 51): 'Queue.unbind_ok',
(60, 10): 'Basic.qos',
(60, 11): 'Basic.qos_ok',
(60, 20): 'Basic.consume',
(60, 21): 'Basic.consume_ok',
(60, 30): 'Basic.cancel',
(60, 31): 'Basic.cancel_ok',
(60, 40): 'Basic.publish',
(60, 50): 'Basic.return',
(60, 60): 'Basic.deliver',
(60, 70): 'Basic.get',
(60, 71): 'Basic.get_ok',
(60, 72): 'Basic.get_empty',
(60, 80): 'Basic.ack',
(60, 90): 'Basic.reject',
(60, 100): 'Basic.recover_async',
(60, 110): 'Basic.recover',
(60, 111): 'Basic.recover_ok',
(60, 120): 'Basic.nack',
(90, 10): 'Tx.select',
(90, 11): 'Tx.select_ok',
(90, 20): 'Tx.commit',
(90, 21): 'Tx.commit_ok',
(90, 30): 'Tx.rollback',
(90, 31): 'Tx.rollback_ok',
(85, 10): 'Confirm.select',
(85, 11): 'Confirm.select_ok',
}
for _method_id, _method_name in list(METHOD_NAME_MAP.items()):
METHOD_NAME_MAP[unpack('>I', pack('>HH', *_method_id))[0]] = _method_name

Просмотреть файл

@ -1,228 +0,0 @@
"""Convert between frames and higher-level AMQP methods"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
from collections import defaultdict
from struct import pack, unpack
from Queue import Queue
try:
bytes
except NameError:
# Python 2.5 and lower
bytes = str
from .basic_message import Message
from .exceptions import AMQPError
from .serialization import AMQPReader
__all__ = ['MethodReader']
#
# MethodReader needs to know which methods are supposed
# to be followed by content headers and bodies.
#
_CONTENT_METHODS = [
(60, 50), # Basic.return
(60, 60), # Basic.deliver
(60, 71), # Basic.get_ok
]
class _PartialMessage(object):
"""Helper class to build up a multi-frame method."""
def __init__(self, method_sig, args):
self.method_sig = method_sig
self.args = args
self.msg = Message()
self.body_parts = []
self.body_received = 0
self.body_size = None
self.complete = False
def add_header(self, payload):
class_id, weight, self.body_size = unpack('>HHQ', payload[:12])
self.msg._load_properties(payload[12:])
self.complete = (self.body_size == 0)
def add_payload(self, payload):
self.body_parts.append(payload)
self.body_received += len(payload)
if self.body_received == self.body_size:
self.msg.body = bytes().join(self.body_parts)
self.complete = True
class MethodReader(object):
"""Helper class to receive frames from the broker, combine them if
necessary with content-headers and content-bodies into complete methods.
Normally a method is represented as a tuple containing
(channel, method_sig, args, content).
In the case of a framing error, an :exc:`ConnectionError` is placed
in the queue.
In the case of unexpected frames, a tuple made up of
``(channel, ChannelError)`` is placed in the queue.
"""
def __init__(self, source):
self.source = source
self.queue = Queue()
self.running = False
self.partial_messages = {}
self.heartbeats = 0
# For each channel, which type is expected next
self.expected_types = defaultdict(lambda: 1)
# not an actual byte count, just incremented whenever we receive
self.bytes_recv = 0
def _next_method(self):
"""Read the next method from the source, once one complete method has
been assembled it is placed in the internal queue."""
empty = self.queue.empty
read_frame = self.source.read_frame
while empty():
try:
frame_type, channel, payload = read_frame()
except Exception, e:
#
# Connection was closed? Framing Error?
#
self.queue.put(e)
break
self.bytes_recv += 1
if frame_type not in (self.expected_types[channel], 8):
self.queue.put((
channel,
AMQPError(
'Received frame type %s while expecting type: %s' % (
frame_type, self.expected_types[channel]))
))
elif frame_type == 1:
self._process_method_frame(channel, payload)
elif frame_type == 2:
self._process_content_header(channel, payload)
elif frame_type == 3:
self._process_content_body(channel, payload)
elif frame_type == 8:
self._process_heartbeat(channel, payload)
def _process_heartbeat(self, channel, payload):
self.heartbeats += 1
def _process_method_frame(self, channel, payload):
"""Process Method frames"""
method_sig = unpack('>HH', payload[:4])
args = AMQPReader(payload[4:])
if method_sig in _CONTENT_METHODS:
#
# Save what we've got so far and wait for the content-header
#
self.partial_messages[channel] = _PartialMessage(method_sig, args)
self.expected_types[channel] = 2
else:
self.queue.put((channel, method_sig, args, None))
def _process_content_header(self, channel, payload):
"""Process Content Header frames"""
partial = self.partial_messages[channel]
partial.add_header(payload)
if partial.complete:
#
# a bodyless message, we're done
#
self.queue.put((channel, partial.method_sig,
partial.args, partial.msg))
self.partial_messages.pop(channel, None)
self.expected_types[channel] = 1
else:
#
# wait for the content-body
#
self.expected_types[channel] = 3
def _process_content_body(self, channel, payload):
"""Process Content Body frames"""
partial = self.partial_messages[channel]
partial.add_payload(payload)
if partial.complete:
#
# Stick the message in the queue and go back to
# waiting for method frames
#
self.queue.put((channel, partial.method_sig,
partial.args, partial.msg))
self.partial_messages.pop(channel, None)
self.expected_types[channel] = 1
def read_method(self):
"""Read a method from the peer."""
self._next_method()
m = self.queue.get()
if isinstance(m, Exception):
raise m
if isinstance(m, tuple) and isinstance(m[1], AMQPError):
raise m[1]
return m
class MethodWriter(object):
"""Convert AMQP methods into AMQP frames and send them out
to the peer."""
def __init__(self, dest, frame_max):
self.dest = dest
self.frame_max = frame_max
self.bytes_sent = 0
def write_method(self, channel, method_sig, args, content=None):
write_frame = self.dest.write_frame
payload = pack('>HH', method_sig[0], method_sig[1]) + args
if content:
# do this early, so we can raise an exception if there's a
# problem with the content properties, before sending the
# first frame
body = content.body
if isinstance(body, unicode):
coding = content.properties.get('content_encoding', None)
if coding is None:
coding = content.properties['content_encoding'] = 'UTF-8'
body = body.encode(coding)
properties = content._serialize_properties()
write_frame(1, channel, payload)
if content:
payload = pack('>HHQ', method_sig[0], 0, len(body)) + properties
write_frame(2, channel, payload)
chunk_size = self.frame_max - 8
for i in xrange(0, len(body), chunk_size):
write_frame(3, channel, body[i:i + chunk_size])
self.bytes_sent += 1

Просмотреть файл

@ -1,432 +0,0 @@
"""
Convert between bytestreams and higher-level AMQP types.
2007-11-05 Barry Pederson <bp@barryp.org>
"""
# Copyright (C) 2007 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
import sys
from datetime import datetime
from decimal import Decimal
from struct import pack, unpack
from time import mktime
IS_PY3K = sys.version_info[0] >= 3
if IS_PY3K:
def byte(n):
return bytes([n])
else:
byte = chr
try:
from io import BytesIO
except ImportError: # Py2.5
try:
from cStringIO import StringIO as BytesIO # noqa
except ImportError:
from StringIO import StringIO as BytesIO # noqa
try:
bytes
except NameError:
# Python 2.5 and lower
bytes = str
class AMQPReader(object):
"""Read higher-level AMQP types from a bytestream."""
def __init__(self, source):
"""Source should be either a file-like object with a read() method, or
a plain (non-unicode) string."""
if isinstance(source, bytes):
self.input = BytesIO(source)
elif hasattr(source, 'read'):
self.input = source
else:
raise ValueError(
'AMQPReader needs a file-like object or plain string')
self.bitcount = self.bits = 0
def close(self):
self.input.close()
def read(self, n):
"""Read n bytes."""
self.bitcount = self.bits = 0
return self.input.read(n)
def read_bit(self):
"""Read a single boolean value."""
if not self.bitcount:
self.bits = ord(self.input.read(1))
self.bitcount = 8
result = (self.bits & 1) == 1
self.bits >>= 1
self.bitcount -= 1
return result
def read_octet(self):
"""Read one byte, return as an integer"""
self.bitcount = self.bits = 0
return unpack('B', self.input.read(1))[0]
def read_short(self):
"""Read an unsigned 16-bit integer"""
self.bitcount = self.bits = 0
return unpack('>H', self.input.read(2))[0]
def read_long(self):
"""Read an unsigned 32-bit integer"""
self.bitcount = self.bits = 0
return unpack('>I', self.input.read(4))[0]
def read_longlong(self):
"""Read an unsigned 64-bit integer"""
self.bitcount = self.bits = 0
return unpack('>Q', self.input.read(8))[0]
def read_float(self):
"""Read float value."""
self.bitcount = self.bits = 0
return unpack('>d', self.input.read(8))[0]
def read_shortstr(self):
"""Read a short string that's stored in up to 255 bytes.
The encoding isn't specified in the AMQP spec, so
assume it's utf-8
"""
self.bitcount = self.bits = 0
slen = unpack('B', self.input.read(1))[0]
return self.input.read(slen).decode('utf-8')
def read_longstr(self):
"""Read a string that's up to 2**32 bytes.
The encoding isn't specified in the AMQP spec, so
assume it's utf-8
"""
self.bitcount = self.bits = 0
slen = unpack('>I', self.input.read(4))[0]
return self.input.read(slen).decode('utf-8')
def read_table(self):
"""Read an AMQP table, and return as a Python dictionary."""
self.bitcount = self.bits = 0
tlen = unpack('>I', self.input.read(4))[0]
table_data = AMQPReader(self.input.read(tlen))
result = {}
while table_data.input.tell() < tlen:
name = table_data.read_shortstr()
ftype = ord(table_data.input.read(1))
if ftype == 83: # 'S'
val = table_data.read_longstr()
elif ftype == 73: # 'I'
val = unpack('>i', table_data.input.read(4))[0]
elif ftype == 68: # 'D'
d = table_data.read_octet()
n = unpack('>i', table_data.input.read(4))[0]
val = Decimal(n) / Decimal(10 ** d)
elif ftype == 84: # 'T'
val = table_data.read_timestamp()
elif ftype == 70: # 'F'
val = table_data.read_table() # recurse
elif ftype == 116:
val = table_data.read_bit()
elif ftype == 100:
val = table_data.read_float()
else:
raise ValueError('Unknown table item type: %s' % repr(ftype))
result[name] = val
return result
def read_timestamp(self):
"""Read and AMQP timestamp, which is a 64-bit integer representing
seconds since the Unix epoch in 1-second resolution.
Return as a Python datetime.datetime object,
expressed as localtime.
"""
return datetime.fromtimestamp(self.read_longlong())
class AMQPWriter(object):
"""Convert higher-level AMQP types to bytestreams."""
def __init__(self, dest=None):
"""dest may be a file-type object (with a write() method). If None
then a BytesIO is created, and the contents can be accessed with
this class's getvalue() method."""
self.out = BytesIO() if dest is None else dest
self.bits = []
self.bitcount = 0
def _flushbits(self):
if self.bits:
out = self.out
for b in self.bits:
out.write(pack('B', b))
self.bits = []
self.bitcount = 0
def close(self):
"""Pass through if possible to any file-like destinations."""
try:
self.out.close()
except AttributeError:
pass
def flush(self):
"""Pass through if possible to any file-like destinations."""
try:
self.out.flush()
except AttributeError:
pass
def getvalue(self):
"""Get what's been encoded so far if we're working with a BytesIO."""
self._flushbits()
return self.out.getvalue()
def write(self, s):
"""Write a plain Python string with no special encoding in Python 2.x,
or bytes in Python 3.x"""
self._flushbits()
self.out.write(s)
def write_bit(self, b):
"""Write a boolean value."""
b = 1 if b else 0
shift = self.bitcount % 8
if shift == 0:
self.bits.append(0)
self.bits[-1] |= (b << shift)
self.bitcount += 1
def write_octet(self, n):
"""Write an integer as an unsigned 8-bit value."""
if n < 0 or n > 255:
raise ValueError('Octet %r out of range 0..255' % (n, ))
self._flushbits()
self.out.write(pack('B', n))
def write_short(self, n):
"""Write an integer as an unsigned 16-bit value."""
if n < 0 or n > 65535:
raise ValueError('Octet %r out of range 0..65535' % (n, ))
self._flushbits()
self.out.write(pack('>H', int(n)))
def write_long(self, n):
"""Write an integer as an unsigned2 32-bit value."""
if n < 0 or n >= 2 ** 32:
raise ValueError('Octet %r out of range 0..2**31-1' % (n, ))
self._flushbits()
self.out.write(pack('>I', n))
def write_longlong(self, n):
"""Write an integer as an unsigned 64-bit value."""
if n < 0 or n >= 2 ** 64:
raise ValueError('Octet %r out of range 0..2**64-1' % (n, ))
self._flushbits()
self.out.write(pack('>Q', n))
def write_shortstr(self, s):
"""Write a string up to 255 bytes long (after any encoding).
If passed a unicode string, encode with UTF-8.
"""
self._flushbits()
if isinstance(s, unicode):
s = s.encode('utf-8')
if len(s) > 255:
raise ValueError('String too long (%r)' % (len(s), ))
self.write_octet(len(s))
self.out.write(s)
def write_longstr(self, s):
"""Write a string up to 2**32 bytes long after encoding.
If passed a unicode string, encode as UTF-8.
"""
self._flushbits()
if isinstance(s, unicode):
s = s.encode('utf-8')
self.write_long(len(s))
self.out.write(s)
def write_table(self, d):
"""Write out a Python dictionary made of up string keys, and values
that are strings, signed integers, Decimal, datetime.datetime, or
sub-dictionaries following the same constraints."""
self._flushbits()
table_data = AMQPWriter()
for k, v in d.iteritems():
table_data.write_shortstr(k)
if isinstance(v, basestring):
if isinstance(v, unicode):
v = v.encode('utf-8')
table_data.write(byte(83)) # 'S'
table_data.write_longstr(v)
elif isinstance(v, bool):
table_data.write(pack('>cB', 't', int(v)))
elif isinstance(v, float):
table_data.write(pack('>cd', 'd', v))
elif isinstance(v, (int, long)):
table_data.write(pack('>ci', 'I', v))
elif isinstance(v, Decimal):
table_data.write(byte(68)) # 'D'
sign, digits, exponent = v.as_tuple()
v = 0
for d in digits:
v = (v * 10) + d
if sign:
v = -v
table_data.write_octet(-exponent)
table_data.write(pack('>i', v))
elif isinstance(v, datetime):
table_data.write(byte(84)) # 'T'
table_data.write_timestamp(v)
## FIXME: timezone ?
elif isinstance(v, dict):
table_data.write(byte(70)) # 'F'
table_data.write_table(v)
else:
raise ValueError('%r not serializable in AMQP' % (v, ))
table_data = table_data.getvalue()
self.write_long(len(table_data))
self.out.write(table_data)
def write_timestamp(self, v):
"""Write out a Python datetime.datetime object as a 64-bit integer
representing seconds since the Unix epoch."""
self.out.write(pack('>q', long(mktime(v.timetuple()))))
class GenericContent(object):
"""Abstract base class for AMQP content.
Subclasses should override the PROPERTIES attribute.
"""
PROPERTIES = [('dummy', 'shortstr')]
def __init__(self, **props):
"""Save the properties appropriate to this AMQP content type
in a 'properties' dictionary."""
d = {}
for propname, _ in self.PROPERTIES:
if propname in props:
d[propname] = props[propname]
# FIXME: should we ignore unknown properties?
self.properties = d
def __eq__(self, other):
"""Check if this object has the same properties as another
content object."""
try:
return self.properties == other.properties
except AttributeError:
return NotImplemented
def __getattr__(self, name):
"""Look for additional properties in the 'properties'
dictionary, and if present - the 'delivery_info'
dictionary."""
if name == '__setstate__':
# Allows pickling/unpickling to work
raise AttributeError('__setstate__')
if name in self.properties:
return self.properties[name]
if 'delivery_info' in self.__dict__ \
and name in self.delivery_info:
return self.delivery_info[name]
raise AttributeError(name)
def _load_properties(self, raw_bytes):
"""Given the raw bytes containing the property-flags and property-list
from a content-frame-header, parse and insert into a dictionary
stored in this object as an attribute named 'properties'."""
r = AMQPReader(raw_bytes)
#
# Read 16-bit shorts until we get one with a low bit set to zero
#
flags = []
while 1:
flag_bits = r.read_short()
flags.append(flag_bits)
if flag_bits & 1 == 0:
break
shift = 0
d = {}
for key, proptype in self.PROPERTIES:
if shift == 0:
if not flags:
break
flag_bits, flags = flags[0], flags[1:]
shift = 15
if flag_bits & (1 << shift):
d[key] = getattr(r, 'read_' + proptype)()
shift -= 1
self.properties = d
def _serialize_properties(self):
"""serialize the 'properties' attribute (a dictionary) into
the raw bytes making up a set of property flags and a
property list, suitable for putting into a content frame header."""
shift = 15
flag_bits = 0
flags = []
raw_bytes = AMQPWriter()
for key, proptype in self.PROPERTIES:
val = self.properties.get(key, None)
if val is not None:
if shift == 0:
flags.append(flag_bits)
flag_bits = 0
shift = 15
flag_bits |= (1 << shift)
if proptype != 'bit':
getattr(raw_bytes, 'write_' + proptype)(val)
shift -= 1
flags.append(flag_bits)
result = AMQPWriter()
for flag_bits in flags:
result.write_short(flag_bits)
result.write(raw_bytes.getvalue())
return result.getvalue()

Просмотреть файл

@ -1,243 +0,0 @@
"""
Read/Write AMQP frames over network transports.
2009-01-14 Barry Pederson <bp@barryp.org>
"""
# Copyright (C) 2009 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from __future__ import absolute_import
import errno
import re
import socket
#
# See if Python 2.6+ SSL support is available
#
try:
import ssl
HAVE_PY26_SSL = True
except:
HAVE_PY26_SSL = False
try:
bytes
except:
# Python 2.5 and lower
bytes = str
from struct import pack, unpack
from .exceptions import AMQPError
AMQP_PORT = 5672
# Yes, Advanced Message Queuing Protocol Protocol is redundant
AMQP_PROTOCOL_HEADER = 'AMQP\x01\x01\x00\x09'.encode('latin_1')
# Match things like: [fe80::1]:5432, from RFC 2732
IPV6_LITERAL = re.compile(r'\[([\.0-9a-f:]+)\](?::(\d+))?')
class _AbstractTransport(object):
"""Common superclass for TCP and SSL transports"""
def __init__(self, host, connect_timeout):
msg = 'socket.getaddrinfo() for %s returned an empty list' % host
port = AMQP_PORT
m = IPV6_LITERAL.match(host)
if m:
host = m.group(1)
if m.group(2):
port = int(m.group(2))
else:
if ':' in host:
host, port = host.rsplit(':', 1)
port = int(port)
self.sock = None
for res in socket.getaddrinfo(host, port, 0,
socket.SOCK_STREAM, socket.SOL_TCP):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
self.sock.settimeout(connect_timeout)
self.sock.connect(sa)
except socket.error, msg:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
# Didn't connect, return the most recent error message
raise socket.error, msg
self.sock.settimeout(None)
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self._setup_transport()
self._write(AMQP_PROTOCOL_HEADER)
def __del__(self):
try:
self.close()
except socket.error:
pass
finally:
self.sock = None
def _read(self, n, initial=False):
"""Read exactly n bytes from the peer"""
raise NotImplementedError('Must be overriden in subclass')
def _setup_transport(self):
"""Do any additional initialization of the class (used
by the subclasses)."""
pass
def _shutdown_transport(self):
"""Do any preliminary work in shutting down the connection."""
pass
def _write(self, s):
"""Completely write a string to the peer."""
raise NotImplementedError('Must be overriden in subclass')
def close(self):
if self.sock is not None:
self._shutdown_transport()
# Call shutdown first to make sure that pending messages
# reach the AMQP broker if the program exits after
# calling this method.
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
self.sock = None
def read_frame(self):
"""Read an AMQP frame."""
frame_type, channel, size = unpack('>BHI', self._read(7, True))
payload = self._read(size)
ch = ord(self._read(1))
if ch == 206: # '\xce'
return frame_type, channel, payload
else:
raise AMQPError(
'Framing Error, received 0x%02x while expecting 0xce' % ch)
def write_frame(self, frame_type, channel, payload):
"""Write out an AMQP frame."""
size = len(payload)
self._write(pack('>BHI%dsB' % size,
frame_type, channel, size, payload, 0xce))
class SSLTransport(_AbstractTransport):
"""Transport that works over SSL"""
def __init__(self, host, connect_timeout, ssl):
if isinstance(ssl, dict):
self.sslopts = ssl
self.sslobj = None
super(SSLTransport, self).__init__(host, connect_timeout)
def _setup_transport(self):
"""Wrap the socket in an SSL object, either the
new Python 2.6 version, or the older Python 2.5 and
lower version."""
if HAVE_PY26_SSL:
if hasattr(self, 'sslopts'):
self.sslobj = ssl.wrap_socket(self.sock, **self.sslopts)
else:
self.sslobj = ssl.wrap_socket(self.sock)
self.sslobj.do_handshake()
else:
self.sslobj = socket.ssl(self.sock)
def _shutdown_transport(self):
"""Unwrap a Python 2.6 SSL socket, so we can call shutdown()"""
if HAVE_PY26_SSL and (self.sslobj is not None):
self.sock = self.sslobj.unwrap()
self.sslobj = None
def _read(self, n, initial=False):
"""It seems that SSL Objects read() method may not supply as much
as you're asking for, at least with extremely large messages.
somewhere > 16K - found this in the test_channel.py test_large
unittest."""
result = ''
while len(result) < n:
try:
s = self.sslobj.read(n - len(result))
except socket.error, exc:
if not initial and exc.errno in (errno.EAGAIN, errno.EINTR):
continue
raise
if not s:
raise IOError('Socket closed')
result += s
return result
def _write(self, s):
"""Write a string out to the SSL socket fully."""
while s:
n = self.sslobj.write(s)
if not n:
raise IOError('Socket closed')
s = s[n:]
class TCPTransport(_AbstractTransport):
"""Transport that deals directly with TCP socket."""
def _setup_transport(self):
"""Setup to _write() directly to the socket, and
do our own buffered reads."""
self._write = self.sock.sendall
self._read_buffer = bytes()
def _read(self, n, initial=False):
"""Read exactly n bytes from the socket"""
while len(self._read_buffer) < n:
try:
s = self.sock.recv(65536)
except socket.error, exc:
if not initial and exc.errno in (errno.EAGAIN, errno.EINTR):
continue
raise
if not s:
raise IOError('Socket closed')
self._read_buffer += s
result = self._read_buffer[:n]
self._read_buffer = self._read_buffer[n:]
return result
def create_transport(host, connect_timeout, ssl=False):
"""Given a few parameters from the Connection constructor,
select and create a subclass of _AbstractTransport."""
if ssl:
return SSLTransport(host, connect_timeout, ssl)
else:
return TCPTransport(host, connect_timeout)

Просмотреть файл

@ -1,22 +0,0 @@
Metadata-Version: 1.0
Name: amqplib
Version: 1.0.2
Summary: AMQP Client Library
Home-page: http://code.google.com/p/py-amqplib/
Author: Barry Pederson
Author-email: bp@barryp.org
License: LGPL
Description: UNKNOWN
Platform: UNKNOWN
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.4
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Intended Audience :: Developers

Просмотреть файл

@ -1,38 +0,0 @@
CHANGES
INSTALL
LICENSE
MANIFEST.in
README
TODO
setup.cfg
setup.py
amqplib/__init__.py
amqplib.egg-info/PKG-INFO
amqplib.egg-info/SOURCES.txt
amqplib.egg-info/dependency_links.txt
amqplib.egg-info/top_level.txt
amqplib/client_0_8/__init__.py
amqplib/client_0_8/abstract_channel.py
amqplib/client_0_8/basic_message.py
amqplib/client_0_8/channel.py
amqplib/client_0_8/connection.py
amqplib/client_0_8/exceptions.py
amqplib/client_0_8/method_framing.py
amqplib/client_0_8/serialization.py
amqplib/client_0_8/transport.py
demo/amqp_clock.py
demo/demo_receive.py
demo/demo_send.py
docs/code_layout.txt
docs/overview.txt
extras/README
extras/generate_skeleton_0_8.py
tests/client_0_8/fake_redirect.py
tests/client_0_8/run_all.py
tests/client_0_8/settings.py
tests/client_0_8/test_basic_message.py
tests/client_0_8/test_channel.py
tests/client_0_8/test_connection.py
tests/client_0_8/test_exceptions.py
tests/client_0_8/test_serialization.py
tests/client_0_8/test_with.py

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,25 +0,0 @@
../amqplib/__init__.py
../amqplib/client_0_8/transport.py
../amqplib/client_0_8/abstract_channel.py
../amqplib/client_0_8/exceptions.py
../amqplib/client_0_8/basic_message.py
../amqplib/client_0_8/connection.py
../amqplib/client_0_8/__init__.py
../amqplib/client_0_8/method_framing.py
../amqplib/client_0_8/serialization.py
../amqplib/client_0_8/channel.py
../amqplib/__init__.pyc
../amqplib/client_0_8/transport.pyc
../amqplib/client_0_8/abstract_channel.pyc
../amqplib/client_0_8/exceptions.pyc
../amqplib/client_0_8/basic_message.pyc
../amqplib/client_0_8/connection.pyc
../amqplib/client_0_8/__init__.pyc
../amqplib/client_0_8/method_framing.pyc
../amqplib/client_0_8/serialization.pyc
../amqplib/client_0_8/channel.pyc
./
top_level.txt
SOURCES.txt
PKG-INFO
dependency_links.txt

Просмотреть файл

@ -1 +0,0 @@
amqplib

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,36 +0,0 @@
"""
AMQP Client implementing the 0-8 spec.
"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
# Pull in the public items from the various sub-modules
#
from basic_message import *
from channel import *
from connection import *
from exceptions import *
__all__ = [
'Connection',
'Channel', # here mainly so it shows in in pydoc
'Message',
'AMQPException',
'AMQPConnectionException',
'AMQPChannelException',
]

Просмотреть файл

@ -1,124 +0,0 @@
"""
Code common to Connection and Channel objects.
"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from serialization import AMQPWriter
try:
bytes
except NameError:
# Python 2.5 and lower
bytes = str
__all__ = [
'AbstractChannel',
]
class AbstractChannel(object):
"""
Superclass for both the Connection, which is treated
as channel 0, and other user-created Channel objects.
The subclasses must have a _METHOD_MAP class property, mapping
between AMQP method signatures and Python methods.
"""
def __init__(self, connection, channel_id):
self.connection = connection
self.channel_id = channel_id
connection.channels[channel_id] = self
self.method_queue = [] # Higher level queue for methods
self.auto_decode = False
def __enter__(self):
"""
Support for Python >= 2.5 'with' statements.
"""
return self
def __exit__(self, type, value, traceback):
"""
Support for Python >= 2.5 'with' statements.
"""
self.close()
def _send_method(self, method_sig, args=bytes(), content=None):
"""
Send a method for our channel.
"""
if isinstance(args, AMQPWriter):
args = args.getvalue()
self.connection.method_writer.write_method(self.channel_id,
method_sig, args, content)
def close(self):
"""
Close this Channel or Connection
"""
raise NotImplementedError('Must be overriden in subclass')
def wait(self, allowed_methods=None):
"""
Wait for a method that matches our allowed_methods parameter (the
default value of None means match any method), and dispatch to it.
"""
method_sig, args, content = self.connection._wait_method(
self.channel_id, allowed_methods)
return self.dispatch_method(method_sig, args, content)
def dispatch_method(self, method_sig, args, content):
if content \
and self.auto_decode \
and hasattr(content, 'content_encoding'):
try:
content.body = content.body.decode(content.content_encoding)
except Exception:
pass
amqp_method = self._METHOD_MAP.get(method_sig, None)
if amqp_method is None:
raise Exception('Unknown AMQP method (%d, %d)' % method_sig)
if content is None:
return amqp_method(self, args)
else:
return amqp_method(self, args, content)
#
# Placeholder, the concrete implementations will have to
# supply their own versions of _METHOD_MAP
#
_METHOD_MAP = {}

Просмотреть файл

@ -1,132 +0,0 @@
"""
Messages for AMQP
"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from serialization import GenericContent
__all__ = [
'Message',
]
class Message(GenericContent):
"""
A Message for use with the Channnel.basic_* methods.
"""
#
# Instances of this class have these attributes, which
# are passed back and forth as message properties between
# client and server
#
PROPERTIES = [
('content_type', 'shortstr'),
('content_encoding', 'shortstr'),
('application_headers', 'table'),
('delivery_mode', 'octet'),
('priority', 'octet'),
('correlation_id', 'shortstr'),
('reply_to', 'shortstr'),
('expiration', 'shortstr'),
('message_id', 'shortstr'),
('timestamp', 'timestamp'),
('type', 'shortstr'),
('user_id', 'shortstr'),
('app_id', 'shortstr'),
('cluster_id', 'shortstr')
]
def __init__(self, body='', children=None, **properties):
"""
Expected arg types
body: string
children: (not supported)
Keyword properties may include:
content_type: shortstr
MIME content type
content_encoding: shortstr
MIME content encoding
application_headers: table
Message header field table, a dict with string keys,
and string | int | Decimal | datetime | dict values.
delivery_mode: octet
Non-persistent (1) or persistent (2)
priority: octet
The message priority, 0 to 9
correlation_id: shortstr
The application correlation identifier
reply_to: shortstr
The destination to reply to
expiration: shortstr
Message expiration specification
message_id: shortstr
The application message identifier
timestamp: datetime.datetime
The message timestamp
type: shortstr
The message type name
user_id: shortstr
The creating user id
app_id: shortstr
The creating application id
cluster_id: shortstr
Intra-cluster routing identifier
Unicode bodies are encoded according to the 'content_encoding'
argument. If that's None, it's set to 'UTF-8' automatically.
example:
msg = Message('hello world',
content_type='text/plain',
application_headers={'foo': 7})
"""
super(Message, self).__init__(**properties)
self.body = body
def __eq__(self, other):
"""
Check if the properties and bodies of this Message and another
Message are the same.
Received messages may contain a 'delivery_info' attribute,
which isn't compared.
"""
return super(Message, self).__eq__(other) \
and hasattr(other, 'body') and (self.body == other.body)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,842 +0,0 @@
"""
AMQP 0-8 Connections
"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
import logging
from abstract_channel import AbstractChannel
from channel import Channel
from exceptions import *
from method_framing import MethodReader, MethodWriter
from serialization import AMQPReader, AMQPWriter
from transport import create_transport
__all__ = [
'Connection',
]
#
# Client property info that gets sent to the server on connection startup
#
LIBRARY_PROPERTIES = {
'library': 'Python amqplib',
'library_version': '1.0.2',
}
AMQP_LOGGER = logging.getLogger('amqplib')
class Connection(AbstractChannel):
"""
The connection class provides methods for a client to establish a
network connection to a server, and for both peers to operate the
connection thereafter.
GRAMMAR:
connection = open-connection *use-connection close-connection
open-connection = C:protocol-header
S:START C:START-OK
*challenge
S:TUNE C:TUNE-OK
C:OPEN S:OPEN-OK | S:REDIRECT
challenge = S:SECURE C:SECURE-OK
use-connection = *channel
close-connection = C:CLOSE S:CLOSE-OK
/ S:CLOSE C:CLOSE-OK
"""
def __init__(self,
host='localhost',
userid='guest',
password='guest',
login_method='AMQPLAIN',
login_response=None,
virtual_host='/',
locale='en_US',
client_properties=None,
ssl=False,
insist=False,
connect_timeout=None,
**kwargs):
"""
Create a connection to the specified host, which should be
a 'host[:port]', such as 'localhost', or '1.2.3.4:5672'
(defaults to 'localhost', if a port is not specified then
5672 is used)
If login_response is not specified, one is built up for you from
userid and password if they are present.
The 'ssl' parameter may be simply True/False, or for Python >= 2.6
a dictionary of options to pass to ssl.wrap_socket() such as
requiring certain certificates.
"""
if (login_response is None) \
and (userid is not None) \
and (password is not None):
login_response = AMQPWriter()
login_response.write_table({'LOGIN': userid, 'PASSWORD': password})
login_response = login_response.getvalue()[4:] #Skip the length
#at the beginning
d = {}
d.update(LIBRARY_PROPERTIES)
if client_properties:
d.update(client_properties)
self.known_hosts = ''
while True:
self.channels = {}
# The connection object itself is treated as channel 0
super(Connection, self).__init__(self, 0)
self.transport = None
# Properties set in the Tune method
self.channel_max = 65535
self.frame_max = 131072
self.heartbeat = 0
# Properties set in the Start method
self.version_major = 0
self.version_minor = 0
self.server_properties = {}
self.mechanisms = []
self.locales = []
# Let the transport.py module setup the actual
# socket connection to the broker.
#
self.transport = create_transport(host, connect_timeout, ssl)
self.method_reader = MethodReader(self.transport)
self.method_writer = MethodWriter(self.transport, self.frame_max)
self.wait(allowed_methods=[
(10, 10), # start
])
self._x_start_ok(d, login_method, login_response, locale)
self._wait_tune_ok = True
while self._wait_tune_ok:
self.wait(allowed_methods=[
(10, 20), # secure
(10, 30), # tune
])
host = self._x_open(virtual_host, insist=insist)
if host is None:
# we weren't redirected
return
# we were redirected, close the socket, loop and try again
try:
self.close()
except Exception:
pass
def _do_close(self):
self.transport.close()
self.transport = None
temp_list = [x for x in self.channels.values() if x is not self]
for ch in temp_list:
ch._do_close()
self.connection = self.channels = None
def _get_free_channel_id(self):
for i in xrange(1, self.channel_max+1):
if i not in self.channels:
return i
raise AMQPException('No free channel ids, current=%d, channel_max=%d'
% (len(self.channels), self.channel_max))
def _wait_method(self, channel_id, allowed_methods):
"""
Wait for a method from the server destined for
a particular channel.
"""
#
# Check the channel's deferred methods
#
method_queue = self.channels[channel_id].method_queue
for queued_method in method_queue:
method_sig = queued_method[0]
if (allowed_methods is None) \
or (method_sig in allowed_methods) \
or (method_sig == (20, 40)):
method_queue.remove(queued_method)
return queued_method
#
# Nothing queued, need to wait for a method from the peer
#
while True:
channel, method_sig, args, content = \
self.method_reader.read_method()
if (channel == channel_id) \
and ((allowed_methods is None) \
or (method_sig in allowed_methods) \
or (method_sig == (20, 40))):
return method_sig, args, content
#
# Certain methods like basic_return should be dispatched
# immediately rather than being queued, even if they're not
# one of the 'allowed_methods' we're looking for.
#
if (channel != 0) and (method_sig in Channel._IMMEDIATE_METHODS):
self.channels[channel].dispatch_method(method_sig, args, content)
continue
#
# Not the channel and/or method we were looking for. Queue
# this method for later
#
self.channels[channel].method_queue.append((method_sig, args, content))
#
# If we just queued up a method for channel 0 (the Connection
# itself) it's probably a close method in reaction to some
# error, so deal with it right away.
#
if channel == 0:
self.wait()
def channel(self, channel_id=None):
"""
Fetch a Channel object identified by the numeric channel_id, or
create that object if it doesn't already exist.
"""
if channel_id in self.channels:
return self.channels[channel_id]
return Channel(self, channel_id)
#################
def close(self, reply_code=0, reply_text='', method_sig=(0, 0)):
"""
request a connection close
This method indicates that the sender wants to close the
connection. This may be due to internal conditions (e.g. a
forced shut-down) or due to an error handling a specific
method, i.e. an exception. When a close is due to an
exception, the sender provides the class and method id of the
method which caused the exception.
RULE:
After sending this method any received method except the
Close-OK method MUST be discarded.
RULE:
The peer sending this method MAY use a counter or timeout
to detect failure of the other peer to respond correctly
with the Close-OK method.
RULE:
When a server receives the Close method from a client it
MUST delete all server-side resources associated with the
client's context. A client CANNOT reconnect to a context
after sending or receiving a Close method.
PARAMETERS:
reply_code: short
The reply code. The AMQ reply codes are defined in AMQ
RFC 011.
reply_text: shortstr
The localised reply text. This text can be logged as an
aid to resolving issues.
class_id: short
failing method class
When the close is provoked by a method exception, this
is the class of the method.
method_id: short
failing method ID
When the close is provoked by a method exception, this
is the ID of the method.
"""
if self.transport is None:
# already closed
return
args = AMQPWriter()
args.write_short(reply_code)
args.write_shortstr(reply_text)
args.write_short(method_sig[0]) # class_id
args.write_short(method_sig[1]) # method_id
self._send_method((10, 60), args)
return self.wait(allowed_methods=[
(10, 61), # Connection.close_ok
])
def _close(self, args):
"""
request a connection close
This method indicates that the sender wants to close the
connection. This may be due to internal conditions (e.g. a
forced shut-down) or due to an error handling a specific
method, i.e. an exception. When a close is due to an
exception, the sender provides the class and method id of the
method which caused the exception.
RULE:
After sending this method any received method except the
Close-OK method MUST be discarded.
RULE:
The peer sending this method MAY use a counter or timeout
to detect failure of the other peer to respond correctly
with the Close-OK method.
RULE:
When a server receives the Close method from a client it
MUST delete all server-side resources associated with the
client's context. A client CANNOT reconnect to a context
after sending or receiving a Close method.
PARAMETERS:
reply_code: short
The reply code. The AMQ reply codes are defined in AMQ
RFC 011.
reply_text: shortstr
The localised reply text. This text can be logged as an
aid to resolving issues.
class_id: short
failing method class
When the close is provoked by a method exception, this
is the class of the method.
method_id: short
failing method ID
When the close is provoked by a method exception, this
is the ID of the method.
"""
reply_code = args.read_short()
reply_text = args.read_shortstr()
class_id = args.read_short()
method_id = args.read_short()
self._x_close_ok()
raise AMQPConnectionException(reply_code, reply_text, (class_id, method_id))
def _x_close_ok(self):
"""
confirm a connection close
This method confirms a Connection.Close method and tells the
recipient that it is safe to release resources for the
connection and close the socket.
RULE:
A peer that detects a socket closure without having
received a Close-Ok handshake method SHOULD log the error.
"""
self._send_method((10, 61))
self._do_close()
def _close_ok(self, args):
"""
confirm a connection close
This method confirms a Connection.Close method and tells the
recipient that it is safe to release resources for the
connection and close the socket.
RULE:
A peer that detects a socket closure without having
received a Close-Ok handshake method SHOULD log the error.
"""
self._do_close()
def _x_open(self, virtual_host, capabilities='', insist=False):
"""
open connection to virtual host
This method opens a connection to a virtual host, which is a
collection of resources, and acts to separate multiple
application domains within a server.
RULE:
The client MUST open the context before doing any work on
the connection.
PARAMETERS:
virtual_host: shortstr
virtual host name
The name of the virtual host to work with.
RULE:
If the server supports multiple virtual hosts, it
MUST enforce a full separation of exchanges,
queues, and all associated entities per virtual
host. An application, connected to a specific
virtual host, MUST NOT be able to access resources
of another virtual host.
RULE:
The server SHOULD verify that the client has
permission to access the specified virtual host.
RULE:
The server MAY configure arbitrary limits per
virtual host, such as the number of each type of
entity that may be used, per connection and/or in
total.
capabilities: shortstr
required capabilities
The client may specify a number of capability names,
delimited by spaces. The server can use this string
to how to process the client's connection request.
insist: boolean
insist on connecting to server
In a configuration with multiple load-sharing servers,
the server may respond to a Connection.Open method
with a Connection.Redirect. The insist option tells
the server that the client is insisting on a
connection to the specified server.
RULE:
When the client uses the insist option, the server
SHOULD accept the client connection unless it is
technically unable to do so.
"""
args = AMQPWriter()
args.write_shortstr(virtual_host)
args.write_shortstr(capabilities)
args.write_bit(insist)
self._send_method((10, 40), args)
return self.wait(allowed_methods=[
(10, 41), # Connection.open_ok
(10, 50), # Connection.redirect
])
def _open_ok(self, args):
"""
signal that the connection is ready
This method signals to the client that the connection is ready
for use.
PARAMETERS:
known_hosts: shortstr
"""
self.known_hosts = args.read_shortstr()
AMQP_LOGGER.debug('Open OK! known_hosts [%s]' % self.known_hosts)
return None
def _redirect(self, args):
"""
asks the client to use a different server
This method redirects the client to another server, based on
the requested virtual host and/or capabilities.
RULE:
When getting the Connection.Redirect method, the client
SHOULD reconnect to the host specified, and if that host
is not present, to any of the hosts specified in the
known-hosts list.
PARAMETERS:
host: shortstr
server to connect to
Specifies the server to connect to. This is an IP
address or a DNS name, optionally followed by a colon
and a port number. If no port number is specified, the
client should use the default port number for the
protocol.
known_hosts: shortstr
"""
host = args.read_shortstr()
self.known_hosts = args.read_shortstr()
AMQP_LOGGER.debug('Redirected to [%s], known_hosts [%s]' % (host, self.known_hosts))
return host
def _secure(self, args):
"""
security mechanism challenge
The SASL protocol works by exchanging challenges and responses
until both peers have received sufficient information to
authenticate each other. This method challenges the client to
provide more information.
PARAMETERS:
challenge: longstr
security challenge data
Challenge information, a block of opaque binary data
passed to the security mechanism.
"""
challenge = args.read_longstr()
def _x_secure_ok(self, response):
"""
security mechanism response
This method attempts to authenticate, passing a block of SASL
data for the security mechanism at the server side.
PARAMETERS:
response: longstr
security response data
A block of opaque data passed to the security
mechanism. The contents of this data are defined by
the SASL security mechanism.
"""
args = AMQPWriter()
args.write_longstr(response)
self._send_method((10, 21), args)
def _start(self, args):
"""
start connection negotiation
This method starts the connection negotiation process by
telling the client the protocol version that the server
proposes, along with a list of security mechanisms which the
client can use for authentication.
RULE:
If the client cannot handle the protocol version suggested
by the server it MUST close the socket connection.
RULE:
The server MUST provide a protocol version that is lower
than or equal to that requested by the client in the
protocol header. If the server cannot support the
specified protocol it MUST NOT send this method, but MUST
close the socket connection.
PARAMETERS:
version_major: octet
protocol major version
The protocol major version that the server agrees to
use, which cannot be higher than the client's major
version.
version_minor: octet
protocol major version
The protocol minor version that the server agrees to
use, which cannot be higher than the client's minor
version.
server_properties: table
server properties
mechanisms: longstr
available security mechanisms
A list of the security mechanisms that the server
supports, delimited by spaces. Currently ASL supports
these mechanisms: PLAIN.
locales: longstr
available message locales
A list of the message locales that the server
supports, delimited by spaces. The locale defines the
language in which the server will send reply texts.
RULE:
All servers MUST support at least the en_US
locale.
"""
self.version_major = args.read_octet()
self.version_minor = args.read_octet()
self.server_properties = args.read_table()
self.mechanisms = args.read_longstr().split(' ')
self.locales = args.read_longstr().split(' ')
AMQP_LOGGER.debug('Start from server, version: %d.%d, properties: %s, mechanisms: %s, locales: %s'
% (self.version_major, self.version_minor,
str(self.server_properties), self.mechanisms, self.locales))
def _x_start_ok(self, client_properties, mechanism, response, locale):
"""
select security mechanism and locale
This method selects a SASL security mechanism. ASL uses SASL
(RFC2222) to negotiate authentication and encryption.
PARAMETERS:
client_properties: table
client properties
mechanism: shortstr
selected security mechanism
A single security mechanisms selected by the client,
which must be one of those specified by the server.
RULE:
The client SHOULD authenticate using the highest-
level security profile it can handle from the list
provided by the server.
RULE:
The mechanism field MUST contain one of the
security mechanisms proposed by the server in the
Start method. If it doesn't, the server MUST close
the socket.
response: longstr
security response data
A block of opaque data passed to the security
mechanism. The contents of this data are defined by
the SASL security mechanism. For the PLAIN security
mechanism this is defined as a field table holding two
fields, LOGIN and PASSWORD.
locale: shortstr
selected message locale
A single message local selected by the client, which
must be one of those specified by the server.
"""
args = AMQPWriter()
args.write_table(client_properties)
args.write_shortstr(mechanism)
args.write_longstr(response)
args.write_shortstr(locale)
self._send_method((10, 11), args)
def _tune(self, args):
"""
propose connection tuning parameters
This method proposes a set of connection configuration values
to the client. The client can accept and/or adjust these.
PARAMETERS:
channel_max: short
proposed maximum channels
The maximum total number of channels that the server
allows per connection. Zero means that the server does
not impose a fixed limit, but the number of allowed
channels may be limited by available server resources.
frame_max: long
proposed maximum frame size
The largest frame size that the server proposes for
the connection. The client can negotiate a lower
value. Zero means that the server does not impose any
specific limit but may reject very large frames if it
cannot allocate resources for them.
RULE:
Until the frame-max has been negotiated, both
peers MUST accept frames of up to 4096 octets
large. The minimum non-zero value for the frame-
max field is 4096.
heartbeat: short
desired heartbeat delay
The delay, in seconds, of the connection heartbeat
that the server wants. Zero means the server does not
want a heartbeat.
"""
self.channel_max = args.read_short() or self.channel_max
self.frame_max = args.read_long() or self.frame_max
self.method_writer.frame_max = self.frame_max
self.heartbeat = args.read_short()
self._x_tune_ok(self.channel_max, self.frame_max, 0)
def _x_tune_ok(self, channel_max, frame_max, heartbeat):
"""
negotiate connection tuning parameters
This method sends the client's connection tuning parameters to
the server. Certain fields are negotiated, others provide
capability information.
PARAMETERS:
channel_max: short
negotiated maximum channels
The maximum total number of channels that the client
will use per connection. May not be higher than the
value specified by the server.
RULE:
The server MAY ignore the channel-max value or MAY
use it for tuning its resource allocation.
frame_max: long
negotiated maximum frame size
The largest frame size that the client and server will
use for the connection. Zero means that the client
does not impose any specific limit but may reject very
large frames if it cannot allocate resources for them.
Note that the frame-max limit applies principally to
content frames, where large contents can be broken
into frames of arbitrary size.
RULE:
Until the frame-max has been negotiated, both
peers must accept frames of up to 4096 octets
large. The minimum non-zero value for the frame-
max field is 4096.
heartbeat: short
desired heartbeat delay
The delay, in seconds, of the connection heartbeat
that the client wants. Zero means the client does not
want a heartbeat.
"""
args = AMQPWriter()
args.write_short(channel_max)
args.write_long(frame_max)
args.write_short(heartbeat)
self._send_method((10, 31), args)
self._wait_tune_ok = False
_METHOD_MAP = {
(10, 10): _start,
(10, 20): _secure,
(10, 30): _tune,
(10, 41): _open_ok,
(10, 50): _redirect,
(10, 60): _close,
(10, 61): _close_ok,
}
_IMMEDIATE_METHODS = []

Просмотреть файл

@ -1,105 +0,0 @@
"""
Exceptions used by amqplib.client_0_8
"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
__all__ = [
'AMQPException',
'AMQPConnectionException',
'AMQPChannelException',
]
class AMQPException(Exception):
def __init__(self, reply_code, reply_text, method_sig):
Exception.__init__(self)
self.amqp_reply_code = reply_code
self.amqp_reply_text = reply_text
self.amqp_method_sig = method_sig
self.args = (
reply_code,
reply_text,
method_sig,
METHOD_NAME_MAP.get(method_sig, '')
)
class AMQPConnectionException(AMQPException):
pass
class AMQPChannelException(AMQPException):
pass
METHOD_NAME_MAP = {
(10, 10): 'Connection.start',
(10, 11): 'Connection.start_ok',
(10, 20): 'Connection.secure',
(10, 21): 'Connection.secure_ok',
(10, 30): 'Connection.tune',
(10, 31): 'Connection.tune_ok',
(10, 40): 'Connection.open',
(10, 41): 'Connection.open_ok',
(10, 50): 'Connection.redirect',
(10, 60): 'Connection.close',
(10, 61): 'Connection.close_ok',
(20, 10): 'Channel.open',
(20, 11): 'Channel.open_ok',
(20, 20): 'Channel.flow',
(20, 21): 'Channel.flow_ok',
(20, 30): 'Channel.alert',
(20, 40): 'Channel.close',
(20, 41): 'Channel.close_ok',
(30, 10): 'Channel.access_request',
(30, 11): 'Channel.access_request_ok',
(40, 10): 'Channel.exchange_declare',
(40, 11): 'Channel.exchange_declare_ok',
(40, 20): 'Channel.exchange_delete',
(40, 21): 'Channel.exchange_delete_ok',
(50, 10): 'Channel.queue_declare',
(50, 11): 'Channel.queue_declare_ok',
(50, 20): 'Channel.queue_bind',
(50, 21): 'Channel.queue_bind_ok',
(50, 30): 'Channel.queue_purge',
(50, 31): 'Channel.queue_purge_ok',
(50, 40): 'Channel.queue_delete',
(50, 41): 'Channel.queue_delete_ok',
(60, 10): 'Channel.basic_qos',
(60, 11): 'Channel.basic_qos_ok',
(60, 20): 'Channel.basic_consume',
(60, 21): 'Channel.basic_consume_ok',
(60, 30): 'Channel.basic_cancel',
(60, 31): 'Channel.basic_cancel_ok',
(60, 40): 'Channel.basic_publish',
(60, 50): 'Channel.basic_return',
(60, 60): 'Channel.basic_deliver',
(60, 70): 'Channel.basic_get',
(60, 71): 'Channel.basic_get_ok',
(60, 72): 'Channel.basic_get_empty',
(60, 80): 'Channel.basic_ack',
(60, 90): 'Channel.basic_reject',
(60, 100): 'Channel.basic_recover',
(90, 10): 'Channel.tx_select',
(90, 11): 'Channel.tx_select_ok',
(90, 20): 'Channel.tx_commit',
(90, 21): 'Channel.tx_commit_ok',
(90, 30): 'Channel.tx_rollback',
(90, 31): 'Channel.tx_rollback_ok',
}

Просмотреть файл

@ -1,261 +0,0 @@
"""
Convert between frames and higher-level AMQP methods
"""
# Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
from Queue import Empty, Queue
from struct import pack, unpack
try:
bytes
except NameError:
# Python 2.5 and lower
bytes = str
try:
from collections import defaultdict
except:
class defaultdict(dict):
"""
Mini-implementation of collections.defaultdict that
appears in Python 2.5 and up.
"""
def __init__(self, default_factory):
dict.__init__(self)
self.default_factory = default_factory
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
result = self.default_factory()
dict.__setitem__(self, key, result)
return result
from basic_message import Message
from exceptions import *
from serialization import AMQPReader
__all__ = [
'MethodReader',
]
#
# MethodReader needs to know which methods are supposed
# to be followed by content headers and bodies.
#
_CONTENT_METHODS = [
(60, 50), # Basic.return
(60, 60), # Basic.deliver
(60, 71), # Basic.get_ok
]
class _PartialMessage(object):
"""
Helper class to build up a multi-frame method.
"""
def __init__(self, method_sig, args):
self.method_sig = method_sig
self.args = args
self.msg = Message()
self.body_parts = []
self.body_received = 0
self.body_size = None
self.complete = False
def add_header(self, payload):
class_id, weight, self.body_size = unpack('>HHQ', payload[:12])
self.msg._load_properties(payload[12:])
self.complete = (self.body_size == 0)
def add_payload(self, payload):
self.body_parts.append(payload)
self.body_received += len(payload)
if self.body_received == self.body_size:
self.msg.body = bytes().join(self.body_parts)
self.complete = True
class MethodReader(object):
"""
Helper class to receive frames from the broker, combine them if
necessary with content-headers and content-bodies into complete methods.
Normally a method is represented as a tuple containing
(channel, method_sig, args, content).
In the case of a framing error, an AMQPConnectionException is placed
in the queue.
In the case of unexpected frames, a tuple made up of
(channel, AMQPChannelException) is placed in the queue.
"""
def __init__(self, source):
self.source = source
self.queue = Queue()
self.running = False
self.partial_messages = {}
# For each channel, which type is expected next
self.expected_types = defaultdict(lambda:1)
def _next_method(self):
"""
Read the next method from the source, once one complete method has
been assembled it is placed in the internal queue.
"""
while self.queue.empty():
try:
frame_type, channel, payload = self.source.read_frame()
except Exception, e:
#
# Connection was closed? Framing Error?
#
self.queue.put(e)
break
if self.expected_types[channel] != frame_type:
self.queue.put((
channel,
Exception('Received frame type %s while expecting type: %s' %
(frame_type, self.expected_types[channel])
)
))
elif frame_type == 1:
self._process_method_frame(channel, payload)
elif frame_type == 2:
self._process_content_header(channel, payload)
elif frame_type == 3:
self._process_content_body(channel, payload)
def _process_method_frame(self, channel, payload):
"""
Process Method frames
"""
method_sig = unpack('>HH', payload[:4])
args = AMQPReader(payload[4:])
if method_sig in _CONTENT_METHODS:
#
# Save what we've got so far and wait for the content-header
#
self.partial_messages[channel] = _PartialMessage(method_sig, args)
self.expected_types[channel] = 2
else:
self.queue.put((channel, method_sig, args, None))
def _process_content_header(self, channel, payload):
"""
Process Content Header frames
"""
partial = self.partial_messages[channel]
partial.add_header(payload)
if partial.complete:
#
# a bodyless message, we're done
#
self.queue.put((channel, partial.method_sig, partial.args, partial.msg))
del self.partial_messages[channel]
self.expected_types[channel] = 1
else:
#
# wait for the content-body
#
self.expected_types[channel] = 3
def _process_content_body(self, channel, payload):
"""
Process Content Body frames
"""
partial = self.partial_messages[channel]
partial.add_payload(payload)
if partial.complete:
#
# Stick the message in the queue and go back to
# waiting for method frames
#
self.queue.put((channel, partial.method_sig, partial.args, partial.msg))
del self.partial_messages[channel]
self.expected_types[channel] = 1
def read_method(self):
"""
Read a method from the peer.
"""
self._next_method()
m = self.queue.get()
if isinstance(m, Exception):
raise m
return m
class MethodWriter(object):
"""
Convert AMQP methods into AMQP frames and send them out
to the peer.
"""
def __init__(self, dest, frame_max):
self.dest = dest
self.frame_max = frame_max
def write_method(self, channel, method_sig, args, content=None):
payload = pack('>HH', method_sig[0], method_sig[1]) + args
if content:
# do this early, so we can raise an exception if there's a
# problem with the content properties, before sending the
# first frame
body = content.body
if isinstance(body, unicode):
coding = content.properties.get('content_encoding', None)
if coding is None:
coding = content.properties['content_encoding'] = 'UTF-8'
body = body.encode(coding)
properties = content._serialize_properties()
self.dest.write_frame(1, channel, payload)
if content:
payload = pack('>HHQ', method_sig[0], 0, len(body)) + properties
self.dest.write_frame(2, channel, payload)
chunk_size = self.frame_max - 8
for i in xrange(0, len(body), chunk_size):
self.dest.write_frame(3, channel, body[i:i+chunk_size])

Просмотреть файл

@ -1,541 +0,0 @@
"""
Convert between bytestreams and higher-level AMQP types.
2007-11-05 Barry Pederson <bp@barryp.org>
"""
# Copyright (C) 2007 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
import string
import sys
from datetime import datetime
from decimal import Decimal
from struct import pack, unpack
from time import mktime
IS_PY3K = sys.version_info[0] >= 3
if IS_PY3K:
def byte(n):
return bytes([n])
else:
byte = chr
try:
from io import BytesIO
except:
# Python 2.5 and lower
try:
from cStringIO import StringIO as BytesIO
except:
from StringIO import StringIO as BytesIO
try:
bytes
except NameError:
# Python 2.5 and lower
bytes = str
class AMQPReader(object):
"""
Read higher-level AMQP types from a bytestream.
"""
def __init__(self, source):
"""
Source should be either a file-like object with a read() method, or
a plain (non-unicode) string.
"""
if isinstance(source, bytes):
self.input = BytesIO(source)
elif hasattr(source, 'read'):
self.input = source
else:
raise ValueError('AMQPReader needs a file-like object or plain string')
self.bitcount = self.bits = 0
def close(self):
self.input.close()
def read(self, n):
"""
Read n bytes.
"""
self.bitcount = self.bits = 0
return self.input.read(n)
def read_bit(self):
"""
Read a single boolean value.
"""
if not self.bitcount:
self.bits = ord(self.input.read(1))
self.bitcount = 8
result = (self.bits & 1) == 1
self.bits >>= 1
self.bitcount -= 1
return result
def read_octet(self):
"""
Read one byte, return as an integer
"""
self.bitcount = self.bits = 0
return unpack('B', self.input.read(1))[0]
def read_short(self):
"""
Read an unsigned 16-bit integer
"""
self.bitcount = self.bits = 0
return unpack('>H', self.input.read(2))[0]
def read_long(self):
"""
Read an unsigned 32-bit integer
"""
self.bitcount = self.bits = 0
return unpack('>I', self.input.read(4))[0]
def read_longlong(self):
"""
Read an unsigned 64-bit integer
"""
self.bitcount = self.bits = 0
return unpack('>Q', self.input.read(8))[0]
def read_shortstr(self):
"""
Read a short string that's stored in up to 255 bytes.
The encoding isn't specified in the AMQP spec, so
assume it's utf-8
"""
self.bitcount = self.bits = 0
slen = unpack('B', self.input.read(1))[0]
return self.input.read(slen).decode('utf-8')
def read_longstr(self):
"""
Read a string that's up to 2**32 bytes.
The encoding isn't specified in the AMQP spec, so
assume it's utf-8
"""
self.bitcount = self.bits = 0
slen = unpack('>I', self.input.read(4))[0]
return self.input.read(slen).decode('utf-8')
def read_table(self):
"""
Read an AMQP table, and return as a Python dictionary.
"""
self.bitcount = self.bits = 0
tlen = unpack('>I', self.input.read(4))[0]
table_data = AMQPReader(self.input.read(tlen))
result = {}
while table_data.input.tell() < tlen:
name = table_data.read_shortstr()
ftype = ord(table_data.input.read(1))
if ftype == 83: # 'S'
val = table_data.read_longstr()
elif ftype == 73: # 'I'
val = unpack('>i', table_data.input.read(4))[0]
elif ftype == 68: # 'D'
d = table_data.read_octet()
n = unpack('>i', table_data.input.read(4))[0]
val = Decimal(n) / Decimal(10 ** d)
elif ftype == 84: # 'T'
val = table_data.read_timestamp()
elif ftype == 70: # 'F'
val = table_data.read_table() # recurse
else:
raise ValueError('Unknown table item type: %s' % repr(ftype))
result[name] = val
return result
def read_timestamp(self):
"""
Read and AMQP timestamp, which is a 64-bit integer representing
seconds since the Unix epoch in 1-second resolution. Return as
a Python datetime.datetime object, expressed as localtime.
"""
return datetime.fromtimestamp(self.read_longlong())
class AMQPWriter(object):
"""
Convert higher-level AMQP types to bytestreams.
"""
def __init__(self, dest=None):
"""
dest may be a file-type object (with a write() method). If None
then a BytesIO is created, and the contents can be accessed with
this class's getvalue() method.
"""
if dest is None:
self.out = BytesIO()
else:
self.out = dest
self.bits = []
self.bitcount = 0
def _flushbits(self):
if self.bits:
for b in self.bits:
self.out.write(pack('B', b))
self.bits = []
self.bitcount = 0
def close(self):
"""
Pass through if possible to any file-like destinations.
"""
if hasattr(self.out, 'close'):
self.out.close()
def flush(self):
"""
Pass through if possible to any file-like destinations.
"""
if hasattr(self.out, 'flush'):
self.out.flush()
def getvalue(self):
"""
Get what's been encoded so far if we're working with a BytesIO.
"""
self._flushbits()
return self.out.getvalue()
def write(self, s):
"""
Write a plain Python string with no special encoding in Python 2.x,
or bytes in Python 3.x
"""
self._flushbits()
self.out.write(s)
def write_bit(self, b):
"""
Write a boolean value.
"""
if b:
b = 1
else:
b = 0
shift = self.bitcount % 8
if shift == 0:
self.bits.append(0)
self.bits[-1] |= (b << shift)
self.bitcount += 1
def write_octet(self, n):
"""
Write an integer as an unsigned 8-bit value.
"""
if (n < 0) or (n > 255):
raise ValueError('Octet out of range 0..255')
self._flushbits()
self.out.write(pack('B', n))
def write_short(self, n):
"""
Write an integer as an unsigned 16-bit value.
"""
if (n < 0) or (n > 65535):
raise ValueError('Octet out of range 0..65535')
self._flushbits()
self.out.write(pack('>H', n))
def write_long(self, n):
"""
Write an integer as an unsigned2 32-bit value.
"""
if (n < 0) or (n >= (2**32)):
raise ValueError('Octet out of range 0..2**31-1')
self._flushbits()
self.out.write(pack('>I', n))
def write_longlong(self, n):
"""
Write an integer as an unsigned 64-bit value.
"""
if (n < 0) or (n >= (2**64)):
raise ValueError('Octet out of range 0..2**64-1')
self._flushbits()
self.out.write(pack('>Q', n))
def write_shortstr(self, s):
"""
Write a string up to 255 bytes long (after any encoding).
If passed a unicode string, encode with UTF-8.
"""
self._flushbits()
if isinstance(s, unicode):
s = s.encode('utf-8')
if len(s) > 255:
raise ValueError('String too long')
self.write_octet(len(s))
self.out.write(s)
def write_longstr(self, s):
"""
Write a string up to 2**32 bytes long after encoding.
If passed a unicode string, encode as UTF-8.
"""
self._flushbits()
if isinstance(s, unicode):
s = s.encode('utf-8')
self.write_long(len(s))
self.out.write(s)
def write_table(self, d):
"""
Write out a Python dictionary made of up string keys, and values
that are strings, signed integers, Decimal, datetime.datetime, or
sub-dictionaries following the same constraints.
"""
self._flushbits()
table_data = AMQPWriter()
for k, v in d.items():
table_data.write_shortstr(k)
if isinstance(v, basestring):
if isinstance(v, unicode):
v = v.encode('utf-8')
table_data.write(byte(83)) # 'S'
table_data.write_longstr(v)
elif isinstance(v, (int, long)):
table_data.write(byte(73)) # 'I'
table_data.write(pack('>i', v))
elif isinstance(v, Decimal):
table_data.write(byte(68)) # 'D'
sign, digits, exponent = v.as_tuple()
v = 0
for d in digits:
v = (v * 10) + d
if sign:
v = -v
table_data.write_octet(-exponent)
table_data.write(pack('>i', v))
elif isinstance(v, datetime):
table_data.write(byte(84)) # 'T'
table_data.write_timestamp(v)
## FIXME: timezone ?
elif isinstance(v, dict):
table_data.write(byte(70)) # 'F'
table_data.write_table(v)
else:
raise ValueError('%s not serializable in AMQP' % repr(v))
table_data = table_data.getvalue()
self.write_long(len(table_data))
self.out.write(table_data)
def write_timestamp(self, v):
"""
Write out a Python datetime.datetime object as a 64-bit integer
representing seconds since the Unix epoch.
"""
self.out.write(pack('>q', long(mktime(v.timetuple()))))
class GenericContent(object):
"""
Abstract base class for AMQP content. Subclasses should
override the PROPERTIES attribute.
"""
PROPERTIES = [
('dummy', 'shortstr'),
]
def __init__(self, **props):
"""
Save the properties appropriate to this AMQP content type
in a 'properties' dictionary.
"""
d = {}
for propname, _ in self.PROPERTIES:
if propname in props:
d[propname] = props[propname]
# FIXME: should we ignore unknown properties?
self.properties = d
def __eq__(self, other):
"""
Check if this object has the same properties as another
content object.
"""
return hasattr(other, 'properties') \
and (self.properties == other.properties)
def __getattr__(self, name):
"""
Look for additional properties in the 'properties'
dictionary, and if present - the 'delivery_info'
dictionary.
"""
if name == '__setstate__':
# Allows pickling/unpickling to work
raise AttributeError('__setstate__')
if name in self.properties:
return self.properties[name]
if ('delivery_info' in self.__dict__) \
and (name in self.delivery_info):
return self.delivery_info[name]
raise AttributeError(name)
def __ne__(self, other):
"""
Just return the opposite of __eq__
"""
return not self.__eq__(other)
def _load_properties(self, raw_bytes):
"""
Given the raw bytes containing the property-flags and property-list
from a content-frame-header, parse and insert into a dictionary
stored in this object as an attribute named 'properties'.
"""
r = AMQPReader(raw_bytes)
#
# Read 16-bit shorts until we get one with a low bit set to zero
#
flags = []
while True:
flag_bits = r.read_short()
flags.append(flag_bits)
if flag_bits & 1 == 0:
break
shift = 0
d = {}
for key, proptype in self.PROPERTIES:
if shift == 0:
if not flags:
break
flag_bits, flags = flags[0], flags[1:]
shift = 15
if flag_bits & (1 << shift):
d[key] = getattr(r, 'read_' + proptype)()
shift -= 1
self.properties = d
def _serialize_properties(self):
"""
serialize the 'properties' attribute (a dictionary) into
the raw bytes making up a set of property flags and a
property list, suitable for putting into a content frame header.
"""
shift = 15
flag_bits = 0
flags = []
raw_bytes = AMQPWriter()
for key, proptype in self.PROPERTIES:
val = self.properties.get(key, None)
if val is not None:
if shift == 0:
flags.append(flag_bits)
flag_bits = 0
shift = 15
flag_bits |= (1 << shift)
if proptype != 'bit':
getattr(raw_bytes, 'write_' + proptype)(val)
shift -= 1
flags.append(flag_bits)
result = AMQPWriter()
for flag_bits in flags:
result.write_short(flag_bits)
result.write(raw_bytes.getvalue())
return result.getvalue()

Просмотреть файл

@ -1,281 +0,0 @@
"""
Read/Write AMQP frames over network transports.
2009-01-14 Barry Pederson <bp@barryp.org>
"""
# Copyright (C) 2009 Barry Pederson <bp@barryp.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
import re
import socket
#
# See if Python 2.6+ SSL support is available
#
try:
import ssl
HAVE_PY26_SSL = True
except:
HAVE_PY26_SSL = False
try:
bytes
except:
# Python 2.5 and lower
bytes = str
from struct import pack, unpack
AMQP_PORT = 5672
# Yes, Advanced Message Queuing Protocol Protocol is redundant
AMQP_PROTOCOL_HEADER = 'AMQP\x01\x01\x09\x01'.encode('latin_1')
# Match things like: [fe80::1]:5432, from RFC 2732
IPV6_LITERAL = re.compile(r'\[([\.0-9a-f:]+)\](?::(\d+))?')
class _AbstractTransport(object):
"""
Common superclass for TCP and SSL transports
"""
def __init__(self, host, connect_timeout):
msg = 'socket.getaddrinfo() for %s returned an empty list' % host
port = AMQP_PORT
m = IPV6_LITERAL.match(host)
if m:
host = m.group(1)
if m.group(2):
port = int(m.group(2))
else:
if ':' in host:
host, port = host.rsplit(':', 1)
port = int(port)
self.sock = None
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM, socket.SOL_TCP):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
self.sock.settimeout(connect_timeout)
self.sock.connect(sa)
except socket.error, msg:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
# Didn't connect, return the most recent error message
raise socket.error, msg
self.sock.settimeout(None)
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self._setup_transport()
self._write(AMQP_PROTOCOL_HEADER)
def __del__(self):
self.close()
def _read(self, n):
"""
Read exactly n bytes from the peer
"""
raise NotImplementedError('Must be overriden in subclass')
def _setup_transport(self):
"""
Do any additional initialization of the class (used
by the subclasses).
"""
pass
def _shutdown_transport(self):
"""
Do any preliminary work in shutting down the connection.
"""
pass
def _write(self, s):
"""
Completely write a string to the peer.
"""
raise NotImplementedError('Must be overriden in subclass')
def close(self):
if self.sock is not None:
self._shutdown_transport()
# Call shutdown first to make sure that pending messages
# reach the AMQP broker if the program exits after
# calling this method.
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
self.sock = None
def read_frame(self):
"""
Read an AMQP frame.
"""
frame_type, channel, size = unpack('>BHI', self._read(7))
payload = self._read(size)
ch = ord(self._read(1))
if ch == 206: # '\xce'
return frame_type, channel, payload
else:
raise Exception('Framing Error, received 0x%02x while expecting 0xce' % ch)
def write_frame(self, frame_type, channel, payload):
"""
Write out an AMQP frame.
"""
size = len(payload)
self._write(pack('>BHI%dsB' % size,
frame_type, channel, size, payload, 0xce))
class SSLTransport(_AbstractTransport):
"""
Transport that works over SSL
"""
def __init__(self, host, connect_timeout, ssl):
if isinstance(ssl, dict):
self.sslopts = ssl
self.sslobj = None
super(SSLTransport, self).__init__(host, connect_timeout)
def _setup_transport(self):
"""
Wrap the socket in an SSL object, either the
new Python 2.6 version, or the older Python 2.5 and
lower version.
"""
if HAVE_PY26_SSL:
if hasattr(self, 'sslopts'):
self.sslobj = ssl.wrap_socket(self.sock, **self.sslopts)
else:
self.sslobj = ssl.wrap_socket(self.sock)
self.sslobj.do_handshake()
else:
self.sslobj = socket.ssl(self.sock)
def _shutdown_transport(self):
"""
Unwrap a Python 2.6 SSL socket, so we can call shutdown()
"""
if HAVE_PY26_SSL and (self.sslobj is not None):
self.sock = self.sslobj.unwrap()
self.sslobj = None
def _read(self, n):
"""
It seems that SSL Objects read() method may not supply as much
as you're asking for, at least with extremely large messages.
somewhere > 16K - found this in the test_channel.py test_large
unittest.
"""
result = self.sslobj.read(n)
while len(result) < n:
s = self.sslobj.read(n - len(result))
if not s:
raise IOError('Socket closed')
result += s
return result
def _write(self, s):
"""
Write a string out to the SSL socket fully.
"""
while s:
n = self.sslobj.write(s)
if not n:
raise IOError('Socket closed')
s = s[n:]
class TCPTransport(_AbstractTransport):
"""
Transport that deals directly with TCP socket.
"""
def _setup_transport(self):
"""
Setup to _write() directly to the socket, and
do our own buffered reads.
"""
self._write = self.sock.sendall
self._read_buffer = bytes()
def _read(self, n):
"""
Read exactly n bytes from the socket
"""
while len(self._read_buffer) < n:
s = self.sock.recv(65536)
if not s:
raise IOError('Socket closed')
self._read_buffer += s
result = self._read_buffer[:n]
self._read_buffer = self._read_buffer[n:]
return result
def create_transport(host, connect_timeout, ssl=False):
"""
Given a few parameters from the Connection constructor,
select and create a subclass of _AbstractTransport.
"""
if ssl:
return SSLTransport(host, connect_timeout, ssl)
else:
return TCPTransport(host, connect_timeout)

Просмотреть файл

@ -1,85 +0,0 @@
Metadata-Version: 1.0
Name: anyjson
Version: 0.3.3
Summary: Wraps the best available JSON implementation available in a common interface
Home-page: http://bitbucket.org/runeh/anyjson/
Author: Rune Halvorsen
Author-email: runefh@gmail.com
License: BSD
Description: ##############################
anyjson - JSON library wrapper
##############################
Overview
--------
Anyjson loads whichever is the fastest JSON module installed and provides
a uniform API regardless of which JSON implementation is used.
Originally part of carrot (http://github.com/ask/carrot/)
Examples
--------
To serialize a python object to a JSON string, call the `serialize` function:
>>> import anyjson
>>> anyjson.serialize(["test", 1, {"foo": 3.141592}, "bar"])
'["test", 1, {"foo": 3.141592}, "bar"]'
Conversion the other way is done with the `deserialize` call.
>>> anyjson.deserialize("""["test", 1, {"foo": 3.141592}, "bar"]""")
['test', 1, {'foo': 3.1415920000000002}, 'bar']
Regardless of the JSON implementation used, the exceptions will be the same.
This means that trying to serialize something not compatible with JSON
raises a TypeError:
>>> anyjson.serialize([object()])
Traceback (most recent call last):
<snipped traceback>
TypeError: object is not JSON encodable
And deserializing a JSON string with invalid JSON raises a ValueError:
>>> anyjson.deserialize("""['missing square brace!""")
Traceback (most recent call last):
<snipped traceback>
ValueError: cannot parse JSON description
Contact
-------
The module is maintaned by Rune F. Halvorsen <runefh@gmail.com>.
The project resides at http://bitbucket.org/runeh/anyjson . Bugs and feature
requests can be submitted there. Patches are also very welcome.
Changelog
---------
See CHANGELOG file
License
-------
see the LICENSE file
Keywords: json
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.4
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: Implementation :: Jython

Просмотреть файл

@ -1,15 +0,0 @@
CHANGELOG
LICENSE
MANIFEST.in
README
setup.cfg
setup.py
anyjson/__init__.py
anyjson.egg-info/PKG-INFO
anyjson.egg-info/SOURCES.txt
anyjson.egg-info/dependency_links.txt
anyjson.egg-info/not-zip-safe
anyjson.egg-info/top_level.txt
tests/benchmark.py
tests/test_implementations.py
tests/test_implementations.pyc

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,8 +0,0 @@
../anyjson/__init__.py
../anyjson/__init__.pyc
./
top_level.txt
SOURCES.txt
not-zip-safe
PKG-INFO
dependency_links.txt

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1 +0,0 @@
anyjson

Просмотреть файл

@ -1,142 +0,0 @@
"""Wraps the best available JSON implementation available in a common
interface"""
import sys
VERSION = (0, 3, 3)
__version__ = ".".join(map(str, VERSION[0:3])) + "".join(VERSION[3:])
__author__ = "Rune Halvorsen"
__contact__ = "runefh@gmail.com"
__homepage__ = "http://bitbucket.org/runeh/anyjson/"
__docformat__ = "restructuredtext"
# -eof meta-
#: The json implementation object. This is probably not useful to you,
#: except to get the name of the implementation in use. The name is
#: available through ``implementation.name``.
implementation = None
# json.loads does not support buffer() objects,
# so we load() and StringIO instead, and it won't copy.
if sys.version_info[0] == 3:
from io import StringIO
else:
try:
from cStringIO import StringIO # noqa
except ImportError:
from StringIO import StringIO # noqa
#: List of known json modules, and the names of their loads/dumps
#: methods, as well as the exceptions they throw. Exception can be either
#: an exception class or a string.
_modules = [("yajl", "dumps", TypeError, "loads", ValueError, "load"),
("jsonlib2", "write", "WriteError", "read", "ReadError", None),
("jsonlib", "write", "WriteError", "read", "ReadError", None),
("simplejson", "dumps", TypeError, "loads", ValueError, "load"),
("json", "dumps", TypeError, "loads", ValueError, "load"),
("django.utils.simplejson", "dumps", TypeError, "loads", ValueError, "load"),
("cjson", "encode", "EncodeError", "decode", "DecodeError", None)
]
_fields = ("modname", "encoder", "encerror",
"decoder", "decerror", "filedecoder")
class _JsonImplementation(object):
"""Incapsulates a JSON implementation"""
def __init__(self, modspec):
modinfo = dict(zip(_fields, modspec))
if modinfo["modname"] == "cjson":
import warnings
warnings.warn("cjson is deprecated! See http://pypi.python.org/pypi/python-cjson/1.0.5", DeprecationWarning)
# No try block. We want importerror to end up at caller
module = self._attempt_load(modinfo["modname"])
self.implementation = modinfo["modname"]
self._encode = getattr(module, modinfo["encoder"])
self._decode = getattr(module, modinfo["decoder"])
fdec = modinfo["filedecoder"]
self._filedecode = fdec and getattr(module, fdec)
self._encode_error = modinfo["encerror"]
self._decode_error = modinfo["decerror"]
if isinstance(modinfo["encerror"], basestring):
self._encode_error = getattr(module, modinfo["encerror"])
if isinstance(modinfo["decerror"], basestring):
self._decode_error = getattr(module, modinfo["decerror"])
self.name = modinfo["modname"]
def __repr__(self):
return "<_JsonImplementation instance using %s>" % self.name
def _attempt_load(self, modname):
"""Attempt to load module name modname, returning it on success,
throwing ImportError if module couldn't be imported"""
__import__(modname)
return sys.modules[modname]
def dumps(self, data):
"""Serialize the datastructure to json. Returns a string. Raises
TypeError if the object could not be serialized."""
try:
return self._encode(data)
except self._encode_error, exc:
raise TypeError, TypeError(*exc.args), sys.exc_info()[2]
serialize = dumps
def loads(self, s):
"""deserialize the string to python data types. Raises
ValueError if the string could not be parsed."""
# uses StringIO to support buffer objects.
try:
if self._filedecode and not isinstance(s, basestring):
return self._filedecode(StringIO(s))
return self._decode(s)
except self._decode_error, exc:
raise ValueError, ValueError(*exc.args), sys.exc_info()[2]
deserialize = loads
def force_implementation(modname):
"""Forces anyjson to use a specific json module if it's available"""
global implementation
for name, spec in [(e[0], e) for e in _modules]:
if name == modname:
implementation = _JsonImplementation(spec)
return
raise ImportError("No module named: %s" % modname)
if __name__ == "__main__":
# If run as a script, we do nothing but print an error message.
# We do NOT try to load a compatible module because that may throw an
# exception, which renders the package uninstallable with easy_install
# (It trys to execfile the script when installing, to make sure it works)
print "Running anyjson as a stand alone script is not supported"
sys.exit(1)
else:
for modspec in _modules:
try:
implementation = _JsonImplementation(modspec)
break
except ImportError:
pass
else:
raise ImportError("No supported JSON module found")
def loads(value):
"""Serialize the object to JSON."""
return implementation.loads(value)
deserialize = loads # compat
def dumps(value):
"""Deserialize JSON-encoded object to a Python object."""
return implementation.dumps(value)
serialize = dumps

Просмотреть файл

@ -1,14 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2008—2012 Andy Mikhailenko
#
# This file is part of django-autoslug.
#
# django-autoslug is free software under terms of the GNU Lesser
# General Public License version 3 (LGPLv3) as published by the Free
# Software Foundation. See the file README for copying conditions.
#
from fields import AutoSlugField
__all__ = ['AutoSlugField']

Просмотреть файл

@ -1,244 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2008—2012 Andy Mikhailenko
#
# This file is part of django-autoslug.
#
# django-autoslug is free software under terms of the GNU Lesser
# General Public License version 3 (LGPLv3) as published by the Free
# Software Foundation. See the file README for copying conditions.
#
# python
from warnings import warn
# django
from django.db.models.fields import SlugField
# 3rd-party
try:
from south.modelsinspector import introspector
except ImportError:
introspector = lambda self: [], {}
# this app
from autoslug.settings import slugify
import utils
__all__ = ['AutoSlugField']
SLUG_INDEX_SEPARATOR = '-' # the "-" in "foo-2"
class AutoSlugField(SlugField):
"""
AutoSlugField is an extended SlugField able to automatically resolve name
clashes.
AutoSlugField can also perform the following tasks on save:
- populate itself from another field (using `populate_from`),
- use custom `slugify` function (using `slugify` or :doc:`settings`), and
- preserve uniqueness of the value (using `unique` or `unique_with`).
None of the tasks is mandatory, i.e. you can have auto-populated non-unique
fields, manually entered unique ones (absolutely unique or within a given
date) or both.
Uniqueness is preserved by checking if the slug is unique with given constraints
(`unique_with`) or globally (`unique`) and adding a number to the slug to make
it unique.
:param always_update: boolean: if True, the slug is updated each time the
model instance is saved. Use with care because `cool URIs don't
change`_ (and the slug is usually a part of object's URI). Note that
even if the field is editable, any manual changes will be lost when
this option is activated.
:param populate_from: string or callable: if string is given, it is considered
as the name of attribute from which to fill the slug. If callable is given,
it should accept `instance` parameter and return a value to fill the slug
with.
:param sep: string: if defined, overrides default separator for automatically
incremented slug index (i.e. the "-" in "foo-2").
:param slugify: callable: if defined, overrides `AUTOSLUG_SLUGIFY_FUNCTION`
defined in :doc:`settings`.
:param unique: boolean: ensure total slug uniqueness (unless more precise
`unique_with` is defined).
:param unique_with: string or tuple of strings: name or names of attributes
to check for "partial uniqueness", i.e. there will not be two objects
with identical slugs if these objects share the same values of given
attributes. For instance, ``unique_with='pub_date'`` tells AutoSlugField
to enforce slug uniqueness of all items published on given date. The
slug, however, may reappear on another date. If more than one field is
given, e.g. ``unique_with=('pub_date', 'author')``, then the same slug may
reappear within a day or within some author's articles but never within
a day for the same author. Foreign keys are also supported, i.e. not only
`unique_with='author'` will do, but also `unique_with='author__name'`.
.. _cool URIs don't change: http://w3.org/Provider/Style/URI.html
.. note:: always place any slug attribute *after* attributes referenced
by it (i.e. those from which you wish to `populate_from` or check
`unique_with`). The reasoning is that autosaved dates and other such
fields must be already processed before using them in the AutoSlugField.
Example usage::
from django.db import models
from autoslug import AutoSlugField
class Article(models.Model):
'''An article with title, date and slug. The slug is not totally
unique but there will be no two articles with the same slug within
any month.
'''
title = models.CharField(max_length=200)
pub_date = models.DateField(auto_now_add=True)
slug = AutoSlugField(populate_from='title', unique_with='pub_date__month')
More options::
# slugify but allow non-unique slugs
slug = AutoSlugField()
# globally unique, silently fix on conflict ("foo" --> "foo-1".."foo-n")
slug = AutoSlugField(unique=True)
# autoslugify value from attribute named "title"; editable defaults to False
slug = AutoSlugField(populate_from='title')
# same as above but force editable=True
slug = AutoSlugField(populate_from='title', editable=True)
# ensure that slug is unique with given date (not globally)
slug = AutoSlugField(unique_with='pub_date')
# ensure that slug is unique with given date AND category
slug = AutoSlugField(unique_with=('pub_date','category'))
# ensure that slug in unique with an external object
# assuming that author=ForeignKey(Author)
slug = AutoSlugField(unique_with='author')
# ensure that slug in unique with a subset of external objects (by lookups)
# assuming that author=ForeignKey(Author)
slug = AutoSlugField(unique_with='author__name')
# mix above-mentioned behaviour bits
slug = AutoSlugField(populate_from='title', unique_with='pub_date')
# minimum date granularity is shifted from day to month
slug = AutoSlugField(populate_from='title', unique_with='pub_date__month')
# autoslugify value from a dynamic attribute (i.e. a method)
slug = AutoSlugField(populate_from='get_full_name')
# autoslugify value from a custom callable
# (ex. usage: user profile models)
slug = AutoSlugField(populate_from=lambda instance: instance.user.get_full_name())
# specify model manager for looking up slugs shared by subclasses
class Article(models.Model):
'''An article with title, date and slug. The slug is not totally
unique but there will be no two articles with the same slug within
any month.
'''
objects = models.Manager()
title = models.CharField(max_length=200)
slug = AutoSlugField(populate_from='title', unique_with='pub_date__month', manager=objects)
class NewsArticle(Article):
pass
# autoslugify value using custom `slugify` function
from autoslug.settings import slugify as default_slugify
def custom_slugify(value):
return default_slugify(value).replace('-', '_')
slug = AutoSlugField(slugify=custom_slugify)
"""
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 50)
# autopopulated slug is not editable unless told so
self.populate_from = kwargs.pop('populate_from', None)
if self.populate_from:
kwargs.setdefault('editable', False)
# unique_with value can be string or tuple
self.unique_with = kwargs.pop('unique_with', ())
if isinstance(self.unique_with, basestring):
self.unique_with = (self.unique_with,)
self.slugify = kwargs.pop('slugify', slugify)
assert hasattr(self.slugify, '__call__')
self.index_sep = kwargs.pop('sep', SLUG_INDEX_SEPARATOR)
# backward compatibility
if kwargs.get('unique_with_date'):
warn('Using unique_with_date="foo" in AutoSlugField is deprecated, '
'use unique_with=("foo",) instead.', DeprecationWarning)
self.unique_with += (kwargs['unique_with_date'],)
if self.unique_with:
# we will do "manual" granular check below
kwargs['unique'] = False
# Set db_index=True unless it's been set manually.
if 'db_index' not in kwargs:
kwargs['db_index'] = True
# When using model inheritence, set manager to search for matching
# slug values
self.manager = kwargs.pop('manager', None)
self.always_update = kwargs.pop('always_update', False)
super(SlugField, self).__init__(*args, **kwargs)
def pre_save(self, instance, add):
# get currently entered slug
value = self.value_from_object(instance)
manager = self.manager
# autopopulate
if self.always_update or (self.populate_from and not value):
value = utils.get_prepopulated_value(self, instance)
if __debug__ and not value:
print 'Failed to populate slug %s.%s from %s' % \
(instance._meta.object_name, self.name, self.populate_from)
slug = self.slugify(value)
if not slug:
# no incoming value, use model name
slug = instance._meta.module_name
assert slug, 'slug is defined before trying to ensure uniqueness'
slug = utils.crop_slug(self, slug)
# ensure the slug is unique (if required)
if self.unique or self.unique_with:
slug = utils.generate_unique_slug(self, instance, slug, manager)
assert slug, 'value is filled before saving'
# make the updated slug available as instance attribute
setattr(instance, self.name, slug)
return slug
def south_field_triple(self):
"Returns a suitable description of this field for South."
args, kwargs = introspector(self)
kwargs.update({
'populate_from': 'None' if callable(self.populate_from) else repr(self.populate_from),
'unique_with': repr(self.unique_with)
})
return ('autoslug.fields.AutoSlugField', args, kwargs)

Просмотреть файл

Просмотреть файл

@ -1,74 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2008—2012 Andy Mikhailenko
#
# This file is part of django-autoslug.
#
# django-autoslug is free software under terms of the GNU Lesser
# General Public License version 3 (LGPLv3) as published by the Free
# Software Foundation. See the file README for copying conditions.
#
"""
Django settings that affect django-autoslug:
`AUTOSLUG_SLUGIFY_FUNCTION`
Allows to define a custom slugifying function.
The function can be repsesented as string or callable, e.g.::
# custom function, path as string:
AUTOSLUG_SLUGIFY_FUNCTION = 'some_app.slugify_func'
# custom function, callable:
AUTOSLUG_SLUGIFY_FUNCTION = some_app.slugify_func
# custom function, defined inline:
AUTOSLUG_SLUGIFY_FUNCTION = lambda slug: 'can i haz %s?' % slug
If no value is given, default value is used.
Default value is one of these depending on availability in given order:
* `unidecode.unidecode()` if Unidecode_ is available;
* `pytils.translit.slugify()` if pytils_ is available;
* `django.template.defaultfilters.slugify()` bundled with Django.
django-autoslug also ships a couple of slugify functions that use
the translitcodec_ Python library, e.g.::
# using as many characters as needed to make a natural replacement
AUTOSLUG_SLUGIFY_FUNCTION = 'autoslug.utils.translit_long'
# using the minimum number of characters to make a replacement
AUTOSLUG_SLUGIFY_FUNCTION = 'autoslug.utils.translit_short'
# only performing single character replacements
AUTOSLUG_SLUGIFY_FUNCTION = 'autoslug.utils.translit_one'
.. _Unidecode: http://pypi.python.org/pypi/Unidecode
.. _pytils: http://pypi.python.org/pypi/pytils
.. _translitcodec: http://pypi.python.org/pypi/translitcodec
"""
from django.conf import settings
# use custom slugifying function if any
slugify = getattr(settings, 'AUTOSLUG_SLUGIFY_FUNCTION', None)
if not slugify:
try:
# i18n-friendly approach
from unidecode import unidecode
slugify = lambda s: unidecode(s).replace(' ', '-')
except ImportError:
try:
# Cyrillic transliteration (primarily Russian)
from pytils.translit import slugify
except ImportError:
# fall back to Django's default method
slugify = 'django.template.defaultfilters.slugify'
# find callable by string
if isinstance(slugify, str):
from django.core.urlresolvers import get_callable
slugify = get_callable(slugify)

Просмотреть файл

@ -1,349 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2008—2012 Andy Mikhailenko
#
# This file is part of django-autoslug.
#
# django-autoslug is free software under terms of the GNU Lesser
# General Public License version 3 (LGPLv3) as published by the Free
# Software Foundation. See the file README for copying conditions.
#
# python
import datetime
# django
from django.db.models import Model, CharField, DateField, ForeignKey, Manager
# this app
from autoslug.settings import slugify as default_slugify
from autoslug import AutoSlugField
class SimpleModel(Model):
"""
>>> a = SimpleModel(name='test')
>>> a.save()
>>> a.slug
'simplemodel'
"""
name = CharField(max_length=200)
slug = AutoSlugField()
class ModelWithUniqueSlug(Model):
"""
>>> greeting = 'Hello world!'
>>> a = ModelWithUniqueSlug(name=greeting)
>>> a.save()
>>> a.slug
u'hello-world'
>>> b = ModelWithUniqueSlug(name=greeting)
>>> b.save()
>>> b.slug
u'hello-world-2'
"""
name = CharField(max_length=200)
slug = AutoSlugField(populate_from='name', unique=True)
class ModelWithUniqueSlugFK(Model):
"""
>>> sm1 = SimpleModel.objects.create(name='test')
>>> sm2 = SimpleModel.objects.create(name='test')
>>> sm3 = SimpleModel.objects.create(name='test2')
>>> greeting = 'Hello world!'
>>> a = ModelWithUniqueSlugFK.objects.create(name=greeting, simple_model=sm1)
>>> a.slug
u'hello-world'
>>> b = ModelWithUniqueSlugFK.objects.create(name=greeting, simple_model=sm2)
>>> b.slug
u'hello-world-2'
>>> c = ModelWithUniqueSlugFK.objects.create(name=greeting, simple_model=sm3)
>>> c.slug
u'hello-world'
>>> d = ModelWithUniqueSlugFK.objects.create(name=greeting, simple_model=sm1)
>>> d.slug
u'hello-world-3'
>>> sm3.name = 'test'
>>> sm3.save()
>>> c.slug
u'hello-world'
>>> c.save()
>>> c.slug
u'hello-world-4'
"""
name = CharField(max_length=200)
simple_model = ForeignKey(SimpleModel)
slug = AutoSlugField(populate_from='name', unique_with='simple_model__name')
class ModelWithUniqueSlugDate(Model):
"""
>>> a = ModelWithUniqueSlugDate(slug='test', date=datetime.date(2009,9,9))
>>> b = ModelWithUniqueSlugDate(slug='test', date=datetime.date(2009,9,9))
>>> c = ModelWithUniqueSlugDate(slug='test', date=datetime.date(2009,9,10))
>>> for m in a,b,c:
... m.save()
>>> a.slug
u'test'
>>> b.slug
u'test-2'
>>> c.slug
u'test'
"""
date = DateField()
slug = AutoSlugField(unique_with='date')
class ModelWithUniqueSlugDay(Model): # same as ...Date, just more explicit
"""
>>> a = ModelWithUniqueSlugDay(slug='test', date=datetime.date(2009, 9, 9))
>>> b = ModelWithUniqueSlugDay(slug='test', date=datetime.date(2009, 9, 9))
>>> c = ModelWithUniqueSlugDay(slug='test', date=datetime.date(2009, 9, 10))
>>> for m in a,b,c:
... m.save()
>>> a.slug
u'test'
>>> b.slug
u'test-2'
>>> c.slug
u'test'
"""
date = DateField()
slug = AutoSlugField(unique_with='date__day')
class ModelWithUniqueSlugMonth(Model):
"""
>>> a = ModelWithUniqueSlugMonth(slug='test', date=datetime.date(2009, 9, 9))
>>> b = ModelWithUniqueSlugMonth(slug='test', date=datetime.date(2009, 9, 10))
>>> c = ModelWithUniqueSlugMonth(slug='test', date=datetime.date(2009, 10, 9))
>>> for m in a,b,c:
... m.save()
>>> a.slug
u'test'
>>> b.slug
u'test-2'
>>> c.slug
u'test'
"""
date = DateField()
slug = AutoSlugField(unique_with='date__month')
class ModelWithUniqueSlugYear(Model):
"""
>>> a = ModelWithUniqueSlugYear(slug='test', date=datetime.date(2009, 9, 9))
>>> b = ModelWithUniqueSlugYear(slug='test', date=datetime.date(2009, 10, 9))
>>> c = ModelWithUniqueSlugYear(slug='test', date=datetime.date(2010, 9, 9))
>>> for m in a,b,c:
... m.save()
>>> a.slug
u'test'
>>> b.slug
u'test-2'
>>> c.slug
u'test'
"""
date = DateField()
slug = AutoSlugField(unique_with='date__year')
class ModelWithLongName(Model):
"""
>>> long_name = 'x' * 250
>>> a = ModelWithLongName(name=long_name)
>>> a.save()
>>> len(a.slug) # original slug is cropped by field length
50
"""
name = CharField(max_length=200)
slug = AutoSlugField(populate_from='name')
class ModelWithLongNameUnique(Model):
"""
>>> long_name = 'x' * 250
>>> a = ModelWithLongNameUnique(name=long_name)
>>> a.save()
>>> len(a.slug) # original slug is cropped by field length
50
>>> b = ModelWithLongNameUnique(name=long_name)
>>> b.save()
>>> b.slug[-3:] # uniqueness is forced
u'x-2'
>>> len(b.slug) # slug is cropped
50
"""
name = CharField(max_length=200)
slug = AutoSlugField(populate_from='name', unique=True)
class ModelWithCallable(Model):
"""
>>> a = ModelWithCallable.objects.create(name='larch')
>>> a.slug
u'the-larch'
"""
name = CharField(max_length=200)
slug = AutoSlugField(populate_from=lambda instance: u'the %s' % instance.name)
class ModelWithCallableAttr(Model):
"""
>>> a = ModelWithCallableAttr.objects.create(name='albatross')
>>> a.slug
u'spam-albatross-and-spam'
"""
name = CharField(max_length=200)
slug = AutoSlugField(populate_from='get_name')
def get_name(self):
return u'spam, %s and spam' % self.name
class ModelWithCustomPrimaryKey(Model):
"""
# just check if models are created without exceptions
>>> a = ModelWithCustomPrimaryKey.objects.create(custom_primary_key='a',
... name='name used in slug')
>>> b = ModelWithCustomPrimaryKey.objects.create(custom_primary_key='b',
... name='name used in slug')
>>> a.slug
u'name-used-in-slug'
"""
custom_primary_key = CharField(primary_key=True, max_length=1)
name = CharField(max_length=200)
slug = AutoSlugField(populate_from='name', unique=True)
custom_slugify = lambda value: default_slugify(value).replace('-', '_')
class ModelWithCustomSlugifier(Model):
"""
>>> a = ModelWithCustomSlugifier.objects.create(slug='hello world!')
>>> b = ModelWithCustomSlugifier.objects.create(slug='hello world!')
>>> b.slug
u'hello_world-2'
"""
slug = AutoSlugField(unique=True, slugify=custom_slugify)
class ModelWithCustomSeparator(Model):
"""
>>> a = ModelWithCustomSeparator.objects.create(slug='hello world!')
>>> b = ModelWithCustomSeparator.objects.create(slug='hello world!')
>>> b.slug
u'hello-world_2'
"""
slug = AutoSlugField(unique=True, sep='_')
class ModelWithReferenceToItself(Model):
"""
>>> a = ModelWithReferenceToItself(slug='test')
>>> a.save()
Traceback (most recent call last):
...
ValueError: Attribute ModelWithReferenceToItself.slug references itself \
in `unique_with`. Please use "unique=True" for this case.
"""
slug = AutoSlugField(unique_with='slug')
class ModelWithWrongReferencedField(Model):
"""
>>> a = ModelWithWrongReferencedField(slug='test')
>>> a.save()
Traceback (most recent call last):
...
ValueError: Could not find attribute ModelWithWrongReferencedField.wrong_field \
referenced by ModelWithWrongReferencedField.slug (see constraint `unique_with`)
"""
slug = AutoSlugField(unique_with='wrong_field')
class ModelWithWrongLookupInUniqueWith(Model):
"""
>>> a = ModelWithWrongLookupInUniqueWith(name='test', slug='test')
>>> a.save()
Traceback (most recent call last):
...
ValueError: Could not resolve lookup "name__foo" in `unique_with` of \
ModelWithWrongLookupInUniqueWith.slug
"""
slug = AutoSlugField(unique_with='name__foo')
name = CharField(max_length=10)
class ModelWithWrongFieldOrder(Model):
"""
>>> a = ModelWithWrongFieldOrder(slug='test')
>>> a.save()
Traceback (most recent call last):
...
ValueError: Could not check uniqueness of ModelWithWrongFieldOrder.slug with \
respect to ModelWithWrongFieldOrder.date because the latter is empty. Please \
ensure that "slug" is declared *after* all fields listed in unique_with.
"""
slug = AutoSlugField(unique_with='date')
date = DateField(blank=False, null=False)
class ModelWithAcceptableEmptyDependency(Model):
"""
>>> model = ModelWithAcceptableEmptyDependency
>>> instances = [model.objects.create(slug='hello') for x in range(0,2)]
>>> [x.slug for x in model.objects.all()]
[u'hello', u'hello-2']
"""
date = DateField(blank=True, null=True)
slug = AutoSlugField(unique_with='date')
class ModelWithAutoUpdateEnabled(Model):
"""
>>> a = ModelWithAutoUpdateEnabled(name='My name')
>>> a.save()
>>> a.slug
u'my-name'
>>> a.name = 'My new name'
>>> a.save()
>>> a.slug
u'my-new-name'
"""
name = CharField(max_length=200)
slug = AutoSlugField(populate_from='name', always_update=True)
class ModelWithSlugSpaceSharedIntegrityError(ModelWithUniqueSlug):
"""
>>> a = ModelWithUniqueSlug(name='My name')
>>> a.save()
>>> b = ModelWithSlugSpaceSharedIntegrityError(name='My name')
>>> b.save()
Traceback (most recent call last):
...
IntegrityError: column slug is not unique
"""
class SharedSlugSpace(Model):
objects = Manager()
name = CharField(max_length=200)
# ensure that any subclasses use the base model's manager for testing
# slug uniqueness
slug = AutoSlugField(populate_from='name', unique=True, manager=objects)
class ModelWithSlugSpaceShared(SharedSlugSpace):
"""
>>> a = SharedSlugSpace(name='My name')
>>> a.save()
>>> a.slug
u'my-name'
>>> b = ModelWithSlugSpaceShared(name='My name')
>>> b.save()
>>> b.slug
u'my-name-2'
"""

Просмотреть файл

@ -1,176 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2008—2012 Andy Mikhailenko
#
# This file is part of django-autoslug.
#
# django-autoslug is free software under terms of the GNU Lesser
# General Public License version 3 (LGPLv3) as published by the Free
# Software Foundation. See the file README for copying conditions.
#
# django
from django.core.exceptions import ImproperlyConfigured
from django.db.models.fields import FieldDoesNotExist, DateField
def get_prepopulated_value(field, instance):
"""
Returns preliminary value based on `populate_from`.
"""
if hasattr(field.populate_from, '__call__'):
# AutoSlugField(populate_from=lambda instance: ...)
return field.populate_from(instance)
else:
# AutoSlugField(populate_from='foo')
attr = getattr(instance, field.populate_from)
return callable(attr) and attr() or attr
def generate_unique_slug(field, instance, slug, manager):
"""
Generates unique slug by adding a number to given value until no model
instance can be found with such slug. If ``unique_with`` (a tuple of field
names) was specified for the field, all these fields are included together
in the query when looking for a "rival" model instance.
"""
original_slug = slug = crop_slug(field, slug)
default_lookups = tuple(get_uniqueness_lookups(field, instance, field.unique_with))
index = 1
if not manager:
manager = type(instance).objects
# keep changing the slug until it is unique
while True:
# find instances with same slug
lookups = dict(default_lookups, **{field.name: slug})
rivals = manager.filter(**lookups).exclude(pk=instance.pk)
if not rivals:
# the slug is unique, no model uses it
return slug
# the slug is not unique; change once more
index += 1
# ensure the resulting string is not too long
tail_length = len(field.index_sep) + len(str(index))
combined_length = len(original_slug) + tail_length
if field.max_length < combined_length:
original_slug = original_slug[:field.max_length - tail_length]
# re-generate the slug
data = dict(slug=original_slug, sep=field.index_sep, index=index)
slug = '%(slug)s%(sep)s%(index)d' % data
# ...next iteration...
def get_uniqueness_lookups(field, instance, unique_with):
"""
Returns a dict'able tuple of lookups to ensure uniqueness of a slug.
"""
for original_lookup_name in unique_with:
if '__' in original_lookup_name:
field_name, inner_lookup = original_lookup_name.split('__', 1)
else:
field_name, inner_lookup = original_lookup_name, None
try:
other_field = instance._meta.get_field(field_name)
except FieldDoesNotExist:
raise ValueError('Could not find attribute %s.%s referenced'
' by %s.%s (see constraint `unique_with`)'
% (instance._meta.object_name, field_name,
instance._meta.object_name, field.name))
if field == other_field:
raise ValueError('Attribute %s.%s references itself in `unique_with`.'
' Please use "unique=True" for this case.'
% (instance._meta.object_name, field_name))
value = getattr(instance, field_name)
if not value:
if other_field.blank:
break
raise ValueError('Could not check uniqueness of %s.%s with'
' respect to %s.%s because the latter is empty.'
' Please ensure that "%s" is declared *after*'
' all fields listed in unique_with.'
% (instance._meta.object_name, field.name,
instance._meta.object_name, field_name,
field.name))
if isinstance(other_field, DateField): # DateTimeField is a DateField subclass
inner_lookup = inner_lookup or 'day'
if '__' in inner_lookup:
raise ValueError('The `unique_with` constraint in %s.%s'
' is set to "%s", but AutoSlugField only'
' accepts one level of nesting for dates'
' (e.g. "date__month").'
% (instance._meta.object_name, field.name,
original_lookup_name))
parts = ['year', 'month', 'day']
try:
granularity = parts.index(inner_lookup) + 1
except ValueError:
raise ValueError('expected one of %s, got "%s" in "%s"'
% (parts, inner_lookup, original_lookup_name))
else:
for part in parts[:granularity]:
lookup = '%s__%s' % (field_name, part)
yield lookup, getattr(value, part)
else:
# TODO: this part should be documented as it involves recursion
if inner_lookup:
if not hasattr(value, '_meta'):
raise ValueError('Could not resolve lookup "%s" in `unique_with` of %s.%s'
% (original_lookup_name, instance._meta.object_name, field.name))
for inner_name, inner_value in get_uniqueness_lookups(field, value, [inner_lookup]):
yield original_lookup_name, inner_value
else:
yield field_name, value
def crop_slug(field, slug):
if field.max_length < len(slug):
return slug[:field.max_length]
return slug
try:
import translitcodec
except ImportError:
pass
else:
import re
PUNCT_RE = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
def translitcodec_slugify(codec):
def _slugify(value, delim=u'-', encoding=''):
"""
Generates an ASCII-only slug.
Borrowed from http://flask.pocoo.org/snippets/5/
"""
if encoding:
encoder = "%s/%s" % (codec, encoding)
else:
encoder = codec
result = []
for word in PUNCT_RE.split(value.lower()):
word = word.encode(encoder)
if word:
result.append(word)
return unicode(delim.join(result))
return _slugify
translit_long = translitcodec_slugify("translit/long")
translit_short = translitcodec_slugify("translit/short")
translit_one = translitcodec_slugify("translit/one")

Просмотреть файл

@ -1,339 +0,0 @@
Metadata-Version: 1.0
Name: celery
Version: 2.4.0
Summary: Distributed Task Queue
Home-page: http://celeryproject.org
Author: Ask Solem
Author-email: ask@celeryproject.org
License: BSD
Description: =================================
celery - Distributed Task Queue
=================================
.. image:: http://cloud.github.com/downloads/ask/celery/celery_128.png
:Version: 2.4.0
:Web: http://celeryproject.org/
:Download: http://pypi.python.org/pypi/celery/
:Source: http://github.com/ask/celery/
:Keywords: task queue, job queue, asynchronous, rabbitmq, amqp, redis,
python, webhooks, queue, distributed
--
.. _celery-synopsis:
Celery is an open source asynchronous task queue/job queue based on
distributed message passing. It is focused on real-time operation,
but supports scheduling as well.
The execution units, called tasks, are executed concurrently on one or
more worker nodes using multiprocessing, `Eventlet`_ or `gevent`_. Tasks can
execute asynchronously (in the background) or synchronously
(wait until ready).
Celery is used in production systems to process millions of tasks a day.
Celery is written in Python, but the protocol can be implemented in any
language. It can also `operate with other languages using webhooks`_.
The recommended message broker is `RabbitMQ`_, but `limited support`_ for
`Redis`_, `Beanstalk`_, `MongoDB`_, `CouchDB`_ and
databases (using `SQLAlchemy`_ or the `Django ORM`_) is also available.
Celery is easy to integrate with `Django`_, `Pylons`_ and `Flask`_, using
the `django-celery`_, `celery-pylons`_ and `Flask-Celery`_ add-on packages.
.. _`RabbitMQ`: http://www.rabbitmq.com/
.. _`Redis`: http://code.google.com/p/redis/
.. _`SQLAlchemy`: http://www.sqlalchemy.org/
.. _`Django`: http://djangoproject.com/
.. _`Django ORM`: http://djangoproject.com/
.. _`Eventlet`: http://eventlet.net/
.. _`gevent`: http://gevent.org/
.. _`Beanstalk`: http://kr.github.com/beanstalkd/
.. _`MongoDB`: http://mongodb.org/
.. _`CouchDB`: http://couchdb.apache.org/
.. _`Pylons`: http://pylonshq.com/
.. _`Flask`: http://flask.pocoo.org/
.. _`django-celery`: http://pypi.python.org/pypi/django-celery
.. _`celery-pylons`: http://pypi.python.org/pypi/celery-pylons
.. _`Flask-Celery`: http://github.com/ask/flask-celery/
.. _`operate with other languages using webhooks`:
http://ask.github.com/celery/userguide/remote-tasks.html
.. _`limited support`:
http://kombu.readthedocs.org/en/latest/introduction.html#transport-comparison
.. contents::
:local:
.. _celery-overview:
Overview
========
This is a high level overview of the architecture.
.. image:: http://cloud.github.com/downloads/ask/celery/Celery-Overview-v4.jpg
The broker delivers tasks to the worker nodes.
A worker node is a networked machine running `celeryd`. This can be one or
more machines depending on the workload.
The result of the task can be stored for later retrieval (called its
"tombstone").
.. _celery-example:
Example
=======
You probably want to see some code by now, so here's an example task
adding two numbers:
::
from celery.task import task
@task
def add(x, y):
return x + y
You can execute the task in the background, or wait for it to finish::
>>> result = add.delay(4, 4)
>>> result.wait() # wait for and return the result
8
Simple!
.. _celery-features:
Features
========
+-----------------+----------------------------------------------------+
| Messaging | Supported brokers include `RabbitMQ`_, `Redis`_, |
| | `Beanstalk`_, `MongoDB`_, `CouchDB`_, and popular |
| | SQL databases. |
+-----------------+----------------------------------------------------+
| Fault-tolerant | Excellent configurable error recovery when using |
| | `RabbitMQ`, ensures your tasks are never lost. |
| | scenarios, and your tasks will never be lost. |
+-----------------+----------------------------------------------------+
| Distributed | Runs on one or more machines. Supports |
| | broker `clustering`_ and `HA`_ when used in |
| | combination with `RabbitMQ`_. You can set up new |
| | workers without central configuration (e.g. use |
| | your grandma's laptop to help if the queue is |
| | temporarily congested). |
+-----------------+----------------------------------------------------+
| Concurrency | Concurrency is achieved by using multiprocessing, |
| | `Eventlet`_, `gevent` or a mix of these. |
+-----------------+----------------------------------------------------+
| Scheduling | Supports recurring tasks like cron, or specifying |
| | an exact date or countdown for when after the task |
| | should be executed. |
+-----------------+----------------------------------------------------+
| Latency | Low latency means you are able to execute tasks |
| | *while the user is waiting*. |
+-----------------+----------------------------------------------------+
| Return Values | Task return values can be saved to the selected |
| | result store backend. You can wait for the result, |
| | retrieve it later, or ignore it. |
+-----------------+----------------------------------------------------+
| Result Stores | Database, `MongoDB`_, `Redis`_, `Tokyo Tyrant`, |
| | `Cassandra`, or `AMQP`_ (message notification). |
+-----------------+----------------------------------------------------+
| Webhooks | Your tasks can also be HTTP callbacks, enabling |
| | cross-language communication. |
+-----------------+----------------------------------------------------+
| Rate limiting | Supports rate limiting by using the token bucket |
| | algorithm, which accounts for bursts of traffic. |
| | Rate limits can be set for each task type, or |
| | globally for all. |
+-----------------+----------------------------------------------------+
| Routing | Using AMQP's flexible routing model you can route |
| | tasks to different workers, or select different |
| | message topologies, by configuration or even at |
| | runtime. |
+-----------------+----------------------------------------------------+
| Remote-control | Worker nodes can be controlled from remote by |
| | using broadcast messaging. A range of built-in |
| | commands exist in addition to the ability to |
| | easily define your own. (AMQP/Redis only) |
+-----------------+----------------------------------------------------+
| Monitoring | You can capture everything happening with the |
| | workers in real-time by subscribing to events. |
| | A real-time web monitor is in development. |
+-----------------+----------------------------------------------------+
| Serialization | Supports Pickle, JSON, YAML, or easily defined |
| | custom schemes. One task invocation can have a |
| | different scheme than another. |
+-----------------+----------------------------------------------------+
| Tracebacks | Errors and tracebacks are stored and can be |
| | investigated after the fact. |
+-----------------+----------------------------------------------------+
| UUID | Every task has an UUID (Universally Unique |
| | Identifier), which is the task id used to query |
| | task status and return value. |
+-----------------+----------------------------------------------------+
| Retries | Tasks can be retried if they fail, with |
| | configurable maximum number of retries, and delays |
| | between each retry. |
+-----------------+----------------------------------------------------+
| Task Sets | A Task set is a task consisting of several |
| | sub-tasks. You can find out how many, or if all |
| | of the sub-tasks has been executed, and even |
| | retrieve the results in order. Progress bars, |
| | anyone? |
+-----------------+----------------------------------------------------+
| Made for Web | You can query status and results via URLs, |
| | enabling the ability to poll task status using |
| | Ajax. |
+-----------------+----------------------------------------------------+
| Error Emails | Can be configured to send emails to the |
| | administrators when tasks fails. |
+-----------------+----------------------------------------------------+
.. _`clustering`: http://www.rabbitmq.com/clustering.html
.. _`HA`: http://www.rabbitmq.com/pacemaker.html
.. _`AMQP`: http://www.amqp.org/
.. _`Stomp`: http://stomp.codehaus.org/
.. _`Tokyo Tyrant`: http://tokyocabinet.sourceforge.net/
.. _celery-documentation:
Documentation
=============
The `latest documentation`_ with user guides, tutorials and API reference
is hosted at Github.
.. _`latest documentation`: http://ask.github.com/celery/
.. _celery-installation:
Installation
============
You can install Celery either via the Python Package Index (PyPI)
or from source.
To install using `pip`,::
$ pip install Celery
To install using `easy_install`,::
$ easy_install Celery
.. _celery-installing-from-source:
Downloading and installing from source
--------------------------------------
Download the latest version of Celery from
http://pypi.python.org/pypi/celery/
You can install it by doing the following,::
$ tar xvfz celery-0.0.0.tar.gz
$ cd celery-0.0.0
$ python setup.py build
# python setup.py install # as root
.. _celery-installing-from-git:
Using the development version
-----------------------------
You can clone the repository by doing the following::
$ git clone git://github.com/ask/celery.git
.. _getting-help:
Getting Help
============
.. _mailing-list:
Mailing list
------------
For discussions about the usage, development, and future of celery,
please join the `celery-users`_ mailing list.
.. _`celery-users`: http://groups.google.com/group/celery-users/
.. _irc-channel:
IRC
---
Come chat with us on IRC. The `#celery`_ channel is located at the `Freenode`_
network.
.. _`#celery`: irc://irc.freenode.net/celery
.. _`Freenode`: http://freenode.net
.. _bug-tracker:
Bug tracker
===========
If you have any suggestions, bug reports or annoyances please report them
to our issue tracker at http://github.com/ask/celery/issues/
.. _wiki:
Wiki
====
http://wiki.github.com/ask/celery/
.. _contributing-short:
Contributing
============
Development of `celery` happens at Github: http://github.com/ask/celery
You are highly encouraged to participate in the development
of `celery`. If you don't like Github (for some reason) you're welcome
to send regular patches.
Be sure to also read the `Contributing to Celery`_ section in the
documentation.
.. _`Contributing to Celery`: http://ask.github.com/celery/contributing.html
.. _license:
License
=======
This software is licensed under the `New BSD License`. See the ``LICENSE``
file in the top distribution directory for the full license text.
.. # vim: syntax=rst expandtab tabstop=4 shiftwidth=4 shiftround
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Operating System :: OS Independent
Classifier: Environment :: No Input/Output (Daemon)
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: POSIX
Classifier: Topic :: Communications
Classifier: Topic :: System :: Distributed Computing
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3

Просмотреть файл

@ -1,414 +0,0 @@
AUTHORS
Changelog
FAQ
INSTALL
LICENSE
MANIFEST.in
README
README.rst
THANKS
TODO
setup.cfg
setup.py
celery/__init__.py
celery/beat.py
celery/conf.py
celery/datastructures.py
celery/decorators.py
celery/exceptions.py
celery/local.py
celery/log.py
celery/messaging.py
celery/platforms.py
celery/registry.py
celery/result.py
celery/routes.py
celery/schedules.py
celery/signals.py
celery/states.py
celery.egg-info/PKG-INFO
celery.egg-info/SOURCES.txt
celery.egg-info/dependency_links.txt
celery.egg-info/entry_points.txt
celery.egg-info/not-zip-safe
celery.egg-info/requires.txt
celery.egg-info/top_level.txt
celery/app/__init__.py
celery/app/amqp.py
celery/app/base.py
celery/app/defaults.py
celery/app/task/__init__.py
celery/apps/__init__.py
celery/apps/beat.py
celery/apps/worker.py
celery/backends/__init__.py
celery/backends/amqp.py
celery/backends/base.py
celery/backends/cache.py
celery/backends/cassandra.py
celery/backends/database.py
celery/backends/mongodb.py
celery/backends/pyredis.py
celery/backends/redis.py
celery/backends/tyrant.py
celery/bin/__init__.py
celery/bin/base.py
celery/bin/camqadm.py
celery/bin/celerybeat.py
celery/bin/celeryctl.py
celery/bin/celeryd.py
celery/bin/celeryd_detach.py
celery/bin/celeryd_multi.py
celery/bin/celeryev.py
celery/concurrency/__init__.py
celery/concurrency/base.py
celery/concurrency/eventlet.py
celery/concurrency/gevent.py
celery/concurrency/solo.py
celery/concurrency/threads.py
celery/concurrency/processes/__init__.py
celery/concurrency/processes/_win.py
celery/concurrency/processes/pool.py
celery/contrib/__init__.py
celery/contrib/abortable.py
celery/contrib/batches.py
celery/contrib/rdb.py
celery/db/__init__.py
celery/db/a805d4bd.py
celery/db/dfd042c7.py
celery/db/models.py
celery/db/session.py
celery/events/__init__.py
celery/events/cursesmon.py
celery/events/dumper.py
celery/events/snapshot.py
celery/events/state.py
celery/execute/__init__.py
celery/execute/trace.py
celery/loaders/__init__.py
celery/loaders/app.py
celery/loaders/base.py
celery/loaders/default.py
celery/task/__init__.py
celery/task/base.py
celery/task/chords.py
celery/task/control.py
celery/task/http.py
celery/task/schedules.py
celery/task/sets.py
celery/tests/__init__.py
celery/tests/compat.py
celery/tests/config.py
celery/tests/utils.py
celery/tests/functional/__init__.py
celery/tests/functional/case.py
celery/tests/functional/tasks.py
celery/tests/test_app/__init__.py
celery/tests/test_app/test_app_amqp.py
celery/tests/test_app/test_app_defaults.py
celery/tests/test_app/test_beat.py
celery/tests/test_app/test_celery.py
celery/tests/test_app/test_loaders.py
celery/tests/test_app/test_log.py
celery/tests/test_app/test_routes.py
celery/tests/test_backends/__init__.py
celery/tests/test_backends/test_amqp.py
celery/tests/test_backends/test_base.py
celery/tests/test_backends/test_cache.py
celery/tests/test_backends/test_database.py
celery/tests/test_backends/test_pyredis_compat.py
celery/tests/test_backends/test_redis.py
celery/tests/test_backends/test_redis_unit.py
celery/tests/test_backends/test_tyrant.py
celery/tests/test_bin/__init__.py
celery/tests/test_bin/test_celerybeat.py
celery/tests/test_bin/test_celeryd.py
celery/tests/test_bin/test_celeryev.py
celery/tests/test_compat/__init__.py
celery/tests/test_compat/test_decorators.py
celery/tests/test_compat/test_messaging.py
celery/tests/test_concurrency/__init__.py
celery/tests/test_concurrency/test_concurrency_eventlet.py
celery/tests/test_concurrency/test_concurrency_processes.py
celery/tests/test_concurrency/test_concurrency_solo.py
celery/tests/test_concurrency/test_pool.py
celery/tests/test_events/__init__.py
celery/tests/test_events/test_events_cursesmon.py
celery/tests/test_events/test_events_snapshot.py
celery/tests/test_events/test_events_state.py
celery/tests/test_slow/__init__.py
celery/tests/test_slow/test_buckets.py
celery/tests/test_task/__init__.py
celery/tests/test_task/test_chord.py
celery/tests/test_task/test_context.py
celery/tests/test_task/test_execute_trace.py
celery/tests/test_task/test_registry.py
celery/tests/test_task/test_result.py
celery/tests/test_task/test_states.py
celery/tests/test_task/test_task_abortable.py
celery/tests/test_task/test_task_builtins.py
celery/tests/test_task/test_task_control.py
celery/tests/test_task/test_task_http.py
celery/tests/test_task/test_task_sets.py
celery/tests/test_utils/__init__.py
celery/tests/test_utils/test_datastructures.py
celery/tests/test_utils/test_pickle.py
celery/tests/test_utils/test_serialization.py
celery/tests/test_utils/test_timer2.py
celery/tests/test_utils/test_utils_encoding.py
celery/tests/test_utils/test_utils_info.py
celery/tests/test_utils/test_utils_timeutils.py
celery/tests/test_worker/__init__.py
celery/tests/test_worker/test_worker_autoscale.py
celery/tests/test_worker/test_worker_control.py
celery/tests/test_worker/test_worker_heartbeat.py
celery/tests/test_worker/test_worker_job.py
celery/tests/test_worker/test_worker_mediator.py
celery/tests/test_worker/test_worker_revoke.py
celery/tests/test_worker/test_worker_state.py
celery/utils/__init__.py
celery/utils/compat.py
celery/utils/encoding.py
celery/utils/functional.py
celery/utils/mail.py
celery/utils/patch.py
celery/utils/serialization.py
celery/utils/term.py
celery/utils/timer2.py
celery/utils/timeutils.py
celery/utils/dispatch/__init__.py
celery/utils/dispatch/saferef.py
celery/utils/dispatch/signal.py
celery/worker/__init__.py
celery/worker/autoscale.py
celery/worker/buckets.py
celery/worker/consumer.py
celery/worker/heartbeat.py
celery/worker/job.py
celery/worker/mediator.py
celery/worker/state.py
celery/worker/control/__init__.py
celery/worker/control/builtins.py
celery/worker/control/registry.py
contrib/centos/celeryd.init
contrib/centos/celeryd.sysconfig
contrib/debian/README.rst
contrib/debian/init.d-deprecated/celerybeat
contrib/debian/init.d-deprecated/celeryd
contrib/debian/init.d-deprecated/celeryevcam
contrib/generic-init.d/celerybeat
contrib/generic-init.d/celeryd
contrib/generic-init.d/celeryevcam
contrib/logtools/find-unprocessed-tasks-debug.sh
contrib/logtools/find-unprocessed-tasks.sh
contrib/logtools/periodic-task-runtimes.sh
contrib/mac/org.celeryq.celerybeat.plist
contrib/mac/org.celeryq.celeryd.plist
contrib/mac/org.celeryq.celerymon.plist
contrib/mac/watch-workers.applescript
contrib/release/core-modules.txt
contrib/release/doc4allmods
contrib/release/flakeplus.py
contrib/release/py3k-run-tests
contrib/release/removepyc.sh
contrib/release/sphinx-to-rst.py
contrib/release/verify-reference-index.sh
contrib/release/verify_config_reference.py
contrib/supervisord/celerybeat.conf
contrib/supervisord/celeryd.conf
contrib/supervisord/supervisord.conf
docs/Makefile
docs/changelog.rst
docs/community.rst
docs/conf.py
docs/configuration.rst
docs/contributing.rst
docs/faq.rst
docs/index.rst
docs/.static/.keep
docs/.templates/page.html
docs/.templates/sidebarintro.html
docs/.templates/sidebarlogo.html
docs/_ext/applyxrefs.py
docs/_ext/celerydocs.py
docs/_ext/literals_to_xrefs.py
docs/_theme/celery/theme.conf
docs/_theme/celery/static/celery.css_t
docs/cookbook/daemonizing.rst
docs/cookbook/index.rst
docs/cookbook/tasks.rst
docs/getting-started/broker-installation.rst
docs/getting-started/first-steps-with-celery.rst
docs/getting-started/index.rst
docs/getting-started/introduction.rst
docs/getting-started/resources.rst
docs/images/Celery-Overview-v4.jpg
docs/images/Celery1.0-inside-worker.jpg
docs/images/celery-broker-worker-nodes.jpg
docs/images/celery-broker-worker-relationship.jpg
docs/images/celery-icon-128.png
docs/images/celery-icon-32.png
docs/images/celery-icon-64.png
docs/images/celery-worker-bindings.jpg
docs/images/celery_128.png
docs/images/celery_512.png
docs/images/celery_favicon_128.png
docs/images/celeryevshotsm.jpg
docs/images/djangoceleryadmin2.jpg
docs/images/favicon.ico
docs/images/favicon.png
docs/includes/installation.txt
docs/includes/introduction.txt
docs/includes/resources.txt
docs/internals/app-overview.rst
docs/internals/deprecation.rst
docs/internals/index.rst
docs/internals/protocol.rst
docs/internals/worker.rst
docs/internals/reference/celery.backends.amqp.rst
docs/internals/reference/celery.backends.base.rst
docs/internals/reference/celery.backends.cache.rst
docs/internals/reference/celery.backends.cassandra.rst
docs/internals/reference/celery.backends.database.rst
docs/internals/reference/celery.backends.mongodb.rst
docs/internals/reference/celery.backends.redis.rst
docs/internals/reference/celery.backends.rst
docs/internals/reference/celery.backends.tyrant.rst
docs/internals/reference/celery.beat.rst
docs/internals/reference/celery.concurrency.base.rst
docs/internals/reference/celery.concurrency.eventlet.rst
docs/internals/reference/celery.concurrency.gevent.rst
docs/internals/reference/celery.concurrency.processes.pool.rst
docs/internals/reference/celery.concurrency.processes.rst
docs/internals/reference/celery.concurrency.rst
docs/internals/reference/celery.concurrency.solo.rst
docs/internals/reference/celery.concurrency.threads.rst
docs/internals/reference/celery.datastructures.rst
docs/internals/reference/celery.db.models.rst
docs/internals/reference/celery.db.session.rst
docs/internals/reference/celery.events.cursesmon.rst
docs/internals/reference/celery.events.dumper.rst
docs/internals/reference/celery.events.snapshot.rst
docs/internals/reference/celery.execute.trace.rst
docs/internals/reference/celery.log.rst
docs/internals/reference/celery.platforms.rst
docs/internals/reference/celery.routes.rst
docs/internals/reference/celery.utils.compat.rst
docs/internals/reference/celery.utils.dispatch.rst
docs/internals/reference/celery.utils.dispatch.saferef.rst
docs/internals/reference/celery.utils.dispatch.signal.rst
docs/internals/reference/celery.utils.encoding.rst
docs/internals/reference/celery.utils.functional.rst
docs/internals/reference/celery.utils.patch.rst
docs/internals/reference/celery.utils.rst
docs/internals/reference/celery.utils.serialization.rst
docs/internals/reference/celery.utils.term.rst
docs/internals/reference/celery.utils.timer2.rst
docs/internals/reference/celery.utils.timeutils.rst
docs/internals/reference/celery.worker.autoscale.rst
docs/internals/reference/celery.worker.buckets.rst
docs/internals/reference/celery.worker.consumer.rst
docs/internals/reference/celery.worker.heartbeat.rst
docs/internals/reference/celery.worker.job.rst
docs/internals/reference/celery.worker.mediator.rst
docs/internals/reference/celery.worker.rst
docs/internals/reference/celery.worker.state.rst
docs/internals/reference/index.rst
docs/reference/celery.app.amqp.rst
docs/reference/celery.app.defaults.rst
docs/reference/celery.app.rst
docs/reference/celery.app.task.rst
docs/reference/celery.apps.beat.rst
docs/reference/celery.apps.worker.rst
docs/reference/celery.bin.base.rst
docs/reference/celery.bin.camqadm.rst
docs/reference/celery.bin.celerybeat.rst
docs/reference/celery.bin.celeryctl.rst
docs/reference/celery.bin.celeryd.rst
docs/reference/celery.bin.celeryd_multi.rst
docs/reference/celery.bin.celeryev.rst
docs/reference/celery.contrib.abortable.rst
docs/reference/celery.contrib.batches.rst
docs/reference/celery.contrib.rdb.rst
docs/reference/celery.events.rst
docs/reference/celery.events.state.rst
docs/reference/celery.exceptions.rst
docs/reference/celery.loaders.app.rst
docs/reference/celery.loaders.base.rst
docs/reference/celery.loaders.default.rst
docs/reference/celery.loaders.rst
docs/reference/celery.registry.rst
docs/reference/celery.result.rst
docs/reference/celery.schedules.rst
docs/reference/celery.signals.rst
docs/reference/celery.states.rst
docs/reference/celery.task.base.rst
docs/reference/celery.task.chords.rst
docs/reference/celery.task.control.rst
docs/reference/celery.task.http.rst
docs/reference/celery.task.rst
docs/reference/celery.task.sets.rst
docs/reference/celery.utils.mail.rst
docs/reference/index.rst
docs/releases/1.0/announcement.rst
docs/slidesource/slide-example1-result.py
docs/slidesource/slide-example1.py
docs/templates/readme.txt
docs/tutorials/clickcounter.rst
docs/tutorials/debugging.rst
docs/tutorials/index.rst
docs/tutorials/otherqueues.rst
docs/userguide/executing.rst
docs/userguide/index.rst
docs/userguide/monitoring.rst
docs/userguide/optimizing.rst
docs/userguide/overview.rst
docs/userguide/periodic-tasks.rst
docs/userguide/remote-tasks.rst
docs/userguide/routing.rst
docs/userguide/signals.rst
docs/userguide/tasks.rst
docs/userguide/tasksets.rst
docs/userguide/workers.rst
docs/userguide/concurrency/eventlet.rst
docs/userguide/concurrency/index.rst
examples/README.rst
examples/app/myapp.py
examples/celery_http_gateway/README.rst
examples/celery_http_gateway/__init__.py
examples/celery_http_gateway/manage.py
examples/celery_http_gateway/settings.py
examples/celery_http_gateway/urls.py
examples/eventlet/README.rst
examples/eventlet/bulk_task_producer.py
examples/eventlet/celeryconfig.py
examples/eventlet/tasks.py
examples/eventlet/webcrawler.py
examples/gevent/celeryconfig.py
examples/gevent/tasks.py
examples/httpexample/README.rst
examples/httpexample/__init__.py
examples/httpexample/manage.py
examples/httpexample/settings.py
examples/httpexample/urls.py
examples/httpexample/views.py
examples/pythonproject/demoapp/README.rst
examples/pythonproject/demoapp/__init__.py
examples/pythonproject/demoapp/celeryconfig.py
examples/pythonproject/demoapp/tasks.py
examples/pythonproject/demoapp/test.py
funtests/setup.py
funtests/bench/worker.py
funtests/suite/__init__.py
funtests/suite/config.py
funtests/suite/test_basic.py
funtests/suite/test_leak.py
requirements/default-py3k.txt
requirements/default.txt
requirements/docs.txt
requirements/pkgutils.txt
requirements/py25.txt
requirements/py26.txt
requirements/test-py3k.txt
requirements/test-pypy.txt
requirements/test.txt

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,8 +0,0 @@
[console_scripts]
celeryctl = celery.bin.celeryctl:main
celeryd = celery.bin.celeryd:main
camqadm = celery.bin.camqadm:main
celeryev = celery.bin.celeryev:main
celeryd-multi = celery.bin.celeryd_multi:main
celerybeat = celery.bin.celerybeat:main

Просмотреть файл

@ -1,360 +0,0 @@
../celery/conf.py
../celery/states.py
../celery/decorators.py
../celery/local.py
../celery/exceptions.py
../celery/messaging.py
../celery/schedules.py
../celery/routes.py
../celery/__init__.py
../celery/platforms.py
../celery/signals.py
../celery/beat.py
../celery/result.py
../celery/registry.py
../celery/log.py
../celery/datastructures.py
../celery/worker/mediator.py
../celery/worker/buckets.py
../celery/worker/state.py
../celery/worker/heartbeat.py
../celery/worker/__init__.py
../celery/worker/job.py
../celery/worker/consumer.py
../celery/worker/autoscale.py
../celery/contrib/batches.py
../celery/contrib/abortable.py
../celery/contrib/__init__.py
../celery/contrib/rdb.py
../celery/backends/cassandra.py
../celery/backends/cache.py
../celery/backends/amqp.py
../celery/backends/pyredis.py
../celery/backends/redis.py
../celery/backends/tyrant.py
../celery/backends/base.py
../celery/backends/__init__.py
../celery/backends/database.py
../celery/backends/mongodb.py
../celery/utils/timer2.py
../celery/utils/encoding.py
../celery/utils/functional.py
../celery/utils/mail.py
../celery/utils/__init__.py
../celery/utils/term.py
../celery/utils/compat.py
../celery/utils/serialization.py
../celery/utils/patch.py
../celery/utils/timeutils.py
../celery/events/state.py
../celery/events/dumper.py
../celery/events/cursesmon.py
../celery/events/snapshot.py
../celery/events/__init__.py
../celery/execute/trace.py
../celery/execute/__init__.py
../celery/apps/worker.py
../celery/apps/__init__.py
../celery/apps/beat.py
../celery/db/dfd042c7.py
../celery/db/a805d4bd.py
../celery/db/session.py
../celery/db/__init__.py
../celery/db/models.py
../celery/bin/celeryev.py
../celery/bin/celeryd_detach.py
../celery/bin/camqadm.py
../celery/bin/base.py
../celery/bin/__init__.py
../celery/bin/celeryd_multi.py
../celery/bin/celerybeat.py
../celery/bin/celeryctl.py
../celery/bin/celeryd.py
../celery/tests/config.py
../celery/tests/utils.py
../celery/tests/__init__.py
../celery/tests/compat.py
../celery/task/chords.py
../celery/task/sets.py
../celery/task/http.py
../celery/task/schedules.py
../celery/task/control.py
../celery/task/base.py
../celery/task/__init__.py
../celery/concurrency/solo.py
../celery/concurrency/gevent.py
../celery/concurrency/base.py
../celery/concurrency/__init__.py
../celery/concurrency/threads.py
../celery/concurrency/eventlet.py
../celery/app/amqp.py
../celery/app/base.py
../celery/app/__init__.py
../celery/app/defaults.py
../celery/loaders/base.py
../celery/loaders/__init__.py
../celery/loaders/app.py
../celery/loaders/default.py
../celery/worker/control/builtins.py
../celery/worker/control/__init__.py
../celery/worker/control/registry.py
../celery/utils/dispatch/__init__.py
../celery/utils/dispatch/signal.py
../celery/utils/dispatch/saferef.py
../celery/tests/test_utils/test_timer2.py
../celery/tests/test_utils/test_pickle.py
../celery/tests/test_utils/test_utils_encoding.py
../celery/tests/test_utils/test_utils_timeutils.py
../celery/tests/test_utils/test_datastructures.py
../celery/tests/test_utils/test_serialization.py
../celery/tests/test_utils/__init__.py
../celery/tests/test_utils/test_utils_info.py
../celery/tests/test_worker/test_worker_job.py
../celery/tests/test_worker/test_worker_heartbeat.py
../celery/tests/test_worker/test_worker_state.py
../celery/tests/test_worker/test_worker_autoscale.py
../celery/tests/test_worker/test_worker_mediator.py
../celery/tests/test_worker/test_worker_revoke.py
../celery/tests/test_worker/__init__.py
../celery/tests/test_worker/test_worker_control.py
../celery/tests/test_compat/test_messaging.py
../celery/tests/test_compat/__init__.py
../celery/tests/test_compat/test_decorators.py
../celery/tests/functional/case.py
../celery/tests/functional/tasks.py
../celery/tests/functional/__init__.py
../celery/tests/test_backends/test_redis_unit.py
../celery/tests/test_backends/test_base.py
../celery/tests/test_backends/test_cache.py
../celery/tests/test_backends/test_redis.py
../celery/tests/test_backends/test_amqp.py
../celery/tests/test_backends/test_tyrant.py
../celery/tests/test_backends/test_database.py
../celery/tests/test_backends/__init__.py
../celery/tests/test_backends/test_pyredis_compat.py
../celery/tests/test_concurrency/test_concurrency_solo.py
../celery/tests/test_concurrency/test_concurrency_eventlet.py
../celery/tests/test_concurrency/__init__.py
../celery/tests/test_concurrency/test_concurrency_processes.py
../celery/tests/test_concurrency/test_pool.py
../celery/tests/test_events/test_events_state.py
../celery/tests/test_events/test_events_cursesmon.py
../celery/tests/test_events/test_events_snapshot.py
../celery/tests/test_events/__init__.py
../celery/tests/test_slow/test_buckets.py
../celery/tests/test_slow/__init__.py
../celery/tests/test_bin/test_celeryev.py
../celery/tests/test_bin/test_celeryd.py
../celery/tests/test_bin/__init__.py
../celery/tests/test_bin/test_celerybeat.py
../celery/tests/test_task/test_execute_trace.py
../celery/tests/test_task/test_result.py
../celery/tests/test_task/test_task_http.py
../celery/tests/test_task/test_task_abortable.py
../celery/tests/test_task/test_task_builtins.py
../celery/tests/test_task/test_states.py
../celery/tests/test_task/__init__.py
../celery/tests/test_task/test_chord.py
../celery/tests/test_task/test_registry.py
../celery/tests/test_task/test_context.py
../celery/tests/test_task/test_task_control.py
../celery/tests/test_task/test_task_sets.py
../celery/tests/test_app/test_app_amqp.py
../celery/tests/test_app/test_routes.py
../celery/tests/test_app/test_app_defaults.py
../celery/tests/test_app/__init__.py
../celery/tests/test_app/test_loaders.py
../celery/tests/test_app/test_log.py
../celery/tests/test_app/test_beat.py
../celery/tests/test_app/test_celery.py
../celery/concurrency/processes/pool.py
../celery/concurrency/processes/__init__.py
../celery/concurrency/processes/_win.py
../celery/app/task/__init__.py
../celery/conf.pyc
../celery/states.pyc
../celery/decorators.pyc
../celery/local.pyc
../celery/exceptions.pyc
../celery/messaging.pyc
../celery/schedules.pyc
../celery/routes.pyc
../celery/__init__.pyc
../celery/platforms.pyc
../celery/signals.pyc
../celery/beat.pyc
../celery/result.pyc
../celery/registry.pyc
../celery/log.pyc
../celery/datastructures.pyc
../celery/worker/mediator.pyc
../celery/worker/buckets.pyc
../celery/worker/state.pyc
../celery/worker/heartbeat.pyc
../celery/worker/__init__.pyc
../celery/worker/job.pyc
../celery/worker/consumer.pyc
../celery/worker/autoscale.pyc
../celery/contrib/batches.pyc
../celery/contrib/abortable.pyc
../celery/contrib/__init__.pyc
../celery/contrib/rdb.pyc
../celery/backends/cassandra.pyc
../celery/backends/cache.pyc
../celery/backends/amqp.pyc
../celery/backends/pyredis.pyc
../celery/backends/redis.pyc
../celery/backends/tyrant.pyc
../celery/backends/base.pyc
../celery/backends/__init__.pyc
../celery/backends/database.pyc
../celery/backends/mongodb.pyc
../celery/utils/timer2.pyc
../celery/utils/encoding.pyc
../celery/utils/functional.pyc
../celery/utils/mail.pyc
../celery/utils/__init__.pyc
../celery/utils/term.pyc
../celery/utils/compat.pyc
../celery/utils/serialization.pyc
../celery/utils/patch.pyc
../celery/utils/timeutils.pyc
../celery/events/state.pyc
../celery/events/dumper.pyc
../celery/events/cursesmon.pyc
../celery/events/snapshot.pyc
../celery/events/__init__.pyc
../celery/execute/trace.pyc
../celery/execute/__init__.pyc
../celery/apps/worker.pyc
../celery/apps/__init__.pyc
../celery/apps/beat.pyc
../celery/db/dfd042c7.pyc
../celery/db/a805d4bd.pyc
../celery/db/session.pyc
../celery/db/__init__.pyc
../celery/db/models.pyc
../celery/bin/celeryev.pyc
../celery/bin/celeryd_detach.pyc
../celery/bin/camqadm.pyc
../celery/bin/base.pyc
../celery/bin/__init__.pyc
../celery/bin/celeryd_multi.pyc
../celery/bin/celerybeat.pyc
../celery/bin/celeryctl.pyc
../celery/bin/celeryd.pyc
../celery/tests/config.pyc
../celery/tests/utils.pyc
../celery/tests/__init__.pyc
../celery/tests/compat.pyc
../celery/task/chords.pyc
../celery/task/sets.pyc
../celery/task/http.pyc
../celery/task/schedules.pyc
../celery/task/control.pyc
../celery/task/base.pyc
../celery/task/__init__.pyc
../celery/concurrency/solo.pyc
../celery/concurrency/gevent.pyc
../celery/concurrency/base.pyc
../celery/concurrency/__init__.pyc
../celery/concurrency/threads.pyc
../celery/concurrency/eventlet.pyc
../celery/app/amqp.pyc
../celery/app/base.pyc
../celery/app/__init__.pyc
../celery/app/defaults.pyc
../celery/loaders/base.pyc
../celery/loaders/__init__.pyc
../celery/loaders/app.pyc
../celery/loaders/default.pyc
../celery/worker/control/builtins.pyc
../celery/worker/control/__init__.pyc
../celery/worker/control/registry.pyc
../celery/utils/dispatch/__init__.pyc
../celery/utils/dispatch/signal.pyc
../celery/utils/dispatch/saferef.pyc
../celery/tests/test_utils/test_timer2.pyc
../celery/tests/test_utils/test_pickle.pyc
../celery/tests/test_utils/test_utils_encoding.pyc
../celery/tests/test_utils/test_utils_timeutils.pyc
../celery/tests/test_utils/test_datastructures.pyc
../celery/tests/test_utils/test_serialization.pyc
../celery/tests/test_utils/__init__.pyc
../celery/tests/test_utils/test_utils_info.pyc
../celery/tests/test_worker/test_worker_job.pyc
../celery/tests/test_worker/test_worker_heartbeat.pyc
../celery/tests/test_worker/test_worker_state.pyc
../celery/tests/test_worker/test_worker_autoscale.pyc
../celery/tests/test_worker/test_worker_mediator.pyc
../celery/tests/test_worker/test_worker_revoke.pyc
../celery/tests/test_worker/__init__.pyc
../celery/tests/test_worker/test_worker_control.pyc
../celery/tests/test_compat/test_messaging.pyc
../celery/tests/test_compat/__init__.pyc
../celery/tests/test_compat/test_decorators.pyc
../celery/tests/functional/case.pyc
../celery/tests/functional/tasks.pyc
../celery/tests/functional/__init__.pyc
../celery/tests/test_backends/test_redis_unit.pyc
../celery/tests/test_backends/test_base.pyc
../celery/tests/test_backends/test_cache.pyc
../celery/tests/test_backends/test_redis.pyc
../celery/tests/test_backends/test_amqp.pyc
../celery/tests/test_backends/test_tyrant.pyc
../celery/tests/test_backends/test_database.pyc
../celery/tests/test_backends/__init__.pyc
../celery/tests/test_backends/test_pyredis_compat.pyc
../celery/tests/test_concurrency/test_concurrency_solo.pyc
../celery/tests/test_concurrency/test_concurrency_eventlet.pyc
../celery/tests/test_concurrency/__init__.pyc
../celery/tests/test_concurrency/test_concurrency_processes.pyc
../celery/tests/test_concurrency/test_pool.pyc
../celery/tests/test_events/test_events_state.pyc
../celery/tests/test_events/test_events_cursesmon.pyc
../celery/tests/test_events/test_events_snapshot.pyc
../celery/tests/test_events/__init__.pyc
../celery/tests/test_slow/test_buckets.pyc
../celery/tests/test_slow/__init__.pyc
../celery/tests/test_bin/test_celeryev.pyc
../celery/tests/test_bin/test_celeryd.pyc
../celery/tests/test_bin/__init__.pyc
../celery/tests/test_bin/test_celerybeat.pyc
../celery/tests/test_task/test_execute_trace.pyc
../celery/tests/test_task/test_result.pyc
../celery/tests/test_task/test_task_http.pyc
../celery/tests/test_task/test_task_abortable.pyc
../celery/tests/test_task/test_task_builtins.pyc
../celery/tests/test_task/test_states.pyc
../celery/tests/test_task/__init__.pyc
../celery/tests/test_task/test_chord.pyc
../celery/tests/test_task/test_registry.pyc
../celery/tests/test_task/test_context.pyc
../celery/tests/test_task/test_task_control.pyc
../celery/tests/test_task/test_task_sets.pyc
../celery/tests/test_app/test_app_amqp.pyc
../celery/tests/test_app/test_routes.pyc
../celery/tests/test_app/test_app_defaults.pyc
../celery/tests/test_app/__init__.pyc
../celery/tests/test_app/test_loaders.pyc
../celery/tests/test_app/test_log.pyc
../celery/tests/test_app/test_beat.pyc
../celery/tests/test_app/test_celery.pyc
../celery/concurrency/processes/pool.pyc
../celery/concurrency/processes/__init__.pyc
../celery/concurrency/processes/_win.pyc
../celery/app/task/__init__.pyc
./
top_level.txt
SOURCES.txt
not-zip-safe
entry_points.txt
PKG-INFO
requires.txt
dependency_links.txt
../../../bin/celeryctl
../../../bin/celeryd
../../../bin/camqadm
../../../bin/celeryev
../../../bin/celeryd-multi
../../../bin/celerybeat

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,5 +0,0 @@
importlib
anyjson>=0.3.1
kombu>=1.4.3,<3.0.0
python-dateutil>=1.5.0,<2.0.0
ordereddict

Просмотреть файл

@ -1 +0,0 @@
celery

Просмотреть файл

@ -1,393 +0,0 @@
Metadata-Version: 1.0
Name: celery
Version: 2.5.0
Summary: Distributed Task Queue
Home-page: http://celeryproject.org
Author: Ask Solem
Author-email: ask@celeryproject.org
License: BSD
Description: =================================
celery - Distributed Task Queue
=================================
.. image:: http://cloud.github.com/downloads/ask/celery/celery_128.png
:Version: 2.5.0
:Web: http://celeryproject.org/
:Download: http://pypi.python.org/pypi/celery/
:Source: http://github.com/ask/celery/
:Keywords: task queue, job queue, asynchronous, rabbitmq, amqp, redis,
python, webhooks, queue, distributed
--
.. _celery-synopsis:
Celery is an open source asynchronous task queue/job queue based on
distributed message passing. It is focused on real-time operation,
but supports scheduling as well.
The execution units, called tasks, are executed concurrently on one or
more worker nodes using multiprocessing, `Eventlet`_ or `gevent`_. Tasks can
execute asynchronously (in the background) or synchronously
(wait until ready).
Celery is used in production systems to process millions of tasks a day.
Celery is written in Python, but the protocol can be implemented in any
language. It can also `operate with other languages using webhooks`_.
There's also `RCelery` for the Ruby programming language, and a `PHP client`.
The recommended message broker is `RabbitMQ`_, but support for
`Redis`_, `MongoDB`_, Beanstalk`_, `Amazon SQS`_, `CouchDB`_ and
databases (using `SQLAlchemy`_ or the `Django ORM`_) is also available.
Celery is easy to integrate with `Django`_, `Pylons`_ `Flask`_, and `web2py`_, using
the `django-celery`_, `celery-pylons`_ and `Flask-Celery`_ add-on packages.
But Celery is only Python, and the integration packages is used mostly for
convenience, Celery has also been successfully used with other frameworks and
libraries, like `Pyramid`_ and `Bottle`_.
.. _`RCelery`: http://leapfrogdevelopment.github.com/rcelery/
.. _`PHP client`: https://github.com/gjedeer/celery-php
.. _`RabbitMQ`: http://www.rabbitmq.com/
.. _`Redis`: http://code.google.com/p/redis/
.. _`SQLAlchemy`: http://www.sqlalchemy.org/
.. _`Django`: http://djangoproject.com/
.. _`Django ORM`: http://djangoproject.com/
.. _`Eventlet`: http://eventlet.net/
.. _`gevent`: http://gevent.org/
.. _`Beanstalk`: http://kr.github.com/beanstalkd/
.. _`MongoDB`: http://mongodb.org/
.. _`CouchDB`: http://couchdb.apache.org/
.. _`Amazon SQS`: http://aws.amazon.com/sqs/
.. _`Pylons`: http://pylonshq.com/
.. _`Flask`: http://flask.pocoo.org/
.. _`web2py`: http://web2py.com/
.. _`Bottle`: http://bottlepy.org/
.. _`Pyramid`: http://docs.pylonsproject.org/en/latest/docs/pyramid.html
.. _`django-celery`: http://pypi.python.org/pypi/django-celery
.. _`celery-pylons`: http://pypi.python.org/pypi/celery-pylons
.. _`Flask-Celery`: http://github.com/ask/flask-celery/
.. _`web2py-celery`: http://code.google.com/p/web2py-celery/
.. _`operate with other languages using webhooks`:
http://ask.github.com/celery/userguide/remote-tasks.html
.. _`limited support`:
http://kombu.readthedocs.org/en/latest/introduction.html#transport-comparison
.. contents::
:local:
.. _celery-overview:
Overview
========
This is a high level overview of the architecture.
.. image:: http://cloud.github.com/downloads/ask/celery/Celery-Overview-v4.jpg
The broker delivers tasks to the worker nodes.
A worker node is a networked machine running `celeryd`. This can be one or
more machines depending on the workload.
The result of the task can be stored for later retrieval (called its
"tombstone").
.. _celery-example:
Example
=======
You probably want to see some code by now, so here's an example task
adding two numbers:
::
from celery.task import task
@task
def add(x, y):
return x + y
You can execute the task in the background, or wait for it to finish::
>>> result = add.delay(4, 4)
>>> result.wait() # wait for and return the result
8
Simple!
.. _celery-features:
Features
========
+-----------------+----------------------------------------------------+
| Messaging | Supported brokers include `RabbitMQ`_, `Redis`_, |
| | `Beanstalk`_, `MongoDB`_, `CouchDB`_, and popular |
| | SQL databases. |
+-----------------+----------------------------------------------------+
| Fault-tolerant | Excellent configurable error recovery when using |
| | `RabbitMQ`, ensures your tasks are never lost. |
+-----------------+----------------------------------------------------+
| Distributed | Runs on one or more machines. Supports |
| | broker `clustering`_ and `HA`_ when used in |
| | combination with `RabbitMQ`_. You can set up new |
| | workers without central configuration (e.g. use |
| | your grandma's laptop to help if the queue is |
| | temporarily congested). |
+-----------------+----------------------------------------------------+
| Concurrency | Concurrency is achieved by using multiprocessing, |
| | `Eventlet`_, `gevent` or a mix of these. |
+-----------------+----------------------------------------------------+
| Scheduling | Supports recurring tasks like cron, or specifying |
| | an exact date or countdown for when after the task |
| | should be executed. |
+-----------------+----------------------------------------------------+
| Latency | Low latency means you are able to execute tasks |
| | *while the user is waiting*. |
+-----------------+----------------------------------------------------+
| Return Values | Task return values can be saved to the selected |
| | result store backend. You can wait for the result, |
| | retrieve it later, or ignore it. |
+-----------------+----------------------------------------------------+
| Result Stores | Database, `MongoDB`_, `Redis`_, `Tokyo Tyrant`, |
| | `Cassandra`, or `AMQP`_ (message notification). |
+-----------------+----------------------------------------------------+
| Webhooks | Your tasks can also be HTTP callbacks, enabling |
| | cross-language communication. |
+-----------------+----------------------------------------------------+
| Rate limiting | Supports rate limiting by using the token bucket |
| | algorithm, which accounts for bursts of traffic. |
| | Rate limits can be set for each task type, or |
| | globally for all. |
+-----------------+----------------------------------------------------+
| Routing | Using AMQP's flexible routing model you can route |
| | tasks to different workers, or select different |
| | message topologies, by configuration or even at |
| | runtime. |
+-----------------+----------------------------------------------------+
| Remote-control | Worker nodes can be controlled from remote by |
| | using broadcast messaging. A range of built-in |
| | commands exist in addition to the ability to |
| | easily define your own. (AMQP/Redis only) |
+-----------------+----------------------------------------------------+
| Monitoring | You can capture everything happening with the |
| | workers in real-time by subscribing to events. |
| | A real-time web monitor is in development. |
+-----------------+----------------------------------------------------+
| Serialization | Supports Pickle, JSON, YAML, or easily defined |
| | custom schemes. One task invocation can have a |
| | different scheme than another. |
+-----------------+----------------------------------------------------+
| Tracebacks | Errors and tracebacks are stored and can be |
| | investigated after the fact. |
+-----------------+----------------------------------------------------+
| UUID | Every task has an UUID (Universally Unique |
| | Identifier), which is the task id used to query |
| | task status and return value. |
+-----------------+----------------------------------------------------+
| Retries | Tasks can be retried if they fail, with |
| | configurable maximum number of retries, and delays |
| | between each retry. |
+-----------------+----------------------------------------------------+
| Task Sets | A Task set is a task consisting of several |
| | sub-tasks. You can find out how many, or if all |
| | of the sub-tasks has been executed, and even |
| | retrieve the results in order. Progress bars, |
| | anyone? |
+-----------------+----------------------------------------------------+
| Made for Web | You can query status and results via URLs, |
| | enabling the ability to poll task status using |
| | Ajax. |
+-----------------+----------------------------------------------------+
| Error Emails | Can be configured to send emails to the |
| | administrators when tasks fails. |
+-----------------+----------------------------------------------------+
.. _`clustering`: http://www.rabbitmq.com/clustering.html
.. _`HA`: http://www.rabbitmq.com/pacemaker.html
.. _`AMQP`: http://www.amqp.org/
.. _`Stomp`: http://stomp.codehaus.org/
.. _`Tokyo Tyrant`: http://tokyocabinet.sourceforge.net/
.. _celery-documentation:
Documentation
=============
The `latest documentation`_ with user guides, tutorials and API reference
is hosted at Github.
.. _`latest documentation`: http://ask.github.com/celery/
.. _celery-installation:
Installation
============
You can install Celery either via the Python Package Index (PyPI)
or from source.
To install using `pip`,::
$ pip install -U Celery
To install using `easy_install`,::
$ easy_install -U Celery
Bundles
-------
Celery also defines a group of bundles that can be used
to install Celery and the dependencies for a given feature.
The following bundles are available:
:`celery-with-redis`_:
for using Redis as a broker.
:`celery-with-mongodb`_:
for using MongoDB as a broker.
:`django-celery-with-redis`_:
for Django, and using Redis as a broker.
:`django-celery-with-mongodb`_:
for Django, and using MongoDB as a broker.
:`bundle-celery`_:
convenience bundle installing *Celery* and related packages.
.. _`celery-with-redis`:
http://pypi.python.org/pypi/celery-with-redis/
.. _`celery-with-mongodb`:
http://pypi.python.org/pypi/celery-with-mongdb/
.. _`django-celery-with-redis`:
http://pypi.python.org/pypi/django-celery-with-redis/
.. _`django-celery-with-mongodb`:
http://pypi.python.org/pypi/django-celery-with-mongdb/
.. _`bundle-celery`:
http://pypi.python.org/pypi/bundle-celery/
.. _celery-installing-from-source:
Downloading and installing from source
--------------------------------------
Download the latest version of Celery from
http://pypi.python.org/pypi/celery/
You can install it by doing the following,::
$ tar xvfz celery-0.0.0.tar.gz
$ cd celery-0.0.0
$ python setup.py build
# python setup.py install # as root
.. _celery-installing-from-git:
Using the development version
-----------------------------
You can clone the repository by doing the following::
$ git clone git://github.com/ask/celery.git
.. _getting-help:
Getting Help
============
.. _mailing-list:
Mailing list
------------
For discussions about the usage, development, and future of celery,
please join the `celery-users`_ mailing list.
.. _`celery-users`: http://groups.google.com/group/celery-users/
.. _irc-channel:
IRC
---
Come chat with us on IRC. The `#celery`_ channel is located at the `Freenode`_
network.
.. _`#celery`: irc://irc.freenode.net/celery
.. _`Freenode`: http://freenode.net
.. _bug-tracker:
Bug tracker
===========
If you have any suggestions, bug reports or annoyances please report them
to our issue tracker at http://github.com/ask/celery/issues/
.. _wiki:
Wiki
====
http://wiki.github.com/ask/celery/
.. _contributing-short:
Contributing
============
Development of `celery` happens at Github: http://github.com/ask/celery
You are highly encouraged to participate in the development
of `celery`. If you don't like Github (for some reason) you're welcome
to send regular patches.
Be sure to also read the `Contributing to Celery`_ section in the
documentation.
.. _`Contributing to Celery`: http://ask.github.com/celery/contributing.html
.. _license:
License
=======
This software is licensed under the `New BSD License`. See the ``LICENSE``
file in the top distribution directory for the full license text.
.. # vim: syntax=rst expandtab tabstop=4 shiftwidth=4 shiftround
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
Classifier: Topic :: System :: Distributed Computing
Classifier: Topic :: Software Development :: Object Brokering
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Healthcare Industry
Classifier: Environment :: No Input/Output (Daemon)
Classifier: Environment :: Console
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: Implementation :: Jython
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS :: MacOS X

Просмотреть файл

@ -1,465 +0,0 @@
AUTHORS
Changelog
FAQ
INSTALL
LICENSE
MANIFEST.in
README
README.rst
THANKS
TODO
setup.cfg
setup.py
celery/__init__.py
celery/abstract.py
celery/actors.py
celery/beat.py
celery/conf.py
celery/datastructures.py
celery/decorators.py
celery/exceptions.py
celery/local.py
celery/log.py
celery/messaging.py
celery/platforms.py
celery/registry.py
celery/result.py
celery/routes.py
celery/schedules.py
celery/signals.py
celery/states.py
celery.egg-info/PKG-INFO
celery.egg-info/SOURCES.txt
celery.egg-info/dependency_links.txt
celery.egg-info/entry_points.txt
celery.egg-info/not-zip-safe
celery.egg-info/requires.txt
celery.egg-info/top_level.txt
celery/app/__init__.py
celery/app/abstract.py
celery/app/amqp.py
celery/app/annotations.py
celery/app/base.py
celery/app/defaults.py
celery/app/task/__init__.py
celery/apps/__init__.py
celery/apps/beat.py
celery/apps/worker.py
celery/backends/__init__.py
celery/backends/amqp.py
celery/backends/base.py
celery/backends/cache.py
celery/backends/cassandra.py
celery/backends/database.py
celery/backends/mongodb.py
celery/backends/pyredis.py
celery/backends/redis.py
celery/backends/tyrant.py
celery/bin/__init__.py
celery/bin/base.py
celery/bin/camqadm.py
celery/bin/celerybeat.py
celery/bin/celeryctl.py
celery/bin/celeryd.py
celery/bin/celeryd_detach.py
celery/bin/celeryd_multi.py
celery/bin/celeryev.py
celery/concurrency/__init__.py
celery/concurrency/base.py
celery/concurrency/eventlet.py
celery/concurrency/gevent.py
celery/concurrency/solo.py
celery/concurrency/threads.py
celery/concurrency/processes/__init__.py
celery/concurrency/processes/_win.py
celery/concurrency/processes/forking.py
celery/concurrency/processes/pool.py
celery/concurrency/processes/process.py
celery/contrib/__init__.py
celery/contrib/abortable.py
celery/contrib/batches.py
celery/contrib/bundles.py
celery/contrib/migrate.py
celery/contrib/rdb.py
celery/db/__init__.py
celery/db/a805d4bd.py
celery/db/dfd042c7.py
celery/db/models.py
celery/db/session.py
celery/events/__init__.py
celery/events/cursesmon.py
celery/events/dumper.py
celery/events/snapshot.py
celery/events/state.py
celery/execute/__init__.py
celery/execute/trace.py
celery/loaders/__init__.py
celery/loaders/app.py
celery/loaders/base.py
celery/loaders/default.py
celery/security/__init__.py
celery/security/certificate.py
celery/security/key.py
celery/security/serialization.py
celery/task/__init__.py
celery/task/base.py
celery/task/chords.py
celery/task/control.py
celery/task/http.py
celery/task/schedules.py
celery/task/sets.py
celery/tests/__init__.py
celery/tests/compat.py
celery/tests/config.py
celery/tests/utils.py
celery/tests/functional/__init__.py
celery/tests/functional/case.py
celery/tests/functional/tasks.py
celery/tests/test_app/__init__.py
celery/tests/test_app/test_actors.py
celery/tests/test_app/test_annotations.py
celery/tests/test_app/test_app_amqp.py
celery/tests/test_app/test_app_defaults.py
celery/tests/test_app/test_beat.py
celery/tests/test_app/test_celery.py
celery/tests/test_app/test_loaders.py
celery/tests/test_app/test_log.py
celery/tests/test_app/test_routes.py
celery/tests/test_backends/__init__.py
celery/tests/test_backends/test_amqp.py
celery/tests/test_backends/test_base.py
celery/tests/test_backends/test_cache.py
celery/tests/test_backends/test_database.py
celery/tests/test_backends/test_mongodb.py
celery/tests/test_backends/test_pyredis_compat.py
celery/tests/test_backends/test_redis.py
celery/tests/test_backends/test_redis_unit.py
celery/tests/test_backends/test_tyrant.py
celery/tests/test_bin/__init__.py
celery/tests/test_bin/test_celerybeat.py
celery/tests/test_bin/test_celeryd.py
celery/tests/test_bin/test_celeryev.py
celery/tests/test_compat/__init__.py
celery/tests/test_compat/test_decorators.py
celery/tests/test_compat/test_messaging.py
celery/tests/test_concurrency/__init__.py
celery/tests/test_concurrency/test_concurrency_eventlet.py
celery/tests/test_concurrency/test_concurrency_gevent.py
celery/tests/test_concurrency/test_concurrency_processes.py
celery/tests/test_concurrency/test_concurrency_solo.py
celery/tests/test_concurrency/test_pool.py
celery/tests/test_events/__init__.py
celery/tests/test_events/test_events_cursesmon.py
celery/tests/test_events/test_events_snapshot.py
celery/tests/test_events/test_events_state.py
celery/tests/test_security/__init__.py
celery/tests/test_security/case.py
celery/tests/test_security/test_certificate.py
celery/tests/test_security/test_key.py
celery/tests/test_security/test_serialization.py
celery/tests/test_slow/__init__.py
celery/tests/test_slow/test_buckets.py
celery/tests/test_task/__init__.py
celery/tests/test_task/test_chord.py
celery/tests/test_task/test_context.py
celery/tests/test_task/test_execute_trace.py
celery/tests/test_task/test_registry.py
celery/tests/test_task/test_result.py
celery/tests/test_task/test_states.py
celery/tests/test_task/test_task_abortable.py
celery/tests/test_task/test_task_builtins.py
celery/tests/test_task/test_task_control.py
celery/tests/test_task/test_task_http.py
celery/tests/test_task/test_task_sets.py
celery/tests/test_utils/__init__.py
celery/tests/test_utils/test_datastructures.py
celery/tests/test_utils/test_pickle.py
celery/tests/test_utils/test_serialization.py
celery/tests/test_utils/test_timer2.py
celery/tests/test_utils/test_utils_encoding.py
celery/tests/test_utils/test_utils_info.py
celery/tests/test_utils/test_utils_timeutils.py
celery/tests/test_worker/__init__.py
celery/tests/test_worker/test_bootsteps.py
celery/tests/test_worker/test_worker_autoscale.py
celery/tests/test_worker/test_worker_control.py
celery/tests/test_worker/test_worker_heartbeat.py
celery/tests/test_worker/test_worker_job.py
celery/tests/test_worker/test_worker_mediator.py
celery/tests/test_worker/test_worker_revoke.py
celery/tests/test_worker/test_worker_state.py
celery/utils/__init__.py
celery/utils/compat.py
celery/utils/encoding.py
celery/utils/functional.py
celery/utils/mail.py
celery/utils/patch.py
celery/utils/serialization.py
celery/utils/term.py
celery/utils/threads.py
celery/utils/timer2.py
celery/utils/timeutils.py
celery/utils/dispatch/__init__.py
celery/utils/dispatch/saferef.py
celery/utils/dispatch/signal.py
celery/worker/__init__.py
celery/worker/autoreload.py
celery/worker/autoscale.py
celery/worker/buckets.py
celery/worker/consumer.py
celery/worker/control.py
celery/worker/heartbeat.py
celery/worker/job.py
celery/worker/mediator.py
celery/worker/state.py
celery/worker/strategy.py
contrib/bundles/generate.py
contrib/centos/celeryd.init
contrib/centos/celeryd.sysconfig
contrib/debian/README.rst
contrib/debian/init.d-deprecated/celerybeat
contrib/debian/init.d-deprecated/celeryd
contrib/debian/init.d-deprecated/celeryevcam
contrib/generic-init.d/celerybeat
contrib/generic-init.d/celeryd
contrib/generic-init.d/celeryevcam
contrib/logtools/find-unprocessed-tasks-debug.sh
contrib/logtools/find-unprocessed-tasks.sh
contrib/logtools/periodic-task-runtimes.sh
contrib/mac/org.celeryq.celerybeat.plist
contrib/mac/org.celeryq.celeryd.plist
contrib/mac/org.celeryq.celerymon.plist
contrib/mac/watch-workers.applescript
contrib/release/attribution.py
contrib/release/bump_version.py
contrib/release/core-modules.txt
contrib/release/doc4allmods
contrib/release/flakeplus.py
contrib/release/py3k-run-tests
contrib/release/removepyc.sh
contrib/release/sphinx-to-rst.py
contrib/release/verify-reference-index.sh
contrib/release/verify_config_reference.py
contrib/supervisord/celerybeat.conf
contrib/supervisord/celeryd.conf
contrib/supervisord/supervisord.conf
docs/Makefile
docs/changelog.rst
docs/community.rst
docs/conf.py
docs/configuration.rst
docs/contributing.rst
docs/faq.rst
docs/index.rst
docs/whatsnew-2.5.rst
docs/.static/.keep
docs/.templates/page.html
docs/.templates/sidebarintro.html
docs/.templates/sidebarlogo.html
docs/_ext/applyxrefs.py
docs/_ext/celerydocs.py
docs/_ext/literals_to_xrefs.py
docs/_theme/celery/theme.conf
docs/_theme/celery/static/celery.css_t
docs/cookbook/daemonizing.rst
docs/cookbook/index.rst
docs/cookbook/tasks.rst
docs/getting-started/first-steps-with-celery.rst
docs/getting-started/index.rst
docs/getting-started/introduction.rst
docs/getting-started/resources.rst
docs/getting-started/brokers/beanstalk.rst
docs/getting-started/brokers/couchdb.rst
docs/getting-started/brokers/django.rst
docs/getting-started/brokers/index.rst
docs/getting-started/brokers/mongodb.rst
docs/getting-started/brokers/rabbitmq.rst
docs/getting-started/brokers/redis.rst
docs/getting-started/brokers/sqlalchemy.rst
docs/images/Celery-Overview-v4.jpg
docs/images/Celery1.0-inside-worker.jpg
docs/images/celery-broker-worker-nodes.jpg
docs/images/celery-broker-worker-relationship.jpg
docs/images/celery-icon-128.png
docs/images/celery-icon-32.png
docs/images/celery-icon-64.png
docs/images/celery-worker-bindings.jpg
docs/images/celery_128.png
docs/images/celery_512.png
docs/images/celery_favicon_128.png
docs/images/celeryevshotsm.jpg
docs/images/djangoceleryadmin2.jpg
docs/images/favicon.ico
docs/images/favicon.png
docs/includes/installation.txt
docs/includes/introduction.txt
docs/includes/resources.txt
docs/internals/app-overview.rst
docs/internals/deprecation.rst
docs/internals/guide.rst
docs/internals/index.rst
docs/internals/protocol.rst
docs/internals/worker.rst
docs/internals/reference/celery.abstract.rst
docs/internals/reference/celery.app.abstract.rst
docs/internals/reference/celery.app.annotations.rst
docs/internals/reference/celery.backends.amqp.rst
docs/internals/reference/celery.backends.base.rst
docs/internals/reference/celery.backends.cache.rst
docs/internals/reference/celery.backends.cassandra.rst
docs/internals/reference/celery.backends.database.rst
docs/internals/reference/celery.backends.mongodb.rst
docs/internals/reference/celery.backends.redis.rst
docs/internals/reference/celery.backends.rst
docs/internals/reference/celery.backends.tyrant.rst
docs/internals/reference/celery.beat.rst
docs/internals/reference/celery.concurrency.base.rst
docs/internals/reference/celery.concurrency.eventlet.rst
docs/internals/reference/celery.concurrency.gevent.rst
docs/internals/reference/celery.concurrency.processes.pool.rst
docs/internals/reference/celery.concurrency.processes.rst
docs/internals/reference/celery.concurrency.rst
docs/internals/reference/celery.concurrency.solo.rst
docs/internals/reference/celery.concurrency.threads.rst
docs/internals/reference/celery.datastructures.rst
docs/internals/reference/celery.db.models.rst
docs/internals/reference/celery.db.session.rst
docs/internals/reference/celery.events.cursesmon.rst
docs/internals/reference/celery.events.dumper.rst
docs/internals/reference/celery.events.snapshot.rst
docs/internals/reference/celery.execute.trace.rst
docs/internals/reference/celery.log.rst
docs/internals/reference/celery.platforms.rst
docs/internals/reference/celery.routes.rst
docs/internals/reference/celery.security.certificate.rst
docs/internals/reference/celery.security.key.rst
docs/internals/reference/celery.security.serialization.rst
docs/internals/reference/celery.utils.compat.rst
docs/internals/reference/celery.utils.dispatch.rst
docs/internals/reference/celery.utils.dispatch.saferef.rst
docs/internals/reference/celery.utils.dispatch.signal.rst
docs/internals/reference/celery.utils.encoding.rst
docs/internals/reference/celery.utils.functional.rst
docs/internals/reference/celery.utils.patch.rst
docs/internals/reference/celery.utils.rst
docs/internals/reference/celery.utils.serialization.rst
docs/internals/reference/celery.utils.term.rst
docs/internals/reference/celery.utils.threads.rst
docs/internals/reference/celery.utils.timer2.rst
docs/internals/reference/celery.utils.timeutils.rst
docs/internals/reference/celery.worker.autoreload.rst
docs/internals/reference/celery.worker.autoscale.rst
docs/internals/reference/celery.worker.buckets.rst
docs/internals/reference/celery.worker.consumer.rst
docs/internals/reference/celery.worker.heartbeat.rst
docs/internals/reference/celery.worker.job.rst
docs/internals/reference/celery.worker.mediator.rst
docs/internals/reference/celery.worker.rst
docs/internals/reference/celery.worker.state.rst
docs/internals/reference/celery.worker.strategy.rst
docs/internals/reference/index.rst
docs/reference/celery.actors.rst
docs/reference/celery.app.amqp.rst
docs/reference/celery.app.defaults.rst
docs/reference/celery.app.rst
docs/reference/celery.app.task.rst
docs/reference/celery.apps.beat.rst
docs/reference/celery.apps.worker.rst
docs/reference/celery.bin.base.rst
docs/reference/celery.bin.camqadm.rst
docs/reference/celery.bin.celerybeat.rst
docs/reference/celery.bin.celeryctl.rst
docs/reference/celery.bin.celeryd.rst
docs/reference/celery.bin.celeryd_multi.rst
docs/reference/celery.bin.celeryev.rst
docs/reference/celery.contrib.abortable.rst
docs/reference/celery.contrib.batches.rst
docs/reference/celery.contrib.migrate.rst
docs/reference/celery.contrib.rdb.rst
docs/reference/celery.events.rst
docs/reference/celery.events.state.rst
docs/reference/celery.exceptions.rst
docs/reference/celery.loaders.app.rst
docs/reference/celery.loaders.base.rst
docs/reference/celery.loaders.default.rst
docs/reference/celery.loaders.rst
docs/reference/celery.registry.rst
docs/reference/celery.result.rst
docs/reference/celery.schedules.rst
docs/reference/celery.security.rst
docs/reference/celery.signals.rst
docs/reference/celery.states.rst
docs/reference/celery.task.base.rst
docs/reference/celery.task.chords.rst
docs/reference/celery.task.control.rst
docs/reference/celery.task.http.rst
docs/reference/celery.task.rst
docs/reference/celery.task.sets.rst
docs/reference/celery.utils.mail.rst
docs/reference/index.rst
docs/releases/1.0/announcement.rst
docs/sec/CELERYSA-0001.txt
docs/slidesource/slide-example1-result.py
docs/slidesource/slide-example1.py
docs/templates/readme.txt
docs/tutorials/clickcounter.rst
docs/tutorials/debugging.rst
docs/tutorials/index.rst
docs/tutorials/otherqueues.rst
docs/userguide/executing.rst
docs/userguide/index.rst
docs/userguide/monitoring.rst
docs/userguide/optimizing.rst
docs/userguide/overview.rst
docs/userguide/periodic-tasks.rst
docs/userguide/remote-tasks.rst
docs/userguide/routing.rst
docs/userguide/security.rst
docs/userguide/signals.rst
docs/userguide/tasks.rst
docs/userguide/tasksets.rst
docs/userguide/workers.rst
docs/userguide/concurrency/eventlet.rst
docs/userguide/concurrency/index.rst
examples/README.rst
examples/app/myapp.py
examples/celery_http_gateway/README.rst
examples/celery_http_gateway/__init__.py
examples/celery_http_gateway/manage.py
examples/celery_http_gateway/settings.py
examples/celery_http_gateway/urls.py
examples/eventlet/README.rst
examples/eventlet/bulk_task_producer.py
examples/eventlet/celeryconfig.py
examples/eventlet/tasks.py
examples/eventlet/webcrawler.py
examples/gevent/celeryconfig.py
examples/gevent/tasks.py
examples/httpexample/README.rst
examples/httpexample/__init__.py
examples/httpexample/manage.py
examples/httpexample/settings.py
examples/httpexample/urls.py
examples/httpexample/views.py
examples/pythonproject/demoapp/README.rst
examples/pythonproject/demoapp/__init__.py
examples/pythonproject/demoapp/celeryconfig.py
examples/pythonproject/demoapp/tasks.py
examples/pythonproject/demoapp/test.py
examples/resultgraph/tasks.py
funtests/setup.py
funtests/benchmarks/bench_worker.py
funtests/suite/__init__.py
funtests/suite/config.py
funtests/suite/test_basic.py
funtests/suite/test_leak.py
requirements/default-py3k.txt
requirements/default.txt
requirements/docs.txt
requirements/pkgutils.txt
requirements/py25.txt
requirements/py26.txt
requirements/security.txt
requirements/test-py3k.txt
requirements/test-pypy.txt
requirements/test.txt

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,11 +0,0 @@
[console_scripts]
celeryctl = celery.bin.celeryctl:main
celeryd = celery.bin.celeryd:main
camqadm = celery.bin.camqadm:main
celeryev = celery.bin.celeryev:main
celeryd-multi = celery.bin.celeryd_multi:main
celerybeat = celery.bin.celerybeat:main
[bundle.bundles]
celery = celery.contrib.bundles:bundles

Просмотреть файл

@ -1,406 +0,0 @@
../celery/conf.py
../celery/abstract.py
../celery/states.py
../celery/decorators.py
../celery/local.py
../celery/exceptions.py
../celery/messaging.py
../celery/schedules.py
../celery/routes.py
../celery/__init__.py
../celery/platforms.py
../celery/signals.py
../celery/beat.py
../celery/result.py
../celery/registry.py
../celery/log.py
../celery/actors.py
../celery/datastructures.py
../celery/worker/mediator.py
../celery/worker/buckets.py
../celery/worker/state.py
../celery/worker/heartbeat.py
../celery/worker/strategy.py
../celery/worker/control.py
../celery/worker/__init__.py
../celery/worker/job.py
../celery/worker/consumer.py
../celery/worker/autoscale.py
../celery/worker/autoreload.py
../celery/contrib/batches.py
../celery/contrib/abortable.py
../celery/contrib/__init__.py
../celery/contrib/migrate.py
../celery/contrib/rdb.py
../celery/contrib/bundles.py
../celery/backends/cassandra.py
../celery/backends/cache.py
../celery/backends/amqp.py
../celery/backends/pyredis.py
../celery/backends/redis.py
../celery/backends/tyrant.py
../celery/backends/base.py
../celery/backends/__init__.py
../celery/backends/database.py
../celery/backends/mongodb.py
../celery/utils/timer2.py
../celery/utils/encoding.py
../celery/utils/functional.py
../celery/utils/mail.py
../celery/utils/__init__.py
../celery/utils/term.py
../celery/utils/threads.py
../celery/utils/compat.py
../celery/utils/serialization.py
../celery/utils/patch.py
../celery/utils/timeutils.py
../celery/events/state.py
../celery/events/dumper.py
../celery/events/cursesmon.py
../celery/events/snapshot.py
../celery/events/__init__.py
../celery/execute/trace.py
../celery/execute/__init__.py
../celery/apps/worker.py
../celery/apps/__init__.py
../celery/apps/beat.py
../celery/db/dfd042c7.py
../celery/db/a805d4bd.py
../celery/db/session.py
../celery/db/__init__.py
../celery/db/models.py
../celery/bin/celeryev.py
../celery/bin/celeryd_detach.py
../celery/bin/camqadm.py
../celery/bin/base.py
../celery/bin/__init__.py
../celery/bin/celeryd_multi.py
../celery/bin/celerybeat.py
../celery/bin/celeryctl.py
../celery/bin/celeryd.py
../celery/security/key.py
../celery/security/certificate.py
../celery/security/__init__.py
../celery/security/serialization.py
../celery/tests/config.py
../celery/tests/utils.py
../celery/tests/__init__.py
../celery/tests/compat.py
../celery/task/chords.py
../celery/task/sets.py
../celery/task/http.py
../celery/task/schedules.py
../celery/task/control.py
../celery/task/base.py
../celery/task/__init__.py
../celery/concurrency/solo.py
../celery/concurrency/gevent.py
../celery/concurrency/base.py
../celery/concurrency/__init__.py
../celery/concurrency/threads.py
../celery/concurrency/eventlet.py
../celery/app/abstract.py
../celery/app/amqp.py
../celery/app/base.py
../celery/app/__init__.py
../celery/app/defaults.py
../celery/app/annotations.py
../celery/loaders/base.py
../celery/loaders/__init__.py
../celery/loaders/app.py
../celery/loaders/default.py
../celery/utils/dispatch/__init__.py
../celery/utils/dispatch/signal.py
../celery/utils/dispatch/saferef.py
../celery/tests/test_utils/test_timer2.py
../celery/tests/test_utils/test_pickle.py
../celery/tests/test_utils/test_utils_encoding.py
../celery/tests/test_utils/test_utils_timeutils.py
../celery/tests/test_utils/test_datastructures.py
../celery/tests/test_utils/test_serialization.py
../celery/tests/test_utils/__init__.py
../celery/tests/test_utils/test_utils_info.py
../celery/tests/test_worker/test_worker_job.py
../celery/tests/test_worker/test_worker_heartbeat.py
../celery/tests/test_worker/test_worker_state.py
../celery/tests/test_worker/test_worker_autoscale.py
../celery/tests/test_worker/test_worker_mediator.py
../celery/tests/test_worker/test_worker_revoke.py
../celery/tests/test_worker/test_bootsteps.py
../celery/tests/test_worker/__init__.py
../celery/tests/test_worker/test_worker_control.py
../celery/tests/test_compat/test_messaging.py
../celery/tests/test_compat/__init__.py
../celery/tests/test_compat/test_decorators.py
../celery/tests/functional/case.py
../celery/tests/functional/tasks.py
../celery/tests/functional/__init__.py
../celery/tests/test_backends/test_mongodb.py
../celery/tests/test_backends/test_redis_unit.py
../celery/tests/test_backends/test_base.py
../celery/tests/test_backends/test_cache.py
../celery/tests/test_backends/test_redis.py
../celery/tests/test_backends/test_amqp.py
../celery/tests/test_backends/test_tyrant.py
../celery/tests/test_backends/test_database.py
../celery/tests/test_backends/__init__.py
../celery/tests/test_backends/test_pyredis_compat.py
../celery/tests/test_concurrency/test_concurrency_solo.py
../celery/tests/test_concurrency/test_concurrency_eventlet.py
../celery/tests/test_concurrency/__init__.py
../celery/tests/test_concurrency/test_concurrency_processes.py
../celery/tests/test_concurrency/test_concurrency_gevent.py
../celery/tests/test_concurrency/test_pool.py
../celery/tests/test_events/test_events_state.py
../celery/tests/test_events/test_events_cursesmon.py
../celery/tests/test_events/test_events_snapshot.py
../celery/tests/test_events/__init__.py
../celery/tests/test_slow/test_buckets.py
../celery/tests/test_slow/__init__.py
../celery/tests/test_bin/test_celeryev.py
../celery/tests/test_bin/test_celeryd.py
../celery/tests/test_bin/__init__.py
../celery/tests/test_bin/test_celerybeat.py
../celery/tests/test_security/case.py
../celery/tests/test_security/test_key.py
../celery/tests/test_security/test_serialization.py
../celery/tests/test_security/__init__.py
../celery/tests/test_security/test_certificate.py
../celery/tests/test_task/test_execute_trace.py
../celery/tests/test_task/test_result.py
../celery/tests/test_task/test_task_http.py
../celery/tests/test_task/test_task_abortable.py
../celery/tests/test_task/test_task_builtins.py
../celery/tests/test_task/test_states.py
../celery/tests/test_task/__init__.py
../celery/tests/test_task/test_chord.py
../celery/tests/test_task/test_registry.py
../celery/tests/test_task/test_context.py
../celery/tests/test_task/test_task_control.py
../celery/tests/test_task/test_task_sets.py
../celery/tests/test_app/test_app_amqp.py
../celery/tests/test_app/test_routes.py
../celery/tests/test_app/test_annotations.py
../celery/tests/test_app/test_app_defaults.py
../celery/tests/test_app/test_actors.py
../celery/tests/test_app/__init__.py
../celery/tests/test_app/test_loaders.py
../celery/tests/test_app/test_log.py
../celery/tests/test_app/test_beat.py
../celery/tests/test_app/test_celery.py
../celery/concurrency/processes/pool.py
../celery/concurrency/processes/process.py
../celery/concurrency/processes/__init__.py
../celery/concurrency/processes/forking.py
../celery/concurrency/processes/_win.py
../celery/app/task/__init__.py
../celery/conf.pyc
../celery/abstract.pyc
../celery/states.pyc
../celery/decorators.pyc
../celery/local.pyc
../celery/exceptions.pyc
../celery/messaging.pyc
../celery/schedules.pyc
../celery/routes.pyc
../celery/__init__.pyc
../celery/platforms.pyc
../celery/signals.pyc
../celery/beat.pyc
../celery/result.pyc
../celery/registry.pyc
../celery/log.pyc
../celery/actors.pyc
../celery/datastructures.pyc
../celery/worker/mediator.pyc
../celery/worker/buckets.pyc
../celery/worker/state.pyc
../celery/worker/heartbeat.pyc
../celery/worker/strategy.pyc
../celery/worker/control.pyc
../celery/worker/__init__.pyc
../celery/worker/job.pyc
../celery/worker/consumer.pyc
../celery/worker/autoscale.pyc
../celery/worker/autoreload.pyc
../celery/contrib/batches.pyc
../celery/contrib/abortable.pyc
../celery/contrib/__init__.pyc
../celery/contrib/migrate.pyc
../celery/contrib/rdb.pyc
../celery/contrib/bundles.pyc
../celery/backends/cassandra.pyc
../celery/backends/cache.pyc
../celery/backends/amqp.pyc
../celery/backends/pyredis.pyc
../celery/backends/redis.pyc
../celery/backends/tyrant.pyc
../celery/backends/base.pyc
../celery/backends/__init__.pyc
../celery/backends/database.pyc
../celery/backends/mongodb.pyc
../celery/utils/timer2.pyc
../celery/utils/encoding.pyc
../celery/utils/functional.pyc
../celery/utils/mail.pyc
../celery/utils/__init__.pyc
../celery/utils/term.pyc
../celery/utils/threads.pyc
../celery/utils/compat.pyc
../celery/utils/serialization.pyc
../celery/utils/patch.pyc
../celery/utils/timeutils.pyc
../celery/events/state.pyc
../celery/events/dumper.pyc
../celery/events/cursesmon.pyc
../celery/events/snapshot.pyc
../celery/events/__init__.pyc
../celery/execute/trace.pyc
../celery/execute/__init__.pyc
../celery/apps/worker.pyc
../celery/apps/__init__.pyc
../celery/apps/beat.pyc
../celery/db/dfd042c7.pyc
../celery/db/a805d4bd.pyc
../celery/db/session.pyc
../celery/db/__init__.pyc
../celery/db/models.pyc
../celery/bin/celeryev.pyc
../celery/bin/celeryd_detach.pyc
../celery/bin/camqadm.pyc
../celery/bin/base.pyc
../celery/bin/__init__.pyc
../celery/bin/celeryd_multi.pyc
../celery/bin/celerybeat.pyc
../celery/bin/celeryctl.pyc
../celery/bin/celeryd.pyc
../celery/security/key.pyc
../celery/security/certificate.pyc
../celery/security/__init__.pyc
../celery/security/serialization.pyc
../celery/tests/config.pyc
../celery/tests/utils.pyc
../celery/tests/__init__.pyc
../celery/tests/compat.pyc
../celery/task/chords.pyc
../celery/task/sets.pyc
../celery/task/http.pyc
../celery/task/schedules.pyc
../celery/task/control.pyc
../celery/task/base.pyc
../celery/task/__init__.pyc
../celery/concurrency/solo.pyc
../celery/concurrency/gevent.pyc
../celery/concurrency/base.pyc
../celery/concurrency/__init__.pyc
../celery/concurrency/threads.pyc
../celery/concurrency/eventlet.pyc
../celery/app/abstract.pyc
../celery/app/amqp.pyc
../celery/app/base.pyc
../celery/app/__init__.pyc
../celery/app/defaults.pyc
../celery/app/annotations.pyc
../celery/loaders/base.pyc
../celery/loaders/__init__.pyc
../celery/loaders/app.pyc
../celery/loaders/default.pyc
../celery/utils/dispatch/__init__.pyc
../celery/utils/dispatch/signal.pyc
../celery/utils/dispatch/saferef.pyc
../celery/tests/test_utils/test_timer2.pyc
../celery/tests/test_utils/test_pickle.pyc
../celery/tests/test_utils/test_utils_encoding.pyc
../celery/tests/test_utils/test_utils_timeutils.pyc
../celery/tests/test_utils/test_datastructures.pyc
../celery/tests/test_utils/test_serialization.pyc
../celery/tests/test_utils/__init__.pyc
../celery/tests/test_utils/test_utils_info.pyc
../celery/tests/test_worker/test_worker_job.pyc
../celery/tests/test_worker/test_worker_heartbeat.pyc
../celery/tests/test_worker/test_worker_state.pyc
../celery/tests/test_worker/test_worker_autoscale.pyc
../celery/tests/test_worker/test_worker_mediator.pyc
../celery/tests/test_worker/test_worker_revoke.pyc
../celery/tests/test_worker/test_bootsteps.pyc
../celery/tests/test_worker/__init__.pyc
../celery/tests/test_worker/test_worker_control.pyc
../celery/tests/test_compat/test_messaging.pyc
../celery/tests/test_compat/__init__.pyc
../celery/tests/test_compat/test_decorators.pyc
../celery/tests/functional/case.pyc
../celery/tests/functional/tasks.pyc
../celery/tests/functional/__init__.pyc
../celery/tests/test_backends/test_mongodb.pyc
../celery/tests/test_backends/test_redis_unit.pyc
../celery/tests/test_backends/test_base.pyc
../celery/tests/test_backends/test_cache.pyc
../celery/tests/test_backends/test_redis.pyc
../celery/tests/test_backends/test_amqp.pyc
../celery/tests/test_backends/test_tyrant.pyc
../celery/tests/test_backends/test_database.pyc
../celery/tests/test_backends/__init__.pyc
../celery/tests/test_backends/test_pyredis_compat.pyc
../celery/tests/test_concurrency/test_concurrency_solo.pyc
../celery/tests/test_concurrency/test_concurrency_eventlet.pyc
../celery/tests/test_concurrency/__init__.pyc
../celery/tests/test_concurrency/test_concurrency_processes.pyc
../celery/tests/test_concurrency/test_concurrency_gevent.pyc
../celery/tests/test_concurrency/test_pool.pyc
../celery/tests/test_events/test_events_state.pyc
../celery/tests/test_events/test_events_cursesmon.pyc
../celery/tests/test_events/test_events_snapshot.pyc
../celery/tests/test_events/__init__.pyc
../celery/tests/test_slow/test_buckets.pyc
../celery/tests/test_slow/__init__.pyc
../celery/tests/test_bin/test_celeryev.pyc
../celery/tests/test_bin/test_celeryd.pyc
../celery/tests/test_bin/__init__.pyc
../celery/tests/test_bin/test_celerybeat.pyc
../celery/tests/test_security/case.pyc
../celery/tests/test_security/test_key.pyc
../celery/tests/test_security/test_serialization.pyc
../celery/tests/test_security/__init__.pyc
../celery/tests/test_security/test_certificate.pyc
../celery/tests/test_task/test_execute_trace.pyc
../celery/tests/test_task/test_result.pyc
../celery/tests/test_task/test_task_http.pyc
../celery/tests/test_task/test_task_abortable.pyc
../celery/tests/test_task/test_task_builtins.pyc
../celery/tests/test_task/test_states.pyc
../celery/tests/test_task/__init__.pyc
../celery/tests/test_task/test_chord.pyc
../celery/tests/test_task/test_registry.pyc
../celery/tests/test_task/test_context.pyc
../celery/tests/test_task/test_task_control.pyc
../celery/tests/test_task/test_task_sets.pyc
../celery/tests/test_app/test_app_amqp.pyc
../celery/tests/test_app/test_routes.pyc
../celery/tests/test_app/test_annotations.pyc
../celery/tests/test_app/test_app_defaults.pyc
../celery/tests/test_app/test_actors.pyc
../celery/tests/test_app/__init__.pyc
../celery/tests/test_app/test_loaders.pyc
../celery/tests/test_app/test_log.pyc
../celery/tests/test_app/test_beat.pyc
../celery/tests/test_app/test_celery.pyc
../celery/concurrency/processes/pool.pyc
../celery/concurrency/processes/process.pyc
../celery/concurrency/processes/__init__.pyc
../celery/concurrency/processes/forking.pyc
../celery/concurrency/processes/_win.pyc
../celery/app/task/__init__.pyc
./
top_level.txt
SOURCES.txt
not-zip-safe
entry_points.txt
PKG-INFO
requires.txt
dependency_links.txt
../../../bin/celeryctl
../../../bin/celeryd
../../../bin/camqadm
../../../bin/celeryev
../../../bin/celeryd-multi
../../../bin/celerybeat

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,5 +0,0 @@
importlib
anyjson>=0.3.1
kombu>=2.1.1,<3.0
python-dateutil>=1.5.0,<2.0.0
ordereddict

Просмотреть файл

@ -1 +0,0 @@
celery

Просмотреть файл

@ -1,365 +0,0 @@
Metadata-Version: 1.0
Name: celery
Version: 2.5.5
Summary: Distributed Task Queue
Home-page: http://celeryproject.org
Author: Ask Solem
Author-email: ask@celeryproject.org
License: BSD
Description: =================================
celery - Distributed Task Queue
=================================
.. image:: http://cloud.github.com/downloads/ask/celery/celery_128.png
:Version: 2.5.5
:Web: http://celeryproject.org/
:Download: http://pypi.python.org/pypi/celery/
:Source: http://github.com/celery/celery/
:Keywords: task queue, job queue, asynchronous, rabbitmq, amqp, redis,
python, webhooks, queue, distributed
--
Celery is an open source asynchronous task queue/job queue based on
distributed message passing.
It is focused on real-time operation, but supports scheduling as well.
The execution units, called tasks, are executed concurrently on one or
more worker nodes using multiprocessing, `Eventlet`_ or `gevent`_. Tasks can
execute asynchronously (in the background) or synchronously
(wait until ready).
Celery is used in production systems to process millions of tasks every hour.
Celery is written in Python, but the protocol can be implemented in any
language. It can also `operate with other languages using webhooks`_.
There's also `RCelery`_ for the Ruby programming language, and a `PHP client`_.
The recommended message broker is `RabbitMQ`_, but support for
`Redis`_, `MongoDB`_, `Beanstalk`_, `Amazon SQS`_, `CouchDB`_ and
databases (using `SQLAlchemy`_ or the `Django ORM`_) is also available.
Celery is easy to integrate with web frameworks, some of which even have
integration packages:
+-----------------+------------------------+
| `Django`_ | `django-celery`_ |
+-----------------+------------------------+
| `Pyramid`_ | `pyramid_celery`_ |
+-----------------+------------------------+
| `Pylons`_ | `celery-pylons`_ |
+-----------------+------------------------+
| `Flask`_ | `flask-celery`_ |
+-----------------+------------------------+
| `web2py`_ | `web2py-celery`_ |
+-----------------+------------------------+
.. _`RCelery`: http://leapfrogdevelopment.github.com/rcelery/
.. _`PHP client`: https://github.com/gjedeer/celery-php
.. _`RabbitMQ`: http://www.rabbitmq.com/
.. _`Redis`: http://code.google.com/p/redis/
.. _`SQLAlchemy`: http://www.sqlalchemy.org/
.. _`Django`: http://djangoproject.com/
.. _`Django ORM`: http://djangoproject.com/
.. _`Eventlet`: http://eventlet.net/
.. _`gevent`: http://gevent.org/
.. _`Beanstalk`: http://kr.github.com/beanstalkd/
.. _`MongoDB`: http://mongodb.org/
.. _`CouchDB`: http://couchdb.apache.org/
.. _`Amazon SQS`: http://aws.amazon.com/sqs/
.. _`Pylons`: http://pylonshq.com/
.. _`Flask`: http://flask.pocoo.org/
.. _`web2py`: http://web2py.com/
.. _`Pyramid`: http://docs.pylonsproject.org/en/latest/docs/pyramid.html
.. _`pyramid_celery`: http://pypi.python.org/pypi/pyramid_celery/
.. _`django-celery`: http://pypi.python.org/pypi/django-celery
.. _`celery-pylons`: http://pypi.python.org/pypi/celery-pylons
.. _`flask-celery`: http://github.com/celery/flask-celery/
.. _`web2py-celery`: http://code.google.com/p/web2py-celery/
.. _`operate with other languages using webhooks`:
http://celery.github.com/celery/userguide/remote-tasks.html
Overview
========
This is a high level overview of the architecture.
.. image:: http://cloud.github.com/downloads/ask/celery/Celery-Overview-v4.jpg
The broker delivers tasks to the worker nodes.
A worker node is a networked machine running `celeryd`. This can be one or
more machines depending on the workload.
The result of the task can be stored for later retrieval (called its
"tombstone").
Example
=======
You probably want to see some code by now, so here's an example task
adding two numbers:
::
from celery.task import task
@task
def add(x, y):
return x + y
You can execute the task in the background, or wait for it to finish::
>>> result = add.delay(4, 4)
>>> result.wait() # wait for and return the result
8
Simple!
Features
========
+-----------------+----------------------------------------------------+
| Messaging | Supported brokers include `RabbitMQ`_, `Redis`_, |
| | `Beanstalk`_, `MongoDB`_, `CouchDB`_, and popular |
| | SQL databases. |
+-----------------+----------------------------------------------------+
| Fault-tolerant | Excellent configurable error recovery when using |
| | `RabbitMQ`, ensures your tasks are never lost. |
+-----------------+----------------------------------------------------+
| Distributed | Runs on one or more machines. Supports |
| | broker `clustering`_ and `HA`_ when used in |
| | combination with `RabbitMQ`_. You can set up new |
| | workers without central configuration (e.g. use |
| | your grandma's laptop to help if the queue is |
| | temporarily congested). |
+-----------------+----------------------------------------------------+
| Concurrency | Concurrency is achieved by using multiprocessing, |
| | `Eventlet`_, `gevent` or a mix of these. |
+-----------------+----------------------------------------------------+
| Scheduling | Supports recurring tasks like cron, or specifying |
| | an exact date or countdown for when after the task |
| | should be executed. |
+-----------------+----------------------------------------------------+
| Latency | Low latency means you are able to execute tasks |
| | *while the user is waiting*. |
+-----------------+----------------------------------------------------+
| Return Values | Task return values can be saved to the selected |
| | result store backend. You can wait for the result, |
| | retrieve it later, or ignore it. |
+-----------------+----------------------------------------------------+
| Result Stores | Database, `MongoDB`_, `Redis`_, |
| | `Cassandra`, or `AMQP`_ (message notification). |
+-----------------+----------------------------------------------------+
| Webhooks | Your tasks can also be HTTP callbacks, enabling |
| | cross-language communication. |
+-----------------+----------------------------------------------------+
| Rate limiting | Supports rate limiting by using the token bucket |
| | algorithm, which accounts for bursts of traffic. |
| | Rate limits can be set for each task type, or |
| | globally for all. |
+-----------------+----------------------------------------------------+
| Routing | Using AMQP's flexible routing model you can route |
| | tasks to different workers, or select different |
| | message topologies, by configuration or even at |
| | runtime. |
+-----------------+----------------------------------------------------+
| Remote-control | Worker nodes can be controlled from remote by |
| | using broadcast messaging. A range of built-in |
| | commands exist in addition to the ability to |
| | easily define your own. (AMQP/Redis only) |
+-----------------+----------------------------------------------------+
| Monitoring | You can capture everything happening with the |
| | workers in real-time by subscribing to events. |
| | A real-time web monitor is in development. |
+-----------------+----------------------------------------------------+
| Serialization | Supports Pickle, JSON, YAML, or easily defined |
| | custom schemes. One task invocation can have a |
| | different scheme than another. |
+-----------------+----------------------------------------------------+
| Tracebacks | Errors and tracebacks are stored and can be |
| | investigated after the fact. |
+-----------------+----------------------------------------------------+
| UUID | Every task has an UUID (Universally Unique |
| | Identifier), which is the task id used to query |
| | task status and return value. |
+-----------------+----------------------------------------------------+
| Retries | Tasks can be retried if they fail, with |
| | configurable maximum number of retries, and delays |
| | between each retry. |
+-----------------+----------------------------------------------------+
| Task Sets | A Task set is a task consisting of several |
| | sub-tasks. You can find out how many, or if all |
| | of the sub-tasks has been executed, and even |
| | retrieve the results in order. Progress bars, |
| | anyone? |
+-----------------+----------------------------------------------------+
| Made for Web | You can query status and results via URLs, |
| | enabling the ability to poll task status using |
| | Ajax. |
+-----------------+----------------------------------------------------+
| Error Emails | Can be configured to send emails to the |
| | administrators when tasks fails. |
+-----------------+----------------------------------------------------+
.. _`clustering`: http://www.rabbitmq.com/clustering.html
.. _`HA`: http://www.rabbitmq.com/pacemaker.html
.. _`AMQP`: http://www.amqp.org/
Documentation
=============
Documentation for the production version can be found here:
http://docs.celeryproject.org/en/latest
and the documentation for the development version can be found here:
http://celery.github.com/celery/
Installation
============
You can install Celery either via the Python Package Index (PyPI)
or from source.
To install using `pip`,::
$ pip install -U Celery
To install using `easy_install`,::
$ easy_install -U Celery
Bundles
-------
Celery also defines a group of bundles that can be used
to install Celery and the dependencies for a given feature.
The following bundles are available:
:`celery-with-redis`_:
for using Redis as a broker.
:`celery-with-mongodb`_:
for using MongoDB as a broker.
:`django-celery-with-redis`_:
for Django, and using Redis as a broker.
:`django-celery-with-mongodb`_:
for Django, and using MongoDB as a broker.
:`bundle-celery`_:
convenience bundle installing *Celery* and related packages.
.. _`celery-with-redis`:
http://pypi.python.org/pypi/celery-with-redis/
.. _`celery-with-mongodb`:
http://pypi.python.org/pypi/celery-with-mongdb/
.. _`django-celery-with-redis`:
http://pypi.python.org/pypi/django-celery-with-redis/
.. _`django-celery-with-mongodb`:
http://pypi.python.org/pypi/django-celery-with-mongdb/
.. _`bundle-celery`:
http://pypi.python.org/pypi/bundle-celery/
Downloading and installing from source
--------------------------------------
Download the latest version of Celery from
http://pypi.python.org/pypi/celery/
You can install it by doing the following,::
$ tar xvfz celery-0.0.0.tar.gz
$ cd celery-0.0.0
$ python setup.py build
# python setup.py install # as root
Using the development version
-----------------------------
You can clone the repository by doing the following::
$ git clone git://github.com/celery/celery.git
Getting Help
============
Mailing list
------------
For discussions about the usage, development, and future of celery,
please join the `celery-users`_ mailing list.
.. _`celery-users`: http://groups.google.com/group/celery-users/
IRC
---
Come chat with us on IRC. The **#celery** channel is located at the `Freenode`_
network.
.. _`Freenode`: http://freenode.net
Bug tracker
===========
If you have any suggestions, bug reports or annoyances please report them
to our issue tracker at http://github.com/celery/celery/issues/
Wiki
====
http://wiki.github.com/celery/celery/
Contributing
============
Development of `celery` happens at Github: http://github.com/celery/celery
You are highly encouraged to participate in the development
of `celery`. If you don't like Github (for some reason) you're welcome
to send regular patches.
Be sure to also read the `Contributing to Celery`_ section in the
documentation.
.. _`Contributing to Celery`: http://celery.github.com/celery/contributing.html
License
=======
This software is licensed under the `New BSD License`. See the ``LICENSE``
file in the top distribution directory for the full license text.
.. # vim: syntax=rst expandtab tabstop=4 shiftwidth=4 shiftround
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
Classifier: Topic :: System :: Distributed Computing
Classifier: Topic :: Software Development :: Object Brokering
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: Implementation :: Jython
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS :: MacOS X

Просмотреть файл

@ -1,468 +0,0 @@
AUTHORS
Changelog
FAQ
INSTALL
LICENSE
MANIFEST.in
README
README.rst
THANKS
TODO
setup.cfg
setup.py
celery/__init__.py
celery/abstract.py
celery/actors.py
celery/beat.py
celery/conf.py
celery/datastructures.py
celery/decorators.py
celery/exceptions.py
celery/local.py
celery/log.py
celery/messaging.py
celery/platforms.py
celery/registry.py
celery/result.py
celery/routes.py
celery/schedules.py
celery/signals.py
celery/states.py
celery.egg-info/PKG-INFO
celery.egg-info/SOURCES.txt
celery.egg-info/dependency_links.txt
celery.egg-info/entry_points.txt
celery.egg-info/not-zip-safe
celery.egg-info/requires.txt
celery.egg-info/top_level.txt
celery/app/__init__.py
celery/app/abstract.py
celery/app/amqp.py
celery/app/annotations.py
celery/app/base.py
celery/app/defaults.py
celery/app/task/__init__.py
celery/apps/__init__.py
celery/apps/beat.py
celery/apps/worker.py
celery/backends/__init__.py
celery/backends/amqp.py
celery/backends/base.py
celery/backends/cache.py
celery/backends/cassandra.py
celery/backends/database.py
celery/backends/mongodb.py
celery/backends/pyredis.py
celery/backends/redis.py
celery/backends/tyrant.py
celery/bin/__init__.py
celery/bin/base.py
celery/bin/camqadm.py
celery/bin/celerybeat.py
celery/bin/celeryctl.py
celery/bin/celeryd.py
celery/bin/celeryd_detach.py
celery/bin/celeryd_multi.py
celery/bin/celeryev.py
celery/concurrency/__init__.py
celery/concurrency/base.py
celery/concurrency/eventlet.py
celery/concurrency/gevent.py
celery/concurrency/solo.py
celery/concurrency/threads.py
celery/concurrency/processes/__init__.py
celery/concurrency/processes/_win.py
celery/concurrency/processes/forking.py
celery/concurrency/processes/pool.py
celery/concurrency/processes/process.py
celery/contrib/__init__.py
celery/contrib/abortable.py
celery/contrib/batches.py
celery/contrib/bundles.py
celery/contrib/migrate.py
celery/contrib/rdb.py
celery/db/__init__.py
celery/db/a805d4bd.py
celery/db/dfd042c7.py
celery/db/models.py
celery/db/session.py
celery/events/__init__.py
celery/events/cursesmon.py
celery/events/dumper.py
celery/events/snapshot.py
celery/events/state.py
celery/execute/__init__.py
celery/execute/trace.py
celery/loaders/__init__.py
celery/loaders/app.py
celery/loaders/base.py
celery/loaders/default.py
celery/security/__init__.py
celery/security/certificate.py
celery/security/key.py
celery/security/serialization.py
celery/task/__init__.py
celery/task/base.py
celery/task/chords.py
celery/task/control.py
celery/task/http.py
celery/task/schedules.py
celery/task/sets.py
celery/tests/__init__.py
celery/tests/compat.py
celery/tests/config.py
celery/tests/utils.py
celery/tests/functional/__init__.py
celery/tests/functional/case.py
celery/tests/functional/tasks.py
celery/tests/test_app/__init__.py
celery/tests/test_app/test_actors.py
celery/tests/test_app/test_annotations.py
celery/tests/test_app/test_app_amqp.py
celery/tests/test_app/test_app_defaults.py
celery/tests/test_app/test_beat.py
celery/tests/test_app/test_celery.py
celery/tests/test_app/test_loaders.py
celery/tests/test_app/test_log.py
celery/tests/test_app/test_routes.py
celery/tests/test_backends/__init__.py
celery/tests/test_backends/test_amqp.py
celery/tests/test_backends/test_base.py
celery/tests/test_backends/test_cache.py
celery/tests/test_backends/test_database.py
celery/tests/test_backends/test_mongodb.py
celery/tests/test_backends/test_pyredis_compat.py
celery/tests/test_backends/test_redis.py
celery/tests/test_backends/test_redis_unit.py
celery/tests/test_backends/test_tyrant.py
celery/tests/test_bin/__init__.py
celery/tests/test_bin/test_celerybeat.py
celery/tests/test_bin/test_celeryd.py
celery/tests/test_bin/test_celeryev.py
celery/tests/test_compat/__init__.py
celery/tests/test_compat/test_decorators.py
celery/tests/test_compat/test_messaging.py
celery/tests/test_concurrency/__init__.py
celery/tests/test_concurrency/test_concurrency_eventlet.py
celery/tests/test_concurrency/test_concurrency_gevent.py
celery/tests/test_concurrency/test_concurrency_processes.py
celery/tests/test_concurrency/test_concurrency_solo.py
celery/tests/test_concurrency/test_pool.py
celery/tests/test_events/__init__.py
celery/tests/test_events/test_events_cursesmon.py
celery/tests/test_events/test_events_snapshot.py
celery/tests/test_events/test_events_state.py
celery/tests/test_security/__init__.py
celery/tests/test_security/case.py
celery/tests/test_security/test_certificate.py
celery/tests/test_security/test_key.py
celery/tests/test_security/test_serialization.py
celery/tests/test_slow/__init__.py
celery/tests/test_slow/test_buckets.py
celery/tests/test_task/__init__.py
celery/tests/test_task/test_chord.py
celery/tests/test_task/test_context.py
celery/tests/test_task/test_execute_trace.py
celery/tests/test_task/test_registry.py
celery/tests/test_task/test_result.py
celery/tests/test_task/test_states.py
celery/tests/test_task/test_task_abortable.py
celery/tests/test_task/test_task_builtins.py
celery/tests/test_task/test_task_control.py
celery/tests/test_task/test_task_http.py
celery/tests/test_task/test_task_sets.py
celery/tests/test_utils/__init__.py
celery/tests/test_utils/test_datastructures.py
celery/tests/test_utils/test_pickle.py
celery/tests/test_utils/test_serialization.py
celery/tests/test_utils/test_timer2.py
celery/tests/test_utils/test_utils_encoding.py
celery/tests/test_utils/test_utils_info.py
celery/tests/test_utils/test_utils_timeutils.py
celery/tests/test_worker/__init__.py
celery/tests/test_worker/test_bootsteps.py
celery/tests/test_worker/test_worker_autoscale.py
celery/tests/test_worker/test_worker_control.py
celery/tests/test_worker/test_worker_heartbeat.py
celery/tests/test_worker/test_worker_job.py
celery/tests/test_worker/test_worker_mediator.py
celery/tests/test_worker/test_worker_revoke.py
celery/tests/test_worker/test_worker_state.py
celery/utils/__init__.py
celery/utils/compat.py
celery/utils/encoding.py
celery/utils/functional.py
celery/utils/mail.py
celery/utils/patch.py
celery/utils/serialization.py
celery/utils/term.py
celery/utils/threads.py
celery/utils/timer2.py
celery/utils/timeutils.py
celery/utils/dispatch/__init__.py
celery/utils/dispatch/saferef.py
celery/utils/dispatch/signal.py
celery/worker/__init__.py
celery/worker/autoreload.py
celery/worker/autoscale.py
celery/worker/buckets.py
celery/worker/consumer.py
celery/worker/control.py
celery/worker/heartbeat.py
celery/worker/job.py
celery/worker/mediator.py
celery/worker/state.py
celery/worker/strategy.py
contrib/bundles/generate.py
contrib/centos/celeryd.init
contrib/centos/celeryd.sysconfig
contrib/debian/README.rst
contrib/debian/init.d-deprecated/celerybeat
contrib/debian/init.d-deprecated/celeryd
contrib/debian/init.d-deprecated/celeryevcam
contrib/generic-init.d/celerybeat
contrib/generic-init.d/celeryd
contrib/generic-init.d/celeryevcam
contrib/logtools/find-unprocessed-tasks-debug.sh
contrib/logtools/find-unprocessed-tasks.sh
contrib/logtools/periodic-task-runtimes.sh
contrib/mac/org.celeryq.celerybeat.plist
contrib/mac/org.celeryq.celeryd.plist
contrib/mac/org.celeryq.celerymon.plist
contrib/mac/watch-workers.applescript
contrib/release/attribution.py
contrib/release/bump_version.py
contrib/release/core-modules.txt
contrib/release/doc4allmods
contrib/release/py3k-run-tests
contrib/release/removepyc.sh
contrib/release/sphinx-to-rst.py
contrib/release/verify-reference-index.sh
contrib/release/verify_config_reference.py
contrib/supervisord/celerybeat.conf
contrib/supervisord/celeryd.conf
contrib/supervisord/supervisord.conf
docs/Makefile
docs/changelog.rst
docs/community.rst
docs/conf.py
docs/configuration.rst
docs/contributing.rst
docs/faq.rst
docs/index.rst
docs/whatsnew-2.5.rst
docs/.static/.keep
docs/.templates/page.html
docs/.templates/sidebarintro.html
docs/.templates/sidebarlogo.html
docs/_ext/applyxrefs.py
docs/_ext/celerydocs.py
docs/_ext/literals_to_xrefs.py
docs/_theme/celery/theme.conf
docs/_theme/celery/static/celery.css_t
docs/cookbook/daemonizing.rst
docs/cookbook/index.rst
docs/cookbook/tasks.rst
docs/django/first-steps-with-django.rst
docs/django/index.rst
docs/django/unit-testing.rst
docs/getting-started/first-steps-with-celery.rst
docs/getting-started/index.rst
docs/getting-started/introduction.rst
docs/getting-started/resources.rst
docs/getting-started/brokers/beanstalk.rst
docs/getting-started/brokers/couchdb.rst
docs/getting-started/brokers/django.rst
docs/getting-started/brokers/index.rst
docs/getting-started/brokers/mongodb.rst
docs/getting-started/brokers/rabbitmq.rst
docs/getting-started/brokers/redis.rst
docs/getting-started/brokers/sqlalchemy.rst
docs/images/Celery-Overview-v4.jpg
docs/images/Celery1.0-inside-worker.jpg
docs/images/celery-broker-worker-nodes.jpg
docs/images/celery-broker-worker-relationship.jpg
docs/images/celery-icon-128.png
docs/images/celery-icon-32.png
docs/images/celery-icon-64.png
docs/images/celery-worker-bindings.jpg
docs/images/celery_128.png
docs/images/celery_512.png
docs/images/celery_favicon_128.png
docs/images/celeryevshotsm.jpg
docs/images/djangoceleryadmin2.jpg
docs/images/favicon.ico
docs/images/favicon.png
docs/includes/installation.txt
docs/includes/introduction.txt
docs/includes/resources.txt
docs/internals/app-overview.rst
docs/internals/deprecation.rst
docs/internals/guide.rst
docs/internals/index.rst
docs/internals/protocol.rst
docs/internals/worker.rst
docs/internals/reference/celery.abstract.rst
docs/internals/reference/celery.app.abstract.rst
docs/internals/reference/celery.app.annotations.rst
docs/internals/reference/celery.backends.amqp.rst
docs/internals/reference/celery.backends.base.rst
docs/internals/reference/celery.backends.cache.rst
docs/internals/reference/celery.backends.cassandra.rst
docs/internals/reference/celery.backends.database.rst
docs/internals/reference/celery.backends.mongodb.rst
docs/internals/reference/celery.backends.redis.rst
docs/internals/reference/celery.backends.rst
docs/internals/reference/celery.backends.tyrant.rst
docs/internals/reference/celery.beat.rst
docs/internals/reference/celery.concurrency.base.rst
docs/internals/reference/celery.concurrency.eventlet.rst
docs/internals/reference/celery.concurrency.gevent.rst
docs/internals/reference/celery.concurrency.processes.pool.rst
docs/internals/reference/celery.concurrency.processes.rst
docs/internals/reference/celery.concurrency.rst
docs/internals/reference/celery.concurrency.solo.rst
docs/internals/reference/celery.concurrency.threads.rst
docs/internals/reference/celery.datastructures.rst
docs/internals/reference/celery.db.models.rst
docs/internals/reference/celery.db.session.rst
docs/internals/reference/celery.events.cursesmon.rst
docs/internals/reference/celery.events.dumper.rst
docs/internals/reference/celery.events.snapshot.rst
docs/internals/reference/celery.execute.trace.rst
docs/internals/reference/celery.log.rst
docs/internals/reference/celery.platforms.rst
docs/internals/reference/celery.routes.rst
docs/internals/reference/celery.security.certificate.rst
docs/internals/reference/celery.security.key.rst
docs/internals/reference/celery.security.serialization.rst
docs/internals/reference/celery.utils.compat.rst
docs/internals/reference/celery.utils.dispatch.rst
docs/internals/reference/celery.utils.dispatch.saferef.rst
docs/internals/reference/celery.utils.dispatch.signal.rst
docs/internals/reference/celery.utils.encoding.rst
docs/internals/reference/celery.utils.functional.rst
docs/internals/reference/celery.utils.patch.rst
docs/internals/reference/celery.utils.rst
docs/internals/reference/celery.utils.serialization.rst
docs/internals/reference/celery.utils.term.rst
docs/internals/reference/celery.utils.threads.rst
docs/internals/reference/celery.utils.timer2.rst
docs/internals/reference/celery.utils.timeutils.rst
docs/internals/reference/celery.worker.autoreload.rst
docs/internals/reference/celery.worker.autoscale.rst
docs/internals/reference/celery.worker.buckets.rst
docs/internals/reference/celery.worker.consumer.rst
docs/internals/reference/celery.worker.heartbeat.rst
docs/internals/reference/celery.worker.job.rst
docs/internals/reference/celery.worker.mediator.rst
docs/internals/reference/celery.worker.rst
docs/internals/reference/celery.worker.state.rst
docs/internals/reference/celery.worker.strategy.rst
docs/internals/reference/index.rst
docs/reference/celery.actors.rst
docs/reference/celery.app.amqp.rst
docs/reference/celery.app.defaults.rst
docs/reference/celery.app.rst
docs/reference/celery.app.task.rst
docs/reference/celery.apps.beat.rst
docs/reference/celery.apps.worker.rst
docs/reference/celery.bin.base.rst
docs/reference/celery.bin.camqadm.rst
docs/reference/celery.bin.celerybeat.rst
docs/reference/celery.bin.celeryctl.rst
docs/reference/celery.bin.celeryd.rst
docs/reference/celery.bin.celeryd_multi.rst
docs/reference/celery.bin.celeryev.rst
docs/reference/celery.contrib.abortable.rst
docs/reference/celery.contrib.batches.rst
docs/reference/celery.contrib.migrate.rst
docs/reference/celery.contrib.rdb.rst
docs/reference/celery.events.rst
docs/reference/celery.events.state.rst
docs/reference/celery.exceptions.rst
docs/reference/celery.loaders.app.rst
docs/reference/celery.loaders.base.rst
docs/reference/celery.loaders.default.rst
docs/reference/celery.loaders.rst
docs/reference/celery.registry.rst
docs/reference/celery.result.rst
docs/reference/celery.schedules.rst
docs/reference/celery.security.rst
docs/reference/celery.signals.rst
docs/reference/celery.states.rst
docs/reference/celery.task.base.rst
docs/reference/celery.task.chords.rst
docs/reference/celery.task.control.rst
docs/reference/celery.task.http.rst
docs/reference/celery.task.rst
docs/reference/celery.task.sets.rst
docs/reference/celery.utils.mail.rst
docs/reference/index.rst
docs/releases/1.0/announcement.rst
docs/sec/CELERYSA-0001.txt
docs/slidesource/slide-example1-result.py
docs/slidesource/slide-example1.py
docs/templates/readme.txt
docs/tutorials/clickcounter.rst
docs/tutorials/debugging.rst
docs/tutorials/index.rst
docs/tutorials/otherqueues.rst
docs/userguide/executing.rst
docs/userguide/index.rst
docs/userguide/monitoring.rst
docs/userguide/optimizing.rst
docs/userguide/overview.rst
docs/userguide/periodic-tasks.rst
docs/userguide/remote-tasks.rst
docs/userguide/routing.rst
docs/userguide/security.rst
docs/userguide/signals.rst
docs/userguide/tasks.rst
docs/userguide/tasksets.rst
docs/userguide/workers.rst
docs/userguide/concurrency/eventlet.rst
docs/userguide/concurrency/index.rst
examples/README.rst
examples/app/myapp.py
examples/celery_http_gateway/README.rst
examples/celery_http_gateway/__init__.py
examples/celery_http_gateway/manage.py
examples/celery_http_gateway/settings.py
examples/celery_http_gateway/tasks.py
examples/celery_http_gateway/urls.py
examples/eventlet/README.rst
examples/eventlet/bulk_task_producer.py
examples/eventlet/celeryconfig.py
examples/eventlet/tasks.py
examples/eventlet/webcrawler.py
examples/gevent/celeryconfig.py
examples/gevent/tasks.py
examples/httpexample/README.rst
examples/httpexample/__init__.py
examples/httpexample/manage.py
examples/httpexample/settings.py
examples/httpexample/urls.py
examples/httpexample/views.py
examples/pythonproject/demoapp/README.rst
examples/pythonproject/demoapp/__init__.py
examples/pythonproject/demoapp/celeryconfig.py
examples/pythonproject/demoapp/tasks.py
examples/pythonproject/demoapp/test.py
examples/resultgraph/tasks.py
funtests/setup.py
funtests/benchmarks/bench_worker.py
funtests/suite/__init__.py
funtests/suite/config.py
funtests/suite/test_basic.py
funtests/suite/test_leak.py
requirements/default-py3k.txt
requirements/default.txt
requirements/docs.txt
requirements/pkgutils.txt
requirements/py25.txt
requirements/py26.txt
requirements/security.txt
requirements/test-py3k.txt
requirements/test-pypy.txt
requirements/test.txt

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,11 +0,0 @@
[console_scripts]
celeryctl = celery.bin.celeryctl:main
celeryd = celery.bin.celeryd:main
camqadm = celery.bin.camqadm:main
celeryev = celery.bin.celeryev:main
celeryd-multi = celery.bin.celeryd_multi:main
celerybeat = celery.bin.celerybeat:main
[bundle.bundles]
celery = celery.contrib.bundles:bundles

Просмотреть файл

@ -1,406 +0,0 @@
../celery/conf.py
../celery/abstract.py
../celery/states.py
../celery/decorators.py
../celery/local.py
../celery/exceptions.py
../celery/messaging.py
../celery/schedules.py
../celery/routes.py
../celery/__init__.py
../celery/platforms.py
../celery/signals.py
../celery/beat.py
../celery/result.py
../celery/registry.py
../celery/log.py
../celery/actors.py
../celery/datastructures.py
../celery/worker/mediator.py
../celery/worker/buckets.py
../celery/worker/state.py
../celery/worker/heartbeat.py
../celery/worker/strategy.py
../celery/worker/control.py
../celery/worker/__init__.py
../celery/worker/job.py
../celery/worker/consumer.py
../celery/worker/autoscale.py
../celery/worker/autoreload.py
../celery/contrib/batches.py
../celery/contrib/abortable.py
../celery/contrib/__init__.py
../celery/contrib/migrate.py
../celery/contrib/rdb.py
../celery/contrib/bundles.py
../celery/backends/cassandra.py
../celery/backends/cache.py
../celery/backends/amqp.py
../celery/backends/pyredis.py
../celery/backends/redis.py
../celery/backends/tyrant.py
../celery/backends/base.py
../celery/backends/__init__.py
../celery/backends/database.py
../celery/backends/mongodb.py
../celery/utils/timer2.py
../celery/utils/encoding.py
../celery/utils/functional.py
../celery/utils/mail.py
../celery/utils/__init__.py
../celery/utils/term.py
../celery/utils/threads.py
../celery/utils/compat.py
../celery/utils/serialization.py
../celery/utils/patch.py
../celery/utils/timeutils.py
../celery/events/state.py
../celery/events/dumper.py
../celery/events/cursesmon.py
../celery/events/snapshot.py
../celery/events/__init__.py
../celery/execute/trace.py
../celery/execute/__init__.py
../celery/apps/worker.py
../celery/apps/__init__.py
../celery/apps/beat.py
../celery/db/dfd042c7.py
../celery/db/a805d4bd.py
../celery/db/session.py
../celery/db/__init__.py
../celery/db/models.py
../celery/bin/celeryev.py
../celery/bin/celeryd_detach.py
../celery/bin/camqadm.py
../celery/bin/base.py
../celery/bin/__init__.py
../celery/bin/celeryd_multi.py
../celery/bin/celerybeat.py
../celery/bin/celeryctl.py
../celery/bin/celeryd.py
../celery/security/key.py
../celery/security/certificate.py
../celery/security/__init__.py
../celery/security/serialization.py
../celery/tests/config.py
../celery/tests/utils.py
../celery/tests/__init__.py
../celery/tests/compat.py
../celery/task/chords.py
../celery/task/sets.py
../celery/task/http.py
../celery/task/schedules.py
../celery/task/control.py
../celery/task/base.py
../celery/task/__init__.py
../celery/concurrency/solo.py
../celery/concurrency/gevent.py
../celery/concurrency/base.py
../celery/concurrency/__init__.py
../celery/concurrency/threads.py
../celery/concurrency/eventlet.py
../celery/app/abstract.py
../celery/app/amqp.py
../celery/app/base.py
../celery/app/__init__.py
../celery/app/defaults.py
../celery/app/annotations.py
../celery/loaders/base.py
../celery/loaders/__init__.py
../celery/loaders/app.py
../celery/loaders/default.py
../celery/utils/dispatch/__init__.py
../celery/utils/dispatch/signal.py
../celery/utils/dispatch/saferef.py
../celery/tests/test_utils/test_timer2.py
../celery/tests/test_utils/test_pickle.py
../celery/tests/test_utils/test_utils_encoding.py
../celery/tests/test_utils/test_utils_timeutils.py
../celery/tests/test_utils/test_datastructures.py
../celery/tests/test_utils/test_serialization.py
../celery/tests/test_utils/__init__.py
../celery/tests/test_utils/test_utils_info.py
../celery/tests/test_worker/test_worker_job.py
../celery/tests/test_worker/test_worker_heartbeat.py
../celery/tests/test_worker/test_worker_state.py
../celery/tests/test_worker/test_worker_autoscale.py
../celery/tests/test_worker/test_worker_mediator.py
../celery/tests/test_worker/test_worker_revoke.py
../celery/tests/test_worker/test_bootsteps.py
../celery/tests/test_worker/__init__.py
../celery/tests/test_worker/test_worker_control.py
../celery/tests/test_compat/test_messaging.py
../celery/tests/test_compat/__init__.py
../celery/tests/test_compat/test_decorators.py
../celery/tests/functional/case.py
../celery/tests/functional/tasks.py
../celery/tests/functional/__init__.py
../celery/tests/test_backends/test_mongodb.py
../celery/tests/test_backends/test_redis_unit.py
../celery/tests/test_backends/test_base.py
../celery/tests/test_backends/test_cache.py
../celery/tests/test_backends/test_redis.py
../celery/tests/test_backends/test_amqp.py
../celery/tests/test_backends/test_tyrant.py
../celery/tests/test_backends/test_database.py
../celery/tests/test_backends/__init__.py
../celery/tests/test_backends/test_pyredis_compat.py
../celery/tests/test_concurrency/test_concurrency_solo.py
../celery/tests/test_concurrency/test_concurrency_eventlet.py
../celery/tests/test_concurrency/__init__.py
../celery/tests/test_concurrency/test_concurrency_processes.py
../celery/tests/test_concurrency/test_concurrency_gevent.py
../celery/tests/test_concurrency/test_pool.py
../celery/tests/test_events/test_events_state.py
../celery/tests/test_events/test_events_cursesmon.py
../celery/tests/test_events/test_events_snapshot.py
../celery/tests/test_events/__init__.py
../celery/tests/test_slow/test_buckets.py
../celery/tests/test_slow/__init__.py
../celery/tests/test_bin/test_celeryev.py
../celery/tests/test_bin/test_celeryd.py
../celery/tests/test_bin/__init__.py
../celery/tests/test_bin/test_celerybeat.py
../celery/tests/test_security/case.py
../celery/tests/test_security/test_key.py
../celery/tests/test_security/test_serialization.py
../celery/tests/test_security/__init__.py
../celery/tests/test_security/test_certificate.py
../celery/tests/test_task/test_execute_trace.py
../celery/tests/test_task/test_result.py
../celery/tests/test_task/test_task_http.py
../celery/tests/test_task/test_task_abortable.py
../celery/tests/test_task/test_task_builtins.py
../celery/tests/test_task/test_states.py
../celery/tests/test_task/__init__.py
../celery/tests/test_task/test_chord.py
../celery/tests/test_task/test_registry.py
../celery/tests/test_task/test_context.py
../celery/tests/test_task/test_task_control.py
../celery/tests/test_task/test_task_sets.py
../celery/tests/test_app/test_app_amqp.py
../celery/tests/test_app/test_routes.py
../celery/tests/test_app/test_annotations.py
../celery/tests/test_app/test_app_defaults.py
../celery/tests/test_app/test_actors.py
../celery/tests/test_app/__init__.py
../celery/tests/test_app/test_loaders.py
../celery/tests/test_app/test_log.py
../celery/tests/test_app/test_beat.py
../celery/tests/test_app/test_celery.py
../celery/concurrency/processes/pool.py
../celery/concurrency/processes/process.py
../celery/concurrency/processes/__init__.py
../celery/concurrency/processes/forking.py
../celery/concurrency/processes/_win.py
../celery/app/task/__init__.py
../celery/conf.pyc
../celery/abstract.pyc
../celery/states.pyc
../celery/decorators.pyc
../celery/local.pyc
../celery/exceptions.pyc
../celery/messaging.pyc
../celery/schedules.pyc
../celery/routes.pyc
../celery/__init__.pyc
../celery/platforms.pyc
../celery/signals.pyc
../celery/beat.pyc
../celery/result.pyc
../celery/registry.pyc
../celery/log.pyc
../celery/actors.pyc
../celery/datastructures.pyc
../celery/worker/mediator.pyc
../celery/worker/buckets.pyc
../celery/worker/state.pyc
../celery/worker/heartbeat.pyc
../celery/worker/strategy.pyc
../celery/worker/control.pyc
../celery/worker/__init__.pyc
../celery/worker/job.pyc
../celery/worker/consumer.pyc
../celery/worker/autoscale.pyc
../celery/worker/autoreload.pyc
../celery/contrib/batches.pyc
../celery/contrib/abortable.pyc
../celery/contrib/__init__.pyc
../celery/contrib/migrate.pyc
../celery/contrib/rdb.pyc
../celery/contrib/bundles.pyc
../celery/backends/cassandra.pyc
../celery/backends/cache.pyc
../celery/backends/amqp.pyc
../celery/backends/pyredis.pyc
../celery/backends/redis.pyc
../celery/backends/tyrant.pyc
../celery/backends/base.pyc
../celery/backends/__init__.pyc
../celery/backends/database.pyc
../celery/backends/mongodb.pyc
../celery/utils/timer2.pyc
../celery/utils/encoding.pyc
../celery/utils/functional.pyc
../celery/utils/mail.pyc
../celery/utils/__init__.pyc
../celery/utils/term.pyc
../celery/utils/threads.pyc
../celery/utils/compat.pyc
../celery/utils/serialization.pyc
../celery/utils/patch.pyc
../celery/utils/timeutils.pyc
../celery/events/state.pyc
../celery/events/dumper.pyc
../celery/events/cursesmon.pyc
../celery/events/snapshot.pyc
../celery/events/__init__.pyc
../celery/execute/trace.pyc
../celery/execute/__init__.pyc
../celery/apps/worker.pyc
../celery/apps/__init__.pyc
../celery/apps/beat.pyc
../celery/db/dfd042c7.pyc
../celery/db/a805d4bd.pyc
../celery/db/session.pyc
../celery/db/__init__.pyc
../celery/db/models.pyc
../celery/bin/celeryev.pyc
../celery/bin/celeryd_detach.pyc
../celery/bin/camqadm.pyc
../celery/bin/base.pyc
../celery/bin/__init__.pyc
../celery/bin/celeryd_multi.pyc
../celery/bin/celerybeat.pyc
../celery/bin/celeryctl.pyc
../celery/bin/celeryd.pyc
../celery/security/key.pyc
../celery/security/certificate.pyc
../celery/security/__init__.pyc
../celery/security/serialization.pyc
../celery/tests/config.pyc
../celery/tests/utils.pyc
../celery/tests/__init__.pyc
../celery/tests/compat.pyc
../celery/task/chords.pyc
../celery/task/sets.pyc
../celery/task/http.pyc
../celery/task/schedules.pyc
../celery/task/control.pyc
../celery/task/base.pyc
../celery/task/__init__.pyc
../celery/concurrency/solo.pyc
../celery/concurrency/gevent.pyc
../celery/concurrency/base.pyc
../celery/concurrency/__init__.pyc
../celery/concurrency/threads.pyc
../celery/concurrency/eventlet.pyc
../celery/app/abstract.pyc
../celery/app/amqp.pyc
../celery/app/base.pyc
../celery/app/__init__.pyc
../celery/app/defaults.pyc
../celery/app/annotations.pyc
../celery/loaders/base.pyc
../celery/loaders/__init__.pyc
../celery/loaders/app.pyc
../celery/loaders/default.pyc
../celery/utils/dispatch/__init__.pyc
../celery/utils/dispatch/signal.pyc
../celery/utils/dispatch/saferef.pyc
../celery/tests/test_utils/test_timer2.pyc
../celery/tests/test_utils/test_pickle.pyc
../celery/tests/test_utils/test_utils_encoding.pyc
../celery/tests/test_utils/test_utils_timeutils.pyc
../celery/tests/test_utils/test_datastructures.pyc
../celery/tests/test_utils/test_serialization.pyc
../celery/tests/test_utils/__init__.pyc
../celery/tests/test_utils/test_utils_info.pyc
../celery/tests/test_worker/test_worker_job.pyc
../celery/tests/test_worker/test_worker_heartbeat.pyc
../celery/tests/test_worker/test_worker_state.pyc
../celery/tests/test_worker/test_worker_autoscale.pyc
../celery/tests/test_worker/test_worker_mediator.pyc
../celery/tests/test_worker/test_worker_revoke.pyc
../celery/tests/test_worker/test_bootsteps.pyc
../celery/tests/test_worker/__init__.pyc
../celery/tests/test_worker/test_worker_control.pyc
../celery/tests/test_compat/test_messaging.pyc
../celery/tests/test_compat/__init__.pyc
../celery/tests/test_compat/test_decorators.pyc
../celery/tests/functional/case.pyc
../celery/tests/functional/tasks.pyc
../celery/tests/functional/__init__.pyc
../celery/tests/test_backends/test_mongodb.pyc
../celery/tests/test_backends/test_redis_unit.pyc
../celery/tests/test_backends/test_base.pyc
../celery/tests/test_backends/test_cache.pyc
../celery/tests/test_backends/test_redis.pyc
../celery/tests/test_backends/test_amqp.pyc
../celery/tests/test_backends/test_tyrant.pyc
../celery/tests/test_backends/test_database.pyc
../celery/tests/test_backends/__init__.pyc
../celery/tests/test_backends/test_pyredis_compat.pyc
../celery/tests/test_concurrency/test_concurrency_solo.pyc
../celery/tests/test_concurrency/test_concurrency_eventlet.pyc
../celery/tests/test_concurrency/__init__.pyc
../celery/tests/test_concurrency/test_concurrency_processes.pyc
../celery/tests/test_concurrency/test_concurrency_gevent.pyc
../celery/tests/test_concurrency/test_pool.pyc
../celery/tests/test_events/test_events_state.pyc
../celery/tests/test_events/test_events_cursesmon.pyc
../celery/tests/test_events/test_events_snapshot.pyc
../celery/tests/test_events/__init__.pyc
../celery/tests/test_slow/test_buckets.pyc
../celery/tests/test_slow/__init__.pyc
../celery/tests/test_bin/test_celeryev.pyc
../celery/tests/test_bin/test_celeryd.pyc
../celery/tests/test_bin/__init__.pyc
../celery/tests/test_bin/test_celerybeat.pyc
../celery/tests/test_security/case.pyc
../celery/tests/test_security/test_key.pyc
../celery/tests/test_security/test_serialization.pyc
../celery/tests/test_security/__init__.pyc
../celery/tests/test_security/test_certificate.pyc
../celery/tests/test_task/test_execute_trace.pyc
../celery/tests/test_task/test_result.pyc
../celery/tests/test_task/test_task_http.pyc
../celery/tests/test_task/test_task_abortable.pyc
../celery/tests/test_task/test_task_builtins.pyc
../celery/tests/test_task/test_states.pyc
../celery/tests/test_task/__init__.pyc
../celery/tests/test_task/test_chord.pyc
../celery/tests/test_task/test_registry.pyc
../celery/tests/test_task/test_context.pyc
../celery/tests/test_task/test_task_control.pyc
../celery/tests/test_task/test_task_sets.pyc
../celery/tests/test_app/test_app_amqp.pyc
../celery/tests/test_app/test_routes.pyc
../celery/tests/test_app/test_annotations.pyc
../celery/tests/test_app/test_app_defaults.pyc
../celery/tests/test_app/test_actors.pyc
../celery/tests/test_app/__init__.pyc
../celery/tests/test_app/test_loaders.pyc
../celery/tests/test_app/test_log.pyc
../celery/tests/test_app/test_beat.pyc
../celery/tests/test_app/test_celery.pyc
../celery/concurrency/processes/pool.pyc
../celery/concurrency/processes/process.pyc
../celery/concurrency/processes/__init__.pyc
../celery/concurrency/processes/forking.pyc
../celery/concurrency/processes/_win.pyc
../celery/app/task/__init__.pyc
./
top_level.txt
SOURCES.txt
not-zip-safe
entry_points.txt
PKG-INFO
requires.txt
dependency_links.txt
../../../bin/celeryctl
../../../bin/celeryd
../../../bin/camqadm
../../../bin/celeryev
../../../bin/celeryd-multi
../../../bin/celerybeat

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1,5 +0,0 @@
importlib
anyjson>=0.3.1
kombu>=2.1.8,<2.2.0
python-dateutil>=1.5,<2.0
ordereddict

Просмотреть файл

@ -1 +0,0 @@
celery

Просмотреть файл

@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
"""Distributed Task Queue"""
# :copyright: (c) 2009 - 2012 by Ask Solem.
# :license: BSD, see LICENSE for more details.
from __future__ import absolute_import
VERSION = (2, 5, 5)
__version__ = ".".join(map(str, VERSION[0:3])) + "".join(VERSION[3:])
__author__ = "Ask Solem"
__contact__ = "ask@celeryproject.org"
__homepage__ = "http://celeryproject.org"
__docformat__ = "restructuredtext"
# -eof meta-
import sys
if sys.version_info < (2, 5):
raise Exception(
"Python 2.4 is not supported by this version. "
"Please use Celery versions 2.1.x or earlier.")
from .local import Proxy
def Celery(*args, **kwargs):
from .app import App
return App(*args, **kwargs)
def _get_current_app():
from .app import current_app
return current_app()
current_app = Proxy(_get_current_app)

Просмотреть файл

@ -1,210 +0,0 @@
# -*- coding: utf-8 -*-
"""
celery.abstract
~~~~~~~~~~~~~~~
Implements components and boot-steps.
:copyright: (c) 2009 - 2012 by Ask Solem.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import
from collections import defaultdict
from importlib import import_module
from .datastructures import DependencyGraph
from .utils import instantiate
class Namespace(object):
"""A namespace containing components.
Every component must belong to a namespace.
When component classes are created they are added to the
mapping of unclaimed components. The components will be
claimed when the namespace they belong to is created.
:keyword name: Set the name of this namespace.
:keyword app: Set the Celery app for this namespace.
"""
name = None
_unclaimed = defaultdict(dict)
_started_count = 0
def __init__(self, name=None, app=None, logger=None):
self.app = app
self.name = name or self.name
self.logger = logger or self.app.log.get_default_logger()
self.services = []
def modules(self):
"""Subclasses can override this to return a
list of modules to import before components are claimed."""
return []
def load_modules(self):
"""Will load the component modules this namespace depends on."""
for m in self.modules():
self.import_module(m)
def apply(self, parent, **kwargs):
"""Apply the components in this namespace to an object.
This will apply the ``__init__`` and ``include`` methods
of each components with the object as argument.
For ``StartStopComponents`` the services created
will also be added the the objects ``components`` attribute.
"""
self._debug("Loading modules.")
self.load_modules()
self._debug("Claiming components.")
self.components = self._claim()
self._debug("Building boot step graph.")
self.boot_steps = [self.bind_component(name, parent, **kwargs)
for name in self._finalize_boot_steps()]
self._debug("New boot order: %r", [c.name for c in self.boot_steps])
for component in self.boot_steps:
component.include(parent)
return self
def bind_component(self, name, parent, **kwargs):
"""Bind component to parent object and this namespace."""
comp = self[name](parent, **kwargs)
comp.namespace = self
return comp
def import_module(self, module):
return import_module(module)
def __getitem__(self, name):
return self.components[name]
def _find_last(self):
for C in self.components.itervalues():
if C.last:
return C
def _finalize_boot_steps(self):
G = self.graph = DependencyGraph((C.name, C.requires)
for C in self.components.itervalues())
last = self._find_last()
if last:
for obj in G:
if obj != last.name:
G.add_edge(last.name, obj)
return G.topsort()
def _claim(self):
return self._unclaimed[self.name]
def _debug(self, msg, *args):
return self.logger.debug("[%s] " + msg,
*(self.name.capitalize(), ) + args)
class ComponentType(type):
"""Metaclass for components."""
def __new__(cls, name, bases, attrs):
abstract = attrs.pop("abstract", False)
if not abstract:
try:
cname = attrs["name"]
except KeyError:
raise NotImplementedError("Components must be named")
namespace = attrs.get("namespace", None)
if not namespace:
attrs["namespace"], _, attrs["name"] = cname.partition('.')
cls = super(ComponentType, cls).__new__(cls, name, bases, attrs)
if not abstract:
Namespace._unclaimed[cls.namespace][cls.name] = cls
return cls
class Component(object):
"""A component.
The :meth:`__init__` method is called when the component
is bound to a parent object, and can as such be used
to initialize attributes in the parent object at
parent instantiation-time.
"""
__metaclass__ = ComponentType
#: The name of the component, or the namespace
#: and the name of the component separated by dot.
name = None
#: List of component names this component depends on.
#: Note that the dependencies must be in the same namespace.
requires = ()
#: can be used to specify the namespace,
#: if the name does not include it.
namespace = None
#: if set the component will not be registered,
#: but can be used as a component base class.
abstract = True
#: Optional obj created by the :meth:`create` method.
#: This is used by StartStopComponents to keep the
#: original service object.
obj = None
#: This flag is reserved for the workers Consumer,
#: since it is required to always be started last.
#: There can only be one object marked with lsat
#: in every namespace.
last = False
#: This provides the default for :meth:`include_if`.
enabled = True
def __init__(self, parent, **kwargs):
pass
def create(self, parent):
"""Create the component."""
pass
def include_if(self, parent):
"""An optional predicate that decided whether this
component should be created."""
return self.enabled
def instantiate(self, qualname, *args, **kwargs):
return instantiate(qualname, *args, **kwargs)
def include(self, parent):
if self.include_if(parent):
self.obj = self.create(parent)
return True
class StartStopComponent(Component):
abstract = True
terminable = False
def start(self):
return self.obj.start()
def stop(self):
return self.obj.stop()
def terminate(self):
if self.terminable:
return self.obj.terminate()
return self.obj.stop()
def include(self, parent):
if super(StartStopComponent, self).include(parent):
parent.components.append(self.obj)

Просмотреть файл

@ -1,30 +0,0 @@
from __future__ import absolute_import
from celery.app import app_or_default
import cl
import cl.presence
def construct(cls, instance, connection=None, *args, **kwargs):
app = instance.app = app_or_default(kwargs.pop("app", None))
super(cls, instance).__init__(connection or app.broker_connection(),
*args, **kwargs)
class Actor(cl.Actor):
def __init__(self, *args, **kwargs):
construct(Actor, self, *args, **kwargs)
class Agent(cl.Agent):
def __init__(self, *args, **kwargs):
construct(Agent, self, *args, **kwargs)
class AwareAgent(cl.presence.AwareAgent):
def __init__(self, *args, **kwargs):
construct(AwareAgent, self, *args, **kwargs)

Просмотреть файл

@ -1,294 +0,0 @@
# -*- coding: utf-8 -*-
"""
celery.app
~~~~~~~~~~
Celery Application.
:copyright: (c) 2009 - 2012 by Ask Solem.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import
import os
import threading
from .. import registry
from ..utils import cached_property, instantiate
from .annotations import (
_first_match, _first_match_any,
prepare as prepare_annotations
)
from .base import BaseApp
class _TLS(threading.local):
#: Apps with the :attr:`~celery.app.base.BaseApp.set_as_current` attribute
#: sets this, so it will always contain the last instantiated app,
#: and is the default app returned by :func:`app_or_default`.
current_app = None
#: The currently executing task.
current_task = None
_tls = _TLS()
class AppPickler(object):
"""Default application pickler/unpickler."""
def __call__(self, cls, *args):
kwargs = self.build_kwargs(*args)
app = self.construct(cls, **kwargs)
self.prepare(app, **kwargs)
return app
def prepare(self, app, **kwargs):
app.conf.update(kwargs["changes"])
def build_kwargs(self, *args):
return self.build_standard_kwargs(*args)
def build_standard_kwargs(self, main, changes, loader, backend, amqp,
events, log, control, accept_magic_kwargs):
return dict(main=main, loader=loader, backend=backend, amqp=amqp,
changes=changes, events=events, log=log, control=control,
set_as_current=False,
accept_magic_kwargs=accept_magic_kwargs)
def construct(self, cls, **kwargs):
return cls(**kwargs)
def _unpickle_app(cls, pickler, *args):
return pickler()(cls, *args)
class App(BaseApp):
"""Celery Application.
:param main: Name of the main module if running as `__main__`.
:keyword loader: The loader class, or the name of the loader class to use.
Default is :class:`celery.loaders.app.AppLoader`.
:keyword backend: The result store backend class, or the name of the
backend class to use. Default is the value of the
:setting:`CELERY_RESULT_BACKEND` setting.
:keyword amqp: AMQP object or class name.
:keyword events: Events object or class name.
:keyword log: Log object or class name.
:keyword control: Control object or class name.
:keyword set_as_current: Make this the global current app.
"""
Pickler = AppPickler
def set_current(self):
"""Make this the current app for this thread."""
_tls.current_app = self
def on_init(self):
if self.set_as_current:
self.set_current()
def create_task_cls(self):
"""Creates a base task class using default configuration
taken from this app."""
conf = self.conf
from .task import BaseTask
class Task(BaseTask):
abstract = True
app = self
backend = self.backend
exchange_type = conf.CELERY_DEFAULT_EXCHANGE_TYPE
delivery_mode = conf.CELERY_DEFAULT_DELIVERY_MODE
send_error_emails = conf.CELERY_SEND_TASK_ERROR_EMAILS
error_whitelist = conf.CELERY_TASK_ERROR_WHITELIST
serializer = conf.CELERY_TASK_SERIALIZER
rate_limit = conf.CELERY_DEFAULT_RATE_LIMIT
track_started = conf.CELERY_TRACK_STARTED
acks_late = conf.CELERY_ACKS_LATE
ignore_result = conf.CELERY_IGNORE_RESULT
store_errors_even_if_ignored = \
conf.CELERY_STORE_ERRORS_EVEN_IF_IGNORED
accept_magic_kwargs = self.accept_magic_kwargs
Task.__doc__ = BaseTask.__doc__
return Task
def Worker(self, **kwargs):
"""Create new :class:`~celery.apps.worker.Worker` instance."""
return instantiate("celery.apps.worker:Worker", app=self, **kwargs)
def WorkController(self, **kwargs):
return instantiate("celery.worker:WorkController", app=self, **kwargs)
def Beat(self, **kwargs):
"""Create new :class:`~celery.apps.beat.Beat` instance."""
return instantiate("celery.apps.beat:Beat", app=self, **kwargs)
def TaskSet(self, *args, **kwargs):
"""Create new :class:`~celery.task.sets.TaskSet`."""
return instantiate("celery.task.sets:TaskSet",
app=self, *args, **kwargs)
def worker_main(self, argv=None):
"""Run :program:`celeryd` using `argv`. Uses :data:`sys.argv`
if `argv` is not specified."""
return instantiate("celery.bin.celeryd:WorkerCommand", app=self) \
.execute_from_commandline(argv)
def task(self, *args, **options):
"""Decorator to create a task class out of any callable.
**Examples:**
.. code-block:: python
@task()
def refresh_feed(url):
return Feed.objects.get(url=url).refresh()
with setting extra options and using retry.
.. code-block:: python
from celery.task import current
@task(exchange="feeds")
def refresh_feed(url):
try:
return Feed.objects.get(url=url).refresh()
except socket.error, exc:
current.retry(exc=exc)
Calling the resulting task::
>>> refresh_feed("http://example.com/rss") # Regular
<Feed: http://example.com/rss>
>>> refresh_feed.delay("http://example.com/rss") # Async
<AsyncResult: 8998d0f4-da0b-4669-ba03-d5ab5ac6ad5d>
"""
def inner_create_task_cls(**options):
def _create_task_cls(fun):
base = options.pop("base", None) or self.Task
T = type(fun.__name__, (base, ), dict({
"app": self,
"accept_magic_kwargs": False,
"run": staticmethod(fun),
"__doc__": fun.__doc__,
"__module__": fun.__module__}, **options))()
return registry.tasks[T.name] # global instance.
return _create_task_cls
if len(args) == 1 and callable(args[0]):
return inner_create_task_cls(**options)(*args)
return inner_create_task_cls(**options)
def annotate_task(self, task):
if self.annotations:
match = _first_match(self.annotations, task)
for attr, value in (match or {}).iteritems():
setattr(task, attr, value)
match_any = _first_match_any(self.annotations)
for attr, value in (match_any or {}).iteritems():
setattr(task, attr, value)
@cached_property
def Task(self):
"""Default Task base class for this application."""
return self.create_task_cls()
@cached_property
def annotations(self):
return prepare_annotations(self.conf.CELERY_ANNOTATIONS)
def __repr__(self):
return "<Celery: %s:0x%x>" % (self.main or "__main__", id(self), )
def __reduce__(self):
# Reduce only pickles the configuration changes,
# so the default configuration doesn't have to be passed
# between processes.
return (_unpickle_app, (self.__class__, self.Pickler)
+ self.__reduce_args__())
def __reduce_args__(self):
return (self.main,
self.conf.changes,
self.loader_cls,
self.backend_cls,
self.amqp_cls,
self.events_cls,
self.log_cls,
self.control_cls,
self.accept_magic_kwargs)
#: The "default" loader is the default loader used by old applications.
default_loader = os.environ.get("CELERY_LOADER") or "default"
#: Global fallback app instance.
default_app = App("default", loader=default_loader,
set_as_current=False,
accept_magic_kwargs=True)
def current_app():
return getattr(_tls, "current_app", None) or default_app
def current_task():
return getattr(_tls, "current_task", None)
def _app_or_default(app=None):
"""Returns the app provided or the default app if none.
The environment variable :envvar:`CELERY_TRACE_APP` is used to
trace app leaks. When enabled an exception is raised if there
is no active app.
"""
if app is None:
return getattr(_tls, "current_app", None) or default_app
return app
def _app_or_default_trace(app=None): # pragma: no cover
from traceback import print_stack
from multiprocessing import current_process
if app is None:
if getattr(_tls, "current_app", None):
print("-- RETURNING TO CURRENT APP --") # noqa+
print_stack()
return _tls.current_app
if current_process()._name == "MainProcess":
raise Exception("DEFAULT APP")
print("-- RETURNING TO DEFAULT APP --") # noqa+
print_stack()
return default_app
return app
def enable_trace():
global app_or_default
app_or_default = _app_or_default_trace
def disable_trace():
global app_or_default
app_or_default = _app_or_default
app_or_default = _app_or_default
if os.environ.get("CELERY_TRACE_APP"): # pragma: no cover
enable_trace()

Просмотреть файл

@ -1,55 +0,0 @@
from __future__ import absolute_import
class from_config(object):
def __init__(self, key=None):
self.key = key
def get_key(self, attr):
return attr if self.key is None else self.key
class _configurated(type):
def __new__(cls, name, bases, attrs):
attrs["__confopts__"] = dict((attr, spec.get_key(attr))
for attr, spec in attrs.iteritems()
if isinstance(spec, from_config))
inherit_from = attrs.get("inherit_confopts", ())
for subcls in bases:
try:
attrs["__confopts__"].update(subcls.__confopts__)
except AttributeError:
pass
for subcls in inherit_from:
attrs["__confopts__"].update(subcls.__confopts__)
attrs = dict((k, v if not isinstance(v, from_config) else None)
for k, v in attrs.iteritems())
return super(_configurated, cls).__new__(cls, name, bases, attrs)
class configurated(object):
__metaclass__ = _configurated
def setup_defaults(self, kwargs, namespace="celery"):
confopts = self.__confopts__
app, find = self.app, self.app.conf.find_value_for_key
for attr, keyname in confopts.iteritems():
try:
value = kwargs[attr]
except KeyError:
value = find(keyname, namespace)
else:
if value is None:
value = find(keyname, namespace)
setattr(self, attr, value)
for attr_name, attr_value in kwargs.iteritems():
if attr_name not in confopts and attr_value is not None:
setattr(self, attr_name, attr_value)
def confopts_as_dict(self):
return dict((key, getattr(self, key))
for key in self.__confopts__.iterkeys())

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше