Ejemplo n.º 1
0
    def init_app(self, app: Starlette, config: Config) -> None:
        """
        Register the starlette app with the email manager.

        App: the starlette app
        config: lamia's config

        Returns: none
        """
        self.config = config
        app.add_event_handler('startup', self._startup)
        app.add_event_handler('shutdown', self._shutdown)
Ejemplo n.º 2
0
def test_app_add_event_handler():
    startup_complete = False
    cleanup_complete = False
    app = Starlette()

    def run_startup():
        nonlocal startup_complete
        startup_complete = True

    def run_cleanup():
        nonlocal cleanup_complete
        cleanup_complete = True

    app.add_event_handler("startup", run_startup)
    app.add_event_handler("shutdown", run_cleanup)

    assert not startup_complete
    assert not cleanup_complete
    with LifespanContext(app):
        assert startup_complete
        assert not cleanup_complete
    assert startup_complete
    assert cleanup_complete
Ejemplo n.º 3
0
app.db_engine = None

@app.route('/')
def homepage(request):
    return PlainTextResponse('Hello, world!')

@app.route('/user/me')
def user_me(request):
    username = "******"
    return PlainTextResponse('Hello, %s!' % username)

@app.route('/user/{username}')
def user(request):
    username = request.path_params['username']
    return PlainTextResponse('Hello, %s!' % username)

@app.on_event('startup')
def startup():
    print('Ready to go')

async def open_database_connection_pool():
    print('Database connection created')
    app.db_engine = await gino.create_engine('postgresql://*****:*****@localhost/gino_user')
    db.bind = app.db_engine

async def close_database_connection_pool():
    print('Database connection Connection close')
    await app.db_engine.close()

app.add_event_handler('startup', open_database_connection_pool)
app.add_event_handler('shutdown', close_database_connection_pool)
Ejemplo n.º 4
0
            },
            {
                'id': '2c2dd3ff',
                'name': 'SanDisk 1TB Harddrive'
            },
            {
                'id': '2c2dd3ff',
                'name': 'Sony Extra Bass Headphones'
            },
            {
                'id': '2c2dd3ff',
                'name': 'RFID Bifold Wallet'
            },
        ]
        return JSONResponse(data)

    async def post(self, request):
        return JSONResponse({'message': 'Product created'},
                            status_code=status.HTTP_201_CREATED)


app = Starlette(debug=settings.DEV)

app.add_event_handler('startup', database.connect)
app.add_event_handler('shutdown', database.close)

app.add_route('/', homepage)
app.add_route('/version', version)
app.add_route('/message', message)
app.add_route('/products', ProductList)
Ejemplo n.º 5
0
 def init_app(self, app: Starlette):
     self.app = app
     app.add_event_handler("startup", self._startup)
     app.add_event_handler("shutdown", self._shutdown)
Ejemplo n.º 6
0
def starlette(parent: Starlette, path: str, app: TartifletteApp) -> None:
    parent.mount(path, app)
    parent.add_event_handler("startup", app.startup)
Ejemplo n.º 7
0
def setup_hunter_service(app: Starlette, config: HunterServiceConfig) -> None:
    hunter_service = HunterService.from_config(config)
    app.state.hunter_service = hunter_service

    app.add_event_handler(Signal.STARTUP, hunter_service.setup)
    app.add_event_handler(Signal.SHUTDOWN, hunter_service.cleanup)
