Skip to content

Commit 9fc1337

Browse files
committed
upload as image
Signed-off-by: Isabella do Amaral <[email protected]>
1 parent b773b29 commit 9fc1337

File tree

7 files changed

+152
-50
lines changed

7 files changed

+152
-50
lines changed

e2e/quay-lite/config.yaml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ DATA_MODEL_CACHE_CONFIG:
44
primary:
55
host: quay-redis
66
SUPER_USERS:
7-
- admin
8-
- user1
7+
- admin
8+
- user1
99
AUTHENTICATION_TYPE: Database
1010
DB_URI: postgresql://quay:quay@quay-postgresql:5432/quay
1111
BUILDLOGS_REDIS:
@@ -15,15 +15,15 @@ USER_EVENTS_REDIS:
1515
host: quay-redis
1616
port: 6379
1717
BITTORRENT_FILENAME_PEPPER: 0ee18f90-5b6d-42d2-ab5e-ec9fcd846272
18-
DATABASE_SECRET_KEY: '30060361640793187613697366923211113205676925445650250274752125083971638376224'
18+
DATABASE_SECRET_KEY: "30060361640793187613697366923211113205676925445650250274752125083971638376224"
1919
DEFAULT_TAG_EXPIRATION: 2w
2020
DISTRIBUTED_STORAGE_CONFIG:
2121
default:
22-
- LocalStorage
23-
- storage_path: /datastorage/registry
22+
- LocalStorage
23+
- storage_path: /datastorage/registry
2424
DISTRIBUTED_STORAGE_DEFAULT_LOCATIONS: []
2525
DISTRIBUTED_STORAGE_PREFERENCE:
26-
- default
26+
- default
2727
ENTERPRISE_LOGO_URL: /static/img/quay-horizontal-color.svg
2828
EXTERNAL_TLS_TERMINATION: true
2929
FEATURE_ANONYMOUS_ACCESS: true
@@ -59,13 +59,13 @@ REPO_MIRROR_TLS_VERIFY: true
5959
SETUP_COMPLETE: true
6060
SIGNING_ENGINE: gpg2
6161
TAG_EXPIRATION_OPTIONS:
62-
- 0s
63-
- 1d
64-
- 1w
65-
- 2w
66-
- 4w
62+
- 0s
63+
- 1d
64+
- 1w
65+
- 2w
66+
- 4w
6767
TEAM_RESYNC_STALE_TIME: 60m
68-
TESTING: false
68+
TESTING: true
6969
USERFILES_LOCATION: default
7070
USERFILES_PATH: userfiles/
7171
USE_CDN: false
@@ -77,4 +77,4 @@ CORS_ORIGIN:
7777
- "http://localhost:9000"
7878
FEATURE_UI_V2: True
7979
FEATURE_USER_METADATA: True
80-
IGNORE_UNKNOWN_MEDIATYPES: True
80+
IGNORE_UNKNOWN_MEDIATYPES: false

