- Getting containers ready for the cloud
This commit is contained in:
@@ -10,7 +10,8 @@ from flask_jwt_extended import JWTManager
|
|||||||
from flask_session import Session
|
from flask_session import Session
|
||||||
from flask_wtf import CSRFProtect
|
from flask_wtf import CSRFProtect
|
||||||
|
|
||||||
from .utils.key_encryption import JosKMSClient
|
# from .utils.key_encryption import JosKMSClient
|
||||||
|
from .utils.simple_encryption import SimpleEncryption
|
||||||
from .utils.minio_utils import MinioClient
|
from .utils.minio_utils import MinioClient
|
||||||
|
|
||||||
# Create extensions
|
# Create extensions
|
||||||
@@ -26,5 +27,7 @@ socketio = SocketIO()
|
|||||||
jwt = JWTManager()
|
jwt = JWTManager()
|
||||||
session = Session()
|
session = Session()
|
||||||
|
|
||||||
kms_client = JosKMSClient.from_service_account_json('config/gc_sa_eveai.json')
|
# kms_client = JosKMSClient.from_service_account_json('config/gc_sa_eveai.json')
|
||||||
|
|
||||||
|
simple_encryption = SimpleEncryption()
|
||||||
minio_client = MinioClient()
|
minio_client = MinioClient()
|
||||||
|
|||||||
39
common/utils/simple_encryption.py
Normal file
39
common/utils/simple_encryption.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
from cryptography.fernet import Fernet
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleEncryption:
|
||||||
|
def __init__(self, app: Flask = None):
|
||||||
|
self.app = app
|
||||||
|
self.fernet = None
|
||||||
|
if app is not None:
|
||||||
|
self.init_app(app)
|
||||||
|
|
||||||
|
def init_app(self, app: Flask):
|
||||||
|
self.app = app
|
||||||
|
encryption_key = app.config.get('API_ENCRYPTION_KEY')
|
||||||
|
if not encryption_key:
|
||||||
|
raise ValueError("ENCRYPTION_KEY is not set in the app configuration")
|
||||||
|
self.fernet = Fernet(encryption_key.encode())
|
||||||
|
|
||||||
|
# Optionally log the initialization (similar to your current setup)
|
||||||
|
app.logger.info('SimpleEncryption initialized')
|
||||||
|
|
||||||
|
def encrypt_api_key(self, api_key: str) -> str:
|
||||||
|
if not self.fernet:
|
||||||
|
raise RuntimeError("SimpleEncryption is not initialized. Call init_app first.")
|
||||||
|
return self.fernet.encrypt(api_key.encode()).decode()
|
||||||
|
|
||||||
|
def decrypt_api_key(self, encrypted_api_key: str) -> str:
|
||||||
|
if not self.fernet:
|
||||||
|
raise RuntimeError("SimpleEncryption is not initialized. Call init_app first.")
|
||||||
|
return self.fernet.decrypt(encrypted_api_key.encode()).decode()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def generate_key() -> str:
|
||||||
|
"""Generate a new Fernet key."""
|
||||||
|
return Fernet.generate_key().decode()
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# from common.utils.simple_encryption import simple_encryption
|
||||||
|
# simple_encryption.init_app(app)
|
||||||
140
config/config.py
140
config/config.py
@@ -10,7 +10,7 @@ basedir = path.abspath(path.dirname(__file__))
|
|||||||
class Config(object):
|
class Config(object):
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
DEVELOPMENT = False
|
DEVELOPMENT = False
|
||||||
SECRET_KEY = '97867c1491bea5ee6a8e8436eb11bf2ba6a69ff53ab1b17ecba450d0f2e572e1'
|
SECRET_KEY = environ.get('SECRET_KEY')
|
||||||
SESSION_COOKIE_SECURE = False
|
SESSION_COOKIE_SECURE = False
|
||||||
SESSION_COOKIE_HTTPONLY = True
|
SESSION_COOKIE_HTTPONLY = True
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ class Config(object):
|
|||||||
# SECURITY_POST_RESET_VIEW = '/admin/login'
|
# SECURITY_POST_RESET_VIEW = '/admin/login'
|
||||||
# SECURITY_POST_CHANGE_VIEW = '/admin/login'
|
# SECURITY_POST_CHANGE_VIEW = '/admin/login'
|
||||||
# SECURITY_BLUEPRINT_NAME = 'security_bp'
|
# SECURITY_BLUEPRINT_NAME = 'security_bp'
|
||||||
SECURITY_PASSWORD_SALT = '228614859439123264035565568761433607235'
|
SECURITY_PASSWORD_SALT = environ.get('SECURITY_PASSWORD_SALT')
|
||||||
REMEMBER_COOKIE_SAMESITE = 'strict'
|
REMEMBER_COOKIE_SAMESITE = 'strict'
|
||||||
SESSION_COOKIE_SAMESITE = 'strict'
|
SESSION_COOKIE_SAMESITE = 'strict'
|
||||||
SECURITY_CONFIRMABLE = True
|
SECURITY_CONFIRMABLE = True
|
||||||
@@ -45,13 +45,6 @@ class Config(object):
|
|||||||
SECURITY_CSRF_HEADER = 'X-XSRF-TOKEN'
|
SECURITY_CSRF_HEADER = 'X-XSRF-TOKEN'
|
||||||
WTF_CSRF_CHECK_DEFAULT = False
|
WTF_CSRF_CHECK_DEFAULT = False
|
||||||
|
|
||||||
# flask-mailman settings
|
|
||||||
MAIL_SERVER = 'mail.flow-it.net'
|
|
||||||
MAIL_PORT = 587
|
|
||||||
MAIL_USE_TLS = True
|
|
||||||
MAIL_USE_SSL = False
|
|
||||||
MAIL_DEFAULT_SENDER = ('eveAI Admin', 'eveai_admin@flow-it.net')
|
|
||||||
|
|
||||||
# file upload settings
|
# file upload settings
|
||||||
MAX_CONTENT_LENGTH = 16 * 1024 * 1024
|
MAX_CONTENT_LENGTH = 16 * 1024 * 1024
|
||||||
UPLOAD_EXTENSIONS = ['.txt', '.pdf', '.png', '.jpg', '.jpeg', '.gif']
|
UPLOAD_EXTENSIONS = ['.txt', '.pdf', '.png', '.jpg', '.jpeg', '.gif']
|
||||||
@@ -75,6 +68,18 @@ class Config(object):
|
|||||||
'anthropic.claude-3-5-sonnet': 8000
|
'anthropic.claude-3-5-sonnet': 8000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# OpenAI API Keys
|
||||||
|
OPENAI_API_KEY = environ.get('OPENAI_API_KEY')
|
||||||
|
|
||||||
|
# Groq API Keys
|
||||||
|
GROQ_API_KEY = environ.get('GROQ_API_KEY')
|
||||||
|
|
||||||
|
# Anthropic API Keys
|
||||||
|
ANTHROPIC_API_KEY = environ.get('ANTHROPIC_API_KEY')
|
||||||
|
|
||||||
|
# Portkey API Keys
|
||||||
|
PORTKEY_API_KEY = environ.get('PORTKEY_API_KEY')
|
||||||
|
|
||||||
# Celery settings
|
# Celery settings
|
||||||
CELERY_TASK_SERIALIZER = 'json'
|
CELERY_TASK_SERIALIZER = 'json'
|
||||||
CELERY_RESULT_SERIALIZER = 'json'
|
CELERY_RESULT_SERIALIZER = 'json'
|
||||||
@@ -93,6 +98,12 @@ class Config(object):
|
|||||||
PERMANENT_SESSION_LIFETIME = timedelta(minutes=60)
|
PERMANENT_SESSION_LIFETIME = timedelta(minutes=60)
|
||||||
SESSION_REFRESH_EACH_REQUEST = True
|
SESSION_REFRESH_EACH_REQUEST = True
|
||||||
|
|
||||||
|
# JWT settings
|
||||||
|
JWT_SECRET_KEY = environ.get('JWT_SECRET_KEY')
|
||||||
|
|
||||||
|
# API Encryption
|
||||||
|
API_ENCRYPTION_KEY = environ.get('API_ENCRYPTION_KEY')
|
||||||
|
|
||||||
# Fallback Algorithms
|
# Fallback Algorithms
|
||||||
FALLBACK_ALGORITHMS = [
|
FALLBACK_ALGORITHMS = [
|
||||||
"RAG_TENANT",
|
"RAG_TENANT",
|
||||||
@@ -115,25 +126,31 @@ class DevConfig(Config):
|
|||||||
DEBUG = True
|
DEBUG = True
|
||||||
FLASK_DEBUG = True
|
FLASK_DEBUG = True
|
||||||
PYCHARM_DEBUG = False
|
PYCHARM_DEBUG = False
|
||||||
|
EXPLAIN_TEMPLATE_LOADING = False
|
||||||
|
|
||||||
|
# Database Settings
|
||||||
DB_HOST = environ.get('DB_HOST', 'localhost')
|
DB_HOST = environ.get('DB_HOST', 'localhost')
|
||||||
DB_USER = environ.get('DB_USER', 'luke')
|
DB_USER = environ.get('DB_USER', 'luke')
|
||||||
DB_PASS = environ.get('DB_PASS', 'Skywalker!')
|
DB_PASS = environ.get('DB_PASS', 'Skywalker!')
|
||||||
DB_NAME = environ.get('DB_NAME', 'eveai')
|
DB_NAME = environ.get('DB_NAME', 'eveai')
|
||||||
|
|
||||||
SQLALCHEMY_DATABASE_URI = f'postgresql+pg8000://{DB_USER}:{DB_PASS}@{DB_HOST}:5432/{DB_NAME}'
|
SQLALCHEMY_DATABASE_URI = f'postgresql+pg8000://{DB_USER}:{DB_PASS}@{DB_HOST}:5432/{DB_NAME}'
|
||||||
SQLALCHEMY_BINDS = {'public': SQLALCHEMY_DATABASE_URI}
|
SQLALCHEMY_BINDS = {'public': SQLALCHEMY_DATABASE_URI}
|
||||||
EXPLAIN_TEMPLATE_LOADING = False
|
|
||||||
|
# flask-mailman settings
|
||||||
|
MAIL_SERVER = 'mail.flow-it.net'
|
||||||
|
MAIL_PORT = 587
|
||||||
|
MAIL_USE_TLS = True
|
||||||
|
MAIL_USE_SSL = False
|
||||||
|
MAIL_DEFAULT_SENDER = ('eveAI Admin', 'eveai_admin@flow-it.net')
|
||||||
|
MAIL_USERNAME = environ.get('MAIL_USERNAME')
|
||||||
|
MAIL_PASSWORD = environ.get('MAIL_PASSWORD')
|
||||||
|
|
||||||
# Define the nginx prefix used for the specific apps
|
# Define the nginx prefix used for the specific apps
|
||||||
EVEAI_APP_LOCATION_PREFIX = '/admin'
|
EVEAI_APP_LOCATION_PREFIX = '/admin'
|
||||||
EVEAI_CHAT_LOCATION_PREFIX = '/chat'
|
EVEAI_CHAT_LOCATION_PREFIX = '/chat'
|
||||||
|
|
||||||
# flask-mailman settings
|
|
||||||
MAIL_USERNAME = 'eveai_super@flow-it.net'
|
|
||||||
MAIL_PASSWORD = '$6xsWGbNtx$CFMQZqc*'
|
|
||||||
|
|
||||||
# file upload settings
|
# file upload settings
|
||||||
UPLOAD_FOLDER = '/app/tenant_files'
|
# UPLOAD_FOLDER = '/app/tenant_files'
|
||||||
|
|
||||||
# Celery settings
|
# Celery settings
|
||||||
# eveai_app Redis Settings
|
# eveai_app Redis Settings
|
||||||
@@ -143,22 +160,10 @@ class DevConfig(Config):
|
|||||||
CELERY_BROKER_URL_CHAT = 'redis://redis:6379/3'
|
CELERY_BROKER_URL_CHAT = 'redis://redis:6379/3'
|
||||||
CELERY_RESULT_BACKEND_CHAT = 'redis://redis:6379/3'
|
CELERY_RESULT_BACKEND_CHAT = 'redis://redis:6379/3'
|
||||||
|
|
||||||
# OpenAI API Keys
|
|
||||||
OPENAI_API_KEY = 'sk-proj-8R0jWzwjL7PeoPyMhJTZT3BlbkFJLb6HfRB2Hr9cEVFWEhU7'
|
|
||||||
|
|
||||||
# Groq API Keys
|
|
||||||
GROQ_API_KEY = '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'
|
|
||||||
|
|
||||||
# Anthropic API Keys
|
|
||||||
ANTHROPIC_API_KEY = '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'
|
|
||||||
|
|
||||||
# Portkey API Keys
|
|
||||||
PORTKEY_API_KEY = 'T2Dt4QTpgCvWxa1OftYCJtj7NcDZ'
|
|
||||||
|
|
||||||
# Unstructured settings
|
# Unstructured settings
|
||||||
UNSTRUCTURED_API_KEY = 'pDgCrXumYhM3CNvjvwV8msMldXC3uw'
|
# UNSTRUCTURED_API_KEY = 'pDgCrXumYhM3CNvjvwV8msMldXC3uw'
|
||||||
UNSTRUCTURED_BASE_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io'
|
# UNSTRUCTURED_BASE_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io'
|
||||||
UNSTRUCTURED_FULL_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io/general/v0/general'
|
# UNSTRUCTURED_FULL_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io/general/v0/general'
|
||||||
|
|
||||||
# SocketIO settings
|
# SocketIO settings
|
||||||
SOCKETIO_MESSAGE_QUEUE = 'redis://redis:6379/1'
|
SOCKETIO_MESSAGE_QUEUE = 'redis://redis:6379/1'
|
||||||
@@ -176,9 +181,6 @@ class DevConfig(Config):
|
|||||||
GC_KEY_RING = 'eveai-chat'
|
GC_KEY_RING = 'eveai-chat'
|
||||||
GC_CRYPTO_KEY = 'envelope-encryption-key'
|
GC_CRYPTO_KEY = 'envelope-encryption-key'
|
||||||
|
|
||||||
# JWT settings
|
|
||||||
JWT_SECRET_KEY = 'bsdMkmQ8ObfMD52yAFg4trrvjgjMhuIqg2fjDpD/JqvgY0ccCcmlsEnVFmR79WPiLKEA3i8a5zmejwLZKl4v9Q=='
|
|
||||||
|
|
||||||
# Session settings
|
# Session settings
|
||||||
SESSION_REDIS = redis.from_url('redis://redis:6379/2')
|
SESSION_REDIS = redis.from_url('redis://redis:6379/2')
|
||||||
|
|
||||||
@@ -194,19 +196,28 @@ class DevConfig(Config):
|
|||||||
class ProdConfig(Config):
|
class ProdConfig(Config):
|
||||||
DEVELOPMENT = False
|
DEVELOPMENT = False
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
DEVELOPMENT = True
|
DEBUG = False
|
||||||
DEBUG = True
|
FLASK_DEBUG = False
|
||||||
FLASK_DEBUG = True
|
|
||||||
PYCHARM_DEBUG = False
|
PYCHARM_DEBUG = False
|
||||||
DB_HOST = environ.get('DB_HOST', 'bswnz4.stackhero-network.com')
|
EXPLAIN_TEMPLATE_LOADING = False
|
||||||
DB_USER = environ.get('DB_USER', 'luke_skywalker')
|
|
||||||
DB_PASS = environ.get('DB_PASS', '2MK&1rHmWEydE2rFuJLq*ls%tdkPAk2')
|
|
||||||
DB_NAME = environ.get('DB_NAME', 'eveai')
|
|
||||||
DB_PORT = environ.get('DB_PORT', '5945')
|
|
||||||
|
|
||||||
|
# Database Settings
|
||||||
|
DB_HOST = environ.get('DB_HOST')
|
||||||
|
DB_USER = environ.get('DB_USER')
|
||||||
|
DB_PASS = environ.get('DB_PASS')
|
||||||
|
DB_NAME = environ.get('DB_NAME')
|
||||||
|
DB_PORT = environ.get('DB_PORT')
|
||||||
SQLALCHEMY_DATABASE_URI = f'postgresql+pg8000://{DB_USER}:{DB_PASS}@{DB_HOST}:{DB_PORT}/{DB_NAME}'
|
SQLALCHEMY_DATABASE_URI = f'postgresql+pg8000://{DB_USER}:{DB_PASS}@{DB_HOST}:{DB_PORT}/{DB_NAME}'
|
||||||
SQLALCHEMY_BINDS = {'public': SQLALCHEMY_DATABASE_URI}
|
SQLALCHEMY_BINDS = {'public': SQLALCHEMY_DATABASE_URI}
|
||||||
EXPLAIN_TEMPLATE_LOADING = False
|
|
||||||
|
# flask-mailman settings
|
||||||
|
MAIL_SERVER = 'mail.askeveai.com'
|
||||||
|
MAIL_PORT = 587
|
||||||
|
MAIL_USE_TLS = True
|
||||||
|
MAIL_USE_SSL = False
|
||||||
|
MAIL_DEFAULT_SENDER = ('Evie Admin', 'evie_admin@askeveai.com')
|
||||||
|
MAIL_USERNAME = environ.get('MAIL_USERNAME')
|
||||||
|
MAIL_PASSWORD = environ.get('MAIL_PASSWORD')
|
||||||
|
|
||||||
# Define the nginx prefix used for the specific apps
|
# Define the nginx prefix used for the specific apps
|
||||||
EVEAI_APP_LOCATION_PREFIX = '/admin'
|
EVEAI_APP_LOCATION_PREFIX = '/admin'
|
||||||
@@ -217,12 +228,13 @@ class ProdConfig(Config):
|
|||||||
MAIL_PASSWORD = '$6xsWGbNtx$CFMQZqc*'
|
MAIL_PASSWORD = '$6xsWGbNtx$CFMQZqc*'
|
||||||
|
|
||||||
# file upload settings
|
# file upload settings
|
||||||
UPLOAD_FOLDER = '/app/tenant_files'
|
# UPLOAD_FOLDER = '/app/tenant_files'
|
||||||
|
|
||||||
REDIS_USER = 'admin'
|
# Redis Settings
|
||||||
REDIS_PASS = 'b32vtDtLriSY1fL2zGrZg8IZKI0g9ucsLtVNanRFAras6oZ51wjVNB1Y05uG7uEw'
|
REDIS_USER = environ.get('REDIS_USER')
|
||||||
REDIS_URL = '8bciqc.stackhero-network.com'
|
REDIS_PASS = environ.get('REDIS_PASS')
|
||||||
REDIS_PORT = '9961'
|
REDIS_URL = environ.get('REDIS_URL')
|
||||||
|
REDIS_PORT = environ.get('REDIS_PORT', '6379')
|
||||||
REDIS_BASE_URI = f'redis://{REDIS_USER}:{REDIS_PASS}@{REDIS_URL}:{REDIS_PORT}'
|
REDIS_BASE_URI = f'redis://{REDIS_USER}:{REDIS_PASS}@{REDIS_URL}:{REDIS_PORT}'
|
||||||
|
|
||||||
# Celery settings
|
# Celery settings
|
||||||
@@ -236,23 +248,6 @@ class ProdConfig(Config):
|
|||||||
# Session settings
|
# Session settings
|
||||||
SESSION_REDIS = redis.from_url(f'{REDIS_BASE_URI}/2')
|
SESSION_REDIS = redis.from_url(f'{REDIS_BASE_URI}/2')
|
||||||
|
|
||||||
# OpenAI API Keys
|
|
||||||
OPENAI_API_KEY = 'sk-proj-8R0jWzwjL7PeoPyMhJTZT3BlbkFJLb6HfRB2Hr9cEVFWEhU7'
|
|
||||||
|
|
||||||
# Groq API Keys
|
|
||||||
GROQ_API_KEY = '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'
|
|
||||||
|
|
||||||
# Anthropic API Keys
|
|
||||||
ANTHROPIC_API_KEY = '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'
|
|
||||||
|
|
||||||
# Portkey API Keys
|
|
||||||
PORTKEY_API_KEY = 'T2Dt4QTpgCvWxa1OftYCJtj7NcDZ'
|
|
||||||
|
|
||||||
# Unstructured settings
|
|
||||||
UNSTRUCTURED_API_KEY = 'pDgCrXumYhM3CNvjvwV8msMldXC3uw'
|
|
||||||
UNSTRUCTURED_BASE_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io'
|
|
||||||
UNSTRUCTURED_FULL_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io/general/v0/general'
|
|
||||||
|
|
||||||
# SocketIO settings
|
# SocketIO settings
|
||||||
SOCKETIO_MESSAGE_QUEUE = f'{REDIS_BASE_URI}/1'
|
SOCKETIO_MESSAGE_QUEUE = f'{REDIS_BASE_URI}/1'
|
||||||
SOCKETIO_CORS_ALLOWED_ORIGINS = '*'
|
SOCKETIO_CORS_ALLOWED_ORIGINS = '*'
|
||||||
@@ -269,15 +264,14 @@ class ProdConfig(Config):
|
|||||||
GC_KEY_RING = 'eveai-chat'
|
GC_KEY_RING = 'eveai-chat'
|
||||||
GC_CRYPTO_KEY = 'envelope-encryption-key'
|
GC_CRYPTO_KEY = 'envelope-encryption-key'
|
||||||
|
|
||||||
# JWT settings
|
|
||||||
JWT_SECRET_KEY = 'bsdMkmQ8ObfMD52yAFg4trrvjgjMhuIqg2fjDpD/JqvgY0ccCcmlsEnVFmR79WPiLKEA3i8a5zmejwLZKl4v9Q=='
|
|
||||||
|
|
||||||
# PATH settings
|
# PATH settings
|
||||||
ffmpeg_path = '/usr/bin/ffmpeg'
|
ffmpeg_path = '/usr/bin/ffmpeg'
|
||||||
|
|
||||||
|
|
||||||
config = {
|
def get_config(config_name='dev'):
|
||||||
'dev': DevConfig(),
|
configs = {
|
||||||
'prod': ProdConfig(),
|
'dev': DevConfig,
|
||||||
'default': DevConfig(),
|
'prod': ProdConfig,
|
||||||
}
|
'default': DevConfig,
|
||||||
|
}
|
||||||
|
return configs.get(config_name)
|
||||||
|
|||||||
81
docker/build_tag_and_push.sh
Executable file
81
docker/build_tag_and_push.sh
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Source the environment setup script
|
||||||
|
if [ -f "./docker_env_switch.sh" ]; then
|
||||||
|
source ./docker_env_switch.sh dev
|
||||||
|
else
|
||||||
|
echo "Error: set_environment.sh not found in the current directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Docker Hub username
|
||||||
|
USERNAME="josakola"
|
||||||
|
|
||||||
|
# List of all your services
|
||||||
|
ALL_SERVICES=("eveai_app" "eveai_workers" "eveai_chat" "eveai_chat_workers" "nginx")
|
||||||
|
|
||||||
|
# Function to build, tag and push an image
|
||||||
|
build_tag_and_push() {
|
||||||
|
local service=$1
|
||||||
|
echo "Building, tagging, and pushing ${service}..."
|
||||||
|
|
||||||
|
# Extract dockerfile and context paths from Docker Compose configuration
|
||||||
|
local dockerfile_path
|
||||||
|
local context_path
|
||||||
|
|
||||||
|
dockerfile_path=$(docker compose -f "$COMPOSE_FILE" config | grep "${service}" -A 10 | grep "dockerfile" | awk '{print $2}')
|
||||||
|
context_path=$(docker compose -f "$COMPOSE_FILE" config | grep "${service}" -A 10 | grep "context" | awk '{print $2}')
|
||||||
|
|
||||||
|
# Verify the paths
|
||||||
|
echo "Dockerfile path: ${dockerfile_path}"
|
||||||
|
echo "Context path: ${context_path}"
|
||||||
|
|
||||||
|
# Use docker buildx to build the image
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
-t "${USERNAME}/${service}:latest" \
|
||||||
|
--push \
|
||||||
|
--file "${dockerfile_path}" \
|
||||||
|
"${context_path}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if a service is in the ALL_SERVICES array
|
||||||
|
service_exists() {
|
||||||
|
local service=$1
|
||||||
|
for s in "${ALL_SERVICES[@]}"; do
|
||||||
|
if [[ "$s" == "$service" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure we're using buildx
|
||||||
|
docker buildx create --use
|
||||||
|
|
||||||
|
# If COMPOSE_FILE is not set, use a default value
|
||||||
|
if [ -z "$COMPOSE_FILE" ]; then
|
||||||
|
COMPOSE_FILE="compose_dev.yaml"
|
||||||
|
echo "COMPOSE_FILE not set, using default: $COMPOSE_FILE"
|
||||||
|
else
|
||||||
|
echo "Using COMPOSE_FILE: $COMPOSE_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If no arguments are provided, process all services
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "No specific services provided. Processing all services..."
|
||||||
|
for service in "${ALL_SERVICES[@]}"; do
|
||||||
|
build_tag_and_push "$service"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# Process only the specified services
|
||||||
|
for service in "$@"; do
|
||||||
|
if service_exists "$service"; then
|
||||||
|
build_tag_and_push "$service"
|
||||||
|
else
|
||||||
|
echo "Warning: ${service} is not a recognized service name. Skipping."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Done!"
|
||||||
@@ -11,17 +11,33 @@
|
|||||||
x-common-variables: &common-variables
|
x-common-variables: &common-variables
|
||||||
DB_HOST: db
|
DB_HOST: db
|
||||||
DB_USER: luke
|
DB_USER: luke
|
||||||
DB_PASS: Skywalker!
|
DB_PASS: 'Skywalker!'
|
||||||
DB_NAME: eveai
|
DB_NAME: eveai
|
||||||
|
DB_PORT: '5432'
|
||||||
FLASK_ENV: development
|
FLASK_ENV: development
|
||||||
FLASK_DEBUG: 1
|
FLASK_DEBUG: true
|
||||||
|
SECRET_KEY: '97867c1491bea5ee6a8e8436eb11bf2ba6a69ff53ab1b17ecba450d0f2e572e1'
|
||||||
|
SECURITY_PASSWORD_SALT: '228614859439123264035565568761433607235'
|
||||||
|
MAIL_USERNAME: eveai_super@flow-it.net
|
||||||
|
MAIL_PASSWORD: '$6xsWGbNtx$CFMQZqc*'
|
||||||
|
OPENAI_API_KEY: 'sk-proj-8R0jWzwjL7PeoPyMhJTZT3BlbkFJLb6HfRB2Hr9cEVFWEhU7'
|
||||||
|
GROQ_API_KEY: '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'
|
||||||
|
ANTHROPIC_API_KEY: 'sk-ant-api03-c2TmkzbReeGhXBO5JxNH6BJNylRDonc9GmZd0eRbrvyekec2'
|
||||||
|
PORTKEY_API_KEY: 'T2Dt4QTpgCvWxa1OftYCJtj7NcDZ'
|
||||||
|
JWT_SECRET_KEY: 'bsdMkmQ8ObfMD52yAFg4trrvjgjMhuIqg2fjDpD/JqvgY0ccCcmlsEnVFmR79WPiLKEA3i8a5zmejwLZKl4v9Q=='
|
||||||
|
API_ENCRYPTION_KEY: 'xfF5369IsredSrlrYZqkM9ZNrfUASYYS6TCcAR9UKj4='
|
||||||
MINIO_ENDPOINT: minio:9000
|
MINIO_ENDPOINT: minio:9000
|
||||||
MINIO_ACCESS_KEY: minioadmin
|
MINIO_ACCESS_KEY: minioadmin
|
||||||
MINIO_SECRET_KEY: minioadmin
|
MINIO_SECRET_KEY: minioadmin
|
||||||
|
|
||||||
services:
|
services:
|
||||||
nginx:
|
nginx:
|
||||||
image: nginx:latest
|
build:
|
||||||
|
context: ../nginx
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
@@ -39,6 +55,9 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: ./docker/eveai_app/Dockerfile
|
dockerfile: ./docker/eveai_app/Dockerfile
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
ports:
|
ports:
|
||||||
- 5001:5001
|
- 5001:5001
|
||||||
environment:
|
environment:
|
||||||
@@ -69,6 +88,9 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: ./docker/eveai_workers/Dockerfile
|
dockerfile: ./docker/eveai_workers/Dockerfile
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
# ports:
|
# ports:
|
||||||
# - 5001:5001
|
# - 5001:5001
|
||||||
environment:
|
environment:
|
||||||
@@ -98,6 +120,9 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: ./docker/eveai_chat/Dockerfile
|
dockerfile: ./docker/eveai_chat/Dockerfile
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
ports:
|
ports:
|
||||||
- 5002:5002
|
- 5002:5002
|
||||||
environment:
|
environment:
|
||||||
@@ -125,6 +150,9 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: ./docker/eveai_chat_workers/Dockerfile
|
dockerfile: ./docker/eveai_chat_workers/Dockerfile
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
# ports:
|
# ports:
|
||||||
# - 5001:5001
|
# - 5001:5001
|
||||||
environment:
|
environment:
|
||||||
123
docker/compose_stackhero.yaml
Normal file
123
docker/compose_stackhero.yaml
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# Comments are provided throughout this file to help you get started.
|
||||||
|
# If you need more help, visit the Docker Compose reference guide at
|
||||||
|
# https://docs.docker.com/go/compose-spec-reference/
|
||||||
|
|
||||||
|
# Here the instructions define your application as a service called "server".
|
||||||
|
# This service is built from the Dockerfile in the current directory.
|
||||||
|
# You can add other services your application may depend on here, such as a
|
||||||
|
# database or a cache. For examples, see the Awesome Compose repository:
|
||||||
|
# https://github.com/docker/awesome-compose
|
||||||
|
|
||||||
|
x-common-variables: &common-variables
|
||||||
|
DB_HOST: bswnz4.stackhero-network.com
|
||||||
|
DB_USER: luke_skywalker
|
||||||
|
DB_PASS: 2MK&1rHmWEydE2rFuJLq*ls%tdkPAk2
|
||||||
|
DB_NAME: eveai
|
||||||
|
DB_PORT: '5945'
|
||||||
|
FLASK_ENV: production
|
||||||
|
FLASK_DEBUG: false
|
||||||
|
SECRET_KEY: '38wg8e1lvhlvcu0apr95n8o07axf244lzaa7b7djh7itrf8jnyyh1lkuco529w'
|
||||||
|
SECURITY_PASSWORD_SALT: '166448071751628781809462050022558634074'
|
||||||
|
MAIL_USERNAME: 'evie_admin@askeveai.com'
|
||||||
|
MAIL_PASSWORD: 's5D%R#y^v!s&6Z^i0k&'
|
||||||
|
REDIS_USER: admin
|
||||||
|
REDIS_PASS: 'b32vtDtLriSY1fL2zGrZg8IZKI0g9ucsLtVNanRFAras6oZ51wjVNB1Y05uG7uEw'
|
||||||
|
REDIS_URL: 8bciqc.stackhero-network.com
|
||||||
|
REDIS_PORT: '9961'
|
||||||
|
OPENAI_API_KEY: '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'
|
||||||
|
GROQ_API_KEY: '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'
|
||||||
|
ANTHROPIC_API_KEY: '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'
|
||||||
|
PORTKEY_API_KEY: '3C+zAGR8pCalevBXFVc0l8R2MPYc'
|
||||||
|
JWT_SECRET_KEY: '0d99e810e686ea567ef305d8e9b06195c4db482952e19276590a726cde60a408'
|
||||||
|
API_ENCRYPTION_KEY: 'Ly5XYWwEKiasfAwEqdEMdwR-k0vhrq6QPYd4whEROB0='
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
image: nginx:latest
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
- 8080:8080
|
||||||
|
volumes:
|
||||||
|
- ../nginx:/etc/nginx
|
||||||
|
- ../nginx/sites-enabled:/etc/nginx/sites-enabled
|
||||||
|
- ../nginx/static:/etc/nginx/static
|
||||||
|
- ../nginx/public:/etc/nginx/public
|
||||||
|
- ./logs/nginx:/var/log/nginx
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.api.rule=Host(`evie.askeveai.com`)"
|
||||||
|
- "traefik.http.services.nginx.loadbalancer.server.port=80"
|
||||||
|
depends_on:
|
||||||
|
- eveai_app
|
||||||
|
- eveai_chat
|
||||||
|
|
||||||
|
eveai_app:
|
||||||
|
image: josakola/eveai_app:latest
|
||||||
|
ports:
|
||||||
|
- 5001:5001
|
||||||
|
environment:
|
||||||
|
<<: *common-variables
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/logs
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:5001/health"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
command: ["sh", "-c", "scripts/start_eveai_app.sh"]
|
||||||
|
|
||||||
|
eveai_workers:
|
||||||
|
image: josakola/eveai_workers:latest
|
||||||
|
# ports:
|
||||||
|
# - 5001:5001
|
||||||
|
environment:
|
||||||
|
<<: *common-variables
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/logs
|
||||||
|
# healthcheck:
|
||||||
|
# test: [ "CMD", "curl", "-f", "http://localhost:5001/health" ]
|
||||||
|
# interval: 10s
|
||||||
|
# timeout: 5s
|
||||||
|
# retries: 5
|
||||||
|
command: [ "sh", "-c", "scripts/start_eveai_workers.sh" ]
|
||||||
|
|
||||||
|
eveai_chat:
|
||||||
|
image: josakola/eveai_chat:latest
|
||||||
|
ports:
|
||||||
|
- 5002:5002
|
||||||
|
environment:
|
||||||
|
<<: *common-variables
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/logs
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "-f", "http://localhost:5002/health" ] # Adjust based on your health endpoint
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
command: ["sh", "-c", "scripts/start_eveai_chat.sh"]
|
||||||
|
|
||||||
|
eveai_chat_workers:
|
||||||
|
image: josakola/eveai_chat_workers:latest
|
||||||
|
# ports:
|
||||||
|
# - 5001:5001
|
||||||
|
environment:
|
||||||
|
<<: *common-variables
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/logs
|
||||||
|
# healthcheck:
|
||||||
|
# test: [ "CMD", "curl", "-f", "http://localhost:5001/health" ]
|
||||||
|
# interval: 10s
|
||||||
|
# timeout: 5s
|
||||||
|
# retries: 5
|
||||||
|
command: [ "sh", "-c", "scripts/start_eveai_chat_workers.sh" ]
|
||||||
|
|
||||||
|
|
||||||
|
#volumes:
|
||||||
|
# minio_data:
|
||||||
|
# db-data:
|
||||||
|
# redis-data:
|
||||||
|
# tenant-files:
|
||||||
|
#secrets:
|
||||||
|
# db-password:
|
||||||
|
# file: ./db/password.txt
|
||||||
|
|
||||||
57
docker/docker_env_switch.sh
Executable file
57
docker/docker_env_switch.sh
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Function to display usage information
|
||||||
|
usage() {
|
||||||
|
echo "Usage: source $0 [dev|prod]"
|
||||||
|
echo " dev : Switch to development environment"
|
||||||
|
echo " prod : Switch to production environment"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the script is sourced
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
|
echo "Error: This script must be sourced, not executed directly."
|
||||||
|
echo "Please run: source $0 [dev|prod]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if an argument is provided
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set variables based on the environment
|
||||||
|
case $1 in
|
||||||
|
dev)
|
||||||
|
DOCKER_CONTEXT="default"
|
||||||
|
COMPOSE_FILE="compose_dev.yaml"
|
||||||
|
;;
|
||||||
|
prod)
|
||||||
|
DOCKER_CONTEXT="mxz536.stackhero-network.com"
|
||||||
|
COMPOSE_FILE="compose_stackhero.yaml"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid environment. Use 'dev' or 'prod'."
|
||||||
|
usage
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Switch Docker context
|
||||||
|
echo "Switching to Docker context: $DOCKER_CONTEXT"
|
||||||
|
docker context use $DOCKER_CONTEXT
|
||||||
|
|
||||||
|
# Set the COMPOSE_FILE environment variable
|
||||||
|
export COMPOSE_FILE=$COMPOSE_FILE
|
||||||
|
echo "Set COMPOSE_FILE to $COMPOSE_FILE"
|
||||||
|
|
||||||
|
# Define aliases for common Docker commands
|
||||||
|
alias docker-compose="docker compose -f $COMPOSE_FILE"
|
||||||
|
alias dc="docker compose -f $COMPOSE_FILE"
|
||||||
|
alias dcup="docker compose -f $COMPOSE_FILE up -d"
|
||||||
|
alias dcdown="docker compose -f $COMPOSE_FILE down"
|
||||||
|
alias dcps="docker compose -f $COMPOSE_FILE ps"
|
||||||
|
alias dclogs="docker compose -f $COMPOSE_FILE logs"
|
||||||
|
|
||||||
|
echo "Docker environment switched to $1"
|
||||||
|
echo "You can now use 'docker-compose', 'dc', 'dcup', 'dcdown', 'dcps', and 'dclogs' commands"
|
||||||
14
docker/stackhero_link.sh
Executable file
14
docker/stackhero_link.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
# HOST is your Stackhero for Docker instance domain name (mxz536.stackhero-network.com).
|
||||||
|
# SERVICE_ID is your Stackhero service ID.
|
||||||
|
# CERTIFICATES_PASSWORD is the password defined in your Stackhero for Docker configuration.
|
||||||
|
(export HOST="mxz536.stackhero-network.com"
|
||||||
|
export SERVICE_ID="svc-rlaeva"
|
||||||
|
export CERTIFICATES_PASSWORD="OonfQaQerGLLsWPKmnudyghFilIcPJRW"
|
||||||
|
|
||||||
|
cd /tmp/ \
|
||||||
|
&& curl -o certificates.tar https://docker:$CERTIFICATES_PASSWORD@$HOST/stackhero/docker/certificates.tar \
|
||||||
|
&& tar -xf certificates.tar \
|
||||||
|
&& (docker context rm -f $HOST 2> /dev/null || true) \
|
||||||
|
&& docker context create $HOST \
|
||||||
|
--description "$SERVICE_ID ($HOST)" \
|
||||||
|
--docker "host=tcp://$HOST:2376,ca=ca.pem,cert=cert.pem,key=key.pem")
|
||||||
@@ -6,8 +6,8 @@ from flask_security.signals import user_authenticated
|
|||||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
import logging.config
|
import logging.config
|
||||||
|
|
||||||
from common.extensions import (db, migrate, bootstrap, security, mail, login_manager, cors, kms_client, csrf, session,
|
from common.extensions import (db, migrate, bootstrap, security, mail, login_manager, cors, csrf, session,
|
||||||
minio_client)
|
minio_client, simple_encryption)
|
||||||
from common.models.user import User, Role, Tenant, TenantDomain
|
from common.models.user import User, Role, Tenant, TenantDomain
|
||||||
import common.models.interaction
|
import common.models.interaction
|
||||||
from config.logging_config import LOGGING
|
from config.logging_config import LOGGING
|
||||||
@@ -15,6 +15,7 @@ from common.utils.security import set_tenant_session_data
|
|||||||
from .errors import register_error_handlers
|
from .errors import register_error_handlers
|
||||||
from common.utils.celery_utils import make_celery, init_celery
|
from common.utils.celery_utils import make_celery, init_celery
|
||||||
from common.utils.template_filters import register_filters
|
from common.utils.template_filters import register_filters
|
||||||
|
from config.config import get_config
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_file=None):
|
def create_app(config_file=None):
|
||||||
@@ -23,10 +24,16 @@ def create_app(config_file=None):
|
|||||||
# Ensure all necessary headers are handled
|
# Ensure all necessary headers are handled
|
||||||
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)
|
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)
|
||||||
|
|
||||||
if config_file is None:
|
environment = os.getenv('FLASK_ENV', 'development')
|
||||||
app.config.from_object('config.config.DevConfig')
|
print(environment)
|
||||||
else:
|
|
||||||
app.config.from_object(config_file)
|
match environment:
|
||||||
|
case 'development':
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
case 'production':
|
||||||
|
app.config.from_object(get_config('prod'))
|
||||||
|
case _:
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
|
||||||
app.config['SESSION_KEY_PREFIX'] = 'eveai_app_'
|
app.config['SESSION_KEY_PREFIX'] = 'eveai_app_'
|
||||||
|
|
||||||
@@ -39,14 +46,13 @@ def create_app(config_file=None):
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
logger.info("eveai_app starting up")
|
logger.info("eveai_app starting up")
|
||||||
|
logger.debug("start config")
|
||||||
|
logger.debug(app.config)
|
||||||
|
|
||||||
# Register extensions
|
# Register extensions
|
||||||
|
|
||||||
register_extensions(app)
|
register_extensions(app)
|
||||||
|
|
||||||
# Check GCloud availability
|
|
||||||
kms_client.check_kms_access_and_latency()
|
|
||||||
|
|
||||||
app.celery = make_celery(app.name, app.config)
|
app.celery = make_celery(app.name, app.config)
|
||||||
init_celery(app.celery, app)
|
init_celery(app.celery, app)
|
||||||
|
|
||||||
@@ -101,7 +107,8 @@ def register_extensions(app):
|
|||||||
csrf.init_app(app)
|
csrf.init_app(app)
|
||||||
login_manager.init_app(app)
|
login_manager.init_app(app)
|
||||||
cors.init_app(app)
|
cors.init_app(app)
|
||||||
kms_client.init_app(app)
|
# kms_client.init_app(app)
|
||||||
|
simple_encryption.init_app(app)
|
||||||
session.init_app(app)
|
session.init_app(app)
|
||||||
minio_client.init_app(app)
|
minio_client.init_app(app)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<header class="header-2">
|
<header class="header-2">
|
||||||
<div class="page-header min-vh-25" style="background-image: url({{url_for('static', filename='/assets/img/EveAI_bg2.jpg')}})" loading="lazy">
|
<div class="page-header min-vh-25" style="background-image: url({{url_for('static', filename='/assets/img/EveAI_bg.jpg')}})" loading="lazy">
|
||||||
<span class="mask bg-gradient-primary opacity-4"></span>
|
<span class="mask bg-gradient-primary opacity-4"></span>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from sqlalchemy.exc import SQLAlchemyError
|
|||||||
import ast
|
import ast
|
||||||
|
|
||||||
from common.models.user import User, Tenant, Role, TenantDomain
|
from common.models.user import User, Tenant, Role, TenantDomain
|
||||||
from common.extensions import db, kms_client, security, minio_client
|
from common.extensions import db, security, minio_client, simple_encryption
|
||||||
from common.utils.security_utils import send_confirmation_email, send_reset_email
|
from common.utils.security_utils import send_confirmation_email, send_reset_email
|
||||||
from .user_forms import TenantForm, CreateUserForm, EditUserForm, TenantDomainForm
|
from .user_forms import TenantForm, CreateUserForm, EditUserForm, TenantDomainForm
|
||||||
from common.utils.database import Database
|
from common.utils.database import Database
|
||||||
@@ -427,7 +427,7 @@ def generate_chat_api_key():
|
|||||||
tenant = Tenant.query.get_or_404(session['tenant']['id'])
|
tenant = Tenant.query.get_or_404(session['tenant']['id'])
|
||||||
|
|
||||||
new_api_key = generate_api_key(prefix="EveAI-CHAT")
|
new_api_key = generate_api_key(prefix="EveAI-CHAT")
|
||||||
tenant.encrypted_chat_api_key = kms_client.encrypt_api_key(new_api_key)
|
tenant.encrypted_chat_api_key = simple_encryption.encrypt_api_key(new_api_key)
|
||||||
update_logging_information(tenant, dt.now(tz.utc))
|
update_logging_information(tenant, dt.now(tz.utc))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,22 +1,28 @@
|
|||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
from flask import Flask, jsonify
|
from flask import Flask, jsonify
|
||||||
from redis import Redis
|
import os
|
||||||
|
|
||||||
from common.extensions import db, socketio, jwt, kms_client, cors, session
|
from common.extensions import db, socketio, jwt, cors, session, simple_encryption
|
||||||
from config.logging_config import LOGGING
|
from config.logging_config import LOGGING
|
||||||
from eveai_chat.socket_handlers import chat_handler
|
from eveai_chat.socket_handlers import chat_handler
|
||||||
from common.utils.cors_utils import create_cors_after_request
|
from common.utils.cors_utils import create_cors_after_request
|
||||||
from common.utils.celery_utils import make_celery, init_celery
|
from common.utils.celery_utils import make_celery, init_celery
|
||||||
|
from config.config import get_config
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_file=None):
|
def create_app(config_file=None):
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
if config_file is None:
|
environment = os.getenv('FLASK_ENV', 'development')
|
||||||
app.config.from_object('config.config.DevConfig')
|
|
||||||
else:
|
match environment:
|
||||||
app.config.from_object(config_file)
|
case 'development':
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
case 'production':
|
||||||
|
app.config.from_object(get_config('prod'))
|
||||||
|
case _:
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
|
||||||
app.config['SESSION_KEY_PREFIX'] = 'eveai_chat_'
|
app.config['SESSION_KEY_PREFIX'] = 'eveai_chat_'
|
||||||
|
|
||||||
@@ -55,7 +61,8 @@ def register_extensions(app):
|
|||||||
ping_interval=app.config.get('SOCKETIO_PING_INTERVAL'),
|
ping_interval=app.config.get('SOCKETIO_PING_INTERVAL'),
|
||||||
)
|
)
|
||||||
jwt.init_app(app)
|
jwt.init_app(app)
|
||||||
kms_client.init_app(app)
|
# kms_client.init_app(app)
|
||||||
|
simple_encryption.init_app(app)
|
||||||
|
|
||||||
# Cors setup
|
# Cors setup
|
||||||
cors.init_app(app, resources={r"/chat/*": {"origins": "*"}})
|
cors.init_app(app, resources={r"/chat/*": {"origins": "*"}})
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from flask import current_app, request, session
|
|||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from common.extensions import socketio, kms_client, db
|
from common.extensions import socketio, db, simple_encryption
|
||||||
from common.models.user import Tenant
|
from common.models.user import Tenant
|
||||||
from common.models.interaction import Interaction
|
from common.models.interaction import Interaction
|
||||||
from common.utils.celery_utils import current_celery
|
from common.utils.celery_utils import current_celery
|
||||||
@@ -156,7 +156,7 @@ def handle_feedback(data):
|
|||||||
|
|
||||||
def validate_api_key(tenant_id, api_key):
|
def validate_api_key(tenant_id, api_key):
|
||||||
tenant = Tenant.query.get_or_404(tenant_id)
|
tenant = Tenant.query.get_or_404(tenant_id)
|
||||||
decrypted_api_key = kms_client.decrypt_api_key(tenant.encrypted_chat_api_key)
|
decrypted_api_key = simple_encryption.decrypt_api_key(tenant.encrypted_chat_api_key)
|
||||||
|
|
||||||
return decrypted_api_key == api_key
|
return decrypted_api_key == api_key
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
import os
|
||||||
|
|
||||||
from common.utils.celery_utils import make_celery, init_celery
|
from common.utils.celery_utils import make_celery, init_celery
|
||||||
from common.extensions import db
|
from common.extensions import db
|
||||||
from config.logging_config import LOGGING
|
from config.logging_config import LOGGING
|
||||||
|
from config.config import get_config
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_file=None):
|
def create_app(config_file=None):
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
if config_file is None:
|
environment = os.getenv('FLASK_ENV', 'development')
|
||||||
app.config.from_object('config.config.DevConfig')
|
|
||||||
else:
|
match environment:
|
||||||
app.config.from_object(config_file)
|
case 'development':
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
case 'production':
|
||||||
|
app.config.from_object(get_config('prod'))
|
||||||
|
case _:
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
|
||||||
logging.config.dictConfig(LOGGING)
|
logging.config.dictConfig(LOGGING)
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
import os
|
||||||
|
|
||||||
from common.utils.celery_utils import make_celery, init_celery
|
from common.utils.celery_utils import make_celery, init_celery
|
||||||
from common.extensions import db, minio_client
|
from common.extensions import db, minio_client
|
||||||
from config.logging_config import LOGGING
|
from config.logging_config import LOGGING
|
||||||
|
from config.config import get_config
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_file=None):
|
def create_app(config_file=None):
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
if config_file is None:
|
environment = os.getenv('FLASK_ENV', 'development')
|
||||||
app.config.from_object('config.config.DevConfig')
|
|
||||||
else:
|
match environment:
|
||||||
app.config.from_object(config_file)
|
case 'development':
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
case 'production':
|
||||||
|
app.config.from_object(get_config('prod'))
|
||||||
|
case _:
|
||||||
|
app.config.from_object(get_config('dev'))
|
||||||
|
|
||||||
logging.config.dictConfig(LOGGING)
|
logging.config.dictConfig(LOGGING)
|
||||||
app.embed_tuning_logger = logging.getLogger('embed_tuning')
|
app.embed_tuning_logger = logging.getLogger('embed_tuning')
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const eveAI = new EveAI(
|
const eveAI = new EveAI(
|
||||||
'6',
|
'6',
|
||||||
'EveAI-CHAT-3622-2083-4559-6024-8786',
|
'EveAI-CHAT-6530-7449-1171-8988-8156',
|
||||||
'http://macstudio.ask-eve-ai-local.com',
|
'http://macstudio.ask-eve-ai-local.com',
|
||||||
'en'
|
'en'
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*Overriding Colors*/
|
||||||
|
:root {
|
||||||
|
--bs-primary: #76599a;
|
||||||
|
--bs-secondary: #b14f9d;
|
||||||
|
--bs-success: #f8e1a9;
|
||||||
|
--bs-info: #423372;
|
||||||
|
--bs-warning: #eb7f31;
|
||||||
|
--bs-danger: #9c2d66;
|
||||||
|
}
|
||||||
|
|
||||||
.form-control {
|
.form-control {
|
||||||
border: 1px solid #d2d6da;
|
border: 1px solid #d2d6da;
|
||||||
padding: 0.625rem 0.75rem;
|
padding: 0.625rem 0.75rem;
|
||||||
|
|||||||
BIN
nginx/static/assets/img/EveAI_bg.jpg
Normal file
BIN
nginx/static/assets/img/EveAI_bg.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
@@ -80,3 +80,4 @@ portkey_ai~=1.7.0
|
|||||||
minio~=7.2.7
|
minio~=7.2.7
|
||||||
Werkzeug~=3.0.3
|
Werkzeug~=3.0.3
|
||||||
itsdangerous~=2.2.0
|
itsdangerous~=2.2.0
|
||||||
|
cryptography~=43.0.0
|
||||||
6
scripts/generate_api_key_secret.py
Normal file
6
scripts/generate_api_key_secret.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from common.utils.simple_encryption import SimpleEncryption
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
key = SimpleEncryption.generate_key()
|
||||||
|
print(f"Generated encryption key: {key}")
|
||||||
|
print("Set this as your ENCRYPTION_KEY environment variable or in your config.py file.")
|
||||||
Reference in New Issue
Block a user