fix errors, remove pep8 corrections

This commit is contained in:
Christian Barra
2017-01-03 14:10:46 +01:00
parent dbe8bf5428
commit 02090c953b
5 changed files with 118 additions and 145 deletions

View File

@@ -1095,7 +1095,9 @@ class JupyterHub(Application):
# if user.server is defined.
log = self.log.warning if user.server else self.log.debug
log("%s not running.", user.name)
user.server = None
for server in user.servers:
db.delete(server)
db.commit()
user_summaries.append(_user_summary(user))

View File

@@ -19,7 +19,7 @@ from sqlalchemy import (
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import sessionmaker, relationship, backref
from sqlalchemy.pool import StaticPool
from sqlalchemy.schema import Index
from sqlalchemy.schema import Index, UniqueConstraint
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.sql.expression import bindparam
from sqlalchemy import create_engine, Table
@@ -32,11 +32,8 @@ from .utils import (
class JSONDict(TypeDecorator):
"""Represents an immutable structure as a json-encoded string.
Usage::
JSONEncodedDict(255)
"""
impl = TEXT
@@ -59,7 +56,6 @@ Base.log = app_log
class Server(Base):
"""The basic state of a server
connection and cookie info
"""
__tablename__ = 'servers'
@@ -69,6 +65,7 @@ class Server(Base):
port = Column(Integer, default=random_port)
base_url = Column(Unicode(255), default='/')
cookie_name = Column(Unicode(255), default='cookie')
# added to handle multi-server feature
last_activity = Column(DateTime, default=datetime.utcnow)
@@ -101,10 +98,8 @@ class Server(Base):
@property
def bind_url(self):
"""representation of URL used for binding
Never used in APIs, only logging,
since it can be non-connectable value, such as '',
meaning all interfaces.
since it can be non-connectable value, such as '', meaning all interfaces.
"""
if self.ip in {'', '0.0.0.0'}:
return self.url.replace('127.0.0.1', self.ip or '*', 1)
@@ -116,8 +111,7 @@ class Server(Base):
if http:
yield wait_for_http_server(self.url, timeout=timeout)
else:
yield wait_for_server(self.ip or '127.0.0.1', self.port,
timeout=timeout)
yield wait_for_server(self.ip or '127.0.0.1', self.port, timeout=timeout)
def is_up(self):
"""Is the server accepting connections?"""
@@ -126,7 +120,6 @@ class Server(Base):
class Proxy(Base):
"""A configurable-http-proxy instance.
A proxy consists of the API server info and the public-facing server info,
plus an auth token for configuring the proxy table.
"""
@@ -191,9 +184,9 @@ class Proxy(Base):
client=client,
)
@gen.coroutine
# FIX-ME
# we need to add a reference to a specific server
@gen.coroutine
def add_user(self, user, client=None):
"""Add a user's server to the proxy table."""
self.log.info("Adding user %s to proxy %s => %s",
@@ -225,7 +218,6 @@ class Proxy(Base):
@gen.coroutine
def add_all_services(self, service_dict):
"""Update the proxy table from the database.
Used when loading up a new proxy.
"""
db = inspect(self).session
@@ -241,7 +233,6 @@ class Proxy(Base):
@gen.coroutine
def add_all_users(self, user_dict):
"""Update the proxy table from the database.
Used when loading up a new proxy.
"""
db = inspect(self).session
@@ -299,11 +290,10 @@ class Proxy(Base):
yield f
class Hub(Base):
"""Bring it all together at the hub.
The Hub is a server, plus its API path suffix
the api_url is the full URL plus the api_path suffix on the end
of the server base_url.
"""
@@ -331,8 +321,7 @@ class Hub(Base):
user_group_map = Table('user_group_map', Base.metadata,
Column('user_id', ForeignKey('users.id'), primary_key=True),
Column('group_id', ForeignKey('groups.id'), primary_key=True),
)
)
class Group(Base):
"""User Groups"""
@@ -345,47 +334,41 @@ class Group(Base):
return "<%s %s (%i users)>" % (
self.__class__.__name__, self.name, len(self.users)
)
@classmethod
def find(cls, db, name):
"""Find a group by name.
Returns None if not found.
"""
return db.query(cls).filter(cls.name == name).first()
return db.query(cls).filter(cls.name==name).first()
class User(Base):
"""The User table
Each user can have more than one server,
Each user can have more than a single server,
and multiple tokens used for authorization.
API tokens grant access to the Hub's REST API.
These are used by single-user servers to authenticate requests,
and external services to manipulate the Hub.
Cookies are set with a single ID.
Resetting the Cookie ID invalidates all cookies, forcing user to login again.
`server` returns the first entry for the users' servers.
A `state` column contains a JSON dict,
used for restoring state of a Spawner.
`server` returns the first entry for the users' servers.
'servers' is a list that contains a reference to the ser's Servers.
"""
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(Unicode(1023), unique=True)
admin = Column(Boolean, default=False)
last_activity = Column(DateTime, default=datetime.utcnow)
servers = association_proxy("user_to_servers", "server", creator=lambda server: UserServer(server=server))
admin = Column(Boolean, default=False)
last_activity = Column(DateTime, default=datetime.utcnow)
api_tokens = relationship("APIToken", backref="user")
cookie_id = Column(Unicode(1023), default=new_token)
# User.state is actually Spawner state
# We will need to figure something else
# out if/when we have multiple spawners per user
# We will need to figure something else out if/when we have multiple spawners per user
state = Column(JSONDict)
# Authenticators can store their state here:
auth_state = Column(JSONDict)
@@ -397,7 +380,6 @@ class User(Base):
@property
def server(self):
"""Returns the first element of servers.
Returns None if the list is empty.
"""
if len(self.servers) == 0:
@@ -429,24 +411,19 @@ class User(Base):
@classmethod
def find(cls, db, name):
"""Find a user by name.
Returns None if not found.
"""
return db.query(cls).filter(cls.name == name).first()
return db.query(cls).filter(cls.name==name).first()
class UserServer(Base):
"""The UserServer table
Each user can have have more than one server,
we use this table to mantain the Many-To-Many
relationship between Users and Servers.
we use this table to mantain the Many-To-One
relationship between Users and Servers tables.
Cookies are set with a single ID.
Resetting the Cookie ID invalidates all cookies, forcing user to login again.
A `state` column contains a JSON dict,
used for restoring state of a Spawner.
Servers can have only 1 user, this condition is mantained
by UniqueConstraint
"""
__tablename__ = 'users_servers'
@@ -454,9 +431,12 @@ class UserServer(Base):
_server_id = Column(Integer, ForeignKey('servers.id'), primary_key=True)
user = relationship(User, backref=backref('user_to_servers', cascade='all, delete-orphan'))
server = relationship(Server, backref=backref('server_to_users', cascade='all, delete-orphan'))
server = relationship(Server, backref=backref('server_to_users', cascade='all, delete-orphan')
)
__table_args__ = (Index('server_user_index', '_server_id', '_user_id'),)
__table_args__ = (
UniqueConstraint('_server_id'),
Index('server_user_index', '_server_id', '_user_id'),)
def __repr__(self):
return "<{cls}({name}@{ip}:{port})>".format(
@@ -469,21 +449,15 @@ class UserServer(Base):
class Service(Base):
"""A service run with JupyterHub
A service is similar to a User without a Spawner.
A service can have API tokens for accessing the Hub's API
It has:
- name
- admin
- api tokens
- server (if proxied http endpoint)
In addition to what it has in common with users, a Service has extra info:
- pid: the process id (if managed)
"""
__tablename__ = 'services'
id = Column(Integer, primary_key=True, autoincrement=True)
@@ -501,7 +475,6 @@ class Service(Base):
def new_api_token(self, token=None):
"""Create a new API token
If `token` is given, load that token.
"""
return APIToken.new(token=token, service=self)
@@ -509,7 +482,6 @@ class Service(Base):
@classmethod
def find(cls, db, name):
"""Find a service by name.
Returns None if not found.
"""
return db.query(cls).filter(cls.name==name).first()
@@ -567,7 +539,6 @@ class APIToken(Base):
@classmethod
def find(cls, db, token, *, kind=None):
"""Find a token object by value.
Returns None if not found.
`kind='user'` only returns API tokens for users

View File

@@ -30,8 +30,8 @@ def db():
_db = orm.new_session_factory('sqlite:///:memory:', echo=True)()
user = orm.User(
name=getuser(),
server=orm.Server(),
)
user.servers.append(orm.Server())
hub = orm.Hub(
server=orm.Server(),
)

View File

@@ -198,12 +198,12 @@ class User(HasTraits):
def spawn(self, options=None):
"""Start the user's spawner"""
db = self.db
self.server = orm.Server(
server = orm.Server(
cookie_name=self.cookie_name,
base_url=self.base_url,
)
db.add(self.server)
self.servers.append(server)
db.add(self)
db.commit()
api_token = self.new_api_token()
@@ -316,7 +316,8 @@ class User(HasTraits):
orm_token = orm.APIToken.find(self.db, api_token)
if orm_token:
self.db.delete(orm_token)
self.server = None
for server in self.servers:
self.db.delete(server)
self.db.commit()
finally:
self.stop_pending = False
@@ -326,4 +327,3 @@ class User(HasTraits):
yield gen.maybe_future(
auth.post_spawn_stop(self, spawner)
)