Using Cursor And Git To Make A FastApi App With PostgreSQL And OpenCV
Lasted edited: February 14, 2025
A work in progress. Maybe.
Reminder - good branch add-object-identification-to-opencv
Commonly Used Commands
source venv/bin/activate
docker-compose down
docker-compose up -d
docker-compose up --build
docker-compose logs -f web
To Back Up Project Files
I realize that best practices includes using git and requirements.txt for the backup. But you better be backing up the project folder too for when your git inevitably gets all messed up and you need to start again. Look, I ain’t no large organization with some git expert to check every commit, push, and merge. So, you know I’m gonna screw up the git every so often. This is when a project folder may save you some time. So this is how I do it.
Deactivate Virtual Environment
deactivate
Shutdown Docker Container
docker-compose down
Change Into Directory/Folder Above Project To Be Backed Up
cd ..
Duplicate Project Folder With Date & Time To Back Up
cp -r project-folder-name project-folder-name-back-up-$(date +%Y%m%d_%H%M%S)
Example - media-manager folder to be backed up
cp -r media-manager media-manager-back-up-$(date +%Y%m%d_%H%M%S)
Git Help To Delete The Messy Branch
I’m a solo developer who believes that always working on a branch rather than main is the way to go. And this why.
Whenever I’m working on something, or I should say AI is working is working on something, it’s gonna get messed up. Deleting the branch and starting over works for me. So this is how I do it.
First Create A Branch
checkout -b branch-that-is gonna-get-messed up
Make sure that you’re in the new branch.
git status
Make sure again.
git status
Work. Modify files. Delete files. Add Files. Mess up the branch. Oh, no. Nothings working.
git status
See what’s change and make sure you’re still on the messed up branch.
Add all to git
git add .
Commit the changes with a message
git commit -m "This is a temporary commit before I delete branch-that-is gonna-get-messed up"
Go back to main
git status
I’m in main and all looks good.
Delete messed up branch with the capital D since it hasn’t been merged.
git branch -D branch-that-is gonna-get-messed up
Take a deep breath
git status
Moving Project To Cloud
When To Use Sudo
System updates and package installation
sudo apt update
sudo apt upgrade
sudo apt install
Initial Docker installation
sudo sh get-docker.sh sudo usermod -aG docker $USER
If you need to edit system files
sudo nano /etc/hosts
View system logs
sudo tail -f /var/log/syslog
When Not To Use Sudo
Docker commands (after adding user to docker group)
docker-compose up -d docker ps docker logs
Git operations
git clone git pull git push
Project files
cd your-project nano docker-compose.yml mkdir new-directory
Python/pip commands in your project
pip install -r requirements.txt python main.py
To Run Project
Change Into Project Folder directory
cd name-of-project-folder
Activate Virtual Environment
source venv/bin/activate
Start Docker Container
docker-compose up -d
Open Browser And Go To:
http://localhost:8000/docs
click on POST
click on Try it out
click on choose file to open file browser
click on file that you want to upload
click on open
click on execute
wait for results
To Find Info On Database
Go To backend/.env
to find the database url.
DATABASE_URL=postgresql://myuser:mypassword@db:5432/mydatabase
This connection string tells you:
postgresql: The database type is PostgreSQL.
myuser: The username is myuser.
mypassword: The password is mypassword. (Important: In real applications, store passwords securely, not directly in code or configuration files. Use environment variables or secrets management.)
db:5432: The hostname is db (which is likely the name of your PostgreSQL service in your docker-compose.yml file), and the port is 5432.
/mydatabase: This is the database name!
Your application is connecting to a database named mydatabase.
Therefore, to connect manually using psql, you should use:
docker-compose exec db psql -U myuser -d mydatabase
The -d mydatabase
part is crucial. It tells psql to connect to the mydatabase
database.
Key takeaway: The DATABASE_URL (or similar connection string) is the definitive source for the database name your application is using. Always refer to it when you need to connect manually or perform database administration tasks.
Run Alembic Migration Within Docker With Web service name from docker-compose.yml
docker-compose run --rm web alembic revision --autogenerate -m "your message"
Git General Process
Make sure you’re on your working branch
git status
Add your changes
git add backend/app/services/opencv_service.py (example file name)
git add backend/app/main.py (example file name)
git add docker-compose.yml (example file name)
Create a meaningful commit
git commit -m “Add comprehensive video analysis with OpenCV”
Push to your branch
git push origin your-branch-name
**If everything is working well, merge to main
git checkout main
git merge your-branch-name
git push origin main
** To create new branch and move into it
git checkout -b name-of-new-branch
Initial Process To Create An App, Use Cursor Workspace, And Git
Create Project Directory Than Change Into It
mkdir my-project
cd my-project
Initialize Git in your project directory
git init
You should see a message like “Initialized empty Git repository in /your/path/.git/”
Create a .gitignore
File
# Create and open .gitignore
touch .gitignore
Add common files/directories to ignore:
# Dependencies
node_modules/
venv/
.env
# IDE specific
.vscode/
.idea/
*.swp
*.swo
# Cursor specific
.cursor/
.cursor-log/
Open Project in Cursor
-
Launch Cursor
-
File > Open Folder > Select your project directory
Initial Commit
git add .
git commit -m "Initial commit"
Set Up Remote Repository on Github and get the repository url
git remote add origin <your-repository-url>
git branch -M main
git push -u origin main
Python Virtual Environment:
To set up
python -m venv venv
To activate
source venv/bin/activate
Docker with PostgreSQL
With Docker Compose you use a YAML configuration file, known as the Compose file, to configure your application’s services, and then you create and start all the services from your configuration with the Compose CLI.
The default path for a Compose file is compose.yaml (preferred) or compose.yml that is placed in the working directory. Compose also supports docker-compose.yaml and docker-compose.yml for backwards compatibility of earlier versions. If both files exist, Compose prefers the canonical compose.yaml.
To Start PostgreSQL (using Docker)
docker run --name postgres-db -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgre
Start the database
docker-compose up -d
Start the database and build for changes
docker-compose up --build
Stop the database
docker-compose down
Stop and remove volumes (will delete all data)
docker-compose down -v
View logs
docker-compose logs -f db
Restart the database
docker-compose restart db
To list all the services along with their current status
docker compose ps
Check PostgreSQL/Docker container status by executing the below command in the project’s root directory.
docker-compose ps
Check logs if needed
docker-compose logs db
To activate virtual environment
source venv/bin/activate
Make sure the environment is running before executing the below uvicorn
command to start the web application.
uvicorn main:app --reload
Uvicorn
command is used to start a web application using Uvicorn
, a popular ASGI (Asynchronous Server Gateway Interface) server, often used with frameworks like FastAPI.
uvicorn
invokes the Uvicorn server. It’s the command you use to run your ASGI-compatible application.
main:app
specifies the location of your application.
main
refers to the Python module or file where your application code resides (e.g., main.py).
app refers to the actual application object within that module. This could be an instance of a FastAPI application, a Starlette application, or any other ASGI-compatible callable.
--reload
is a crucial flag for development. It enables auto-reloading. When you make changes to your code, Uvicorn will automatically detect those changes and restart the server, so you don’t have to manually restart it every time you modify your application.
Alembic commands are run where alembic.ini is located
Generates Migration
alembic revision --autogenerate -m "Rename metadata to file_metadata in Asset model"
Apply Migration
alembic upgrade head
If unable to install python face recognition models/opencv:
Error is generally “Please install face_recognition_models with this command before using face_recognition”
To fix:
pip install setuptools
Suggested FastApi Project Structure
Common FastAPI Project Structure
backend/
│
├── app/
│ ├── api/
│ │ ├── endpoints/
│ │ │ ├── assets.py
│ │ │ └── other_endpoints.py
│ │ └── __init__.py
│ ├── core/
│ │ ├── config.py
│ │ └── security.py
│ ├── db/
│ │ ├── base.py
│ │ ├── session.py
│ │ └── models/
│ │ ├── asset.py
│ │ └── other_models.py
│ ├── schemas/
│ │ ├── asset.py
│ │ └── other_schemas.py
│ ├── utils/
│ │ ├── metadata_extractor.py # Utility for extracting metadata
│ │ └── other_utilities.py
│ ├── main.py
│ └── __init__.py
│
├── alembic/
│ ├── versions/
│ └── env.py
│
├── tests/
│ ├── test_assets.py
│ └── other_tests.py
│
├── .env
├── .gitignore
├── requirements.txt
└── README.md
Steps to Back Up and Recreate Your Virtual Environment
- Ensure requirements.txt is Up-to-Date If you’ve installed additional packages since creating your requirements.txt, you can update it with the current list of installed packages: txt This command will overwrite your existing requirements.txt with the current list of installed packages in your virtual environment.
- Recreate the Virtual Environment If you need to recreate your virtual environment, you can do so by following these steps: Delete the Existing venv: If it exists and you want to start fresh, delete it:
- Version Control: Keep your requirements.txt file under version control (e.g., Git) to ensure you always have a record of your project’s dependencies.
- Environment Variables: If you have any environment-specific settings, consider using a .env file to store them, and ensure it’s also backed up or documented.
To run Postgres migrations in docker
Stop the containers
docker-compose down
Rebuild and start
docker-compose up --build -d
Run the migration
docker-compose exec web alembic revision --autogenerate -m "add_metadata_columns"
docker-compose exec web alembic upgrade head
Adding fields to OpenCv for analysis
The error occurs because we’re trying to return a NumPy boolean (np.True_) in the response, which FastAPI can’t serialize to JSON. Let’s fix the OpenCVService class to convert NumPy types to Python native types:
def analyze_video(self, video_path: str) -> Dict[Any, Any]:
"""Analyze video file and extract various metrics."""
try:
# ... (previous code remains the same until return statement)
return {
"fps": float(fps),
"total_frames": int(total_frames),
"width": int(width),
"height": int(height),
"faces_detected": int(avg_faces),
"motion_score": float(avg_motion),
"brightness_score": float(avg_brightness),
"is_stable": bool(avg_motion < 30), # Convert to Python bool
"scene_changes": [float(ts) for ts in scene_changes], # Convert to list of floats
"shot_types": {
"close_up_percentage": float(close_up),
"wide_shot_percentage": float(wide_shot),
"action_shot_percentage": float(action_shot),
"static_shot_percentage": float(static_shot)
},
"camera_motion": {
"static_percentage": float(static),
"pan_tilt_percentage": float(pan_tilt),
"tracking_percentage": float(tracking),
"rapid_movement_percentage": float(rapid)
}
}
except Exception as e:
print(f"Error analyzing video: {str(e)}")
return {}
The key changes are converting NumPy types to Python native types using float(), int(), and bool(). Converting NumPy arrays to Python lists with list comprehension Ensuring all numeric values are explicitly converted to Python types.
After making these changes, rebuild your container:
docker-compose down
docker-compose up --build