diff --git a/.gitignore b/.gitignore index 51570f7..662e366 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,163 @@ -*~ -*/venv -devbox-back/devbox_emails.db -devbox-back/__pycache__ +# ---> Python +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +db/ + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + diff --git a/README.md b/README.md index d279094..2a6b0bf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,90 @@ # DevBox Landing Page Git repository for frontend and backend for the DevBox landing page and email collection service. + +## Development Setup + +### Set up development environment with Python venv + +We use pythons built in module, venv, to create an isolated python environment. + +[Python Documentation for virtual environments][0] + +#### Initialize the virtual environment + +The following command initializes the virtual environment in the `.venv/`-dirctory + +```shell +python3 -m venv .venv +``` + +Then you use one of the following commands to activate the virtual environment in your current shell session + +##### Bash + +```shell +source .venv/bin/activate +``` + +##### Fish + +```shell +source .venv/bin/activate.fish +``` + +##### Install python modules + +Now you can install the python modules for this project with the following command + +```shell +pip3 install -r requirements.txt +``` + +##### Add a new module to requirements.txt + +Run the following commands to install a new module and add it to the `requirements.txt`-file. + +In this example we install the `SQLAlchemy`-module. + +```shell +pip3 install SQLAlchemy +python3 -m pip freeze > requirements.txt +``` + +##### Upgrade pip3 modules + +###### List outdated modules + +```shell +pip3 list --outdated +``` + +###### Upgrade all outdated modules + +```shell +pip3 list -o | cut -f1 -d' ' | tr " " "\n" | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 pip3 install -U +``` + +###### Save changes to requirements.txt + +```shell +python3 -m pip freeze > requirements.txt +``` + +### Building and running with Docker or Podman + +#### Docker + +```shell +docker build -t devbox-back:latest . +docker run --rm -it -p "8000:8000" -v './db:/usr/src/app/db' devbox-back:latest +``` + +#### Podman + +```shell +podman build -t devbox-back:latest . +podman run --rm -it -p "8000:8000" -v './db:/usr/src/app/db' devbox-back:latest +``` + +[0]: https://docs.python.org/3/library/venv.html \ No newline at end of file diff --git a/devbox-back/Dockerfile b/devbox-back/Dockerfile new file mode 100644 index 0000000..6f6f893 --- /dev/null +++ b/devbox-back/Dockerfile @@ -0,0 +1,19 @@ + +FROM python:3.13.4-alpine + +RUN apk update \ + && apk upgrade \ + && mkdir -p /usr/src/app + +EXPOSE 8000 + +WORKDIR /usr/src/app + +COPY requirements.txt ./ + +RUN pip install --upgrade pip +RUN pip install --no-cache-dir -r requirements.txt + +COPY app/* . + +CMD [ "gunicorn", "--config", "gunicorn-cfg.py", "main:app" ] diff --git a/devbox-back/app/gunicorn-cfg.py b/devbox-back/app/gunicorn-cfg.py new file mode 100644 index 0000000..388cb71 --- /dev/null +++ b/devbox-back/app/gunicorn-cfg.py @@ -0,0 +1,10 @@ + +# -*- encoding: utf-8 -*- + +bind = '0.0.0.0:8080' +workers = 2 +worker_class = 'uvicorn.workers.UvicornWorker' +accesslog = '-' +loglevel = 'debug' +capture_output = True +enable_stdio_inheritance = True diff --git a/devbox-back/main.py b/devbox-back/app/main.py similarity index 99% rename from devbox-back/main.py rename to devbox-back/app/main.py index 9dff28a..a03a875 100644 --- a/devbox-back/main.py +++ b/devbox-back/app/main.py @@ -14,7 +14,7 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Database configuration -DATABASE_FILE = "devbox_emails.db" +DATABASE_FILE = "db/devbox.sqlite3" def get_db_connection(): """Create and return a database connection""" diff --git a/devbox-back/database_manager.py b/devbox-back/database_manager.py index 9a5e44a..88b2283 100755 --- a/devbox-back/database_manager.py +++ b/devbox-back/database_manager.py @@ -38,7 +38,7 @@ class DevBoxEmailManager: Database manager for DevBox email subscriptions """ - def __init__(self, db_file: str = "devbox_emails.db"): + def __init__(self, db_file: str = "db/devbox.sqlite3"): self.db_file = db_file self.ensure_database_exists() diff --git a/devbox-back/pyproject.toml b/devbox-back/pyproject.toml deleted file mode 100644 index fe50251..0000000 --- a/devbox-back/pyproject.toml +++ /dev/null @@ -1,46 +0,0 @@ -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[project] -name = "devbox-email-api" -version = "1.0.0" -description = "Email collection API for DevBox landing page" -readme = "README.md" -license = {text = "MIT"} -authors = [ - {name = "DevBox Team"}, -] -requires-python = ">=3.8" -dependencies = [ - "fastapi>=0.104.0", - "uvicorn[standard]>=0.24.0", - "pydantic[email]>=2.5.0", - "python-multipart>=0.0.6", -] - -[project.optional-dependencies] -dev = [ - "pytest>=7.0.0", - "black>=23.0.0", - "isort>=5.12.0", - "flake8>=6.0.0", -] - -[project.urls] -Homepage = "https://github.com/yourusername/devbox-email-api" -Repository = "https://github.com/yourusername/devbox-email-api" - -[tool.hatch.build.targets.wheel] -packages = ["src"] - -[tool.black] -line-length = 88 -target-version = ['py38'] - -[tool.isort] -profile = "black" -line_length = 88 - -[project.scripts] -devbox-api = "main:main" \ No newline at end of file diff --git a/devbox-back/requirements.txt b/devbox-back/requirements.txt new file mode 100644 index 0000000..c1d060c --- /dev/null +++ b/devbox-back/requirements.txt @@ -0,0 +1,24 @@ +annotated-types==0.7.0 +anyio==4.9.0 +click==8.2.1 +dnspython==2.7.0 +email_validator==2.2.0 +fastapi==0.115.12 +gunicorn==23.0.0 +h11==0.16.0 +httptools==0.6.4 +idna==3.10 +packaging==25.0 +pydantic==2.11.5 +pydantic_core==2.33.2 +python-dotenv==1.1.0 +python-multipart==0.0.20 +PyYAML==6.0.2 +sniffio==1.3.1 +starlette==0.46.2 +typing-inspection==0.4.1 +typing_extensions==4.14.0 +uvicorn==0.34.3 +uvloop==0.21.0 +watchfiles==1.0.5 +websockets==15.0.1 diff --git a/devbox-back/run.sh b/devbox-back/run.sh index 0c000c1..8310438 100755 --- a/devbox-back/run.sh +++ b/devbox-back/run.sh @@ -13,6 +13,13 @@ fi echo "✅ Found Python: $(python3 --version)" +# Check if we're in the right directory +if [ ! -f "requirements.txt" ]; then + echo "❌ Error: requirements.txt not found!" + echo "Please run this script from the project root directory." + exit 1 +fi + # Create virtual environment if it doesn't exist if [ ! -d "venv" ]; then echo "📦 Creating virtual environment..." @@ -23,10 +30,10 @@ fi echo "🔧 Activating virtual environment..." source venv/bin/activate -# Install dependencies directly (simpler approach) -echo "📚 Installing dependencies..." +# Install dependencies from requirements.txt +echo "📚 Installing dependencies from requirements.txt..." pip install --upgrade pip -pip install fastapi uvicorn[standard] pydantic[email] python-multipart +pip install -r requirements.txt echo "" echo "🎉 Setup complete!" @@ -38,4 +45,4 @@ echo "💡 Press Ctrl+C to stop" echo "" # Start the application -python main.py --dev \ No newline at end of file +python main.py --dev