Skip to content

Commit

Permalink
📦 NEW: Added API endpoints for querying and Docker image
Browse files Browse the repository at this point in the history
  • Loading branch information
bearlike committed May 12, 2024
1 parent 23f2867 commit 5828237
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 58 deletions.
115 changes: 82 additions & 33 deletions .github/workflows/docker-buildx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
# If the branch name is 'release/1.0.2-dev', the image is tagged as '1.0.2-dev'.
#
# * The 'latest' and 'stable' tags allow us to easily switch between different versions.
# * The 'dev' tag allows you to have a separate version for development.
# * The 'dev' tag allows you to have a separate version for development.

name: Build Meseeks Chat Docker Image

name: Build and Push Docker Images

on:
workflow_dispatch:
Expand All @@ -25,48 +26,96 @@ on:
- "release/*"

jobs:
build:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Extract version and release type
id: extract_version
run: |
BRANCH_NAME=${{ github.ref }}
VERSION=$(echo $BRANCH_NAME | cut -d'/' -f 3 | cut -d'-' -f 1)
RELEASE_TYPE=$(echo $BRANCH_NAME | cut -d'/' -f 3 | cut -d'-' -f 2)
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "release_type=$RELEASE_TYPE" >> $GITHUB_OUTPUT
- name: Docker meta for meeseeks-base
id: meta_base
uses: docker/metadata-action@v5
with:
images: ghcr.io/bearlike/meeseeks-base
tags: |
type=raw,value=${{ steps.extract_version.outputs.version }}${{ steps.extract_version.outputs.release_type == 'dev' && '-dev' || '' }}
type=raw,value=latest,enable=${{ steps.extract_version.outputs.release_type == 'latest' }}
type=raw,value=stable,enable=${{ steps.extract_version.outputs.release_type == 'stable' }}
type=raw,value=dev,enable=${{ steps.extract_version.outputs.release_type == 'dev' }}
- name: Docker meta for meeseeks-chat
id: meta_chat
uses: docker/metadata-action@v5
with:
images: ghcr.io/bearlike/meeseeks-chat
tags: |
type=raw,value=${{ steps.extract_version.outputs.version }}${{ steps.extract_version.outputs.release_type == 'dev' && '-dev' || '' }}
type=raw,value=latest,enable=${{ steps.extract_version.outputs.release_type == 'latest' }}
type=raw,value=stable,enable=${{ steps.extract_version.outputs.release_type == 'stable' }}
type=raw,value=dev,enable=${{ steps.extract_version.outputs.release_type == 'dev' }}
- name: Docker meta for meeseeks-api
id: meta_api
uses: docker/metadata-action@v5
with:
images: ghcr.io/bearlike/meeseeks-api
tags: |
type=raw,value=${{ steps.extract_version.outputs.version }}${{ steps.extract_version.outputs.release_type == 'dev' && '-dev' || '' }}
type=raw,value=latest,enable=${{ steps.extract_version.outputs.release_type == 'latest' }}
type=raw,value=stable,enable=${{ steps.extract_version.outputs.release_type == 'stable' }}
type=raw,value=dev,enable=${{ steps.extract_version.outputs.release_type == 'dev' }}
- name: Login to DockerHub
uses: docker/login-action@v1
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract branch name
id: extract_branch
shell: bash
run: |
BRANCH_NAME=$(echo ${{ github.ref }} | sed 's/refs\/heads\///')
echo "branch=$BRANCH_NAME" >> $GITHUB_ENV
echo "Extracted branch name: $BRANCH_NAME"
- name: Build and push meeseeks-base
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.base
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta_base.outputs.tags }}
labels: ${{ steps.meta_base.outputs.labels }}

- name: Set version and channel
id: version_channel
run: |
BRANCH_NAME=${{ env.branch }}
VERSION=$(echo $BRANCH_NAME | cut -d'/' -f 2 | cut -d'-' -f 1)
CHANNEL=$(echo $BRANCH_NAME | cut -d'/' -f 2 | cut -d'-' -f 2)
echo "version=$VERSION" >> $GITHUB_ENV
echo "channel=$CHANNEL" >> $GITHUB_ENV
echo "Extracted version: $VERSION"
echo "Extracted channel: $CHANNEL"
echo "Extracted branch name: $BRANCH_NAME"
- name: Build and push meeseeks-chat
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.chat
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta_chat.outputs.tags }}
labels: ${{ steps.meta_chat.outputs.labels }}
build-args: |
BASE_IMAGE=ghcr.io/bearlike/meeseeks-base:${{ steps.extract_version.outputs.version }}${{ steps.extract_version.outputs.release_type == 'dev' && '-dev' || '' }}
- name: Build and push
uses: docker/build-push-action@v2
- name: Build and push meeseeks-api
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
ghcr.io/bearlike/meeseeks-chat:${{ env.version }}${{ env.channel == 'dev' && '-dev' || '' }}
ghcr.io/bearlike/meeseeks-chat:${{ env.channel == 'latest' && 'latest' || env.channel == 'stable' && 'stable' || 'dev' }}
file: Dockerfile.api
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta_api.outputs.tags }}
labels: ${{ steps.meta_api.outputs.labels }}
build-args: |
BASE_IMAGE=ghcr.io/bearlike/meeseeks-base:${{ steps.extract_version.outputs.version }}${{ steps.extract_version.outputs.release_type == 'dev' && '-dev' || '' }}
22 changes: 22 additions & 0 deletions Dockerfile.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# syntax=docker/dockerfile:1

# Dockerfile.api
ARG BASE_IMAGE="ghcr.io/bearlike/meeseeks-base:latest"
FROM $BASE_IMAGE

ARG TITLE="Meeseeks API: Personal Assistant"

LABEL title=$TITLE

