Skip to content

Commit a675af0

Browse files
authored
Merge pull request #36 from dlcs/feature/composite_id
Handle "compositeId" parameter
2 parents 2d6911e + 62d1ce8 commit a675af0

5 files changed

Lines changed: 30 additions & 15 deletions

File tree

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Additionally, the project uses:
2424
The project ships with a [`docker-compose.yml`](docker-compose.yml) that can be used to get a local version of the component running:
2525

2626
```bash
27-
docker-compose up
27+
docker compose up
2828
```
2929

3030
> Note that for the Composite Handler to be able to interact with the target S3 bucket, the Docker Compose assumes that the `AWS_PROFILE` environment variable has been set and a valid AWS session is available.
@@ -58,7 +58,7 @@ The administrator user can be used to browse the database and manage the queue (
5858
There are 3 possible entrypoints to make the above easier:
5959

6060
* `entrypoint.sh` - this will wait for Postgres to be available and run `manage.py migrate` and `manage.py createcachetable` if `MIGRATE=True`. It will run `manage.py createsuperuser` is `INIT_SUPERUSER=True` (also needs `DJANGO_SUPERUSER_*` envvars)
61-
* `entrypoint-api.sh` - this runs above then `python manage.py runserver 0.0.0.0:8000`
61+
* `entrypoint-api.sh` - this runs above then starts nginx instance fronting gunicorn process
6262
* `entrypoint-worker.sh` - this runs above then `python manage.py qcluster`
6363

6464
## Configuration
@@ -88,6 +88,7 @@ The following list of environment variables are supported:
8888
| `ENGINE_WORKER_MAX_ATTEMPTS` | `0` | Engine | The number of processing attempts a single task will undergo before it is abandoned. Setting this value to `0` will cause a task to be retried forever. |
8989
| `MIGRATE` | None | API, Engine | If "True" will run migrations + createcachetable on startup if entrypoint used. |
9090
| `INIT_SUPERUSER` | None | API, Engine | If "True" will attempt to create superuser. Needs standard Django envvars to be set (e.g. `DJANGO_SUPERUSER_USERNAME`, `DJANGO_SUPERUSER_EMAIL`, `DJANGO_SUPERUSER_PASSWORD`) if entrypoint used. |
91+
| `GUNICORN_WORKERS` | `2` | API | The value of [`--workers`](https://docs.gunicorn.org/en/stable/run.html) arg when running gunicorn |
9192

9293
Note that in order to access the S3 bucket, the Composite Handler assumes that valid AWS credentials are available in the environment - this can be in the former of [environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html), or in the form of ambient credentials.
9394

@@ -96,15 +97,15 @@ Note that in order to access the S3 bucket, the Composite Handler assumes that v
9697
The project ships with a [`Dockerfile`](./Dockerfile):
9798

9899
```bash
99-
docker build -t dlcs/composite-handler:latest .
100+
docker build -t dlcs/composite-handler:local .
100101
```
101102

102103
This will produce a single image that can be used to execute any of the supported Django commands, including running the API and the engine:
103104

104105
```bash
105-
docker run dlcs/composite-handler:latest python manage.py migrate # Apply any pending DB schema changes
106-
docker run dlcs/composite-handler:latest python manage.py createcachetable # Create the cache table (if it doesn't exist)
107-
docker run dlcs/composite-handler:latest python manage.py runserver 0.0.0.0:8000 # Run the API
108-
docker run dlcs/composite-handler:latest python manage.py qcluster # Run the engine
109-
docker run dlcs/composite-handler:latest python manage.py qmonitor # Monitor the workers
106+
docker run dlcs/composite-handler:local python manage.py migrate # Apply any pending DB schema changes
107+
docker run dlcs/composite-handler:local python manage.py createcachetable # Create the cache table (if it doesn't exist)
108+
docker run --env-file .env -it --rm dlcs/composite-handler:local /srv/dlcs/entrypoint-api.sh # Run the API
109+
docker run --env-file .env -it --rm dlcs/composite-handler:local /srv/dlcs/entrypoint-worker.sh # Run the engine
110+
docker run dlcs/composite-handler:local python manage.py qmonitor # Monitor the workers
110111
```

src/app/api/schemas/member.schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
},
7272
"incrementSeed": {
7373
"type": "integer"
74+
},
75+
"compositeId": {
76+
"type": "string"
7477
}
7578
},
7679
"required": [

src/app/engine/builder.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class MemberBuilder:
55
STATIC_FIELDS = {"mediaType": "image/jpeg", "family": "I"}
66

7-
STRIP_FIELDS = ["@type", "originFormat", "incrementSeed"]
7+
STRIP_FIELDS = ["@type", "originFormat", "incrementSeed", "compositeId"]
88

99
FORMAT_FIELDS = [
1010
"id",
@@ -26,7 +26,8 @@ def __init__(self, template):
2626
def __build_template(self, original_template):
2727
template = dict(original_template) | self.STATIC_FIELDS
2828
for strip_field in self.STRIP_FIELDS:
29-
template.pop(strip_field)
29+
if strip_field in template:
30+
template.pop(strip_field)
3031
return template
3132

3233
def build_member(self, dlcs_uri):

src/app/engine/s3.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ def __build_bucket_base_url(self):
2626
else:
2727
return f"https://s3.amazonaws.com/{self._bucket_name}"
2828

29-
def put_images(self, submission_id, images):
29+
def put_images(self, images, submission_id, composite_id, customer_id, space_id):
3030
s3_uris = []
3131

32+
key_prefix = self.__get_key_prefix(
33+
submission_id, composite_id, customer_id, space_id
34+
)
35+
3236
with tqdm.tqdm(
3337
desc=f"[{submission_id}] Upload images to S3",
3438
unit=" image",
@@ -39,14 +43,17 @@ def put_images(self, submission_id, images):
3943
# same order as the list of images provided to it. '.map(...)' gives us that,
4044
# whilst '.submit(...)' does not.
4145
for s3_uri in executor.map(
42-
self.__put_image, repeat(submission_id), images
46+
self.__put_image, repeat(key_prefix), images
4347
):
4448
s3_uris.append(s3_uri)
4549
progress_bar.update(1)
4650
return s3_uris
4751

48-
def __put_image(self, submission_id, image):
49-
object_key = f"{self._object_key_prefix}/{submission_id}/{os.path.basename(image.filename)}"
52+
def __get_key_prefix(self, submission_id, composite_id, customer, space):
53+
return f"{self._object_key_prefix}/{customer}/{space}/{composite_id or submission_id}"
54+
55+
def __put_image(self, key_prefix, image):
56+
object_key = f"{key_prefix}/{os.path.basename(image.filename)}"
5057
with open(image.filename, "rb") as file:
5158
self._client.put_object(Bucket=self._bucket_name, Key=object_key, Body=file)
5259
return f"{self._bucket_base_url}/{object_key}"

src/app/engine/tasks.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ def __rasterize_composite(member, pdf_path):
5757

5858
def __push_images_to_dlcs(member, images):
5959
__update_status(member, "PUSHING_TO_DLCS", image_count=len(images))
60-
return s3_client.put_images(member.id, images)
60+
composite_id = member.json_data.get("compositeId")
61+
customer = member.collection.customer
62+
space = member.json_data["space"]
63+
return s3_client.put_images(images, member.id, composite_id, customer, space)
6164

6265

6366
def __build_dlcs_requests(member, dlcs_uris):

0 commit comments

Comments
 (0)