Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# syntax=docker/dockerfile:1.7-labs
# Start from a base image with Miniconda installed
FROM continuumio/miniconda3

Expand All @@ -9,14 +10,36 @@ RUN apt-get update && \
# Set the working directory in the container
WORKDIR /backend-api

# Copy the current directory contents and the Conda environment file into the container
COPY . .

# Create the environment from the environment.yml file
COPY environment.yml ./
RUN conda env create -f environment.yml

# Make RUN commands use the new environment
SHELL ["conda", "run", "-n", "backend-api", "/bin/bash", "-c"]

# Copy Optional wheels directory and handle wheel installation (for utilizing local hummingbot version)
COPY --parents wheels* .

# Optionally install local Hummingbot wheel if present - use the latest wheel only
RUN if [ -n "$(find wheels/ -name 'hummingbot-*.whl' 2>/dev/null)" ]; then \
echo "Installing local Hummingbot wheel..." && \
LATEST_WHEEL=$(find wheels/ -name 'hummingbot-*.whl' | sort -r | head -n1) && \
echo "Using wheel: $LATEST_WHEEL" && \
pip install --force-reinstall $LATEST_WHEEL && \
echo "Local Hummingbot wheel installed successfully"; \
else \
echo "No local Hummingbot wheel found, using version from environment.yml"; \
fi

# Copy the current directory contents and the Conda environment file into the container
COPY main.py models.py config.py LICENSE README.md ./
COPY utils/ utils/
COPY routers/ routers/
COPY services/ services/

COPY bots/controllers bots/credentials bots/scripts bots/__init__.py bots/

# Add any other specific directories or files needed

# The code to run when container is started
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "backend-api", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
.PHONY: install-pre-commit
.PHONY: docker_build
.PHONY: docker_run
.PHONY: reference-local-hummingbot


detect_conda_bin := $(shell bash -c 'if [ "${CONDA_EXE} " == " " ]; then \
Expand Down Expand Up @@ -44,7 +45,11 @@ install-pre-commit:
fi && pre-commit install'

docker_build:
docker build -t hummingbot/backend-api:latest .
docker build -t hummingbot/backend-api$(TAG) .

docker_run:
docker compose up -d

# See reference_local_hummingbot.sh for available options
reference-local-hummingbot:
bash ./scripts/reference_local_hummingbot.sh $(if $(force-repackage),--force-repackage,) $(if $(build-env),--build-env=$(build-env),) $(ARGS)
166 changes: 166 additions & 0 deletions scripts/reference_local_hummingbot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/bin/bash

# Script to build, copy and install a Python wheel package from a source directory to a destination directory

print_usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " --force-repackage Force rebuilding the wheel package"
echo " --source-dir=DIR Source directory containing the Python package (default: ../hummingbot)"
echo " --dest-dir=DIR Destination directory for the wheel file (default: ./wheels)"
echo " --package-name=NAME Name of the package to build (default: hummingbot)"
echo " --conda-env=NAME Conda environment to install into (required if not in environment.yml or .env)"
echo " --build-env=NAME Conda environment to build the package in (default: hummingbot)"
echo " --help Show this help message"
echo ""
echo "When called from Makefile, you can use this format for arguments not in the makefile:"
echo "make reference-local-hummingbot ARGS=\"--force-repackage --source-dir=DIR ...\""
}

# Default values
FORCE_REPACKAGE=false
SOURCE_DIR=""
DEST_DIR=""
PACKAGE_NAME="hummingbot"
CONDA_ENV=""
BUILD_ENV="hummingbot"

# Get current working directory
CWD="$(pwd)"

# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--force-repackage)
FORCE_REPACKAGE=true
shift
;;
--source-dir=*)
SOURCE_DIR="${1#*=}"
shift
;;
--dest-dir=*)
DEST_DIR="${1#*=}"
shift
;;
--package-name=*)
PACKAGE_NAME="${1#*=}"
shift
;;
--conda-env=*)
CONDA_ENV="${1#*=}"
shift
;;
--build-env=*)
BUILD_ENV="${1#*=}"
shift
;;
--help)
print_usage
exit 0
;;
*)
echo "Unknown option: $1"
print_usage
exit 1
;;
esac
done

