mirror of
https://github.com/sprockets/sprockets.mixins.postgresql.git
synced 2024-12-29 03:00:29 +00:00
Merge pull request #1 from sprockets/initial-version
Initial version of the handler mixins
This commit is contained in:
commit
bc0e255777
20 changed files with 727 additions and 26 deletions
26
.travis.yml
Normal file
26
.travis.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
%YAML 1.1
|
||||
---
|
||||
language: python
|
||||
python:
|
||||
- 2.6
|
||||
- 2.7
|
||||
- pypy
|
||||
- 3.2
|
||||
- 3.3
|
||||
- 3.4
|
||||
install:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi
|
||||
- pip install -e .
|
||||
- pip install -r test-requirements.txt
|
||||
script: nosetests
|
||||
after_success:
|
||||
- coveralls
|
||||
deploy:
|
||||
provider: pypi
|
||||
user: sprockets
|
||||
on:
|
||||
python: 2.7
|
||||
tags: true
|
||||
all_branches: true
|
||||
password:
|
||||
secure: JRmF7wfSuD3Aes2exf7x5mu9tqgkn5gmj1THacfcqqWntWW9odhVcdDfDzLltVsTpA8AKWkcSVBpUczZHWzq4J2lGfrkC5vzi9CHxepxWAduZ7YjmOi9UXxY5A0xjviZGObJjzpnnkeQD/M9dF0KcD/mm6ks94BLoeQeuHlUnPg=
|
45
LICENSE
45
LICENSE
|
@ -1,28 +1,25 @@
|
|||
Copyright (c) 2014, Sprockets
|
||||
Copyright (c) 2014 AWeber Communications
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the {organization} nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of Sprockets nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
7
MANIFEST.in
Normal file
7
MANIFEST.in
Normal file
|
@ -0,0 +1,7 @@
|
|||
include LICENSE
|
||||
include README.rst
|
||||
include *requirements.txt
|
||||
graft docs
|
||||
graft tests.py
|
||||
global-exclude __pycache__
|
||||
global-exclude *.pyc
|
|
@ -1,2 +0,0 @@
|
|||
sprockets.mixins.postgresql
|
||||
===========================
|
97
README.rst
Normal file
97
README.rst
Normal file
|
@ -0,0 +1,97 @@
|
|||
sprockets.mixins.postgresql
|
||||
===========================
|
||||
Handler mixins that automatically connect a PostgreSQL client session upon initialization.
|
||||
|
||||
|Version| |Downloads| |Status| |Coverage| |License|
|
||||
|
||||
Installation
|
||||
------------
|
||||
sprockets.mixins.postgresql is available on the
|
||||
`Python Package Index <https://pypi.python.org/pypi/sprockets.mixins.postgresql>`_
|
||||
and can be installed via ``pip`` or ``easy_install``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
pip install sprockets.mixins.postgresql
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
https://sprocketsmixinspostgresql.readthedocs.org
|
||||
|
||||
Requirements
|
||||
------------
|
||||
- `sprockets <https://github.com/sprockets/sprockets>`_
|
||||
- `sprockets.clients.postgresql <https://github.com/sprockets/sprockets.clients.postgresql>`_
|
||||
|
||||
Example
|
||||
-------
|
||||
The following example demonstrates using the ``HandlerMixin`` with a
|
||||
synchronous Tornado ``RequestHandler <tornado.web.RequestHandler>`` for a
|
||||
database named ``postgres``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
import os
|
||||
|
||||
from sprockets.mixins import postgresql
|
||||
from tornado import web
|
||||
|
||||
os.environ['POSTGRES_HOST'] = 'localhost'
|
||||
os.environ['POSTGRES_USER'] = 'postgres'
|
||||
os.environ['POSTGRES_PORT'] = 5432
|
||||
os.environ['POSTGRES_DBNAME'] = 'postgres'
|
||||
|
||||
class PostgresRequestHandler(postgresql.HandlerMixin,
|
||||
web.RequestHandler):
|
||||
|
||||
DBNAME = 'postgres'
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
result = self.foo_session.query('SELECT * FROM bar')
|
||||
self.finish({'data': result.items()})
|
||||
|
||||
The second example demonstrates using the ``AsyncHandlerMixin`` with an
|
||||
asynchronous Tornado ``RequestHandler`` for a database named ``foo``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
import os
|
||||
|
||||
from sprockets.mixins import postgresql
|
||||
from tornado import web
|
||||
|
||||
os.environ['FOO_HOST'] = 'localhost'
|
||||
os.environ['FOO_USER'] = 'postgres'
|
||||
os.environ['FOO_PORT'] = 5432
|
||||
os.environ['FOO_DBNAME'] = 'foo'
|
||||
os.environ['FOO_PASSWORD'] = 'bar'
|
||||
|
||||
class FooRequestHandler(postgresql.HandlerMixin,
|
||||
web.RequestHandler):
|
||||
|
||||
DBNAME = 'foo'
|
||||
|
||||
@web.asynchronous
|
||||
def get(self, *args, **kwargs):
|
||||
result = yield self.foo_session.query('SELECT * FROM baz')
|
||||
self.finish({'data': result.items()})
|
||||
result.free()
|
||||
|
||||
Version History
|
||||
---------------
|
||||
Available at https://sprocketsmixinspostgresql.readthedocs.org/en/latest/history.html
|
||||
|
||||
.. |Version| image:: https://badge.fury.io/py/sprockets.mixins.postgresql.svg?
|
||||
:target: http://badge.fury.io/py/sprockets.mixins.postgresql
|
||||
|
||||
.. |Status| image:: https://travis-ci.org/sprockets/sprockets.mixins.postgresql.svg?branch=master
|
||||
:target: https://travis-ci.org/sprockets/sprockets.mixins.postgresql
|
||||
|
||||
.. |Coverage| image:: https://img.shields.io/coveralls/sprockets/sprockets.mixins.postgresql.svg?
|
||||
:target: https://coveralls.io/r/sprockets/sprockets.mixins.postgresql
|
||||
|
||||
.. |Downloads| image:: https://pypip.in/d/sprockets.mixins.postgresql/badge.svg?
|
||||
:target: https://pypi.python.org/pypi/sprockets.mixins.postgresql
|
||||
|
||||
.. |License| image:: https://pypip.in/license/sprockets.mixins.postgresql/badge.svg?
|
||||
:target: https://sprocketsmixinspostgresql.readthedocs.org
|
6
dev-requirements.txt
Normal file
6
dev-requirements.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
-r requirements.txt
|
||||
-r test-requirements.txt
|
||||
flake8>=2.1,<3
|
||||
sphinx>=1.2,<2
|
||||
sphinx-rtd-theme>=0.1,<1.0
|
||||
sphinxcontrib-httpdomain>=1.2,<2
|
153
docs/Makefile
Normal file
153
docs/Makefile
Normal file
|
@ -0,0 +1,153 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/rabbitpy.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/rabbitpy.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/rabbitpy"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/rabbitpy"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
2
docs/api.rst
Normal file
2
docs/api.rst
Normal file
|
@ -0,0 +1,2 @@
|
|||
.. automodule:: sprockets.mixins.postgresql
|
||||
:members:
|
32
docs/conf.py
Normal file
32
docs/conf.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
import sphinx_rtd_theme
|
||||
|
||||
from sprockets.mixins.postgresql import version_info, __version__
|
||||
|
||||
needs_sphinx = '1.0'
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinxcontrib.httpdomain',
|
||||
]
|
||||
templates_path = []
|
||||
source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
project = 'sprockets.mixins.postgresql'
|
||||
copyright = '2014, AWeber Communications'
|
||||
version = '.'.join(__version__.split('.')[0:1])
|
||||
release = __version__
|
||||
if len(version_info) > 3:
|
||||
release += '-{0}'.format(str(v) for v in version_info[3:])
|
||||
exclude_patterns = []
|
||||
pygments_style = 'sphinx'
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
intersphinx_mapping = {
|
||||
'python': ('https://docs.python.org/', None),
|
||||
'sprockets': ('https://sprockets.readthedocs.org/en/latest/', None),
|
||||
'sprockets.clients.postgresql': (
|
||||
'https://sprocketsclientspostgresql.readthedocs.org/en/latest/',
|
||||
None),
|
||||
'tornado': ('http://tornadoweb.org/en/stable/', None)
|
||||
}
|
57
docs/examples.rst
Normal file
57
docs/examples.rst
Normal file
|
@ -0,0 +1,57 @@
|
|||
Examples
|
||||
========
|
||||
The following example demonstrates using the
|
||||
:py:class:`HandlerMixin <sprockets.mixins.postgresql.HandlerMixin>` with a
|
||||
synchronous Tornado :py:class:`RequestHandler <tornado.web.RequestHandler>` for a database
|
||||
named ``postgres``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
import os
|
||||
|
||||
from sprockets.mixins import postgresql
|
||||
from tornado import web
|
||||
|
||||
os.environ['POSTGRES_HOST'] = 'localhost'
|
||||
os.environ['POSTGRES_USER'] = 'postgres'
|
||||
os.environ['POSTGRES_PORT'] = 5432
|
||||
os.environ['POSTGRES_DBNAME'] = 'postgres'
|
||||
|
||||
class PostgresRequestHandler(postgresql.HandlerMixin,
|
||||
web.RequestHandler):
|
||||
|
||||
DBNAME = 'postgres'
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
result = self.foo_session.query('SELECT * FROM bar')
|
||||
self.finish({'data': result.items()})
|
||||
|
||||
The second example demonstrates using the
|
||||
:py:class:`AsyncHandlerMixin <sprockets.mixins.postgresql.AsyncHandlerMixin>`
|
||||
with an asynchronous Tornado :py:class:`RequestHandler <tornado.web.RequestHandler>`
|
||||
for a database named ``foo``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
import os
|
||||
|
||||
from sprockets.mixins import postgresql
|
||||
from tornado import web
|
||||
|
||||
os.environ['FOO_HOST'] = 'localhost'
|
||||
os.environ['FOO_USER'] = 'postgres'
|
||||
os.environ['FOO_PORT'] = 5432
|
||||
os.environ['FOO_DBNAME'] = 'foo'
|
||||
os.environ['FOO_PASSWORD'] = 'bar'
|
||||
|
||||
class FooRequestHandler(postgresql.HandlerMixin,
|
||||
web.RequestHandler):
|
||||
|
||||
DBNAME = 'foo'
|
||||
|
||||
@web.asynchronous
|
||||
def get(self, *args, **kwargs):
|
||||
result = yield self.foo_session.query('SELECT * FROM baz')
|
||||
self.finish({'data': result.items()})
|
||||
result.free()
|
||||
|
5
docs/history.rst
Normal file
5
docs/history.rst
Normal file
|
@ -0,0 +1,5 @@
|
|||
Version History
|
||||
---------------
|
||||
- 0.0.0 [YYYY-MM-DD]
|
||||
- Change 1
|
||||
- Change 2
|
66
docs/index.rst
Normal file
66
docs/index.rst
Normal file
|
@ -0,0 +1,66 @@
|
|||
sprockets.mixins.postgresql
|
||||
===========================
|
||||
Handler mixins that automatically connect a PostgreSQL client session upon initialization.
|
||||
|
||||
|Version| |Downloads| |Status| |Coverage| |License|
|
||||
|
||||
Installation
|
||||
------------
|
||||
``sprockets.mixins.postgresql`` is available on the
|
||||
`Python Package Index <https://pypi.python.org/pypi/sprockets.mixins.postgresql>`_
|
||||
and can be installed via ``pip`` or ``easy_install``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
pip install sprockets.mixins.postgresql
|
||||
|
||||
Requirements
|
||||
------------
|
||||
- `sprockets <https://github.com/sprockets/sprockets>`_
|
||||
- `sprockets.clients.postgresql <https://github.com/sprockets/sprockets.clients.postgresql>`_
|
||||
|
||||
API Documentation
|
||||
-----------------
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api
|
||||
examples
|
||||
|
||||
Version History
|
||||
---------------
|
||||
See :doc:`history`
|
||||
|
||||
Issues
|
||||
------
|
||||
Please report any issues to the Github project at `https://github.com/sprockets/sprockets.mixins.postgresql/issues <https://github.com/sprockets/sprockets.mixins.postgresql/issues>`_
|
||||
|
||||
Source
|
||||
------
|
||||
``sprockets.mixins.postgresql`` source is available on Github at `https://github.com/sprockets/sprockets.mixins.postgresql <https://github.com/sprockets/sprockets.mixins.postgresql>`_
|
||||
|
||||
License
|
||||
-------
|
||||
``sprockets.mixins.postgresql`` is released under the `3-Clause BSD license <https://github.com/sprockets/sprockets.mixins.postgresql/blob/master/LICENSE>`_.
|
||||
|
||||
Indices and tables
|
||||
------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
.. |Version| image:: https://badge.fury.io/py/sprockets.mixins.postgresql.svg?
|
||||
:target: http://badge.fury.io/py/sprockets.mixins.postgresql
|
||||
|
||||
.. |Status| image:: https://travis-ci.org/sprockets/sprockets.mixins.postgresql.svg?branch=master
|
||||
:target: https://travis-ci.org/sprockets/sprockets.mixins.postgresql
|
||||
|
||||
.. |Coverage| image:: https://img.shields.io/coveralls/sprockets/sprockets.mixins.postgresql.svg?
|
||||
:target: https://coveralls.io/r/sprockets/sprockets.mixins.postgresql
|
||||
|
||||
.. |Downloads| image:: https://pypip.in/d/sprockets.mixins.postgresql/badge.svg?
|
||||
:target: https://pypi.python.org/pypi/sprockets.mixins.postgresql
|
||||
|
||||
.. |License| image:: https://pypip.in/license/sprockets.mixins.postgresql/badge.svg?
|
||||
:target: https://sprocketsmixinspostgresql.readthedocs.org
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
sprockets<2
|
||||
sprockets.clients.postgresql>=1.0.0
|
12
setup.cfg
Normal file
12
setup.cfg
Normal file
|
@ -0,0 +1,12 @@
|
|||
[build_sphinx]
|
||||
all-files = 1
|
||||
source-dir = docs
|
||||
build-dir = build/docs
|
||||
|
||||
[nosetests]
|
||||
with-coverage = 1
|
||||
cover-package = sprockets.mixins.postgresql
|
||||
verbose = 1
|
||||
|
||||
[flake8]
|
||||
exclude = build,dist,docs,env
|
68
setup.py
Normal file
68
setup.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
import codecs
|
||||
import sys
|
||||
|
||||
import setuptools
|
||||
|
||||
|
||||
def read_requirements_file(req_name):
|
||||
requirements = []
|
||||
try:
|
||||
with codecs.open(req_name, encoding='utf-8') as req_file:
|
||||
for req_line in req_file:
|
||||
if '#' in req_line:
|
||||
req_line = req_line[0:req_line.find('#')].strip()
|
||||
if req_line:
|
||||
requirements.append(req_line.strip())
|
||||
except IOError:
|
||||
pass
|
||||
return requirements
|
||||
|
||||
|
||||
install_requires = read_requirements_file('requirements.txt')
|
||||
setup_requires = read_requirements_file('setup-requirements.txt')
|
||||
tests_require = read_requirements_file('test-requirements.txt')
|
||||
|
||||
if sys.version_info < (2, 7):
|
||||
tests_require.append('unittest2')
|
||||
if sys.version_info < (3, 0):
|
||||
tests_require.append('mock')
|
||||
|
||||
setuptools.setup(
|
||||
name='sprockets.mixins.postgresql',
|
||||
version='0.0.0',
|
||||
description='A sprockets mixin that automatically connects to PostgreSQL',
|
||||
long_description=codecs.open('README.rst', encoding='utf-8').read(),
|
||||
url='https://github.com/sprockets/sprockets.mixins.postgresql.git',
|
||||
author='AWeber Communications',
|
||||
author_email='api@aweber.com',
|
||||
license=codecs.open('LICENSE', encoding='utf-8').read(),
|
||||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Natural Language :: English',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules'
|
||||
],
|
||||
packages=['sprockets',
|
||||
'sprockets.mixins',
|
||||
'sprockets.mixins.postgresql'],
|
||||
package_data={'': ['LICENSE', 'README.md']},
|
||||
include_package_data=True,
|
||||
namespace_packages=['sprockets',
|
||||
'sprockets.mixins'],
|
||||
install_requires=install_requires,
|
||||
setup_requires=setup_requires,
|
||||
tests_require=tests_require,
|
||||
test_suite='nose.collector',
|
||||
zip_safe=False)
|
1
sprockets/__init__.py
Normal file
1
sprockets/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
__import__('pkg_resources').declare_namespace(__name__)
|
1
sprockets/mixins/__init__.py
Normal file
1
sprockets/mixins/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
__import__('pkg_resources').declare_namespace(__name__)
|
109
sprockets/mixins/postgresql/__init__.py
Normal file
109
sprockets/mixins/postgresql/__init__.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
"""
|
||||
PostgreSQL Client Mixins
|
||||
========================
|
||||
|
||||
Sprockets mixins that automatically connects to PostgreSQL using
|
||||
`sprockets.clients.postgresql <http://sprocketsclientspostgresql.rtfd.org>`_.
|
||||
|
||||
Handlers implementing one of the mixins should set an attribute called
|
||||
``DBNAME`` that specifies the database name to connect to. The value of
|
||||
``DBNAME`` will be passed into the creation of the
|
||||
:py:class:`Session <sprockets.clients.postgresql.Session>` or
|
||||
:py:class:`TornadoSession <sprockets.clients.postgresql.TornadoSession>`
|
||||
object.
|
||||
|
||||
The Session classes wrap the Queries :py:class:`Session <queries.Session>` or
|
||||
:py:class:`TornadoSession <queries.tornado_session.TornadoSession>` providing
|
||||
environment variable based configuration.
|
||||
|
||||
The environment variables should be set using the ``DBNAME_[VARIABLE]`` format
|
||||
where ``[VARIABLE]`` is one of ``HOST``, ``PORT``, ``DBNAME``, ``USER``, and
|
||||
``PASSWORD``.
|
||||
|
||||
"""
|
||||
version_info = (1, 0, 0)
|
||||
__version__ = '.'.join(str(v) for v in version_info)
|
||||
|
||||
from sprockets.clients import postgresql
|
||||
|
||||
|
||||
class HandlerMixin(object):
|
||||
"""A handler mixin for connecting to PostgreSQL. The mixin automatically
|
||||
creates the database session using the DBNAME attribute of the class as
|
||||
the database name for the
|
||||
:py:class:`Session <sprockets.clients.postgresql.Session>` object
|
||||
creation.
|
||||
|
||||
Using the mixin, the name of the session attribute will be
|
||||
``<dbname>_session``, automatically created when initializing the object.
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from sprockets.mixins import postgresql
|
||||
from tornado import web
|
||||
|
||||
|
||||
class FooRequestHandler(postgresql.HandlerMixin,
|
||||
web.RequestHandler,):
|
||||
|
||||
DBNAME = 'foo'
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
result = self.foo_session.query('SELECT * FROM bar')
|
||||
self.finish({'data': result.items()})
|
||||
|
||||
"""
|
||||
DBNAME = 'postgres'
|
||||
|
||||
def initialize(self):
|
||||
setattr(self,
|
||||
'%s_session' % self.DBNAME,
|
||||
postgresql.Session(self.DBNAME))
|
||||
try:
|
||||
super(HandlerMixin, self).initialize()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
class AsyncHandlerMixin(object):
|
||||
"""A asynchronous Tornado handler mixin for connecting to PostgreSQL. The
|
||||
mixin automatically creates the database session using the DBNAME attribute
|
||||
of the class as the database name for the
|
||||
:py:class:`TornadoSession <sprockets.clients.postgresql.TornadoSession>`
|
||||
object creation.
|
||||
|
||||
Using the mixin, the name of the session attribute will be
|
||||
``<dbname>_session``, automatically created when initializing the object.
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from sprockets.mixins import postgresql
|
||||
from tornado import web
|
||||
|
||||
|
||||
class FooRequestHandler(postgresql.AsyncHandlerMixin,
|
||||
web.RequestHandler):
|
||||
|
||||
DBNAME = 'foo'
|
||||
|
||||
@web.asynchronous
|
||||
def get(self, *args, **kwargs):
|
||||
result = yield self.foo_session.query('SELECT * FROM bar')
|
||||
self.finish({'data': result.items()})
|
||||
result.free()
|
||||
|
||||
"""
|
||||
DBNAME = 'postgres'
|
||||
|
||||
def initialize(self):
|
||||
setattr(self,
|
||||
'%s_session' % self.DBNAME,
|
||||
postgresql.TornadoSession(self.DBNAME))
|
||||
try:
|
||||
super(AsyncHandlerMixin, self).initialize()
|
||||
except AttributeError:
|
||||
pass
|
3
test-requirements.txt
Normal file
3
test-requirements.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
coverage>=3.7,<4
|
||||
coveralls>=0.4,<1
|
||||
nose>=1.3,<2
|
59
tests.py
Normal file
59
tests.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
"""
|
||||
Tests for the sprockets.mixins.postgresql package
|
||||
|
||||
"""
|
||||
import mock
|
||||
import os
|
||||
try:
|
||||
import unittest2 as unittest
|
||||
except ImportError:
|
||||
import unittest
|
||||
|
||||
from sprockets.clients import postgresql as _postgresql
|
||||
from sprockets.mixins import postgresql
|
||||
|
||||
|
||||
class MixinRequestHandler(postgresql.HandlerMixin):
|
||||
DBNAME = 'bar'
|
||||
|
||||
|
||||
class AsyncMixinRequestHandler(postgresql.AsyncHandlerMixin):
|
||||
DBNAME = 'baz'
|
||||
|
||||
|
||||
class HandlerMixinTest(unittest.TestCase):
|
||||
|
||||
@mock.patch('queries.session.Session.__init__')
|
||||
def setUp(self, mock_init):
|
||||
self.mock_init = mock_init
|
||||
|
||||
os.environ['BAR_HOST'] = 'db1'
|
||||
os.environ['BAR_PORT'] = '5433'
|
||||
os.environ['BAR_DBNAME'] = 'bar'
|
||||
os.environ['BAR_USER'] = 'foo'
|
||||
os.environ['BAR_PASSWORD'] = 'baz'
|
||||
self.mixin = MixinRequestHandler()
|
||||
self.mixin.initialize()
|
||||
|
||||
def test_session_get_uri_value(self):
|
||||
self.assertIsInstance(getattr(self.mixin, 'bar_session'),
|
||||
_postgresql.Session)
|
||||
|
||||
|
||||
class AsyncHandlerMixinTest(unittest.TestCase):
|
||||
|
||||
@mock.patch('queries.tornado_session.TornadoSession.__init__')
|
||||
def setUp(self, mock_init):
|
||||
self.mock_init = mock_init
|
||||
|
||||
os.environ['BAZ_HOST'] = 'db2'
|
||||
os.environ['BAZ_PORT'] = '5434'
|
||||
os.environ['BAZ_DBNAME'] = 'baz'
|
||||
os.environ['BAZ_USER'] = 'qux'
|
||||
os.environ['BAZ_PASSWORD'] = 'corgie'
|
||||
self.mixin = AsyncMixinRequestHandler()
|
||||
self.mixin.initialize()
|
||||
|
||||
def test_session_get_uri_value(self):
|
||||
self.assertIsInstance(getattr(self.mixin, 'baz_session'),
|
||||
_postgresql.TornadoSession)
|
Loading…
Reference in a new issue