├── docs
├── _themes
│ ├── .gitignore
│ ├── flask
│ │ ├── theme.conf
│ │ ├── relations.html
│ │ ├── layout.html
│ │ └── static
│ │ │ ├── small_flask.css
│ │ │ └── flasky.css_t
│ ├── flask_small
│ │ ├── theme.conf
│ │ ├── layout.html
│ │ └── static
│ │ │ └── flasky.css_t
│ ├── README
│ ├── LICENSE
│ └── flask_theme_support.py
├── _static
│ └── flask-mongokit.png
├── Makefile
├── make.bat
├── index.rst
└── conf.py
├── tests
├── __main__.py
├── test_decorator_registration.py
├── run.py
├── __init__.py
└── test_base.py
├── MANIFEST.in
├── .gitignore
├── example
├── templates
│ ├── task.html
│ ├── base.html
│ ├── list.html
│ └── new.html
├── static
│ └── style.css
└── todo.py
├── .travis.yml
├── LICENSE
├── setup.py
├── README.rst
└── flask_mongokit.py
/docs/_themes/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.pyo
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/tests/__main__.py:
--------------------------------------------------------------------------------
1 | from run import run
2 |
3 | if __name__ == '__main__':
4 | run()
--------------------------------------------------------------------------------
/docs/_static/flask-mongokit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jarus/flask-mongokit/HEAD/docs/_static/flask-mongokit.png
--------------------------------------------------------------------------------
/ MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE *.py
2 | recursive-include docs *
3 | recursive-exclude docs *.pyc
4 | recursive-exclude docs *.pyo
5 | prune docs/_build
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.pyc
3 | *.pyo
4 | env
5 | env*
6 | dist
7 | *.egg
8 | *.egg-info
9 | _build
10 |
11 | Vagrantfile
12 | .vagrant/
13 |
--------------------------------------------------------------------------------
/example/templates/task.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% block body %}
3 |
Task: {{ task.title }}
4 | Created: {{ task.creation.strftime('%Y-%m-%d %H:%M') }}
5 | {{ task.text }}
6 | {% endblock %}
--------------------------------------------------------------------------------
/docs/_themes/flask/theme.conf:
--------------------------------------------------------------------------------
1 | [theme]
2 | inherit = basic
3 | stylesheet = flasky.css
4 | pygments_style = flask_theme_support.FlaskyStyle
5 |
6 | [options]
7 | index_logo = ''
8 | index_logo_height = 120px
9 | touch_icon =
10 |
--------------------------------------------------------------------------------
/docs/_themes/flask_small/theme.conf:
--------------------------------------------------------------------------------
1 | [theme]
2 | inherit = basic
3 | stylesheet = flasky.css
4 | nosidebar = true
5 | pygments_style = flask_theme_support.FlaskyStyle
6 |
7 | [options]
8 | index_logo = ''
9 | index_logo_height = 120px
10 | github_fork = ''
11 |
--------------------------------------------------------------------------------
/example/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Simple ToDo Example
4 |
5 |
6 |
7 | Simple MongoDB ToDo List
8 | {% block body %}{% endblock %}
9 |
10 |
--------------------------------------------------------------------------------
/tests/test_decorator_registration.py:
--------------------------------------------------------------------------------
1 | from flask_mongokit import Document
2 |
3 | def decorator_registration(self):
4 |
5 | @self.db.register
6 | class DecoratorRegistered(Document):
7 | pass
8 |
9 | assert len(self.db.registered_documents) > 0
10 | assert self.db.registered_documents[0] == DecoratorRegistered
--------------------------------------------------------------------------------
/example/templates/list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% block body %}
3 | All Items
4 |
5 | {% for task in tasks %}
6 | - {{ task.title }} - Created: {{ task.creation.strftime('%Y-%m-%d %H:%M') }}
7 | {% endfor %}
8 |
9 | Add new Task
10 | {% endblock %}
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "2.7"
4 | - "2.6"
5 | env:
6 | - FLASK=0.10.1
7 | - FLASK=0.9
8 | - FLASK=0.8.1
9 | services: mongodb
10 | install:
11 | - pip install coverage --use-mirrors
12 | - pip install flask==$FLASK --use-mirrors
13 | - pip install -e . --use-mirrors
14 | script:
15 | - python tests/run.py
16 | notifications:
17 | email:
18 | - christoph.heer@googlemail.com
--------------------------------------------------------------------------------
/example/templates/new.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% block body %}
3 | New Todo Task
4 |
14 | {% endblock %}
--------------------------------------------------------------------------------
/docs/_themes/flask/relations.html:
--------------------------------------------------------------------------------
1 | Related Topics
2 |
20 |
--------------------------------------------------------------------------------
/docs/_themes/flask_small/layout.html:
--------------------------------------------------------------------------------
1 | {% extends "basic/layout.html" %}
2 | {% block header %}
3 | {{ super() }}
4 | {% if pagename == 'index' %}
5 |
6 | {% endif %}
7 | {% endblock %}
8 | {% block footer %}
9 | {% if pagename == 'index' %}
10 |
11 | {% endif %}
12 | {% endblock %}
13 | {# do not display relbars #}
14 | {% block relbar1 %}{% endblock %}
15 | {% block relbar2 %}
16 | {% if theme_github_fork %}
17 |
19 | {% endif %}
20 | {% endblock %}
21 | {% block sidebar1 %}{% endblock %}
22 | {% block sidebar2 %}{% endblock %}
23 |
--------------------------------------------------------------------------------
/tests/run.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import unittest
3 |
4 | try:
5 | from coverage import coverage
6 | coverage_available = True
7 | except ImportError:
8 | coverage_available = False
9 |
10 |
11 | def run():
12 | if coverage_available:
13 | cov = coverage(source=['flask_mongokit'])
14 | cov.start()
15 |
16 | from tests import suite
17 | result = unittest.TextTestRunner(verbosity=2).run(suite())
18 | if not result.wasSuccessful():
19 | sys.exit(1)
20 |
21 | if coverage_available:
22 | cov.stop()
23 |
24 | print "\nCode Coverage"
25 | cov.report()
26 | cov.html_report(directory='cover')
27 | else:
28 | print("\nTipp:\n\tUse 'pip install coverage' to get great code "
29 | "coverage stats")
30 |
31 | if __name__ == '__main__':
32 | run()
33 |
--------------------------------------------------------------------------------
/docs/_themes/flask/layout.html:
--------------------------------------------------------------------------------
1 | {%- extends "basic/layout.html" %}
2 | {%- block extrahead %}
3 | {{ super() }}
4 | {% if theme_touch_icon %}
5 |
6 | {% endif %}
7 |
9 | {% endblock %}
10 | {%- block relbar2 %}{% endblock %}
11 | {% block header %}
12 | {{ super() }}
13 | {% if pagename == 'index' %}
14 |
15 | {% endif %}
16 | {% endblock %}
17 | {%- block footer %}
18 |
22 | {% if pagename == 'index' %}
23 |
24 | {% endif %}
25 | {%- endblock %}
26 |
--------------------------------------------------------------------------------
/example/static/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | max-width: 480px;
3 | padding: 0 10px;
4 | margin: 0 auto;
5 | font: 1em/1.4 Calibri, sans-serif;
6 | color: #222;
7 | background: #fff;
8 | }
9 |
10 | h1 {
11 | margin: 0.25em 0 0.5em;
12 | font-size: 3.5em;
13 | font-weight: bold;
14 | text-decoration: none;
15 | color: #6EAD1A;
16 | }
17 |
18 | h2 {
19 | margin: 1.25em 0 0.75em;
20 | font-size: 1.5em;
21 | text-decoration: none;
22 | }
23 |
24 | a {
25 | font-weight:bold;
26 | text-decoration: none;
27 | color: #6EAD1A;
28 | }
29 |
30 | a:focus {
31 | outline: thin dotted;
32 | }
33 |
34 | a:hover,
35 | a:active {
36 | outline: 0;
37 | }
38 |
39 | a:hover,
40 | a:focus,
41 | a:active {
42 | text-decoration: underline;
43 | color: #6EAD1A;
44 | }
45 |
46 | strong {
47 | font-weight: bold;
48 | }
49 |
50 | ul {
51 | list-style: square;
52 | padding: 0;
53 | margin: 1.4em 0;
54 | }
55 |
56 | li {
57 | margin: 0.35em 0;
58 | }
59 |
60 | p {
61 | margin: 0 0 1em;
62 | }
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import unittest
3 | from flask import Flask
4 |
5 | from test_base import *
6 |
7 | if sys.version_info > (2, 6):
8 | from test_decorator_registration import decorator_registration
9 | setattr(TestCaseContextIndependent, 'test_decorator_registration',
10 | decorator_registration)
11 |
12 | def suite():
13 | suite = unittest.TestSuite()
14 | suite.addTest(unittest.makeSuite(TestCaseContextIndependent))
15 | suite.addTest(unittest.makeSuite(TestCaseInitAppWithRequestContext))
16 | suite.addTest(unittest.makeSuite(TestCaseWithRequestContext))
17 | suite.addTest(unittest.makeSuite(TestCaseWithRequestContextAuth))
18 | suite.addTest(unittest.makeSuite(TestCaseMultipleAppsWithRequestContext))
19 | if hasattr(Flask, "app_context"):
20 | suite.addTest(unittest.makeSuite(TestCaseInitAppWithAppContext))
21 | suite.addTest(unittest.makeSuite(TestCaseWithAppContext))
22 | suite.addTest(unittest.makeSuite(TestCaseWithAppContextAuth))
23 | suite.addTest(unittest.makeSuite(TestCaseMultipleAppsWithAppContext))
24 | return suite
25 |
26 |
--------------------------------------------------------------------------------
/docs/_themes/README:
--------------------------------------------------------------------------------
1 | Flask Sphinx Styles
2 | ===================
3 |
4 | This repository contains sphinx styles for Flask and Flask related
5 | projects. To use this style in your Sphinx documentation, follow
6 | this guide:
7 |
8 | 1. put this folder as _themes into your docs folder. Alternatively
9 | you can also use git submodules to check out the contents there.
10 | 2. add this to your conf.py:
11 |
12 | sys.path.append(os.path.abspath('_themes'))
13 | html_theme_path = ['_themes']
14 | html_theme = 'flask'
15 |
16 | The following themes exist:
17 |
18 | - 'flask' - the standard flask documentation theme for large
19 | projects
20 | - 'flask_small' - small one-page theme. Intended to be used by
21 | very small addon libraries for flask.
22 |
23 | The following options exist for the flask_small theme:
24 |
25 | [options]
26 | index_logo = '' filename of a picture in _static
27 | to be used as replacement for the
28 | h1 in the index.rst file.
29 | index_logo_height = 120px height of the index logo
30 | github_fork = '' repository name on github for the
31 | "fork me" badge
32 |
--------------------------------------------------------------------------------
/docs/_themes/flask/static/small_flask.css:
--------------------------------------------------------------------------------
1 | /*
2 | * small_flask.css_t
3 | * ~~~~~~~~~~~~~~~~~
4 | *
5 | * :copyright: Copyright 2010 by Armin Ronacher.
6 | * :license: Flask Design License, see LICENSE for details.
7 | */
8 |
9 | body {
10 | margin: 0;
11 | padding: 20px 30px;
12 | }
13 |
14 | div.documentwrapper {
15 | float: none;
16 | background: white;
17 | }
18 |
19 | div.sphinxsidebar {
20 | display: block;
21 | float: none;
22 | width: 102.5%;
23 | margin: 50px -30px -20px -30px;
24 | padding: 10px 20px;
25 | background: #333;
26 | color: white;
27 | }
28 |
29 | div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
30 | div.sphinxsidebar h3 a {
31 | color: white;
32 | }
33 |
34 | div.sphinxsidebar a {
35 | color: #aaa;
36 | }
37 |
38 | div.sphinxsidebar p.logo {
39 | display: none;
40 | }
41 |
42 | div.document {
43 | width: 100%;
44 | margin: 0;
45 | }
46 |
47 | div.related {
48 | display: block;
49 | margin: 0;
50 | padding: 10px 0 20px 0;
51 | }
52 |
53 | div.related ul,
54 | div.related ul li {
55 | margin: 0;
56 | padding: 0;
57 | }
58 |
59 | div.footer {
60 | display: none;
61 | }
62 |
63 | div.bodywrapper {
64 | margin: 0;
65 | }
66 |
67 | div.body {
68 | min-height: 0;
69 | padding: 0;
70 | }
71 |
--------------------------------------------------------------------------------
/example/todo.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from flask import Flask, request, render_template, redirect, url_for
4 | from flask.ext.mongokit import MongoKit, Document
5 |
6 | app = Flask(__name__)
7 |
8 |
9 | class Task(Document):
10 | __collection__ = 'tasks'
11 | structure = {
12 | 'title': unicode,
13 | 'text': unicode,
14 | 'creation': datetime,
15 | }
16 | required_fields = ['title', 'creation']
17 | default_values = {'creation': datetime.utcnow()}
18 | use_dot_notation = True
19 |
20 | db = MongoKit(app)
21 | db.register([Task])
22 |
23 |
24 | @app.route('/')
25 | def show_all():
26 | tasks = db.Task.find()
27 | return render_template('list.html', tasks=tasks)
28 |
29 |
30 | @app.route('/')
31 | def show_task(task_id):
32 | task = db.Task.get_from_id(task_id)
33 | return render_template('task.html', task=task)
34 |
35 |
36 | @app.route('/new', methods=["GET", "POST"])
37 | def new_task():
38 | if request.method == 'POST':
39 | task = db.Task()
40 | task.title = request.form['title']
41 | task.text = request.form['text']
42 | task.save()
43 | return redirect(url_for('show_all'))
44 | return render_template('new.html')
45 |
46 | if __name__ == '__main__':
47 | app.run(debug=True)
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011 by Christoph Heer
2 |
3 | Some rights reserved.
4 |
5 | Redistribution and use in source and binary forms of the software as well
6 | as documentation, with or without modification, are permitted provided
7 | that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above
13 | copyright notice, this list of conditions and the following
14 | disclaimer in the documentation and/or other materials provided
15 | with the distribution.
16 |
17 | * The names of the contributors may not be used to endorse or
18 | promote products derived from this software without specific
19 | prior written permission.
20 |
21 | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
22 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
23 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 | DAMAGE.
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | """
2 | Flask-MongoKit
3 | --------------
4 |
5 | Flask-MongoKit simplifies to use MongoKit, a powerful MongoDB ORM in Flask
6 | applications.
7 |
8 | Links
9 | `````
10 |
11 | * `documentation `_
12 | * `development version `_
13 | * `MongoKit `_
14 | * `Flask `_
15 |
16 | """
17 | import sys
18 | from setuptools import setup
19 |
20 | install_requires = [
21 | "Flask",
22 | "MongoKit"
23 | ]
24 |
25 | if sys.version_info < (2, 6):
26 | install_requires.append('simplejson')
27 |
28 | setup(
29 | name='Flask-MongoKit',
30 | version='0.6',
31 | url='http://github.com/jarus/flask-mongokit',
32 | license='BSD',
33 | author='Christoph Heer',
34 | author_email='Christoph.Heer@googlemail.com',
35 | description='A Flask extension simplifies to use MongoKit',
36 | long_description=__doc__,
37 | py_modules=['flask_mongokit'],
38 | zip_safe=False,
39 | platforms='any',
40 | install_requires=install_requires,
41 | test_suite='tests.suite',
42 | classifiers=[
43 | 'Development Status :: 4 - Beta',
44 | 'Environment :: Web Environment',
45 | 'Intended Audience :: Developers',
46 | 'License :: OSI Approved :: BSD License',
47 | 'Operating System :: OS Independent',
48 | 'Programming Language :: Python',
49 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
50 | 'Topic :: Software Development :: Libraries :: Python Modules'
51 | ]
52 | )
53 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Flask-MongoKit
2 | ==============
3 |
4 | .. image:: https://secure.travis-ci.org/jarus/flask-mongokit.png
5 | :target: http://travis-ci.org/jarus/flask-mongokit
6 |
7 | Flask-MongoKit simplifies to use `MongoKit`_, a powerful `MongoDB`_ ORM
8 | in Flask applications.
9 |
10 | .. _MongoKit: http://namlook.github.com/mongokit/
11 | .. _MongoDB: http://www.mongodb.org/
12 | .. _here: http://bitbucket.org/Jarus/flask-mongokit/
13 |
14 | Installation
15 | ------------
16 | The installation is thanks to the Python Package Index and `pip`_ really simple.
17 |
18 | ::
19 |
20 | $ pip install Flask-MongoKit
21 |
22 | If you only can use `easy_install` than use
23 |
24 | ::
25 |
26 | $ easy_install Flask-MongoKit
27 |
28 | .. _pip: http://pip.openplans.org/
29 |
30 | Flask-MongoKit requires to run some packages (they will be installed automatically if they not already installed):
31 |
32 | * Flask
33 | * MongoKit
34 | * pymongo
35 |
36 | Changelog
37 | =========
38 |
39 | * **0.6 (08.07.2012)**
40 |
41 | * Use the new app context and again the old request context.
42 | * The MongoKit object is now subscriptable and support the typical syntax to
43 | get a collection.::
44 |
45 | db['my_collection'].insert({'x': 5})
46 |
47 | * Restructured and improved test suite.
48 | * Sounds crazy but improved python2.5 support.
49 |
50 | * **0.5 (02.07.2012)**
51 |
52 | * You don't need a request context anymore for the mongodb connection.
53 | (A bad decision ... look in 0.6)
54 |
55 | * **0.4 (23.02.2012)**
56 |
57 | * Support new import system of flask. Use now::
58 |
59 | from flask.ext.mongokit import Mongokit
60 |
--------------------------------------------------------------------------------
/docs/_themes/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 by Armin Ronacher.
2 |
3 | Some rights reserved.
4 |
5 | Redistribution and use in source and binary forms of the theme, with or
6 | without modification, are permitted provided that the following conditions
7 | are met:
8 |
9 | * Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above
13 | copyright notice, this list of conditions and the following
14 | disclaimer in the documentation and/or other materials provided
15 | with the distribution.
16 |
17 | * The names of the contributors may not be used to endorse or
18 | promote products derived from this software without specific
19 | prior written permission.
20 |
21 | We kindly ask you to only use these themes in an unmodified manner just
22 | for Flask and Flask-related products, not for unrelated projects. If you
23 | like the visual style and want to use it for your own projects, please
24 | consider making some larger changes to the themes (such as changing
25 | font faces, sizes, colors or margins).
26 |
27 | THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 | ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
37 | POSSIBILITY OF SUCH DAMAGE.
38 |
--------------------------------------------------------------------------------
/docs/_themes/flask_theme_support.py:
--------------------------------------------------------------------------------
1 | # flasky extensions. flasky pygments style based on tango style
2 | from pygments.style import Style
3 | from pygments.token import Keyword, Name, Comment, String, Error, \
4 | Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
5 |
6 |
7 | class FlaskyStyle(Style):
8 | background_color = "#f8f8f8"
9 | default_style = ""
10 |
11 | styles = {
12 | # No corresponding class for the following:
13 | #Text: "", # class: ''
14 | Whitespace: "underline #f8f8f8", # class: 'w'
15 | Error: "#a40000 border:#ef2929", # class: 'err'
16 | Other: "#000000", # class 'x'
17 |
18 | Comment: "italic #8f5902", # class: 'c'
19 | Comment.Preproc: "noitalic", # class: 'cp'
20 |
21 | Keyword: "bold #004461", # class: 'k'
22 | Keyword.Constant: "bold #004461", # class: 'kc'
23 | Keyword.Declaration: "bold #004461", # class: 'kd'
24 | Keyword.Namespace: "bold #004461", # class: 'kn'
25 | Keyword.Pseudo: "bold #004461", # class: 'kp'
26 | Keyword.Reserved: "bold #004461", # class: 'kr'
27 | Keyword.Type: "bold #004461", # class: 'kt'
28 |
29 | Operator: "#582800", # class: 'o'
30 | Operator.Word: "bold #004461", # class: 'ow' - like keywords
31 |
32 | Punctuation: "bold #000000", # class: 'p'
33 |
34 | # because special names such as Name.Class, Name.Function, etc.
35 | # are not recognized as such later in the parsing, we choose them
36 | # to look the same as ordinary variables.
37 | Name: "#000000", # class: 'n'
38 | Name.Attribute: "#c4a000", # class: 'na' - to be revised
39 | Name.Builtin: "#004461", # class: 'nb'
40 | Name.Builtin.Pseudo: "#3465a4", # class: 'bp'
41 | Name.Class: "#000000", # class: 'nc' - to be revised
42 | Name.Constant: "#000000", # class: 'no' - to be revised
43 | Name.Decorator: "#888", # class: 'nd' - to be revised
44 | Name.Entity: "#ce5c00", # class: 'ni'
45 | Name.Exception: "bold #cc0000", # class: 'ne'
46 | Name.Function: "#000000", # class: 'nf'
47 | Name.Property: "#000000", # class: 'py'
48 | Name.Label: "#f57900", # class: 'nl'
49 | Name.Namespace: "#000000", # class: 'nn' - to be revised
50 | Name.Other: "#000000", # class: 'nx'
51 | Name.Tag: "bold #004461", # class: 'nt' - like a keyword
52 | Name.Variable: "#000000", # class: 'nv' - to be revised
53 | Name.Variable.Class: "#000000", # class: 'vc' - to be revised
54 | Name.Variable.Global: "#000000", # class: 'vg' - to be revised
55 | Name.Variable.Instance: "#000000", # class: 'vi' - to be revised
56 |
57 | Number: "#990000", # class: 'm'
58 |
59 | Literal: "#000000", # class: 'l'
60 | Literal.Date: "#000000", # class: 'ld'
61 |
62 | String: "#4e9a06", # class: 's'
63 | String.Backtick: "#4e9a06", # class: 'sb'
64 | String.Char: "#4e9a06", # class: 'sc'
65 | String.Doc: "italic #8f5902", # class: 'sd' - like a comment
66 | String.Double: "#4e9a06", # class: 's2'
67 | String.Escape: "#4e9a06", # class: 'se'
68 | String.Heredoc: "#4e9a06", # class: 'sh'
69 | String.Interpol: "#4e9a06", # class: 'si'
70 | String.Other: "#4e9a06", # class: 'sx'
71 | String.Regex: "#4e9a06", # class: 'sr'
72 | String.Single: "#4e9a06", # class: 's1'
73 | String.Symbol: "#4e9a06", # class: 'ss'
74 |
75 | Generic: "#000000", # class: 'g'
76 | Generic.Deleted: "#a40000", # class: 'gd'
77 | Generic.Emph: "italic #000000", # class: 'ge'
78 | Generic.Error: "#ef2929", # class: 'gr'
79 | Generic.Heading: "bold #000080", # class: 'gh'
80 | Generic.Inserted: "#00A000", # class: 'gi'
81 | Generic.Output: "#888", # class: 'go'
82 | Generic.Prompt: "#745334", # class: 'gp'
83 | Generic.Strong: "bold #000000", # class: 'gs'
84 | Generic.Subheading: "bold #800080", # class: 'gu'
85 | Generic.Traceback: "bold #a40000", # class: 'gt'
86 | }
87 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # Internal variables.
11 | PAPEROPT_a4 = -D latex_paper_size=a4
12 | PAPEROPT_letter = -D latex_paper_size=letter
13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
14 |
15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
16 |
17 | help:
18 | @echo "Please use \`make ' where is one of"
19 | @echo " html to make standalone HTML files"
20 | @echo " dirhtml to make HTML files named index.html in directories"
21 | @echo " singlehtml to make a single large HTML file"
22 | @echo " pickle to make pickle files"
23 | @echo " json to make JSON files"
24 | @echo " htmlhelp to make HTML files and a HTML help project"
25 | @echo " qthelp to make HTML files and a qthelp project"
26 | @echo " devhelp to make HTML files and a Devhelp project"
27 | @echo " epub to make an epub"
28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
29 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
30 | @echo " text to make text files"
31 | @echo " man to make manual pages"
32 | @echo " changes to make an overview of all changed/added/deprecated items"
33 | @echo " linkcheck to check all external links for integrity"
34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
35 |
36 | clean:
37 | -rm -rf $(BUILDDIR)/*
38 |
39 | html:
40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
41 | @echo
42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
43 |
44 | dirhtml:
45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
46 | @echo
47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
48 |
49 | singlehtml:
50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
51 | @echo
52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
53 |
54 | pickle:
55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
56 | @echo
57 | @echo "Build finished; now you can process the pickle files."
58 |
59 | json:
60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
61 | @echo
62 | @echo "Build finished; now you can process the JSON files."
63 |
64 | htmlhelp:
65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
66 | @echo
67 | @echo "Build finished; now you can run HTML Help Workshop with the" \
68 | ".hhp project file in $(BUILDDIR)/htmlhelp."
69 |
70 | qthelp:
71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
72 | @echo
73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Flask-MongoKit.qhcp"
76 | @echo "To view the help file:"
77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Flask-MongoKit.qhc"
78 |
79 | devhelp:
80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
81 | @echo
82 | @echo "Build finished."
83 | @echo "To view the help file:"
84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Flask-MongoKit"
85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Flask-MongoKit"
86 | @echo "# devhelp"
87 |
88 | epub:
89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
90 | @echo
91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
92 |
93 | latex:
94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
95 | @echo
96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
98 | "(use \`make latexpdf' here to do that automatically)."
99 |
100 | latexpdf:
101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
102 | @echo "Running LaTeX files through pdflatex..."
103 | make -C $(BUILDDIR)/latex all-pdf
104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
105 |
106 | text:
107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
108 | @echo
109 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
110 |
111 | man:
112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
113 | @echo
114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
115 |
116 | changes:
117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
118 | @echo
119 | @echo "The overview file is in $(BUILDDIR)/changes."
120 |
121 | linkcheck:
122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
123 | @echo
124 | @echo "Link check complete; look for any errors in the above output " \
125 | "or in $(BUILDDIR)/linkcheck/output.txt."
126 |
127 | doctest:
128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
129 | @echo "Testing of doctests in the sources finished, look at the " \
130 | "results in $(BUILDDIR)/doctest/output.txt."
131 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | if NOT "%PAPER%" == "" (
11 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
12 | )
13 |
14 | if "%1" == "" goto help
15 |
16 | if "%1" == "help" (
17 | :help
18 | echo.Please use `make ^` where ^ is one of
19 | echo. html to make standalone HTML files
20 | echo. dirhtml to make HTML files named index.html in directories
21 | echo. singlehtml to make a single large HTML file
22 | echo. pickle to make pickle files
23 | echo. json to make JSON files
24 | echo. htmlhelp to make HTML files and a HTML help project
25 | echo. qthelp to make HTML files and a qthelp project
26 | echo. devhelp to make HTML files and a Devhelp project
27 | echo. epub to make an epub
28 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
29 | echo. text to make text files
30 | echo. man to make manual pages
31 | echo. changes to make an overview over all changed/added/deprecated items
32 | echo. linkcheck to check all external links for integrity
33 | echo. doctest to run all doctests embedded in the documentation if enabled
34 | goto end
35 | )
36 |
37 | if "%1" == "clean" (
38 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
39 | del /q /s %BUILDDIR%\*
40 | goto end
41 | )
42 |
43 | if "%1" == "html" (
44 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
45 | if errorlevel 1 exit /b 1
46 | echo.
47 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
48 | goto end
49 | )
50 |
51 | if "%1" == "dirhtml" (
52 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
53 | if errorlevel 1 exit /b 1
54 | echo.
55 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
56 | goto end
57 | )
58 |
59 | if "%1" == "singlehtml" (
60 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
61 | if errorlevel 1 exit /b 1
62 | echo.
63 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
64 | goto end
65 | )
66 |
67 | if "%1" == "pickle" (
68 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
69 | if errorlevel 1 exit /b 1
70 | echo.
71 | echo.Build finished; now you can process the pickle files.
72 | goto end
73 | )
74 |
75 | if "%1" == "json" (
76 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
77 | if errorlevel 1 exit /b 1
78 | echo.
79 | echo.Build finished; now you can process the JSON files.
80 | goto end
81 | )
82 |
83 | if "%1" == "htmlhelp" (
84 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
85 | if errorlevel 1 exit /b 1
86 | echo.
87 | echo.Build finished; now you can run HTML Help Workshop with the ^
88 | .hhp project file in %BUILDDIR%/htmlhelp.
89 | goto end
90 | )
91 |
92 | if "%1" == "qthelp" (
93 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
94 | if errorlevel 1 exit /b 1
95 | echo.
96 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
97 | .qhcp project file in %BUILDDIR%/qthelp, like this:
98 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Flask-MongoKit.qhcp
99 | echo.To view the help file:
100 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Flask-MongoKit.ghc
101 | goto end
102 | )
103 |
104 | if "%1" == "devhelp" (
105 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
106 | if errorlevel 1 exit /b 1
107 | echo.
108 | echo.Build finished.
109 | goto end
110 | )
111 |
112 | if "%1" == "epub" (
113 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
114 | if errorlevel 1 exit /b 1
115 | echo.
116 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
117 | goto end
118 | )
119 |
120 | if "%1" == "latex" (
121 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
122 | if errorlevel 1 exit /b 1
123 | echo.
124 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
125 | goto end
126 | )
127 |
128 | if "%1" == "text" (
129 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
130 | if errorlevel 1 exit /b 1
131 | echo.
132 | echo.Build finished. The text files are in %BUILDDIR%/text.
133 | goto end
134 | )
135 |
136 | if "%1" == "man" (
137 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
138 | if errorlevel 1 exit /b 1
139 | echo.
140 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
141 | goto end
142 | )
143 |
144 | if "%1" == "changes" (
145 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
146 | if errorlevel 1 exit /b 1
147 | echo.
148 | echo.The overview file is in %BUILDDIR%/changes.
149 | goto end
150 | )
151 |
152 | if "%1" == "linkcheck" (
153 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
154 | if errorlevel 1 exit /b 1
155 | echo.
156 | echo.Link check complete; look for any errors in the above output ^
157 | or in %BUILDDIR%/linkcheck/output.txt.
158 | goto end
159 | )
160 |
161 | if "%1" == "doctest" (
162 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
163 | if errorlevel 1 exit /b 1
164 | echo.
165 | echo.Testing of doctests in the sources finished, look at the ^
166 | results in %BUILDDIR%/doctest/output.txt.
167 | goto end
168 | )
169 |
170 | :end
171 |
--------------------------------------------------------------------------------
/docs/_themes/flask_small/static/flasky.css_t:
--------------------------------------------------------------------------------
1 | /*
2 | * flasky.css_t
3 | * ~~~~~~~~~~~~
4 | *
5 | * Sphinx stylesheet -- flasky theme based on nature theme.
6 | *
7 | * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | @import url("basic.css");
13 |
14 | /* -- page layout ----------------------------------------------------------- */
15 |
16 | body {
17 | font-family: 'Georgia', serif;
18 | font-size: 17px;
19 | color: #000;
20 | background: white;
21 | margin: 0;
22 | padding: 0;
23 | }
24 |
25 | div.documentwrapper {
26 | float: left;
27 | width: 100%;
28 | }
29 |
30 | div.bodywrapper {
31 | margin: 40px auto 0 auto;
32 | width: 700px;
33 | }
34 |
35 | hr {
36 | border: 1px solid #B1B4B6;
37 | }
38 |
39 | div.body {
40 | background-color: #ffffff;
41 | color: #3E4349;
42 | padding: 0 30px 30px 30px;
43 | }
44 |
45 | img.floatingflask {
46 | padding: 0 0 10px 10px;
47 | float: right;
48 | }
49 |
50 | div.footer {
51 | text-align: right;
52 | color: #888;
53 | padding: 10px;
54 | font-size: 14px;
55 | width: 650px;
56 | margin: 0 auto 40px auto;
57 | }
58 |
59 | div.footer a {
60 | color: #888;
61 | text-decoration: underline;
62 | }
63 |
64 | div.related {
65 | line-height: 32px;
66 | color: #888;
67 | }
68 |
69 | div.related ul {
70 | padding: 0 0 0 10px;
71 | }
72 |
73 | div.related a {
74 | color: #444;
75 | }
76 |
77 | /* -- body styles ----------------------------------------------------------- */
78 |
79 | a {
80 | color: #004B6B;
81 | text-decoration: underline;
82 | }
83 |
84 | a:hover {
85 | color: #6D4100;
86 | text-decoration: underline;
87 | }
88 |
89 | div.body {
90 | padding-bottom: 40px; /* saved for footer */
91 | }
92 |
93 | div.body h1,
94 | div.body h2,
95 | div.body h3,
96 | div.body h4,
97 | div.body h5,
98 | div.body h6 {
99 | font-family: 'Garamond', 'Georgia', serif;
100 | font-weight: normal;
101 | margin: 30px 0px 10px 0px;
102 | padding: 0;
103 | }
104 |
105 | {% if theme_index_logo %}
106 | div.indexwrapper h1 {
107 | text-indent: -999999px;
108 | background: url({{ theme_index_logo }}) no-repeat center center;
109 | height: {{ theme_index_logo_height }};
110 | }
111 | {% endif %}
112 |
113 | div.body h2 { font-size: 180%; }
114 | div.body h3 { font-size: 150%; }
115 | div.body h4 { font-size: 130%; }
116 | div.body h5 { font-size: 100%; }
117 | div.body h6 { font-size: 100%; }
118 |
119 | a.headerlink {
120 | color: white;
121 | padding: 0 4px;
122 | text-decoration: none;
123 | }
124 |
125 | a.headerlink:hover {
126 | color: #444;
127 | background: #eaeaea;
128 | }
129 |
130 | div.body p, div.body dd, div.body li {
131 | line-height: 1.4em;
132 | }
133 |
134 | div.admonition {
135 | background: #fafafa;
136 | margin: 20px -30px;
137 | padding: 10px 30px;
138 | border-top: 1px solid #ccc;
139 | border-bottom: 1px solid #ccc;
140 | }
141 |
142 | div.admonition p.admonition-title {
143 | font-family: 'Garamond', 'Georgia', serif;
144 | font-weight: normal;
145 | font-size: 24px;
146 | margin: 0 0 10px 0;
147 | padding: 0;
148 | line-height: 1;
149 | }
150 |
151 | div.admonition p.last {
152 | margin-bottom: 0;
153 | }
154 |
155 | div.highlight{
156 | background-color: white;
157 | }
158 |
159 | dt:target, .highlight {
160 | background: #FAF3E8;
161 | }
162 |
163 | div.note {
164 | background-color: #eee;
165 | border: 1px solid #ccc;
166 | }
167 |
168 | div.seealso {
169 | background-color: #ffc;
170 | border: 1px solid #ff6;
171 | }
172 |
173 | div.topic {
174 | background-color: #eee;
175 | }
176 |
177 | div.warning {
178 | background-color: #ffe4e4;
179 | border: 1px solid #f66;
180 | }
181 |
182 | p.admonition-title {
183 | display: inline;
184 | }
185 |
186 | p.admonition-title:after {
187 | content: ":";
188 | }
189 |
190 | pre, tt {
191 | font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
192 | font-size: 0.85em;
193 | }
194 |
195 | img.screenshot {
196 | }
197 |
198 | tt.descname, tt.descclassname {
199 | font-size: 0.95em;
200 | }
201 |
202 | tt.descname {
203 | padding-right: 0.08em;
204 | }
205 |
206 | img.screenshot {
207 | -moz-box-shadow: 2px 2px 4px #eee;
208 | -webkit-box-shadow: 2px 2px 4px #eee;
209 | box-shadow: 2px 2px 4px #eee;
210 | }
211 |
212 | table.docutils {
213 | border: 1px solid #888;
214 | -moz-box-shadow: 2px 2px 4px #eee;
215 | -webkit-box-shadow: 2px 2px 4px #eee;
216 | box-shadow: 2px 2px 4px #eee;
217 | }
218 |
219 | table.docutils td, table.docutils th {
220 | border: 1px solid #888;
221 | padding: 0.25em 0.7em;
222 | }
223 |
224 | table.field-list, table.footnote {
225 | border: none;
226 | -moz-box-shadow: none;
227 | -webkit-box-shadow: none;
228 | box-shadow: none;
229 | }
230 |
231 | table.footnote {
232 | margin: 15px 0;
233 | width: 100%;
234 | border: 1px solid #eee;
235 | }
236 |
237 | table.field-list th {
238 | padding: 0 0.8em 0 0;
239 | }
240 |
241 | table.field-list td {
242 | padding: 0;
243 | }
244 |
245 | table.footnote td {
246 | padding: 0.5em;
247 | }
248 |
249 | dl {
250 | margin: 0;
251 | padding: 0;
252 | }
253 |
254 | dl dd {
255 | margin-left: 30px;
256 | }
257 |
258 | pre {
259 | padding: 0;
260 | margin: 15px -30px;
261 | padding: 8px;
262 | line-height: 1.3em;
263 | padding: 7px 30px;
264 | background: #eee;
265 | border-radius: 2px;
266 | -moz-border-radius: 2px;
267 | -webkit-border-radius: 2px;
268 | }
269 |
270 | dl pre {
271 | margin-left: -60px;
272 | padding-left: 60px;
273 | }
274 |
275 | tt {
276 | background-color: #ecf0f3;
277 | color: #222;
278 | /* padding: 1px 2px; */
279 | }
280 |
281 | tt.xref, a tt {
282 | background-color: #FBFBFB;
283 | }
284 |
285 | a:hover tt {
286 | background: #EEE;
287 | }
288 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | ==============
2 | Flask-MongoKit
3 | ==============
4 | .. currentmodule:: flask_mongokit
5 |
6 | Flask-MongoKit simplifies to use `MongoKit`_, a powerful `MongoDB`_ ORM
7 | in Flask applications. If you find bugs or want to support this extension you can find the source code `here`_.
8 |
9 | .. _MongoKit: http://namlook.github.com/mongokit/
10 | .. _MongoDB: http://www.mongodb.org/
11 | .. _here: https://github.com/jarus/flask-mongokit/
12 |
13 | Installation
14 | ============
15 | The installation is thanks to the Python Package Index and `pip`_ really simple.
16 |
17 | .. code-block:: console
18 |
19 | $ pip install Flask-MongoKit
20 |
21 | If you only can use `easy_install` than use
22 |
23 | .. code-block:: console
24 |
25 | $ easy_install Flask-MongoKit
26 |
27 | .. _pip: http://pip.openplans.org/
28 |
29 | Flask-MongoKit requires to run some packages (they will be installed automatically if they not already installed):
30 |
31 | * Flask
32 | * MongoKit
33 | * pymongo
34 |
35 | Your first Document
36 | ===================
37 | It is very simple to use MongoKit in your Flask application. Let's create a simple ToDo application.
38 |
39 | .. code-block:: python
40 |
41 | from datetime import datetime
42 |
43 | from flask import Flask, request, render_template, redirect, url_for
44 | from flask.ext.mongokit import MongoKit, Document
45 |
46 | app = Flask(__name__)
47 |
48 | class Task(Document):
49 | __collection__ = 'tasks'
50 | structure = {
51 | 'title': unicode,
52 | 'text': unicode,
53 | 'creation': datetime,
54 | }
55 | required_fields = ['title', 'creation']
56 | default_values = {'creation': datetime.utcnow}
57 | use_dot_notation = True
58 |
59 | db = MongoKit(app)
60 | db.register([Task])
61 |
62 | As you can see we create a document model as class *Task* which uses Document from flask.ext.mongokit as parent class. In this model we describe the structure of our document and we can set a list of required fields and default values. The :class:`flask.ext.mongokit.Document` is beside some extensions the same like :class:`mongokit.Document` so if you want to know more about the core features of the Document class please look into the `MongoKit documentation`_. For using the the document model we must register it with the connection. But we use the :meth:`~flask.ext.mongokit.MongoKit.register` method from the :class:`flask.ext.mongokit.MongoKit` class.
63 |
64 | Now we need a view to add a new task like this.
65 |
66 | .. code-block:: python
67 |
68 | @app.route('/new', methods=["GET", "POST"])
69 | def new_task():
70 | if request.method == 'POST':
71 | task = db.Task()
72 | task.title = request.form['title']
73 | task.text = request.form['text']
74 | task.save()
75 | return redirect(url_for('show_all'))
76 | return render_template('new.html')
77 |
78 | If someone now clicks on the submit button of the form your application will create a new instance of your Task model class. After that we set title and text of the task and save it into your MongoDB.
79 |
80 | But now we want to get a list of task, so we add an other view.
81 |
82 | .. code-block:: python
83 |
84 | @app.route('/')
85 | def show_all():
86 | tasks = db.Task.find()
87 | return render_template('list.html', tasks=tasks)
88 |
89 | This view is very simple. You can see we only call the :meth:`find` method and put the result into our template. Now we have a running example that works simple with a MongoDB inside a Flask application.
90 |
91 | If you want to see a full example of Flask-MongoKit look inside the repository. You will find there this ToDo application with the matching templates.
92 |
93 | .. _MongoKit documentation: http://namlook.github.com/mongokit/descriptors.html
94 |
95 | Configuration values
96 | --------------------
97 |
98 | The following configuration variables are used in Flask-MongoKit:
99 |
100 | .. tabularcolumns:: |p{6.5cm}|p{8.5cm}|
101 |
102 | =============================== =========================================
103 | ``MONGODB_DATABASE`` The database name that should used.
104 |
105 | *Default value:* ``flask``
106 | ``MONGODB_HOST`` Hostname or IP address of the MongoDB host.
107 |
108 | *Default value:* ``localhost``
109 | ``MONGODB_PORT`` Listening port of the MongoDB host.
110 |
111 | *Default value:* ``27017``
112 | ``MONGODB_USERNAME`` If you need authentication than you can set
113 | there your username.
114 |
115 | *Default value:* ``None``
116 | ``MONGODB_PASSWORD`` Password for authentication.
117 |
118 | *Default value:* ``None``
119 | ``MONGODB_TZ_AWARE`` It sets the tz_aware parameter to True when
120 | creating a connection. The timezone of datetime
121 | objects returned from MongoDB will always be UTC.
122 |
123 | *Default value:* ``False``
124 | =============================== =========================================
125 |
126 | .. _request-app-context:
127 |
128 | Request and App context
129 | -----------------------
130 |
131 | If you want to make some operations on your MongoDB with Flask-MongoKit you need a context like the request or app context. If you want to use it for example in Flask-Script than the best choise is the app context (implemented since Flask v0.9). There is a small example how to use the app context.::
132 |
133 | from flask import Flask
134 | from flask.ext.mongokit import MongoKit
135 |
136 | app = Flask(__name__)
137 | db = MongoKit(app)
138 |
139 | with app.app_context():
140 | db['my_collection'].insert({'x': 5})
141 | print db['my_collection'].find_one({'x': 5})
142 |
143 | You can also use it in the normal request context like insite of a view function or in the test request context like the following example.::
144 |
145 | with app.test_request_context('/'):
146 | db['my_collection'].insert({'x': 5})
147 | print db['my_collection'].find_one({'x': 5})
148 |
149 | Changelog
150 | =========
151 |
152 | * **0.6 (08.07.2012)**
153 |
154 | * Use the new app context and again the old request context,
155 | see :ref:`request-app-context`.
156 | * The MongoKit object is now subscriptable and support the typical syntax to
157 | get a collection.::
158 |
159 | db['my_collection'].insert({'x': 5})
160 |
161 | * Restructured and improved test suite.
162 | * Sounds crazy but improved python2.5 support.
163 |
164 | * **0.5 (02.07.2012)**
165 |
166 | * You don't need a request context anymore for the mongodb connection.
167 | (A bad decision ... look in 0.6)
168 |
169 | * **0.4 (23.02.2012)**
170 |
171 | * Support new import system of flask. Use now::
172 |
173 | form flask.ext.mongokit import Mongokit
174 |
175 |
176 | API Documentation
177 | =================
178 |
179 | .. autoclass:: MongoKit
180 | :members:
181 |
182 | .. autoclass:: Document
183 | :members:
184 |
185 | .. autoclass:: BSONObjectIdConverter
186 | :members:
187 |
--------------------------------------------------------------------------------
/docs/_themes/flask/static/flasky.css_t:
--------------------------------------------------------------------------------
1 | /*
2 | * flasky.css_t
3 | * ~~~~~~~~~~~~
4 | *
5 | * :copyright: Copyright 2010 by Armin Ronacher.
6 | * :license: Flask Design License, see LICENSE for details.
7 | */
8 |
9 | {% set page_width = '940px' %}
10 | {% set sidebar_width = '220px' %}
11 |
12 | @import url("basic.css");
13 |
14 | /* -- page layout ----------------------------------------------------------- */
15 |
16 | body {
17 | font-family: 'Georgia', serif;
18 | font-size: 17px;
19 | background-color: white;
20 | color: #000;
21 | margin: 0;
22 | padding: 0;
23 | }
24 |
25 | div.document {
26 | width: {{ page_width }};
27 | margin: 30px auto 0 auto;
28 | }
29 |
30 | div.documentwrapper {
31 | float: left;
32 | width: 100%;
33 | }
34 |
35 | div.bodywrapper {
36 | margin: 0 0 0 {{ sidebar_width }};
37 | }
38 |
39 | div.sphinxsidebar {
40 | width: {{ sidebar_width }};
41 | }
42 |
43 | hr {
44 | border: 1px solid #B1B4B6;
45 | }
46 |
47 | div.body {
48 | background-color: #ffffff;
49 | color: #3E4349;
50 | padding: 0 30px 0 30px;
51 | }
52 |
53 | img.floatingflask {
54 | padding: 0 0 10px 10px;
55 | float: right;
56 | }
57 |
58 | div.footer {
59 | width: {{ page_width }};
60 | margin: 20px auto 30px auto;
61 | font-size: 14px;
62 | color: #888;
63 | text-align: right;
64 | }
65 |
66 | div.footer a {
67 | color: #888;
68 | }
69 |
70 | div.related {
71 | display: none;
72 | }
73 |
74 | div.sphinxsidebar a {
75 | color: #444;
76 | text-decoration: none;
77 | border-bottom: 1px dotted #999;
78 | }
79 |
80 | div.sphinxsidebar a:hover {
81 | border-bottom: 1px solid #999;
82 | }
83 |
84 | div.sphinxsidebar {
85 | font-size: 14px;
86 | line-height: 1.5;
87 | }
88 |
89 | div.sphinxsidebarwrapper {
90 | padding: 18px 10px;
91 | }
92 |
93 | div.sphinxsidebarwrapper p.logo {
94 | padding: 0 0 20px 0;
95 | margin: 0;
96 | text-align: center;
97 | }
98 |
99 | div.sphinxsidebar h3,
100 | div.sphinxsidebar h4 {
101 | font-family: 'Garamond', 'Georgia', serif;
102 | color: #444;
103 | font-size: 24px;
104 | font-weight: normal;
105 | margin: 0 0 5px 0;
106 | padding: 0;
107 | }
108 |
109 | div.sphinxsidebar h4 {
110 | font-size: 20px;
111 | }
112 |
113 | div.sphinxsidebar h3 a {
114 | color: #444;
115 | }
116 |
117 | div.sphinxsidebar p.logo a,
118 | div.sphinxsidebar h3 a,
119 | div.sphinxsidebar p.logo a:hover,
120 | div.sphinxsidebar h3 a:hover {
121 | border: none;
122 | }
123 |
124 | div.sphinxsidebar p {
125 | color: #555;
126 | margin: 10px 0;
127 | }
128 |
129 | div.sphinxsidebar ul {
130 | margin: 10px 0;
131 | padding: 0;
132 | color: #000;
133 | }
134 |
135 | div.sphinxsidebar input {
136 | border: 1px solid #ccc;
137 | font-family: 'Georgia', serif;
138 | font-size: 1em;
139 | }
140 |
141 | /* -- body styles ----------------------------------------------------------- */
142 |
143 | a {
144 | color: #004B6B;
145 | text-decoration: underline;
146 | }
147 |
148 | a:hover {
149 | color: #6D4100;
150 | text-decoration: underline;
151 | }
152 |
153 | div.body h1,
154 | div.body h2,
155 | div.body h3,
156 | div.body h4,
157 | div.body h5,
158 | div.body h6 {
159 | font-family: 'Garamond', 'Georgia', serif;
160 | font-weight: normal;
161 | margin: 30px 0px 10px 0px;
162 | padding: 0;
163 | }
164 |
165 | {% if theme_index_logo %}
166 | div.indexwrapper h1 {
167 | text-indent: -999999px;
168 | background: url({{ theme_index_logo }}) no-repeat center center;
169 | height: {{ theme_index_logo_height }};
170 | }
171 | {% endif %}
172 |
173 | div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
174 | div.body h2 { font-size: 180%; }
175 | div.body h3 { font-size: 150%; }
176 | div.body h4 { font-size: 130%; }
177 | div.body h5 { font-size: 100%; }
178 | div.body h6 { font-size: 100%; }
179 |
180 | a.headerlink {
181 | color: #ddd;
182 | padding: 0 4px;
183 | text-decoration: none;
184 | }
185 |
186 | a.headerlink:hover {
187 | color: #444;
188 | background: #eaeaea;
189 | }
190 |
191 | div.body p, div.body dd, div.body li {
192 | line-height: 1.4em;
193 | }
194 |
195 | div.admonition {
196 | background: #fafafa;
197 | margin: 20px -30px;
198 | padding: 10px 30px;
199 | border-top: 1px solid #ccc;
200 | border-bottom: 1px solid #ccc;
201 | }
202 |
203 | div.admonition tt.xref, div.admonition a tt {
204 | border-bottom: 1px solid #fafafa;
205 | }
206 |
207 | dd div.admonition {
208 | margin-left: -60px;
209 | padding-left: 60px;
210 | }
211 |
212 | div.admonition p.admonition-title {
213 | font-family: 'Garamond', 'Georgia', serif;
214 | font-weight: normal;
215 | font-size: 24px;
216 | margin: 0 0 10px 0;
217 | padding: 0;
218 | line-height: 1;
219 | }
220 |
221 | div.admonition p.last {
222 | margin-bottom: 0;
223 | }
224 |
225 | div.highlight {
226 | background-color: white;
227 | }
228 |
229 | dt:target, .highlight {
230 | background: #FAF3E8;
231 | }
232 |
233 | div.note {
234 | background-color: #eee;
235 | border: 1px solid #ccc;
236 | }
237 |
238 | div.seealso {
239 | background-color: #ffc;
240 | border: 1px solid #ff6;
241 | }
242 |
243 | div.topic {
244 | background-color: #eee;
245 | }
246 |
247 | p.admonition-title {
248 | display: inline;
249 | }
250 |
251 | p.admonition-title:after {
252 | content: ":";
253 | }
254 |
255 | pre, tt {
256 | font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
257 | font-size: 0.9em;
258 | }
259 |
260 | img.screenshot {
261 | }
262 |
263 | tt.descname, tt.descclassname {
264 | font-size: 0.95em;
265 | }
266 |
267 | tt.descname {
268 | padding-right: 0.08em;
269 | }
270 |
271 | img.screenshot {
272 | -moz-box-shadow: 2px 2px 4px #eee;
273 | -webkit-box-shadow: 2px 2px 4px #eee;
274 | box-shadow: 2px 2px 4px #eee;
275 | }
276 |
277 | table.docutils {
278 | border: 1px solid #888;
279 | -moz-box-shadow: 2px 2px 4px #eee;
280 | -webkit-box-shadow: 2px 2px 4px #eee;
281 | box-shadow: 2px 2px 4px #eee;
282 | }
283 |
284 | table.docutils td, table.docutils th {
285 | border: 1px solid #888;
286 | padding: 0.25em 0.7em;
287 | }
288 |
289 | table.field-list, table.footnote {
290 | border: none;
291 | -moz-box-shadow: none;
292 | -webkit-box-shadow: none;
293 | box-shadow: none;
294 | }
295 |
296 | table.footnote {
297 | margin: 15px 0;
298 | width: 100%;
299 | border: 1px solid #eee;
300 | background: #fdfdfd;
301 | font-size: 0.9em;
302 | }
303 |
304 | table.footnote + table.footnote {
305 | margin-top: -15px;
306 | border-top: none;
307 | }
308 |
309 | table.field-list th {
310 | padding: 0 0.8em 0 0;
311 | }
312 |
313 | table.field-list td {
314 | padding: 0;
315 | }
316 |
317 | table.footnote td.label {
318 | width: 0px;
319 | padding: 0.3em 0 0.3em 0.5em;
320 | }
321 |
322 | table.footnote td {
323 | padding: 0.3em 0.5em;
324 | }
325 |
326 | dl {
327 | margin: 0;
328 | padding: 0;
329 | }
330 |
331 | dl dd {
332 | margin-left: 30px;
333 | }
334 |
335 | blockquote {
336 | margin: 0 0 0 30px;
337 | padding: 0;
338 | }
339 |
340 | ul, ol {
341 | margin: 10px 0 10px 30px;
342 | padding: 0;
343 | }
344 |
345 | pre {
346 | background: #eee;
347 | padding: 7px 30px;
348 | margin: 15px -30px;
349 | line-height: 1.3em;
350 | }
351 |
352 | dl pre, blockquote pre, li pre {
353 | margin-left: -60px;
354 | padding-left: 60px;
355 | }
356 |
357 | dl dl pre {
358 | margin-left: -90px;
359 | padding-left: 90px;
360 | }
361 |
362 | tt {
363 | background-color: #ecf0f3;
364 | color: #222;
365 | /* padding: 1px 2px; */
366 | }
367 |
368 | tt.xref, a tt {
369 | background-color: #FBFBFB;
370 | border-bottom: 1px solid white;
371 | }
372 |
373 | a.reference {
374 | text-decoration: none;
375 | border-bottom: 1px dotted #004B6B;
376 | }
377 |
378 | a.reference:hover {
379 | border-bottom: 1px solid #6D4100;
380 | }
381 |
382 | a.footnote-reference {
383 | text-decoration: none;
384 | font-size: 0.7em;
385 | vertical-align: top;
386 | border-bottom: 1px dotted #004B6B;
387 | }
388 |
389 | a.footnote-reference:hover {
390 | border-bottom: 1px solid #6D4100;
391 | }
392 |
393 | a:hover tt {
394 | background: #EEE;
395 | }
396 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Flask-MongoKit documentation build configuration file, created by
4 | # sphinx-quickstart on Tue Aug 16 21:56:43 2011.
5 | #
6 | # This file is execfile()d with the current directory set to its containing dir.
7 | #
8 | # Note that not all possible configuration values are present in this
9 | # autogenerated file.
10 | #
11 | # All configuration values have a default; values that are commented out
12 | # serve to show the default.
13 |
14 | import sys, os
15 |
16 | # If extensions (or modules to document with autodoc) are in another directory,
17 | # add these directories to sys.path here. If the directory is relative to the
18 | # documentation root, use os.path.abspath to make it absolute, like shown here.
19 | sys.path.append(os.path.abspath('_themes'))
20 |
21 | # -- General configuration -----------------------------------------------------
22 |
23 | # If your documentation needs a minimal Sphinx version, state it here.
24 | #needs_sphinx = '1.0'
25 |
26 | # Add any Sphinx extension module names here, as strings. They can be extensions
27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo']
29 |
30 | # Add any paths that contain templates here, relative to this directory.
31 | templates_path = ['_templates']
32 |
33 | # The suffix of source filenames.
34 | source_suffix = '.rst'
35 |
36 | # The encoding of source files.
37 | #source_encoding = 'utf-8-sig'
38 |
39 | # The master toctree document.
40 | master_doc = 'index'
41 |
42 | # General information about the project.
43 | project = u'Flask-MongoKit'
44 | copyright = u'2011, Christoph Heer'
45 |
46 | # The version info for the project you're documenting, acts as replacement for
47 | # |version| and |release|, also used in various other places throughout the
48 | # built documents.
49 | #
50 | # The short X.Y version.
51 | version = '0.2'
52 | # The full version, including alpha/beta/rc tags.
53 | release = '0.2'
54 |
55 | # The language for content autogenerated by Sphinx. Refer to documentation
56 | # for a list of supported languages.
57 | #language = None
58 |
59 | # There are two options for replacing |today|: either, you set today to some
60 | # non-false value, then it is used:
61 | #today = ''
62 | # Else, today_fmt is used as the format for a strftime call.
63 | #today_fmt = '%B %d, %Y'
64 |
65 | # List of patterns, relative to source directory, that match files and
66 | # directories to ignore when looking for source files.
67 | exclude_patterns = ['_build']
68 |
69 | # The reST default role (used for this markup: `text`) to use for all documents.
70 | #default_role = None
71 |
72 | # If true, '()' will be appended to :func: etc. cross-reference text.
73 | #add_function_parentheses = True
74 |
75 | # If true, the current module name will be prepended to all description
76 | # unit titles (such as .. function::).
77 | #add_module_names = True
78 |
79 | # If true, sectionauthor and moduleauthor directives will be shown in the
80 | # output. They are ignored by default.
81 | #show_authors = False
82 |
83 | # The name of the Pygments (syntax highlighting) style to use.
84 | #pygments_style = 'sphinx'
85 |
86 | # A list of ignored prefixes for module index sorting.
87 | #modindex_common_prefix = []
88 |
89 |
90 | # -- Options for HTML output ---------------------------------------------------
91 |
92 | # The theme to use for HTML and HTML Help pages. See the documentation for
93 | # a list of builtin themes.
94 | html_theme = 'flask_small'
95 |
96 | # Theme options are theme-specific and customize the look and feel of a theme
97 | # further. For a list of options available for each theme, see the
98 | # documentation.
99 | html_theme_options = {
100 | 'github_fork': 'jarus/flask-mongokit',
101 | 'index_logo': 'flask-mongokit.png'
102 | }
103 |
104 | # Add any paths that contain custom themes here, relative to this directory.
105 | html_theme_path = ['_themes']
106 |
107 | # The name for this set of Sphinx documents. If None, it defaults to
108 | # " v documentation".
109 | #html_title = None
110 |
111 | # A shorter title for the navigation bar. Default is the same as html_title.
112 | #html_short_title = None
113 |
114 | # The name of an image file (relative to this directory) to place at the top
115 | # of the sidebar.
116 | #html_logo = None
117 |
118 | # The name of an image file (within the static path) to use as favicon of the
119 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
120 | # pixels large.
121 | #html_favicon = None
122 |
123 | # Add any paths that contain custom static files (such as style sheets) here,
124 | # relative to this directory. They are copied after the builtin static files,
125 | # so a file named "default.css" will overwrite the builtin "default.css".
126 | html_static_path = ['_static']
127 |
128 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
129 | # using the given strftime format.
130 | #html_last_updated_fmt = '%b %d, %Y'
131 |
132 | # If true, SmartyPants will be used to convert quotes and dashes to
133 | # typographically correct entities.
134 | #html_use_smartypants = True
135 |
136 | # Custom sidebar templates, maps document names to template names.
137 | #html_sidebars = {}
138 |
139 | # Additional templates that should be rendered to pages, maps page names to
140 | # template names.
141 | #html_additional_pages = {}
142 |
143 | # If false, no module index is generated.
144 | #html_domain_indices = True
145 |
146 | # If false, no index is generated.
147 | #html_use_index = True
148 |
149 | # If true, the index is split into individual pages for each letter.
150 | #html_split_index = False
151 |
152 | # If true, links to the reST sources are added to the pages.
153 | #html_show_sourcelink = True
154 |
155 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
156 | #html_show_sphinx = True
157 |
158 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
159 | #html_show_copyright = True
160 |
161 | # If true, an OpenSearch description file will be output, and all pages will
162 | # contain a tag referring to it. The value of this option must be the
163 | # base URL from which the finished HTML is served.
164 | #html_use_opensearch = ''
165 |
166 | # This is the file name suffix for HTML files (e.g. ".xhtml").
167 | #html_file_suffix = None
168 |
169 | # Output file base name for HTML help builder.
170 | htmlhelp_basename = 'Flask-MongoKitdoc'
171 |
172 |
173 | # -- Options for LaTeX output --------------------------------------------------
174 |
175 | # The paper size ('letter' or 'a4').
176 | #latex_paper_size = 'letter'
177 |
178 | # The font size ('10pt', '11pt' or '12pt').
179 | #latex_font_size = '10pt'
180 |
181 | # Grouping the document tree into LaTeX files. List of tuples
182 | # (source start file, target name, title, author, documentclass [howto/manual]).
183 | latex_documents = [
184 | ('index', 'Flask-MongoKit.tex', u'Flask-MongoKit Documentation',
185 | u'Christoph Heer', 'manual'),
186 | ]
187 |
188 | # The name of an image file (relative to this directory) to place at the top of
189 | # the title page.
190 | #latex_logo = None
191 |
192 | # For "manual" documents, if this is true, then toplevel headings are parts,
193 | # not chapters.
194 | #latex_use_parts = False
195 |
196 | # If true, show page references after internal links.
197 | #latex_show_pagerefs = False
198 |
199 | # If true, show URL addresses after external links.
200 | #latex_show_urls = False
201 |
202 | # Additional stuff for the LaTeX preamble.
203 | #latex_preamble = ''
204 |
205 | # Documents to append as an appendix to all manuals.
206 | #latex_appendices = []
207 |
208 | # If false, no module index is generated.
209 | #latex_domain_indices = True
210 |
211 |
212 | # -- Options for manual page output --------------------------------------------
213 |
214 | # One entry per manual page. List of tuples
215 | # (source start file, name, description, authors, manual section).
216 | man_pages = [
217 | ('index', 'flask-mongokit', u'Flask-MongoKit Documentation',
218 | [u'Christoph Heer'], 1)
219 | ]
220 |
221 | # Example configuration for intersphinx: refer to the Python standard library.
222 | intersphinx_mapping = {
223 | 'python': ('http://docs.python.org/', None),
224 | 'flask': ('http://flask.pocoo.org/docs/', None),
225 | 'mongokit': ('http://namlook.github.com/mongokit/', None),
226 | 'pymongo': ('http://api.mongodb.org/python/current/', None),
227 | 'bson': ('http://api.mongodb.org/python/current/', None),
228 | }
--------------------------------------------------------------------------------
/flask_mongokit.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | flask.ext.mongokit
4 | ~~~~~~~~~~~~~~~~~~
5 |
6 | Flask-MongoKit simplifies to use MongoKit, a powerful MongoDB ORM in Flask
7 | applications.
8 |
9 | :copyright: 2011 by Christoph Heer ')
37 | def show_task(task_id):
38 | task = db.Task.get_from_id(task_id)
39 | return render_template('task.html', task=task)
40 |
41 | It checks the validate of the id and converts it into a
42 | :class:`bson.objectid.ObjectId` object. The converter will be
43 | automatically registered by the initialization of
44 | :class:`~flask.ext.mongokit.MongoKit` with keyword :attr:`ObjectId`.
45 | """
46 |
47 | def to_python(self, value):
48 | try:
49 | return bson.ObjectId(value)
50 | except bson.errors.InvalidId:
51 | raise abort(400)
52 |
53 | def to_url(self, value):
54 | return str(value)
55 |
56 |
57 | class Document(Document):
58 | def get_or_404(self, id):
59 | """This method get one document over the _id field. If there no
60 | document with this id then it will raised a 404 error.
61 |
62 | :param id: The id from the document. The most time there will be
63 | an :class:`bson.objectid.ObjectId`.
64 | """
65 | doc = self.get_from_id(id)
66 | if doc is None:
67 | abort(404)
68 | else:
69 | return doc
70 |
71 | def find_one_or_404(self, *args, **kwargs):
72 | """This method get one document over normal query parameter like
73 | :meth:`~flask.ext.mongokit.Document.find_one` but if there no document
74 | then it will raise a 404 error.
75 | """
76 |
77 | doc = self.find_one(*args, **kwargs)
78 | if doc is None:
79 | abort(404)
80 | else:
81 | return doc
82 |
83 |
84 | class MongoKit(object):
85 | """This class is used to integrate `MongoKit`_ into a Flask application.
86 |
87 | :param app: The Flask application will be bound to this MongoKit instance.
88 | If an app is not provided at initialization time than it
89 | must be provided later by calling :meth:`init_app` manually.
90 |
91 | .. _MongoKit: http://namlook.github.com/mongokit/
92 | """
93 |
94 | def __init__(self, app=None):
95 | #: :class:`list` of :class:`mongokit.Document`
96 | #: which will be automated registed at connection
97 | self.registered_documents = []
98 |
99 | if app is not None:
100 | self.app = app
101 | self.init_app(self.app)
102 | else:
103 | self.app = None
104 |
105 | def init_app(self, app):
106 | """This method connect your ``app`` with this extension. Flask-
107 | MongoKit will now take care about to open and close the connection to
108 | your MongoDB.
109 |
110 | Also it registers the
111 | :class:`flask.ext.mongokit.BSONObjectIdConverter`
112 | as a converter with the key word **ObjectId**.
113 |
114 | :param app: The Flask application will be bound to this MongoKit
115 | instance.
116 | """
117 | app.config.setdefault('MONGODB_HOST', '127.0.0.1')
118 | app.config.setdefault('MONGODB_PORT', 27017)
119 | app.config.setdefault('MONGODB_DATABASE', 'flask')
120 | app.config.setdefault('MONGODB_SLAVE_OKAY', False)
121 | app.config.setdefault('MONGODB_USERNAME', None)
122 | app.config.setdefault('MONGODB_PASSWORD', None)
123 |
124 | # 0.9 and later
125 | # no coverage check because there is everytime only one
126 | if hasattr(app, 'teardown_appcontext'): # pragma: no cover
127 | app.teardown_appcontext(self._teardown_request)
128 | # 0.7 to 0.8
129 | elif hasattr(app, 'teardown_request'): # pragma: no cover
130 | app.teardown_request(self._teardown_request)
131 | # Older Flask versions
132 | else: # pragma: no cover
133 | app.after_request(self._teardown_request)
134 |
135 | # register extension with app only to say "I'm here"
136 | app.extensions = getattr(app, 'extensions', {})
137 | app.extensions['mongokit'] = self
138 |
139 | app.url_map.converters['ObjectId'] = BSONObjectIdConverter
140 |
141 | self.app = app
142 |
143 | def register(self, documents):
144 | """Register one or more :class:`mongokit.Document` instances to the
145 | connection.
146 |
147 | Can be also used as a decorator on documents:
148 |
149 | .. code-block:: python
150 |
151 | db = MongoKit(app)
152 |
153 | @db.register
154 | class Task(Document):
155 | structure = {
156 | 'title': unicode,
157 | 'text': unicode,
158 | 'creation': datetime,
159 | }
160 |
161 | :param documents: A :class:`list` of :class:`mongokit.Document`.
162 | """
163 |
164 | #enable decorator usage as in mongokit.Connection
165 | decorator = None
166 | if not isinstance(documents, (list, tuple, set, frozenset)):
167 | # we assume that the user used this as a decorator
168 | # using @register syntax or using db.register(SomeDoc)
169 | # we stock the class object in order to return it later
170 | decorator = documents
171 | documents = [documents]
172 |
173 | for document in documents:
174 | if document not in self.registered_documents:
175 | self.registered_documents.append(document)
176 |
177 | if decorator is None:
178 | return self.registered_documents
179 | else:
180 | return decorator
181 |
182 | def connect(self):
183 | """Connect to the MongoDB server and register the documents from
184 | :attr:`registered_documents`. If you set ``MONGODB_USERNAME`` and
185 | ``MONGODB_PASSWORD`` then you will be authenticated at the
186 | ``MONGODB_DATABASE``. You can also enable timezone awareness if
187 | you set to True ``MONGODB_TZ_AWARE`.
188 | """
189 | if self.app is None:
190 | raise RuntimeError('The flask-mongokit extension was not init to '
191 | 'the current application. Please make sure '
192 | 'to call init_app() first.')
193 |
194 | ctx = ctx_stack.top
195 | mongokit_connection = getattr(ctx, 'mongokit_connection', None)
196 | if mongokit_connection is None:
197 | ctx.mongokit_connection = Connection(
198 | host=ctx.app.config.get('MONGODB_HOST'),
199 | port=ctx.app.config.get('MONGODB_PORT'),
200 | slave_okay=ctx.app.config.get('MONGODB_SLAVE_OKAY'),
201 | tz_aware=ctx.app.config.get('MONGODB_TZ_AWARE', False)
202 | )
203 |
204 | ctx.mongokit_connection.register(self.registered_documents)
205 |
206 | mongokit_database = getattr(ctx, 'mongokit_database', None)
207 | if mongokit_database is None:
208 | ctx.mongokit_database = Database(
209 | ctx.mongokit_connection,
210 | ctx.app.config.get('MONGODB_DATABASE')
211 | )
212 |
213 | if ctx.app.config.get('MONGODB_USERNAME') is not None:
214 | try:
215 | auth_success = ctx.mongokit_database.authenticate(
216 | ctx.app.config.get('MONGODB_USERNAME'),
217 | ctx.app.config.get('MONGODB_PASSWORD')
218 | )
219 | except OperationFailure:
220 | auth_success = False
221 |
222 | if not auth_success:
223 | raise AuthenticationIncorrect('Server authentication failed')
224 |
225 | @property
226 | def connected(self):
227 | """Connection status to your MongoDB."""
228 | ctx = ctx_stack.top
229 | return getattr(ctx, 'mongokit_connection', None) is not None
230 |
231 | def disconnect(self):
232 | """Close the connection to your MongoDB."""
233 | if self.connected:
234 | ctx = ctx_stack.top
235 | ctx.mongokit_connection.disconnect()
236 | del ctx.mongokit_connection
237 | del ctx.mongokit_database
238 |
239 | def _teardown_request(self, response):
240 | self.disconnect()
241 | return response
242 |
243 | def __getattr__(self, name, **kwargs):
244 | if not self.connected:
245 | self.connect()
246 |
247 | mongokit_database = getattr(ctx_stack.top, "mongokit_database")
248 | return getattr(mongokit_database, name)
249 |
250 | def __getitem__(self, name):
251 | if not self.connected:
252 | self.connect()
253 |
254 | mongokit_database = getattr(ctx_stack.top, "mongokit_database")
255 | return mongokit_database[name]
256 |
--------------------------------------------------------------------------------
/tests/test_base.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import unittest
4 | import os
5 |
6 | from datetime import datetime
7 |
8 | from flask import Flask
9 | from flask_mongokit import MongoKit, BSONObjectIdConverter, \
10 | Document, Collection, AuthenticationIncorrect
11 | from werkzeug.exceptions import BadRequest, NotFound
12 | from bson import ObjectId
13 | from pymongo import Connection
14 | from pymongo.collection import Collection
15 |
16 | class BlogPost(Document):
17 | __collection__ = "posts"
18 | structure = {
19 | 'title': unicode,
20 | 'body': unicode,
21 | 'author': unicode,
22 | 'date_creation': datetime,
23 | 'rank': int,
24 | 'tags': [unicode],
25 | }
26 | required_fields = ['title', 'author', 'date_creation']
27 | default_values = {'rank': 0, 'date_creation': datetime.utcnow}
28 | use_dot_notation = True
29 |
30 | def create_app():
31 | app = Flask(__name__)
32 | app.config['TESTING'] = True
33 | app.config['MONGODB_DATABASE'] = 'flask_testing'
34 |
35 | maybe_conf_file = os.path.join(os.getcwd(), "config_test.cfg")
36 | if os.path.exists(maybe_conf_file):
37 | app.config.from_pyfile(maybe_conf_file)
38 |
39 | return app
40 |
41 | class TestCaseContextIndependent(unittest.TestCase):
42 | def setUp(self):
43 | self.app = create_app()
44 | self.db = MongoKit(self.app)
45 |
46 | def tearDown(self):
47 | pass
48 |
49 | def test_register_document(self):
50 | self.db.register([BlogPost])
51 |
52 | assert len(self.db.registered_documents) > 0
53 | assert self.db.registered_documents[0] == BlogPost
54 |
55 | def test_bson_object_id_converter(self):
56 | converter = BSONObjectIdConverter("/")
57 |
58 | self.assertRaises(BadRequest, converter.to_python, ("132"))
59 | assert converter.to_python("4e4ac5cfffc84958fa1f45fb") == \
60 | ObjectId("4e4ac5cfffc84958fa1f45fb")
61 | assert converter.to_url(ObjectId("4e4ac5cfffc84958fa1f45fb")) == \
62 | "4e4ac5cfffc84958fa1f45fb"
63 |
64 | def test_is_extension_registerd(self):
65 | assert hasattr(self.app, 'extensions')
66 | assert 'mongokit' in self.app.extensions
67 | assert self.app.extensions['mongokit'] == self.db
68 |
69 | class BaseTestCaseInitAppWithContext():
70 | def setUp(self):
71 | self.app = create_app()
72 |
73 | def test_init_later(self):
74 | self.db = MongoKit()
75 | self.assertRaises(RuntimeError, self.db.connect)
76 |
77 | self.db.init_app(self.app)
78 | self.db.connect()
79 | assert self.db.connected
80 |
81 | def test_init_immediately(self):
82 | self.db = MongoKit(self.app)
83 | self.db.connect()
84 | assert self.db.connected
85 |
86 | class BaseTestCaseWithContext():
87 |
88 | def test_initialization(self):
89 | assert isinstance(self.db, MongoKit)
90 | assert self.db.name == self.app.config['MONGODB_DATABASE']
91 | assert isinstance(self.db.test, Collection)
92 |
93 | def test_property_connected(self):
94 | assert not self.db.connected
95 |
96 | self.db.connect()
97 | assert self.db.connected
98 |
99 | self.db.disconnect()
100 | assert not self.db.connected
101 |
102 | self.db.collection_names()
103 | assert self.db.connected
104 |
105 | def test_subscriptable(self):
106 | assert isinstance(self.db['test'], Collection)
107 | assert self.db['test'] == self.db.test
108 |
109 | def test_save_and_find_document(self):
110 | self.db.register([BlogPost])
111 |
112 | assert len(self.db.registered_documents) > 0
113 | assert self.db.registered_documents[0] == BlogPost
114 |
115 | post = self.db.BlogPost()
116 | post.title = u"Flask-MongoKit"
117 | post.body = u"Flask-MongoKit is a layer between Flask and MongoKit"
118 | post.author = u"Christoph Heer"
119 | post.save()
120 |
121 | assert self.db.BlogPost.find().count() > 0
122 | rec_post = self.db.BlogPost.find_one({'title': u"Flask-MongoKit"})
123 | assert rec_post.title == post.title
124 | assert rec_post.body == rec_post.body
125 | assert rec_post.author == rec_post.author
126 |
127 | def test_get_or_404(self):
128 | self.db.register([BlogPost])
129 |
130 | assert len(self.db.registered_documents) > 0
131 | assert self.db.registered_documents[0] == BlogPost
132 |
133 | post = self.db.BlogPost()
134 | post.title = u"Flask-MongoKit"
135 | post.body = u"Flask-MongoKit is a layer between Flask and MongoKit"
136 | post.author = u"Christoph Heer"
137 | post.save()
138 |
139 | assert self.db.BlogPost.find().count() > 0
140 | assert "get_or_404" in dir(self.db.BlogPost)
141 | try:
142 | self.db.BlogPost.get_or_404(post['_id'])
143 | except NotFound:
144 | self.fail("There should be a document with this id")
145 | self.assertRaises(NotFound, self.db.BlogPost.get_or_404, ObjectId())
146 |
147 | def test_find_one_or_404(self):
148 | self.db.register([BlogPost])
149 |
150 | assert len(self.db.registered_documents) > 0
151 | assert self.db.registered_documents[0] == BlogPost
152 |
153 | post = self.db.BlogPost()
154 | post.title = u"Flask-MongoKit"
155 | post.body = u"Flask-MongoKit is a layer between Flask and MongoKit"
156 | post.author = u"Christoph Heer"
157 | post.save()
158 |
159 | assert self.db.BlogPost.find().count() > 0
160 | assert "find_one_or_404" in dir(self.db.BlogPost)
161 | try:
162 | self.db.BlogPost.find_one_or_404({'title': u'Flask-MongoKit'})
163 | except NotFound:
164 | self.fail("There should be a document with this title")
165 | self.assertRaises(NotFound, self.db.BlogPost.find_one_or_404,
166 | {'title': u'Flask is great'})
167 |
168 | class BaseTestCaseWithAuth():
169 | def setUp(self):
170 | db = 'flask_testing_auth'
171 | conn = Connection()
172 | conn[db].add_user('test', 'test')
173 |
174 | self.app = create_app()
175 | self.app.config['TESTING'] = True
176 | self.app.config['MONGODB_DATABASE'] = db
177 |
178 | self.db = MongoKit(self.app)
179 |
180 | def test_correct_login(self):
181 | self.app.config['MONGODB_USERNAME'] = 'test'
182 | self.app.config['MONGODB_PASSWORD'] = 'test'
183 |
184 | self.db.connect()
185 |
186 | def test_incorrect_login(self):
187 | self.app.config['MONGODB_USERNAME'] = 'fuu'
188 | self.app.config['MONGODB_PASSWORD'] = 'baa'
189 |
190 | self.assertRaises(AuthenticationIncorrect, self.db.connect)
191 |
192 | class BaseTestCaseMultipleApps():
193 |
194 | def setUp(self):
195 | self.app_1 = create_app()
196 | self.app_1.config['MONGODB_DATABASE'] = 'app_1'
197 |
198 | self.app_2 = create_app()
199 | self.app_2.config['MONGODB_DATABASE'] = 'app_2'
200 |
201 | assert self.app_1 != self.app_2
202 |
203 | self.db = MongoKit()
204 | self.db.init_app(self.app_1)
205 | self.db.init_app(self.app_2)
206 |
207 | def tearDown(self):
208 | self.pop_ctx()
209 |
210 | def push_ctx(self):
211 | raise NotImplementedError
212 |
213 | def pop_ctx(self):
214 | raise NotImplementedError
215 |
216 | def test_app_1(self):
217 | self.push_ctx(self.app_1)
218 |
219 | self.db.connect()
220 | assert self.db.connected
221 | assert self.db.name == 'app_1'
222 | assert self.db.name != 'app_2'
223 |
224 | def test_app_2(self):
225 | self.push_ctx(self.app_2)
226 |
227 | self.db.connect()
228 | assert self.db.connected
229 | assert self.db.name != 'app_1'
230 | assert self.db.name == 'app_2'
231 |
232 | class TestCaseInitAppWithRequestContext(BaseTestCaseInitAppWithContext, unittest.TestCase):
233 | def setUp(self):
234 | self.app = create_app()
235 |
236 | self.ctx = self.app.test_request_context('/')
237 | self.ctx.push()
238 |
239 | def tearDown(self):
240 | self.ctx.pop()
241 |
242 | class TestCaseWithRequestContext(BaseTestCaseWithContext, unittest.TestCase):
243 | def setUp(self):
244 | self.app = create_app()
245 | self.db = MongoKit(self.app)
246 |
247 | self.ctx = self.app.test_request_context('/')
248 | self.ctx.push()
249 |
250 | def tearDown(self):
251 | self.ctx.pop()
252 |
253 | class TestCaseWithRequestContextAuth(BaseTestCaseWithAuth, unittest.TestCase):
254 | def setUp(self):
255 | super(TestCaseWithRequestContextAuth, self).setUp()
256 |
257 | self.ctx = self.app.test_request_context('/')
258 | self.ctx.push()
259 |
260 | def tearDown(self):
261 | self.ctx.pop()
262 |
263 | class TestCaseMultipleAppsWithRequestContext(BaseTestCaseMultipleApps, unittest.TestCase):
264 | def push_ctx(self, app):
265 | self.ctx = app.test_request_context('/')
266 | self.ctx.push()
267 |
268 | def tearDown(self):
269 | self.ctx.pop()
270 |
271 | # Only testing is the flask version support app context (since flask v0.9)
272 | if hasattr(Flask, "app_context"):
273 | class TestCaseInitAppWithAppContext(BaseTestCaseInitAppWithContext, unittest.TestCase):
274 | def setUp(self):
275 | self.app = create_app()
276 |
277 | self.ctx = self.app.app_context()
278 | self.ctx.push()
279 |
280 | def tearDown(self):
281 | self.ctx.pop()
282 |
283 | class TestCaseWithAppContext(BaseTestCaseWithContext, unittest.TestCase):
284 | def setUp(self):
285 | self.app = create_app()
286 | self.db = MongoKit(self.app)
287 |
288 | self.ctx = self.app.app_context()
289 | self.ctx.push()
290 |
291 | def tearDown(self):
292 | self.ctx.pop()
293 |
294 | class TestCaseWithAppContextAuth(BaseTestCaseWithAuth, unittest.TestCase):
295 | def setUp(self):
296 | super(TestCaseWithAppContextAuth, self).setUp()
297 |
298 | self.ctx = self.app.app_context()
299 | self.ctx.push()
300 |
301 | def tearDown(self):
302 | self.ctx.pop()
303 |
304 | class TestCaseMultipleAppsWithAppContext(BaseTestCaseMultipleApps, unittest.TestCase):
305 | def push_ctx(self, app):
306 | self.ctx = app.app_context()
307 | self.ctx.push()
308 |
309 | def tearDown(self):
310 | self.ctx.pop()
311 |
312 | if __name__ == '__main__':
313 | unittest.main()
314 |
--------------------------------------------------------------------------------