Skip to content

Commit

Permalink
0.8.2
Browse files Browse the repository at this point in the history
  • Loading branch information
lsbardel committed May 30, 2014
2 parents 907eaba + 6639619 commit 675a32a
Show file tree
Hide file tree
Showing 106 changed files with 3,066 additions and 680 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ MANIFEST
.settings
.python-version
examples/webmail/config.py
examples/tweets/settings.py
*~
.htmlprof
examples/djangoapp/test.db
Expand All @@ -27,4 +28,4 @@ extensions/lua/lua.c
extensions/lib/lib.c
.coveralls.yml
*.rdb
config.py
/config.py
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ language: python
python:
- "2.7"
- "3.3"
- "3.4"
- "pypy"

services:
Expand All @@ -21,10 +22,10 @@ services:
- mongodb

script:
- python -m covrun --pep8
- python -m covrun --pep8 pulsar examples tests
- sudo rm -rf pulsar
- python -m covrun -w 2 -e taskqueue pshell philosophers async webmail djangoapp stores.odm stores.couchdb stores.query stores.redis
- if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then python -m runtests --coveralls; fi
- python -m covrun -w 2 -e taskqueue pshell philosophers webmail djangoapp stores.odm stores.couchdb stores.query stores.redis
- if [[ $TRAVIS_PYTHON_VERSION == '3.4' ]]; then python -m runtests --coveralls; fi

notifications:
email: false
Expand Down
32 changes: 28 additions & 4 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
Ver. 0.8.2 - 2014-May-30
===========================
* :ref:`--pep8 <setting-pep8>` is a new command line option for the
:mod:`~pulsar.apps.test` application
* :class:`.ProtocolConsumer` has its own ``_loop`` attribute rather than
obtaining indirectly from the underling :class:`.Connection`.
This avoids several logging errors when a connection is dropped
* Added utilities to execute :postgresql:`PostgreSql <>` queries via
psycopg2_ in asynchronous mode via the :mod:`~pulsar.apps.greenio` module.
* :ref:`Django pulse application <apps-pulse>` can be run asynchronously
when using PostgreSql database.
It requires the :greenlet:`greenlet module <>`
* Added :attr:`.Head.embedded_js` for adding javascript code directly in the
:class:`.HtmlDocument`
* Improved management of ``meta`` tags in the HTML5 :class:`.Head` class
* Added :class:`.OAuth1` and :class:`.OAuth2` hooks to the
:mod:`~pulsar.apps.http` module (alpha and untested)
* Bug fix in :class:`.HttpParser` when ``Transfer-Encoding=chunked``
* Added default javascript libraries to the :class:`.HtmlDocument`
* Both wsgi request wrappers and content don't use coroutines but
straight :class:`~asyncio.Future` for compatibility with other frameworks.
* pulsar can be imported and used (with limited scope) in the google appengine

Ver. 0.8.1 - 2014-Apr-14
===========================
* Added :mod:`pulsar.apps.greenio` application for writing asynchronous code
Expand All @@ -20,7 +43,7 @@ Ver. 0.8.1 - 2014-Apr-14
Ver. 0.8.0 - 2014-Mar-06
===========================
* **Backward incompatible version**


* **Asyncio Integration**

* asyncio_ integration with several changes in internals. The integration
Expand Down Expand Up @@ -111,21 +134,21 @@ Ver. 0.8.0 - 2014-Mar-06

* **1,166 regression tests**, **91% coverage**.

Ver. 0.7.4 - 2013-Dec-22
Ver. 0.7.4 - 2013-Dec-22
===========================
* A bug fix release.
* Fixes an issue with Cookie handling in the wsgi application.
* Don't log errors when writing back to a stale client
* **822 regression tests**, **91% coverage**

Ver. 0.7.3 - 2013-Dec-12
===========================
===========================
* A bug fix release.
* ``setup.py`` only import pulsar version and skip the rest
* The :func:`.wait_for_body_middleware` read the HTTP body only without
decoding it
* C extensions included in ``MANIFEST.in`` so that they can be compiled from PyPi
* **823 regression tests**, **91% coverage**
* **823 regression tests**, **91% coverage**