e2e/quay-lite/quay-app-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ metadata:
44
name: quay-app-config
55
type: Opaque
66
data:
7-
config.yaml: REFUQV9NT0RFTF9DQUNIRV9DT05GSUc6CiAgZW5naW5lOiByZWRpcwogIHJlZGlzX2NvbmZpZzoKICAgIHByaW1hcnk6CiAgICAgIGhvc3Q6IHF1YXktcmVkaXMKU1VQRVJfVVNFUlM6Ci0gYWRtaW4KLSB1c2VyMQpBVVRIRU5USUNBVElPTl9UWVBFOiBEYXRhYmFzZQpEQl9VUkk6IHBvc3RncmVzcWw6Ly9xdWF5OnF1YXlAcXVheS1wb3N0Z3Jlc3FsOjU0MzIvcXVheQpCVUlMRExPR1NfUkVESVM6CiAgaG9zdDogcXVheS1yZWRpcwogIHBvcnQ6IDYzNzkKVVNFUl9FVkVOVFNfUkVESVM6CiAgaG9zdDogcXVheS1yZWRpcwogIHBvcnQ6IDYzNzkKQklUVE9SUkVOVF9GSUxFTkFNRV9QRVBQRVI6IDBlZTE4ZjkwLTViNmQtNDJkMi1hYjVlLWVjOWZjZDg0NjI3MgpEQVRBQkFTRV9TRUNSRVRfS0VZOiAnMzAwNjAzNjE2NDA3OTMxODc2MTM2OTczNjY5MjMyMTExMTMyMDU2NzY5MjU0NDU2NTAyNTAyNzQ3NTIxMjUwODM5NzE2MzgzNzYyMjQnCkRFRkFVTFRfVEFHX0VYUElSQVRJT046IDJ3CkRJU1RSSUJVVEVEX1NUT1JBR0VfQ09ORklHOgogIGRlZmF1bHQ6CiAgLSBMb2NhbFN0b3JhZ2UKICAtIHN0b3JhZ2VfcGF0aDogL2RhdGFzdG9yYWdlL3JlZ2lzdHJ5CkRJU1RSSUJVVEVEX1NUT1JBR0VfREVGQVVMVF9MT0NBVElPTlM6IFtdCkRJU1RSSUJVVEVEX1NUT1JBR0VfUFJFRkVSRU5DRToKLSBkZWZhdWx0CkVOVEVSUFJJU0VfTE9HT19VUkw6IC9zdGF0aWMvaW1nL3F1YXktaG9yaXpvbnRhbC1jb2xvci5zdmcKRVhURVJOQUxfVExTX1RFUk1JTkFUSU9OOiB0cnVlCkZFQVRVUkVfQU5PTllNT1VTX0FDQ0VTUzogdHJ1ZQpGRUFUVVJFX0FQUF9SRUdJU1RSWTogZmFsc2UKRkVBVFVSRV9BUFBfU1BFQ0lGSUNfVE9LRU5TOiB0cnVlCkZFQVRVUkVfQlVJTERfU1VQUE9SVDogZmFsc2UKRkVBVFVSRV9DSEFOR0VfVEFHX0VYUElSQVRJT046IHRydWUKRkVBVFVSRV9ESVJFQ1RfTE9HSU46IHRydWUKRkVBVFVSRV9NQUlMSU5HOiBmYWxzZQpGRUFUVVJFX1BBUlRJQUxfVVNFUl9BVVRPQ09NUExFVEU6IHRydWUKRkVBVFVSRV9SRVBPX01JUlJPUjogZmFsc2UKRkVBVFVSRV9SRVFVSVJFX1RFQU1fSU5WSVRFOiB0cnVlCkZFQVRVUkVfUkVTVFJJQ1RFRF9WMV9QVVNIOiBmYWxzZQpGRUFUVVJFX1NFQ1VSSVRZX05PVElGSUNBVElPTlM6IGZhbHNlCkZFQVRVUkVfU0VDVVJJVFlfU0NBTk5FUjogZmFsc2UKRkVBVFVSRV9VU0VSTkFNRV9DT05GSVJNQVRJT046IHRydWUKRkVBVFVSRV9VU0VSX0lOSVRJQUxJWkU6IHRydWUKRkVBVFVSRV9VU0VSX0NSRUFUSU9OOiB0cnVlCkZFQVRVUkVfVVNFUl9MT0dfQUNDRVNTOiB0cnVlCkZFQVRVUkVfUFJPWFlfQ0FDSEU6IHRydWUKR0lUSFVCX0xPR0lOX0NPTkZJRzoge30KR0lUSFVCX1RSSUdHRVJfQ09ORklHOiB7fQpHSVRMQUJfVFJJR0dFUl9LSU5EOiB7fQpMT0dfQVJDSElWRV9MT0NBVElPTjogZGVmYXVsdApNQUlMX0RFRkFVTFRfU0VOREVSOiBhZG1pbkBleGFtcGxlLmNvbQpNQUlMX1BPUlQ6IDU4NwpNQUlMX1VTRV9UTFM6IHRydWUKUFJFRkVSUkVEX1VSTF9TQ0hFTUU6IGh0dHAKUkVHSVNUUllfVElUTEU6IFJlZCBIYXQgUXVheSBMSVRFClJFR0lTVFJZX1RJVExFX1NIT1JUOiBSZWQgSGF0IFF1YXkgTElURQpSRVBPX01JUlJPUl9TRVJWRVJfSE9TVE5BTUU6IG51bGwKUkVQT19NSVJST1JfVExTX1ZFUklGWTogdHJ1ZQpTRVRVUF9DT01QTEVURTogdHJ1ZQpTSUdOSU5HX0VOR0lORTogZ3BnMgpUQUdfRVhQSVJBVElPTl9PUFRJT05TOgotIDBzCi0gMWQKLSAxdwotIDJ3Ci0gNHcKVEVBTV9SRVNZTkNfU1RBTEVfVElNRTogNjBtClRFU1RJTkc6IGZhbHNlClVTRVJGSUxFU19MT0NBVElPTjogZGVmYXVsdApVU0VSRklMRVNfUEFUSDogdXNlcmZpbGVzLwpVU0VfQ0ROOiBmYWxzZQpGRUFUVVJFX1FVT1RBX01BTkFHRU1FTlQ6IFRydWUKU0VSVkVSX0hPU1ROQU1FOiBsb2NhbGhvc3Q6NTAwMQpCUk9XU0VSX0FQSV9DQUxMU19YSFJfT05MWTogRmFsc2UKQ09SU19PUklHSU46CiAgLSAiaHR0cHM6Ly9zdGFnZS5mb28ucmVkaGF0LmNvbToxMzM3IgogIC0gImh0dHA6Ly9sb2NhbGhvc3Q6OTAwMCIKRkVBVFVSRV9VSV9WMjogVHJ1ZQpGRUFUVVJFX1VTRVJfTUVUQURBVEE6IFRydWUKSUdOT1JFX1VOS05PV05fTUVESUFUWVBFUzogVHJ1ZQo=
7+
config.yaml: REFUQV9NT0RFTF9DQUNIRV9DT05GSUc6CiAgZW5naW5lOiByZWRpcwogIHJlZGlzX2NvbmZpZzoKICAgIHByaW1hcnk6CiAgICAgIGhvc3Q6IHF1YXktcmVkaXMKU1VQRVJfVVNFUlM6CiAgLSBhZG1pbgogIC0gdXNlcjEKQVVUSEVOVElDQVRJT05fVFlQRTogRGF0YWJhc2UKREJfVVJJOiBwb3N0Z3Jlc3FsOi8vcXVheTpxdWF5QHF1YXktcG9zdGdyZXNxbDo1NDMyL3F1YXkKQlVJTERMT0dTX1JFRElTOgogIGhvc3Q6IHF1YXktcmVkaXMKICBwb3J0OiA2Mzc5ClVTRVJfRVZFTlRTX1JFRElTOgogIGhvc3Q6IHF1YXktcmVkaXMKICBwb3J0OiA2Mzc5CkJJVFRPUlJFTlRfRklMRU5BTUVfUEVQUEVSOiAwZWUxOGY5MC01YjZkLTQyZDItYWI1ZS1lYzlmY2Q4NDYyNzIKREFUQUJBU0VfU0VDUkVUX0tFWTogIjMwMDYwMzYxNjQwNzkzMTg3NjEzNjk3MzY2OTIzMjExMTEzMjA1Njc2OTI1NDQ1NjUwMjUwMjc0NzUyMTI1MDgzOTcxNjM4Mzc2MjI0IgpERUZBVUxUX1RBR19FWFBJUkFUSU9OOiAydwpESVNUUklCVVRFRF9TVE9SQUdFX0NPTkZJRzoKICBkZWZhdWx0OgogICAgLSBMb2NhbFN0b3JhZ2UKICAgIC0gc3RvcmFnZV9wYXRoOiAvZGF0YXN0b3JhZ2UvcmVnaXN0cnkKRElTVFJJQlVURURfU1RPUkFHRV9ERUZBVUxUX0xPQ0FUSU9OUzogW10KRElTVFJJQlVURURfU1RPUkFHRV9QUkVGRVJFTkNFOgogIC0gZGVmYXVsdApFTlRFUlBSSVNFX0xPR09fVVJMOiAvc3RhdGljL2ltZy9xdWF5LWhvcml6b250YWwtY29sb3Iuc3ZnCkVYVEVSTkFMX1RMU19URVJNSU5BVElPTjogdHJ1ZQpGRUFUVVJFX0FOT05ZTU9VU19BQ0NFU1M6IHRydWUKRkVBVFVSRV9BUFBfUkVHSVNUUlk6IGZhbHNlCkZFQVRVUkVfQVBQX1NQRUNJRklDX1RPS0VOUzogdHJ1ZQpGRUFUVVJFX0JVSUxEX1NVUFBPUlQ6IGZhbHNlCkZFQVRVUkVfQ0hBTkdFX1RBR19FWFBJUkFUSU9OOiB0cnVlCkZFQVRVUkVfRElSRUNUX0xPR0lOOiB0cnVlCkZFQVRVUkVfTUFJTElORzogZmFsc2UKRkVBVFVSRV9QQVJUSUFMX1VTRVJfQVVUT0NPTVBMRVRFOiB0cnVlCkZFQVRVUkVfUkVQT19NSVJST1I6IGZhbHNlCkZFQVRVUkVfUkVRVUlSRV9URUFNX0lOVklURTogdHJ1ZQpGRUFUVVJFX1JFU1RSSUNURURfVjFfUFVTSDogZmFsc2UKRkVBVFVSRV9TRUNVUklUWV9OT1RJRklDQVRJT05TOiBmYWxzZQpGRUFUVVJFX1NFQ1VSSVRZX1NDQU5ORVI6IGZhbHNlCkZFQVRVUkVfVVNFUk5BTUVfQ09ORklSTUFUSU9OOiB0cnVlCkZFQVRVUkVfVVNFUl9JTklUSUFMSVpFOiB0cnVlCkZFQVRVUkVfVVNFUl9DUkVBVElPTjogdHJ1ZQpGRUFUVVJFX1VTRVJfTE9HX0FDQ0VTUzogdHJ1ZQpGRUFUVVJFX1BST1hZX0NBQ0hFOiB0cnVlCkdJVEhVQl9MT0dJTl9DT05GSUc6IHt9CkdJVEhVQl9UUklHR0VSX0NPTkZJRzoge30KR0lUTEFCX1RSSUdHRVJfS0lORDoge30KTE9HX0FSQ0hJVkVfTE9DQVRJT046IGRlZmF1bHQKTUFJTF9ERUZBVUxUX1NFTkRFUjogYWRtaW5AZXhhbXBsZS5jb20KTUFJTF9QT1JUOiA1ODcKTUFJTF9VU0VfVExTOiB0cnVlClBSRUZFUlJFRF9VUkxfU0NIRU1FOiBodHRwClJFR0lTVFJZX1RJVExFOiBSZWQgSGF0IFF1YXkgTElURQpSRUdJU1RSWV9USVRMRV9TSE9SVDogUmVkIEhhdCBRdWF5IExJVEUKUkVQT19NSVJST1JfU0VSVkVSX0hPU1ROQU1FOiBudWxsClJFUE9fTUlSUk9SX1RMU19WRVJJRlk6IHRydWUKU0VUVVBfQ09NUExFVEU6IHRydWUKU0lHTklOR19FTkdJTkU6IGdwZzIKVEFHX0VYUElSQVRJT05fT1BUSU9OUzoKICAtIDBzCiAgLSAxZAogIC0gMXcKICAtIDJ3CiAgLSA0dwpURUFNX1JFU1lOQ19TVEFMRV9USU1FOiA2MG0KVEVTVElORzogdHJ1ZQpVU0VSRklMRVNfTE9DQVRJT046IGRlZmF1bHQKVVNFUkZJTEVTX1BBVEg6IHVzZXJmaWxlcy8KVVNFX0NETjogZmFsc2UKRkVBVFVSRV9RVU9UQV9NQU5BR0VNRU5UOiBUcnVlClNFUlZFUl9IT1NUTkFNRTogbG9jYWxob3N0OjUwMDEKQlJPV1NFUl9BUElfQ0FMTFNfWEhSX09OTFk6IEZhbHNlCkNPUlNfT1JJR0lOOgogIC0gImh0dHBzOi8vc3RhZ2UuZm9vLnJlZGhhdC5jb206MTMzNyIKICAtICJodHRwOi8vbG9jYWxob3N0OjkwMDAiCkZFQVRVUkVfVUlfVjI6IFRydWUKRkVBVFVSRV9VU0VSX01FVEFEQVRBOiBUcnVlCklHTk9SRV9VTktOT1dOX01FRElBVFlQRVM6IGZhbHNlCg==