# Install the meeseeks-api dependencies
WORKDIR /app/meeseeks-api
RUN poetry install

# Set API specific environment variable
ENV MASTER_API_TOKEN='msk-strong-password'

# Expose port 5123 for the API
EXPOSE 5123

# Run the API application
ENTRYPOINT ["poetry", "run", "python", "backend.py"]
21 changes: 4 additions & 17 deletions Dockerfile → Dockerfile.base
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Dockerfile to build meeseeks-chat with core dependencies.
# syntax=docker/dockerfile:1

# Dockerfile.base
FROM python:3.11-buster

# Set the title, GitHub repo URL, version, and author
ARG TITLE="Meeseeks Chat: Personal Assistant" \
ARG TITLE="Meeseeks Base" \
VERSION="1.0.0" \
AUTHOR="Krishnakanth Alagiri"

Expand Down Expand Up @@ -43,11 +44,7 @@ RUN pip install 'poetry>=1.8,<1.9'
# Install the core dependencies
RUN poetry install

# Install the meeseeks-chat dependencies
WORKDIR /app/meeseeks-chat
RUN poetry install

# Set default environment variablesfor Meeseeks
# Set default environment variables for Meeseeks (common ones)
ENV CACHE_DIR='/tmp/meeseeks_cache' \
DEFAULT_MODEL='gpt-3.5-turbo' \
LOG_LEVEL=DEBUG \
Expand All @@ -56,13 +53,3 @@ ENV CACHE_DIR='/tmp/meeseeks_cache' \
COLOREDLOGS_FIELD_STYLES='asctime=color=240;name=45,inverse' \
COLOREDLOGS_LEVEL_STYLES='info=220;spam=22;debug=34;verbose=34;notice=220;warning=202;success=118,bold;error=124;critical=background=red' \
COLOREDLOGS_LOG_FORMAT='%(asctime)s [%(name)s] %(levelname)s %(message)s'


# Expose port 8501 for Streamlit
EXPOSE 8502

# Healthcheck to ensure the Streamlit server is running
HEALTHCHECK CMD curl --fail http://localhost:8502/_stcore/health

# Run the Streamlit application
ENTRYPOINT ["poetry", "run", "python", "-m", "streamlit", "run", "chat_master.py", "--server.port=8502", "--server.address=0.0.0.0"]
22 changes: 22 additions & 0 deletions Dockerfile.chat
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# syntax=docker/dockerfile:1

# Dockerfile.chat
ARG BASE_IMAGE="ghcr.io/bearlike/meeseeks-base:latest"
FROM $BASE_IMAGE

ARG TITLE="Meeseeks Chat: Personal Assistant"

LABEL title=$TITLE

# Install the meeseeks-chat dependencies
WORKDIR /app/meeseeks-chat
RUN poetry install

# Expose port 8502 for Streamlit
EXPOSE 8502

# Healthcheck to ensure the Streamlit server is running
HEALTHCHECK CMD curl --fail http://localhost:8502/_stcore/health

# Run the Streamlit application
ENTRYPOINT ["poetry", "run", "python", "-m", "streamlit", "run", "chat_master.py", "--server.port=8502", "--server.address=0.0.0.0"]
3 changes: 2 additions & 1 deletion meeseeks-api/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# meeseeks-api

REST API Engine wrapped around the meeseeks-core
- REST API Engine wrapped around the meeseeks-core.
- No components are explicitly tested for safety or security. Use with caution in a production environment.

[Link to GitHub Repository](https://github.com/bearlike/Personal-Assistant/edit/main/README.md)
28 changes: 21 additions & 7 deletions meeseeks-api/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,28 @@

# Load environment variables
load_dotenv()
# Get the API token from the environment variables
# The default API token is "msk-strong-password"
MASTER_API_TOKEN = os.getenv("MASTER_API_TOKEN", "msk-strong-password")

# Initialize logger
logging = get_logger(name="meeseeks-api")

logging.debug("Starting API server with API token: %s", MASTER_API_TOKEN)
# Create Flask application
app = Flask(__name__)

authorizations = {
'apikey': {
'type': 'apiKey',
'in': 'header',
'name': 'X-API-KEY'
}
}
VERSION = os.getenv("VERSION", "(Dev)")
# Create API instance with Swagger documentation
api = Api(app, version='1.0', title='Meeseeks API',
api = Api(app, version=VERSION, title='Meeseeks API',
description='Interact with Meeseeks through a REST API',
doc='/swagger-ui/')
doc='/swagger-ui/', authorizations=authorizations, security='apikey')

# Define API namespace
ns = api.namespace('api', description='Meeseeks operations')
Expand Down Expand Up @@ -70,7 +82,7 @@ class MeeseeksQuery(Resource):
action plan as a JSON response.
"""

@api.doc(security='apiKey')
@api.doc(security='apikey')
@api.expect(api.model('Query', {'query': fields.String(
required=True, description='The user query')}))
@api.response(200, 'Success', task_queue_model)
Expand All @@ -84,10 +96,12 @@ def post(self) -> Dict:
Requires a valid API token for authorization.
"""
# Get API token from headers
api_token = request.headers.get('X-API-Key')
api_token = request.headers.get('X-API-Key', None)

# Validate API token
if api_token != os.getenv("MASTER_API_TOKEN"):
if api_token is None:
return {"message": "API token is not provided."}, 401
if api_token != MASTER_API_TOKEN:
logging.warning(
"Unauthorized API call attempt with token: %s", api_token)
return {"message": "Unauthorized"}, 401
Expand All @@ -111,4 +125,4 @@ def post(self) -> Dict:


if __name__ == '__main__':
app.run(debug=True)
app.run(debug=True, host='0.0.0.0', port=5123)

0 comments on commit 5828237

Please sign in to comment.