Skip to content

Commit 3139019

Browse files
author
Scott Sanderson
committed
Merge pull request #10 from quantopian/release-0.2
MAINT: Release 0.2
2 parents 4d2b5f3 + 3656777 commit 3139019

File tree

9 files changed

+90
-69
lines changed

9 files changed

+90
-69
lines changed

.travis.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
language: python
2+
sudo: false
3+
matrix:
4+
include:
5+
- python: 2.7
6+
- python: 3.4
7+
addons:
8+
postgresql: "9.3"
9+
10+
install:
11+
- python setup.py install
12+
- pip install -r requirements_dev.txt
13+
14+
before_script:
15+
- flake8 pgcontents
16+
- psql -c 'create database pgcontents_testing;' -U postgres
17+
script:
18+
nosetests pgcontents/tests

README.md

Lines changed: 0 additions & 19 deletions
This file was deleted.

README.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
PGContents
2+
==========
3+
4+
PGContents is a PostgreSQL-backed implementation of `IPEP 27 <https://github.com/ipython/ipython/wiki/IPEP-27:-Contents-Service>`_. It aims to a be a transparent, drop-in replacement for IPython's standard filesystem-backed storage system. PGContents' `PostgresContentsManager` class can be used to replace all local filesystem storage with database-backed storage, while its `PostgresCheckpoints` class can be used to replace just IPython's checkpoint storage. These features are useful when running IPython in environments where you either don't have access to—or don't trust the reliability of—the local filesystem of your notebook server.
5+
6+
This repository is under development as part of the `Quantopian Research Environment <https://www.quantopian.com/research>`_, currently in Open Beta.
7+
8+
Getting Started
9+
---------------
10+
**Prerequisites:**
11+
- Write access to an empty `PostgreSQL <http://www.postgresql.org>`_ database.
12+
- A Python installation with `IPython <https://github.com/ipython/ipython>`_ 3.2.x.
13+
14+
**Installation:**
15+
16+
0. Install `pgcontents` from PyPI via `pip install pgcontents`.
17+
1. Run `pgcontents init` to configure your database. You will be prompted for a database URL for pgcontents to use for storage.
18+
2. Configure IPython Notebook to use pgcontents as its storage backend. This can be done from the command line or by modifying your `ipython_notebook_config.py` file. For a standard IPython installation on Unix-like systems, your profile will be located located at `~/.ipython/profile_default/ipython_notebook_config.py`. See the `examples` directory for example configuration files.
19+
3. Enjoy your filesystem-free IPython experience!
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from pgcontents import PostgresCheckpoints
2+
c = get_config()
3+
4+
# Tell IPython to use PostgresCheckpoints for checkpoint storage.
5+
c.NotebookApp.checkpoints_class = PostgresCheckpoints
6+
7+
# Set the url for the database used to store files. See
8+
# http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#postgresql
9+
# for more info on db url formatting.
10+
c.PostgresContentsManager.db_url = 'postgresql://ssanderson:[email protected]:5432/pgcontents'
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
from pgcontents import PostgresContentsManager
12
c = get_config()
23

3-
# Tell IPython to use PostgresContentsManager.
4-
c.NotebookApp.contents_manager_class = 'pgcontents.pgmanager.PostgresContentsManager'
4+
# Tell IPython to use PostgresContentsManager for all storage.
5+
c.NotebookApp.contents_manager_class = PostgresContentsManager
56

67
# Set the url for the database used to store files. See
78
# http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#postgresql
89
# for more info on db url formatting.
9-
# c.PostgresContentsManager.db_url = 'postgresql://ssanderson@/pgcontents'
10+
c.PostgresContentsManager.db_url = 'postgresql://ssanderson@/pgcontents'
1011

11-
# Set a user ID. Defaults to the result of getpass.getuser()
12-
# c.PostgresContentsManager.user_id = 'my_awesome_username'
12+
# PGContents associates each running notebook server with a user, allowing
13+
# multiple users to connect to the same database without trampling each other's
14+
# notebooks. By default, we use the result of result of getpass.getuser(), but
15+
# a username can be specified manually like so:
16+
c.PostgresContentsManager.user_id = 'my_awesome_username'
1317

