Skip to content

Commit 9582968

Browse files
committed
refactor a bit, linting, introduce setuptools-scm, fix a bunch of package meta stuff
1 parent 3b66809 commit 9582968

File tree

5 files changed

+89
-49
lines changed

5 files changed

+89
-49
lines changed

.github/workflows/pypi.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
name: "Publish PyPi package when a new tag is pushed"
3+
4+
on: # yamllint disable-line rule:truthy
5+
push:
6+
tags:
7+
- 'v*'
8+
9+
# https://docs.pypi.org/trusted-publishers/using-a-publisher/
10+
jobs:
11+
pypi-publish:
12+
name: "upload release to PyPI"
13+
runs-on: "ubuntu-latest"
14+
environment: "pypi-publish"
15+
permissions:
16+
id-token: "write"
17+
steps:
18+
# https://github.com/pypa/sampleproject/blob/main/.github/workflows/release.yml
19+
- name: "Checkout"
20+
uses: "actions/checkout@v3"
21+
- name: "Set up Python"
22+
uses: "actions/setup-python@v4"
23+
with:
24+
python-version: '3.11'
25+
- name: "Install build dependencies"
26+
run: "python -m pip install -U setuptools wheel build"
27+
- name: "Build"
28+
run: "python -m build ."
29+
- name: "Publish package distributions to PyPI"
30+
uses: "pypa/gh-action-pypi-publish@release/v1"
31+
...

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# vim
2+
*.swp
3+
14
# Byte-compiled / optimized / DLL files
25
__pycache__/
36
*.py[cod]

.pre-commit-config.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
default_language_version:
3+
python: "python3"
4+
repos:
5+
- repo: "https://github.com/astral-sh/ruff-pre-commit"
6+
rev: "v0.6.9"
7+
hooks:
8+
- id: "ruff"
9+
args: ["--fix"]
10+
- id: "ruff-format"
11+
- repo: "https://github.com/pre-commit/mirrors-mypy"
12+
rev: 'v1.11.2'
13+
hooks:
14+
- id: "mypy"
15+
additional_dependencies:
16+
- "typer-slim"
17+
- "bornhack-media-archive-client"
18+
...

