Skip to content
This repository has been archived by the owner on May 31, 2024. It is now read-only.

Commit

Permalink
Add support for Python 3.12 and prep v0.2.0. (#35)
Browse files Browse the repository at this point in the history
Also document how modern Pex can be used instead of Lambdex to pave the
way to archiving the project after the 0.2.0 release.
  • Loading branch information
jsirois authored May 30, 2024
1 parent 7477011 commit 00938f0
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 54 deletions.
65 changes: 46 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on: [push, pull_request]
jobs:
checks:
name: TOXENV=${{ matrix.tox-env }}
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
include:
Expand All @@ -15,53 +15,80 @@ jobs:
tox-env: package
steps:
- name: Checkout Lambdex
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python-version }}"
- name: Check ${{ matrix.check-name }}
uses: pantsbuild/actions/run-tox@e63d2d0e3c339bdffbe5e51e7c39550e3bc527bb
with:
tox-env: ${{ matrix.tox-env }}
integration-tests:
integration-tests-27-36:
name: (${{ matrix.os }}) TOXENV=py${{ matrix.python-version[0] }}${{ matrix.python-version[1] }}-int-${{ matrix.it-selector }}-pex1.6
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- python-version: [2, 7]
os: macos-11
- python-version: [2, 7, 18]
os: macos-12
it-selector: "{pre,post}"
- python-version: [2, 7]
os: ubuntu-20.04
- python-version: [2, 7, 18]
os: ubuntu-22.04
it-selector: "{pre,post}"
- python-version: [3, 6]
os: ubuntu-20.04
- python-version: [3, 6, 15]
os: ubuntu-22.04
it-selector: "{pre,post}"
steps:
- name: Checkout Lambdex
uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version[0] }}${{ matrix.python-version[1] }}
# Upgrade node16 -> node20: Out for review here:
# https://github.com/gabrielfalcao/pyenv-action/pull/444
uses: pex-tool/pyenv-action@baec18679698d2f80064cc04eb9ad0c8dc5ca8f8
env:
ENSUREPIP: no
with:
default: "${{ join(matrix.python-version, '.') }}"
- name: Run Integration Tests
run: |
which python
python -V
python <(curl -fSL https://bootstrap.pypa.io/pip/${{ matrix.python-version[0] }}.${{ matrix.python-version[1] }}/get-pip.py)
python -m pip install -U "tox<4"
python -m tox -e py${{ matrix.python-version[0] }}${{ matrix.python-version[1] }}-int-${{ matrix.it-selector }}-pex1.6
integration-tests-37-312:
name: (${{ matrix.os }}) TOXENV=py${{ matrix.python-version[0] }}${{ matrix.python-version[1] }}-int-${{ matrix.it-selector }}-pex1.6
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- python-version: [3, 7]
os: ubuntu-20.04
os: ubuntu-22.04
it-selector: "{pre,post}"
- python-version: [3, 8]
os: ubuntu-20.04
os: ubuntu-22.04
it-selector: "{pre,post}"
- python-version: [3, 9]
os: ubuntu-20.04
os: ubuntu-22.04
it-selector: "{pre,post}"
- python-version: [3, 10]
os: macos-11
os: macos-12
it-selector: "post"
- python-version: [3, 10]
os: ubuntu-20.04
os: ubuntu-22.04
it-selector: "post"
- python-version: [3, 11]
os: ubuntu-22.04
it-selector: "post"
- python-version: [3, 11, "0-rc.2"]
os: ubuntu-20.04
- python-version: [3, 12]
os: ubuntu-22.04
it-selector: "post"
steps:
- name: Checkout Lambdex
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Python ${{ join(matrix.python-version, '.') }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "${{ join(matrix.python-version, '.') }}"
- name: Run Integration Tests
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
jobs:
determine-tag:
name: Determine the release tag to operate against.
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
outputs:
release-tag: ${{ steps.determine-tag.outputs.release-tag }}
release-version: ${{ steps.determine-tag.outputs.release-version }}
Expand All @@ -33,16 +33,16 @@ jobs:
fi
pypi:
name: Publish sdist and wheel to PyPI
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
environment: Release
needs: determine-tag
steps:
- name: Checkout ${{ needs.determine-tag.outputs.release-tag }}
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: ${{ needs.determine-tag.outputs.release-tag }}
- name: Setup Python 3.9
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.9
- name: Publish ${{ needs.determine-tag.outputs.release-tag }}
Expand Down
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Release Notes

## 0.2.0

This release brings official support for Python 3.12 and is also the last release of Lambdex.
See [the migration guide](MIGRATING.md) for how modern PEXes can be used directly with no need for
Lambdex.

## 0.1.9

This release fixes a bug wherein, when using the -o/--output option Lambdex would fail to write the
Expand Down
49 changes: 49 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Migrating to modern Pex

Lambdex used to be needed to produce zip files useable in lambda functions, but with modern Pex,
it no longer is. Starting with Pex version 2.1.98 you only need to include `import __pex__` at the
top of your lambda handler entrypoint module and build the PEX with
`--inherit-path {fallback,prefer}`.

For example, with the following `my_lambda_module.py`:
```python
import __pex__

import hashlib

import requests


def handler(event, context):
url = event["url"]
return {
url: hashlib.sha256(requests.get(url).content).hexdigest(),
"requests.__file__": requests.__file__,
}
```

You can create a zip that will work[^1] in the Python 3.12 AWS lambda runtime with:
```
pex \
--python python3.12 \
requests \
--module my_lambda_module \
--output-file pex_lambda_function.zip \
--inherit-path=fallback
```

With the zip uploaded and the lambda runtime configured to use the `my_lambda_module.handler`
handler, you can post an event with `{"url": "https://example.org"}` to the handler endpoint
and see a response similar to:
```json
{
"https://example.org": "ea8fac7c65fb589b0d53560f5251f74f9e9b243478dcb6b3ea79b5e36449c8d9",
"requests.__file__": "/var/task/.deps/requests-2.32.3-py3-none-any.whl/requests/__init__.py"
}
```

[^1]: In general, you need to either build the PEX in an environment compatible with the Lambda
deployment environment or else use the the Pex [`--complete-platform`](
https://docs.pex-tool.org/buildingpex.html#complete-platform) option to properly cross-resolve
for the deployement environment. This is no different a requirement than existed when using
Lambdex to transform a PEX into a lambda-compatible zip previously.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# lambdex

> [!WARNING]
> Lambdex is no longer necessary and the 0.2.0 release of Lambdex is the last.
> Modern PEXes can be used directly as Lambda zips. See the [the migration guide](MIGRATING.md) for
> details.
lambdex turns pex files into aws lambda functions.

[pex](https://github.com/pantsbuild/pex) is a tool that simplifies packaging python environments and is ideally suited
[pex](https://github.com/pex-tool/pex) is a tool that simplifies packaging python environments and is ideally suited
for aws lambda. lambdex takes pex files and turns them into aws lambda functions, allowing
you to more easily run complex applications in the cloud.

Expand Down Expand Up @@ -87,7 +92,7 @@ Amazon provides an amazonlinux docker image which can be useful for building pla
on AWS Lambda. See [documentation](http://docs.aws.amazon.com/AmazonECR/latest/userguide/amazon_linux_container_image.html)
for information about that image.

The minimum Dockerfile to produce can environment that can build Amazon Linux-specific pex files can be found [here](https://github.com/pantsbuild/lambdex/blob/main/Dockerfile)
The minimum Dockerfile to produce can environment that can build Amazon Linux-specific pex files can be found [here](https://github.com/pex-tool/lambdex/blob/main/Dockerfile)

### controlling runtime execution

Expand Down
12 changes: 6 additions & 6 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

Bump the version in [`lambdex/version.py`](lambdex/version.py) and update
[`CHANGES.md`](CHANGES.md) with any changes that are likely to be useful to consumers and then open
a PR with these changes and land it on https://github.com/pantsbuild/lambdex main.
a PR with these changes and land it on https://github.com/pex-tool/lambdex main.

## Release

### Push Release Tag

Sync a local branch with https://github.com/pantsbuild/lambdex main and confirm it has the version
Sync a local branch with https://github.com/pex-tool/lambdex main and confirm it has the version
bump and changelog update as the tip commit:

```
Expand All @@ -28,15 +28,15 @@ Date: Mon Apr 26 12:36:53 2021 -0800
2 files changed, 42 insertions(+), 1 deletions(-)
```

Tag the release as `v<version>` and push the tag to https://github.com/pantsbuild/lambdex main:
Tag the release as `v<version>` and push the tag to https://github.com/pex-tool/lambdex main:

```
$ git tag --sign -am 'Release 0.1.4' v0.1.4
$ git push --tags https://github.com/pantsbuild/lambdex HEAD:main
$ git push --tags https://github.com/pex-tool/lambdex HEAD:main
```

The release to PyPI is automated but requires approval from at least one Core or Maintainers team
member. These folks will all get an email with a link to the GitHub release workflow to do this.
Alternatively, they can open the Release workflow
[here](https://github.com/pantsbuild/lambdex/actions?query=workflow%3ARelease) and navigate to the
release approval widget.
[here](https://github.com/pex-tool/lambdex/actions?query=workflow%3ARelease) and navigate to the
release approval widget.
2 changes: 1 addition & 1 deletion examples/event_based/example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

pex -r requirements.txt -o lambda_function.zip
lambdex build -s example_function.py lambda_function.zip
lambdex test lambda_function.zip <(echo '{"url": "https://github.com/pantsbuild"}')
lambdex test lambda_function.zip <(echo '{"url": "https://github.com/pex-tool"}')
2 changes: 1 addition & 1 deletion examples/gcp_http/example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

pex -r requirements.txt -o lambda_function.zip
dist/lambdex build -s example_http_function.py -M main.py lambda_function.zip
dist/lambdex test --type gcp-http lambda_function.zip <(echo '{"url": "https://github.com/pantsbuild"}')
dist/lambdex test --type gcp-http lambda_function.zip <(echo '{"url": "https://github.com/pex-tool"}')
24 changes: 16 additions & 8 deletions lambdex/bin/lambdex.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@

from lambdex.version import __version__

try:
# PEX >= 1.6.0
from pex.third_party.pkg_resources import EntryPoint
except ImportError:
# PEX < 1.6.0 has an install requirement of setuptools which we leverage knowledge of.
from pkg_resources import EntryPoint

EVENT_FUNCTION_SIGNATURE = "event"
GCP_HTTP_FUNCTION_SIGNATURE = "gcp-http"

Expand Down Expand Up @@ -207,6 +200,21 @@ def chdir(dirname):
os.chdir(cwd)


def load_entry_point(entry_point):
if sys.version_info[:2] >= (3, 8):
from importlib.metadata import EntryPoint

return EntryPoint(name=None, value=entry_point, group=None).load()
else:
try:
# PEX >= 1.6.0
from pex.third_party.pkg_resources import EntryPoint
except ImportError:
# PEX < 1.6.0 has an install requirement of setuptools which we leverage knowledge of.
from pkg_resources import EntryPoint
return EntryPoint.parse("run = {ep}".format(ep=entry_point)).resolve()


# lambdex test [context configuration options] foo.pex <foo.json
def test_lambdex(args):
bootstrap_pex_env(args.pex)
Expand All @@ -223,7 +231,7 @@ def test_lambdex(args):
sys.path.append(target)

with chdir(target):
runner = EntryPoint.parse("run = %s" % lambdex_entry_point).resolve()
runner = load_entry_point(lambdex_entry_point)
if args.type == EVENT_FUNCTION_SIGNATURE:
if args.empty:
runner({}, None)
Expand Down
21 changes: 18 additions & 3 deletions lambdex/resources/lambdex_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@
try:
# PEX >= 1.6.0
from pex.pex_bootstrapper import bootstrap_pex_env
from pex.third_party.pkg_resources import EntryPoint as __EntryPoint
except ImportError:
# PEX < 1.6.0 has an install requirement of setuptools which we leverage knowledge of.
from _pex.pex_bootstrapper import bootstrap_pex_env
from pkg_resources import EntryPoint as __EntryPoint

bootstrap_pex_env(__entry_point__)

Expand All @@ -51,7 +49,24 @@
__lambdex_info = __json.loads(__lambdex_info_blob)
__lambdex_entry_point = __lambdex_info["entry_point"]

__RUNNER = __EntryPoint.parse("run = %s" % __lambdex_entry_point).resolve()

def load_entry_point(entry_point):
if sys.version_info[:2] >= (3, 8):
from importlib.metadata import EntryPoint

return EntryPoint(name=None, value=entry_point, group=None).load()
else:
try:
# PEX >= 1.6.0
from pex.third_party.pkg_resources import EntryPoint
except ImportError:
# PEX < 1.6.0 has an install requirement of setuptools which we leverage knowledge of.
from pkg_resources import EntryPoint
return EntryPoint.parse("run = {ep}".format(ep=entry_point)).resolve()


__RUNNER = load_entry_point(__lambdex_entry_point)
del load_entry_point


def handler(*args, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion lambdex/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

__version__ = "0.1.9"
__version__ = "0.2.0"
9 changes: 5 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ build-backend = "flit_core.buildapi"
[tool.flit.metadata]
module = "lambdex"
author = "The Lambdex developers"
author-email = "[email protected]"
home-page = "https://github.com/pantsbuild/lambdex"
author-email = "[email protected]"
home-page = "https://github.com/pex-tool/lambdex"
description-file = "README.md"
classifiers = [
"Development Status :: 4 - Beta",
Expand All @@ -25,13 +25,14 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Build Tools",
"Topic :: System :: Archiving :: Packaging",
"Topic :: System :: Software Distribution",
"Topic :: Utilities",
]
requires = ["pex>=1.1.15"]
requires-python = ">=2.7,<3.12,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
requires-python = ">=2.7,<3.13,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"

[tool.flit.metadata.requires-extra]
test-gcp-http = [
Expand All @@ -47,7 +48,7 @@ lambdex = "lambdex.bin.lambdex:main"
include = ["CHANGES.md"]

[tool.flit.metadata.urls]
Changelog = "https://github.com/pantsbuild/lambdex/blob/main/CHANGES.md"
Changelog = "https://github.com/pex-tool/lambdex/blob/main/CHANGES.md"

[tool.black]
line-length = 100
Expand Down
Loading

0 comments on commit 00938f0

Please sign in to comment.