From 45a93e5a23d53dff79e27ba0921114ad432f8583 Mon Sep 17 00:00:00 2001 From: Aleeeehh Date: Fri, 1 Aug 2025 23:41:32 +0200 Subject: [PATCH] add initial template --- .gitignore | 58 +++++++++++++++++- README.md | 18 +++++- app/README.md | 0 app/index.html | 97 +++++++++++++++++++++++++++++++ app/script.js | 76 ++++++++++++++++++++++++ backend/README.md | 3 - backend/db/__init__.py | 0 backend/db/schemas.py | 0 backend/docker-compose.yaml | 29 ++++++--- backend/main.py | 22 +++++++ backend/requirements.txt | 4 ++ backend/routes.py | 50 ++++++++++++++++ start.sh | 113 ++++++++++++++++++++++++++++++++++++ 13 files changed, 457 insertions(+), 13 deletions(-) delete mode 100644 app/README.md create mode 100644 app/index.html create mode 100644 app/script.js delete mode 100644 backend/README.md delete mode 100644 backend/db/__init__.py delete mode 100644 backend/db/schemas.py create mode 100644 backend/main.py create mode 100644 backend/routes.py create mode 100755 start.sh diff --git a/.gitignore b/.gitignore index 57d0779..03c9a14 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,56 @@ -.idea -backend/.env +# Virtual environment +venv/ +env/ +.venv/ + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Logs +*.log + +# Environment variables +.env +.env.local +.env.*.local + +# Node modules (se installi http-server globalmente) +node_modules/ + +# Docker +.dockerignore \ No newline at end of file diff --git a/README.md b/README.md index aae5e79..0d994cc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,18 @@ -# Team NPT +# Template per Hackathon +## πŸš€ Avvio Rapido + +```bash +# Avvia tutto con un comando +./start.sh + +#Comandi utili per vedere dati db su mongosh +mongosh +show dbs +use simple_db +show collections +db.items.find() +``` + +Il frontend sarΓ  disponibile su http://localhost:3000 +Il backend sarΓ  hostato localmente su http://localhost:8000 \ No newline at end of file diff --git a/app/README.md b/app/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..45c5ef9 --- /dev/null +++ b/app/index.html @@ -0,0 +1,97 @@ + + + + + + Template APP + + + +
+

πŸš€ Simple Fullstack App

