- well-structured easy to understand and scale-up project structure
.
├── Dockerfile
├── README.md
├── docker-compose.yml
├── logging.ini
├── requirements.txt
├── ruff.toml
├── pytest.ini
├── .env.example
├── tests - tests
│ ├── __init__.py
│ ├── conftest.py
│ └── exchange - testing module
├── scripts - scripts
│ └── start-dev.sh
└── src - global staff
├── __init__.py
├── config.py
├── constants.py - constants
├── exception_handlers.py - exception_handlers
├── exceptions.py - exceptions
├── main.py
├── redis.py - redis query
├── settings.py
└── exchange - exchange app
├── __init__.py
├── client.py - client
├── constants.py
├── exceptions.py
├── helper.py - helper func
├── router.py
├── schemas.py - pydantic schemas
└── utils.py
Caution
External API for rates - https://openexchangerates.org/
Changing the base currency is available only for paid plans.
Free plan support only USD base
Note
The "from" - query parameter by default assigned to "USD"
Note
Pydantic attempts to convert the value to a string, then passes the string to Decimal(v)
- async IO operations
- easy local development
- Dockerfile optimized for small size and fast builds with a non-root user
- Docker-compose for easy deployment
- environment with configured Redis cache
- redis cache
- pydantic model
- decimal in rates calculation
- pytest
- linters / format with ruff
- global custom exceptions
cp .env.example .env
docker network create app_exchange
docker-compose up -d --build
http://localhost:17000/docs
curl -X GET "http://127.0.0.1:17000/api/rates?from=USD&to=RUB&value=1"
or
curl -X GET "http://127.0.0.1:17000/api/rates?to=RUB&value=1"
docker compose exec app pytest -v