Ejemplo n.º 8
0
class NeolithServer:

    def __init__(self):
        self.loop = None
        self.server = None
        self.irc = None
        self.sessions = {}
        self.channels = Channels()
        self.secret_key = os.urandom(32)
        self.name = settings.SERVER_NAME
        if settings.PUBLIC_CHANNEL:
            self.channels.add(Channel(name=settings.PUBLIC_CHANNEL, topic='', protected=True, encrypted=False))
        self.web = Starlette(debug=True)
        self.web.add_event_handler('startup', self.startup)
        self.web.add_event_handler('shutdown', self.shutdown)
        self.web.add_route('/api', self.web_handler, methods=['GET', 'POST'])
        self.web.add_websocket_route('/ws', self.websocket_handler)
        # Server static files
        static_dir = os.path.join(os.path.dirname(__file__), 'static')
        self.web.mount('/static', StaticFiles(directory=static_dir))
        if settings.ENABLE_WEB_CLIENT:
            self.web.add_route('/', client, methods=['GET'])
        if settings.ENABLE_DOCS:
            self.web.add_route('/docs', docs, methods=['GET'])
        if settings.ENABLE_SIGNUP:
            self.web.add_route('/signup', signup, methods=['GET', 'POST'])

    async def startup(self):
        dorm.setup(settings.DATABASE, models=[Account])
        print('Starting binary protocol server on {}:{}'.format(settings.SOCKET_BIND, settings.SOCKET_PORT))
        # Careful not to use the event loop until after uvicorn starts it, since it may swap in uvloop.
        self.loop = asyncio.get_event_loop()
        self.server = await self.loop.create_server(lambda: SocketSession(self), settings.SOCKET_BIND,
            settings.SOCKET_PORT)
        if settings.ENABLE_IRC:
            print('Starting IRC server on {}:{}'.format(settings.IRC_BIND, settings.IRC_PORT))
            self.irc = await self.loop.create_server(lambda: IRCSession(self), settings.IRC_BIND, settings.IRC_PORT)

    async def shutdown(self):
        print('Stopping binary protocol server')
        self.server.close()
        if self.irc:
            self.irc.close()

    async def web_handler(self, request):
        session_token = request.headers.get('x-neolith-session')
        session = self.get(token=session_token, default=WebSession())
        if request.method == 'GET':
            return JSONResponse([tx.to_dict() for tx in await session.events()])
        elif request.method == 'POST':
            session.hostname = request.client.host
            if not session.ident:
                await self.connected(session)
            tx = Transaction(await request.json())
            response = await self.handle(session, tx, send=False)
            return JSONResponse(response.to_dict())
        else:
            return JSONResponse({'error': 'Invalid HTTP method.'}, status_code=405)

    async def websocket_handler(self, websocket, **kwargs):
        await websocket.accept()

        session = WebSocketSession(websocket)
        session.hostname = websocket.client.host

        await self.connected(session)

        try:
            while True:
                tx = Transaction(await websocket.receive_json())
                await self.handle(session, tx)
        except WebSocketDisconnect:
            print('websocket disconnected')
        finally:
            await self.disconnected(session)

    async def handle(self, session, transaction, send=True):
        print(session, '-->', transaction.to_dict())
        response = transaction.response()
        for packet in transaction.packets:
            assert isinstance(packet, ClientPacket)
            try:
                if packet.requires_auth and not session.authenticated:
                    raise ProtocolError('This request requires authentication.')
                response.add(await packet.handle(self, session))
            except ProtocolError as e:
                response.error = str(e)
        if send and not response.empty:
            await session.send(response)
        return response

    async def connected(self, session):
        print('New connection - {}'.format(session))
        session.ident = binascii.hexlify(os.urandom(16)).decode('ascii')
        session.token = binascii.hexlify(os.urandom(16)).decode('ascii')
        self.sessions[session.ident] = session

    async def disconnected(self, session):
        if session.authenticated:
            session.authenticated = False
            for channel in self.channels:
                if session in channel.sessions:
                    channel.remove(session)
                    await channel.send(ChannelLeave(channel=channel.name, user=session))
            await self.broadcast(UserLeft(user=session))
        if session.ident in self.sessions:
            del self.sessions[session.ident]

    def start(self):
        uvicorn.run(self.web, host=settings.WEB_BIND, port=settings.WEB_PORT)

    async def broadcast(self, message):
        for session in self.sessions.values():
            if session.authenticated:
                await session.send(message)

    async def authenticate(self, session):
        if session.authenticated:
            raise ProtocolError('Session is already authenticated.')
        if self.get(nickname=session.nickname, authenticated=True):
            raise ProtocolError('This nickname is already in use.')
        # XXX: where should this go? maybe a new task to be executed next time through the loop?
        await self.broadcast(UserJoined(user=session))
        if settings.PUBLIC_CHANNEL and settings.AUTO_JOIN:
            channel = self.channels[settings.PUBLIC_CHANNEL]
            channel.add(session)
            await channel.send(ChannelJoin(channel=settings.PUBLIC_CHANNEL, user=session))
        # Authenticate the session after sending the joins, so we don't send joins before the login response.
        print('Authenticated {}'.format(session))
        session.authenticated = True
        return session.ident

    def find(self, **kwargs):
        for session in self.sessions.values():
            match = True
            for field, value in kwargs.items():
                if getattr(session, field) != value:
                    match = False
            if match:
                yield session

    def get(self, **kwargs):
        default = kwargs.pop('default', None)
        for session in self.find(**kwargs):
            return session
        return default