# Extract conda environment name from environment.yml
if [ -z "$CONDA_ENV" ] && [ -f "$CWD/environment.yml" ]; then
CONDA_ENV=$(grep "^name:" "$CWD/environment.yml" | cut -d ":" -f2 | tr -d " ")
fi

# If not found in environment.yml, try .env file
if [ -z "$CONDA_ENV" ] && [ -f "$CWD/.env" ]; then
CONDA_ENV=$(grep "^CONDA_ENV=" "$CWD/.env" | cut -d "=" -f2 | tr -d '"' | tr -d "'" | tr -d " ")
fi

# If still not found, throw an error
if [ -z "$CONDA_ENV" ]; then
echo "Error: Conda environment name not found in environment.yml or .env"
echo "Please specify with --conda-env option or add CONDA_ENV to .env file or name to environment.yml"
exit 1
fi

# Set default paths if not provided
if [ -z "$SOURCE_DIR" ]; then
SOURCE_DIR="../$PACKAGE_NAME"
fi

if [ -z "$DEST_DIR" ]; then
DEST_DIR="./wheels"
fi

# Convert to absolute paths if relative
if [[ ! "$SOURCE_DIR" = /* ]]; then
SOURCE_DIR="$CWD/$SOURCE_DIR"
fi

if [[ ! "$DEST_DIR" = /* ]]; then
DEST_DIR="$CWD/$DEST_DIR"
fi

# Create wheels directory if it doesn't exist
mkdir -p "$DEST_DIR"

# Check for existing wheel in source directory
cd "$SOURCE_DIR" || { echo "Error: Could not change to source directory: $SOURCE_DIR"; exit 1; }
EXISTING_WHEEL=$(ls "dist/$PACKAGE_NAME-"*.whl 2>/dev/null)
if [ -n "$EXISTING_WHEEL" ] && [ "$FORCE_REPACKAGE" = false ]; then
echo "Found existing wheel: $EXISTING_WHEEL"
WHEEL_FILE="$EXISTING_WHEEL"
else
if [ -n "$EXISTING_WHEEL" ]; then
echo "Force repackage requested, rebuilding wheel..."
rm -f "$EXISTING_WHEEL"
echo "Removed existing wheel: $EXISTING_WHEEL"
fi

# Build wheel
echo "Building $PACKAGE_NAME wheel in conda environment '$BUILD_ENV'..."
conda run -n $BUILD_ENV python setup.py sdist bdist_wheel

# Find the wheel file
WHEEL_FILE=$(ls "dist/$PACKAGE_NAME-"*.whl 2>/dev/null)
if [ -z "$WHEEL_FILE" ]; then
echo "Error: No wheel file found in dist directory"
exit 1
fi
fi

# Get the wheel filename without path
WHEEL_FILENAME=$(basename "$WHEEL_FILE")

# Check if there's already a matching wheel file in the destination directory
LOCAL_WHEEL_FILE="$DEST_DIR/$WHEEL_FILENAME"
if [ -f "$LOCAL_WHEEL_FILE" ]; then
# Calculate hashes for both files
SOURCE_HASH=$(sha256sum "$WHEEL_FILE" | cut -d ' ' -f 1)
LOCAL_HASH=$(sha256sum "$LOCAL_WHEEL_FILE" | cut -d ' ' -f 1)

# Compare hashes
if [ "$SOURCE_HASH" = "$LOCAL_HASH" ]; then
if [ -z "$EXISTING_WHEEL" ] || [ "$FORCE_REPACKAGE" = true ]; then
echo "Existing local $LOCAL_WHEEL_FILE already matches generated $WHEEL_FILE"
else
echo "Existing local $LOCAL_WHEEL_FILE already matches existing $WHEEL_FILE"
fi
echo "Skipping installation as files are identical."
exit 0
else
echo "Local wheel exists but has different hash, will update..."
fi
fi

# Copy wheel to destination directory
echo "Copying $(basename "$WHEEL_FILE") to wheels directory..."
cp "$WHEEL_FILE" "$DEST_DIR/"
WHEEL_FILE="$DEST_DIR/$(basename "$WHEEL_FILE")"

# Install new wheel
echo "Installing $(basename "$WHEEL_FILE") into conda environment '$CONDA_ENV'..."
conda run -n $CONDA_ENV pip install --force-reinstall "$WHEEL_FILE"

echo -e "\nSuccessfully installed $(basename "$WHEEL_FILE") into conda environment '$CONDA_ENV'"