This is a RESTful API able to upload and apply effects to images using Django Rest Framework that has
- Docker to run all the needed services
- Uses Cloudflare R2 with boto3 to store images
- Celery to perform transforms on the background as tasks, without blocking the app
- Redis as Celery broker and results backend, as well as application cache store for recent data.
- JWT for authentication
- Unit tests
The images are private to the users and retrieving image details returns a temporary URL that grants access for a period of time.
to be able to use this repo you should first get a Cloudflare R2 account and create a bucket for storing the images. From there you should get the necesary keys to store in an .env file:
R2_STORAGE_URI=`<your-account-url>`
R2_ACCOUNT_ID=`<your-account-id>`
R2_BUCKET_NAME=`<bucket-name>`
R2_API_TOKEN=`<your-api-token>`
AWS_SECRET_ACCESS_KEY=`<secret-access-key>`
AWS_ACCESS_KEY_ID=`<secret-key-id>`you'll need also your postgres credentials
POSTGRES_DB=`<your-db-name>`
POSTGRES_USER=`<your-user-name>`
POSTGRES_PASSWORD=`<your-password>`a Django secret key
SECRET_KEY=`<secret>`and the Redis urls needed for Celery and the in memory cache
REDIS_CACHE_URL='redis://redis:6379/1'
CELERY_BROKER='redis://redis:6379/0'Then run from the projects root:
pipenv install --system
docker compose up -d --build
docker compose exec web python manage.py migratePOST hostname:port/api/v1/accounts/register
body: {
'password',
'username',
'email'
}
response: {
'refresh',
'access'
}POST hostname:port/api/v1/accounts/token
body: {
'password',
'username',
}
response: {
'refresh',
'access'
}POST hostname:port/api/v1/accounts/token/refresh
body: {
'password',
'username',
}
response: {
'access'
}POST hostname:port/api/v1/accounts/logout
headers: {
'Authorization': 'Bearer <accesstoken>'
}POST hostname:port/api/v1/images
headers: {
'Authorization': 'Bearer: <access-token>'
}
form-data: {
'image': '<filepath>'
}specified by UUID which is the image id
GET hostname:port/api/v1/images/<uuid>
headers: {
'Authorization': 'Bearer: <access-token>'
}
response: {
'id'
'file_key', # internal R2 key
'user_id',
'created_at',
'url',
}returns a list of paginated image details that the user owns. Query params will fall back to defaults if missing or invalid
GET hostname:port/api/v1/images
query_params: {
'pages', #optional
'page_size', #optional
'limit' #optional
}
headers: {
'Authorization': 'Bearer: <access-token>'
}the response is a json array with all the pages with the image details, each image has a access url to be able to use it for a period of time
DELETE hostname:port/api/v1/images/<uuid>
headers: {
'Authorization': 'Bearer: <access-token>'
}apply transforms to image and receive the image details as response, all the listed effects are optional, only a one is needed to work
PUT hostname:port/api/v1/images/<uuid>/transform
headers: {
'Authorization': 'Bearer: <access-token>'
}
body: {
resize: {
width,
height
}
crop: {
width,
height,
x,
y
}
rotate: Float
flip: Char # either lr (left-right) or tb (top-bottom)
filters: {
sepia,
grayscale
}
}
response: {
task_id
}this will create a background task that you can poll using task_id
GET hostname:port/api/v1/images/tasks/<task_id>
headers: {
'Authorization': 'Bearer: <access-token>'
}
response: {
task_id,
status,
# if finished
result: {
success,
error,
data
}
}with docker container running execute:
docker compose exec web python manage.py test
pytest -m api/v1/images/tests/test_effects.py