yggdrasil.path.pypi¶
pypi ¶
:class:PyPIPath — managed PEP 503 simple index at any :class:Path root.
A drop-in "package artifactory" that publishes Python distributions
under a yggdrasil :class:~yggdrasil.io.path.path.Path root —
local, workspace, S3, DBFS volumes, in-memory — and keeps a
PEP 503-shaped index.html per project so the result is consumable
by pip install --extra-index-url=<root>.
Two ingestion shapes:
- :meth:
PyPIPath.publish— build a realpipwheel for a local module (importable name or source path) and upload the versioned wheel under<root>/<normalized-project>/<wheel>.whl. This is the pip-installable path: the wheel filename carries the version, the index page lists every uploaded wheel, and re-publishing the same source short-circuits when the target already exists. - :meth:
PyPIPath.publish_archive— zip a module via :meth:Path.upload_moduleand drop the archive under the same versioned layout. Used when the artefact ships as a raw zip (SparkaddArtifacts(pyfile=True),sys.pathextension) rather than a pip wheel.
Both shapes use the same versioning + subfolder convention; the caller picks based on the consumer.
:class:yggdrasil.databricks.jobs.workspace_pypi.WorkspacePyPI is
a thin subclass that pins the root to /Workspace/Shared/.ygg/pypi/simple
and binds the publisher to a workspace client.
PyPIPath ¶
A PEP 503 simple index hosted at root (any yggdrasil :class:Path).
Parameters¶
root
Where to publish. Anything :meth:Path.from_ accepts —
a :class:Path instance, a URL string
("/Workspace/Shared/pypi/simple",
"s3://my-bucket/pypi", "file:///tmp/pypi"), or a
:class:pathlib.Path. Strings without a scheme resolve to
:class:LocalPath.
Examples¶
Local index for testing::
pypi = PyPIPath("/tmp/my-index")
pypi.publish("my_local_pkg")
# → /tmp/my-index/my-local-pkg/my_local_pkg-0.1.0-py3-none-any.whl
Layered S3 index::
pypi = PyPIPath("s3://wheels.example.com/simple")
pypi.publish("internal_lib")
publish ¶
publish(
module: Any,
*,
source_path: Optional[str] = None,
version: Optional[str] = None,
rebuild: bool = False
) -> "Path"
Build a wheel for module and upload it under :attr:root.
module is anything :func:resolve_local_lib_path accepts —
an importable module name ("my_local_pkg"), a directory
path, or a pre-built .whl. The wheel is built via
python -m pip wheel --no-deps so we don't take a hard
dependency on :mod:build. Pre-built wheels handed in via
source_path are uploaded verbatim.
Re-publishing the same source is a no-op unless rebuild is set — the wheel filename carries the version, so an already-uploaded target short-circuits.
Returns the published :class:Path (full URL accessible via
.full_path() or .url).
publish_archive ¶
publish_archive(
module: Any,
*,
name: Optional[str] = None,
version: Optional[str] = None,
rebuild: bool = True
) -> "Path"
Zip module via :meth:Path.upload_module and place under :attr:root.
Mirrors :meth:publish but emits a raw .zip (suitable for
SparkSession.addArtifacts(pyfile=True) /
sys.path extension) instead of a pip wheel. The version is
derived from installed metadata when available; pass version
to override. The archive filename follows
{name}-{version}.zip so the per-project subfolder still
sorts by version.
rebuild=True (default) re-uploads each call — matches the
cheap-and-idempotent contract of :meth:Path.upload_module.
import_module ¶
import_module(
module_name: str,
*,
version: Optional[str] = None,
install: bool = False,
cache_dir: Any = None
) -> Any
Locate and import the published module_name from this index.
Locates the matching wheel / archive under
<root>/<normalized-name>/, prefers the requested version
when set (matched against the wheel filename), otherwise picks
the lexicographically-highest filename (the typical PEP 440
ordering for the same project). The resolved
:class:Path is then imported via
:meth:Path.import_module.
install=False (default) downloads the artefact and prepends
the local archive to sys.path. For .zip archives that's
enough; for .whl wheels the import will fail with
:class:ModuleNotFoundError unless the wheel is already
installed locally — pass install=True to opt into the
pip install fallback. The conservative default avoids
mutating the active interpreter's site-packages on a casual
lookup; callers that explicitly want the install step ask for
it.
Raises :class:ModuleNotFoundError when no artefact is
published under that name, with a hint pointing at
:meth:publish / :meth:publish_archive.
normalize_pep503_name ¶
Return the PEP 503-normalized form of a project name.
parse_wheel_filename ¶
Return (distribution, version) from a wheel filename, or (None, None).