Welcome to your Python capstone project! You'll be working with a FastAPI + PostgreSQL application that helps people track their daily learning journey. This will prepare you for deploying to the cloud in the next phase.
By the end of this capstone, your API should be working locally and ready for cloud deployment.
- π Getting Started
- οΏ½οΈ Explore Your Database (Optional)
- Project Structure
- Your Learning Goals
- π― Development Tasks (Your Work!)
- π Data Schema
- π API Endpoints
- β How to Complete This Project
- π§ Troubleshooting
- π€ Contributing
- π License
- Git installed on your machine
- Docker Desktop installed and running
- VS Code with the Dev Containers extension
-
Fork this repository to your GitHub account by clicking the "Fork" button
-
Clone your fork to your local machine:
git clone https://github.com/YOUR_USERNAME/journal-starter.git
-
Move into the project directory:
cd journal-starter -
Open in VS Code:
code .
Environment variables live in a .env file (which is git-ignored so you don't accidentally commit secrets). This repo ships with a template named .env-sample.
-
Copy the sample file to create your real
.env:cp .env-sample .env
- Install the Dev Containers extension in VS Code (if not already installed)
- Reopen in container: When VS Code detects the
.devcontainerfolder, click "Reopen in Container"- Or use Command Palette (
Cmd/Ctrl + Shift + P):Dev Containers: Reopen in Container
- Or use Command Palette (
- Wait for setup: The API container will automatically install Python, dependencies, and configure your environment. The PostgreSQL Database container will also automatically be created.
In a terminal outside of VS Code, run:
docker psYou should see the postgres service running.
Make sure you are in the root of your project in the terminal:
./start.sh- Visit the API docs: http://localhost:8000/docs
- Create your first entry In the Docs UI Use the POST
/entriesendpoint to create a new journal entry. - View your entries using the GET
/entriesendpoint to see what you've created!
π― Once you can create and see entries, you're ready to start implementing the missing endpoints!
Want to see your data directly in the database? You can connect to PostgreSQL using VS Code's PostgreSQL extension:
- Install the PostgreSQL extension in VS Code (search for "PostgreSQL" by Chris Kolkman)
- Restart VS Code after installation
- Open the PostgreSQL extension (click the PostgreSQL icon in the sidebar)
- Click "Add Connection" or the "+" button
- Enter these connection details:
- Host name:
postgres - User name:
postgres - Password:
postgres - Port:
5432 - Conection Type:
Standard/No SSL - Database:
career_journal - Display name:
Journal Starter DB(or any name you prefer)
- Host name:
-
Expand your connection in the PostgreSQL panel
-
Left-click on "Journal Starter DB" to expand
-
Right-click on "career_journal"
-
Select "New Query"
-
Type this query to see all your entries:
SELECT * FROM entries;
-
Run the query to see all your journal data! (Ctrl/Cmd + Enter OR use the PostgreSQL command pallete: Run Query)
You can now explore the database structure, see exactly how your data is stored, and run custom queries to understand PostgreSQL better.
This project uses a clean FastAPI architecture with PostgreSQL:
api/
βββ main.py # FastAPI app entry point
βββ requirements.txt # Python dependencies
βββ models/
β βββ entry.py # Pydantic data models
βββ repositories/
β βββ interface_repository.py # Database interface
β βββ postgres_repository.py # PostgreSQL implementation
βββ routers/
β βββ journal_router.py # API endpoints (YOUR MAIN WORK HERE)
βββ services/
βββ entry_service.py # Business logic layerYou'll use feature branches and Pull Requests (PRs) for each task.
Create a feature branch for each task:
# 1. Start from main
git checkout main
git pull origin main
# 2. Create feature branch
git checkout -b feature/get-single-entry
# 3. Work and commit
git add .
git commit -m "feat: implement GET /entries/{id} endpoint"
# 4. Push and create PR
git push origin feature/get-single-entryfeature/get-single-entry- GET single entry endpointfeature/delete-entry- DELETE entry endpointfeature/logging-setup- Logging implementationfeature/cloud-cli-setup- Cloud CLI configuration
Complete a Journal API that allows users to:
- β Store journal entries (already implemented)
- β Retrieve all journal entries (already implemented)
- β Retrieve single journal entry (you need to implement)
- β Delete specific journal entries (you need to implement)
- β Update journal entries (already implemented)
- β Delete all entries (already implemented)
- β Setup logging (you need to implement)
Complete each task using the feature branch workflow. This mirrors real-world development practices!
Branch: feature/get-single-entry
-
Create your feature branch:
git checkout main git pull origin main git checkout -b feature/get-single-entry
-
Implement the endpoint in
api/routers/journal_router.py:- GET /entries/{entry_id} - Get single entry by ID
-
Test your implementation:
- Use the
/docspage to test your endpoint - Try valid and invalid entry IDs
- Use the
-
Commit and push:
git add . git commit -m "feat: implement GET /entries/{id} endpoint - Add route handler for single entry retrieval - Include proper error handling for non-existent entries - Add response model validation" git push origin feature/get-single-entry
-
Create a Pull Request:
- Go to your GitHub repository
- Click "Compare & pull request"
- Use this PR template:
## π Description Implements GET /entries/{entry_id} endpoint for retrieving single journal entries. ## β Testing Done - [x] Tested with valid entry ID via /docs - [x] Tested with invalid entry ID (returns 404) - [x] Verified response matches Entry model schema ## πΈ Screenshots (Add screenshot of successful test from /docs page)
Branch: feature/delete-entry
-
Create your feature branch:
git checkout main git pull origin main # Get any merged changes git checkout -b feature/delete-entry -
Implement the endpoint:
- DELETE /entries/{entry_id} - Delete specific entry
-
Follow the same commit, push, and PR process as above
Branch: feature/logging-setup
File: api/main.py
- Configure basic logging using
logging.basicConfig() - Set logging level to INFO
- Add console handler
- Test with a startup log message
Branch: feature/data-model-improvements
File: api/models/entry.py
- Add custom field validators (e.g., minimum length)
- Add data sanitization methods
- Add schema version tracking
Branch: feature/cloud-cli-setup
File: .devcontainer/devcontainer.json
- Choose and uncomment ONE cloud CLI tool:
- Azure CLI:
"ghcr.io/devcontainers/features/azure-cli:1": {} - AWS CLI:
"ghcr.io/devcontainers/features/aws-cli:1": {} - Google Cloud CLI:
"ghcr.io/devcontainers/features/gcloud:1": {}
- Azure CLI:
PR Title Format:
feat: implement GET /entries/{id} endpoint
fix: resolve database connection timeout
docs: update API documentation
PR Description Template:
## π Description
Brief description of what this PR accomplishes.
## π― Type of Change
- [ ] New feature (non-breaking change)
- [ ] Bug fix (non-breaking change)
- [ ] Documentation update
- [ ] Code refactoring
## β
Testing Done
- [ ] Tested manually via /docs interface
- [ ] Verified no existing functionality broken
- [ ] Added appropriate error handling
## πΈ Screenshots/Demo
(If applicable, add screenshots or GIFs showing the feature working)
## π Review Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex logic
- [ ] No sensitive data exposedDo a Self-Review Before merging your PR, do a thorough self-review:
- Check the diff - Does every change make sense?
- Test thoroughly - Does the feature work as expected?
- Read your code - Is it clear and well-commented?
- Run the app - Does everything still work?
- Consider edge cases - What could go wrong?
Optional: Share in Discord Feel free to share your PR in the Learn to Cloud Discord #phase-2 channel if you'd like additional feedback from the community!
Once you've completed your self-review:
- Address any issues - Fix anything you found during review
- Test one more time - Make sure everything works
- Merge when ready - Use "Squash and merge" for clean history
- Delete the branch - Keep your repository clean
# After merging, clean up locally
git checkout main
git pull origin main
git branch -d feature/your-branch-nameEach journal entry follows this structure:
| Field | Type | Description | Validation |
|---|---|---|---|
| id | string | Unique identifier (UUID) | Auto-generated |
| work | string | What did you work on today? | Required, max 256 characters |
| struggle | string | What's one thing you struggled with today? | Required, max 256 characters |
| intention | string | What will you study/work on tomorrow? | Required, max 256 characters |
| created_at | datetime | When entry was created | Auto-generated UTC |
| updated_at | datetime | When entry was last updated | Auto-updated UTC |
| Method | Endpoint | Status | Description |
|---|---|---|---|
| POST | /entries | β Done | Create new journal entry |
| GET | /entries | β Done | List all journal entries |
| GET | /entries/{id} | β TODO | Get single entry by ID |
| PATCH | /entries/{id} | β Done | Update existing entry |
| DELETE | /entries/{id} | β TODO | Delete specific entry |
| DELETE | /entries | β Done | Delete all entries |
- Set up your repository - Fork, clone, and configure environment
- Create feature branches - One branch per task/endpoint
- Implement incrementally - Small, focused changes
- Test thoroughly - Use /docs to verify each endpoint
- Create quality PRs - Clear descriptions and testing evidence
- Get code reviewed - Self-review with optional Discord sharing
- Merge and clean up - Maintain high code quality
# Starting new work
git checkout main
git pull origin main
git checkout -b feature/your-feature-name
# Working on your feature
git add .
git commit -m "descriptive commit message"
git push origin feature/your-feature-name
# After PR is merged
git checkout main
git pull origin main
git branch -d feature/your-feature-nameBy the end of this project, you should have:
- β 4+ merged Pull Requests - One for each major feature
- β Clean commit history - Descriptive commit messages
- β Working API - All endpoints functional and tested
- β Professional workflow - Feature branches and code review
- β Deployment ready - Cloud CLI configured
This project teaches you:
- FastAPI development - Building REST APIs
- PostgreSQL integration - Database operations
- Docker containers - Development environment
- API testing - Using interactive documentation
- Git workflows - Feature branches and PRs
- Code review - Self-review with optional community feedback
- Project organization - Clean, maintainable code structure
- Documentation - Clear commit messages and PR descriptions
- Containerization - App ready for cloud deployment
- Environment configuration - Proper secret management
- CLI tools - Ready for cloud provider interaction
If the API won't start:
- Make sure the PostgreSQL container is running:
docker ps - Check the container logs:
docker logs your-postgres-container-name - Restart the database:
docker restart your-postgres-container-name
If you can't connect to the database:
- Verify the
.envfile exists and has the correct DATABASE_URL - Make sure Docker Desktop is running
- Try restarting the dev container:
Dev Containers: Rebuild Container
If the dev container won't open:
- Ensure Docker Desktop is running
- Install the "Dev Containers" extension in VS Code
- Try:
Dev Containers: Rebuild and Reopen in Container
We welcome contributions to improve this capstone project! Open an issue and we can plan from there.
Found a bug or have a suggestion? Please open an issue with:
- Clear description of the problem or suggestion
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Environment details (OS, Docker version, etc.)
This project is licensed under the MIT License - see the LICENSE file for details.
- β Commercial use - You can use this code in commercial projects
- β Modification - You can modify and distribute the code
- β Distribution - You can distribute the original or modified code
- β Private use - You can use this code for personal projects
- β Liability - The authors are not liable for any damages
- β Warranty - This code comes with no warranty
If you use this project as a foundation for your own work, we'd appreciate a link back to this repository, but it's not required.
Happy coding! π Built with β€οΈ for learning cloud development.