ungana

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README

commit 3375febd6f2ad05f5c6bebd2dc7e40bfdfe4a2e1
parent 4aa7c70724a1b39cc0b523739271287522d4896a
Author: Carlosokumu <carlosokumu254@gmail.com>
Date:   Wed,  5 Nov 2025 10:41:34 +0300

feat: add store implementation for  fs and wala

Diffstat:
Aungana/store/__init.__.py | 0
Aungana/store/base_store.py | 12++++++++++++
Aungana/store/fs_store.py | 26++++++++++++++++++++++++++
Aungana/store/resolve.py | 12++++++++++++
Aungana/store/wala_store.py | 28++++++++++++++++++++++++++++
5 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/ungana/store/__init.__.py b/ungana/store/__init.__.py diff --git a/ungana/store/base_store.py b/ungana/store/base_store.py @@ -0,0 +1,12 @@ +from abc import ABC, abstractmethod +from typing import Union + +class UnganaBaseStore(ABC): + + @abstractmethod + def put(self, base_uri: str, name: str, data: Union[bytes, str]) -> str: + pass + + @abstractmethod + def get(self, base_uri: str, name: str) -> bytes: + pass diff --git a/ungana/store/fs_store.py b/ungana/store/fs_store.py @@ -0,0 +1,26 @@ +from pathlib import Path +from urllib.parse import urlparse +from .base_store import UnganaBaseStore + + +class UnganaFSStore(UnganaBaseStore): + def _resolve_base_path(self, uri: str) -> Path: + parsed = urlparse(uri) + path = parsed.path if parsed.scheme else uri + return Path(path).expanduser().resolve() + + def put(self, base_uri: str, name: str, data: bytes) -> str: + base_path = self._resolve_base_path(base_uri) + target = base_path.joinpath(name) + target.parent.mkdir(parents=True, exist_ok=True) + with open(target, "wb") as f: + f.write(data) + return f"file://{target}" + + def get(self, base_uri: str, name: str) -> bytes: + base_path = self._resolve_base_path(base_uri) + target = base_path.joinpath(name) + if not target.exists(): + raise FileNotFoundError(f"{target} does not exist") + return target.read_bytes() + diff --git a/ungana/store/resolve.py b/ungana/store/resolve.py @@ -0,0 +1,12 @@ +from urllib.parse import urlparse +from .fs_store import UnganaFSStore +from .wala_store import UnganaWalaStore + +def resolve_backend_store(uri: str): + parsed = urlparse(uri) + scheme = parsed.scheme.lower() + if scheme in ("http", "https"): + return UnganaWalaStore() + if scheme in ("", "file"): + return UnganaFSStore() + raise ValueError(f"Unsupported storage scheme: {parsed.scheme}") diff --git a/ungana/store/wala_store.py b/ungana/store/wala_store.py @@ -0,0 +1,28 @@ +import requests +from urllib.parse import urljoin, urlparse +import requests +from urllib.parse import urlparse, urljoin +from .base_store import UnganaBaseStore + + +class UnganaWalaStore(UnganaBaseStore): + + def put(self, base_url: str, name: str, data: bytes) -> str: + parsed = urlparse(base_url) + if not parsed.scheme.startswith("http"): + raise ValueError(f"Invalid Wala URL: {base_url}") + resp = requests.put(base_url, data=data, timeout=10) + resp.raise_for_status() + digest = resp.text.strip() + return urljoin(base_url.rstrip("/") + "/", digest) + + def get(self, base_url: str, name: str) -> bytes: + parsed = urlparse(base_url) + if not parsed.scheme.startswith("http"): + raise ValueError(f"Invalid Wala URL: {base_url}") + target_url = urljoin(base_url.rstrip("/") + "/", name) + resp = requests.get(target_url, timeout=10) + resp.raise_for_status() + return resp.content + +