e2e/test_cli.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ omlmd push localhost:5001/mmortari/mlartifact:v1 README.md --metadata tests/data
1717
DIR="tmp/a"
1818
omlmd pull localhost:5001/mmortari/mlartifact:v1 -o "$DIR" --plain-http
1919
file_count=$(find "$DIR" -type f | wc -l)
20-
if [ "$file_count" -eq 3 ]; then
21-
echo "Expected 3 files in $DIR, ok."
20+
if [ "$file_count" -eq 2 ]; then
21+
echo "Expected 2 files in $DIR, ok."
2222
else
23-
echo "Expected 3 files in $DIR, got $file_count, FAIL."
23+
echo "Expected 2 files in $DIR, got $file_count, FAIL."
2424
exit 1
2525
fi
2626

2727
DIR="tmp/b"
28-
omlmd pull localhost:5001/mmortari/mlartifact:v1 -o "$DIR" --media-types "application/x-mlmodel" --plain-http
28+
omlmd pull localhost:5001/mmortari/mlartifact:v1 -o "$DIR" --media-types "application/vnd.oci.image.layer.v1.tar" --plain-http
2929
file_count=$(find "$DIR" -type f | wc -l)
3030
if [ "$file_count" -eq 1 ]; then
3131
echo "Expected 1 file in $DIR, ok."