1418
# Set a maximum file size, if desired.
15-
# c.PostgresContentsManager.max_file_size_bytes = 1000000 # 1MB File cap
19+
c.PostgresContentsManager.max_file_size_bytes = 1000000 # 1MB File cap

pgcontents/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from .checkpoints import PostgresCheckpoints
2+
from .pgmanager import PostgresContentsManager
3+
4+
__all__ = [
5+
'PostgresCheckpoints',
6+
'PostgresContentsManager',
7+
]

pgcontents/tests/test_pgmanager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ def test_max_file_size(self):
183183
self.set_pgmgr_attribute('max_file_size_bytes', max_size)
184184

185185
good = 'a' * 51
186-
self.assertEqual(len(b64encode(good)), max_size)
186+
self.assertEqual(len(b64encode(good.encode('utf-8'))), max_size)
187187
cm.save(
188188
model={
189189
'content': good,
@@ -196,7 +196,7 @@ def test_max_file_size(self):
196196
self.assertEqual(result['content'], good)
197197

198198
bad = 'a' * 52
199-
self.assertGreater(bad, max_size)
199+
self.assertGreater(len(b64encode(bad.encode('utf-8'))), max_size)
200200
with assertRaisesHTTPError(self, 413):
201201
cm.save(
202202
model={

requirements.txt

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
Jinja2==2.7.3
2-
Mako==1.0.0
3-
MarkupSafe==0.23
4-
Pygments==2.0.1
5-
SQLAlchemy==1.0.5
6-
alembic==0.7.6
7-
argparse==1.2.1
8-
backports.ssl-match-hostname==3.4.0.2
9-
certifi==14.05.14
10-
fancycompleter==0.4
11-
ipython==3.2.0
12-
jsonschema==2.4.0
13-
mistune==0.5.0
14-
psycopg2==2.6.1
15-
pyrepl==0.8.4
16-
pyzmq==14.4.1
17-
tornado==4.0.2
18-
wmctrl==0.1
19-
requests==2.7.0
20-
six==1.9.0
21-
click==3.3
1+
Jinja2>=2.7.3
2+
Mako>=1.0.0
3+
MarkupSafe>=0.23
4+
Pygments>=2.0.1
5+
SQLAlchemy>=1.0.5
6+
alembic>=0.7.6
7+
backports.ssl-match-hostname>=3.4.0.2
8+
certifi>=14.05.14
9+
fancycompleter>=0.4
10+
ipython==3.2.1
11+
jsonschema>=2.4.0
12+
mistune>=0.5.0
13+
psycopg2>=2.6.1
14+
pyrepl>=0.8.4
15+
pyzmq>=14.4.1
16+
tornado>=4.0.2
17+
wmctrl>=0.1
18+
requests>=2.7.0
19+
six>=1.9.0
20+
click>=3.3

setup.py

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,16 @@
11
from __future__ import print_function
22
from setuptools import setup
3-
from os.path import join, dirname
4-
import sys
5-
6-
7-
def fail(msg):
8-
print(msg, file=sys.stderr)
9-
sys.exit(1)
3+
from os.path import join, dirname, abspath
104

115

126
def main():
13-
try:
14-
import IPython
15-
if IPython.version_info[0] < 3:
16-
fail("PGContents requires IPython 3.0 or greater.")
17-
except ImportError:
18-
fail("PGContents requires IPython.")
19-
20-
reqs_file = join(dirname(__file__), 'requirements.txt')
7+
reqs_file = join(dirname(abspath(__file__)), 'requirements.txt')
218
with open(reqs_file) as f:
22-
requirements = [
23-
req.replace('==', '>=')
24-
for req in f.readlines()
25-
if not req.strip().startswith('-e')
26-
]
9+
requirements = [req.strip() for req in f.readlines()]
2710

2811
setup(
2912
name='pgcontents',
30-
version='0.1',
13+
version='0.2',
3114
description="A Postgres-backed ContentsManager for IPython.",
3215
author="Scott Sanderson",
3316
author_email="[email protected]",

0 commit comments

Comments
 (0)