pyproject.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[build-system]
2-
requires = ["setuptools"]
2+
requires = ["setuptools>=64", "setuptools_scm>=8"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
@@ -13,13 +13,13 @@ classifiers = [
1313
]
1414
dependencies = [
1515
"typer-slim==0.12.5",
16-
"bma-client",
16+
"bornhack-media-archive-client",
1717
]
1818
description = "BornHack Media Archive CLI Tool"
1919
name = "bma-cli"
20-
version = "0.1"
2120
readme = "README.md"
22-
requires-python = ">=3.10"
21+
requires-python = ">=3.11"
22+
dynamic = ["version"]
2323

2424
[project.scripts]
2525
"bma" = "bma_cli:app"
@@ -35,6 +35,8 @@ homepage = "https://github.com/bornhack/bma-cli-python"
3535
[tool.setuptools]
3636
package-dir = {"" = "src"}
3737

38+
[tool.setuptools_scm]
39+
3840
[tool.setuptools.packages.find]
3941
where = ["src"]
4042

src/bma_cli.py

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66
import time
77
import uuid
8-
from io import BytesIO
8+
from importlib.metadata import version as get_version
99
from pathlib import Path
1010
from typing import TypedDict
1111

@@ -56,6 +56,13 @@ class ImageExifExtractionJob(BaseJob):
5656
"""Represent an ImageExifExtractionJob."""
5757

5858

59+
@app.command()
60+
def version() -> None:
61+
"""Return the version of bma-cli and bma-client."""
62+
click.echo(f"bma-cli version {get_version('bma-cli')}")
63+
click.echo(f"bma-client version {get_version('bma-client')}")
64+
65+
5966
@app.command()
6067
def fileinfo(file_uuid: uuid.UUID) -> None:
6168
"""Get info for a file."""
@@ -66,12 +73,11 @@ def fileinfo(file_uuid: uuid.UUID) -> None:
6673

6774
@app.command()
6875
def jobs() -> None:
69-
"""Get info on assigned jobs."""
76+
"""Get info on unfinished jobs."""
7077
client, config = init()
71-
jobs = client.get_jobs(job_filter=f"?limit=0&finished=false&client_uuid={client.uuid}")
78+
jobs = client.get_jobs(job_filter="?limit=0&finished=false")
7279
click.echo(json.dumps(jobs))
73-
click.echo(f"Total {len(jobs)} unfinished jobs assigned to this client.")
74-
80+
click.echo(f"Total {len(jobs)} unfinished jobs.", err=True)
7581

7682

7783
@app.command()
@@ -88,22 +94,24 @@ def grind() -> None:
8894
"""Get jobs from the server and handle them."""
8995
client, config = init()
9096

91-
# get any unfinished jobs already assigned to this client
92-
jobs = client.get_jobs(job_filter=f"?limit=0&finished=false&client_uuid={client.uuid}")
93-
if not jobs:
94-
# no unfinished jobs assigned to this client, ask for new assignment
95-
jobs = client.get_job_assignment()
96-
97-
if not jobs:
98-
click.echo("Nothing to do.")
99-
return
100-
101-
# loop over jobs and handle each
102-
for job in jobs:
103-
# make sure we have the original file locally
104-
fileinfo = client.download(file_uuid=job["basefile_uuid"])
105-
path = Path(config["path"], fileinfo["filename"])
106-
handle_job(f=path, job=job, client=client, config=config)
97+
while True:
98+
# get any unfinished jobs already assigned to this client
99+
jobs = client.get_jobs(job_filter=f"?limit=0&finished=false&client_uuid={client.uuid}")
100+
if not jobs:
101+
# no unfinished jobs assigned to this client, ask for new assignment
102+
jobs = client.get_job_assignment()
103+
104+
if not jobs:
105+
click.echo("Nothing left to do.")
106+
return
107+
108+
# loop over jobs and handle each
109+
click.echo(f"Processing {len(jobs)} jobs for file {jobs[0]['basefile_uuid']} ...")
110+
for job in jobs:
111+
# make sure we have the original file locally
112+
fileinfo = client.download(file_uuid=job["basefile_uuid"])
113+
path = Path(config["path"], fileinfo["filename"])
114+
handle_job(f=path, job=job, client=client, config=config)
107115
click.echo("Done!")
108116

109117

@@ -121,7 +129,7 @@ def upload(files: list[str]) -> None:
121129
if metadata["jobs_unfinished"] == 0:
122130
continue
123131

124-
# it seems there is work to do! ask for assignment
132+
# it seems there is work to do for the newly uploaded file!
125133
jobs = client.get_job_assignment(file_uuid=metadata["uuid"])
126134
if not jobs:
127135
click.echo("No unassigned unfinished jobs found for this file.")
@@ -157,29 +165,7 @@ def handle_job(f: Path, job: ImageConversionJob | ImageExifExtractionJob, client
157165
click.echo(f"Handling job {job['job_type']} {job['job_uuid']} ...")
158166
start = time.time()
159167
result = client.handle_job(job=job, orig=f)
160-
logger.debug(f"Getting result took {time.time() - start} seconds")
161-
if not result:
162-
click.echo(f"No result returned for job {job['job_type']} {job['uuid']} - skipping ...")
163-
return
164-
165-
# got job result, do whatever is needed depending on job_type
166-
if job["job_type"] == "ImageConversionJob":
167-
image, exif = result
168-
filename = job["job_uuid"] + "." + job["filetype"].lower()
169-
logger.debug(f"Encoding result as {job['filetype']} ...")
170-
start = time.time()
171-
with BytesIO() as buf:
172-
image.save(buf, format=job["filetype"], exif=exif, lossless=False, quality=90)
173-
logger.debug(f"Encoding result took {time.time() - start} seconds")
174-
client.upload_job_result(job_uuid=job["job_uuid"], buf=buf, filename=filename)
175-
elif job["job_type"] == "ImageExifExtractionJob":
176-
logger.debug(f"Got exif data {result}")
177-
with BytesIO() as buf:
178-
buf.write(json.dumps(result).encode())
179-
client.upload_job_result(job_uuid=job["job_uuid"], buf=buf, filename="exif.json")
180-
else:
181-
logger.error("Unsupported job type")
182-
raise typer.Exit(1)
168+
logger.debug(f"Getting result took {time.time() - start} seconds: {result}")
183169

184170

185171
def load_config() -> dict[str, str]:

0 commit comments

Comments
 (0)