-
-
Notifications
You must be signed in to change notification settings - Fork 288
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #854 from sickelap/delegate_thumbnail_generation_t…
…o_external_service delegate thumbnails for raw images to external service
- Loading branch information
Showing
10 changed files
with
99 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,4 +13,5 @@ Faker==17.6.0 | |
isort==5.12.0 | ||
setuptools==67.6.1 | ||
black==23.3.0 | ||
pyfakefs==5.2.0 | ||
pyfakefs==5.2.0 | ||
pytest==7.3.1 |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import gevent | ||
from flask import Flask, request | ||
from gevent.pywsgi import WSGIServer | ||
from wand.image import Image | ||
|
||
app = Flask(__name__) | ||
|
||
|
||
def log(message): | ||
print("thumbnail: {}".format(message)) | ||
|
||
|
||
@app.route("/", methods=["POST"]) | ||
def create_thumbnail(): | ||
try: | ||
data = request.get_json() | ||
source = data["source"] | ||
destination = data["destination"] | ||
height = data["height"] | ||
except Exception: | ||
return "", 400 | ||
log(f"creating for source={source} height={height}") | ||
with Image(filename=source) as img: | ||
with img.clone() as thumbnail: | ||
thumbnail.format = "webp" | ||
thumbnail.transform(resize=f"x{height}") | ||
thumbnail.compression_quality = 95 | ||
thumbnail.auto_orient() | ||
thumbnail.save(filename=destination) | ||
log(f"created at location={destination}") | ||
return {"thumbnail": destination}, 201 | ||
|
||
|
||
if __name__ == "__main__": | ||
log("service starting") | ||
server = WSGIServer(("0.0.0.0", 8003), app) | ||
server_thread = gevent.spawn(server.serve_forever) | ||
gevent.joinall([server_thread]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
samples/* | ||
!samples/.gitkeep | ||
!samples/README.md |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
place any *image* files in this directory that you want to use as test data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import os | ||
|
||
from pytest import fixture | ||
|
||
from service.thumbnail.main import app | ||
|
||
|
||
@fixture() | ||
def client(): | ||
return app.test_client() | ||
|
||
|
||
def test_must_fail_when_passing_empty_string(client): | ||
response = client.post("/", data="") | ||
assert response.status_code == 400 | ||
|
||
|
||
def test_must_fail_when_passing_invalid_json(client): | ||
response = client.post("/", data="invalid json") | ||
assert response.status_code == 400 | ||
|
||
|
||
def test_must_fail_when_passing_incomplete_json(client): | ||
invalid_payloads = [ | ||
{"source": "foo"}, | ||
{"destination": "/tmp/result.webp"}, | ||
{"height": 100}, | ||
{"source": "foo", "destination": "/tmp/result.webp"}, | ||
{"destination": "/tmp/result.webp", "height": 100}, | ||
{"height": 100, "source": "foo"}, | ||
] | ||
for payload in invalid_payloads: | ||
response = client.post("/", json=payload) | ||
assert response.status_code == 400 | ||
|
||
|
||
def test_should_create_thumbnail(client): | ||
samples_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "samples") | ||
samples = [f for f in os.listdir(samples_dir) if f not in [".gitkeep", "README.md"]] | ||
thumbnail_path = "/tmp/result.webp" | ||
for sample in samples: | ||
if os.path.exists(thumbnail_path): | ||
os.remove(thumbnail_path) | ||
source = os.path.join(samples_dir, sample) | ||
json = {"source": source, "destination": thumbnail_path, "height": 100} | ||
response = client.post("/", json=json) | ||
assert response.status_code == 201 |