Ejemplo n.º 9
0
app = Starlette()
app.debug = settings.DEBUG
app.testing = settings.TESTING

app.mount(
    "/send",
    Router([
        Route("/email", endpoint=EmailEndpoint, methods=("POST", )),
        Route("/sms", endpoint=SmsEndpoint, methods=("POST", )),
    ]),
)

# Register event handlers for both the "startup" and "shutdown" events. These
# event handlers are used to automatically manage the connection to the
# database.
app.add_event_handler("startup", open_database_connection)
app.add_event_handler("shutdown", close_database_connection)

# Use the built-in Authentication Middleware, utilizing the custom HTTP Basic
# Authentication backend from `middleware.py`. Using this middleware, every
# request requires a username and password to be provided.
app.add_middleware(AuthenticationMiddleware, backend=BasicAuthBackend())

if __name__ == "__main__":
    import uvicorn

    config = {
        "host": "0.0.0.0",
        "port": 8000,
        "log_level": "debug" if settings.DEBUG else "info",
    }
Ejemplo n.º 10
0
def setup_auth_service(app: Starlette, config: AuthServiceConfig) -> None:
    auth_service = AuthService.from_config(config)
    app.state.auth_service = auth_service

    app.add_event_handler(Signal.STARTUP, auth_service.setup)
    app.add_event_handler(Signal.SHUTDOWN, auth_service.cleanup)
Ejemplo n.º 11
0
    return number + 1


schema = make_executable_schema(SCHEMA, [mutation, query, subscription])

graphql_server = GraphQL(schema)


async def init_database():
    await db.set_bind("postgresql://localhost/gino")
    await db.gino.create_all()


app = Starlette()
app.add_route("/graphql/", graphql_server)
app.add_websocket_route("/graphql/", graphql_server)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["POST"],
    allow_headers=[
        "accept",
        "accept-language",
        "content-language",
        "content-type",
        "x-apollo-tracing",
    ],
)
app.add_event_handler("startup", init_database)
app.debug = True
Ejemplo n.º 12
0
class UserCredentials(typesystem.Schema):
    username = typesystem.String()
    password = typesystem.String()


# Application

app = Starlette()

app.add_middleware(
    AuthenticationMiddleware,
    backend=auth_backend,
    on_error=lambda _, exc: PlainTextResponse(str(exc), status_code=401),
)

app.add_event_handler("startup", database.connect)
app.add_event_handler("shutdown", database.disconnect)


@app.route("/protected")
@requires("authenticated")
async def protected(request):
    """Example protected route."""
    return JSONResponse({"message": f"Hello, {request.user.username}!"})


@app.route("/users", methods=["post"])
async def create_user(request: Request):
    """Example user registration route."""
    credentials = UserCredentials.validate(await request.json())
    user = await User.objects.create(
Ejemplo n.º 13
0
from starlette.applications import Starlette
from starlette.responses import PlainTextResponse

from caffeine.common.settings import Settings
from caffeine.rest.bootstrap import RestBootstrap

app = Starlette()

settings = Settings()
settings.read_env()

web = RestBootstrap(app, settings)

app.add_event_handler("startup", web.init)
app.add_event_handler("shutdown", web.shutdown)


@app.route("/")
async def homepage(request):
    return PlainTextResponse("This is messeeks, look at me!")


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="localhost", port=8000)
Ejemplo n.º 14
0
def starlette(parent: Starlette, path: str, app: TartifletteApp, **kwargs):
    parent.mount(path, app, **kwargs)
    parent.add_event_handler("startup", app.startup)
Ejemplo n.º 15
0
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette.routing import Route
from starlette_exporter import PrometheusMiddleware, handle_metrics


async def main(request: Request) -> JSONResponse:
    return JSONResponse({"message": "hello world"})


async def health(request: Request) -> Response:
    return Response()


async def force_failure():
    raise RuntimeError("kaboom")


app = Starlette(debug=True, routes=[
    Route('/', main),
    Route('/health', health)
])
app.last_value = 0
app.add_middleware(PrometheusMiddleware)
app.add_route("/metrics", handle_metrics)
# this will make our probe unstartable
app.add_event_handler("startup", force_failure)