Ver. 0.7.2 - 2013-Oct-16
===========================
Expand Down Expand Up @@ -474,3 +497,4 @@ Ver. 0.1.0 - 2011-Aug-24
.. _asyncio: http://www.python.org/dev/peps/pep-3156/
.. _cauchdb: http://couchdb.apache.org/
.. _greenlet: http://greenlet.readthedocs.org/
.. _psycopg2: http://pythonhosted.org/psycopg2/
5 changes: 3 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ include LICENSE
include README.rst
include docs/make.bat
include docs/Makefile
recursive-include examples *.py *.js *.css *.html
recursive-include pulsar *.json
recursive-include examples *.py *.js *.css *.html *.json
recursive-include pulsar/apps/test/plugins/htmlfiles *
recursive-include docs/source *
recursive-include extensions *.py *.pxd *.pyx *.h
recursive-include extensions *.py *.pxd *.pyx *.h
2 changes: 2 additions & 0 deletions docs/source/_templates/sidebarintro.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
<i class="fa fa-envelope fa-2x"></i> email list @ google</a></li>
<li><a href="http://twitter.com/quantmind" target="_blank">
<i class="fa fa-twitter fa-2x"></i> quantmind @ twitter</a></li>
<li><a href="http://webchat.freenode.net/?channels=pulsar-python" target="_blank">
<i class="fa fa-comments fa-2x"></i> IRC #pulsar-python</a></li>
</ul>
6 changes: 5 additions & 1 deletion docs/source/api/actor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
Actors API
=======================

For an overview of pulsar :class:`.Actor`
check out the :ref:`design documentation <design-actor>`.


High Level Functions
=======================
Expand All @@ -29,7 +32,8 @@ get_actor

.. function:: get_actor

Return the :class:`Actor` controlling the current thread.
Returns the :class:`Actor` controlling the current thread.
Returns ``None`` if no actor is available.

arbiter
~~~~~~~~~~~~~~
Expand Down
41 changes: 31 additions & 10 deletions docs/source/apps/data/clients.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ Datastore Clients
Getting Started
=====================

To create a data :class:`.Store` client one uses the :func:`.create_store`
function with a valid :ref:`connection string <connection-string>`::

>>> from pulsar.apps.data import create_store
>>> store = create_store('redis://user:password@127.0.0.1:6500/11')
>>> store.name
'redis'
>>> store.database
'11'
>>> store.dns
'redis://user:password@127.0.0.1:6500/11'

Additional parameters can be passed via the connection string or as key-valued
parameters. For example::

>>> store = create_store('redis://user:password@127.0.0.1:6500/11',
namespace='test_')
>>> store.dns
'redis://user:password@127.0.0.1:6500/11?namespace=test_'


.. _connection-string:

Connection String
Expand All @@ -21,17 +42,12 @@ of the form::
<scheme>://<username>:<password>@<host>/<database>?param1=...&param2=...


backend to use. Redis supports the following
parameters:

* ``db``, the database number.
* ``namespace``, the namespace for all the keys used by the backend.
* ``password``, database password.
* ``timeout``, connection timeout (0 is an asynchronous connection).
where:

A full connection string could be::

redis://127.0.0.1:6379?db=3&password=bla&namespace=test.&timeout=5
* ``schema`` is the store name
* ``database`` is the database name (or number for redis)
* ``username`` is an optional database username
* ``password`` is an optional database password


Implement a Store
Expand Down Expand Up @@ -71,6 +87,11 @@ a valid :class:`.PubSub` handler.
API
============

The main component of the data store API is the :func:`.create_store`
function which creates in one function call a new :class:`.Store`
object which can be used to interact directly with the backend database
or indirectly via the :ref:`object data mapper <odm>`.

Create store
~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
6 changes: 0 additions & 6 deletions docs/source/apps/wsgi/tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ both server and the :ref:`HTTP client <apps-http>`. Headers are collected using
the :ref:`Headers data structure <tools-http-headers>` which exposes a
list/dictionary-type interface.

At runtime, pulsar checks if the http-parser_ package is available.
If this is the case, it switches the default HTTP parser
to be the one provided by the :mod:`http_parser.paser` module.
To check if the C parser is the default parser::

from pulsar.utils.httpurl import hasextensions

Authentication
=================
Expand Down
6 changes: 6 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,9 @@
intersphinx_mapping = {
'python': ('http://python.readthedocs.org/en/latest/', None),
}

extlinks = {'django': ('https://www.djangoproject.com/', None),
'postgresql': ('http://www.postgresql.org/', None),
'sqlalchemy': ('http://www.sqlalchemy.org/', None),
'greenlet': ('http://greenlet.readthedocs.org/', None),
'psycopg2coroutine': ('http://pythonhosted.org/psycopg2/advanced.html#support-for-coroutine-libraries', None)}
17 changes: 17 additions & 0 deletions docs/source/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ How pulsar handle asynchronous data?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Check the :ref:`asynchronous components documentation <tutorials-coroutine>`.


Socket Servers
--------------------

Expand All @@ -53,6 +54,22 @@ Is a WSGI response asynchronous?
It depends on the WSGI application serving the request.