+ +
+ + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/app/script.js b/app/script.js new file mode 100644 index 0000000..49816d4 --- /dev/null +++ b/app/script.js @@ -0,0 +1,76 @@ +const API_BASE_URL = 'http://localhost:8000'; + +// Funzione per mostrare messaggi di status +function showStatus(message, isSuccess = true) { + const statusDiv = document.getElementById('status'); + statusDiv.innerHTML = `
${message}
`; +} + +// Funzione per mostrare i risultati +function showResult(data) { + const resultDiv = document.getElementById('result'); + resultDiv.style.display = 'block'; + resultDiv.textContent = JSON.stringify(data, null, 2); +} + +// GET: Ottiene dati dal database +async function getData() { + try { + console.log('πŸ“₯ Richiesta GET in corso...'); + showStatus('πŸ“₯ Richiesta GET in corso...', true); + + const response = await fetch(`${API_BASE_URL}/api/data`); + const data = await response.json(); + + if (response.ok) { + showStatus('βœ… Dati ottenuti con successo!', true); + showResult(data); + } else { + showStatus(`❌ Errore: ${data.detail || 'Errore sconosciuto'}`, false); + } + } catch (error) { + console.error('Errore GET:', error); + showStatus(`❌ Errore di connessione: ${error.message}`, false); + } +} + +// POST: Inserisce dati nel database +async function createData() { + try { + console.log('πŸ“€ Richiesta POST in corso...'); + showStatus('πŸ“€ Richiesta POST in corso...', true); + + const response = await fetch(`${API_BASE_URL}/api/data`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + } + }); + + const data = await response.json(); + + if (response.ok) { + showStatus('βœ… Dato inserito con successo!', true); + showResult(data); + } else { + showStatus(`❌ Errore: ${data.detail || 'Errore sconosciuto'}`, false); + } + } catch (error) { + console.error('Errore POST:', error); + showStatus(`❌ Errore di connessione: ${error.message}`, false); + } +} + +// Test di connessione all'avvio +window.addEventListener('load', async () => { + try { + const response = await fetch(`${API_BASE_URL}/`); + if (response.ok) { + console.log('βœ… Backend connesso!'); + } else { + console.log('❌ Backend non raggiungibile'); + } + } catch (error) { + console.log('❌ Backend non raggiungibile:', error.message); + } +}); \ No newline at end of file diff --git a/backend/README.md b/backend/README.md deleted file mode 100644 index 7378979..0000000 --- a/backend/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ENV -- MONGO_INITDB_ROOT_USERNAME= -- MONGO_INITDB_ROOT_PASSWORD= \ No newline at end of file diff --git a/backend/db/__init__.py b/backend/db/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/backend/db/schemas.py b/backend/db/schemas.py deleted file mode 100644 index e69de29..0000000 diff --git a/backend/docker-compose.yaml b/backend/docker-compose.yaml index 969666d..8347b75 100644 --- a/backend/docker-compose.yaml +++ b/backend/docker-compose.yaml @@ -1,15 +1,30 @@ +version: '3.8' + services: mongodb: - image: mongo:8.0.0 - container_name: mongodb - restart: unless-stopped + image: mongo:7.0 + container_name: simple_mongodb ports: - "27017:27017" environment: - - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} - - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} + MONGO_INITDB_ROOT_USERNAME: admin + MONGO_INITDB_ROOT_PASSWORD: password volumes: - - mongo-data:/data/db + - mongodb_data:/data/db + restart: unless-stopped + + mongo-express: + image: mongo-express:latest + container_name: mongo_express + ports: + - "8081:8081" + environment: + ME_CONFIG_MONGODB_ADMINUSERNAME: admin + ME_CONFIG_MONGODB_ADMINPASSWORD: password + ME_CONFIG_MONGODB_URL: mongodb://admin:password@mongodb:27017/ + depends_on: + - mongodb + restart: unless-stopped volumes: - mongo-data: + mongodb_data: diff --git a/backend/main.py b/backend/main.py new file mode 100644 index 0000000..e2744c8 --- /dev/null +++ b/backend/main.py @@ -0,0 +1,22 @@ +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from routes import router + +app = FastAPI(title="Simple Fullstack API") + +# CORS per permettere richieste dal frontend +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Includi le route +app.include_router(router) + +if __name__ == "__main__": + import uvicorn + print("πŸš€ Avvio server FastAPI...") + uvicorn.run(app, host="0.0.0.0", port=8000) \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt index e69de29..ec9f051 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -0,0 +1,4 @@ +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +pymongo==4.6.0 +python-multipart==0.0.6 diff --git a/backend/routes.py b/backend/routes.py new file mode 100644 index 0000000..4621b8b --- /dev/null +++ b/backend/routes.py @@ -0,0 +1,50 @@ +from fastapi import APIRouter, HTTPException +from pymongo import MongoClient +from datetime import datetime + +# Router per le API +router = APIRouter() + +# Connessione MongoDB +client = MongoClient("mongodb://localhost:27017/") +db = client["simple_db"] +collection = db["items"] + +@router.get("/") +def read_root(): + """Root endpoint per test connessione""" + return {"message": "Simple Fullstack API is running!"} + +@router.get("/api/data") +def get_data(): + """GET: Ottiene il primo documento dal database""" + try: + # Trova il primo documento disponibile + document = collection.find_one() + if document: + # Converti ObjectId in stringa per JSON serialization + document["_id"] = str(document["_id"]) + return {"success": True, "data": document} + else: + return {"success": False, "message": "Nessun dato trovato nel database"} + except Exception as e: + raise HTTPException(status_code=500, detail=f"Errore database: {str(e)}") + +@router.post("/api/data") +def create_data(): + """POST: Inserisce un dato hardcoded nel database""" + try: + # Dato hardcoded da inserire + new_item = { + "name": "Item di esempio", + "description": "Questo Γ¨ un item creato tramite API", + "timestamp": datetime.now().isoformat(), + "value": 42 + } + + result = collection.insert_one(new_item) + new_item["_id"] = str(result.inserted_id) + + return {"success": True, "message": "Dato inserito con successo", "data": new_item} + except Exception as e: + raise HTTPException(status_code=500, detail=f"Errore inserimento: {str(e)}") \ No newline at end of file diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..5f009f7 --- /dev/null +++ b/start.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +echo "πŸš€ Avvio Simple Fullstack App..." + +# Colori per output +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Funzione per stampare messaggi colorati +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +# Controlla se Python3 Γ¨ installato +if ! command -v python3 &> /dev/null; then + echo "❌ Python3 non trovato. Installa Python3 prima di continuare." + exit 1 +fi + +# Controlla se Docker Γ¨ installato +if ! command -v docker &> /dev/null; then + echo "❌ Docker non trovato. Installa Docker prima di continuare." + exit 1 +fi + +# Controlla se http-server Γ¨ installato +if ! command -v http-server &> /dev/null; then + print_warning "http-server non trovato. Installando..." + npm install -g http-server +fi + +# Crea virtual environment se non esiste +if [ ! -d "venv" ]; then + print_status "Creazione virtual environment..." + python3 -m venv venv + print_success "Virtual environment creato!" +else + print_status "Virtual environment giΓ  esistente" +fi + +# Attiva virtual environment +print_status "Attivazione virtual environment..." +source venv/bin/activate + +# Installa dipendenze +print_status "Installazione dipendenze Python..." +pip install -r backend/requirements.txt +print_success "Dipendenze installate!" + +# Avvia MongoDB con Docker +print_status "Avvio MongoDB con Docker..." +cd backend +docker-compose up -d +cd .. + +# Aspetta che MongoDB sia pronto +print_status "Attesa MongoDB..." +sleep 5 + +# Avvia backend in background +print_status "Avvio backend FastAPI..." +cd backend +python main.py & +BACKEND_PID=$! +cd .. + +# Aspetta che il backend sia pronto +print_status "Attesa backend..." +sleep 3 + +# Avvia frontend +print_status "Avvio frontend..." +cd app +http-server -p 3000 -o & +FRONTEND_PID=$! +cd .. + +print_success "πŸŽ‰ Tutto avviato!" +echo "" +echo "πŸ“± Frontend: http://localhost:3000" +echo "πŸ”§ Backend API: http://localhost:8000" +echo "πŸ—„οΈ MongoDB: localhost:27017" +echo "" +echo "πŸ’‘ Premi Ctrl+C per fermare tutto" + +# Funzione per cleanup +cleanup() { + echo "" + print_status "Fermando servizi..." + kill $BACKEND_PID 2>/dev/null + kill $FRONTEND_PID 2>/dev/null + cd backend + docker-compose down + cd .. + print_success "Servizi fermati!" + exit 0 +} + +# Intercetta Ctrl+C +trap cleanup SIGINT + +# Mantieni lo script in esecuzione +wait \ No newline at end of file