omlmd/cli.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ def crawl(plain_http: bool, targets: tuple[str]):
7373
required=True,
7474
type=click.Path(path_type=Path, exists=True, resolve_path=True),
7575
)
76+
@click.option(
77+
"--as-artifact",
78+
is_flag=True,
79+
help="Push as an artifact (default is as a blob)",
80+
)
7681
@cloup.option_group(
7782
"Metadata options",
7883
cloup.option(
@@ -88,6 +93,7 @@ def push(
8893
plain_http: bool,
8994
target: str,
9095
path: Path,
96+
as_artifact: bool,
9197
metadata: Path | None,
9298
empty_metadata: bool,
9399
):
@@ -96,4 +102,6 @@ def push(
96102
if empty_metadata:
97103
logger.warning(f"Pushing to {target} with empty metadata.")
98104
md = deserialize_mdfile(metadata) if metadata else {}
99-
click.echo(Helper.from_default_registry(plain_http).push(target, path, **md))
105+
click.echo(
106+
Helper.from_default_registry(plain_http).push(target, path, as_artifact, **md)
107+
)

omlmd/constants.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
from oras.defaults import default_blob_media_type
2+
13
FILENAME_METADATA_JSON = "model_metadata.omlmd.json"
2-
MIME_APPLICATION_CONFIG = "application/x-config"
34
MIME_APPLICATION_MLMODEL = "application/x-mlmodel"
5+
MIME_APPLICATION_MLMETADATA = "application/x-mlmetadata+json"
6+
MIME_BLOB = default_blob_media_type
7+
MIME_MANIFEST_CONFIG = "application/vnd.oci.image.config.v1+json"

omlmd/helpers.py

Lines changed: 80 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from __future__ import annotations
22

3+
import json
34
import logging
45
import os
6+
import platform
7+
import tarfile
58
import urllib.request
69
from collections.abc import Sequence
710
from dataclasses import dataclass, field
@@ -10,8 +13,10 @@
1013

1114
from .constants import (
1215
FILENAME_METADATA_JSON,
13-
MIME_APPLICATION_CONFIG,
16+
MIME_APPLICATION_MLMETADATA,
1417
MIME_APPLICATION_MLMODEL,
18+
MIME_BLOB,
19+
MIME_MANIFEST_CONFIG,
1520
)
1621
from .listener import Event, Listener, PushEvent
1722
from .model_metadata import ModelMetadata
@@ -20,6 +25,18 @@
2025
logger = logging.getLogger(__name__)
2126

2227

28+
def get_arch() -> str:
29+
mac = platform.machine()
30+
if mac == "x86_64":
31+
return "amd64"
32+
if mac == "arm64":
33+
return "arm64"
34+
if mac == "aarch64":
35+
return "arm64"
36+
msg = f"Unsupported architecture: {platform.machine()}"
37+
raise NotImplementedError(msg)
38+
39+
2340
def download_file(uri: str):
2441
file_name = os.path.basename(uri)
2542
urllib.request.urlretrieve(uri, file_name)
@@ -41,39 +58,76 @@ def push(
4158
self,
4259
target: str,
4360
path: Path | str,
61+
as_artifact: bool = False,
4462
**kwargs,
4563
):
4664
owns_meta = True
4765
if isinstance(path, str):
4866
path = Path(path)
4967

5068
meta_path = path.parent / FILENAME_METADATA_JSON
51-
if not kwargs and meta_path.exists():
69+
if meta_path.exists():
5270
owns_meta = False
5371
logger.warning("Reusing intermediate metadata files.")
5472
logger.debug(f"{meta_path}")
55-
with open(meta_path, "r") as f:
56-
model_metadata = ModelMetadata.from_json(f.read())
57-
elif meta_path.exists():
58-
err = dedent(f"""
59-
OMLMD intermediate metadata files found at '{meta_path}'.
60-
Cannot resolve with conflicting keyword args: {kwargs}.
61-
You can reuse the existing metadata by omitting any keywords.
62-
If that was NOT intended, please REMOVE that file from your environment before re-running.
63-
64-
Note for advanced users: if merging keys with existing metadata is desired, you should create a Feature Request upstream: https://github.com/containers/omlmd""")
65-
raise RuntimeError(err)
73+
model_metadata = ModelMetadata(**json.loads(meta_path.read_bytes()))
74+
if kwargs and ModelMetadata.from_dict(kwargs) != model_metadata:
75+
err = dedent(f"""
76+
OMLMD intermediate metadata files found at '{meta_path}'.
77+
Cannot resolve with conflicting keyword args: {kwargs}.
78+
You can reuse the existing metadata by omitting any keywords.
79+
If that was NOT intended, please REMOVE that file from your environment before re-running.
80+
81+
Note for advanced users: if merging keys with existing metadata is desired, you should create a Feature Request upstream: https://github.com/containers/omlmd""")
82+
raise RuntimeError(err)
6683
else:
6784
model_metadata = ModelMetadata.from_dict(kwargs)
68-
meta_path.write_text(model_metadata.to_json())
85+
meta_path.write_text(json.dumps(model_metadata.to_dict()))
86+
87+
owns_model_tar = False
88+
owns_md_tar = False
89+
manifest_path = path.parent / "manifest.json"
90+
model_tar = None
91+
meta_tar = None
92+
if not as_artifact:
93+
manifest_path.write_text(
94+
json.dumps(
95+
{
96+
"architecture": get_arch(),
97+
"os": "linux",
98+
}
99+
)
100+
)
101+
config = f"{manifest_path}:{MIME_MANIFEST_CONFIG}"
102+
model_tar = path.parent / f"{path.stem}.tar"
103+
meta_tar = path.parent / f"{meta_path.stem}.tar"
104+
if not model_tar.exists():
105+
owns_model_tar = True
106+
with tarfile.open(model_tar, "w") as tf:
107+
tf.add(path, arcname=path.name)
108+
if not meta_tar.exists():
109+
owns_md_tar = True
110+
with tarfile.open(meta_tar, "w:gz") as tf:
111+
tf.add(meta_path, arcname=meta_path.name)
112+
files = [
113+
f"{model_tar}:{MIME_BLOB}",
114+
f"{meta_tar}:{MIME_BLOB}+gzip",
115+
]
116+
else:
117+
manifest_path.write_text(
118+
json.dumps(
119+
{
120+
"artifactType": MIME_APPLICATION_MLMODEL,
121+
}
122+
)
123+
)
124+
config = f"{manifest_path}:{MIME_APPLICATION_MLMODEL}"
125+
files = [
126+
f"{path}:{MIME_APPLICATION_MLMODEL}",
127+
f"{meta_path}:{MIME_APPLICATION_MLMETADATA}",
128+
]
69129

70-
config = f"{meta_path}:{MIME_APPLICATION_CONFIG}"
71-
files = [
72-
f"{path}:{MIME_APPLICATION_MLMODEL}",
73-
config,
74-
]
75130
try:
76-
# print(target, files, model_metadata.to_annotations_dict())
77131
result = self._registry.push(
78132
target=target,
79133
files=files,
@@ -88,6 +142,12 @@ def push(
88142
finally:
89143
if owns_meta:
90144
meta_path.unlink()
145+
if owns_model_tar:
146+
assert isinstance(model_tar, Path)
147+
model_tar.unlink()
148+
if owns_md_tar:
149+
assert isinstance(meta_tar, Path)
150+
meta_tar.unlink()
91151

92152
def pull(
93153
self, target: str, outdir: Path | str, media_types: Sequence[str] | None = None

tests/test_helpers.py

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
1+
import io
12
import json
23
import subprocess
4+
import tarfile
35
import tempfile
46
import typing as t
57
from hashlib import sha256
68
from pathlib import Path
79

810
import pytest
911

10-
from omlmd.constants import MIME_APPLICATION_MLMODEL
12+
from omlmd.constants import MIME_BLOB
1113
from omlmd.helpers import Helper
1214
from omlmd.listener import Event, Listener
1315
from omlmd.model_metadata import ModelMetadata, deserialize_mdfile
1416
from omlmd.provider import OMLMDRegistry
1517

1618

19+
def untar(tar: Path, out: Path):
20+
out.write_bytes(
21+
t.cast(io.BufferedReader, tarfile.open(tar, "r:*").extractfile(tar.stem)).read()
22+
)
23+
24+
1725
def test_call_push_using_md_from_file(mocker):
1826
helper = Helper()
1927
mocker.patch.object(helper, "push", return_value=None)
@@ -100,12 +108,33 @@ def test_push_pull_chunked(tmp_path, target):
100108

101109
omlmd.push(target, temp, **md)
102110
omlmd.pull(target, tmp_path)
103-
assert len(list(tmp_path.iterdir())) == 3
104-
assert tmp_path.joinpath(temp.name).stat().st_size == base_size
111+
files = list(tmp_path.iterdir())
112+
print(files)
113+
assert len(files) == 2
114+
print(tmp_path)
115+
out = tmp_path.joinpath(temp.name)
116+
untar(out.with_suffix(".tar"), out)
117+
assert temp.stat().st_size == base_size
105118
finally:
106119
temp.unlink()
107120

108121

122+
@pytest.mark.e2e
123+
def test_e2e_push_pull_as_artifact(tmp_path, target):
124+
omlmd = Helper()
125+
omlmd.push(
126+
target,
127+
Path(__file__).parent / ".." / "README.md",
128+
as_artifact=True,
129+
name="mnist",
130+
description="Lorem ipsum",
131+
author="John Doe",
132+
accuracy=0.987,
133+
)
134+
omlmd.pull(target, tmp_path)
135+
assert len(list(tmp_path.iterdir())) == 2
136+
137+
109138
@pytest.mark.e2e
110139
def test_e2e_push_pull(tmp_path, target):
111140
omlmd = Helper()
@@ -118,7 +147,7 @@ def test_e2e_push_pull(tmp_path, target):
118147
accuracy=0.987,
119148
)
120149
omlmd.pull(target, tmp_path)
121-
assert len(list(tmp_path.iterdir())) == 3
150+
assert len(list(tmp_path.iterdir())) == 2
122151

123152

124153
@pytest.mark.e2e
@@ -132,7 +161,7 @@ def test_e2e_push_pull_with_filters(tmp_path, target):
132161
author="John Doe",
133162
accuracy=0.987,
134163
)
135-
omlmd.pull(target, tmp_path, media_types=[MIME_APPLICATION_MLMODEL])
164+
omlmd.pull(target, tmp_path, media_types=[MIME_BLOB])
136165
assert len(list(tmp_path.iterdir())) == 1
137166

138167

@@ -155,10 +184,11 @@ def test_e2e_push_pull_column(tmp_path, target):
155184

156185
omlmd.push(target, temp, **md)
157186
omlmd.pull(target, tmp_path)
158-
with open(tmp_path.joinpath(temp.name), "r") as f:
159-
pulled = f.read()
160-
assert pulled == content
161-
pulled_sha = sha256(pulled.encode("utf-8")).hexdigest()
162-
assert pulled_sha == content_sha
187+
out = tmp_path.joinpath(temp.name)
188+
untar(out.with_suffix(".tar"), out)
189+
pulled = out.read_text()
190+
assert pulled == content
191+
pulled_sha = sha256(pulled.encode("utf-8")).hexdigest()
192+
assert pulled_sha == content_sha
163193
finally:
164194
temp.unlink()

0 commit comments

Comments
 (0)