diff --git a/README.md b/README.md index 30aa36c0..fb542892 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,12 @@ All open source projects begins with people like you. Open source is the belief Work is organized in the [project board](https://github.com/orgs/LAION-AI/projects/3). -### Python Backend - -For a local developer setup, look into the `backend` folder to pull up a local database and backend. +- To get started with development, if you want to work on the backend, have a look at `backend/scripts/backend-development/README.md`. +- If you want to work on the frontend, have a look at `backend/scripts/frontend-development/README.md`. There is also a minimal implementation of a frontend in the `text-frontend` folder. -We are using Python 3.10 +We are using Python 3.10 for the backend. Check out the [High-Level Protocol Architecture](https://www.notion.so/High-Level-Protocol-Architecture-6f1fd3551da74213b560ead369f132dc) diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 00000000..fe26db34 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,11 @@ +FROM tiangolo/uvicorn-gunicorn-fastapi:python3.10 + +COPY ./requirements.txt /app/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt + +ENV PORT 8080 + +COPY ./alembic.ini /alembic.ini +COPY ./alembic /alembic +COPY ./app /app diff --git a/backend/alembic/env.py b/backend/alembic/env.py index ae870d84..634b79a5 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -3,7 +3,7 @@ from logging.config import fileConfig import sqlmodel from alembic import context -from app import models # noqa: F401 +from ocgpt import models # noqa: F401 from sqlalchemy import engine_from_config, pool # this is the Alembic Config object, which provides @@ -68,6 +68,8 @@ def run_migrations_online() -> None: context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): + context.get_context()._ensure_version_table() + connection.execute("LOCK TABLE alembic_version IN ACCESS EXCLUSIVE MODE") context.run_migrations() diff --git a/backend/app/main.py b/backend/app/main.py index 27edbc88..adb38d93 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -4,9 +4,9 @@ from pathlib import Path import alembic.command import alembic.config import fastapi -from app.api.v1.api import api_router -from app.config import settings from loguru import logger +from ocgpt.api.v1.api import api_router +from ocgpt.config import settings from starlette.middleware.cors import CORSMiddleware app = fastapi.FastAPI(title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json") diff --git a/backend/app/__init__.py b/backend/app/ocgpt/__init__.py similarity index 100% rename from backend/app/__init__.py rename to backend/app/ocgpt/__init__.py diff --git a/backend/app/api/__init__.py b/backend/app/ocgpt/api/__init__.py similarity index 100% rename from backend/app/api/__init__.py rename to backend/app/ocgpt/api/__init__.py diff --git a/backend/app/api/deps.py b/backend/app/ocgpt/api/deps.py similarity index 94% rename from backend/app/api/deps.py rename to backend/app/ocgpt/api/deps.py index 0790cd4d..88c054ae 100644 --- a/backend/app/api/deps.py +++ b/backend/app/ocgpt/api/deps.py @@ -3,12 +3,12 @@ from secrets import token_hex from typing import Generator from uuid import UUID -from app.config import settings -from app.database import engine -from app.models import ApiClient from fastapi import HTTPException, Security from fastapi.security.api_key import APIKey, APIKeyHeader, APIKeyQuery from loguru import logger +from ocgpt.config import settings +from ocgpt.database import engine +from ocgpt.models import ApiClient from sqlmodel import Session from starlette.status import HTTP_403_FORBIDDEN diff --git a/backend/app/api/v1/__init__.py b/backend/app/ocgpt/api/v1/__init__.py similarity index 100% rename from backend/app/api/v1/__init__.py rename to backend/app/ocgpt/api/v1/__init__.py diff --git a/backend/app/api/v1/api.py b/backend/app/ocgpt/api/v1/api.py similarity index 83% rename from backend/app/api/v1/api.py rename to backend/app/ocgpt/api/v1/api.py index afcb9677..1e304656 100644 --- a/backend/app/api/v1/api.py +++ b/backend/app/ocgpt/api/v1/api.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from app.api.v1 import tasks from fastapi import APIRouter +from ocgpt.api.v1 import tasks api_router = APIRouter() api_router.include_router(tasks.router, prefix="/tasks", tags=["tasks"]) diff --git a/backend/app/api/v1/tasks.py b/backend/app/ocgpt/api/v1/tasks.py similarity index 98% rename from backend/app/api/v1/tasks.py rename to backend/app/ocgpt/api/v1/tasks.py index 086f3a4a..ef12276a 100644 --- a/backend/app/api/v1/tasks.py +++ b/backend/app/ocgpt/api/v1/tasks.py @@ -3,13 +3,13 @@ import random from typing import Any from uuid import UUID -from app.api import deps -from app.models.db_payload import TaskPayload -from app.prompt_repository import PromptRepository -from app.schemas import protocol as protocol_schema from fastapi import APIRouter, Depends, HTTPException from fastapi.security.api_key import APIKey from loguru import logger +from ocgpt.api import deps +from ocgpt.models.db_payload import TaskPayload +from ocgpt.prompt_repository import PromptRepository +from ocgpt.schemas import protocol as protocol_schema from sqlmodel import Session from starlette.status import HTTP_400_BAD_REQUEST diff --git a/backend/app/config.py b/backend/app/ocgpt/config.py similarity index 89% rename from backend/app/config.py rename to backend/app/ocgpt/config.py index 0780caf9..71bade6c 100644 --- a/backend/app/config.py +++ b/backend/app/ocgpt/config.py @@ -8,7 +8,8 @@ class Settings(BaseSettings): PROJECT_NAME: str = "open-chatGPT backend" API_V1_STR: str = "/api/v1" - POSTGRES_SERVER: str = "localhost:5432" + POSTGRES_HOST: str = "localhost" + POSTGRES_PORT: str = "5432" POSTGRES_USER: str = "postgres" POSTGRES_PASSWORD: str = "postgres" POSTGRES_DB: str = "postgres" @@ -24,7 +25,8 @@ class Settings(BaseSettings): scheme="postgresql", user=values.get("POSTGRES_USER"), password=values.get("POSTGRES_PASSWORD"), - host=values.get("POSTGRES_SERVER"), + host=values.get("POSTGRES_HOST"), + port=values.get("POSTGRES_PORT"), path=f"/{values.get('POSTGRES_DB') or ''}", ) diff --git a/backend/app/crud/__init__.py b/backend/app/ocgpt/crud/__init__.py similarity index 100% rename from backend/app/crud/__init__.py rename to backend/app/ocgpt/crud/__init__.py diff --git a/backend/app/crud/base.py b/backend/app/ocgpt/crud/base.py similarity index 100% rename from backend/app/crud/base.py rename to backend/app/ocgpt/crud/base.py diff --git a/backend/app/database.py b/backend/app/ocgpt/database.py similarity index 84% rename from backend/app/database.py rename to backend/app/ocgpt/database.py index 89b636cd..96ada5d6 100644 --- a/backend/app/database.py +++ b/backend/app/ocgpt/database.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from app.config import settings +from ocgpt.config import settings from sqlmodel import create_engine if settings.DATABASE_URI is None: diff --git a/backend/app/models/__init__.py b/backend/app/ocgpt/models/__init__.py similarity index 100% rename from backend/app/models/__init__.py rename to backend/app/ocgpt/models/__init__.py diff --git a/backend/app/models/api_client.py b/backend/app/ocgpt/models/api_client.py similarity index 100% rename from backend/app/models/api_client.py rename to backend/app/ocgpt/models/api_client.py diff --git a/backend/app/models/db_payload.py b/backend/app/ocgpt/models/db_payload.py similarity index 94% rename from backend/app/models/db_payload.py rename to backend/app/ocgpt/models/db_payload.py index 52eadb67..730178e3 100644 --- a/backend/app/models/db_payload.py +++ b/backend/app/ocgpt/models/db_payload.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from typing import Literal -from app.models.payload_column_type import payload_type -from app.schemas import protocol as protocol_schema +from ocgpt.models.payload_column_type import payload_type +from ocgpt.schemas import protocol as protocol_schema from pydantic import BaseModel diff --git a/backend/app/models/payload_column_type.py b/backend/app/ocgpt/models/payload_column_type.py similarity index 100% rename from backend/app/models/payload_column_type.py rename to backend/app/ocgpt/models/payload_column_type.py diff --git a/backend/app/models/person.py b/backend/app/ocgpt/models/person.py similarity index 100% rename from backend/app/models/person.py rename to backend/app/ocgpt/models/person.py diff --git a/backend/app/models/person_stats.py b/backend/app/ocgpt/models/person_stats.py similarity index 100% rename from backend/app/models/person_stats.py rename to backend/app/ocgpt/models/person_stats.py diff --git a/backend/app/models/post.py b/backend/app/ocgpt/models/post.py similarity index 100% rename from backend/app/models/post.py rename to backend/app/ocgpt/models/post.py diff --git a/backend/app/models/post_reaction.py b/backend/app/ocgpt/models/post_reaction.py similarity index 100% rename from backend/app/models/post_reaction.py rename to backend/app/ocgpt/models/post_reaction.py diff --git a/backend/app/models/work_package.py b/backend/app/ocgpt/models/work_package.py similarity index 100% rename from backend/app/models/work_package.py rename to backend/app/ocgpt/models/work_package.py diff --git a/backend/app/prompt_repository.py b/backend/app/ocgpt/prompt_repository.py similarity index 98% rename from backend/app/prompt_repository.py rename to backend/app/ocgpt/prompt_repository.py index 43706d00..7b39d0b8 100644 --- a/backend/app/prompt_repository.py +++ b/backend/app/ocgpt/prompt_repository.py @@ -3,11 +3,11 @@ from datetime import datetime from typing import Optional from uuid import UUID, uuid4 -import app.models.db_payload as db_payload -from app.models import ApiClient, Person, Post, PostReaction, WorkPackage -from app.models.payload_column_type import PayloadContainer -from app.schemas import protocol as protocol_schema +import ocgpt.models.db_payload as db_payload from loguru import logger +from ocgpt.models import ApiClient, Person, Post, PostReaction, WorkPackage +from ocgpt.models.payload_column_type import PayloadContainer +from ocgpt.schemas import protocol as protocol_schema from sqlmodel import Session diff --git a/backend/app/schemas/__init__.py b/backend/app/ocgpt/schemas/__init__.py similarity index 100% rename from backend/app/schemas/__init__.py rename to backend/app/ocgpt/schemas/__init__.py diff --git a/backend/app/schemas/protocol.py b/backend/app/ocgpt/schemas/protocol.py similarity index 100% rename from backend/app/schemas/protocol.py rename to backend/app/ocgpt/schemas/protocol.py diff --git a/backend/app/tests/__init__.py b/backend/app/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/backend.dockerfile b/backend/backend.dockerfile deleted file mode 100644 index 53cb0381..00000000 --- a/backend/backend.dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM python:3.10 - -WORKDIR /backend - -COPY ./requirements.txt /backend/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /backend/requirements.txt - -COPY ./alembic.ini /backend/alembic.ini -COPY ./alembic /backend/alembic -COPY ./app /backend/app - -ENV PYTHONPATH=/backend/app - -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] diff --git a/backend/scripts/backend-development/README.md b/backend/scripts/backend-development/README.md new file mode 100644 index 00000000..36a1b964 --- /dev/null +++ b/backend/scripts/backend-development/README.md @@ -0,0 +1,5 @@ +# Backend Development Setup + +Run `docker compose up` to start a database. The default settings are already configured to connect to the database at `localhost:5432`. + +Then, run the backend using the `run-local.sh` script. This will start the backend server at `http://localhost:8080`. diff --git a/backend/scripts/docker-compose.yaml b/backend/scripts/backend-development/docker-compose.yaml similarity index 100% rename from backend/scripts/docker-compose.yaml rename to backend/scripts/backend-development/docker-compose.yaml diff --git a/backend/scripts/run-local.sh b/backend/scripts/backend-development/run-local.sh similarity index 64% rename from backend/scripts/run-local.sh rename to backend/scripts/backend-development/run-local.sh index 871dd85e..187674f3 100755 --- a/backend/scripts/run-local.sh +++ b/backend/scripts/backend-development/run-local.sh @@ -2,10 +2,10 @@ parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) # switch to backend directory -pushd "$parent_path/../" +pushd "$parent_path/../../app" export ALLOW_ANY_API_KEY=True -uvicorn app.main:app --reload +uvicorn main:app --reload --port 8080 --host 0.0.0.0 popd diff --git a/backend/scripts/docker-build-backend.sh b/backend/scripts/docker-build-backend.sh deleted file mode 100755 index 802c5e63..00000000 --- a/backend/scripts/docker-build-backend.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) -pushd $parent_path - -docker build ../../backend -f ../backend.dockerfile -t laion-ai/ocgpt-backend - -popd diff --git a/backend/scripts/docker-run-backend.sh b/backend/scripts/docker-run-backend.sh deleted file mode 100755 index 40160864..00000000 --- a/backend/scripts/docker-run-backend.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -# This script launches a ocgpt-backend docker container stand-alone. - -docker run -it --rm -p 127.0.0.1:8000:80/tcp --env POSTGRES_SERVER=host.docker.internal:5432 --env ALLOW_ANY_API_KEY=True --add-host host.docker.internal:host-gateway laion-ai/ocgpt-backend diff --git a/backend/scripts/frontend-development/README.md b/backend/scripts/frontend-development/README.md new file mode 100644 index 00000000..e13e37c0 --- /dev/null +++ b/backend/scripts/frontend-development/README.md @@ -0,0 +1,5 @@ +# Frontend Development Setup + +Run `docker compose up --build` to start a database and the backend server. + +Then, point your frontend at `http://localhost:8080` to start developing. During development, any API key will be accepted. diff --git a/backend/scripts/frontend-development/docker-compose.yaml b/backend/scripts/frontend-development/docker-compose.yaml new file mode 100644 index 00000000..42f36fb4 --- /dev/null +++ b/backend/scripts/frontend-development/docker-compose.yaml @@ -0,0 +1,26 @@ +version: "3.7" + +services: + db: + extends: + file: ../backend-development/docker-compose.yaml + service: db + healthcheck: + test: ["CMD", "pg_isready", "-U", "postgres"] + interval: 2s + timeout: 2s + retries: 10 + adminer: + extends: + file: ../backend-development/docker-compose.yaml + service: adminer + backend: + build: ../../. + environment: + - POSTGRES_HOST=db + - ALLOW_ANY_API_KEY=True + depends_on: + db: + condition: service_healthy + ports: + - "8080:8080" diff --git a/text-frontend/__main__.py b/text-frontend/__main__.py index 16fc4812..ee34799d 100644 --- a/text-frontend/__main__.py +++ b/text-frontend/__main__.py @@ -25,7 +25,7 @@ def _render_message(message: dict) -> str: @app.command() -def main(backend_url: str = "http://127.0.0.1:8000", api_key: str = "DUMMY_KEY"): +def main(backend_url: str = "http://127.0.0.1:8080", api_key: str = "DUMMY_KEY"): """Simple REPL frontend.""" def _post(path: str, json: dict) -> dict: diff --git a/website/.env.example b/website/.env.example index f0db36e7..1d7721c8 100644 --- a/website/.env.example +++ b/website/.env.example @@ -1,4 +1,4 @@ -FASTAPI_URL=http://xamla.com:8000 +FASTAPI_URL=http://xamla.com:8080 FASTAPI_KEY=magic_key DISCORD_CLIENT_ID=your_discord_bot_client_id