Logging
---------------

log level
~~~~~~~~~~~~~~~~

Pulsar uses the :ref:`log-level <setting_log-level>` setting to control
logging level on the command line or on your :ref:`config <setting_config`
file::

python script.py --log-level debug

Did you know you can pass several namespaces to ``--log-level``::

python script.py --log-level debug asyncio.warning


Internals
---------------
Expand Down
1 change: 1 addition & 0 deletions docs/source/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Most of the material presented in the these tutorials is based on the
chat
taskqueue
django
tweets
philosophers
pulsards
udp
Expand Down
10 changes: 10 additions & 0 deletions docs/source/tutorials/tweets.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. _tutorials-tweets:

==================================
Twitter Streaming
==================================

The code for this example is located in the :mod:`examples.tweets.manage`
module.

.. automodule:: examples.tweets.manage
5 changes: 2 additions & 3 deletions examples/chat/tests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'''Tests the websocket middleware in pulsar.apps.ws.'''
import unittest
from asyncio import Queue

from pulsar import send
from pulsar import asyncio, send
from pulsar.apps import rpc, http, ws
from pulsar.apps.test import dont_run_with_thread
from pulsar.utils.httpurl import HTTPError
Expand All @@ -14,7 +13,7 @@
class Message(ws.WS):

def __init__(self, loop):
self.queue = Queue(loop=loop)
self.queue = asyncio.Queue(loop=loop)

def get(self):
return self.queue.get()
Expand Down
2 changes: 2 additions & 0 deletions examples/djangoapp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
# set the datastore for the pubsub
data_store = 'pulsar://127.0.0.1:6410/1'
# data_store = 'redis://127.0.0.1:6379/1'

thread_workers = 10
5 changes: 2 additions & 3 deletions examples/djangoapp/tests/app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'''Tests django chat application.'''
import unittest
from asyncio import Queue

from pulsar import send, get_application, coroutine_return
from pulsar import asyncio, send, get_application, coroutine_return
from pulsar.utils.path import Path
from pulsar.apps import http, ws
from pulsar.apps.test import dont_run_with_thread
Expand All @@ -24,7 +23,7 @@ def start_server(actor, name, argv):
class MessageHandler(ws.WS):

def __init__(self):
self.queue = Queue()
self.queue = asyncio.Queue()

def get(self):
return self.queue.get()
Expand Down
18 changes: 9 additions & 9 deletions examples/proxyserver/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,14 @@
import sys
import logging
from functools import partial
from asyncio import Queue, QueueEmpty

try:
import pulsar
except ImportError:
sys.path.append('../../')
import pulsar

from pulsar import HttpException, async, coroutine_return, add_errback
from pulsar import asyncio, HttpException, async, coroutine_return, add_errback
from pulsar.apps import wsgi, http
from pulsar.utils.httpurl import Headers
from pulsar.utils.log import LocalMixin, local_property
Expand Down Expand Up @@ -122,8 +121,9 @@ def _call(self, environ, start_response, loop):

def request_headers(self, environ):
'''Fill request headers from the environ dictionary and
modify the headers via the list of :attr:`headers_middleware`.
The returned headers will be sent to the target uri.'''
modify them via the list of :attr:`headers_middleware`.
The returned headers will be sent to the target uri.
'''
headers = Headers(kind='client')
for k in environ:
if k.startswith('HTTP_'):
Expand All @@ -142,7 +142,7 @@ def request_headers(self, environ):
############################################################################
# RESPONSE OBJECTS
class ProxyResponse(object):
'''Asynchronous wsgi response.
'''Asynchronous wsgi response for http requests
'''
_started = False
_headers = None
Expand All @@ -152,22 +152,21 @@ def __init__(self, environ, start_response):
self._loop = environ['pulsar.connection']._loop
self.environ = environ
self.start_response = start_response
self.queue = Queue()
self.queue = asyncio.Queue()

def __iter__(self):
while True:
if self._done:
try:
yield self.queue.get_nowait()
except QueueEmpty:
except asyncio.QueueEmpty:
break
else:
yield async(self.queue.get(), loop=self._loop)

def pre_request(self, response, exc=None):
self._started = True
response.bind_event('data_processed', self.data_processed)
return response

def error(self, exc):
if not self._started:
Expand Down Expand Up @@ -215,7 +214,8 @@ def remove_hop_headers(self, headers):


class ProxyTunnel(ProxyResponse):

'''Asynchronous wsgi response for https requests
'''
def pre_request(self, response, exc=None):
'''Start the tunnel.
Expand Down
Loading

0 comments on commit 675a32a

Please sign in to comment.