Skip to content

Commit

Permalink
feat: Add Chainlit (#2)
Browse files Browse the repository at this point in the history
* Add Chainlit

* Sort imports and remove tests

* Formatting and linting
  • Loading branch information
KevinJBoyer authored Jun 24, 2024
1 parent ce2baee commit b374792
Show file tree
Hide file tree
Showing 13 changed files with 910 additions and 634 deletions.
42 changes: 0 additions & 42 deletions .github/workflows/ci-openapi.yml

This file was deleted.

3 changes: 3 additions & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ coverage.*

# Poetry installer local error logs
poetry-installer-error-*.log

# Chainlit
.chainlit
4 changes: 2 additions & 2 deletions app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ COPY . /app
ENV HOST=0.0.0.0

# Run the application.
CMD ["poetry", "run", "python", "-m", "src"]
CMD ["poetry", "run", "chainlit", "run", "src/app.py", "-w"]

#---------
# Release
Expand Down Expand Up @@ -109,4 +109,4 @@ ENV HOST=0.0.0.0
USER ${RUN_USER}

# Run the application.
CMD ["poetry", "run", "gunicorn", "src.app:create_app()"]
CMD ["poetry", "run", "chainlit", "run", "src/app.py"]
897 changes: 895 additions & 2 deletions app/poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ marshmallow = "^3.20.1"
gunicorn = "^21.2.0"
psycopg = {extras = ["binary"], version = "^3.1.10"}
pydantic-settings = "^2.0.3"
chainlit = "^1.1.304"

[tool.poetry.group.dev.dependencies]
black = "^23.9.1"
Expand Down
94 changes: 7 additions & 87 deletions app/src/app.py
Original file line number Diff line number Diff line change
@@ -1,93 +1,13 @@
import logging
import os
from typing import Optional

from apiflask import APIFlask
from flask import g
from werkzeug.exceptions import Unauthorized

import src.adapters.db as db
import src.adapters.db.flask_db as flask_db
import src.logging
import src.logging.flask_logger as flask_logger
from src.api.healthcheck import healthcheck_blueprint
from src.api.schemas import response_schema
from src.api.users import user_blueprint
from src.auth.api_key_auth import User, get_app_security_scheme
import chainlit as cl

logger = logging.getLogger(__name__)


def create_app() -> APIFlask:
app = APIFlask(__name__)

src.logging.init(__package__)
flask_logger.init_app(logging.root, app)

db_client = db.PostgresDBClient()
flask_db.register_db_client(db_client, app)

configure_app(app)
register_blueprints(app)
register_index(app)

return app


def current_user(is_user_expected: bool = True) -> Optional[User]:
current = g.get("current_user")
if is_user_expected and current is None:
logger.error("No current user found for request")
raise Unauthorized
return current


def configure_app(app: APIFlask) -> None:
# Modify the response schema to instead use the format of our ApiResponse class
# which adds additional details to the object.
# https://apiflask.com/schema/#base-response-schema-customization
app.config["BASE_RESPONSE_SCHEMA"] = response_schema.ResponseSchema

# Set a few values for the Swagger endpoint
app.config["OPENAPI_VERSION"] = "3.0.3"

# Set various general OpenAPI config values
app.info = {
"title": "Template Application Flask",
"description": "Template API for a Flask Application",
"contact": {
"name": "Nava PBC Engineering",
"url": "https://www.navapbc.com",
"email": "[email protected]",
},
}

# Set the security schema and define the header param
# where we expect the API token to reside.
# See: https://apiflask.com/authentication/#use-external-authentication-library
app.security_schemes = get_app_security_scheme()


def register_blueprints(app: APIFlask) -> None:
app.register_blueprint(healthcheck_blueprint)
app.register_blueprint(user_blueprint)


def get_project_root_dir() -> str:
return os.path.join(os.path.dirname(__file__), "..")


def register_index(app: APIFlask) -> None:
@app.route("/")
@app.doc(hide=True)
def index() -> str:
return """
<!Doctype html>
<html>
<head><title>Home</title></head>
<body>
<h1>Home</h1>
<p>Visit <a href="/docs">/docs</a> to view the api documentation for this project.</p>
</body>
</html>
"""
@cl.on_message
async def main(message: cl.Message) -> None:
logger.info(f"Received: {message.content}")
await cl.Message(
content=f"Hello, world! Received: {message.content}",
).send()
20 changes: 0 additions & 20 deletions app/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@

import _pytest.monkeypatch
import boto3
import flask
import flask.testing
import moto
import pytest

import src.adapters.db as db
import src.app as app_entry
import tests.src.db.models.factories as factories
from src.db import models
from src.util.local import load_local_env_vars
Expand Down Expand Up @@ -112,23 +109,6 @@ def enable_factory_create(monkeypatch, db_session) -> db.Session:
####################


# Make app session scoped so the database connection pool is only created once
# for the test session. This speeds up the tests.
@pytest.fixture(scope="session")
def app(db_client) -> flask.Flask:
return app_entry.create_app()


@pytest.fixture
def client(app: flask.Flask) -> flask.testing.FlaskClient:
return app.test_client()


@pytest.fixture
def cli_runner(app: flask.Flask) -> flask.testing.CliRunner:
return app.test_cli_runner()


@pytest.fixture
def api_auth_token(monkeypatch):
auth_token = "abcd1234"
Expand Down
29 changes: 0 additions & 29 deletions app/tests/src/auth/test_api_key_auth.py

This file was deleted.

18 changes: 0 additions & 18 deletions app/tests/src/route/test_healthcheck.py

This file was deleted.

4 changes: 0 additions & 4 deletions app/tests/src/route/test_index_route.py

This file was deleted.

Loading

0 comments on commit b374792

Please sign in to comment.