This API controls a robot on the Moon, translating commands from Earth to instructions the robot understands.
- Python 3.11+
- Docker 20.10+
- PostgreSQL 15+
- Ensure Docker and Docker Compose are installed
- Start the services:
docker-compose -f docker/docker-compose.yml up --build
- The API will be available at http://localhost:8000
- API documentation:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- Install UV:
pip install uv
- Create virtual environment and install dependencies:
uv venv . .venv/bin/activate uv sync - Set up environment variables:
echo "DATABASE_URL=postgresql+asyncpg://robotuser:robotpass@localhost:5432/moonrobot" > .env echo "START_POSITION=(0, 0)" >> .env echo "START_DIRECTION=NORTH" >> .env
- Start PostgreSQL locally (using your preferred method)
- Run the application:
uv run uvicorn src.main:app --reload
Returns the current position and direction of the robot.
Example response:
{
"position": {"x": 0, "y": 0},
"direction": "NORTH"
}Executes a command string and returns the final position.
Request body:
{
"command": "FLFFFRFLB"
}Example response:
{
"position": {"x": -1, "y": 3},
"direction": "NORTH",
"obstacle_detected": false
}When an obstacle is detected:
{
"position": {"x": 0, "y": 3},
"direction": "WEST",
"obstacle_detected": true,
}uv run pytest-
Check initial status:
curl http://localhost:8000/api/v1/status
-
Send movement commands:
curl -X POST http://localhost:8000/api/v1/commands \ -H "Content-Type: application/json" \ -d '{"command": "F"}'
-
Verify new position:
curl http://localhost:8000/api/v1/status
-
Test obstacle detection (start at position (0,3) facing north):
# To test from a specific position, restart the application with new environment variables: # START_POSITION="(0,3)" START_DIRECTION="NORTH" uvicorn src.main:app --reload # Try to move into obstacle at (0,4) curl -X POST http://localhost:8000/api/v1/commands \ -H "Content-Type: application/json" \ -d '{"command": "F"}'
This should return with "obstacle_detected": true
This project uses comprehensive quality checks:
- Ruff for Python linting and formatting
- mypy for static type checking
- Pre-commit hooks for automatic quality checks
- GitHub Actions for CI/CD pipeline
All code must pass these checks before merging.
This project uses Alembic for database migrations. See alembic/README.md for detailed information on how to work with migrations.
For development, it's recommended to run migrations using Docker to ensure consistency with the development environment:
# Apply all pending migrations
docker-compose -f docker/docker-compose.yml exec api alembic upgrade head
# Check current revision
docker-compose -f docker/docker-compose.yml exec api alembic current
# Create a new migration
docker-compose -f docker/docker-compose.yml exec api alembic revision --autogenerate -m "Description of changes"After creating new migration files, you'll need to rebuild the Docker containers to include these files:
docker-compose -f docker/docker-compose.yml up --build -d- Make changes to the code
- Run tests:
uv run pytest - Check linting:
uv run ruff check . - Check types:
uv run mypy . - Commit changes with conventional commits
This project uses pre-commit hooks to ensure code quality and consistency. The hooks automatically run:
- Ruff for Python linting and formatting
- mypy for static type checking
- Various checks for YAML files, trailing whitespace, etc.
To install and set up pre-commit hooks:
-
Install pre-commit (if not already installed):
uv add pre-commit
-
Install the git hook scripts:
uv pre-commit install
The pre-commit hooks will automatically run on every commit. You can also manually run them on all files:
uv run pre-commit run --all-filesIf any hooks fail, fix the issues and try committing again. Some hooks (like Ruff) may automatically fix issues, so you might just need to stage the fixed files and commit again.
The robot can be configured using environment variables:
START_POSITION: Initial position as "(x, y)" (default: "(0, 0)")START_DIRECTION: Initial direction (NORTH, SOUTH, EAST, WEST) (default: "NORTH")DATABASE_URL: PostgreSQL connection string