⚡️ sema4ai-build-common
A Python library containing common utilities for building Sema4AI projects.
-- it deals with things such as building and signing executables.
Notes on how it works:
-
The
sema4ai.build_common.workflowsmodule contains the entry points that should be called by other projects. -
build_and_sign_executableshould be called to actually build the executable and sign it. -
This function handles building and signing an executable, with these main steps:
-
Build: Uses PyInstaller to create an executable from Python code. It always builds in "not onefile" mode, meaning it creates a directory containing the executable and its dependencies.
-
Signing (Optional): If the sign parameter is True:
- On macOS: Signs using macOS code signing and properly notarizes afterwards
- On Windows: Signs using Windows code signing
-
Go Wrapper (Optional): If go_wrapper is True:
- Zips the PyInstaller-built application assets
- Builds a Go wrapper around the application
- Creates a final executable that combines both
- Signs the final executable if signing is enabled
-
-
Requirements for build:
-
A
<project-name>.specfile must be available in the root of the project with the pyinstaller spec to build the executable (the build process will use it to build with pyinstaller) -
The
go-wrapperfor the app must also be in the root of the project (at this point, each app needs its own, although in the future a common base should probably be used). The build utilities will put aversion.txtand anassets.zipin/go-wrapper/assets(if the/go-wrapperdirectory does not exist the build will fail).
-
Example of integration in sai-server -- note that sai-server uses typer to create a command line instead of invoke:
import typer
app = typer.Typer()
@app.command()
def build_executable(
debug: bool = typer.Option(False, help="Build in debug mode"),
ci: bool = typer.Option(
True, help="Build in CI mode, disabling interactive prompts"
),
dist_path: Path = typer.Option("dist", help="Path to the dist directory"),
sign: bool = typer.Option(False, help="Sign the executable"),
go_wrapper: bool = typer.Option(False, help="Build the Go wrapper too"),
version: str | None = typer.Option(
None, help="Version of the executable (gotten from github tag/pr if not passed)"
),
) -> None:
"""Build the project executable via PyInstaller."""
from sema4ai.build_common.root_dir import get_root_dir
from sema4ai.build_common.workflows import build_and_sign_executable
from sema4ai.action_server import __version__
if version is None:
version = __version__ # Get version from the project...
root_dir = get_root_dir()
build_and_sign_executable(
root_dir=root_dir,
name="action-server",
debug=debug,
ci=ci,
dist_path=root_dir / dist_path,
sign=sign,
go_wrapper=go_wrapper,
version=__version__,
)
The job that integrates it needs several environment variables for the signing and version gathering
-- Note that the version is gotten from the tag or pr or branch name (based on the GITUB_EVENT_NAME,
GITHUB_REF_NAME and GITHUB_PR_NUMBER), but applications that handle the version differently
could pass the version in the command-line or call to build_and_sign_executable.
- name: Build SAI Server binary
run: uv run python -m sai_tasks build-executable --sign --go-wrapper
env:
MACOS_SIGNING_CERT: ${{ secrets.MACOS_SIGNING_CERT_SEMA4AI }}
MACOS_SIGNING_CERT_PASSWORD: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD_SEMA4AI }}
MACOS_SIGNING_CERT_NAME: ${{ secrets.MACOS_SIGNING_CERT_NAME_SEMA4AI }}
APPLEID: ${{ secrets.MACOS_APP_ID_FOR_NOTARIZATION_SEMA4AI }}
APPLETEAMID: ${{ secrets.MACOS_TEAM_ID_FOR_NOTARIZATION_SEMA4AI }}
APPLEIDPASS: ${{ secrets.MACOS_APP_ID_PASSWORD_FOR_NOTARIZATION_SEMA4AI }}
VAULT_URL: ${{ secrets.WIN_SIGN_AZURE_KEY_VAULT_URL_SEMA4AI }}
CLIENT_ID: ${{ secrets.WIN_SIGN_AZURE_KEY_VAULT_CLIENT_ID_SEMA4AI }}
TENANT_ID: ${{ secrets.WIN_SIGN_AZURE_KEY_VAULT_TENANT_ID_SEMA4AI }}
CLIENT_SECRET: ${{ secrets.WIN_SIGN_AZURE_KEY_VAULT_CLIENT_SECRET_SEMA4AI }}
CERTIFICATE_NAME: ${{ secrets.WIN_SIGN_AZURE_KEY_VAULT_CERTIFICATE_NAME_SEMA4AI }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
Metadata
Release files for sema4ai-build-common 0.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| sema4ai_build_common-0.0.3.tar.gz | 10.4 kB | Without provenance | Details for sema4ai_build_common-0.0.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| sema4ai_build_common-0.0.3-py3-none-any.whl | Python 3 | none | any | Details for sema4ai_build_common-0.0.3-py3-none-any.whl |
Total release size: 23.3 kB
Release files / sema4ai_build_common-0.0.3.tar.gz
| Download URL | sema4ai_build_common-0.0.3.tar.gz |
|---|---|
| Size | 10.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7515feeee078d1ba99d2be0dda0a24171a816eed1989d6f0caf384c63d69a9a7
|
|
BLAKE2b-256 checksum How to use checksums |
a8c9f8cad5455f30a2502d46c14f34ad74cbbc9c240e00ed2d29eafd5eaed8be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.12.3 Linux/6.11.0-1014-azure
|
Release files / sema4ai_build_common-0.0.3-py3-none-any.whl
| Download URL | sema4ai_build_common-0.0.3-py3-none-any.whl |
|---|---|
| Size | 12.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d0d3713684e6f3608ef8d1b243e8d1f28df46cfbe6e75d052420d81dc784dbca
|
|
BLAKE2b-256 checksum How to use checksums |
f1fec7ad51c8e4ecfa3fbced576186c9a5bbc799eed13bbf25e3d76feb68285c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.12.3 Linux/6.11.0-1014-azure
|
Security for sema4ai-build-common 0.0.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.