├── .flake8 ├── .gitignore ├── README.md ├── backend ├── Dockerfile ├── app │ └── api │ │ ├── __init__.py │ │ ├── routes │ │ ├── __init__.py │ │ └── cleanings.py │ │ └── server.py └── requirements.txt └── docker-compose.yml /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E203,W503 3 | exclude = */tests/* 4 | max-line-length = 120 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .env.development 3 | .env.staging 4 | .env.production 5 | velup-io-service-key.json 6 | .DS_Store 7 | *.DS_Store 8 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Phresh Cleaning - Up and Running With FastAPI Tutorial Series 2 | 3 | This repo holds the code used to create a FastAPI backend for a fake cleaning marketplace called "Phresh". 4 | 5 | Each part of the application is built and tested in small, manageable chunks - accompanied by written tutorials. 6 | 7 | The technology stack used to create the backend of this application is as follows: 8 | 9 | - Framework 10 | - FastAPI and Starlette 11 | - ASGI Server 12 | - Uvicorn and Gunicorn 13 | - Containerization 14 | - Docker 15 | - Database 16 | - Postgres 17 | - Alembic 18 | - encode/databases 19 | - Authentication 20 | - Bcrypt 21 | - Passlib 22 | - JWT Tokens with Pyjwt 23 | - Testing 24 | - Pytest 25 | - Development 26 | - flake8 27 | - black 28 | - vscode 29 | 30 | 31 | ## Roadmap and Completed Articles 32 | 33 | ✅ - Completed 34 | 🛄 - In progress 35 | 📱 - UI 36 | 🚂 - Backend 37 | 38 | - [Part 1: Up and running with FastAPI and docker ✅🚂](https://www.jeffastor.com/blog/up-and-running-with-fastapi-and-docker) 39 | - [Part 2: Configuring a postgresql db with your dockerized FastAPI app ✅🚂](https://www.jeffastor.com/blog/pairing-a-postgresql-db-with-your-dockerized-fastapi-app) 40 | - [Part 3: Hooking FastAPI endpoints up to a postgres database ✅🚂](https://www.jeffastor.com/blog/hooking-fastapi-endpoints-up-to-a-postgres-database) 41 | - [Part 4: Testing FastAPI endpoints with docker and pytest ✅🚂](https://www.jeffastor.com/blog/testing-fastapi-endpoints-with-docker-and-pytest) 42 | - [Part 5: Resource management with FastAPI ✅🚂](https://www.jeffastor.com/blog/resource-management-with-fastapi) 43 | - [Part 6: Designing a robust user model in a FastAPI app ✅🚂](https://www.jeffastor.com/blog/designing-a-robust-user-model-in-a-fastapi-app) 44 | - [Part 7: User auth in FastAPI with jwt tokens ✅🚂](https://www.jeffastor.com/blog/authenticating-users-in-fastapi-with-jwt-tokens) 45 | - [Part 8: Auth dependencies in FastAPI ✅🚂](https://www.jeffastor.com/blog/authentication-dependencies-in-fastapi) 46 | - [Part 9: Setting up user profiles in FastAPI ✅🚂](https://www.jeffastor.com/blog/setting-up-user-profiles-in-fastapi) 47 | - [Part 10: User owned resources in FastAPI ✅🚂](https://www.jeffastor.com/blog/user-owned-resources-in-fastapi) 48 | - [Part 11: Marketplace functionality in FastAPI ✅🚂](https://www.jeffastor.com/blog/marketplace-functionality-in-fastapi) 49 | - [Part 12: Evaluations and SQL aggregations in FastAPI ✅🚂](https://www.jeffastor.com/blog/evaluations-and-sql-aggreations-in-fastapi) 50 | - [Part 13: Phresh frontend - bootstrapping a React app ✅📱](https://www.jeffastor.com/blog/phresh-frontend-bootstrapping-a-react-app) 51 | - [Part 14: Frontend navigation with React router ✅📱](https://www.jeffastor.com/blog/frontend-navigation-with-react-router) 52 | - [Part 15: Managing auth state with redux ✅📱](https://www.jeffastor.com/blog/managing-auth-state-with-redux) 53 | - [Part 16: Client-side protected routes and user registration ✅📱](https://www.jeffastor.com/blog/client-side-protected-routes-and-user-registration) 54 | - [Part 17: Consuming a FastAPI backend from a React frontend ✅🚂📱](https://www.jeffastor.com/blog/consuming-a-fastapi-backend-from-a-react-frontend) 55 | - [Part 18: Edit user-owned cleaning resources with React and FastAPI ✅📱](https://www.jeffastor.com/blog/edit-user-owned-cleaning-resources-with-react-and-fastapi) 56 | - [Part 19: Creating and viewing job offers with React and FastAPI ✅📱](https://www.jeffastor.com/blog/creating-and-viewing-job-offers-with-react-and-fastapi) 57 | - [Part 20: Approving and rejecting job offers with React and FastAPI ✅🚂📱](https://www.jeffastor.com/blog/approving-and-rejecting-job-offers-with-react-and-fastapi) 58 | - [Part 21: Serving a paginated activity feed from FastAPI ✅🚂📱](https://www.jeffastor.com/blog/serving-a-paginated-activity-feed-from-fastapi) 59 | - [Part 22: Designing a feed page for a FastAPI app ✅📱](https://www.jeffastor.com/blog/designing-a-feed-page-for-a-fastapi-app) 60 | - [Part 23: Refactoring our React UI into composable hooks ✅📱](https://www.jeffastor.com/blog/refactoring-our-react-ui-into-composable-hooks) 61 | - [Part 24: Refactoring our UI into hooks - Part II ✅📱](https://www.jeffastor.com/blog/refactoring-our-react-ui-into-composable-hooks-part-ii) 62 | - [Part 25: Populating cleaning jobs with user offers in FastAPI ✅🚂](https://www.jeffastor.com/blog/populating-cleaning-jobs-with-user-offers-in-fastapi) 63 | -------------------------------------------------------------------------------- /backend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-slim-buster 2 | 3 | WORKDIR /backend 4 | 5 | ENV PYTHONDONTWRITEBYTECODE 1 6 | ENV PYTHONBUFFERED 1 7 | 8 | # install system dependencies 9 | RUN apt-get update \ 10 | && apt-get -y install netcat gcc postgresql \ 11 | && apt-get clean 12 | 13 | # install python dependencies 14 | RUN pip install --upgrade pip 15 | COPY ./requirements.txt . 16 | RUN pip install -r requirements.txt 17 | 18 | COPY . /backend 19 | 20 | -------------------------------------------------------------------------------- /backend/app/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jastor11/phresh-tutorial/30b5216ebdd43f7ce397e87c13a4d3713720cee2/backend/app/api/__init__.py -------------------------------------------------------------------------------- /backend/app/api/routes/__init__.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter 2 | 3 | from app.api.routes.cleanings import router as cleanings_router 4 | 5 | 6 | router = APIRouter() 7 | 8 | 9 | router.include_router(cleanings_router, prefix="/cleanings", tags=["cleanings"]) 10 | 11 | -------------------------------------------------------------------------------- /backend/app/api/routes/cleanings.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from fastapi import APIRouter 4 | 5 | 6 | router = APIRouter() 7 | 8 | 9 | @router.get("/") 10 | async def get_all_cleanings() -> List[dict]: 11 | cleanings = [ 12 | {"id": 1, "name": "My house", "cleaning_type": "full_clean", "price_per_hour": 29.99}, 13 | {"id": 2, "name": "Someone else's house", "cleaning_type": "spot_clean", "price_per_hour": 19.99} 14 | ] 15 | 16 | return cleanings 17 | 18 | -------------------------------------------------------------------------------- /backend/app/api/server.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI 2 | from fastapi.middleware.cors import CORSMiddleware 3 | 4 | from app.api.routes import router as api_router 5 | 6 | 7 | def get_application(): 8 | app = FastAPI(title="Phresh", version="1.0.0") 9 | 10 | app.add_middleware( 11 | CORSMiddleware, 12 | allow_origins=["*"], 13 | allow_credentials=True, 14 | allow_methods=["*"], 15 | allow_headers=["*"], 16 | ) 17 | 18 | app.include_router(api_router, prefix="/api") 19 | 20 | return app 21 | 22 | 23 | app = get_application() 24 | -------------------------------------------------------------------------------- /backend/requirements.txt: -------------------------------------------------------------------------------- 1 | # app 2 | fastapi==0.55.1 3 | uvicorn==0.11.3 4 | pydantic==1.4 5 | email-validator==1.1.1 -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | server: 5 | build: 6 | context: ./backend 7 | dockerfile: Dockerfile 8 | volumes: 9 | - ./backend/:/backend/ 10 | - /var/run/docker.sock:/var/run/docker.sock 11 | command: uvicorn app.api.server:app --reload --workers 1 --host 0.0.0.0 --port 8000 12 | env_file: 13 | - ./backend/.env 14 | ports: 15 | - 8000:8000 16 | 17 | --------------------------------------------------------------------------------