From 42a447f12ebaf6deabd274e14e9bab5ebbf4f5ae Mon Sep 17 00:00:00 2001 From: egutierrez Date: Tue, 24 Dec 2024 19:55:36 +0100 Subject: [PATCH] Add FastAPI backend and React frontend setup with initial routes and components --- .gitignore | 14 ++++++++++++++ backend/app/dependencies.py | 5 +++++ backend/app/main.py | 21 +++++++++++++++++++++ backend/app/routers/__init__.py | 2 ++ backend/app/routers/example_router.py | 11 +++++++++++ backend/requirements.txt | 3 +++ frontend/package.json | 19 +++++++++++++++++++ frontend/src/App.js | 24 ++++++++++++++++++++++++ frontend/src/index.js | 9 +++++++++ frontend/vite.config.js | 6 ++++++ 10 files changed, 114 insertions(+) create mode 100644 .gitignore create mode 100644 backend/app/dependencies.py create mode 100644 backend/app/main.py create mode 100644 backend/app/routers/__init__.py create mode 100644 backend/app/routers/example_router.py create mode 100644 backend/requirements.txt create mode 100644 frontend/package.json create mode 100644 frontend/src/App.js create mode 100644 frontend/src/index.js create mode 100644 frontend/vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c7b5335 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +venv/ +.env + +# Node +node_modules/ +dist/ +.env.local +.env.development.local +.env.test.local +.env.production.local diff --git a/backend/app/dependencies.py b/backend/app/dependencies.py new file mode 100644 index 0000000..1bedbea --- /dev/null +++ b/backend/app/dependencies.py @@ -0,0 +1,5 @@ +from fastapi import Header, HTTPException + +async def get_token_header(x_token: str = Header()): + if x_token != "fake-super-secret-token": + raise HTTPException(status_code=400, detail="X-Token header invalid") diff --git a/backend/app/main.py b/backend/app/main.py new file mode 100644 index 0000000..eefaf6f --- /dev/null +++ b/backend/app/main.py @@ -0,0 +1,21 @@ +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from .routers import example_router + +app = FastAPI() + +# Configure CORS +app.add_middleware( + CORSMiddleware, + allow_origins=["http://localhost:5173"], # Vite's default port + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Include routers +app.include_router(example_router.router) + +@app.get("/") +async def root(): + return {"message": "Welcome to FastAPI"} diff --git a/backend/app/routers/__init__.py b/backend/app/routers/__init__.py new file mode 100644 index 0000000..59ee39c --- /dev/null +++ b/backend/app/routers/__init__.py @@ -0,0 +1,2 @@ + +# backend/app/routers/__init__.py diff --git a/backend/app/routers/example_router.py b/backend/app/routers/example_router.py new file mode 100644 index 0000000..1fc0f34 --- /dev/null +++ b/backend/app/routers/example_router.py @@ -0,0 +1,11 @@ +from fastapi import APIRouter + +router = APIRouter( + prefix="/api", + tags=["example"], + responses={404: {"description": "Not found"}}, +) + +@router.get("/items") +async def read_items(): + return [{"name": "Item 1"}, {"name": "Item 2"}] diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..deb3352 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,3 @@ +fastapi==0.100.0 +uvicorn==0.22.0 +pydantic==2.0.2 diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..e784a4f --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,19 @@ +{ + "name": "react-fastapi-template", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.0.3", + "vite": "^4.4.5" + } +} diff --git a/frontend/src/App.js b/frontend/src/App.js new file mode 100644 index 0000000..68637dc --- /dev/null +++ b/frontend/src/App.js @@ -0,0 +1,24 @@ +import { useState, useEffect } from 'react' + +function App() { + const [items, setItems] = useState([]) + + useEffect(() => { + fetch('http://localhost:8000/api/items') + .then(response => response.json()) + .then(data => setItems(data)) + }, []) + + return ( +
+

React + FastAPI Template

+ +
+ ) +} + +export default App diff --git a/frontend/src/index.js b/frontend/src/index.js new file mode 100644 index 0000000..3885300 --- /dev/null +++ b/frontend/src/index.js @@ -0,0 +1,9 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App' + +ReactDOM.createRoot(document.getElementById('root')).render( + + + +) diff --git a/frontend/vite.config.js b/frontend/vite.config.js new file mode 100644 index 0000000..9ffcc67 --- /dev/null +++ b/frontend/vite.config.js @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react()], +})