diff --git a/README.md b/README.md new file mode 100644 index 0000000..e8c7df0 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Geekbrain.io Portfolio + +FastAPI portfolio website with steampunk design. + +## Setup + +1. Copy `.env.example` to `.env` and fill in values. +2. Ensure MariaDB is accessible and create database/user (see spec). +3. Run: `docker-compose up -d` (from `docker/` directory) +4. Configure Nginx Proxy Manager to proxy `portfolio.geekbrain.io` to port 8000. + +## Development + +```bash +uvicorn app.main:app --reload +``` + +## Spec + +See `docs/superpowers/specs/2025-03-21-geekbrain-portfolio-design.md` for full specification. diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..edabda9 --- /dev/null +++ b/app/__init__.py @@ -0,0 +1 @@ +# App package diff --git a/app/config.py b/app/config.py new file mode 100644 index 0000000..3616585 --- /dev/null +++ b/app/config.py @@ -0,0 +1,19 @@ +from pydantic_settings import BaseSettings +from pydantic import Field, HttpUrl + +class Settings(BaseSettings): + database_url: str = Field(..., description="MariaDB async connection string") + smtp_host: str = Field(..., description="SMTP server host") + smtp_port: int = Field(587, description="SMTP port") + smtp_user: str = Field(..., description="SMTP username (email)") + smtp_password: str = Field(..., description="SMTP password/app password") + recaptcha_secret: str = Field(..., description="reCAPTCHA secret key") + recaptcha_site_key: str = Field(..., description="reCAPTCHA site key (frontend)") + gitbucket_url: HttpUrl = Field(..., description="GitBucket API URL") + cache_ttl: int = Field(300, description="Cache TTL in seconds") + log_level: str = Field("INFO", description="Logging level") + + class Config: + env_file = ".env" + +settings = Settings() diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000..66578df --- /dev/null +++ b/docker/.env.example @@ -0,0 +1,17 @@ +# Database +DATABASE_URL=mysql+aiomysql://geekbrain_app:YOUR_PASSWORD@10.0.0.16:3306/geekbrain_portfolio + +# SMTP (Gmail) +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_USER=rcairbum@gmail.com +SMTP_PASSWORD=your_gmail_app_password + +# reCAPTCHA +RECAPTCHA_SITE_KEY=your_site_key_here +RECAPTCHA_SECRET=your_recaptcha_secret_key + +# GitBucket +GITBUCKET_URL=http://10.0.0.16:8080/api/v3/users/rcairbum/repos +CACHE_TTL=300 +LOG_LEVEL=INFO diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..954eef8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +sqlalchemy==2.0.23 +aiomysql==0.2.0 +pydantic==2.5.0 +pydantic-settings==2.1.0 +aiosmtplib==3.0.1 +httpx==0.25.1 +pytest==7.4.3 +pytest-asyncio==0.21.1 +python-dotenv==1.0.0 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..d4839a6 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +# Tests package diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..5871ed8 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1 @@ +import pytest